Delete android directory

Signed-off-by: Nerd Boy 4 Ever <48769137+n9lvc5@users.noreply.github.com>
This commit is contained in:
Nerd Boy 4 Ever 2025-10-29 10:08:58 -05:00 committed by GitHub
parent 6b6d4cbf9f
commit 592b0c3b61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
55 changed files with 0 additions and 3130 deletions

View File

@ -1,58 +0,0 @@
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.dmr.droidstardmr" android:installLocation="auto" android:versionCode="-- %%INSERT_VERSION_CODE%% --" android:versionName="-- %%INSERT_VERSION_NAME%% --">
<!-- %%INSERT_PERMISSIONS -->
<!-- %%INSERT_FEATURES -->
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true"/>
<application android:name="org.qtproject.qt.android.bindings.QtApplication" android:hardwareAccelerated="true" android:label="-- %%INSERT_APP_NAME%% --" android:requestLegacyExternalStorage="true" android:allowBackup="true" android:fullBackupOnly="false" android:icon="@drawable/icon" android:networkSecurityConfig="@xml/network_security_config" android:usesCleartextTraffic="false" >
<activity android:name="org.qtproject.qt.android.bindings.QtActivity" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:launchMode="singleTop" android:screenOrientation="unspecified" android:exported="true" android:label="Droidstar DMR" android:theme="@style/splashScreenTheme" android:alwaysRetainTaskState="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.arguments" android:value="-- %%INSERT_APP_ARGUMENTS%% --"/>
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splashscreen"/>
<meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/splashscreen_port"/>
<meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/splashscreen_land"/>
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splashscreen"/>
<meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/splashscreen_port"/>
<meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/splashscreen_land"/>
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splashscreen"/>
<meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/splashscreen_port"/>
<meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/splashscreen_land"/>
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splashscreen"/>
<meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/splashscreen_port"/>
<meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/splashscreen_land"/>
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splashscreen"/>
<meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/splashscreen_port"/>
<meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/splashscreen_land"/>
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splashscreen"/>
<meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/splashscreen_port"/>
<meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/splashscreen_land"/>
</activity>
<!-- Ensure the service is not stopped when the app is backgrounded -->
<service android:name=".YourForegroundService" android:exported="false" android:stopWithTask="false"/>
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.qtprovider;com.dmr.droidstardmr.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/qtprovider_paths"/>
</provider>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>

View File

@ -1,82 +0,0 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.1'
}
}
repositories {
google()
mavenCentral()
}
apply plugin: 'com.android.application'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation 'androidx.core:core:1.10.1'
}
android {
/*******************************************************
* The following variables:
* - androidBuildToolsVersion,
* - androidCompileSdkVersion
* - qtAndroidDir - holds the path to qt android files
* needed to build any Qt application
* on Android.
*
* are defined in gradle.properties file. This file is
* updated by QtCreator and androiddeployqt tools.
* Changing them manually might break the compilation!
*******************************************************/
compileSdkVersion androidCompileSdkVersion
buildToolsVersion androidBuildToolsVersion
ndkVersion androidNdkVersion
// Extract native libraries from the APK
packagingOptions.jniLibs.useLegacyPackaging true
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = [qtAndroidDir + '/src', 'src', 'java']
aidl.srcDirs = [qtAndroidDir + '/src', 'src', 'aidl']
res.srcDirs = [qtAndroidDir + '/res', 'res']
resources.srcDirs = ['resources']
renderscript.srcDirs = ['src']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
tasks.withType(JavaCompile) {
options.incremental = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
abortOnError false
}
// Do not compress Qt binary resources file
aaptOptions {
noCompress 'rcc'
}
defaultConfig {
resConfig "en"
minSdkVersion qtMinSdkVersion
targetSdkVersion qtTargetSdkVersion
ndk.abiFilters = qtTargetAbiList.split(",")
}
}

View File

@ -1,18 +0,0 @@
# Project-wide Gradle settings.
# 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.
org.gradle.jvmargs=-Xmx2500m -XX:MaxMetaspaceSize=768m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# Enable building projects in parallel
org.gradle.parallel=true
# Gradle caching allows reusing the build artifacts from a previous
# build with the same inputs. However, over time, the cache size will
# grow. Uncomment the following line to enable it.
#org.gradle.caching=true
#org.gradle.configuration-cache=true
# Allow AndroidX usage
android.useAndroidX=true

Binary file not shown.

View File

@ -1,7 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

249
android/gradlew vendored
View File

@ -1,249 +0,0 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
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
if ! command -v java >/dev/null 2>&1
then
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
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

92
android/gradlew.bat vendored
View File

@ -1,92 +0,0 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@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
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@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=-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
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 execute
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
: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 %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 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!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -1,8 +0,0 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Sat Aug 17 23:29:40 IST 2024
sdk.dir=C\:\\Users\\rohith\\AppData\\Local\\Android\\Sdk

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
<item>
<bitmap android:src="@drawable/logo" android:gravity="fill"/>
</item>
</layer-list>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
<item>
<bitmap android:src="@drawable/logo_land" android:gravity="fill"/>
</item>
</layer-list>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
<item>
<bitmap android:src="@drawable/logo_port" android:gravity="fill"/>
</item>
</layer-list>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="splashScreenTheme">
<item name="android:windowBackground">@drawable/splashscreen_land</item>
</style>
</resources>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="splashScreenTheme">
<item name="android:windowBackground">@drawable/splashscreen_port</item>
</style>
</resources>

View File

@ -1,21 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<!-- DO NOT EDIT THIS: This file is populated automatically by the deployment tool. -->
<array name="bundled_libs">
<!-- %%INSERT_EXTRA_LIBS%% -->
</array>
<array name="qt_libs">
<!-- %%INSERT_QT_LIBS%% -->
</array>
<array name="load_local_libs">
<!-- %%INSERT_LOCAL_LIBS%% -->
</array>
<string name="static_init_classes"><!-- %%INSERT_INIT_CLASSES%% --></string>
<string name="use_local_qt_libs"><!-- %%USE_LOCAL_QT_LIBS%% --></string>
<string name="bundle_local_qt_libs"><!-- %%BUNDLE_LOCAL_QT_LIBS%% --></string>
<string name="system_libs_prefix"><!-- %%SYSTEM_LIBS_PREFIX%% --></string>
</resources>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="splashScreenTheme">
<item name="android:windowBackground">@drawable/splashscreen</item>
</style>
</resources>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!-- Allows secure connections to the radioid.net API domain -->
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">radioid.net</domain>
</domain-config>
</network-security-config>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="files_path" path="/"/>
<external-path name="dslog_files" path="Download/DSLog/" />
</paths>

View File

