Migration to Android Studio
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
|
@ -1,2 +1,6 @@
|
|||
/gen/
|
||||
/bin/
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
DFULibrary
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
</project>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<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="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/dfu" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/DFULibrary.iml" filepath="$PROJECT_DIR$/DFULibrary.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/dfu/dfu.iml" filepath="$PROJECT_DIR$/dfu/dfu.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<component name="DependencyValidationManager">
|
||||
<state>
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||
</state>
|
||||
</component>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="" />
|
||||
</component>
|
||||
</project>
|
||||
|
33
.project
|
@ -1,33 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>DFULibrary</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,23 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
|
||||
The information contained herein is property of Nordic Semiconductor ASA.
|
||||
Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
This heading must NOT be removed from the file.
|
||||
|
||||
The DFU Library is compatible with OTA-DFU bootloader from SDK version 7.0.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="no.nordicsemi.android.dfu"
|
||||
android:versionCode="2"
|
||||
android:versionName="7.0" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="18"
|
||||
android:targetSdkVersion="21" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true" />
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1 @@
|
|||
/build
|
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":app" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
|
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
|
||||
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="appcompat-v7-21.0.3" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-21.0.3" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion "21.1.2"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "no.nordicsemi.android.dfu"
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 21
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:appcompat-v7:21.0.3'
|
||||
}
|
|
@ -1,11 +1,8 @@
|
|||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
# in C:\Users\alno\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
@ -0,0 +1,13 @@
|
|||
package no.nordicsemi.android.dfu;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="no.nordicsemi.android.dfu">
|
||||
|
||||
<application android:allowBackup="true" android:label="@string/app_name"
|
||||
android:icon="@drawable/ic_launcher" android:theme="@style/AppTheme">
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
After Width: | Height: | Size: 9.2 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">DFULibrary</string>
|
||||
</resources>
|
|
@ -0,0 +1,8 @@
|
|||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,19 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.0.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
}
|
92
build.xml
|
@ -1,92 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="DFULibrary" default="help">
|
||||
|
||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||
It contains the path to the SDK. It should *NOT* be checked into
|
||||
Version Control Systems. -->
|
||||
<property file="local.properties" />
|
||||
|
||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
||||
'android' tool to add properties to it.
|
||||
This is the place to change some Ant specific build properties.
|
||||
Here are some properties you may want to change/update:
|
||||
|
||||
source.dir
|
||||
The name of the source directory. Default is 'src'.
|
||||
out.dir
|
||||
The name of the output directory. Default is 'bin'.
|
||||
|
||||
For other overridable properties, look at the beginning of the rules
|
||||
files in the SDK, at tools/ant/build.xml
|
||||
|
||||
Properties related to the SDK location or the project target should
|
||||
be updated using the 'android' tool with the 'update' action.
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems.
|
||||
|
||||
-->
|
||||
<property file="ant.properties" />
|
||||
|
||||
<!-- if sdk.dir was not set from one of the property file, then
|
||||
get it from the ANDROID_HOME env var.
|
||||
This must be done before we load project.properties since
|
||||
the proguard config can use sdk.dir -->
|
||||
<property environment="env" />
|
||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
||||
<isset property="env.ANDROID_HOME" />
|
||||
</condition>
|
||||
|
||||
<!-- The project.properties file is created and updated by the 'android'
|
||||
tool, as well as ADT.
|
||||
|
||||
This contains project specific properties such as project target, and library
|
||||
dependencies. Lower level build properties are stored in ant.properties
|
||||
(or in .classpath for Eclipse projects).
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems. -->
|
||||
<loadproperties srcFile="project.properties" />
|
||||
|
||||
<!-- quick check on sdk.dir -->
|
||||
<fail
|
||||
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
||||
unless="sdk.dir"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Import per project custom build rules if present at the root of the project.
|
||||
This is the place to put custom intermediary targets such as:
|
||||
-pre-build
|
||||
-pre-compile
|
||||
-post-compile (This is typically used for code obfuscation.
|
||||
Compiled code location: ${out.classes.absolute.dir}
|
||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
||||
-post-package
|
||||
-post-build
|
||||
-pre-clean
|
||||
-->
|
||||
<import file="custom_rules.xml" optional="true" />
|
||||
|
||||
<!-- Import the actual build file.
|
||||
|
||||
To customize existing targets, there are two options:
|
||||
- Customize only one target:
|
||||
- copy/paste the target into this file, *before* the
|
||||
<import> task.
|
||||
- customize it to your needs.
|
||||
- Customize the whole content of build.xml
|
||||
- copy/paste the content of the rules files (minus the top node)
|
||||
into this file, replacing the <import> task.
|
||||
- customize to your needs.
|
||||
|
||||
***********************
|
||||
****** IMPORTANT ******
|
||||
***********************
|
||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
||||
in order to avoid having your file be overridden by tools such as "android update project"
|
||||
-->
|
||||
<!-- version-tag: 1 -->
|
||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
/build
|
|
@ -0,0 +1,24 @@
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion "21.1.2"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 21
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:support-v4:21.0.3'
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/../../nRFToolbox" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":..:DFULibrary:dfu" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
|
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
|
||||
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
<option name="LIBRARY_PROJECT" value="true" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="nrf-logger-v2.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-21.0.3" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in C:/Users/alno/AppData/Local/Android/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
|
@ -0,0 +1,13 @@
|
|||
package no.nordicsemi.android.dfu;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="no.nordicsemi.android.dfu"
|
||||
android:versionCode="2"
|
||||
android:versionName="7.0" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="18"
|
||||
android:targetSdkVersion="21" />
|
||||
|
||||
|
||||
</manifest>
|
|
@ -1,9 +1,9 @@
|
|||
package no.nordicsemi.android.dfu;
|
||||
|
||||
public interface DfuSettingsConstants {
|
||||
public static final String SETTINGS_PACKET_RECEIPT_NOTIFICATION_ENABLED = "settings_packet_receipt_notification_enabled";
|
||||
public static final String SETTINGS_NUMBER_OF_PACKETS = "settings_number_of_packets";
|
||||
public static final String SETTINGS_MBR_SIZE = "settings_mbr_size";
|
||||
public static final int SETTINGS_DEFAULT_MBR_SIZE = 0x1000;
|
||||
public static final int SETTINGS_NUMBER_OF_PACKETS_DEFAULT = 10;
|
||||
}
|
||||
package no.nordicsemi.android.dfu;
|
||||
|
||||
public interface DfuSettingsConstants {
|
||||
public static final String SETTINGS_PACKET_RECEIPT_NOTIFICATION_ENABLED = "settings_packet_receipt_notification_enabled";
|
||||
public static final String SETTINGS_NUMBER_OF_PACKETS = "settings_number_of_packets";
|
||||
public static final String SETTINGS_MBR_SIZE = "settings_mbr_size";
|
||||
public static final int SETTINGS_DEFAULT_MBR_SIZE = 0x1000;
|
||||
public static final int SETTINGS_NUMBER_OF_PACKETS_DEFAULT = 10;
|
||||
}
|
|
@ -1,332 +1,332 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import no.nordicsemi.android.dfu.exception.HexFileValidationException;
|
||||
|
||||
/**
|
||||
* Reads the binary content from the HEX file using IntelHex standard: http://www.interlog.com/~speff/usefulinfo/Hexfrmt.pdf
|
||||
* Truncates the HEX file from all meta data and returns only the BIN content.
|
||||
* <p>
|
||||
* In nRF51 chips memory a SoftDevice starts at address 0x1000. From 0x0000 to 0x1000 there is MBR sector (since SoftDevice 7.0.0) which should not be transmitted using DFU. Therefore this class skips
|
||||
* all data from addresses below 0x1000.
|
||||
* </p>
|
||||
*/
|
||||
public class HexInputStream extends FilterInputStream {
|
||||
private final int LINE_LENGTH = 128;
|
||||
|
||||
private final byte[] localBuf;
|
||||
private int localPos;
|
||||
private int pos;
|
||||
private int size;
|
||||
private int lastAddress;
|
||||
private int available, bytesRead;
|
||||
private int MBRsize;
|
||||
|
||||
/**
|
||||
* Creates the HEX Input Stream. The constructor calculates the size of the BIN content which is available through {@link #sizeInBytes()}. If HEX file is invalid then the bin size is 0.
|
||||
*
|
||||
* @param in
|
||||
* the input stream to read from
|
||||
* @param trim
|
||||
* if <code>true</code> the bin data will be trimmed. All data from addresses < 0x1000 will be skipped. In the Soft Device 7.0.0 it's MBR space and this HEX fragment should not be
|
||||
* transmitted. However, other DFU implementations (f.e. without Soft Device) may require uploading the whole file.
|
||||
* @throws HexFileValidationException
|
||||
* if HEX file is invalid. F.e. there is no semicolon (':') on the beginning of each line.
|
||||
* @throws IOException
|
||||
* if the stream is closed or another IOException occurs.
|
||||
*/
|
||||
protected HexInputStream(final InputStream in, final int mbrSize) throws HexFileValidationException, IOException {
|
||||
super(new BufferedInputStream(in));
|
||||
this.localBuf = new byte[LINE_LENGTH];
|
||||
this.localPos = LINE_LENGTH; // we are at the end of the local buffer, new one must be obtained
|
||||
this.size = localBuf.length;
|
||||
this.lastAddress = 0;
|
||||
this.MBRsize = mbrSize;
|
||||
|
||||
this.available = calculateBinSize(mbrSize);
|
||||
}
|
||||
|
||||
protected HexInputStream(final byte[] data, final int mbrSize) throws HexFileValidationException, IOException {
|
||||
super(new ByteArrayInputStream(data));
|
||||
this.localBuf = new byte[LINE_LENGTH];
|
||||
this.localPos = LINE_LENGTH; // we are at the end of the local buffer, new one must be obtained
|
||||
this.size = localBuf.length;
|
||||
this.lastAddress = 0;
|
||||
this.MBRsize = mbrSize;
|
||||
|
||||
this.available = calculateBinSize(mbrSize);
|
||||
}
|
||||
|
||||
private int calculateBinSize(final int mbrSize) throws IOException {
|
||||
int binSize = 0;
|
||||
final InputStream in = this.in;
|
||||
in.mark(in.available());
|
||||
|
||||
int b, lineSize, offset, type;
|
||||
int lastBaseAddress = 0; // last Base Address, default 0
|
||||
int lastAddress = 0;
|
||||
try {
|
||||
b = in.read();
|
||||
while (true) {
|
||||
checkComma(b);
|
||||
|
||||
lineSize = readByte(in); // reading the length of the data in this line
|
||||
offset = readAddress(in);// reading the offset
|
||||
type = readByte(in); // reading the line type
|
||||
switch (type) {
|
||||
case 0x01:
|
||||
// end of file
|
||||
return binSize;
|
||||
case 0x04: {
|
||||
// extended linear address record
|
||||
/*
|
||||
* The HEX file may contain jump to different addresses. The MSB of LBA (Linear Base Address) is given using the line type 4.
|
||||
* We only support files where bytes are located together, no jumps are allowed. Therefore the newULBA may be only lastULBA + 1 (or any, if this is the first line of the HEX)
|
||||
*/
|
||||
final int newULBA = readAddress(in);
|
||||
if (binSize > 0 && newULBA != (lastBaseAddress >> 16) + 1)
|
||||
return binSize;
|
||||
lastBaseAddress = newULBA << 16;
|
||||
in.skip(2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
case 0x02: {
|
||||
// extended segment address record
|
||||
final int newSBA = readAddress(in) << 4;
|
||||
if (binSize > 0 && (newSBA >> 16) != (lastBaseAddress >> 16) + 1)
|
||||
return binSize;
|
||||
lastBaseAddress = newSBA;
|
||||
in.skip(2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
case 0x00:
|
||||
// data type line
|
||||
lastAddress = lastBaseAddress + offset;
|
||||
if (lastAddress >= mbrSize) // we must skip all data from below last MBR address (default 0x1000) as those are the MBR. The Soft Device starts at the end of MBR (0x1000), the app and bootloader farther more
|
||||
binSize += lineSize;
|
||||
// no break!
|
||||
default:
|
||||
in.skip(lineSize * 2 /* 2 hex per one byte */+ 2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
// skip end of line
|
||||
while (true) {
|
||||
b = in.read();
|
||||
|
||||
if (b != '\n' && b != '\r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
in.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return available - bytesRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the buffer with next bytes from the stream.
|
||||
*
|
||||
* @return the size of the buffer
|
||||
* @throws IOException
|
||||
*/
|
||||
public int readPacket(byte[] buffer) throws HexFileValidationException, IOException {
|
||||
int i = 0;
|
||||
while (i < buffer.length) {
|
||||
if (localPos < size) {
|
||||
buffer[i++] = localBuf[localPos++];
|
||||
continue;
|
||||
}
|
||||
|
||||
bytesRead += size = readLine();
|
||||
if (size == 0)
|
||||
break; // end of file reached
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
throw new UnsupportedOperationException("Please, use readPacket() method instead");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
return readPacket(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer, int offset, int count) throws IOException {
|
||||
throw new UnsupportedOperationException("Please, use readPacket() method instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of bytes.
|
||||
*
|
||||
* @return total number of bytes available
|
||||
*/
|
||||
public int sizeInBytes() {
|
||||
return available;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of packets with given size that are needed to get all available data
|
||||
*
|
||||
* @param packetSize
|
||||
* the maximum packet size
|
||||
* @return the number of packets needed to get all the content
|
||||
* @throws IOException
|
||||
*/
|
||||
public int sizeInPackets(final int packetSize) throws IOException {
|
||||
final int sizeInBytes = sizeInBytes();
|
||||
|
||||
return sizeInBytes / packetSize + ((sizeInBytes % packetSize) > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads new line from the input stream. Input stream must be a HEX file. The first line is always skipped.
|
||||
*
|
||||
* @return the number of data bytes in the new line. 0 if end of file.
|
||||
* @throws IOException
|
||||
* if this stream is closed or another IOException occurs.
|
||||
*/
|
||||
private int readLine() throws IOException {
|
||||
// end of file reached
|
||||
if (pos == -1)
|
||||
return 0;
|
||||
final InputStream in = this.in;
|
||||
|
||||
// temporary value
|
||||
int b = 0;
|
||||
|
||||
int lineSize, type, offset;
|
||||
do {
|
||||
// skip end of line
|
||||
while (true) {
|
||||
b = in.read();
|
||||
pos++;
|
||||
|
||||
if (b != '\n' && b != '\r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Each line starts with comma (':')
|
||||
* Data is written in HEX, so each 2 ASCII letters give one byte.
|
||||
* After the comma there is one byte (2 HEX signs) with line length (normally 10 -> 0x10 -> 16 bytes -> 32 HEX characters)
|
||||
* After that there is a 4 byte of an address. This part may be skipped.
|
||||
* There is a packet type after the address (1 byte = 2 HEX characters). 00 is the valid data. Other values can be skipped when
|
||||
* converting to BIN file.
|
||||
* Then goes n bytes of data followed by 1 byte (2 HEX chars) of checksum, which is also skipped in BIN file.
|
||||
*/
|
||||
checkComma(b); // checking the comma at the beginning
|
||||
lineSize = readByte(in); // reading the length of the data in this line
|
||||
pos += 2;
|
||||
offset = readAddress(in);// reading the offset
|
||||
pos += 4;
|
||||
type = readByte(in); // reading the line type
|
||||
pos += 2;
|
||||
|
||||
// if the line type is no longer data type (0x00), we've reached the end of the file
|
||||
switch (type) {
|
||||
case 0x00:
|
||||
// data type
|
||||
if (lastAddress + offset < MBRsize) { // skip MBR
|
||||
type = -1; // some other than 0
|
||||
pos += in.skip(lineSize * 2 /* 2 hex per one byte */+ 2 /* check sum */);
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
// end of file
|
||||
pos = -1;
|
||||
return 0;
|
||||
case 0x02: {
|
||||
// extended segment address
|
||||
final int address = readAddress(in) << 4;
|
||||
pos += 4;
|
||||
if (bytesRead > 0 && (address >> 16) != (lastAddress >> 16) + 1)
|
||||
return 0;
|
||||
lastAddress = address;
|
||||
pos += in.skip(2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
case 0x04: {
|
||||
// extended linear address
|
||||
final int address = readAddress(in);
|
||||
pos += 4;
|
||||
if (bytesRead > 0 && address != (lastAddress >> 16) + 1)
|
||||
return 0;
|
||||
lastAddress = address << 16;
|
||||
pos += in.skip(2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pos += in.skip(lineSize * 2 /* 2 hex per one byte */+ 2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
} while (type != 0);
|
||||
|
||||
// otherwise read lineSize bytes or fill the whole buffer
|
||||
for (int i = 0; i < localBuf.length && i < lineSize; ++i) {
|
||||
b = readByte(in);
|
||||
pos += 2;
|
||||
localBuf[i] = (byte) b;
|
||||
}
|
||||
pos += in.skip(2); // skip the checksum
|
||||
localPos = 0;
|
||||
|
||||
return lineSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
super.reset();
|
||||
|
||||
pos = 0;
|
||||
bytesRead = 0;
|
||||
localPos = 0;
|
||||
}
|
||||
|
||||
private void checkComma(final int comma) throws HexFileValidationException {
|
||||
if (comma != ':')
|
||||
throw new HexFileValidationException("Not a HEX file");
|
||||
}
|
||||
|
||||
private int readByte(final InputStream in) throws IOException {
|
||||
final int first = asciiToInt(in.read());
|
||||
final int second = asciiToInt(in.read());
|
||||
|
||||
return first << 4 | second;
|
||||
}
|
||||
|
||||
private int readAddress(final InputStream in) throws IOException {
|
||||
return readByte(in) << 8 | readByte(in);
|
||||
}
|
||||
|
||||
private int asciiToInt(final int ascii) {
|
||||
if (ascii >= 'A')
|
||||
return ascii - 0x37;
|
||||
|
||||
if (ascii >= '0')
|
||||
return ascii - '0';
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import no.nordicsemi.android.dfu.exception.HexFileValidationException;
|
||||
|
||||
/**
|
||||
* Reads the binary content from the HEX file using IntelHex standard: http://www.interlog.com/~speff/usefulinfo/Hexfrmt.pdf
|
||||
* Truncates the HEX file from all meta data and returns only the BIN content.
|
||||
* <p>
|
||||
* In nRF51 chips memory a SoftDevice starts at address 0x1000. From 0x0000 to 0x1000 there is MBR sector (since SoftDevice 7.0.0) which should not be transmitted using DFU. Therefore this class skips
|
||||
* all data from addresses below 0x1000.
|
||||
* </p>
|
||||
*/
|
||||
public class HexInputStream extends FilterInputStream {
|
||||
private final int LINE_LENGTH = 128;
|
||||
|
||||
private final byte[] localBuf;
|
||||
private int localPos;
|
||||
private int pos;
|
||||
private int size;
|
||||
private int lastAddress;
|
||||
private int available, bytesRead;
|
||||
private int MBRsize;
|
||||
|
||||
/**
|
||||
* Creates the HEX Input Stream. The constructor calculates the size of the BIN content which is available through {@link #sizeInBytes()}. If HEX file is invalid then the bin size is 0.
|
||||
*
|
||||
* @param in
|
||||
* the input stream to read from
|
||||
* @param trim
|
||||
* if <code>true</code> the bin data will be trimmed. All data from addresses < 0x1000 will be skipped. In the Soft Device 7.0.0 it's MBR space and this HEX fragment should not be
|
||||
* transmitted. However, other DFU implementations (f.e. without Soft Device) may require uploading the whole file.
|
||||
* @throws HexFileValidationException
|
||||
* if HEX file is invalid. F.e. there is no semicolon (':') on the beginning of each line.
|
||||
* @throws java.io.IOException
|
||||
* if the stream is closed or another IOException occurs.
|
||||
*/
|
||||
protected HexInputStream(final InputStream in, final int mbrSize) throws HexFileValidationException, IOException {
|
||||
super(new BufferedInputStream(in));
|
||||
this.localBuf = new byte[LINE_LENGTH];
|
||||
this.localPos = LINE_LENGTH; // we are at the end of the local buffer, new one must be obtained
|
||||
this.size = localBuf.length;
|
||||
this.lastAddress = 0;
|
||||
this.MBRsize = mbrSize;
|
||||
|
||||
this.available = calculateBinSize(mbrSize);
|
||||
}
|
||||
|
||||
protected HexInputStream(final byte[] data, final int mbrSize) throws HexFileValidationException, IOException {
|
||||
super(new ByteArrayInputStream(data));
|
||||
this.localBuf = new byte[LINE_LENGTH];
|
||||
this.localPos = LINE_LENGTH; // we are at the end of the local buffer, new one must be obtained
|
||||
this.size = localBuf.length;
|
||||
this.lastAddress = 0;
|
||||
this.MBRsize = mbrSize;
|
||||
|
||||
this.available = calculateBinSize(mbrSize);
|
||||
}
|
||||
|
||||
private int calculateBinSize(final int mbrSize) throws IOException {
|
||||
int binSize = 0;
|
||||
final InputStream in = this.in;
|
||||
in.mark(in.available());
|
||||
|
||||
int b, lineSize, offset, type;
|
||||
int lastBaseAddress = 0; // last Base Address, default 0
|
||||
int lastAddress = 0;
|
||||
try {
|
||||
b = in.read();
|
||||
while (true) {
|
||||
checkComma(b);
|
||||
|
||||
lineSize = readByte(in); // reading the length of the data in this line
|
||||
offset = readAddress(in);// reading the offset
|
||||
type = readByte(in); // reading the line type
|
||||
switch (type) {
|
||||
case 0x01:
|
||||
// end of file
|
||||
return binSize;
|
||||
case 0x04: {
|
||||
// extended linear address record
|
||||
/*
|
||||
* The HEX file may contain jump to different addresses. The MSB of LBA (Linear Base Address) is given using the line type 4.
|
||||
* We only support files where bytes are located together, no jumps are allowed. Therefore the newULBA may be only lastULBA + 1 (or any, if this is the first line of the HEX)
|
||||
*/
|
||||
final int newULBA = readAddress(in);
|
||||
if (binSize > 0 && newULBA != (lastBaseAddress >> 16) + 1)
|
||||
return binSize;
|
||||
lastBaseAddress = newULBA << 16;
|
||||
in.skip(2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
case 0x02: {
|
||||
// extended segment address record
|
||||
final int newSBA = readAddress(in) << 4;
|
||||
if (binSize > 0 && (newSBA >> 16) != (lastBaseAddress >> 16) + 1)
|
||||
return binSize;
|
||||
lastBaseAddress = newSBA;
|
||||
in.skip(2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
case 0x00:
|
||||
// data type line
|
||||
lastAddress = lastBaseAddress + offset;
|
||||
if (lastAddress >= mbrSize) // we must skip all data from below last MBR address (default 0x1000) as those are the MBR. The Soft Device starts at the end of MBR (0x1000), the app and bootloader farther more
|
||||
binSize += lineSize;
|
||||
// no break!
|
||||
default:
|
||||
in.skip(lineSize * 2 /* 2 hex per one byte */+ 2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
// skip end of line
|
||||
while (true) {
|
||||
b = in.read();
|
||||
|
||||
if (b != '\n' && b != '\r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
in.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return available - bytesRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the buffer with next bytes from the stream.
|
||||
*
|
||||
* @return the size of the buffer
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public int readPacket(byte[] buffer) throws HexFileValidationException, IOException {
|
||||
int i = 0;
|
||||
while (i < buffer.length) {
|
||||
if (localPos < size) {
|
||||
buffer[i++] = localBuf[localPos++];
|
||||
continue;
|
||||
}
|
||||
|
||||
bytesRead += size = readLine();
|
||||
if (size == 0)
|
||||
break; // end of file reached
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
throw new UnsupportedOperationException("Please, use readPacket() method instead");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
return readPacket(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer, int offset, int count) throws IOException {
|
||||
throw new UnsupportedOperationException("Please, use readPacket() method instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of bytes.
|
||||
*
|
||||
* @return total number of bytes available
|
||||
*/
|
||||
public int sizeInBytes() {
|
||||
return available;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of packets with given size that are needed to get all available data
|
||||
*
|
||||
* @param packetSize
|
||||
* the maximum packet size
|
||||
* @return the number of packets needed to get all the content
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public int sizeInPackets(final int packetSize) throws IOException {
|
||||
final int sizeInBytes = sizeInBytes();
|
||||
|
||||
return sizeInBytes / packetSize + ((sizeInBytes % packetSize) > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads new line from the input stream. Input stream must be a HEX file. The first line is always skipped.
|
||||
*
|
||||
* @return the number of data bytes in the new line. 0 if end of file.
|
||||
* @throws java.io.IOException
|
||||
* if this stream is closed or another IOException occurs.
|
||||
*/
|
||||
private int readLine() throws IOException {
|
||||
// end of file reached
|
||||
if (pos == -1)
|
||||
return 0;
|
||||
final InputStream in = this.in;
|
||||
|
||||
// temporary value
|
||||
int b = 0;
|
||||
|
||||
int lineSize, type, offset;
|
||||
do {
|
||||
// skip end of line
|
||||
while (true) {
|
||||
b = in.read();
|
||||
pos++;
|
||||
|
||||
if (b != '\n' && b != '\r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Each line starts with comma (':')
|
||||
* Data is written in HEX, so each 2 ASCII letters give one byte.
|
||||
* After the comma there is one byte (2 HEX signs) with line length (normally 10 -> 0x10 -> 16 bytes -> 32 HEX characters)
|
||||
* After that there is a 4 byte of an address. This part may be skipped.
|
||||
* There is a packet type after the address (1 byte = 2 HEX characters). 00 is the valid data. Other values can be skipped when
|
||||
* converting to BIN file.
|
||||
* Then goes n bytes of data followed by 1 byte (2 HEX chars) of checksum, which is also skipped in BIN file.
|
||||
*/
|
||||
checkComma(b); // checking the comma at the beginning
|
||||
lineSize = readByte(in); // reading the length of the data in this line
|
||||
pos += 2;
|
||||
offset = readAddress(in);// reading the offset
|
||||
pos += 4;
|
||||
type = readByte(in); // reading the line type
|
||||
pos += 2;
|
||||
|
||||
// if the line type is no longer data type (0x00), we've reached the end of the file
|
||||
switch (type) {
|
||||
case 0x00:
|
||||
// data type
|
||||
if (lastAddress + offset < MBRsize) { // skip MBR
|
||||
type = -1; // some other than 0
|
||||
pos += in.skip(lineSize * 2 /* 2 hex per one byte */+ 2 /* check sum */);
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
// end of file
|
||||
pos = -1;
|
||||
return 0;
|
||||
case 0x02: {
|
||||
// extended segment address
|
||||
final int address = readAddress(in) << 4;
|
||||
pos += 4;
|
||||
if (bytesRead > 0 && (address >> 16) != (lastAddress >> 16) + 1)
|
||||
return 0;
|
||||
lastAddress = address;
|
||||
pos += in.skip(2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
case 0x04: {
|
||||
// extended linear address
|
||||
final int address = readAddress(in);
|
||||
pos += 4;
|
||||
if (bytesRead > 0 && address != (lastAddress >> 16) + 1)
|
||||
return 0;
|
||||
lastAddress = address << 16;
|
||||
pos += in.skip(2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pos += in.skip(lineSize * 2 /* 2 hex per one byte */+ 2 /* check sum */);
|
||||
break;
|
||||
}
|
||||
} while (type != 0);
|
||||
|
||||
// otherwise read lineSize bytes or fill the whole buffer
|
||||
for (int i = 0; i < localBuf.length && i < lineSize; ++i) {
|
||||
b = readByte(in);
|
||||
pos += 2;
|
||||
localBuf[i] = (byte) b;
|
||||
}
|
||||
pos += in.skip(2); // skip the checksum
|
||||
localPos = 0;
|
||||
|
||||
return lineSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
super.reset();
|
||||
|
||||
pos = 0;
|
||||
bytesRead = 0;
|
||||
localPos = 0;
|
||||
}
|
||||
|
||||
private void checkComma(final int comma) throws HexFileValidationException {
|
||||
if (comma != ':')
|
||||
throw new HexFileValidationException("Not a HEX file");
|
||||
}
|
||||
|
||||
private int readByte(final InputStream in) throws IOException {
|
||||
final int first = asciiToInt(in.read());
|
||||
final int second = asciiToInt(in.read());
|
||||
|
||||
return first << 4 | second;
|
||||
}
|
||||
|
||||
private int readAddress(final InputStream in) throws IOException {
|
||||
return readByte(in) << 8 | readByte(in);
|
||||
}
|
||||
|
||||
private int asciiToInt(final int ascii) {
|
||||
if (ascii >= 'A')
|
||||
return ascii - 0x37;
|
||||
|
||||
if (ascii >= '0')
|
||||
return ascii - '0';
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -1,259 +1,259 @@
|
|||
package no.nordicsemi.android.dfu;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class ZipHexInputStream extends ZipInputStream {
|
||||
private static final String SOFTDEVICE_NAME = "softdevice.(hex|bin)";
|
||||
private static final String BOOTLOADER_NAME = "bootloader.(hex|bin)";
|
||||
private static final String APPLICATION_NAME = "application.(hex|bin)";
|
||||
private static final String SYSTEM_INIT = "system.dat";
|
||||
private static final String APPLICATION_INIT = "application.dat";
|
||||
|
||||
private byte[] softDeviceBytes;
|
||||
private byte[] bootloaderBytes;
|
||||
private byte[] applicationBytes;
|
||||
private byte[] systemInitBytes;
|
||||
private byte[] applicationInitBytes;
|
||||
private byte[] currentSource;
|
||||
private int bytesReadFromCurrentSource;
|
||||
private int softDeviceSize;
|
||||
private int bootloaderSize;
|
||||
private int applicationSize;
|
||||
private int bytesRead;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The {@link ZipHexInputStream} read HEX files from the Zip stream. It may skip some of them, depending on the value of types parameter. This is useful if the service wants to send the Soft
|
||||
* Device and Bootloader only, and then Application in the next connection despite that ZIP file contains all 3 HEX files. When types is equal to {@link DfuBaseService#TYPE_AUTO} all present files
|
||||
* are read.
|
||||
* </p>
|
||||
* <p>
|
||||
* Use bit combination of the following types:
|
||||
* <ul>
|
||||
* <li>{@link DfuBaseService#TYPE_SOFT_DEVICE}</li>
|
||||
* <li>{@link DfuBaseService#TYPE_BOOTLOADER}</li>
|
||||
* <li>{@link DfuBaseService#TYPE_APPLICATION}</li>
|
||||
* <li>{@link DfuBaseService#TYPE_AUTO}</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param stream
|
||||
* the Zip Input Stream
|
||||
* @param types
|
||||
* files to read
|
||||
* @param trim
|
||||
* if <code>true</code> the bin data will be trimmed. All data from addresses < 0x1000 will be skipped. In the Soft Device 7.0.0 it's MBR space and this HEX fragment should not be
|
||||
* transmitted. However, other DFU implementations (f.e. without Soft Device) may require uploading the whole file.
|
||||
* @throws IOException
|
||||
*/
|
||||
public ZipHexInputStream(final InputStream stream, final int mbrSize, final int types) throws IOException {
|
||||
super(stream);
|
||||
|
||||
this.bytesRead = 0;
|
||||
this.bytesReadFromCurrentSource = 0;
|
||||
|
||||
try {
|
||||
ZipEntry ze;
|
||||
while ((ze = getNextEntry()) != null) {
|
||||
final String filename = ze.getName();
|
||||
final boolean softDevice = filename.matches(SOFTDEVICE_NAME);
|
||||
final boolean bootloader = filename.matches(BOOTLOADER_NAME);
|
||||
final boolean application = filename.matches(APPLICATION_NAME);
|
||||
final boolean systemInit = filename.matches(SYSTEM_INIT);
|
||||
final boolean applicationInit = filename.matches(APPLICATION_INIT);
|
||||
if (ze.isDirectory() || !(softDevice || bootloader || application || systemInit || applicationInit))
|
||||
throw new IOException("ZIP content not supported. Only " + SOFTDEVICE_NAME + ", " + BOOTLOADER_NAME + ", " + APPLICATION_NAME + ", " + SYSTEM_INIT + " or " + APPLICATION_INIT
|
||||
+ " are allowed.");
|
||||
|
||||
// Skip files that are not specified in 'types'
|
||||
if (types != DfuBaseService.TYPE_AUTO && (
|
||||
((softDevice || systemInit) && (types & DfuBaseService.TYPE_SOFT_DEVICE) == 0) ||
|
||||
((bootloader || systemInit) && (types & DfuBaseService.TYPE_BOOTLOADER) == 0) ||
|
||||
((application || applicationInit) && (types & DfuBaseService.TYPE_APPLICATION) == 0))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read file content to byte array
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
final byte[] buffer = new byte[1024];
|
||||
int count;
|
||||
while ((count = super.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, count);
|
||||
}
|
||||
byte[] source = baos.toByteArray();
|
||||
|
||||
// Create HexInputStream from bytes and copy BIN content to arrays
|
||||
if (softDevice) {
|
||||
if (filename.endsWith("hex")) {
|
||||
final HexInputStream is = new HexInputStream(source, mbrSize);
|
||||
source = softDeviceBytes = new byte[softDeviceSize = is.available()];
|
||||
is.read(softDeviceBytes);
|
||||
is.close();
|
||||
} else {
|
||||
softDeviceBytes = source;
|
||||
softDeviceSize = source.length;
|
||||
}
|
||||
// upload must always start from Soft Device
|
||||
currentSource = source;
|
||||
} else if (bootloader) {
|
||||
if (filename.endsWith("hex")) {
|
||||
final HexInputStream is = new HexInputStream(source, mbrSize);
|
||||
source = bootloaderBytes = new byte[bootloaderSize = is.available()];
|
||||
is.read(bootloaderBytes);
|
||||
is.close();
|
||||
} else {
|
||||
bootloaderBytes = source;
|
||||
bootloaderSize = source.length;
|
||||
}
|
||||
// If the current source is null or application, switch it to the bootloader
|
||||
if (currentSource == applicationBytes)
|
||||
currentSource = source;
|
||||
} else if (application) {
|
||||
if (filename.endsWith("hex")) {
|
||||
final HexInputStream is = new HexInputStream(source, mbrSize);
|
||||
source = applicationBytes = new byte[applicationSize = is.available()];
|
||||
is.read(applicationBytes);
|
||||
is.close();
|
||||
} else {
|
||||
applicationBytes = source;
|
||||
applicationSize = source.length;
|
||||
}
|
||||
// Temporarily set the current source to application, it may be overwritten in a moment
|
||||
if (currentSource == null)
|
||||
currentSource = source;
|
||||
} else if (systemInit) {
|
||||
systemInitBytes = source;
|
||||
} else if (applicationInit) {
|
||||
applicationInitBytes = source;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
softDeviceBytes = null;
|
||||
bootloaderBytes = null;
|
||||
softDeviceBytes = null;
|
||||
softDeviceSize = bootloaderSize = applicationSize = 0;
|
||||
currentSource = null;
|
||||
bytesRead = bytesReadFromCurrentSource = 0;
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(final byte[] buffer) throws IOException {
|
||||
int maxSize = currentSource.length - bytesReadFromCurrentSource;
|
||||
int size = buffer.length <= maxSize ? buffer.length : maxSize;
|
||||
System.arraycopy(currentSource, bytesReadFromCurrentSource, buffer, 0, size);
|
||||
bytesReadFromCurrentSource += size;
|
||||
if (buffer.length > size) {
|
||||
if (startNextFile() == null) {
|
||||
bytesRead += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
maxSize = currentSource.length;
|
||||
final int nextSize = buffer.length - size <= maxSize ? buffer.length - size : maxSize;
|
||||
System.arraycopy(currentSource, 0, buffer, size, nextSize);
|
||||
bytesReadFromCurrentSource += nextSize;
|
||||
size += nextSize;
|
||||
}
|
||||
bytesRead += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content type based on the content of the ZIP file. The content type may be truncated using {@link #setContentType(int)}.
|
||||
*
|
||||
* @return a bit field of {@link DfuBaseService#TYPE_SOFT_DEVICE TYPE_SOFT_DEVICE}, {@link DfuBaseService#TYPE_BOOTLOADER TYPE_BOOTLOADER} and {@link DfuBaseService#TYPE_APPLICATION
|
||||
* TYPE_APPLICATION}
|
||||
*/
|
||||
public int getContentType() {
|
||||
byte b = 0;
|
||||
if (softDeviceSize > 0)
|
||||
b |= DfuBaseService.TYPE_SOFT_DEVICE;
|
||||
if (bootloaderSize > 0)
|
||||
b |= DfuBaseService.TYPE_BOOTLOADER;
|
||||
if (applicationSize > 0)
|
||||
b |= DfuBaseService.TYPE_APPLICATION;
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the current content type. May be used to hide some files, f.e. to send Soft Device and Bootloader without Application or only the Application.
|
||||
*
|
||||
* @param type
|
||||
* the new type
|
||||
* @return the final type after truncating
|
||||
*/
|
||||
public int setContentType(final int type) {
|
||||
if (bytesRead > 0)
|
||||
throw new UnsupportedOperationException("Content type must not be change after reading content");
|
||||
|
||||
final int t = getContentType() & type;
|
||||
|
||||
if ((t & DfuBaseService.TYPE_SOFT_DEVICE) == 0) {
|
||||
softDeviceBytes = null;
|
||||
softDeviceSize = 0;
|
||||
}
|
||||
if ((t & DfuBaseService.TYPE_BOOTLOADER) == 0) {
|
||||
bootloaderBytes = null;
|
||||
bootloaderSize = 0;
|
||||
}
|
||||
if ((t & DfuBaseService.TYPE_APPLICATION) == 0) {
|
||||
applicationBytes = null;
|
||||
applicationSize = 0;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currentSource to the new file or to <code>null</code> if the last file has been transmitted.
|
||||
*
|
||||
* @return the new source, the same as {@link #currentSource}
|
||||
*/
|
||||
private byte[] startNextFile() {
|
||||
byte[] ret = null;
|
||||
if (currentSource == softDeviceBytes && bootloaderBytes != null) {
|
||||
ret = currentSource = bootloaderBytes;
|
||||
} else if (currentSource != applicationBytes && applicationBytes != null) {
|
||||
ret = currentSource = applicationBytes;
|
||||
} else {
|
||||
ret = currentSource = null;
|
||||
}
|
||||
bytesReadFromCurrentSource = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return softDeviceSize + bootloaderSize + applicationSize - bytesRead;
|
||||
}
|
||||
|
||||
public int softDeviceImageSize() {
|
||||
return softDeviceSize;
|
||||
}
|
||||
|
||||
public int bootloaderImageSize() {
|
||||
return bootloaderSize;
|
||||
}
|
||||
|
||||
public int applicationImageSize() {
|
||||
return applicationSize;
|
||||
}
|
||||
|
||||
public byte[] getSystemInit() {
|
||||
return systemInitBytes;
|
||||
}
|
||||
|
||||
public byte[] getApplicationInit() {
|
||||
return applicationInitBytes;
|
||||
}
|
||||
}
|
||||
package no.nordicsemi.android.dfu;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class ZipHexInputStream extends ZipInputStream {
|
||||
private static final String SOFTDEVICE_NAME = "softdevice.(hex|bin)";
|
||||
private static final String BOOTLOADER_NAME = "bootloader.(hex|bin)";
|
||||
private static final String APPLICATION_NAME = "application.(hex|bin)";
|
||||
private static final String SYSTEM_INIT = "system.dat";
|
||||
private static final String APPLICATION_INIT = "application.dat";
|
||||
|
||||
private byte[] softDeviceBytes;
|
||||
private byte[] bootloaderBytes;
|
||||
private byte[] applicationBytes;
|
||||
private byte[] systemInitBytes;
|
||||
private byte[] applicationInitBytes;
|
||||
private byte[] currentSource;
|
||||
private int bytesReadFromCurrentSource;
|
||||
private int softDeviceSize;
|
||||
private int bootloaderSize;
|
||||
private int applicationSize;
|
||||
private int bytesRead;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The {@link no.nordicsemi.android.dfu.ZipHexInputStream} read HEX files from the Zip stream. It may skip some of them, depending on the value of types parameter. This is useful if the service wants to send the Soft
|
||||
* Device and Bootloader only, and then Application in the next connection despite that ZIP file contains all 3 HEX files. When types is equal to {@link DfuBaseService#TYPE_AUTO} all present files
|
||||
* are read.
|
||||
* </p>
|
||||
* <p>
|
||||
* Use bit combination of the following types:
|
||||
* <ul>
|
||||
* <li>{@link DfuBaseService#TYPE_SOFT_DEVICE}</li>
|
||||
* <li>{@link DfuBaseService#TYPE_BOOTLOADER}</li>
|
||||
* <li>{@link DfuBaseService#TYPE_APPLICATION}</li>
|
||||
* <li>{@link DfuBaseService#TYPE_AUTO}</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param stream
|
||||
* the Zip Input Stream
|
||||
* @param types
|
||||
* files to read
|
||||
* @param trim
|
||||
* if <code>true</code> the bin data will be trimmed. All data from addresses < 0x1000 will be skipped. In the Soft Device 7.0.0 it's MBR space and this HEX fragment should not be
|
||||
* transmitted. However, other DFU implementations (f.e. without Soft Device) may require uploading the whole file.
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public ZipHexInputStream(final InputStream stream, final int mbrSize, final int types) throws IOException {
|
||||
super(stream);
|
||||
|
||||
this.bytesRead = 0;
|
||||
this.bytesReadFromCurrentSource = 0;
|
||||
|
||||
try {
|
||||
ZipEntry ze;
|
||||
while ((ze = getNextEntry()) != null) {
|
||||
final String filename = ze.getName();
|
||||
final boolean softDevice = filename.matches(SOFTDEVICE_NAME);
|
||||
final boolean bootloader = filename.matches(BOOTLOADER_NAME);
|
||||
final boolean application = filename.matches(APPLICATION_NAME);
|
||||
final boolean systemInit = filename.matches(SYSTEM_INIT);
|
||||
final boolean applicationInit = filename.matches(APPLICATION_INIT);
|
||||
if (ze.isDirectory() || !(softDevice || bootloader || application || systemInit || applicationInit))
|
||||
throw new IOException("ZIP content not supported. Only " + SOFTDEVICE_NAME + ", " + BOOTLOADER_NAME + ", " + APPLICATION_NAME + ", " + SYSTEM_INIT + " or " + APPLICATION_INIT
|
||||
+ " are allowed.");
|
||||
|
||||
// Skip files that are not specified in 'types'
|
||||
if (types != DfuBaseService.TYPE_AUTO && (
|
||||
((softDevice || systemInit) && (types & DfuBaseService.TYPE_SOFT_DEVICE) == 0) ||
|
||||
((bootloader || systemInit) && (types & DfuBaseService.TYPE_BOOTLOADER) == 0) ||
|
||||
((application || applicationInit) && (types & DfuBaseService.TYPE_APPLICATION) == 0))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read file content to byte array
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
final byte[] buffer = new byte[1024];
|
||||
int count;
|
||||
while ((count = super.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, count);
|
||||
}
|
||||
byte[] source = baos.toByteArray();
|
||||
|
||||
// Create HexInputStream from bytes and copy BIN content to arrays
|
||||
if (softDevice) {
|
||||
if (filename.endsWith("hex")) {
|
||||
final HexInputStream is = new HexInputStream(source, mbrSize);
|
||||
source = softDeviceBytes = new byte[softDeviceSize = is.available()];
|
||||
is.read(softDeviceBytes);
|
||||
is.close();
|
||||
} else {
|
||||
softDeviceBytes = source;
|
||||
softDeviceSize = source.length;
|
||||
}
|
||||
// upload must always start from Soft Device
|
||||
currentSource = source;
|
||||
} else if (bootloader) {
|
||||
if (filename.endsWith("hex")) {
|
||||
final HexInputStream is = new HexInputStream(source, mbrSize);
|
||||
source = bootloaderBytes = new byte[bootloaderSize = is.available()];
|
||||
is.read(bootloaderBytes);
|
||||
is.close();
|
||||
} else {
|
||||
bootloaderBytes = source;
|
||||
bootloaderSize = source.length;
|
||||
}
|
||||
// If the current source is null or application, switch it to the bootloader
|
||||
if (currentSource == applicationBytes)
|
||||
currentSource = source;
|
||||
} else if (application) {
|
||||
if (filename.endsWith("hex")) {
|
||||
final HexInputStream is = new HexInputStream(source, mbrSize);
|
||||
source = applicationBytes = new byte[applicationSize = is.available()];
|
||||
is.read(applicationBytes);
|
||||
is.close();
|
||||
} else {
|
||||
applicationBytes = source;
|
||||
applicationSize = source.length;
|
||||
}
|
||||
// Temporarily set the current source to application, it may be overwritten in a moment
|
||||
if (currentSource == null)
|
||||
currentSource = source;
|
||||
} else if (systemInit) {
|
||||
systemInitBytes = source;
|
||||
} else if (applicationInit) {
|
||||
applicationInitBytes = source;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
softDeviceBytes = null;
|
||||
bootloaderBytes = null;
|
||||
softDeviceBytes = null;
|
||||
softDeviceSize = bootloaderSize = applicationSize = 0;
|
||||
currentSource = null;
|
||||
bytesRead = bytesReadFromCurrentSource = 0;
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(final byte[] buffer) throws IOException {
|
||||
int maxSize = currentSource.length - bytesReadFromCurrentSource;
|
||||
int size = buffer.length <= maxSize ? buffer.length : maxSize;
|
||||
System.arraycopy(currentSource, bytesReadFromCurrentSource, buffer, 0, size);
|
||||
bytesReadFromCurrentSource += size;
|
||||
if (buffer.length > size) {
|
||||
if (startNextFile() == null) {
|
||||
bytesRead += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
maxSize = currentSource.length;
|
||||
final int nextSize = buffer.length - size <= maxSize ? buffer.length - size : maxSize;
|
||||
System.arraycopy(currentSource, 0, buffer, size, nextSize);
|
||||
bytesReadFromCurrentSource += nextSize;
|
||||
size += nextSize;
|
||||
}
|
||||
bytesRead += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content type based on the content of the ZIP file. The content type may be truncated using {@link #setContentType(int)}.
|
||||
*
|
||||
* @return a bit field of {@link DfuBaseService#TYPE_SOFT_DEVICE TYPE_SOFT_DEVICE}, {@link DfuBaseService#TYPE_BOOTLOADER TYPE_BOOTLOADER} and {@link DfuBaseService#TYPE_APPLICATION
|
||||
* TYPE_APPLICATION}
|
||||
*/
|
||||
public int getContentType() {
|
||||
byte b = 0;
|
||||
if (softDeviceSize > 0)
|
||||
b |= DfuBaseService.TYPE_SOFT_DEVICE;
|
||||
if (bootloaderSize > 0)
|
||||
b |= DfuBaseService.TYPE_BOOTLOADER;
|
||||
if (applicationSize > 0)
|
||||
b |= DfuBaseService.TYPE_APPLICATION;
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the current content type. May be used to hide some files, f.e. to send Soft Device and Bootloader without Application or only the Application.
|
||||
*
|
||||
* @param type
|
||||
* the new type
|
||||
* @return the final type after truncating
|
||||
*/
|
||||
public int setContentType(final int type) {
|
||||
if (bytesRead > 0)
|
||||
throw new UnsupportedOperationException("Content type must not be change after reading content");
|
||||
|
||||
final int t = getContentType() & type;
|
||||
|
||||
if ((t & DfuBaseService.TYPE_SOFT_DEVICE) == 0) {
|
||||
softDeviceBytes = null;
|
||||
softDeviceSize = 0;
|
||||
}
|
||||
if ((t & DfuBaseService.TYPE_BOOTLOADER) == 0) {
|
||||
bootloaderBytes = null;
|
||||
bootloaderSize = 0;
|
||||
}
|
||||
if ((t & DfuBaseService.TYPE_APPLICATION) == 0) {
|
||||
applicationBytes = null;
|
||||
applicationSize = 0;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currentSource to the new file or to <code>null</code> if the last file has been transmitted.
|
||||
*
|
||||
* @return the new source, the same as {@link #currentSource}
|
||||
*/
|
||||
private byte[] startNextFile() {
|
||||
byte[] ret = null;
|
||||
if (currentSource == softDeviceBytes && bootloaderBytes != null) {
|
||||
ret = currentSource = bootloaderBytes;
|
||||
} else if (currentSource != applicationBytes && applicationBytes != null) {
|
||||
ret = currentSource = applicationBytes;
|
||||
} else {
|
||||
ret = currentSource = null;
|
||||
}
|
||||
bytesReadFromCurrentSource = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return softDeviceSize + bootloaderSize + applicationSize - bytesRead;
|
||||
}
|
||||
|
||||
public int softDeviceImageSize() {
|
||||
return softDeviceSize;
|
||||
}
|
||||
|
||||
public int bootloaderImageSize() {
|
||||
return bootloaderSize;
|
||||
}
|
||||
|
||||
public int applicationImageSize() {
|
||||
return applicationSize;
|
||||
}
|
||||
|
||||
public byte[] getSystemInit() {
|
||||
return systemInitBytes;
|
||||
}
|
||||
|
||||
public byte[] getApplicationInit() {
|
||||
return applicationInitBytes;
|
||||
}
|
||||
}
|
|
@ -1,30 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
public class DeviceDisconnectedException extends Exception {
|
||||
private static final long serialVersionUID = -6901728550661937942L;
|
||||
|
||||
private final int mState;
|
||||
|
||||
public DeviceDisconnectedException(final String message, final int state) {
|
||||
super(message);
|
||||
|
||||
mState = state;
|
||||
}
|
||||
|
||||
public int getConnectionState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage() + " (connection state: " + mState + ")";
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
public class DeviceDisconnectedException extends Exception {
|
||||
private static final long serialVersionUID = -6901728550661937942L;
|
||||
|
||||
private final int mState;
|
||||
|
||||
public DeviceDisconnectedException(final String message, final int state) {
|
||||
super(message);
|
||||
|
||||
mState = state;
|
||||
}
|
||||
|
||||
public int getConnectionState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage() + " (connection state: " + mState + ")";
|
||||
}
|
||||
}
|
|
@ -1,32 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
import no.nordicsemi.android.dfu.DfuBaseService;
|
||||
|
||||
public class DfuException extends Exception {
|
||||
private static final long serialVersionUID = -6901728550661937942L;
|
||||
|
||||
private final int mError;
|
||||
|
||||
public DfuException(final String message, final int state) {
|
||||
super(message);
|
||||
|
||||
mError = state;
|
||||
}
|
||||
|
||||
public int getErrorNumber() {
|
||||
return mError;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage() + " (error " + (mError & ~DfuBaseService.ERROR_CONNECTION_MASK) + ")";
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
import no.nordicsemi.android.dfu.DfuBaseService;
|
||||
|
||||
public class DfuException extends Exception {
|
||||
private static final long serialVersionUID = -6901728550661937942L;
|
||||
|
||||
private final int mError;
|
||||
|
||||
public DfuException(final String message, final int state) {
|
||||
super(message);
|
||||
|
||||
mError = state;
|
||||
}
|
||||
|
||||
public int getErrorNumber() {
|
||||
return mError;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage() + " (error " + (mError & ~DfuBaseService.ERROR_CONNECTION_MASK) + ")";
|
||||
}
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class HexFileValidationException extends IOException {
|
||||
private static final long serialVersionUID = -6467104024030837875L;
|
||||
|
||||
public HexFileValidationException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class HexFileValidationException extends IOException {
|
||||
private static final long serialVersionUID = -6467104024030837875L;
|
||||
|
||||
public HexFileValidationException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -1,30 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
public class RemoteDfuException extends Exception {
|
||||
private static final long serialVersionUID = -6901728550661937942L;
|
||||
|
||||
private final int mState;
|
||||
|
||||
public RemoteDfuException(final String message, final int state) {
|
||||
super(message);
|
||||
|
||||
mState = state;
|
||||
}
|
||||
|
||||
public int getErrorNumber() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage() + " (error " + mState + ")";
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
public class RemoteDfuException extends Exception {
|
||||
private static final long serialVersionUID = -6901728550661937942L;
|
||||
|
||||
private final int mState;
|
||||
|
||||
public RemoteDfuException(final String message, final int state) {
|
||||
super(message);
|
||||
|
||||
mState = state;
|
||||
}
|
||||
|
||||
public int getErrorNumber() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage() + " (error " + mState + ")";
|
||||
}
|
||||
}
|
|
@ -1,43 +1,43 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
public class UnknownResponseException extends Exception {
|
||||
private static final long serialVersionUID = -8716125467309979289L;
|
||||
private static final char[] HEX_ARRAY = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
private final byte[] mResponse;
|
||||
private final int mExpectedOpCode;
|
||||
|
||||
public UnknownResponseException(final String message, final byte[] response, final int expectedOpCode) {
|
||||
super(message);
|
||||
|
||||
mResponse = response != null ? response : new byte[0];
|
||||
mExpectedOpCode = expectedOpCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return String.format("%s (response: %s, expected: 0x10%02X..)", super.getMessage(), bytesToHex(mResponse, 0, mResponse.length), mExpectedOpCode);
|
||||
}
|
||||
|
||||
public static String bytesToHex(final byte[] bytes, final int start, final int length) {
|
||||
if (bytes == null || bytes.length <= start || length <= 0)
|
||||
return "";
|
||||
|
||||
final int maxLength = Math.min(length, bytes.length - start);
|
||||
final char[] hexChars = new char[maxLength * 2];
|
||||
for (int j = 0; j < maxLength; j++) {
|
||||
final int v = bytes[start + j] & 0xFF;
|
||||
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
|
||||
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
|
||||
}
|
||||
return "0x" + new String(hexChars);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
public class UnknownResponseException extends Exception {
|
||||
private static final long serialVersionUID = -8716125467309979289L;
|
||||
private static final char[] HEX_ARRAY = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
private final byte[] mResponse;
|
||||
private final int mExpectedOpCode;
|
||||
|
||||
public UnknownResponseException(final String message, final byte[] response, final int expectedOpCode) {
|
||||
super(message);
|
||||
|
||||
mResponse = response != null ? response : new byte[0];
|
||||
mExpectedOpCode = expectedOpCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return String.format("%s (response: %s, expected: 0x10%02X..)", super.getMessage(), bytesToHex(mResponse, 0, mResponse.length), mExpectedOpCode);
|
||||
}
|
||||
|
||||
public static String bytesToHex(final byte[] bytes, final int start, final int length) {
|
||||
if (bytes == null || bytes.length <= start || length <= 0)
|
||||
return "";
|
||||
|
||||
final int maxLength = Math.min(length, bytes.length - start);
|
||||
final char[] hexChars = new char[maxLength * 2];
|
||||
for (int j = 0; j < maxLength; j++) {
|
||||
final int v = bytes[start + j] & 0xFF;
|
||||
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
|
||||
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
|
||||
}
|
||||
return "0x" + new String(hexChars);
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
public class UploadAbortedException extends Exception {
|
||||
private static final long serialVersionUID = -6901728550661937942L;
|
||||
|
||||
public UploadAbortedException() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.dfu.exception;
|
||||
|
||||
public class UploadAbortedException extends Exception {
|
||||
private static final long serialVersionUID = -6901728550661937942L;
|
||||
|
||||
public UploadAbortedException() {
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -1,123 +1,123 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.error;
|
||||
|
||||
import no.nordicsemi.android.dfu.DfuBaseService;
|
||||
|
||||
public class GattError {
|
||||
|
||||
public static String parse(final int error) {
|
||||
switch (error) {
|
||||
case 0x0001:
|
||||
return "GATT INVALID HANDLE";
|
||||
case 0x0002:
|
||||
return "GATT READ NOT PERMIT";
|
||||
case 0x0003:
|
||||
return "GATT WRITE NOT PERMIT";
|
||||
case 0x0004:
|
||||
return "GATT INVALID PDU";
|
||||
case 0x0005:
|
||||
return "GATT INSUF AUTHENTICATION";
|
||||
case 0x0006:
|
||||
return "GATT REQ NOT SUPPORTED";
|
||||
case 0x0007:
|
||||
return "GATT INVALID OFFSET";
|
||||
case 0x0008:
|
||||
return "GATT INSUF AUTHORIZATION";
|
||||
case 0x0009:
|
||||
return "GATT PREPARE Q FULL";
|
||||
case 0x000a:
|
||||
return "GATT NOT FOUND";
|
||||
case 0x000b:
|
||||
return "GATT NOT LONG";
|
||||
case 0x000c:
|
||||
return "GATT INSUF KEY SIZE";
|
||||
case 0x000d:
|
||||
return "GATT INVALID ATTR LEN";
|
||||
case 0x000e:
|
||||
return "GATT ERR UNLIKELY";
|
||||
case 0x000f:
|
||||
return "GATT INSUF ENCRYPTION";
|
||||
case 0x0010:
|
||||
return "GATT UNSUPPORT GRP TYPE";
|
||||
case 0x0011:
|
||||
return "GATT INSUF RESOURCE";
|
||||
case 0x0087:
|
||||
return "GATT ILLEGAL PARAMETER";
|
||||
case 0x0080:
|
||||
return "GATT NO RESOURCES";
|
||||
case 0x0081:
|
||||
return "GATT INTERNAL ERROR";
|
||||
case 0x0082:
|
||||
return "GATT WRONG STATE";
|
||||
case 0x0083:
|
||||
return "GATT DB FULL";
|
||||
case 0x0084:
|
||||
return "GATT BUSY";
|
||||
case 0x0085:
|
||||
return "GATT ERROR";
|
||||
case 0x0086:
|
||||
return "GATT CMD STARTED";
|
||||
case 0x0088:
|
||||
return "GATT PENDING";
|
||||
case 0x0089:
|
||||
return "GATT AUTH FAIL";
|
||||
case 0x008a:
|
||||
return "GATT MORE";
|
||||
case 0x008b:
|
||||
return "GATT INVALID CFG";
|
||||
case 0x008c:
|
||||
return "GATT SERVICE STARTED";
|
||||
case 0x008d:
|
||||
return "GATT ENCRYPED NO MITM";
|
||||
case 0x008e:
|
||||
return "GATT NOT ENCRYPTED";
|
||||
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:
|
||||
return "DFU FILE ERROR";
|
||||
case DfuBaseService.ERROR_FILE_INVALID:
|
||||
return "DFU NOT A VALID HEX FILE";
|
||||
case DfuBaseService.ERROR_FILE_IO_EXCEPTION:
|
||||
return "DFU IO EXCEPTION";
|
||||
case DfuBaseService.ERROR_FILE_NOT_FOUND:
|
||||
return "DFU FILE NOT FOUND";
|
||||
case DfuBaseService.ERROR_SERVICE_DISCOVERY_NOT_STARTED:
|
||||
return "DFU ERROR WHILE SERVICE DISCOVERY";
|
||||
case DfuBaseService.ERROR_SERVICE_NOT_FOUND:
|
||||
return "DFU SERVICE NOT FOUND";
|
||||
case DfuBaseService.ERROR_CHARACTERISTICS_NOT_FOUND:
|
||||
return "DFU CHARACTERISTICS NOT FOUND";
|
||||
case DfuBaseService.ERROR_FILE_TYPE_UNSUPPORTED:
|
||||
return "DFU FILE TYPE NOT SUPPORTED";
|
||||
case DfuBaseService.ERROR_BLUETOOTH_DISABLED:
|
||||
return "BLUETOOTH ADAPTER DISABLED";
|
||||
default:
|
||||
if ((DfuBaseService.ERROR_REMOTE_MASK & error) > 0) {
|
||||
switch (error & (~DfuBaseService.ERROR_REMOTE_MASK)) {
|
||||
case DfuBaseService.DFU_STATUS_INVALID_STATE:
|
||||
return "REMOTE DFU INVALID STATE";
|
||||
case DfuBaseService.DFU_STATUS_NOT_SUPPORTED:
|
||||
return "REMOTE DFU NOT SUPPORTED";
|
||||
case DfuBaseService.DFU_STATUS_DATA_SIZE_EXCEEDS_LIMIT:
|
||||
return "REMOTE DFU DATA SIZE EXCEEDS LIMIT";
|
||||
case DfuBaseService.DFU_STATUS_CRC_ERROR:
|
||||
return "REMOTE DFU INVALID CRC ERROR";
|
||||
case DfuBaseService.DFU_STATUS_OPERATION_FAILED:
|
||||
return "REMOTE DFU OPERATION FAILED";
|
||||
}
|
||||
}
|
||||
return "UNKNOWN (" + error + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
|
||||
* This heading must NOT be removed from the file.
|
||||
******************************************************************************/
|
||||
package no.nordicsemi.android.error;
|
||||
|
||||
import no.nordicsemi.android.dfu.DfuBaseService;
|
||||
|
||||
public class GattError {
|
||||
|
||||
public static String parse(final int error) {
|
||||
switch (error) {
|
||||
case 0x0001:
|
||||
return "GATT INVALID HANDLE";
|
||||
case 0x0002:
|
||||
return "GATT READ NOT PERMIT";
|
||||
case 0x0003:
|
||||
return "GATT WRITE NOT PERMIT";
|
||||
case 0x0004:
|
||||
return "GATT INVALID PDU";
|
||||
case 0x0005:
|
||||
return "GATT INSUF AUTHENTICATION";
|
||||
case 0x0006:
|
||||
return "GATT REQ NOT SUPPORTED";
|
||||
case 0x0007:
|
||||
return "GATT INVALID OFFSET";
|
||||
case 0x0008:
|
||||
return "GATT INSUF AUTHORIZATION";
|
||||
case 0x0009:
|
||||
return "GATT PREPARE Q FULL";
|
||||
case 0x000a:
|
||||
return "GATT NOT FOUND";
|
||||
case 0x000b:
|
||||
return "GATT NOT LONG";
|
||||
case 0x000c:
|
||||
return "GATT INSUF KEY SIZE";
|
||||
case 0x000d:
|
||||
return "GATT INVALID ATTR LEN";
|
||||
case 0x000e:
|
||||
return "GATT ERR UNLIKELY";
|
||||
case 0x000f:
|
||||
return "GATT INSUF ENCRYPTION";
|
||||
case 0x0010:
|
||||
return "GATT UNSUPPORT GRP TYPE";
|
||||
case 0x0011:
|
||||
return "GATT INSUF RESOURCE";
|
||||
case 0x0087:
|
||||
return "GATT ILLEGAL PARAMETER";
|
||||
case 0x0080:
|
||||
return "GATT NO RESOURCES";
|
||||
case 0x0081:
|
||||
return "GATT INTERNAL ERROR";
|
||||
case 0x0082:
|
||||
return "GATT WRONG STATE";
|
||||
case 0x0083:
|
||||
return "GATT DB FULL";
|
||||
case 0x0084:
|
||||
return "GATT BUSY";
|
||||
case 0x0085:
|
||||
return "GATT ERROR";
|
||||
case 0x0086:
|
||||
return "GATT CMD STARTED";
|
||||
case 0x0088:
|
||||
return "GATT PENDING";
|
||||
case 0x0089:
|
||||
return "GATT AUTH FAIL";
|
||||
case 0x008a:
|
||||
return "GATT MORE";
|
||||
case 0x008b:
|
||||
return "GATT INVALID CFG";
|
||||
case 0x008c:
|
||||
return "GATT SERVICE STARTED";
|
||||
case 0x008d:
|
||||
return "GATT ENCRYPED NO MITM";
|
||||
case 0x008e:
|
||||
return "GATT NOT ENCRYPTED";
|
||||
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:
|
||||
return "DFU FILE ERROR";
|
||||
case DfuBaseService.ERROR_FILE_INVALID:
|
||||
return "DFU NOT A VALID HEX FILE";
|
||||
case DfuBaseService.ERROR_FILE_IO_EXCEPTION:
|
||||
return "DFU IO EXCEPTION";
|
||||
case DfuBaseService.ERROR_FILE_NOT_FOUND:
|
||||
return "DFU FILE NOT FOUND";
|
||||
case DfuBaseService.ERROR_SERVICE_DISCOVERY_NOT_STARTED:
|
||||
return "DFU ERROR WHILE SERVICE DISCOVERY";
|
||||
case DfuBaseService.ERROR_SERVICE_NOT_FOUND:
|
||||
return "DFU SERVICE NOT FOUND";
|
||||
case DfuBaseService.ERROR_CHARACTERISTICS_NOT_FOUND:
|
||||
return "DFU CHARACTERISTICS NOT FOUND";
|
||||
case DfuBaseService.ERROR_FILE_TYPE_UNSUPPORTED:
|
||||
return "DFU FILE TYPE NOT SUPPORTED";
|
||||
case DfuBaseService.ERROR_BLUETOOTH_DISABLED:
|
||||
return "BLUETOOTH ADAPTER DISABLED";
|
||||
default:
|
||||
if ((DfuBaseService.ERROR_REMOTE_MASK & error) > 0) {
|
||||
switch (error & (~DfuBaseService.ERROR_REMOTE_MASK)) {
|
||||
case DfuBaseService.DFU_STATUS_INVALID_STATE:
|
||||
return "REMOTE DFU INVALID STATE";
|
||||
case DfuBaseService.DFU_STATUS_NOT_SUPPORTED:
|
||||
return "REMOTE DFU NOT SUPPORTED";
|
||||
case DfuBaseService.DFU_STATUS_DATA_SIZE_EXCEEDS_LIMIT:
|
||||
return "REMOTE DFU DATA SIZE EXCEEDS LIMIT";
|
||||
case DfuBaseService.DFU_STATUS_CRC_ERROR:
|
||||
return "REMOTE DFU INVALID CRC ERROR";
|
||||
case DfuBaseService.DFU_STATUS_OPERATION_FAILED:
|
||||
return "REMOTE DFU OPERATION FAILED";
|
||||
}
|
||||
}
|
||||
return "UNKNOWN (" + error + ")";
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 353 B After Width: | Height: | Size: 353 B |
Before Width: | Height: | Size: 993 B After Width: | Height: | Size: 993 B |
Before Width: | Height: | Size: 415 B After Width: | Height: | Size: 415 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
@ -1,31 +1,31 @@
|
|||
<resources>
|
||||
|
||||
<string name="dfu_unknown_name">unnamed device</string>
|
||||
|
||||
<string name="dfu_action_abort">Abort</string>
|
||||
|
||||
<string name="dfu_status_initializing">Initializing…</string>
|
||||
<string name="dfu_status_connecting">Connecting…</string>
|
||||
<string name="dfu_status_starting">Starting DFU…</string>
|
||||
<string name="dfu_status_switching_to_dfu">Starting bootloader…</string>
|
||||
<string name="dfu_status_uploading">Uploading…</string>
|
||||
<string name="dfu_status_uploading_part" formatted="false">Uploading part %d/%d…</string>
|
||||
<string name="dfu_status_validating">Validating…</string>
|
||||
<string name="dfu_status_disconnecting">Disconnecting…</string>
|
||||
<string name="dfu_status_completed">Done</string>
|
||||
<string name="dfu_status_aborted">Aborted</string>
|
||||
<string name="dfu_status_aborting">Aborting…</string>
|
||||
<string name="dfu_status_error">Upload failed</string>
|
||||
|
||||
<string name="dfu_status_connecting_msg">Connecting to %s…</string>
|
||||
<string name="dfu_status_starting_msg">Initializing DFU process…</string>
|
||||
<string name="dfu_status_switching_to_dfu_msg">Waiting for bootloader…</string>
|
||||
<string name="dfu_status_uploading_components_msg">Transmitting components to %s…</string>
|
||||
<string name="dfu_status_uploading_msg">Transmitting application to %s…</string>
|
||||
<string name="dfu_status_validating_msg">Validating…</string>
|
||||
<string name="dfu_status_completed_msg">Application has been send successfully.</string>
|
||||
<string name="dfu_status_aborted_msg">Application upload has been canceled.</string>
|
||||
<string name="dfu_status_disconnecting_msg">Disconnecting from %s…</string>
|
||||
<string name="dfu_status_error_msg">DFU process failed.</string>
|
||||
|
||||
</resources>
|
||||
<resources>
|
||||
|
||||
<string name="dfu_unknown_name">unnamed device</string>
|
||||
|
||||
<string name="dfu_action_abort">Abort</string>
|
||||
|
||||
<string name="dfu_status_initializing">Initializing…</string>
|
||||
<string name="dfu_status_connecting">Connecting…</string>
|
||||
<string name="dfu_status_starting">Starting DFU…</string>
|
||||
<string name="dfu_status_switching_to_dfu">Starting bootloader…</string>
|
||||
<string name="dfu_status_uploading">Uploading…</string>
|
||||
<string name="dfu_status_uploading_part" formatted="false">Uploading part %d/%d…</string>
|
||||
<string name="dfu_status_validating">Validating…</string>
|
||||
<string name="dfu_status_disconnecting">Disconnecting…</string>
|
||||
<string name="dfu_status_completed">Done</string>
|
||||
<string name="dfu_status_aborted">Aborted</string>
|
||||
<string name="dfu_status_aborting">Aborting…</string>
|
||||
<string name="dfu_status_error">Upload failed</string>
|
||||
|
||||
<string name="dfu_status_connecting_msg">Connecting to %s…</string>
|
||||
<string name="dfu_status_starting_msg">Initializing DFU process…</string>
|
||||
<string name="dfu_status_switching_to_dfu_msg">Waiting for bootloader…</string>
|
||||
<string name="dfu_status_uploading_components_msg">Transmitting components to %s…</string>
|
||||
<string name="dfu_status_uploading_msg">Transmitting application to %s…</string>
|
||||
<string name="dfu_status_validating_msg">Validating…</string>
|
||||
<string name="dfu_status_completed_msg">Application has been send successfully.</string>
|
||||
<string name="dfu_status_aborted_msg">Application upload has been canceled.</string>
|
||||
<string name="dfu_status_disconnecting_msg">Disconnecting from %s…</string>
|
||||
<string name="dfu_status_error_msg">DFU process failed.</string>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,18 @@
|
|||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
|
@ -0,0 +1,6 @@
|
|||
#Wed Apr 10 15:27:10 PDT 2013
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
|
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
|
@ -0,0 +1,90 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
|
@ -1,16 +0,0 @@
|
|||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-21
|
||||
android.library=true
|
||||
android.library.reference.1=../AndroidSupportLibrary
|
|
@ -0,0 +1 @@
|
|||
include ':dfu'
|