@ -1,46 +0,0 @@
/*
Original Copyright (C) 2019-2021 Doug McLain
Modification Copyright (C) 2024 Rohith Namboothiri
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.dmr.droidstardmr;
import android.content.Intent;
import android.net.Uri;
import android.content.Context;
import androidx.core.content.FileProvider;
import java.io.File;
public class ShareUtils {
public static void shareFile(Context context, String filePath) {
File file = new File(filePath);
if (file.exists()) {
// Use the hardcoded authority string
Uri fileUri = FileProvider.getUriForFile(context, "com.dmr.droidstardmr.fileprovider", file);
// Create an intent to share the file
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/csv"); // Adjust MIME type as needed
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Start the share intent
context.startActivity(Intent.createChooser(shareIntent, "Share File"));
}
}
}

View File

@ -1,260 +0,0 @@
/*
Copyright (C) 2019-2021 Doug McLain
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package DroidStar;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.app.PendingIntent;
import android.content.Context;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbDeviceConnection;
import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
import com.hoho.android.usbserial.util.SerialInputOutputManagerTest;
public class USBSerialWrapper implements SerialInputOutputManagerTest.Listener {
public static int counter = 0;
public int id;
public Context m_context;
public int m_baudrate = 115200;
public int m_databits = 8;
public int m_stopbits = 1;
public int m_parity = 0;
public int m_flowcontrol = 0;
public int m_rts = 0;
public String m_devicename;
UsbSerialPort m_port;
SerialInputOutputManagerTest usbIoManager;
private static final String ACTION_USB_PERMISSION = "org.dudetronics.droidstar.USB_PERMISSION";
IntentFilter m_filter = new IntentFilter(ACTION_USB_PERMISSION);
UsbManager m_manager;
UsbSerialDriver m_driver;
public BroadcastReceiver m_usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
System.out.println("BroadcastReceiver() onReceive() action == " + action);
if (ACTION_USB_PERMISSION.equals(action)) {
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
System.out.println("USB Permission Granted");
if(open_device() > 0) device_open();
}
else {
System.out.println("USB Permission Denied");
device_denied();
}
}
if ( (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) || (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) ) {
devices_changed();
System.out.println("USB devices changed");
}
}
};
public USBSerialWrapper() {
this.id = counter;
System.out.println("Created USBSerialWrapper object with id: " + this.id);
counter++;
m_filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
m_filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
}
public void set_port_name(String d)
{
m_devicename = d;
System.out.println("Java Devicename: " + m_devicename);
}
public void set_baud_rate(int br)
{
m_baudrate = br;
System.out.println("Java Baudrate: " + br);
}
public void set_data_bits(int db)
{
m_databits = db;
System.out.println("Java DataBits: " + db);
}
public void set_stop_bits(int sb)
{
m_stopbits = sb;
System.out.println("Java StopBits: " + sb);
}
public void set_parity(int p)
{
m_parity = p;
System.out.println("Java Parity: " + p);
}
public void set_flow_control(int fc)
{
m_flowcontrol = fc;
System.out.println("Java FlowControl: " + fc);
}
public void set_rts(int rts)
{
m_rts = rts;
System.out.println("Java RTS: " + rts);
}
public String[] discover_devices(Context c)
{
System.out.println("Java: discover_devices()");
m_manager = (UsbManager) c.getSystemService(Context.USB_SERVICE);
List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(m_manager);
String[] devices = new String[availableDrivers.size()];
if (availableDrivers.isEmpty()) {
System.out.println("No drivers found");
}
else {
System.out.println(availableDrivers.size() + " found");
for(int i = 0; i < availableDrivers.size(); ++i){
devices[i] = availableDrivers.get(i).getDevice().getProductName() + ":" + availableDrivers.get(i).getDevice().getDeviceName();
System.out.println("USB device getDeviceName() == " + availableDrivers.get(i).getDevice().getDeviceName());
System.out.println("USB device getProductName() == " + availableDrivers.get(i).getDevice().getProductName());
System.out.println("USB device getProductId() == " + availableDrivers.get(i).getDevice().getProductId());
System.out.println("USB device getVendorId() == " + availableDrivers.get(i).getDevice().getVendorId());
}
}
c.registerReceiver(m_usbReceiver, m_filter, Context.RECEIVER_EXPORTED);
return devices;
}
public String setup_serial(Context c)
{
m_context = c;
int devicenum = 0;
List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(m_manager);
if (availableDrivers.isEmpty()) {
System.out.println("No drivers found");
return "returning...";
}
else {
System.out.println(availableDrivers.size() + " found");
for(int i = 0; i < availableDrivers.size(); ++i){
System.out.println("USB device getDeviceName() == " + availableDrivers.get(i).getDevice().getDeviceName());
System.out.println("USB device getProductName() == " + availableDrivers.get(i).getDevice().getProductName());
System.out.println("USB device getProductId() == " + availableDrivers.get(i).getDevice().getProductId());
System.out.println("USB device getVendorId() == " + availableDrivers.get(i).getDevice().getVendorId());
if(m_devicename.equals(availableDrivers.get(i).getDevice().getDeviceName())){
devicenum = i;
System.out.println("Found device == " + devicenum);
}
}
}
m_driver = availableDrivers.get(devicenum);
PendingIntent mPendingIntent = PendingIntent.getBroadcast(c, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT);
m_manager.requestPermission(m_driver.getDevice(), mPendingIntent);
System.out.println("setup_serial() finished");
return "Yipee!";
}
public int open_device()
{
UsbDeviceConnection connection = m_manager.openDevice(m_driver.getDevice());
if (connection == null) {
return 0;
}
m_port = m_driver.getPorts().get(0); // Most devices have just one port (port 0)
try {
m_port.open(connection);
m_port.setParameters(m_baudrate, m_databits, m_stopbits, m_parity);
m_port.setRTS(true);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
System.out.println("Created UsbManager");
usbIoManager = new SerialInputOutputManagerTest(m_port, this);
usbIoManager.start();
return 1;
}
public void write(byte[] data)
{
try {
m_port.write(data, 0);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
}
public byte[] read()
{
byte[] buffer = new byte[1024];
int r = 0;
try {
r = m_port.read(buffer, 0);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
byte[] returnbytes = Arrays.copyOf(buffer, r);
return returnbytes;
}
public void close(int c)
{
if(usbIoManager != null) {
usbIoManager.setListener(null);
usbIoManager.stop();
}
usbIoManager = null;
try {
m_port.close();
} catch (IOException ignored) {}
m_port = null;
}
@Override
public void onNewData(byte[] data) {
data_received(data);
}
@Override
public void onRunError(Exception e) {
System.out.println("Exception: " + e.getMessage());
}
private static native void data_received(byte[] data);
private static native void device_open();
private static native void device_denied();
private static native void devices_changed();
}

View File

@ -1,327 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* USB CDC/ACM serial driver implementation.
*
* @author mike wakerly (opensource@hoho.com)
* @see <a
* href="http://www.usb.org/developers/devclass_docs/usbcdc11.pdf">Universal
* Serial Bus Class Definitions for Communication Devices, v1.1</a>
*/
public class CdcAcmSerialDriver implements UsbSerialDriver {
private final String TAG = CdcAcmSerialDriver.class.getSimpleName();
private final UsbDevice mDevice;
private final List<UsbSerialPort> mPorts;
public CdcAcmSerialDriver(UsbDevice device) {
mDevice = device;
mPorts = new ArrayList<>();
int controlInterfaceCount = 0;
int dataInterfaceCount = 0;
for( int i = 0; i < device.getInterfaceCount(); i++) {
if(device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_COMM)
controlInterfaceCount++;
if(device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA)
dataInterfaceCount++;
}
for( int port = 0; port < Math.min(controlInterfaceCount, dataInterfaceCount); port++) {
mPorts.add(new CdcAcmSerialPort(mDevice, port));
}
if(mPorts.size() == 0) {
mPorts.add(new CdcAcmSerialPort(mDevice, -1));
}
}
@Override
public UsbDevice getDevice() {
return mDevice;
}
@Override
public List<UsbSerialPort> getPorts() {
return mPorts;
}
public class CdcAcmSerialPort extends CommonUsbSerialPort {
private UsbInterface mControlInterface;
private UsbInterface mDataInterface;
private UsbEndpoint mControlEndpoint;
private int mControlIndex;
private boolean mRts = false;
private boolean mDtr = false;
private static final int USB_RECIP_INTERFACE = 0x01;
private static final int USB_RT_ACM = UsbConstants.USB_TYPE_CLASS | USB_RECIP_INTERFACE;
private static final int SET_LINE_CODING = 0x20; // USB CDC 1.1 section 6.2
private static final int GET_LINE_CODING = 0x21;
private static final int SET_CONTROL_LINE_STATE = 0x22;
private static final int SEND_BREAK = 0x23;
public CdcAcmSerialPort(UsbDevice device, int portNumber) {
super(device, portNumber);
}
@Override
public UsbSerialDriver getDriver() {
return CdcAcmSerialDriver.this;
}
@Override
protected void openInt(UsbDeviceConnection connection) throws IOException {
if (mPortNumber == -1) {
Log.d(TAG,"device might be castrated ACM device, trying single interface logic");
openSingleInterface();
} else {
Log.d(TAG,"trying default interface logic");
openInterface();
}
}
private void openSingleInterface() throws IOException {
// the following code is inspired by the cdc-acm driver in the linux kernel
mControlIndex = 0;
mControlInterface = mDevice.getInterface(0);
mDataInterface = mDevice.getInterface(0);
if (!mConnection.claimInterface(mControlInterface, true)) {
throw new IOException("Could not claim shared control/data interface");
}
for (int i = 0; i < mControlInterface.getEndpointCount(); ++i) {
UsbEndpoint ep = mControlInterface.getEndpoint(i);
if ((ep.getDirection() == UsbConstants.USB_DIR_IN) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT)) {
mControlEndpoint = ep;
} else if ((ep.getDirection() == UsbConstants.USB_DIR_IN) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)) {
mReadEndpoint = ep;
} else if ((ep.getDirection() == UsbConstants.USB_DIR_OUT) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)) {
mWriteEndpoint = ep;
}
}
if (mControlEndpoint == null) {
throw new IOException("No control endpoint");
}
}
private void openInterface() throws IOException {
Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());
int controlInterfaceCount = 0;
int dataInterfaceCount = 0;
mControlInterface = null;
mDataInterface = null;
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
UsbInterface usbInterface = mDevice.getInterface(i);
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_COMM) {
if(controlInterfaceCount == mPortNumber) {
mControlIndex = i;
mControlInterface = usbInterface;
}
controlInterfaceCount++;
}
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
if(dataInterfaceCount == mPortNumber) {
mDataInterface = usbInterface;
}
dataInterfaceCount++;
}
}
if(mControlInterface == null) {
throw new IOException("No control interface");
}
Log.d(TAG, "Control iface=" + mControlInterface);
if (!mConnection.claimInterface(mControlInterface, true)) {
throw new IOException("Could not claim control interface");
}
mControlEndpoint = mControlInterface.getEndpoint(0);
if (mControlEndpoint.getDirection() != UsbConstants.USB_DIR_IN || mControlEndpoint.getType() != UsbConstants.USB_ENDPOINT_XFER_INT) {
throw new IOException("Invalid control endpoint");
}
if(mDataInterface == null) {
throw new IOException("No data interface");
}
Log.d(TAG, "data iface=" + mDataInterface);
if (!mConnection.claimInterface(mDataInterface, true)) {
throw new IOException("Could not claim data interface");
}
for (int i = 0; i < mDataInterface.getEndpointCount(); i++) {
UsbEndpoint ep = mDataInterface.getEndpoint(i);
if (ep.getDirection() == UsbConstants.USB_DIR_IN && ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
mReadEndpoint = ep;
if (ep.getDirection() == UsbConstants.USB_DIR_OUT && ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
mWriteEndpoint = ep;
}
}
private int sendAcmControlMessage(int request, int value, byte[] buf) throws IOException {
int len = mConnection.controlTransfer(
USB_RT_ACM, request, value, mControlIndex, buf, buf != null ? buf.length : 0, 5000);
if(len < 0) {
throw new IOException("controlTransfer failed");
}
return len;
}
@Override
protected void closeInt() {
try {
mConnection.releaseInterface(mControlInterface);
mConnection.releaseInterface(mDataInterface);
} catch(Exception ignored) {}
}
@Override
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException {
if(baudRate <= 0) {
throw new IllegalArgumentException("Invalid baud rate: " + baudRate);
}
if(dataBits < DATABITS_5 || dataBits > DATABITS_8) {
throw new IllegalArgumentException("Invalid data bits: " + dataBits);
}
byte stopBitsByte;
switch (stopBits) {
case STOPBITS_1: stopBitsByte = 0; break;
case STOPBITS_1_5: stopBitsByte = 1; break;
case STOPBITS_2: stopBitsByte = 2; break;
default: throw new IllegalArgumentException("Invalid stop bits: " + stopBits);
}
byte parityBitesByte;
switch (parity) {
case 0: parityBitesByte = 0; break;
case 1: parityBitesByte = 1; break;
case 2: parityBitesByte = 2; break;
case 3: parityBitesByte = 3; break;
case 4: parityBitesByte = 4; break;
default: throw new IllegalArgumentException("Invalid parity: " + parity);
}
byte[] msg = {
(byte) ( baudRate & 0xff),
(byte) ((baudRate >> 8 ) & 0xff),
(byte) ((baudRate >> 16) & 0xff),
(byte) ((baudRate >> 24) & 0xff),
stopBitsByte,
parityBitesByte,
(byte) dataBits};
sendAcmControlMessage(SET_LINE_CODING, 0, msg);
}
@Override
public boolean getDTR() throws IOException {
return mDtr;
}
@Override
public void setDTR(boolean value) throws IOException {
mDtr = value;
setDtrRts();
}
@Override
public boolean getRTS() throws IOException {
return mRts;
}
@Override
public void setRTS(boolean value) throws IOException {
mRts = value;
setDtrRts();
}
private void setDtrRts() throws IOException {
int value = (mRts ? 0x2 : 0) | (mDtr ? 0x1 : 0);
sendAcmControlMessage(SET_CONTROL_LINE_STATE, value, null);
}
@Override
public EnumSet<ControlLine> getControlLines() throws IOException {
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
if(mRts) set.add(ControlLine.RTS);
if(mDtr) set.add(ControlLine.DTR);
return set;
}
@Override
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.of(ControlLine.RTS, ControlLine.DTR);
}
@Override
public void setBreak(boolean value) throws IOException {
sendAcmControlMessage(SEND_BREAK, value ? 0xffff : 0, null);
}
}
public static Map<Integer, int[]> getSupportedDevices() {
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>();
supportedDevices.put(UsbId.VENDOR_ARDUINO,
new int[] {
UsbId.ARDUINO_UNO,
UsbId.ARDUINO_UNO_R3,
UsbId.ARDUINO_MEGA_2560,
UsbId.ARDUINO_MEGA_2560_R3,
UsbId.ARDUINO_SERIAL_ADAPTER,
UsbId.ARDUINO_SERIAL_ADAPTER_R3,
UsbId.ARDUINO_MEGA_ADK,
UsbId.ARDUINO_MEGA_ADK_R3,
UsbId.ARDUINO_LEONARDO,
UsbId.ARDUINO_MICRO,
});
supportedDevices.put(UsbId.VENDOR_VAN_OOIJEN_TECH,
new int[] {
UsbId.VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL,
});
supportedDevices.put(UsbId.VENDOR_ATMEL,
new int[] {
UsbId.ATMEL_LUFA_CDC_DEMO_APP,
});
supportedDevices.put(UsbId.VENDOR_LEAFLABS,
new int[] {
UsbId.LEAFLABS_MAPLE,
});
supportedDevices.put(UsbId.VENDOR_ARM,
new int[] {
UsbId.ARM_MBED,
});
supportedDevices.put(UsbId.VENDOR_ST,
new int[] {
UsbId.ST_CDC,
});
return supportedDevices;
}
}

View File

@ -1,301 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbRequest;
import android.util.Log;
import com.hoho.android.usbserial.util.MonotonicClock;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.EnumSet;
/**
* A base class shared by several driver implementations.
*
* @author mike wakerly (opensource@hoho.com)
*/
public abstract class CommonUsbSerialPort implements UsbSerialPort {
private static final String TAG = CommonUsbSerialPort.class.getSimpleName();
private static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;
private static final int MAX_READ_SIZE = 16 * 1024; // = old bulkTransfer limit
protected final UsbDevice mDevice;
protected final int mPortNumber;
// non-null when open()
protected UsbDeviceConnection mConnection = null;
protected UsbEndpoint mReadEndpoint;
protected UsbEndpoint mWriteEndpoint;
protected UsbRequest mUsbRequest;
protected final Object mWriteBufferLock = new Object();
/** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
protected byte[] mWriteBuffer;
public CommonUsbSerialPort(UsbDevice device, int portNumber) {
mDevice = device;
mPortNumber = portNumber;
mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
}
@Override
public String toString() {
return String.format("<%s device_name=%s device_id=%s port_number=%s>",
getClass().getSimpleName(), mDevice.getDeviceName(),
mDevice.getDeviceId(), mPortNumber);
}
@Override
public UsbDevice getDevice() {
return mDevice;
}
@Override
public int getPortNumber() {
return mPortNumber;
}
@Override
public UsbEndpoint getWriteEndpoint() { return mWriteEndpoint; }
@Override
public UsbEndpoint getReadEndpoint() { return mReadEndpoint; }
/**
* Returns the device serial number
* @return serial number
*/
@Override
public String getSerial() {
return mConnection.getSerial();
}
/**
* Sets the size of the internal buffer used to exchange data with the USB
* stack for write operations. Most users should not need to change this.
*
* @param bufferSize the size in bytes
*/
public final void setWriteBufferSize(int bufferSize) {
synchronized (mWriteBufferLock) {
if (bufferSize == mWriteBuffer.length) {
return;
}
mWriteBuffer = new byte[bufferSize];
}
}
@Override
public void open(UsbDeviceConnection connection) throws IOException {
if (mConnection != null) {
throw new IOException("Already open");
}
if(connection == null) {
throw new IllegalArgumentException("Connection is null");
}
mConnection = connection;
try {
openInt(connection);
if (mReadEndpoint == null || mWriteEndpoint == null) {
throw new IOException("Could not get read & write endpoints");
}
mUsbRequest = new UsbRequest();
mUsbRequest.initialize(mConnection, mReadEndpoint);
} catch(Exception e) {
try {
close();
} catch(Exception ignored) {}
throw e;
}
}
protected abstract void openInt(UsbDeviceConnection connection) throws IOException;
@Override
public void close() throws IOException {
if (mConnection == null) {
throw new IOException("Already closed");
}
try {
mUsbRequest.cancel();
} catch(Exception ignored) {}
mUsbRequest = null;
try {
closeInt();
} catch(Exception ignored) {}
try {
mConnection.close();
} catch(Exception ignored) {}
mConnection = null;
}
protected abstract void closeInt();
/**
* use simple USB request supported by all devices to test if connection is still valid
*/
protected void testConnection() throws IOException {
byte[] buf = new byte[2];
int len = mConnection.controlTransfer(0x80 /*DEVICE*/, 0 /*GET_STATUS*/, 0, 0, buf, buf.length, 200);
if(len < 0)
throw new IOException("USB get_status request failed");
}
@Override
public int read(final byte[] dest, final int timeout) throws IOException {
return read(dest, timeout, true);
}
protected int read(final byte[] dest, final int timeout, boolean testConnection) throws IOException {
if(mConnection == null) {
throw new IOException("Connection closed");
}
if(dest.length <= 0) {
throw new IllegalArgumentException("Read buffer to small");
}
final int nread;
if (timeout != 0) {
// bulkTransfer will cause data loss with short timeout + high baud rates + continuous transfer
// https://stackoverflow.com/questions/9108548/android-usb-host-bulktransfer-is-losing-data
// but mConnection.requestWait(timeout) available since Android 8.0 es even worse,
// as it crashes with short timeout, e.g.
// A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x276a in tid 29846 (pool-2-thread-1), pid 29618 (.usbserial.test)
// /system/lib64/libusbhost.so (usb_request_wait+192)
// /system/lib64/libandroid_runtime.so (android_hardware_UsbDeviceConnection_request_wait(_JNIEnv*, _jobject*, long)+84)
// data loss / crashes were observed with timeout up to 200 msec
long endTime = testConnection ? MonotonicClock.millis() + timeout : 0;
int readMax = Math.min(dest.length, MAX_READ_SIZE);
nread = mConnection.bulkTransfer(mReadEndpoint, dest, readMax, timeout);
// Android error propagation is improvable:
// nread == -1 can be: timeout, connection lost, buffer to small, ???
if(nread == -1 && testConnection && MonotonicClock.millis() < endTime)
testConnection();
} else {
final ByteBuffer buf = ByteBuffer.wrap(dest);
if (!mUsbRequest.queue(buf, dest.length)) {
throw new IOException("Queueing USB request failed");
}
final UsbRequest response = mConnection.requestWait();
if (response == null) {
throw new IOException("Waiting for USB request failed");
}
nread = buf.position();
// Android error propagation is improvable:
// response != null & nread == 0 can be: connection lost, buffer to small, ???
if(nread == 0) {
testConnection();
}
}
return Math.max(nread, 0);
}
@Override
public void write(final byte[] src, final int timeout) throws IOException {
int offset = 0;
final long endTime = (timeout == 0) ? 0 : (MonotonicClock.millis() + timeout);
if(mConnection == null) {
throw new IOException("Connection closed");
}
while (offset < src.length) {
int requestTimeout;
final int requestLength;
final int actualLength;
synchronized (mWriteBufferLock) {
final byte[] writeBuffer;
requestLength = Math.min(src.length - offset, mWriteBuffer.length);
if (offset == 0) {
writeBuffer = src;
} else {
// bulkTransfer does not support offsets, make a copy.
System.arraycopy(src, offset, mWriteBuffer, 0, requestLength);
writeBuffer = mWriteBuffer;
}
if (timeout == 0 || offset == 0) {
requestTimeout = timeout;
} else {
requestTimeout = (int)(endTime - MonotonicClock.millis());
if(requestTimeout == 0)
requestTimeout = -1;
}
if (requestTimeout < 0) {
actualLength = -2;
} else {
actualLength = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, requestLength, requestTimeout);
}
}
Log.d(TAG, "Wrote " + actualLength + "/" + requestLength + " offset " + offset + "/" + src.length + " timeout " + requestTimeout);
if (actualLength <= 0) {
if (timeout != 0 && MonotonicClock.millis() >= endTime) {
SerialTimeoutException ex = new SerialTimeoutException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.length + ", rc=" + actualLength);
ex.bytesTransferred = offset;
throw ex;
} else {
throw new IOException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.length);
}
}
offset += actualLength;
}
}
@Override
public boolean isOpen() {
return mConnection != null;
}
@Override
public abstract void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException;
@Override
public boolean getCD() throws IOException { throw new UnsupportedOperationException(); }
@Override
public boolean getCTS() throws IOException { throw new UnsupportedOperationException(); }
@Override
public boolean getDSR() throws IOException { throw new UnsupportedOperationException(); }
@Override
public boolean getDTR() throws IOException { throw new UnsupportedOperationException(); }
@Override
public void setDTR(boolean value) throws IOException { throw new UnsupportedOperationException(); }
@Override
public boolean getRI() throws IOException { throw new UnsupportedOperationException(); }
@Override
public boolean getRTS() throws IOException { throw new UnsupportedOperationException(); }
@Override
public void setRTS(boolean value) throws IOException { throw new UnsupportedOperationException(); }
@Override
public abstract EnumSet<ControlLine> getControlLines() throws IOException;
@Override
public abstract EnumSet<ControlLine> getSupportedControlLines() throws IOException;
@Override
public void purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void setBreak(boolean value) throws IOException { throw new UnsupportedOperationException(); }
}

View File

@ -1,335 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class Cp21xxSerialDriver implements UsbSerialDriver {
private static final String TAG = Cp21xxSerialDriver.class.getSimpleName();
private final UsbDevice mDevice;
private final List<UsbSerialPort> mPorts;
public Cp21xxSerialDriver(UsbDevice device) {
mDevice = device;
mPorts = new ArrayList<>();
for( int port = 0; port < device.getInterfaceCount(); port++) {
mPorts.add(new Cp21xxSerialPort(mDevice, port));
}
}
@Override
public UsbDevice getDevice() {
return mDevice;
}
@Override
public List<UsbSerialPort> getPorts() {
return mPorts;
}
public class Cp21xxSerialPort extends CommonUsbSerialPort {
private static final int USB_WRITE_TIMEOUT_MILLIS = 5000;
/*
* Configuration Request Types
*/
private static final int REQTYPE_HOST_TO_DEVICE = 0x41;
private static final int REQTYPE_DEVICE_TO_HOST = 0xc1;
/*
* Configuration Request Codes
*/
private static final int SILABSER_IFC_ENABLE_REQUEST_CODE = 0x00;
private static final int SILABSER_SET_LINE_CTL_REQUEST_CODE = 0x03;
private static final int SILABSER_SET_BREAK_REQUEST_CODE = 0x05;
private static final int SILABSER_SET_MHS_REQUEST_CODE = 0x07;
private static final int SILABSER_SET_BAUDRATE = 0x1E;
private static final int SILABSER_FLUSH_REQUEST_CODE = 0x12;
private static final int SILABSER_GET_MDMSTS_REQUEST_CODE = 0x08;
private static final int FLUSH_READ_CODE = 0x0a;
private static final int FLUSH_WRITE_CODE = 0x05;
/*
* SILABSER_IFC_ENABLE_REQUEST_CODE
*/
private static final int UART_ENABLE = 0x0001;
private static final int UART_DISABLE = 0x0000;
/*
* SILABSER_SET_MHS_REQUEST_CODE
*/
private static final int DTR_ENABLE = 0x101;
private static final int DTR_DISABLE = 0x100;
private static final int RTS_ENABLE = 0x202;
private static final int RTS_DISABLE = 0x200;
/*
* SILABSER_GET_MDMSTS_REQUEST_CODE
*/
private static final int STATUS_CTS = 0x10;
private static final int STATUS_DSR = 0x20;
private static final int STATUS_RI = 0x40;
private static final int STATUS_CD = 0x80;
private boolean dtr = false;
private boolean rts = false;
// second port of Cp2105 has limited baudRate, dataBits, stopBits, parity
// unsupported baudrate returns error at controlTransfer(), other parameters are silently ignored
private boolean mIsRestrictedPort;
public Cp21xxSerialPort(UsbDevice device, int portNumber) {
super(device, portNumber);
}
@Override
public UsbSerialDriver getDriver() {
return Cp21xxSerialDriver.this;
}
private void setConfigSingle(int request, int value) throws IOException {
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, request, value,
mPortNumber, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Control transfer failed: " + request + " / " + value + " -> " + result);
}
}
private byte getStatus() throws IOException {
byte[] buffer = new byte[1];
int result = mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, SILABSER_GET_MDMSTS_REQUEST_CODE, 0,
mPortNumber, buffer, buffer.length, USB_WRITE_TIMEOUT_MILLIS);
if (result != 1) {
throw new IOException("Control transfer failed: " + SILABSER_GET_MDMSTS_REQUEST_CODE + " / " + 0 + " -> " + result);
}
return buffer[0];
}
@Override
protected void openInt(UsbDeviceConnection connection) throws IOException {
mIsRestrictedPort = mDevice.getInterfaceCount() == 2 && mPortNumber == 1;
if(mPortNumber >= mDevice.getInterfaceCount()) {
throw new IOException("Unknown port number");
}
UsbInterface dataIface = mDevice.getInterface(mPortNumber);
if (!mConnection.claimInterface(dataIface, true)) {
throw new IOException("Could not claim interface " + mPortNumber);
}
for (int i = 0; i < dataIface.getEndpointCount(); i++) {
UsbEndpoint ep = dataIface.getEndpoint(i);
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
mReadEndpoint = ep;
} else {
mWriteEndpoint = ep;
}
}
}
setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_ENABLE);
setConfigSingle(SILABSER_SET_MHS_REQUEST_CODE, (dtr ? DTR_ENABLE : DTR_DISABLE) | (rts ? RTS_ENABLE : RTS_DISABLE));
}
@Override
protected void closeInt() {
try {
setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_DISABLE);
} catch (Exception ignored) {}
try {
mConnection.releaseInterface(mDevice.getInterface(mPortNumber));
} catch(Exception ignored) {}
}
private void setBaudRate(int baudRate) throws IOException {
byte[] data = new byte[] {
(byte) ( baudRate & 0xff),
(byte) ((baudRate >> 8 ) & 0xff),
(byte) ((baudRate >> 16) & 0xff),
(byte) ((baudRate >> 24) & 0xff)
};
int ret = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SILABSER_SET_BAUDRATE,
0, mPortNumber, data, 4, USB_WRITE_TIMEOUT_MILLIS);
if (ret < 0) {
throw new IOException("Error setting baud rate");
}
}
@Override
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException {
if(baudRate <= 0) {
throw new IllegalArgumentException("Invalid baud rate: " + baudRate);
}
setBaudRate(baudRate);
int configDataBits = 0;
switch (dataBits) {
case DATABITS_5:
if(mIsRestrictedPort)
throw new UnsupportedOperationException("Unsupported data bits: " + dataBits);
configDataBits |= 0x0500;
break;
case DATABITS_6:
if(mIsRestrictedPort)
throw new UnsupportedOperationException("Unsupported data bits: " + dataBits);
configDataBits |= 0x0600;
break;
case DATABITS_7:
if(mIsRestrictedPort)
throw new UnsupportedOperationException("Unsupported data bits: " + dataBits);
configDataBits |= 0x0700;
break;
case DATABITS_8:
configDataBits |= 0x0800;
break;
default:
throw new IllegalArgumentException("Invalid data bits: " + dataBits);
}
switch (parity) {
case 0:
break;
case 1:
configDataBits |= 0x0010;
break;
case 2:
configDataBits |= 0x0020;
break;
case 3:
if(mIsRestrictedPort)
throw new UnsupportedOperationException("Unsupported parity: mark");
configDataBits |= 0x0030;
break;
case 4:
if(mIsRestrictedPort)
throw new UnsupportedOperationException("Unsupported parity: space");
configDataBits |= 0x0040;
break;
default:
throw new IllegalArgumentException("Invalid parity: " + parity);
}
switch (stopBits) {
case STOPBITS_1:
break;
case STOPBITS_1_5:
throw new UnsupportedOperationException("Unsupported stop bits: 1.5");
case STOPBITS_2:
if(mIsRestrictedPort)
throw new UnsupportedOperationException("Unsupported stop bits: 2");
configDataBits |= 2;
break;
default:
throw new IllegalArgumentException("Invalid stop bits: " + stopBits);
}
setConfigSingle(SILABSER_SET_LINE_CTL_REQUEST_CODE, configDataBits);
}
@Override
public boolean getCD() throws IOException {
return (getStatus() & STATUS_CD) != 0;
}
@Override
public boolean getCTS() throws IOException {
return (getStatus() & STATUS_CTS) != 0;
}
@Override
public boolean getDSR() throws IOException {
return (getStatus() & STATUS_DSR) != 0;
}
@Override
public boolean getDTR() throws IOException {
return dtr;
}
@Override
public void setDTR(boolean value) throws IOException {
dtr = value;
setConfigSingle(SILABSER_SET_MHS_REQUEST_CODE, dtr ? DTR_ENABLE : DTR_DISABLE);
}
@Override
public boolean getRI() throws IOException {
return (getStatus() & STATUS_RI) != 0;
}
@Override
public boolean getRTS() throws IOException {
return rts;
}
@Override
public void setRTS(boolean value) throws IOException {
rts = value;
setConfigSingle(SILABSER_SET_MHS_REQUEST_CODE, rts ? RTS_ENABLE : RTS_DISABLE);
}
@Override
public EnumSet<ControlLine> getControlLines() throws IOException {
byte status = getStatus();
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
if(rts) set.add(ControlLine.RTS);
if((status & STATUS_CTS) != 0) set.add(ControlLine.CTS);
if(dtr) set.add(ControlLine.DTR);
if((status & STATUS_DSR) != 0) set.add(ControlLine.DSR);
if((status & STATUS_CD) != 0) set.add(ControlLine.CD);
if((status & STATUS_RI) != 0) set.add(ControlLine.RI);
return set;
}
@Override
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.allOf(ControlLine.class);
}
@Override
// note: only working on some devices, on other devices ignored w/o error
public void purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException {
int value = (purgeReadBuffers ? FLUSH_READ_CODE : 0)
| (purgeWriteBuffers ? FLUSH_WRITE_CODE : 0);
if (value != 0) {
setConfigSingle(SILABSER_FLUSH_REQUEST_CODE, value);
}
}
@Override
public void setBreak(boolean value) throws IOException {
setConfigSingle(SILABSER_SET_BREAK_REQUEST_CODE, value ? 1 : 0);
}
}
public static Map<Integer, int[]> getSupportedDevices() {
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>();
supportedDevices.put(UsbId.VENDOR_SILABS,
new int[] {
UsbId.SILABS_CP2102, // same ID for CP2101, CP2103, CP2104, CP2109
UsbId.SILABS_CP2105,
UsbId.SILABS_CP2108,
});
return supportedDevices;
}
}

View File

@ -1,431 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
* Copyright 2020 kai morich <mail@kai-morich.de>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.util.Log;
import com.hoho.android.usbserial.util.MonotonicClock;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/*
* driver is implemented from various information scattered over FTDI documentation
*
* baud rate calculation https://www.ftdichip.com/Support/Documents/AppNotes/AN232B-05_BaudRates.pdf
* control bits https://www.ftdichip.com/Firmware/Precompiled/UM_VinculumFirmware_V205.pdf
* device type https://www.ftdichip.com/Support/Documents/AppNotes/AN_233_Java_D2XX_for_Android_API_User_Manual.pdf -> bvdDevice
*
*/
public class FtdiSerialDriver implements UsbSerialDriver {
private static final String TAG = FtdiSerialPort.class.getSimpleName();
private final UsbDevice mDevice;
private final List<UsbSerialPort> mPorts;
public FtdiSerialDriver(UsbDevice device) {
mDevice = device;
mPorts = new ArrayList<>();
for( int port = 0; port < device.getInterfaceCount(); port++) {
mPorts.add(new FtdiSerialPort(mDevice, port));
}
}
@Override
public UsbDevice getDevice() {
return mDevice;
}
@Override
public List<UsbSerialPort> getPorts() {
return mPorts;
}
public class FtdiSerialPort extends CommonUsbSerialPort {
private static final int USB_WRITE_TIMEOUT_MILLIS = 5000;
private static final int READ_HEADER_LENGTH = 2; // contains MODEM_STATUS
private static final int REQTYPE_HOST_TO_DEVICE = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT;
private static final int REQTYPE_DEVICE_TO_HOST = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_IN;
private static final int RESET_REQUEST = 0;
private static final int MODEM_CONTROL_REQUEST = 1;
private static final int SET_BAUD_RATE_REQUEST = 3;
private static final int SET_DATA_REQUEST = 4;
private static final int GET_MODEM_STATUS_REQUEST = 5;
private static final int SET_LATENCY_TIMER_REQUEST = 9;
private static final int GET_LATENCY_TIMER_REQUEST = 10;
private static final int MODEM_CONTROL_DTR_ENABLE = 0x0101;
private static final int MODEM_CONTROL_DTR_DISABLE = 0x0100;
private static final int MODEM_CONTROL_RTS_ENABLE = 0x0202;
private static final int MODEM_CONTROL_RTS_DISABLE = 0x0200;
private static final int MODEM_STATUS_CTS = 0x10;
private static final int MODEM_STATUS_DSR = 0x20;
private static final int MODEM_STATUS_RI = 0x40;
private static final int MODEM_STATUS_CD = 0x80;
private static final int RESET_ALL = 0;
private static final int RESET_PURGE_RX = 1;
private static final int RESET_PURGE_TX = 2;
private boolean baudRateWithPort = false;
private boolean dtr = false;
private boolean rts = false;
private int breakConfig = 0;
public FtdiSerialPort(UsbDevice device, int portNumber) {
super(device, portNumber);
}
@Override
public UsbSerialDriver getDriver() {
return FtdiSerialDriver.this;
}
@Override
protected void openInt(UsbDeviceConnection connection) throws IOException {
if (!connection.claimInterface(mDevice.getInterface(mPortNumber), true)) {
throw new IOException("Could not claim interface " + mPortNumber);
}
if (mDevice.getInterface(mPortNumber).getEndpointCount() < 2) {
throw new IOException("Not enough endpoints");
}
mReadEndpoint = mDevice.getInterface(mPortNumber).getEndpoint(0);
mWriteEndpoint = mDevice.getInterface(mPortNumber).getEndpoint(1);
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, RESET_REQUEST,
RESET_ALL, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Reset failed: result=" + result);
}
result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, MODEM_CONTROL_REQUEST,
(dtr ? MODEM_CONTROL_DTR_ENABLE : MODEM_CONTROL_DTR_DISABLE) |
(rts ? MODEM_CONTROL_RTS_ENABLE : MODEM_CONTROL_RTS_DISABLE),
mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Init RTS,DTR failed: result=" + result);
}
// mDevice.getVersion() would require API 23
byte[] rawDescriptors = connection.getRawDescriptors();
if(rawDescriptors == null || rawDescriptors.length < 14) {
throw new IOException("Could not get device descriptors");
}
int deviceType = rawDescriptors[13];
baudRateWithPort = deviceType == 7 || deviceType == 8 || deviceType == 9 // ...H devices
|| mDevice.getInterfaceCount() > 1; // FT2232C
}
@Override
protected void closeInt() {
try {
mConnection.releaseInterface(mDevice.getInterface(mPortNumber));
} catch(Exception ignored) {}
}
@Override
public int read(final byte[] dest, final int timeout) throws IOException {
if(dest.length <= READ_HEADER_LENGTH) {
throw new IllegalArgumentException("Read buffer to small");
// could allocate larger buffer, including space for 2 header bytes, but this would
// result in buffers not being 64 byte aligned any more, causing data loss at continuous
// data transfer at high baud rates when buffers are fully filled.
}
int nread;
if (timeout != 0) {
long endTime = MonotonicClock.millis() + timeout;
do {
nread = super.read(dest, Math.max(1, (int)(endTime - MonotonicClock.millis())), false);
} while (nread == READ_HEADER_LENGTH && MonotonicClock.millis() < endTime);
if(nread <= 0 && MonotonicClock.millis() < endTime)
testConnection();
} else {
do {
nread = super.read(dest, timeout, false);
} while (nread == READ_HEADER_LENGTH);
}
return readFilter(dest, nread);
}
protected int readFilter(byte[] buffer, int totalBytesRead) throws IOException {
final int maxPacketSize = mReadEndpoint.getMaxPacketSize();
int destPos = 0;
for(int srcPos = 0; srcPos < totalBytesRead; srcPos += maxPacketSize) {
int length = Math.min(srcPos + maxPacketSize, totalBytesRead) - (srcPos + READ_HEADER_LENGTH);
if (length < 0)
throw new IOException("Expected at least " + READ_HEADER_LENGTH + " bytes");
System.arraycopy(buffer, srcPos + READ_HEADER_LENGTH, buffer, destPos, length);
destPos += length;
}
//Log.d(TAG, "read filter " + totalBytesRead + " -> " + destPos);
return destPos;
}
private void setBaudrate(int baudRate) throws IOException {
int divisor, subdivisor, effectiveBaudRate;
if (baudRate > 3500000) {
throw new UnsupportedOperationException("Baud rate to high");
} else if(baudRate >= 2500000) {
divisor = 0;
subdivisor = 0;
effectiveBaudRate = 3000000;
} else if(baudRate >= 1750000) {
divisor = 1;
subdivisor = 0;
effectiveBaudRate = 2000000;
} else {
divisor = (24000000 << 1) / baudRate;
divisor = (divisor + 1) >> 1; // round
subdivisor = divisor & 0x07;
divisor >>= 3;
if (divisor > 0x3fff) // exceeds bit 13 at 183 baud
throw new UnsupportedOperationException("Baud rate to low");
effectiveBaudRate = (24000000 << 1) / ((divisor << 3) + subdivisor);
effectiveBaudRate = (effectiveBaudRate +1) >> 1;
}
double baudRateError = Math.abs(1.0 - (effectiveBaudRate / (double)baudRate));
if(baudRateError >= 0.031) // can happen only > 1.5Mbaud
throw new UnsupportedOperationException(String.format("Baud rate deviation %.1f%% is higher than allowed 3%%", baudRateError*100));
int value = divisor;
int index = 0;
switch(subdivisor) {
case 0: break; // 16,15,14 = 000 - sub-integer divisor = 0
case 4: value |= 0x4000; break; // 16,15,14 = 001 - sub-integer divisor = 0.5
case 2: value |= 0x8000; break; // 16,15,14 = 010 - sub-integer divisor = 0.25
case 1: value |= 0xc000; break; // 16,15,14 = 011 - sub-integer divisor = 0.125
case 3: value |= 0x0000; index |= 1; break; // 16,15,14 = 100 - sub-integer divisor = 0.375
case 5: value |= 0x4000; index |= 1; break; // 16,15,14 = 101 - sub-integer divisor = 0.625
case 6: value |= 0x8000; index |= 1; break; // 16,15,14 = 110 - sub-integer divisor = 0.75
case 7: value |= 0xc000; index |= 1; break; // 16,15,14 = 111 - sub-integer divisor = 0.875
}
if(baudRateWithPort) {
index <<= 8;
index |= mPortNumber+1;
}
Log.d(TAG, String.format("baud rate=%d, effective=%d, error=%.1f%%, value=0x%04x, index=0x%04x, divisor=%d, subdivisor=%d",
baudRate, effectiveBaudRate, baudRateError*100, value, index, divisor, subdivisor));
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SET_BAUD_RATE_REQUEST,
value, index, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Setting baudrate failed: result=" + result);
}
}
@Override
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException {
if(baudRate <= 0) {
throw new IllegalArgumentException("Invalid baud rate: " + baudRate);
}
setBaudrate(baudRate);
int config = 0;
switch (dataBits) {
case DATABITS_5:
case DATABITS_6:
throw new UnsupportedOperationException("Unsupported data bits: " + dataBits);
case DATABITS_7:
case DATABITS_8:
config |= dataBits;
break;
default:
throw new IllegalArgumentException("Invalid data bits: " + dataBits);
}
switch (parity) {
case 0:
break;
case 1:
config |= 0x100;
break;
case 2:
config |= 0x200;
break;
case 3:
config |= 0x300;
break;
case 4:
config |= 0x400;
break;
default:
throw new IllegalArgumentException("Invalid parity: " + parity);
}
switch (stopBits) {
case STOPBITS_1:
break;
case STOPBITS_1_5:
throw new UnsupportedOperationException("Unsupported stop bits: 1.5");
case STOPBITS_2:
config |= 0x1000;
break;
default:
throw new IllegalArgumentException("Invalid stop bits: " + stopBits);
}
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SET_DATA_REQUEST,
config, mPortNumber+1,null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Setting parameters failed: result=" + result);
}
breakConfig = config;
}
private int getStatus() throws IOException {
byte[] data = new byte[2];
int result = mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, GET_MODEM_STATUS_REQUEST,
0, mPortNumber+1, data, data.length, USB_WRITE_TIMEOUT_MILLIS);
if (result != 2) {
throw new IOException("Get modem status failed: result=" + result);
}
return data[0];
}
@Override
public boolean getCD() throws IOException {
return (getStatus() & MODEM_STATUS_CD) != 0;
}
@Override
public boolean getCTS() throws IOException {
return (getStatus() & MODEM_STATUS_CTS) != 0;
}
@Override
public boolean getDSR() throws IOException {
return (getStatus() & MODEM_STATUS_DSR) != 0;
}
@Override
public boolean getDTR() throws IOException {
return dtr;
}
@Override
public void setDTR(boolean value) throws IOException {
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, MODEM_CONTROL_REQUEST,
value ? MODEM_CONTROL_DTR_ENABLE : MODEM_CONTROL_DTR_DISABLE, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Set DTR failed: result=" + result);
}
dtr = value;
}
@Override
public boolean getRI() throws IOException {
return (getStatus() & MODEM_STATUS_RI) != 0;
}
@Override
public boolean getRTS() throws IOException {
return rts;
}
@Override
public void setRTS(boolean value) throws IOException {
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, MODEM_CONTROL_REQUEST,
value ? MODEM_CONTROL_RTS_ENABLE : MODEM_CONTROL_RTS_DISABLE, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Set DTR failed: result=" + result);
}
rts = value;
}
@Override
public EnumSet<ControlLine> getControlLines() throws IOException {
int status = getStatus();
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
if(rts) set.add(ControlLine.RTS);
if((status & MODEM_STATUS_CTS) != 0) set.add(ControlLine.CTS);
if(dtr) set.add(ControlLine.DTR);
if((status & MODEM_STATUS_DSR) != 0) set.add(ControlLine.DSR);
if((status & MODEM_STATUS_CD) != 0) set.add(ControlLine.CD);
if((status & MODEM_STATUS_RI) != 0) set.add(ControlLine.RI);
return set;
}
@Override
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.allOf(ControlLine.class);
}
@Override
public void purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException {
if (purgeWriteBuffers) {
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, RESET_REQUEST,
RESET_PURGE_RX, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Purge write buffer failed: result=" + result);
}
}
if (purgeReadBuffers) {
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, RESET_REQUEST,
RESET_PURGE_TX, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Purge read buffer failed: result=" + result);
}
}
}
@Override
public void setBreak(boolean value) throws IOException {
int config = breakConfig;
if(value) config |= 0x4000;
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SET_DATA_REQUEST,
config, mPortNumber+1,null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Setting BREAK failed: result=" + result);
}
}
public void setLatencyTimer(int latencyTime) throws IOException {
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SET_LATENCY_TIMER_REQUEST,
latencyTime, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Set latency timer failed: result=" + result);
}
}
public int getLatencyTimer() throws IOException {
byte[] data = new byte[1];
int result = mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, GET_LATENCY_TIMER_REQUEST,
0, mPortNumber+1, data, data.length, USB_WRITE_TIMEOUT_MILLIS);
if (result != 1) {
throw new IOException("Get latency timer failed: result=" + result);
}
return data[0];
}
}
public static Map<Integer, int[]> getSupportedDevices() {
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>();
supportedDevices.put(UsbId.VENDOR_FTDI,
new int[] {
UsbId.FTDI_FT232R,
UsbId.FTDI_FT232H,
UsbId.FTDI_FT2232H,
UsbId.FTDI_FT4232H,
UsbId.FTDI_FT231X, // same ID for FT230X, FT231X, FT234XD
});
return supportedDevices;
}
}

View File

@ -1,87 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
import android.util.Pair;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Maps (vendor id, product id) pairs to the corresponding serial driver.
*
* @author mike wakerly (opensource@hoho.com)
*/
public class ProbeTable {
private final Map<Pair<Integer, Integer>, Class<? extends UsbSerialDriver>> mProbeTable =
new LinkedHashMap<>();
/**
* Adds or updates a (vendor, product) pair in the table.
*
* @param vendorId the USB vendor id
* @param productId the USB product id
* @param driverClass the driver class responsible for this pair
* @return {@code this}, for chaining
*/
public ProbeTable addProduct(int vendorId, int productId,
Class<? extends UsbSerialDriver> driverClass) {
mProbeTable.put(Pair.create(vendorId, productId), driverClass);
return this;
}
/**
* Internal method to add all supported products from
* {@code getSupportedProducts} static method.
*
* @param driverClass
* @return
*/
@SuppressWarnings("unchecked")
ProbeTable addDriver(Class<? extends UsbSerialDriver> driverClass) {
final Method method;
try {
method = driverClass.getMethod("getSupportedDevices");
} catch (SecurityException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
final Map<Integer, int[]> devices;
try {
devices = (Map<Integer, int[]>) method.invoke(null);
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
for (Map.Entry<Integer, int[]> entry : devices.entrySet()) {
final int vendorId = entry.getKey();
for (int productId : entry.getValue()) {
addProduct(vendorId, productId, driverClass);
}
}
return this;
}
/**
* Returns the driver for the given (vendor, product) pair, or {@code null}
* if no match.
*
* @param vendorId the USB vendor id
* @param productId the USB product id
* @return the driver class matching this pair, or {@code null}
*/
public Class<? extends UsbSerialDriver> findDriver(int vendorId, int productId) {
final Pair<Integer, Integer> pair = Pair.create(vendorId, productId);
return mProbeTable.get(pair);
}
}

View File

@ -1,15 +0,0 @@
package com.hoho.android.usbserial.driver;
import java.io.InterruptedIOException;
/**
* Signals that a timeout has occurred on serial write.
* Similar to SocketTimeoutException.
*
* {@see InterruptedIOException#bytesTransferred} may contain bytes transferred
*/
public class SerialTimeoutException extends InterruptedIOException {
public SerialTimeoutException(String s) {
super(s);
}
}

View File

@ -1,76 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
/**
* Registry of USB vendor/product ID constants.
*
* Culled from various sources; see
* <a href="http://www.linux-usb.org/usb.ids">usb.ids</a> for one listing.
*
* @author mike wakerly (opensource@hoho.com)
*/
public final class UsbId {
public static final int VENDOR_FTDI = 0x0403;
public static final int FTDI_FT232R = 0x6001;
public static final int FTDI_FT2232H = 0x6010;
public static final int FTDI_FT4232H = 0x6011;
public static final int FTDI_FT232H = 0x6014;
public static final int FTDI_FT231X = 0x6015; // same ID for FT230X, FT231X, FT234XD
public static final int VENDOR_ATMEL = 0x03EB;
public static final int ATMEL_LUFA_CDC_DEMO_APP = 0x2044;
public static final int VENDOR_ARDUINO = 0x2341;
public static final int ARDUINO_UNO = 0x0001;
public static final int ARDUINO_MEGA_2560 = 0x0010;
public static final int ARDUINO_SERIAL_ADAPTER = 0x003b;
public static final int ARDUINO_MEGA_ADK = 0x003f;
public static final int ARDUINO_MEGA_2560_R3 = 0x0042;
public static final int ARDUINO_UNO_R3 = 0x0043;
public static final int ARDUINO_MEGA_ADK_R3 = 0x0044;
public static final int ARDUINO_SERIAL_ADAPTER_R3 = 0x0044;
public static final int ARDUINO_LEONARDO = 0x8036;
public static final int ARDUINO_MICRO = 0x8037;
public static final int VENDOR_VAN_OOIJEN_TECH = 0x16c0;
public static final int VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL = 0x0483;
public static final int VENDOR_LEAFLABS = 0x1eaf;
public static final int LEAFLABS_MAPLE = 0x0004;
public static final int VENDOR_SILABS = 0x10c4;
public static final int SILABS_CP2102 = 0xea60; // same ID for CP2101, CP2103, CP2104, CP2109
public static final int SILABS_CP2105 = 0xea70;
public static final int SILABS_CP2108 = 0xea71;
public static final int VENDOR_PROLIFIC = 0x067b;
public static final int PROLIFIC_PL2303 = 0x2303; // device type 01, T, HX
public static final int PROLIFIC_PL2303GC = 0x23a3; // device type HXN
public static final int PROLIFIC_PL2303GB = 0x23b3; // "
public static final int PROLIFIC_PL2303GT = 0x23c3; // "
public static final int PROLIFIC_PL2303GL = 0x23d3; // "
public static final int PROLIFIC_PL2303GE = 0x23e3; // "
public static final int PROLIFIC_PL2303GS = 0x23f3; // "
public static final int VENDOR_QINHENG = 0x1a86;
public static final int QINHENG_CH340 = 0x7523;
public static final int QINHENG_CH341A = 0x5523;
// at www.linux-usb.org/usb.ids listed for NXP/LPC1768, but all processors supported by ARM mbed DAPLink firmware report these ids
public static final int VENDOR_ARM = 0x0d28;
public static final int ARM_MBED = 0x0204;
public static final int VENDOR_ST = 0x0483;
public static final int ST_CDC = 0x5740;
private UsbId() {
throw new IllegalAccessError("Non-instantiable class");
}
}

View File

@ -1,33 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbDevice;
import java.util.List;
/**
*
* @author mike wakerly (opensource@hoho.com)
*/
public interface UsbSerialDriver {
/**
* Returns the raw {@link UsbDevice} backing this port.
*
* @return the device
*/
UsbDevice getDevice();
/**
* Returns all available ports for this device. This list must have at least
* one entry.
*
* @return the ports
*/
List<UsbSerialPort> getPorts();
}

View File

@ -1,261 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbManager;
//import androidx.annotation.IntDef;
import java.io.Closeable;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.EnumSet;
/**
* Interface for a single serial port.
*
* @author mike wakerly (opensource@hoho.com)
*/
public interface UsbSerialPort extends Closeable {
/** 5 data bits. */
int DATABITS_5 = 5;
/** 6 data bits. */
int DATABITS_6 = 6;
/** 7 data bits. */
int DATABITS_7 = 7;
/** 8 data bits. */
int DATABITS_8 = 8;
/** Values for setParameters(..., parity) */
//@Retention(RetentionPolicy.SOURCE)
//@IntDef({PARITY_NONE, PARITY_ODD, PARITY_EVEN, PARITY_MARK, PARITY_SPACE})
//@interface Parity {}
/** No parity. */
int PARITY_NONE = 0;
/** Odd parity. */
int PARITY_ODD = 1;
/** Even parity. */
int PARITY_EVEN = 2;
/** Mark parity. */
int PARITY_MARK = 3;
/** Space parity. */
int PARITY_SPACE = 4;
/** 1 stop bit. */
int STOPBITS_1 = 1;
/** 1.5 stop bits. */
int STOPBITS_1_5 = 3;
/** 2 stop bits. */
int STOPBITS_2 = 2;
/** Values for get[Supported]ControlLines() */
enum ControlLine { RTS, CTS, DTR, DSR, CD, RI }
/**
* Returns the driver used by this port.
*/
UsbSerialDriver getDriver();
/**
* Returns the currently-bound USB device.
*/
UsbDevice getDevice();
/**
* Port number within driver.
*/
int getPortNumber();
/**
* Returns the write endpoint.
* @return write endpoint
*/
UsbEndpoint getWriteEndpoint();
/**
* Returns the read endpoint.
* @return read endpoint
*/
UsbEndpoint getReadEndpoint();
/**
* The serial number of the underlying UsbDeviceConnection, or {@code null}.
*
* @return value from {@link UsbDeviceConnection#getSerial()}
* @throws SecurityException starting with target SDK 29 (Android 10) if permission for USB device is not granted
*/
String getSerial();
/**
* Opens and initializes the port. Upon success, caller must ensure that
* {@link #close()} is eventually called.
*
* @param connection an open device connection, acquired with
* {@link UsbManager#openDevice(android.hardware.usb.UsbDevice)}
* @throws IOException on error opening or initializing the port.
*/
void open(UsbDeviceConnection connection) throws IOException;
/**
* Closes the port and {@link UsbDeviceConnection}
*
* @throws IOException on error closing the port.
*/
void close() throws IOException;
/**
* Reads as many bytes as possible into the destination buffer.
*
* @param dest the destination byte buffer
* @param timeout the timeout for reading in milliseconds, 0 is infinite
* @return the actual number of bytes read
* @throws IOException if an error occurred during reading
*/
int read(final byte[] dest, final int timeout) throws IOException;
/**
* Writes as many bytes as possible from the source buffer.
*
* @param src the source byte buffer
* @param timeout the timeout for writing in milliseconds, 0 is infinite
* @throws SerialTimeoutException if timeout reached before sending all data.
* ex.bytesTransferred may contain bytes transferred
* @throws IOException if an error occurred during writing
*/
void write(final byte[] src, final int timeout) throws IOException;
/**
* Sets various serial port parameters.
*
* @param baudRate baud rate as an integer, for example {@code 115200}.
* @param dataBits one of {@link #DATABITS_5}, {@link #DATABITS_6},
* {@link #DATABITS_7}, or {@link #DATABITS_8}.
* @param stopBits one of {@link #STOPBITS_1}, {@link #STOPBITS_1_5}, or {@link #STOPBITS_2}.
* @param parity one of {@link #PARITY_NONE}, {@link #PARITY_ODD},
* {@link #PARITY_EVEN}, {@link #PARITY_MARK}, or {@link #PARITY_SPACE}.
* @throws IOException on error setting the port parameters
* @throws UnsupportedOperationException if values are not supported by a specific device
*/
void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException;
/**
* Gets the CD (Carrier Detect) bit from the underlying UART.
*
* @return the current state
* @throws IOException if an error occurred during reading
* @throws UnsupportedOperationException if not supported
*/
boolean getCD() throws IOException;
/**
* Gets the CTS (Clear To Send) bit from the underlying UART.
*
* @return the current state
* @throws IOException if an error occurred during reading
* @throws UnsupportedOperationException if not supported
*/
boolean getCTS() throws IOException;
/**
* Gets the DSR (Data Set Ready) bit from the underlying UART.
*
* @return the current state
* @throws IOException if an error occurred during reading
* @throws UnsupportedOperationException if not supported
*/
boolean getDSR() throws IOException;
/**
* Gets the DTR (Data Terminal Ready) bit from the underlying UART.
*
* @return the current state
* @throws IOException if an error occurred during reading
* @throws UnsupportedOperationException if not supported
*/
boolean getDTR() throws IOException;
/**
* Sets the DTR (Data Terminal Ready) bit on the underlying UART, if supported.
*
* @param value the value to set
* @throws IOException if an error occurred during writing
* @throws UnsupportedOperationException if not supported
*/
void setDTR(boolean value) throws IOException;
/**
* Gets the RI (Ring Indicator) bit from the underlying UART.
*
* @return the current state
* @throws IOException if an error occurred during reading
* @throws UnsupportedOperationException if not supported
*/
boolean getRI() throws IOException;
/**
* Gets the RTS (Request To Send) bit from the underlying UART.
*
* @return the current state
* @throws IOException if an error occurred during reading
* @throws UnsupportedOperationException if not supported
*/
boolean getRTS() throws IOException;
/**
* Sets the RTS (Request To Send) bit on the underlying UART, if supported.
*
* @param value the value to set
* @throws IOException if an error occurred during writing
* @throws UnsupportedOperationException if not supported
*/
void setRTS(boolean value) throws IOException;
/**
* Gets all control line values from the underlying UART, if supported.
* Requires less USB calls than calling getRTS() + ... + getRI() individually.
*
* @return EnumSet.contains(...) is {@code true} if set, else {@code false}
* @throws IOException if an error occurred during reading
*/
EnumSet<ControlLine> getControlLines() throws IOException;
/**
* Gets all control line supported flags.
*
* @return EnumSet.contains(...) is {@code true} if supported, else {@code false}
* @throws IOException if an error occurred during reading
*/
EnumSet<ControlLine> getSupportedControlLines() throws IOException;
/**
* Purge non-transmitted output data and / or non-read input data.
*
* @param purgeWriteBuffers {@code true} to discard non-transmitted output data
* @param purgeReadBuffers {@code true} to discard non-read input data
* @throws IOException if an error occurred during flush
* @throws UnsupportedOperationException if not supported
*/
void purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException;
/**
* send BREAK condition.
*
* @param value set/reset
*/
void setBreak(boolean value) throws IOException;
/**
* Returns the current state of the connection.
*/
boolean isOpen();
}

View File

@ -1,92 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author mike wakerly (opensource@hoho.com)
*/
public class UsbSerialProber {
private final ProbeTable mProbeTable;
public UsbSerialProber(ProbeTable probeTable) {
mProbeTable = probeTable;
}
public static UsbSerialProber getDefaultProber() {
return new UsbSerialProber(getDefaultProbeTable());
}
public static ProbeTable getDefaultProbeTable() {
final ProbeTable probeTable = new ProbeTable();
probeTable.addDriver(CdcAcmSerialDriver.class);
probeTable.addDriver(Cp21xxSerialDriver.class);
probeTable.addDriver(FtdiSerialDriver.class);
//probeTable.addDriver(ProlificSerialDriver.class);
//probeTable.addDriver(Ch34xSerialDriver.class);
return probeTable;
}
/**
* Finds and builds all possible {@link UsbSerialDriver UsbSerialDrivers}
* from the currently-attached {@link UsbDevice} hierarchy. This method does
* not require permission from the Android USB system, since it does not
* open any of the devices.
*
* @param usbManager usb manager
* @return a list, possibly empty, of all compatible drivers
*/
public List<UsbSerialDriver> findAllDrivers(final UsbManager usbManager) {
final List<UsbSerialDriver> result = new ArrayList<>();
for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
final UsbSerialDriver driver = probeDevice(usbDevice);
if (driver != null) {
result.add(driver);
}
}
return result;
}
/**
* Probes a single device for a compatible driver.
*
* @param usbDevice the usb device to probe
* @return a new {@link UsbSerialDriver} compatible with this device, or
* {@code null} if none available.
*/
public UsbSerialDriver probeDevice(final UsbDevice usbDevice) {
final int vendorId = usbDevice.getVendorId();
final int productId = usbDevice.getProductId();
final Class<? extends UsbSerialDriver> driverClass =
mProbeTable.findDriver(vendorId, productId);
if (driverClass != null) {
final UsbSerialDriver driver;
try {
final Constructor<? extends UsbSerialDriver> ctor =
driverClass.getConstructor(UsbDevice.class);
driver = ctor.newInstance(usbDevice);
} catch (NoSuchMethodException | IllegalArgumentException | InstantiationException |
IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
return driver;
}
return null;
}
}

View File

@ -1,14 +0,0 @@
package com.hoho.android.usbserial.util;
public final class MonotonicClock {
private static final long NS_PER_MS = 1_000_000;
private MonotonicClock() {
}
public static long millis() {
return System.nanoTime() / NS_PER_MS;
}
}

View File

@ -1,254 +0,0 @@
/* Copyright 2011-2013 Google Inc.
* Copyright 2013 mike wakerly <opensource@hoho.com>
*
* Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.util;
import android.os.Process;
import android.util.Log;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* Utility class which services a {@link UsbSerialPort} in its {@link #run()} method.
*
* @author mike wakerly (opensource@hoho.com)
*/
public class SerialInputOutputManagerTest implements Runnable {
private static final String TAG = SerialInputOutputManagerTest.class.getSimpleName();
public static boolean DEBUG = false;
private static final int BUFSIZ = 8192;
/**
* default read timeout is infinite, to avoid data loss with bulkTransfer API
*/
private int mReadTimeout = 0;
private int mWriteTimeout = 0;
private final Object mReadBufferLock = new Object();
private final Object mWriteBufferLock = new Object();
private ByteBuffer mReadBuffer; // default size = getReadEndpoint().getMaxPacketSize()
private ByteBuffer mWriteBuffer = ByteBuffer.allocate(BUFSIZ);
public enum State {
STOPPED,
RUNNING,
STOPPING
}
private int mThreadPriority = Process.THREAD_PRIORITY_URGENT_AUDIO;
private State mState = State.STOPPED; // Synchronized by 'this'
private Listener mListener; // Synchronized by 'this'
private final UsbSerialPort mSerialPort;
public interface Listener {
/**
* Called when new incoming data is available.
*/
void onNewData(byte[] data);
/**
* Called when {@link SerialInputOutputManager#run()} aborts due to an error.
*/
void onRunError(Exception e);
}
public SerialInputOutputManagerTest(UsbSerialPort serialPort) {
mSerialPort = serialPort;
mReadBuffer = ByteBuffer.allocate(serialPort.getReadEndpoint().getMaxPacketSize());
}
public SerialInputOutputManagerTest(UsbSerialPort serialPort, Listener listener) {
mSerialPort = serialPort;
mListener = listener;
mReadBuffer = ByteBuffer.allocate(serialPort.getReadEndpoint().getMaxPacketSize());
}
public synchronized void setListener(Listener listener) {
mListener = listener;
}
public synchronized Listener getListener() {
return mListener;
}
/**
* setThreadPriority. By default a higher priority than UI thread is used to prevent data loss
*
* @param threadPriority see {@link Process#setThreadPriority(int)}
* */
public void setThreadPriority(int threadPriority) {
if (mState != State.STOPPED)
throw new IllegalStateException("threadPriority only configurable before SerialInputOutputManager is started");
mThreadPriority = threadPriority;
}
/**
* read/write timeout
*/
public void setReadTimeout(int timeout) {
// when set if already running, read already blocks and the new value will not become effective now
if(mReadTimeout == 0 && timeout != 0 && mState != State.STOPPED)
throw new IllegalStateException("readTimeout only configurable before SerialInputOutputManager is started");
mReadTimeout = timeout;
}
public int getReadTimeout() {
return mReadTimeout;
}
public void setWriteTimeout(int timeout) {
mWriteTimeout = timeout;
}
public int getWriteTimeout() {
return mWriteTimeout;
}
/**
* read/write buffer size
*/
public void setReadBufferSize(int bufferSize) {
if (getReadBufferSize() == bufferSize)
return;
synchronized (mReadBufferLock) {
mReadBuffer = ByteBuffer.allocate(bufferSize);
}
}
public int getReadBufferSize() {
return mReadBuffer.capacity();
}
public void setWriteBufferSize(int bufferSize) {
if(getWriteBufferSize() == bufferSize)
return;
synchronized (mWriteBufferLock) {
ByteBuffer newWriteBuffer = ByteBuffer.allocate(bufferSize);
if(mWriteBuffer.position() > 0)
newWriteBuffer.put(mWriteBuffer.array(), 0, mWriteBuffer.position());
mWriteBuffer = newWriteBuffer;
}
}
public int getWriteBufferSize() {
return mWriteBuffer.capacity();
}
/**
* when using writeAsync, it is recommended to use readTimeout != 0,
* else the write will be delayed until read data is available
*/
public void writeAsync(byte[] data) {
synchronized (mWriteBufferLock) {
mWriteBuffer.put(data);
}
}
/**
* start SerialInputOutputManager in separate thread
*/
public void start() {
if(mState != State.STOPPED)
throw new IllegalStateException("already started");
new Thread(this, this.getClass().getSimpleName()).start();
}
/**
* stop SerialInputOutputManager thread
*
* when using readTimeout == 0 (default), additionally use usbSerialPort.close() to
* interrupt blocking read
*/
public synchronized void stop() {
if (getState() == State.RUNNING) {
Log.i(TAG, "Stop requested");
mState = State.STOPPING;
}
}
public synchronized State getState() {
return mState;
}
/**
* Continuously services the read and write buffers until {@link #stop()} is
* called, or until a driver exception is raised.
*/
@Override
public void run() {
synchronized (this) {
if (getState() != State.STOPPED) {
throw new IllegalStateException("Already running");
}
mState = State.RUNNING;
}
Log.i(TAG, "Running ...");
try {
if(mThreadPriority != Process.THREAD_PRIORITY_DEFAULT)
Process.setThreadPriority(mThreadPriority);
while (true) {
if (getState() != State.RUNNING) {
Log.i(TAG, "Stopping mState=" + getState());
break;
}
step();
}
} catch (Exception e) {
Log.w(TAG, "Run ending due to exception: " + e.getMessage(), e);
final Listener listener = getListener();
if (listener != null) {
listener.onRunError(e);
}
} finally {
synchronized (this) {
mState = State.STOPPED;
Log.i(TAG, "Stopped");
}
}
}
private void step() throws IOException {
// Handle incoming data.
byte[] buffer;
synchronized (mReadBufferLock) {
buffer = mReadBuffer.array();
}
int len = mSerialPort.read(buffer, mReadTimeout);
if (len > 0) {
if (DEBUG) Log.d(TAG, "Read data len=" + len);
final Listener listener = getListener();
if (listener != null) {
final byte[] data = new byte[len];
System.arraycopy(buffer, 0, data, 0, len);
listener.onNewData(data);
}
}
// Handle outgoing data.
buffer = null;
synchronized (mWriteBufferLock) {
len = mWriteBuffer.position();
if (len > 0) {
buffer = new byte[len];
mWriteBuffer.rewind();
mWriteBuffer.get(buffer, 0, len);
mWriteBuffer.clear();
}
}
if (buffer != null) {
if (DEBUG) {
Log.d(TAG, "Writing data len=" + len);
}
mSerialPort.write(buffer, mWriteTimeout);
}
}
}