Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
59ad9be7
Commit
59ad9be7
authored
Apr 18, 2015
by
dogmaphobic
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First android commit.
parent
9a141821
Changes
53
Hide whitespace changes
Inline
Side-by-side
Showing
53 changed files
with
7242 additions
and
55 deletions
+7242
-55
QGCApplication.pro
QGCApplication.pro
+64
-17
QGCCommon.pri
QGCCommon.pri
+4
-0
QGCSetup.pri
QGCSetup.pri
+8
-2
AndroidManifest.xml
android/AndroidManifest.xml
+67
-0
icon.png
android/res/drawable-ldpi/icon.png
+0
-0
device_filter.xml
android/res/xml/device_filter.xml
+40
-0
CdcAcmSerialDriver.java
...com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java
+252
-0
CommonUsbSerialDriver.java
.../hoho/android/usbserial/driver/CommonUsbSerialDriver.java
+156
-0
Cp2102SerialDriver.java
...com/hoho/android/usbserial/driver/Cp2102SerialDriver.java
+292
-0
FtdiSerialDriver.java
...c/com/hoho/android/usbserial/driver/FtdiSerialDriver.java
+552
-0
ProlificSerialDriver.java
...m/hoho/android/usbserial/driver/ProlificSerialDriver.java
+523
-0
UsbId.java
android/src/com/hoho/android/usbserial/driver/UsbId.java
+69
-0
UsbSerialDriver.java
...rc/com/hoho/android/usbserial/driver/UsbSerialDriver.java
+228
-0
UsbSerialProber.java
...rc/com/hoho/android/usbserial/driver/UsbSerialProber.java
+250
-0
UsbSerialRuntimeException.java
...o/android/usbserial/driver/UsbSerialRuntimeException.java
+46
-0
UsbDeviceJNI.java
android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java
+637
-0
UsbIoManager.java
android/src/org/qgroundcontrol/qgchelper/UsbIoManager.java
+218
-0
qextserialport_unix.cpp
libs/qextserialport/src/qextserialport_unix.cpp
+4
-0
qserialport.cpp
libs/qtandroidserialport/src/qserialport.cpp
+1375
-0
qserialport.h
libs/qtandroidserialport/src/qserialport.h
+287
-0
qserialport_android.cpp
libs/qtandroidserialport/src/qserialport_android.cpp
+867
-0
qserialport_android_p.h
libs/qtandroidserialport/src/qserialport_android_p.h
+133
-0
qserialport_p.h
libs/qtandroidserialport/src/qserialport_p.h
+338
-0
qserialportinfo.cpp
libs/qtandroidserialport/src/qserialportinfo.cpp
+292
-0
qserialportinfo.h
libs/qtandroidserialport/src/qserialportinfo.h
+95
-0
qserialportinfo_android.cpp
libs/qtandroidserialport/src/qserialportinfo_android.cpp
+158
-0
qserialportinfo_p.h
libs/qtandroidserialport/src/qserialportinfo_p.h
+95
-0
qtandroidserialport.pri
libs/qtandroidserialport/src/qtandroidserialport.pri
+28
-0
QGC.h
src/QGC.h
+3
-0
QGCFileDialog.cc
src/QGCFileDialog.cc
+10
-0
QGCMessageBox.h
src/QGCMessageBox.h
+4
-0
PX4Bootloader.cc
src/VehicleSetup/PX4Bootloader.cc
+4
-0
PX4FirmwareUpgradeThread.cc
src/VehicleSetup/PX4FirmwareUpgradeThread.cc
+4
-0
LinkConfiguration.cc
src/comm/LinkConfiguration.cc
+6
-0
LinkManager.cc
src/comm/LinkManager.cc
+8
-0
LinkManager.h
src/comm/LinkManager.h
+2
-0
SerialLink.cc
src/comm/SerialLink.cc
+6
-0
SerialLink.h
src/comm/SerialLink.h
+4
-0
main.cc
src/main.cc
+4
-0
UnitTest.h
src/qgcunittest/UnitTest.h
+2
-0
MainWindow.cc
src/ui/MainWindow.cc
+14
-1
MainWindow.h
src/ui/MainWindow.h
+4
-0
SerialConfigurationWindow.cc
src/ui/SerialConfigurationWindow.cc
+5
-0
SettingsDialog.cc
src/ui/SettingsDialog.cc
+12
-0
SettingsDialog.h
src/ui/SettingsDialog.h
+4
-0
SerialSettingsDialog.cc
src/ui/configuration/SerialSettingsDialog.cc
+5
-0
SerialSettingsDialog.h
src/ui/configuration/SerialSettingsDialog.h
+4
-0
terminalconsole.cpp
src/ui/configuration/terminalconsole.cpp
+5
-0
terminalconsole.h
src/ui/configuration/terminalconsole.h
+4
-0
QGCParamSlider.h
src/ui/designer/QGCParamSlider.h
+2
-0
QGCToolWidgetComboBox.h
src/ui/designer/QGCToolWidgetComboBox.h
+2
-1
MainToolBar.cc
src/ui/toolbar/MainToolBar.cc
+5
-0
MainToolBar.qml
src/ui/toolbar/MainToolBar.qml
+41
-34
No files found.
QGCApplication.pro
View file @
59ad9be7
...
...
@@ -61,12 +61,15 @@ QT += network \
qml
\
quick
\
quickwidgets
\
serialport
\
sql
\
svg
\
widgets
\
xml
\
!
AndroidBuild
{
QT
+=
serialport
}
contains
(
DEFINES
,
QGC_NOTIFY_TUNES_ENABLED
)
{
QT
+=
multimedia
}
...
...
@@ -78,6 +81,11 @@ QT += testlib
#
OS
Specific
settings
#
AndroidBuild
{
DEFINES
+=
__android__
DEFINES
+=
__STDC_LIMIT_MACROS
}
MacBuild
{
QMAKE_INFO_PLIST
=
Custom
-
Info
.
plist
ICON
=
$$
BASEDIR
/
resources
/
icons
/
macx
.
icns
...
...
@@ -173,9 +181,6 @@ FORMS += \
src
/
ui
/
designer
/
QGCToolWidgetComboBox
.
ui
\
src
/
ui
/
designer
/
QGCXYPlot
.
ui
\
src
/
ui
/
HDDisplay
.
ui
\
src
/
ui
/
JoystickAxis
.
ui
\
src
/
ui
/
JoystickButton
.
ui
\
src
/
ui
/
JoystickWidget
.
ui
\
src
/
ui
/
Linechart
.
ui
\
src
/
ui
/
MainWindow
.
ui
\
src
/
ui
/
map
/
QGCMapTool
.
ui
\
...
...
@@ -229,6 +234,13 @@ FORMS += \
src
/
ui
/
WaypointList
.
ui
\
src
/
ui
/
WaypointViewOnlyView
.
ui
\
!
AndroidBuild
{
FORMS
+=
\
src
/
ui
/
JoystickButton
.
ui
\
src
/
ui
/
JoystickAxis
.
ui
\
src
/
ui
/
JoystickWidget
.
ui
}
HEADERS
+=
\
src
/
audio
/
QGCAudioWorker
.
h
\
src
/
CmdLineOptParser
.
h
\
...
...
@@ -250,7 +262,6 @@ HEADERS += \
src
/
comm
/
TCPLink
.
h
\
src
/
comm
/
UDPLink
.
h
\
src
/
GAudioOutput
.
h
\
src
/
input
/
JoystickInput
.
h
\
src
/
LogCompressor
.
h
\
src
/
MG
.
h
\
src
/
QGC
.
h
\
...
...
@@ -281,7 +292,6 @@ HEADERS += \
src
/
uas
/
UASParameterCommsMgr
.
h
\
src
/
uas
/
UASParameterDataModel
.
h
\
src
/
uas
/
UASWaypointManager
.
h
\
src
/
ui
/
CameraView
.
h
\
src
/
ui
/
configuration
/
ApmHighlighter
.
h
\
src
/
ui
/
configuration
/
console
.
h
\
src
/
ui
/
configuration
/
SerialSettingsDialog
.
h
\
...
...
@@ -300,9 +310,6 @@ HEADERS += \
src
/
ui
/
HDDisplay
.
h
\
src
/
ui
/
HSIDisplay
.
h
\
src
/
ui
/
HUD
.
h
\
src
/
ui
/
JoystickAxis
.
h
\
src
/
ui
/
JoystickButton
.
h
\
src
/
ui
/
JoystickWidget
.
h
\
src
/
ui
/
linechart
/
ChartPlot
.
h
\
src
/
ui
/
linechart
/
IncrementalPlot
.
h
\
src
/
ui
/
linechart
/
LinechartPlot
.
h
\
...
...
@@ -376,6 +383,15 @@ HEADERS += \
src
/
ViewWidgets
/
ViewWidgetController
.
h
\
src
/
Waypoint
.
h
\
!
AndroidBuild
{
HEADERS
+=
\
src
/
input
/
JoystickInput
.
h
\
src
/
ui
/
JoystickAxis
.
h
\
src
/
ui
/
JoystickButton
.
h
\
src
/
ui
/
JoystickWidget
.
h
\
src
/
ui
/
CameraView
.
h
\
}
SOURCES
+=
\
src
/
audio
/
QGCAudioWorker
.
cpp
\
src
/
CmdLineOptParser
.
cc
\
...
...
@@ -393,7 +409,6 @@ SOURCES += \
src
/
comm
/
TCPLink
.
cc
\
src
/
comm
/
UDPLink
.
cc
\
src
/
GAudioOutput
.
cc
\
src
/
input
/
JoystickInput
.
cc
\
src
/
LogCompressor
.
cc
\
src
/
main
.
cc
\
src
/
QGC
.
cc
\
...
...
@@ -418,7 +433,6 @@ SOURCES += \
src
/
uas
/
UASParameterCommsMgr
.
cc
\
src
/
uas
/
UASParameterDataModel
.
cc
\
src
/
uas
/
UASWaypointManager
.
cc
\
src
/
ui
/
CameraView
.
cc
\
src
/
ui
/
configuration
/
ApmHighlighter
.
cc
\
src
/
ui
/
configuration
/
console
.
cpp
\
src
/
ui
/
configuration
/
SerialSettingsDialog
.
cc
\
...
...
@@ -437,9 +451,6 @@ SOURCES += \
src
/
ui
/
HDDisplay
.
cc
\
src
/
ui
/
HSIDisplay
.
cc
\
src
/
ui
/
HUD
.
cc
\
src
/
ui
/
JoystickAxis
.
cc
\
src
/
ui
/
JoystickButton
.
cc
\
src
/
ui
/
JoystickWidget
.
cc
\
src
/
ui
/
linechart
/
ChartPlot
.
cc
\
src
/
ui
/
linechart
/
IncrementalPlot
.
cc
\
src
/
ui
/
linechart
/
LinechartPlot
.
cc
\
...
...
@@ -513,6 +524,15 @@ SOURCES += \
src
/
ViewWidgets
/
ViewWidgetController
.
cc
\
src
/
Waypoint
.
cc
\
!
AndroidBuild
{
SOURCES
+=
\
src
/
input
/
JoystickInput
.
cc
\
src
/
ui
/
JoystickAxis
.
cc
\
src
/
ui
/
JoystickButton
.
cc
\
src
/
ui
/
JoystickWidget
.
cc
\
src
/
ui
/
CameraView
.
cc
}
#
#
Unit
Test
specific
configuration
goes
here
#
...
...
@@ -524,6 +544,11 @@ SOURCES += \
DebugBuild
|
WindowsDebugAndRelease
{
HEADERS
+=
src
/
QmlControls
/
QmlTestWidget
.
h
SOURCES
+=
src
/
QmlControls
/
QmlTestWidget
.
cc
!
AndroidBuild
{
INCLUDEPATH
+=
\
src
/
qgcunittest
...
...
@@ -550,7 +575,6 @@ HEADERS += \
src
/
qgcunittest
/
MockLinkMissionItemHandler
.
h
\
src
/
qgcunittest
/
PX4RCCalibrationTest
.
h
\
src
/
qgcunittest
/
UnitTest
.
h
\
src
/
QmlControls
/
QmlTestWidget
.
h
\
src
/
VehicleSetup
/
SetupViewTest
.
h
\
SOURCES
+=
\
...
...
@@ -575,10 +599,10 @@ SOURCES += \
src
/
qgcunittest
/
MockLinkMissionItemHandler
.
cc
\
src
/
qgcunittest
/
PX4RCCalibrationTest
.
cc
\
src
/
qgcunittest
/
UnitTest
.
cc
\
src
/
QmlControls
/
QmlTestWidget
.
cc
\
src
/
VehicleSetup
/
SetupViewTest
.
cc
\
}
}
#
DebugBuild
|
WindowsDebugAndRelease
}
#
AndroidBuild
#
#
AutoPilot
Plugin
Support
...
...
@@ -658,3 +682,26 @@ SOURCES += \
src
/
FactSystem
/
FactSystem
.
cc
\
src
/
FactSystem
/
FactValidator
.
cc
\
src
/
FactSystem
/
ParameterLoader
.
cc
\
#
Android
AndroidBuild
{
include
(
$$
PWD
/
libs
/
qtandroidserialport
/
src
/
qtandroidserialport
.
pri
)
message
(
"Adding Serial Java Classes"
)
QT
+=
androidextras
ANDROID_PACKAGE_SOURCE_DIR
=
$$
PWD
/
android
OTHER_FILES
+=
\
$$
PWD
/
android
/
AndroidManifest
.
xml
\
$$
PWD
/
android
/
res
/
xml
/
device_filter
.
xml
\
$$
PWD
/
android
/
src
/
com
/
hoho
/
android
/
usbserial
/
driver
/
CdcAcmSerialDriver
.
java
\
$$
PWD
/
android
/
src
/
com
/
hoho
/
android
/
usbserial
/
driver
/
CommonUsbSerialDriver
.
java
\
$$
PWD
/
android
/
src
/
com
/
hoho
/
android
/
usbserial
/
driver
/
Cp2102SerialDriver
.
java
\
$$
PWD
/
android
/
src
/
com
/
hoho
/
android
/
usbserial
/
driver
/
FtdiSerialDriver
.
java
\
$$
PWD
/
android
/
src
/
com
/
hoho
/
android
/
usbserial
/
driver
/
ProlificSerialDriver
.
java
\
$$
PWD
/
android
/
src
/
com
/
hoho
/
android
/
usbserial
/
driver
/
UsbId
.
java
\
$$
PWD
/
android
/
src
/
com
/
hoho
/
android
/
usbserial
/
driver
/
UsbSerialDriver
.
java
\
$$
PWD
/
android
/
src
/
com
/
hoho
/
android
/
usbserial
/
driver
/
UsbSerialProber
.
java
\
$$
PWD
/
android
/
src
/
com
/
hoho
/
android
/
usbserial
/
driver
/
UsbSerialRuntimeException
.
java
\
$$
PWD
/
android
/
src
/
org
/
qgroundcontrol
/
qgchelper
/
UsbDeviceJNI
.
java
\
$$
PWD
/
android
/
src
/
org
/
qgroundcontrol
/
qgchelper
/
UsbIoManager
.
java
}
QGCCommon.pri
View file @
59ad9be7
...
...
@@ -30,6 +30,10 @@ linux {
linux-g++ | linux-g++-64 {
message("Linux build")
CONFIG += LinuxBuild
} else : android-g++ {
message("Android build")
CONFIG += AndroidBuild
warning("Android build is experimental and not fully functional")
} else {
error("Unsuported Linux toolchain, only GCC 32- or 64-bit is supported")
}
...
...
QGCSetup.pri
View file @
59ad9be7
...
...
@@ -19,6 +19,10 @@
QMAKE_POST_LINK += echo "Copying files"
AndroidBuild {
INSTALLS += $$DESTDIR
}
#
# Copy the application resources to the associated place alongside the application
#
...
...
@@ -40,8 +44,10 @@ WindowsBuild {
BASEDIR_COPY_RESOURCE_LIST = $$replace(BASEDIR,"/","\\")
QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY_DIR \"$$BASEDIR_COPY_RESOURCE_LIST\\flightgear\" \"$$DESTDIR_COPY_RESOURCE_LIST\\flightgear\"
} else {
# Make sure to keep both side of this if using the same set of directories
QMAKE_POST_LINK += && $$QMAKE_COPY_DIR $$BASEDIR/flightgear $$DESTDIR_COPY_RESOURCE_LIST
!AndroidBuild {
# Make sure to keep both sides of this if using the same set of directories
QMAKE_POST_LINK += && $$QMAKE_COPY_DIR $$BASEDIR/flightgear $$DESTDIR_COPY_RESOURCE_LIST
}
}
#
...
...
android/AndroidManifest.xml
0 → 100644
View file @
59ad9be7
<?xml version="1.0"?>
<manifest
package=
"org.qgroundcontrol"
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:versionName=
"2.3.0"
android:versionCode=
"2"
android:installLocation=
"auto"
>
<application
android:hardwareAccelerated=
"true"
android:name=
"org.qtproject.qt5.android.bindings.QtApplication"
android:label=
"-- %%INSERT_APP_NAME%% --"
android:icon=
"@drawable/icon"
>
<activity
android:configChanges=
"orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
android:name=
"org.qgroundcontrol.qgchelper.UsbDeviceJNI"
android:label=
"-- %%INSERT_APP_NAME%% --"
android:screenOrientation=
"reverseLandscape"
android:launchMode=
"singleTask"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
<action
android:name=
"android.hardware.usb.action.USB_DEVICE_ATTACHED"
/>
<action
android:name=
"android.hardware.usb.action.USB_DEVICE_DETACHED"
/>
</intent-filter>
<!-- Needed to keep working while 'asleep' -->
<uses-permission
android:name=
"android.permission.WAKE_LOCK"
/>
<!-- Support devices without USB host mode since there are other connection types -->
<uses-feature
android:name=
"android.hardware.usb.host"
android:required=
"false"
/>
<meta-data
android:resource=
"@xml/device_filter"
android:name=
"android.hardware.usb.action.USB_DEVICE_ATTACHED"
/>
<meta-data
android:resource=
"@xml/device_filter"
android:name=
"android.hardware.usb.action.USB_DEVICE_DETACHED"
/>
<!-- Rest of Standard Manifest -->
<meta-data
android:name=
"android.app.lib_name"
android:value=
"-- %%INSERT_APP_LIB_NAME%% --"
/>
<meta-data
android:name=
"android.app.qt_sources_resource_id"
android:resource=
"@array/qt_sources"
/>
<meta-data
android:name=
"android.app.repository"
android:value=
"default"
/>
<meta-data
android:name=
"android.app.qt_libs_resource_id"
android:resource=
"@array/qt_libs"
/>
<meta-data
android:name=
"android.app.bundled_libs_resource_id"
android:resource=
"@array/bundled_libs"
/>
<!-- Deploy Qt libs as part of package -->
<meta-data
android:name=
"android.app.bundle_local_qt_libs"
android:value=
"-- %%BUNDLE_LOCAL_QT_LIBS%% --"
/>
<meta-data
android:name=
"android.app.bundled_in_lib_resource_id"
android:resource=
"@array/bundled_in_lib"
/>
<meta-data
android:name=
"android.app.bundled_in_assets_resource_id"
android:resource=
"@array/bundled_in_assets"
/>
<!-- Run with local libs -->
<meta-data
android:name=
"android.app.use_local_qt_libs"
android:value=
"-- %%USE_LOCAL_QT_LIBS%% --"
/>
<meta-data
android:name=
"android.app.libs_prefix"
android:value=
"/data/local/tmp/qt/"
/>
<meta-data
android:name=
"android.app.load_local_libs"
android:value=
"-- %%INSERT_LOCAL_LIBS%% --"
/>
<meta-data
android:name=
"android.app.load_local_jars"
android:value=
"-- %%INSERT_LOCAL_JARS%% --"
/>
<meta-data
android:name=
"android.app.static_init_classes"
android:value=
"-- %%INSERT_INIT_CLASSES%% --"
/>
<!-- Messages maps -->
<meta-data
android:value=
"@string/ministro_not_found_msg"
android:name=
"android.app.ministro_not_found_msg"
/>
<meta-data
android:value=
"@string/ministro_needed_msg"
android:name=
"android.app.ministro_needed_msg"
/>
<meta-data
android:value=
"@string/fatal_error_msg"
android:name=
"android.app.fatal_error_msg"
/>
<!-- Messages maps -->
<!-- Splash screen -->
<!--
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
-->
<!-- Splash screen -->
<!-- Background running -->
<!-- Warning: changing this value to true may cause unexpected crashes if the
application still try to draw after
"applicationStateChanged(Qt::ApplicationSuspended)"
signal is sent! -->
<meta-data
android:name=
"android.app.background_running"
android:value=
"false"
/>
<!-- Background running -->
</activity>
</application>
<uses-sdk
android:minSdkVersion=
"19"
android:targetSdkVersion=
"19"
/>
<supports-screens
android:largeScreens=
"true"
android:normalScreens=
"true"
android:anyDensity=
"true"
android:smallScreens=
"true"
/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Remove the comment if you do not require these default permissions. -->
<!-- %%INSERT_PERMISSIONS -->
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES -->
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
</manifest>
android/res/drawable-ldpi/icon.png
0 → 100644
View file @
59ad9be7
48.1 KB
android/res/xml/device_filter.xml
0 → 100644
View file @
59ad9be7
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Everything -->
<usb-device
/>
<!-- 0x26AC / 0x11: PX4 FMU Pixhawk -->
<!--
<usb-device vendor-id="9900" product-id="17" />
-->
<!-- 0x0403 / 0x6001: FTDI FT232R UART -->
<!--
<usb-device vendor-id="1027" product-id="24577" />
-->
<!-- 0x0403 / 0x6015: FTDI FT231X -->
<!--
<usb-device vendor-id="1027" product-id="24597" />
-->
<!-- 0x2341 / Arduino -->
<!--
<usb-device vendor-id="9025" />
-->
<!-- 0x16C0 / 0x0483: Teensyduino -->
<!--
<usb-device vendor-id="5824" product-id="1155" />
-->
<!-- 0x10C4 / 0xEA60: CP210x UART Bridge -->
<!--
<usb-device vendor-id="4292" product-id="60000" />
-->
<!-- 0x067B / 0x2303: Prolific PL2303 -->
<!--
<usb-device vendor-id="1659" product-id="8963" />
-->
</resources>
android/src/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java
0 → 100644
View file @
59ad9be7
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.LinkedHashMap
;
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
extends
CommonUsbSerialDriver
{
private
final
String
TAG
=
CdcAcmSerialDriver
.
class
.
getSimpleName
();
private
UsbInterface
mControlInterface
;
private
UsbInterface
mDataInterface
;
private
UsbEndpoint
mControlEndpoint
;
private
UsbEndpoint
mReadEndpoint
;
private
UsbEndpoint
mWriteEndpoint
;
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
CdcAcmSerialDriver
(
UsbDevice
device
,
UsbDeviceConnection
connection
)
{
super
(
device
,
connection
);
}
@Override
public
void
open
()
throws
IOException
{
Log
.
d
(
TAG
,
"claiming interfaces, count="
+
mDevice
.
getInterfaceCount
());
Log
.
d
(
TAG
,
"Claiming control interface."
);
mControlInterface
=
mDevice
.
getInterface
(
0
);
Log
.
d
(
TAG
,
"Control iface="
+
mControlInterface
);
// class should be USB_CLASS_COMM
if
(!
mConnection
.
claimInterface
(
mControlInterface
,
true
))
{
throw
new
IOException
(
"Could not claim control interface."
);
}
mControlEndpoint
=
mControlInterface
.
getEndpoint
(
0
);
Log
.
d
(
TAG
,
"Control endpoint direction: "
+
mControlEndpoint
.
getDirection
());
Log
.
d
(
TAG
,
"Claiming data interface."
);
mDataInterface
=
mDevice
.
getInterface
(
1
);
Log
.
d
(
TAG
,
"data iface="
+
mDataInterface
);
// class should be USB_CLASS_CDC_DATA
if
(!
mConnection
.
claimInterface
(
mDataInterface
,
true
))
{
throw
new
IOException
(
"Could not claim data interface."
);
}
mReadEndpoint
=
mDataInterface
.
getEndpoint
(
1
);
Log
.
d
(
TAG
,
"Read endpoint direction: "
+
mReadEndpoint
.
getDirection
());
mWriteEndpoint
=
mDataInterface
.
getEndpoint
(
0
);
Log
.
d
(
TAG
,
"Write endpoint direction: "
+
mWriteEndpoint
.
getDirection
());
}
private
int
sendAcmControlMessage
(
int
request
,
int
value
,
byte
[]
buf
)
{
return
mConnection
.
controlTransfer
(
USB_RT_ACM
,
request
,
value
,
0
,
buf
,
buf
!=
null
?
buf
.
length
:
0
,
5000
);
}
@Override
public
void
close
()
throws
IOException
{
mConnection
.
close
();
}
@Override
public
int
read
(
byte
[]
dest
,
int
timeoutMillis
)
throws
IOException
{
final
int
numBytesRead
;
synchronized
(
mReadBufferLock
)
{
int
readAmt
=
Math
.
min
(
dest
.
length
,
mReadBuffer
.
length
);
numBytesRead
=
mConnection
.
bulkTransfer
(
mReadEndpoint
,
mReadBuffer
,
readAmt
,
timeoutMillis
);
if
(
numBytesRead
<
0
)
{
// This sucks: we get -1 on timeout, not 0 as preferred.
// We *should* use UsbRequest, except it has a bug/api oversight
// where there is no way to determine the number of bytes read
// in response :\ -- http://b.android.com/28023
return
0
;
}
System
.
arraycopy
(
mReadBuffer
,
0
,
dest
,
0
,
numBytesRead
);
}
return
numBytesRead
;
}
@Override
public
int
write
(
byte
[]
src
,
int
timeoutMillis
)
throws
IOException
{
// TODO(mikey): Nearly identical to FtdiSerial write. Refactor.
int
offset
=
0
;
while
(
offset
<
src
.
length
)
{
final
int
writeLength
;
final
int
amtWritten
;
synchronized
(
mWriteBufferLock
)
{
final
byte
[]
writeBuffer
;
writeLength
=
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
,
writeLength
);
writeBuffer
=
mWriteBuffer
;
}
amtWritten
=
mConnection
.
bulkTransfer
(
mWriteEndpoint
,
writeBuffer
,
writeLength
,
timeoutMillis
);
}
if
(
amtWritten
<=
0
)
{
throw
new
IOException
(
"Error writing "
+
writeLength
+
" bytes at offset "
+
offset
+
" length="
+
src
.
length
);
}
//Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength);
offset
+=
amtWritten
;
}
return
offset
;
}
@Override
public
void
setParameters
(
int
baudRate
,
int
dataBits
,
int
stopBits
,
int
parity
)
{
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
(
"Bad value for stopBits: "
+
stopBits
);
}
byte
parityBitesByte
;
switch
(
parity
)
{
case
PARITY_NONE:
parityBitesByte
=
0
;
break
;
case
PARITY_ODD:
parityBitesByte
=
1
;
break
;
case
PARITY_EVEN:
parityBitesByte
=
2
;
break
;
case
PARITY_MARK:
parityBitesByte
=
3
;
break
;
case
PARITY_SPACE:
parityBitesByte
=
4
;
break
;
default
:
throw
new
IllegalArgumentException
(
"Bad value for 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
getCD
()
throws
IOException
{
return
false
;
// TODO
}
@Override
public
boolean
getCTS
()
throws
IOException
{
return
false
;
// TODO
}
@Override
public
boolean
getDSR
()
throws
IOException
{
return
false
;
// TODO
}
@Override
public
boolean
getDTR
()
throws
IOException
{
return
mDtr
;
}
@Override
public
void
setDTR
(
boolean
value
)
throws
IOException
{
mDtr
=
value
;
setDtrRts
();
}
@Override
public
boolean
getRI
()
throws
IOException
{
return
false
;
// TODO
}
@Override
public
boolean
getRTS
()
throws
IOException
{
return
mRts
;
}
@Override
public
void
setRTS
(
boolean
value
)
throws
IOException
{
mRts
=
value
;
setDtrRts
();
}
private
void
setDtrRts
()
{
int
value
=
(
mRts
?
0x2
:
0
)
|
(
mDtr
?
0x1
:
0
);
sendAcmControlMessage
(
SET_CONTROL_LINE_STATE
,
value
,
null
);
}
public
static
Map
<
Integer
,
int
[]>
getSupportedDevices
()
{
final
Map
<
Integer
,
int
[]>
supportedDevices
=
new
LinkedHashMap
<
Integer
,
int
[]>();
supportedDevices
.
put
(
Integer
.
valueOf
(
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
,
});
supportedDevices
.
put
(
Integer
.
valueOf
(
UsbId
.
VENDOR_VAN_OOIJEN_TECH
),
new
int
[]
{
UsbId
.
VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL
,
});
supportedDevices
.
put
(
Integer
.
valueOf
(
UsbId
.
VENDOR_ATMEL
),
new
int
[]
{
UsbId
.
ATMEL_LUFA_CDC_DEMO_APP
,
});
supportedDevices
.
put
(
Integer
.
valueOf
(
UsbId
.
VENDOR_LEAFLABS
),
new
int
[]
{
UsbId
.
LEAFLABS_MAPLE
,
});
supportedDevices
.
put
(
Integer
.
valueOf
(
UsbId
.
VENDOR_PX4
),
new
int
[]
{
UsbId
.
DEVICE_PX4FMU
,
});
return
supportedDevices
;
}
}
android/src/com/hoho/android/usbserial/driver/CommonUsbSerialDriver.java
0 → 100644
View file @
59ad9be7
/* Copyright 2013 Google Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* Project home page: http://code.google.com/p/usb-serial-for-android/
*/
package
com
.
hoho
.
android
.
usbserial
.
driver
;
import
android.hardware.usb.UsbDevice
;
import
android.hardware.usb.UsbDeviceConnection
;
import
java.io.IOException
;
/**
* A base class shared by several driver implementations.
*
* @author mike wakerly (opensource@hoho.com)
*/
abstract
class
CommonUsbSerialDriver
implements
UsbSerialDriver
{
public
static
final
int
DEFAULT_READ_BUFFER_SIZE
=
16
*
1024
;
public
static
final
int
DEFAULT_WRITE_BUFFER_SIZE
=
16
*
1024
;
protected
final
UsbDevice
mDevice
;
protected
final
UsbDeviceConnection
mConnection
;
protected
final
Object
mReadBufferLock
=
new
Object
();
protected
final
Object
mWriteBufferLock
=
new
Object
();
/** Internal read buffer. Guarded by {@link #mReadBufferLock}. */
protected
byte
[]
mReadBuffer
;
/** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
protected
byte
[]
mWriteBuffer
;
public
CommonUsbSerialDriver
(
UsbDevice
device
,
UsbDeviceConnection
connection
)
{
mDevice
=
device
;
mConnection
=
connection
;
mReadBuffer
=
new
byte
[
DEFAULT_READ_BUFFER_SIZE
];
mWriteBuffer
=
new
byte
[
DEFAULT_WRITE_BUFFER_SIZE
];
}
/**
* Returns the currently-bound USB device.
*
* @return the device
*/
@Override
public
final
UsbDevice
getDevice
()
{
return
mDevice
;
}
/**
* Returns the currently-bound USB device connection.
*
* @return the device connection
*/
@Override
public
final
UsbDeviceConnection
getDeviceConnection
()
{
return
mConnection
;
}
/**
* Sets the size of the internal buffer used to exchange data with the USB
* stack for read operations. Most users should not need to change this.
*
* @param bufferSize the size in bytes
*/
public
final
void
setReadBufferSize
(
int
bufferSize
)
{
synchronized
(
mReadBufferLock
)
{
if
(
bufferSize
==
mReadBuffer
.
length
)
{
return
;
}
mReadBuffer
=
new
byte
[
bufferSize
];
}
}
/**
* 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
abstract
void
open
()
throws
IOException
;
@Override
public
abstract
void
close
()
throws
IOException
;
@Override
public
abstract
int
read
(
final
byte
[]
dest
,
final
int
timeoutMillis
)
throws
IOException
;
@Override
public
abstract
int
write
(
final
byte
[]
src
,
final
int
timeoutMillis
)
throws
IOException
;
@Override
public
abstract
void
setParameters
(
int
baudRate
,
int
dataBits
,
int
stopBits
,
int
parity
)
throws
IOException
;
@Override
public
abstract
boolean
getCD
()
throws
IOException
;
@Override
public
abstract
boolean
getCTS
()
throws
IOException
;
@Override
public
abstract
boolean
getDSR
()
throws
IOException
;
@Override
public
abstract
boolean
getDTR
()
throws
IOException
;
@Override
public
abstract
void
setDTR
(
boolean
value
)
throws
IOException
;
@Override
public
abstract
boolean
getRI
()
throws
IOException
;
@Override
public
abstract
boolean
getRTS
()
throws
IOException
;
@Override
public
abstract
void
setRTS
(
boolean
value
)
throws
IOException
;
@Override
public
boolean
purgeHwBuffers
(
boolean
flushReadBuffers
,
boolean
flushWriteBuffers
)
throws
IOException
{
return
!
flushReadBuffers
&&
!
flushWriteBuffers
;
}
}
android/src/com/hoho/android/usbserial/driver/Cp2102SerialDriver.java
0 → 100644
View file @
59ad9be7
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.LinkedHashMap
;
import
java.util.Map
;
public
class
Cp2102SerialDriver
extends
CommonUsbSerialDriver
{
private
static
final
String
TAG
=
Cp2102SerialDriver
.
class
.
getSimpleName
();
private
static
final
int
DEFAULT_BAUD_RATE
=
9600
;
private
static
final
int
USB_WRITE_TIMEOUT_MILLIS
=
5000
;
/*
* Configuration Request Types
*/
private
static
final
int
REQTYPE_HOST_TO_DEVICE
=
0x41
;
/*
* Configuration Request Codes
*/
private
static
final
int
SILABSER_IFC_ENABLE_REQUEST_CODE
=
0x00
;
private
static
final
int
SILABSER_SET_BAUDDIV_REQUEST_CODE
=
0x01
;
private
static
final
int
SILABSER_SET_LINE_CTL_REQUEST_CODE
=
0x03
;
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
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_BAUDDIV_REQUEST_CODE
*/
private
static
final
int
BAUD_RATE_GEN_FREQ
=
0x384000
;
/*
* SILABSER_SET_MHS_REQUEST_CODE
*/
private
static
final
int
MCR_DTR
=
0x0001
;
private
static
final
int
MCR_RTS
=
0x0002
;
private
static
final
int
MCR_ALL
=
0x0003
;
private
static
final
int
CONTROL_WRITE_DTR
=
0x0100
;
private
static
final
int
CONTROL_WRITE_RTS
=
0x0200
;
private
UsbEndpoint
mReadEndpoint
;
private
UsbEndpoint
mWriteEndpoint
;
public
Cp2102SerialDriver
(
UsbDevice
device
,
UsbDeviceConnection
connection
)
{
super
(
device
,
connection
);
}
private
int
setConfigSingle
(
int
request
,
int
value
)
{
return
mConnection
.
controlTransfer
(
REQTYPE_HOST_TO_DEVICE
,
request
,
value
,
0
,
null
,
0
,
USB_WRITE_TIMEOUT_MILLIS
);
}
@Override
public
void
open
()
throws
IOException
{
boolean
opened
=
false
;
try
{
for
(
int
i
=
0
;
i
<
mDevice
.
getInterfaceCount
();
i
++)
{
UsbInterface
usbIface
=
mDevice
.
getInterface
(
i
);
if
(
mConnection
.
claimInterface
(
usbIface
,
true
))
{
Log
.
d
(
TAG
,
"claimInterface "
+
i
+
" SUCCESS"
);
}
else
{
Log
.
d
(
TAG
,
"claimInterface "
+
i
+
" FAIL"
);
}
}
UsbInterface
dataIface
=
mDevice
.
getInterface
(
mDevice
.
getInterfaceCount
()
-
1
);
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
,
MCR_ALL
|
CONTROL_WRITE_DTR
|
CONTROL_WRITE_RTS
);
setConfigSingle
(
SILABSER_SET_BAUDDIV_REQUEST_CODE
,
BAUD_RATE_GEN_FREQ
/
DEFAULT_BAUD_RATE
);
// setParameters(DEFAULT_BAUD_RATE, DEFAULT_DATA_BITS, DEFAULT_STOP_BITS, DEFAULT_PARITY);
opened
=
true
;
}
finally
{
if
(!
opened
)
{
close
();
}
}
}
@Override
public
void
close
()
throws
IOException
{
setConfigSingle
(
SILABSER_IFC_ENABLE_REQUEST_CODE
,
UART_DISABLE
);
mConnection
.
close
();
}
@Override
public
int
read
(
byte
[]
dest
,
int
timeoutMillis
)
throws
IOException
{
final
int
numBytesRead
;
synchronized
(
mReadBufferLock
)
{
int
readAmt
=
Math
.
min
(
dest
.
length
,
mReadBuffer
.
length
);
numBytesRead
=
mConnection
.
bulkTransfer
(
mReadEndpoint
,
mReadBuffer
,
readAmt
,
timeoutMillis
);
if
(
numBytesRead
<
0
)
{
// This sucks: we get -1 on timeout, not 0 as preferred.
// We *should* use UsbRequest, except it has a bug/api oversight
// where there is no way to determine the number of bytes read
// in response :\ -- http://b.android.com/28023
return
0
;
}
System
.
arraycopy
(
mReadBuffer
,
0
,
dest
,
0
,
numBytesRead
);
}
return
numBytesRead
;
}
@Override
public
int
write
(
byte
[]
src
,
int
timeoutMillis
)
throws
IOException
{
int
offset
=
0
;
while
(
offset
<
src
.
length
)
{
final
int
writeLength
;
final
int
amtWritten
;
synchronized
(
mWriteBufferLock
)
{
final
byte
[]
writeBuffer
;
writeLength
=
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
,
writeLength
);
writeBuffer
=
mWriteBuffer
;
}
amtWritten
=
mConnection
.
bulkTransfer
(
mWriteEndpoint
,
writeBuffer
,
writeLength
,
timeoutMillis
);
}
if
(
amtWritten
<=
0
)
{
throw
new
IOException
(
"Error writing "
+
writeLength
+
" bytes at offset "
+
offset
+
" length="
+
src
.
length
);
}
//Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength);
offset
+=
amtWritten
;
}
return
offset
;
}
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
,
0
,
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
{
setBaudRate
(
baudRate
);
int
configDataBits
=
0
;
switch
(
dataBits
)
{
case
DATABITS_5:
configDataBits
|=
0x0500
;
break
;
case
DATABITS_6:
configDataBits
|=
0x0600
;
break
;
case
DATABITS_7:
configDataBits
|=
0x0700
;
break
;
case
DATABITS_8:
configDataBits
|=
0x0800
;
break
;
default
:
configDataBits
|=
0x0800
;
break
;
}
setConfigSingle
(
SILABSER_SET_LINE_CTL_REQUEST_CODE
,
configDataBits
);
int
configParityBits
=
0
;
// PARITY_NONE
switch
(
parity
)
{
case
PARITY_ODD:
configParityBits
|=
0x0010
;
break
;
case
PARITY_EVEN:
configParityBits
|=
0x0020
;
break
;
}
setConfigSingle
(
SILABSER_SET_LINE_CTL_REQUEST_CODE
,
configParityBits
);
int
configStopBits
=
0
;
switch
(
stopBits
)
{
case
STOPBITS_1:
configStopBits
|=
0
;
break
;
case
STOPBITS_2:
configStopBits
|=
2
;
break
;
}
setConfigSingle
(
SILABSER_SET_LINE_CTL_REQUEST_CODE
,
configStopBits
);
}
@Override
public
boolean
getCD
()
throws
IOException
{
return
false
;
}
@Override
public
boolean
getCTS
()
throws
IOException
{
return
false
;
}
@Override
public
boolean
getDSR
()
throws
IOException
{
return
false
;
}
@Override
public
boolean
getDTR
()
throws
IOException
{
return
true
;
}
@Override
public
void
setDTR
(
boolean
value
)
throws
IOException
{
}
@Override
public
boolean
getRI
()
throws
IOException
{
return
false
;
}
@Override
public
boolean
getRTS
()
throws
IOException
{
return
true
;
}
@Override
public
boolean
purgeHwBuffers
(
boolean
purgeReadBuffers
,
boolean
purgeWriteBuffers
)
throws
IOException
{
int
value
=
(
purgeReadBuffers
?
FLUSH_READ_CODE
:
0
)
|
(
purgeWriteBuffers
?
FLUSH_WRITE_CODE
:
0
);
if
(
value
!=
0
)
{
setConfigSingle
(
SILABSER_FLUSH_REQUEST_CODE
,
value
);
}
return
true
;
}
@Override
public
void
setRTS
(
boolean
value
)
throws
IOException
{
}
public
static
Map
<
Integer
,
int
[]>
getSupportedDevices
()
{
final
Map
<
Integer
,
int
[]>
supportedDevices
=
new
LinkedHashMap
<
Integer
,
int
[]>();
supportedDevices
.
put
(
Integer
.
valueOf
(
UsbId
.
VENDOR_SILAB
),
new
int
[]
{
UsbId
.
SILAB_CP2102
});
return
supportedDevices
;
}
}
android/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java
0 → 100644
View file @
59ad9be7
/* Copyright 2011 Google Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* Project home page: http://code.google.com/p/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.UsbRequest
;
import
android.util.Log
;
import
java.io.IOException
;
import
java.nio.ByteBuffer
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
/**
* A {@link CommonUsbSerialDriver} implementation for a variety of FTDI devices
* <p>
* This driver is based on
* <a href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is
* copyright and subject to the following terms:
*
* <pre>
* Copyright (C) 2003 by Intra2net AG
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation;
*
* opensource@intra2net.com
* http://www.intra2net.com/en/developer/libftdi
* </pre>
*
* </p>
* <p>
* Some FTDI devices have not been tested; see later listing of supported and
* unsupported devices. Devices listed as "supported" support the following
* features:
* <ul>
* <li>Read and write of serial data (see {@link #read(byte[], int)} and
* {@link #write(byte[], int)}.
* <li>Setting baud rate (see {@link #setBaudRate(int)}).
* </ul>
* </p>
* <p>
* Supported and tested devices:
* <ul>
* <li>{@value DeviceType#TYPE_R}</li>
* </ul>
* </p>
* <p>
* Unsupported but possibly working devices (please contact the author with
* feedback or patches):
* <ul>
* <li>{@value DeviceType#TYPE_2232C}</li>
* <li>{@value DeviceType#TYPE_2232H}</li>
* <li>{@value DeviceType#TYPE_4232H}</li>
* <li>{@value DeviceType#TYPE_AM}</li>
* <li>{@value DeviceType#TYPE_BM}</li>
* </ul>
* </p>
*
* @author mike wakerly (opensource@hoho.com)
* @see <a href="http://code.google.com/p/usb-serial-for-android/">USB Serial
* for Android project page</a>
* @see <a href="http://www.ftdichip.com/">FTDI Homepage</a>
* @see <a href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>
*/
public
class
FtdiSerialDriver
extends
CommonUsbSerialDriver
{
public
static
final
int
USB_TYPE_STANDARD
=
0x00
<<
5
;
public
static
final
int
USB_TYPE_CLASS
=
0x00
<<
5
;
public
static
final
int
USB_TYPE_VENDOR
=
0x00
<<
5
;
public
static
final
int
USB_TYPE_RESERVED
=
0x00
<<
5
;
public
static
final
int
USB_RECIP_DEVICE
=
0x00
;
public
static
final
int
USB_RECIP_INTERFACE
=
0x01
;
public
static
final
int
USB_RECIP_ENDPOINT
=
0x02
;
public
static
final
int
USB_RECIP_OTHER
=
0x03
;
public
static
final
int
USB_ENDPOINT_IN
=
0x80
;
public
static
final
int
USB_ENDPOINT_OUT
=
0x00
;
public
static
final
int
USB_WRITE_TIMEOUT_MILLIS
=
5000
;
public
static
final
int
USB_READ_TIMEOUT_MILLIS
=
5000
;
// From ftdi.h
/**
* Reset the port.
*/
private
static
final
int
SIO_RESET_REQUEST
=
0
;
/**
* Set the modem control register.
*/
private
static
final
int
SIO_MODEM_CTRL_REQUEST
=
1
;
/**
* Set flow control register.
*/
private
static
final
int
SIO_SET_FLOW_CTRL_REQUEST
=
2
;
/**
* Set baud rate.
*/
private
static
final
int
SIO_SET_BAUD_RATE_REQUEST
=
3
;
/**
* Set the data characteristics of the port.
*/
private
static
final
int
SIO_SET_DATA_REQUEST
=
4
;
private
static
final
int
SIO_RESET_SIO
=
0
;
private
static
final
int
SIO_RESET_PURGE_RX
=
1
;
private
static
final
int
SIO_RESET_PURGE_TX
=
2
;
public
static
final
int
FTDI_DEVICE_OUT_REQTYPE
=
UsbConstants
.
USB_TYPE_VENDOR
|
USB_RECIP_DEVICE
|
USB_ENDPOINT_OUT
;
public
static
final
int
FTDI_DEVICE_IN_REQTYPE
=
UsbConstants
.
USB_TYPE_VENDOR
|
USB_RECIP_DEVICE
|
USB_ENDPOINT_IN
;
/**
* Length of the modem status header, transmitted with every read.
*/
private
static
final
int
MODEM_STATUS_HEADER_LENGTH
=
2
;
private
final
String
TAG
=
FtdiSerialDriver
.
class
.
getSimpleName
();
private
DeviceType
mType
;
/**
* FTDI chip types.
*/
private
static
enum
DeviceType
{
TYPE_BM
,
TYPE_AM
,
TYPE_2232C
,
TYPE_R
,
TYPE_2232H
,
TYPE_4232H
;
}
private
int
mInterface
=
0
;
/* INTERFACE_ANY */
private
int
mMaxPacketSize
=
64
;
// TODO(mikey): detect
/**
* Due to http://b.android.com/28023 , we cannot use UsbRequest async reads
* since it gives no indication of number of bytes read. Set this to
* {@code true} on platforms where it is fixed.
*/
private
static
final
boolean
ENABLE_ASYNC_READS
=
false
;
/**
* Filter FTDI status bytes from buffer
* @param src The source buffer (which contains status bytes)
* @param dest The destination buffer to write the status bytes into (can be src)
* @param totalBytesRead Number of bytes read to src
* @param maxPacketSize The USB endpoint max packet size
* @return The number of payload bytes
*/
private
final
int
filterStatusBytes
(
byte
[]
src
,
byte
[]
dest
,
int
totalBytesRead
,
int
maxPacketSize
)
{
final
int
packetsCount
=
totalBytesRead
/
maxPacketSize
+
1
;
for
(
int
packetIdx
=
0
;
packetIdx
<
packetsCount
;
++
packetIdx
)
{
final
int
count
=
(
packetIdx
==
(
packetsCount
-
1
))
?
(
totalBytesRead
%
maxPacketSize
)
-
MODEM_STATUS_HEADER_LENGTH
:
maxPacketSize
-
MODEM_STATUS_HEADER_LENGTH
;
if
(
count
>
0
)
{
System
.
arraycopy
(
src
,
packetIdx
*
maxPacketSize
+
MODEM_STATUS_HEADER_LENGTH
,
dest
,
packetIdx
*
(
maxPacketSize
-
MODEM_STATUS_HEADER_LENGTH
),
count
);
}
}
return
totalBytesRead
-
(
packetsCount
*
2
);
}
/**
* Constructor.
*
* @param usbDevice the {@link UsbDevice} to use
* @param usbConnection the {@link UsbDeviceConnection} to use
* @throws UsbSerialRuntimeException if the given device is incompatible
* with this driver
*/
public
FtdiSerialDriver
(
UsbDevice
usbDevice
,
UsbDeviceConnection
usbConnection
)
{
super
(
usbDevice
,
usbConnection
);
mType
=
null
;
}
public
void
reset
()
throws
IOException
{
int
result
=
mConnection
.
controlTransfer
(
FTDI_DEVICE_OUT_REQTYPE
,
SIO_RESET_REQUEST
,
SIO_RESET_SIO
,
0
/* index */
,
null
,
0
,
USB_WRITE_TIMEOUT_MILLIS
);
if
(
result
!=
0
)
{
throw
new
IOException
(
"Reset failed: result="
+
result
);
}
// TODO(mikey): autodetect.
mType
=
DeviceType
.
TYPE_R
;
}
@Override
public
void
open
()
throws
IOException
{
boolean
opened
=
false
;
try
{
for
(
int
i
=
0
;
i
<
mDevice
.
getInterfaceCount
();
i
++)
{
if
(
mConnection
.
claimInterface
(
mDevice
.
getInterface
(
i
),
true
))
{
Log
.
d
(
TAG
,
"claimInterface "
+
i
+
" SUCCESS"
);
}
else
{
throw
new
IOException
(
"Error claiming interface "
+
i
);
}
}
reset
();
opened
=
true
;
}
finally
{
if
(!
opened
)
{
close
();
}
}
}
@Override
public
void
close
()
{
mConnection
.
close
();
}
@Override
public
int
read
(
byte
[]
dest
,
int
timeoutMillis
)
throws
IOException
{
final
UsbEndpoint
endpoint
=
mDevice
.
getInterface
(
0
).
getEndpoint
(
0
);
if
(
ENABLE_ASYNC_READS
)
{
final
int
readAmt
;
synchronized
(
mReadBufferLock
)
{
// mReadBuffer is only used for maximum read size.
readAmt
=
Math
.
min
(
dest
.
length
,
mReadBuffer
.
length
);
}
final
UsbRequest
request
=
new
UsbRequest
();
request
.
initialize
(
mConnection
,
endpoint
);
final
ByteBuffer
buf
=
ByteBuffer
.
wrap
(
dest
);
if
(!
request
.
queue
(
buf
,
readAmt
))
{
throw
new
IOException
(
"Error queueing request."
);
}
final
UsbRequest
response
=
mConnection
.
requestWait
();
if
(
response
==
null
)
{
throw
new
IOException
(
"Null response"
);
}
final
int
payloadBytesRead
=
buf
.
position
()
-
MODEM_STATUS_HEADER_LENGTH
;
if
(
payloadBytesRead
>
0
)
{
return
payloadBytesRead
;
}
else
{
return
0
;
}
}
else
{
final
int
totalBytesRead
;
synchronized
(
mReadBufferLock
)
{
final
int
readAmt
=
Math
.
min
(
dest
.
length
,
mReadBuffer
.
length
);
totalBytesRead
=
mConnection
.
bulkTransfer
(
endpoint
,
mReadBuffer
,
readAmt
,
timeoutMillis
);
if
(
totalBytesRead
<
MODEM_STATUS_HEADER_LENGTH
)
{
throw
new
IOException
(
"Expected at least "
+
MODEM_STATUS_HEADER_LENGTH
+
" bytes"
);
}
return
filterStatusBytes
(
mReadBuffer
,
dest
,
totalBytesRead
,
endpoint
.
getMaxPacketSize
());
}
}
}
@Override
public
int
write
(
byte
[]
src
,
int
timeoutMillis
)
throws
IOException
{
final
UsbEndpoint
endpoint
=
mDevice
.
getInterface
(
0
).
getEndpoint
(
1
);
int
offset
=
0
;
while
(
offset
<
src
.
length
)
{
final
int
writeLength
;
final
int
amtWritten
;
synchronized
(
mWriteBufferLock
)
{
final
byte
[]
writeBuffer
;
writeLength
=
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
,
writeLength
);
writeBuffer
=
mWriteBuffer
;
}
amtWritten
=
mConnection
.
bulkTransfer
(
endpoint
,
writeBuffer
,
writeLength
,
timeoutMillis
);
}
if
(
amtWritten
<=
0
)
{
throw
new
IOException
(
"Error writing "
+
writeLength
+
" bytes at offset "
+
offset
+
" length="
+
src
.
length
);
}
//Log.d(TAG, "Wrote amtWritten=" + amtWritten + " attempted=" + writeLength);
offset
+=
amtWritten
;
}
return
offset
;
}
private
int
setBaudRate
(
int
baudRate
)
throws
IOException
{
long
[]
vals
=
convertBaudrate
(
baudRate
);
long
actualBaudrate
=
vals
[
0
];
long
index
=
vals
[
1
];
long
value
=
vals
[
2
];
int
result
=
mConnection
.
controlTransfer
(
FTDI_DEVICE_OUT_REQTYPE
,
SIO_SET_BAUD_RATE_REQUEST
,
(
int
)
value
,
(
int
)
index
,
null
,
0
,
USB_WRITE_TIMEOUT_MILLIS
);
if
(
result
!=
0
)
{
throw
new
IOException
(
"Setting baudrate failed: result="
+
result
);
}
return
(
int
)
actualBaudrate
;
}
@Override
public
void
setParameters
(
int
baudRate
,
int
dataBits
,
int
stopBits
,
int
parity
)
throws
IOException
{
setBaudRate
(
baudRate
);
int
config
=
dataBits
;
switch
(
parity
)
{
case
PARITY_NONE:
config
|=
(
0x00
<<
8
);
break
;
case
PARITY_ODD:
config
|=
(
0x01
<<
8
);
break
;
case
PARITY_EVEN:
config
|=
(
0x02
<<
8
);
break
;
case
PARITY_MARK:
config
|=
(
0x03
<<
8
);
break
;
case
PARITY_SPACE:
config
|=
(
0x04
<<
8
);
break
;
default
:
throw
new
IllegalArgumentException
(
"Unknown parity value: "
+
parity
);
}
switch
(
stopBits
)
{
case
STOPBITS_1:
config
|=
(
0x00
<<
11
);
break
;
case
STOPBITS_1_5:
config
|=
(
0x01
<<
11
);
break
;
case
STOPBITS_2:
config
|=
(
0x02
<<
11
);
break
;
default
:
throw
new
IllegalArgumentException
(
"Unknown stopBits value: "
+
stopBits
);
}
int
result
=
mConnection
.
controlTransfer
(
FTDI_DEVICE_OUT_REQTYPE
,
SIO_SET_DATA_REQUEST
,
config
,
0
/* index */
,
null
,
0
,
USB_WRITE_TIMEOUT_MILLIS
);
if
(
result
!=
0
)
{
throw
new
IOException
(
"Setting parameters failed: result="
+
result
);
}
}
private
long
[]
convertBaudrate
(
int
baudrate
)
{
// TODO(mikey): Braindead transcription of libfti method. Clean up,
// using more idiomatic Java where possible.
int
divisor
=
24000000
/
baudrate
;
int
bestDivisor
=
0
;
int
bestBaud
=
0
;
int
bestBaudDiff
=
0
;
int
fracCode
[]
=
{
0
,
3
,
2
,
4
,
1
,
5
,
6
,
7
};
for
(
int
i
=
0
;
i
<
2
;
i
++)
{
int
tryDivisor
=
divisor
+
i
;
int
baudEstimate
;
int
baudDiff
;
if
(
tryDivisor
<=
8
)
{
// Round up to minimum supported divisor
tryDivisor
=
8
;
}
else
if
(
mType
!=
DeviceType
.
TYPE_AM
&&
tryDivisor
<
12
)
{
// BM doesn't support divisors 9 through 11 inclusive
tryDivisor
=
12
;
}
else
if
(
divisor
<
16
)
{
// AM doesn't support divisors 9 through 15 inclusive
tryDivisor
=
16
;
}
else
{
if
(
mType
==
DeviceType
.
TYPE_AM
)
{
// TODO
}
else
{
if
(
tryDivisor
>
0x1FFFF
)
{
// Round down to maximum supported divisor value (for
// BM)
tryDivisor
=
0x1FFFF
;
}
}
}
// Get estimated baud rate (to nearest integer)
baudEstimate
=
(
24000000
+
(
tryDivisor
/
2
))
/
tryDivisor
;
// Get absolute difference from requested baud rate
if
(
baudEstimate
<
baudrate
)
{
baudDiff
=
baudrate
-
baudEstimate
;
}
else
{
baudDiff
=
baudEstimate
-
baudrate
;
}
if
(
i
==
0
||
baudDiff
<
bestBaudDiff
)
{
// Closest to requested baud rate so far
bestDivisor
=
tryDivisor
;
bestBaud
=
baudEstimate
;
bestBaudDiff
=
baudDiff
;
if
(
baudDiff
==
0
)
{
// Spot on! No point trying
break
;
}
}
}
// Encode the best divisor value
long
encodedDivisor
=
(
bestDivisor
>>
3
)
|
(
fracCode
[
bestDivisor
&
7
]
<<
14
);
// Deal with special cases for encoded value
if
(
encodedDivisor
==
1
)
{
encodedDivisor
=
0
;
// 3000000 baud
}
else
if
(
encodedDivisor
==
0x4001
)
{
encodedDivisor
=
1
;
// 2000000 baud (BM only)
}
// Split into "value" and "index" values
long
value
=
encodedDivisor
&
0xFFFF
;
long
index
;
if
(
mType
==
DeviceType
.
TYPE_2232C
||
mType
==
DeviceType
.
TYPE_2232H
||
mType
==
DeviceType
.
TYPE_4232H
)
{
index
=
(
encodedDivisor
>>
8
)
&
0xffff
;
index
&=
0xFF00
;
index
|=
0
/* TODO mIndex */
;
}
else
{
index
=
(
encodedDivisor
>>
16
)
&
0xffff
;
}
// Return the nearest baud rate
return
new
long
[]
{
bestBaud
,
index
,
value
};
}
@Override
public
boolean
getCD
()
throws
IOException
{
return
false
;
}
@Override
public
boolean
getCTS
()
throws
IOException
{
return
false
;
}
@Override
public
boolean
getDSR
()
throws
IOException
{
return
false
;
}
@Override
public
boolean
getDTR
()
throws
IOException
{
return
false
;
}
@Override
public
void
setDTR
(
boolean
value
)
throws
IOException
{
}
@Override
public
boolean
getRI
()
throws
IOException
{
return
false
;
}
@Override
public
boolean
getRTS
()
throws
IOException
{
return
false
;
}
@Override
public
void
setRTS
(
boolean
value
)
throws
IOException
{
}
@Override
public
boolean
purgeHwBuffers
(
boolean
purgeReadBuffers
,
boolean
purgeWriteBuffers
)
throws
IOException
{
if
(
purgeReadBuffers
)
{
int
result
=
mConnection
.
controlTransfer
(
FTDI_DEVICE_OUT_REQTYPE
,
SIO_RESET_REQUEST
,
SIO_RESET_PURGE_RX
,
0
/* index */
,
null
,
0
,
USB_WRITE_TIMEOUT_MILLIS
);
if
(
result
!=
0
)
{
throw
new
IOException
(
"Flushing RX failed: result="
+
result
);
}
}
if
(
purgeWriteBuffers
)
{
int
result
=
mConnection
.
controlTransfer
(
FTDI_DEVICE_OUT_REQTYPE
,
SIO_RESET_REQUEST
,
SIO_RESET_PURGE_TX
,
0
/* index */
,
null
,
0
,
USB_WRITE_TIMEOUT_MILLIS
);
if
(
result
!=
0
)
{
throw
new
IOException
(
"Flushing RX failed: result="
+
result
);
}
}
return
true
;
}
public
static
Map
<
Integer
,
int
[]>
getSupportedDevices
()
{
final
Map
<
Integer
,
int
[]>
supportedDevices
=
new
LinkedHashMap
<
Integer
,
int
[]>();
supportedDevices
.
put
(
Integer
.
valueOf
(
UsbId
.
VENDOR_FTDI
),
new
int
[]
{
UsbId
.
FTDI_FT232R
,
UsbId
.
FTDI_FT231X
,
});
/*
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_PX4),
new int[] {
UsbId.DEVICE_PX4FMU
});
*/
return
supportedDevices
;
}
}
android/src/com/hoho/android/usbserial/driver/ProlificSerialDriver.java
0 → 100644
View file @
59ad9be7
/* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* Project home page: http://code.google.com/p/usb-serial-for-android/
*/
/*
* Ported to usb-serial-for-android
* by Felix Hädicke <felixhaedicke@web.de>
*
* Based on the pyprolific driver written
* by Emmanuel Blot <emmanuel.blot@free.fr>
* See https://github.com/eblot/pyftdi
*/
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.lang.reflect.Method
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
public
class
ProlificSerialDriver
extends
CommonUsbSerialDriver
{
private
static
final
int
USB_READ_TIMEOUT_MILLIS
=
1000
;
private
static
final
int
USB_WRITE_TIMEOUT_MILLIS
=
5000
;
private
static
final
int
USB_RECIP_INTERFACE
=
0x01
;
private
static
final
int
PROLIFIC_VENDOR_READ_REQUEST
=
0x01
;
private
static
final
int
PROLIFIC_VENDOR_WRITE_REQUEST
=
0x01
;
private
static
final
int
PROLIFIC_VENDOR_OUT_REQTYPE
=
UsbConstants
.
USB_DIR_OUT
|
UsbConstants
.
USB_TYPE_VENDOR
;
private
static
final
int
PROLIFIC_VENDOR_IN_REQTYPE
=
UsbConstants
.
USB_DIR_IN
|
UsbConstants
.
USB_TYPE_VENDOR
;
private
static
final
int
PROLIFIC_CTRL_OUT_REQTYPE
=
UsbConstants
.
USB_DIR_OUT
|
UsbConstants
.
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
;
private
static
final
int
WRITE_ENDPOINT
=
0x02
;
private
static
final
int
READ_ENDPOINT
=
0x83
;
private
static
final
int
INTERRUPT_ENDPOINT
=
0x81
;
private
static
final
int
FLUSH_RX_REQUEST
=
0x08
;
private
static
final
int
FLUSH_TX_REQUEST
=
0x09
;
private
static
final
int
SET_LINE_REQUEST
=
0x20
;
private
static
final
int
SET_CONTROL_REQUEST
=
0x22
;
private
static
final
int
CONTROL_DTR
=
0x01
;
private
static
final
int
CONTROL_RTS
=
0x02
;
private
static
final
int
STATUS_FLAG_CD
=
0x01
;
private
static
final
int
STATUS_FLAG_DSR
=
0x02
;
private
static
final
int
STATUS_FLAG_RI
=
0x08
;
private
static
final
int
STATUS_FLAG_CTS
=
0x80
;
private
static
final
int
STATUS_BUFFER_SIZE
=
10
;
private
static
final
int
STATUS_BYTE_IDX
=
8
;
private
static
final
int
DEVICE_TYPE_HX
=
0
;
private
static
final
int
DEVICE_TYPE_0
=
1
;
private
static
final
int
DEVICE_TYPE_1
=
2
;
private
int
mDeviceType
=
DEVICE_TYPE_HX
;
private
UsbEndpoint
mReadEndpoint
;
private
UsbEndpoint
mWriteEndpoint
;
private
UsbEndpoint
mInterruptEndpoint
;
private
int
mControlLinesValue
=
0
;
private
int
mBaudRate
=
-
1
,
mDataBits
=
-
1
,
mStopBits
=
-
1
,
mParity
=
-
1
;
private
int
mStatus
=
0
;
private
volatile
Thread
mReadStatusThread
=
null
;
private
final
Object
mReadStatusThreadLock
=
new
Object
();
boolean
mStopReadStatusThread
=
false
;
private
IOException
mReadStatusException
=
null
;
private
final
String
TAG
=
ProlificSerialDriver
.
class
.
getSimpleName
();
private
final
byte
[]
inControlTransfer
(
int
requestType
,
int
request
,
int
value
,
int
index
,
int
length
)
throws
IOException
{
byte
[]
buffer
=
new
byte
[
length
];
int
result
=
mConnection
.
controlTransfer
(
requestType
,
request
,
value
,
index
,
buffer
,
length
,
USB_READ_TIMEOUT_MILLIS
);
if
(
result
!=
length
)
{
throw
new
IOException
(
String
.
format
(
"ControlTransfer with value 0x%x failed: %d"
,
value
,
result
));
}
return
buffer
;
}
private
final
void
outControlTransfer
(
int
requestType
,
int
request
,
int
value
,
int
index
,
byte
[]
data
)
throws
IOException
{
int
length
=
(
data
==
null
)
?
0
:
data
.
length
;
int
result
=
mConnection
.
controlTransfer
(
requestType
,
request
,
value
,
index
,
data
,
length
,
USB_WRITE_TIMEOUT_MILLIS
);
if
(
result
!=
length
)
{
throw
new
IOException
(
String
.
format
(
"ControlTransfer with value 0x%x failed: %d"
,
value
,
result
));
}
}
private
final
byte
[]
vendorIn
(
int
value
,
int
index
,
int
length
)
throws
IOException
{
return
inControlTransfer
(
PROLIFIC_VENDOR_IN_REQTYPE
,
PROLIFIC_VENDOR_READ_REQUEST
,
value
,
index
,
length
);
}
private
final
void
vendorOut
(
int
value
,
int
index
,
byte
[]
data
)
throws
IOException
{
outControlTransfer
(
PROLIFIC_VENDOR_OUT_REQTYPE
,
PROLIFIC_VENDOR_WRITE_REQUEST
,
value
,
index
,
data
);
}
private
final
void
ctrlOut
(
int
request
,
int
value
,
int
index
,
byte
[]
data
)
throws
IOException
{
outControlTransfer
(
PROLIFIC_CTRL_OUT_REQTYPE
,
request
,
value
,
index
,
data
);
}
private
void
doBlackMagic
()
throws
IOException
{
vendorIn
(
0x8484
,
0
,
1
);
vendorOut
(
0x0404
,
0
,
null
);
vendorIn
(
0x8484
,
0
,
1
);
vendorIn
(
0x8383
,
0
,
1
);
vendorIn
(
0x8484
,
0
,
1
);
vendorOut
(
0x0404
,
1
,
null
);
vendorIn
(
0x8484
,
0
,
1
);
vendorIn
(
0x8383
,
0
,
1
);
vendorOut
(
0
,
1
,
null
);
vendorOut
(
1
,
0
,
null
);
vendorOut
(
2
,
(
mDeviceType
==
DEVICE_TYPE_HX
)
?
0x44
:
0x24
,
null
);
}
private
void
resetDevice
()
throws
IOException
{
purgeHwBuffers
(
true
,
true
);
}
private
void
setControlLines
(
int
newControlLinesValue
)
throws
IOException
{
ctrlOut
(
SET_CONTROL_REQUEST
,
newControlLinesValue
,
0
,
null
);
mControlLinesValue
=
newControlLinesValue
;
}
private
final
void
readStatusThreadFunction
()
{
try
{
while
(!
mStopReadStatusThread
)
{
byte
[]
buffer
=
new
byte
[
STATUS_BUFFER_SIZE
];
int
readBytesCount
=
mConnection
.
bulkTransfer
(
mInterruptEndpoint
,
buffer
,
STATUS_BUFFER_SIZE
,
500
);
if
(
readBytesCount
>
0
)
{
if
(
readBytesCount
==
STATUS_BUFFER_SIZE
)
{
mStatus
=
buffer
[
STATUS_BYTE_IDX
]
&
0xff
;
}
else
{
throw
new
IOException
(
String
.
format
(
"Invalid CTS / DSR / CD / RI status buffer received, expected %d bytes, but received %d"
,
STATUS_BUFFER_SIZE
,
readBytesCount
));
}
}
}
}
catch
(
IOException
e
)
{
mReadStatusException
=
e
;
}
}
private
final
int
getStatus
()
throws
IOException
{
if
((
mReadStatusThread
==
null
)
&&
(
mReadStatusException
==
null
))
{
synchronized
(
mReadStatusThreadLock
)
{
if
(
mReadStatusThread
==
null
)
{
byte
[]
buffer
=
new
byte
[
STATUS_BUFFER_SIZE
];
int
readBytes
=
mConnection
.
bulkTransfer
(
mInterruptEndpoint
,
buffer
,
STATUS_BUFFER_SIZE
,
100
);
if
(
readBytes
!=
STATUS_BUFFER_SIZE
)
{
Log
.
w
(
TAG
,
"Could not read initial CTS / DSR / CD / RI status"
);
}
else
{
mStatus
=
buffer
[
STATUS_BYTE_IDX
]
&
0xff
;
}
mReadStatusThread
=
new
Thread
(
new
Runnable
()
{
@Override
public
void
run
()
{
readStatusThreadFunction
();
}
});
mReadStatusThread
.
setDaemon
(
true
);
mReadStatusThread
.
start
();
}
}
}
/* throw and clear an exception which occured in the status read thread */
IOException
readStatusException
=
mReadStatusException
;
if
(
mReadStatusException
!=
null
)
{
mReadStatusException
=
null
;
throw
readStatusException
;
}
return
mStatus
;
}
private
final
boolean
testStatusFlag
(
int
flag
)
throws
IOException
{
return
((
getStatus
()
&
flag
)
==
flag
);
}
public
ProlificSerialDriver
(
UsbDevice
device
,
UsbDeviceConnection
connection
)
{
super
(
device
,
connection
);
}
@Override
public
void
open
()
throws
IOException
{
UsbInterface
usbInterface
=
mDevice
.
getInterface
(
0
);
if
(!
mConnection
.
claimInterface
(
usbInterface
,
true
))
{
throw
new
IOException
(
"Error claiming Prolific interface 0"
);
}
boolean
openSuccessful
=
false
;
try
{
for
(
int
i
=
0
;
i
<
usbInterface
.
getEndpointCount
();
++
i
)
{
UsbEndpoint
currentEndpoint
=
usbInterface
.
getEndpoint
(
i
);
switch
(
currentEndpoint
.
getAddress
())
{
case
READ_ENDPOINT:
mReadEndpoint
=
currentEndpoint
;
break
;
case
WRITE_ENDPOINT:
mWriteEndpoint
=
currentEndpoint
;
break
;
case
INTERRUPT_ENDPOINT:
mInterruptEndpoint
=
currentEndpoint
;
break
;
}
}
if
(
mDevice
.
getDeviceClass
()
==
0x02
)
{
mDeviceType
=
DEVICE_TYPE_0
;
}
else
{
try
{
Method
getRawDescriptorsMethod
=
mConnection
.
getClass
().
getMethod
(
"getRawDescriptors"
);
byte
[]
rawDescriptors
=
(
byte
[])
getRawDescriptorsMethod
.
invoke
(
mConnection
);
byte
maxPacketSize0
=
rawDescriptors
[
7
];
if
(
maxPacketSize0
==
64
)
{
mDeviceType
=
DEVICE_TYPE_HX
;
}
else
if
((
mDevice
.
getDeviceClass
()
==
0x00
)
||
(
mDevice
.
getDeviceClass
()
==
0xff
))
{
mDeviceType
=
DEVICE_TYPE_1
;
}
else
{
Log
.
w
(
TAG
,
"Could not detect PL2303 subtype, "
+
"Assuming that it is a HX device"
);
mDeviceType
=
DEVICE_TYPE_HX
;
}
}
catch
(
NoSuchMethodException
e
)
{
Log
.
w
(
TAG
,
"Method UsbDeviceConnection.getRawDescriptors, "
+
"required for PL2303 subtype detection, not "
+
"available! Assuming that it is a HX device"
);
mDeviceType
=
DEVICE_TYPE_HX
;
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"An unexpected exception occured while trying "
+
"to detect PL2303 subtype"
,
e
);
}
}
setControlLines
(
mControlLinesValue
);
resetDevice
();
doBlackMagic
();
openSuccessful
=
true
;
}
finally
{
if
(!
openSuccessful
)
{
try
{
mConnection
.
releaseInterface
(
usbInterface
);
}
catch
(
Exception
ingored
)
{
// Do not cover possible exceptions
}
}
}
}
@Override
public
void
close
()
throws
IOException
{
try
{
mStopReadStatusThread
=
true
;
synchronized
(
mReadStatusThreadLock
)
{
if
(
mReadStatusThread
!=
null
)
{
try
{
mReadStatusThread
.
join
();
}
catch
(
Exception
e
)
{
Log
.
w
(
TAG
,
"An error occured while waiting for status read thread"
,
e
);
}
}
}
resetDevice
();
}
finally
{
mConnection
.
releaseInterface
(
mDevice
.
getInterface
(
0
));
}
}
@Override
public
int
read
(
byte
[]
dest
,
int
timeoutMillis
)
throws
IOException
{
synchronized
(
mReadBufferLock
)
{
int
readAmt
=
Math
.
min
(
dest
.
length
,
mReadBuffer
.
length
);
int
numBytesRead
=
mConnection
.
bulkTransfer
(
mReadEndpoint
,
mReadBuffer
,
readAmt
,
timeoutMillis
);
if
(
numBytesRead
<
0
)
{
return
0
;
}
System
.
arraycopy
(
mReadBuffer
,
0
,
dest
,
0
,
numBytesRead
);
return
numBytesRead
;
}
}
@Override
public
int
write
(
byte
[]
src
,
int
timeoutMillis
)
throws
IOException
{
int
offset
=
0
;
while
(
offset
<
src
.
length
)
{
final
int
writeLength
;
final
int
amtWritten
;
synchronized
(
mWriteBufferLock
)
{
final
byte
[]
writeBuffer
;
writeLength
=
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
,
writeLength
);
writeBuffer
=
mWriteBuffer
;
}
amtWritten
=
mConnection
.
bulkTransfer
(
mWriteEndpoint
,
writeBuffer
,
writeLength
,
timeoutMillis
);
}
if
(
amtWritten
<=
0
)
{
throw
new
IOException
(
"Error writing "
+
writeLength
+
" bytes at offset "
+
offset
+
" length="
+
src
.
length
);
}
offset
+=
amtWritten
;
}
return
offset
;
}
@Override
public
void
setParameters
(
int
baudRate
,
int
dataBits
,
int
stopBits
,
int
parity
)
throws
IOException
{
if
((
mBaudRate
==
baudRate
)
&&
(
mDataBits
==
dataBits
)
&&
(
mStopBits
==
stopBits
)
&&
(
mParity
==
parity
))
{
// Make sure no action is performed if there is nothing to change
return
;
}
byte
[]
lineRequestData
=
new
byte
[
7
];
lineRequestData
[
0
]
=
(
byte
)
(
baudRate
&
0xff
);
lineRequestData
[
1
]
=
(
byte
)
((
baudRate
>>
8
)
&
0xff
);
lineRequestData
[
2
]
=
(
byte
)
((
baudRate
>>
16
)
&
0xff
);
lineRequestData
[
3
]
=
(
byte
)
((
baudRate
>>
24
)
&
0xff
);
switch
(
stopBits
)
{
case
STOPBITS_1:
lineRequestData
[
4
]
=
0
;
break
;
case
STOPBITS_1_5:
lineRequestData
[
4
]
=
1
;
break
;
case
STOPBITS_2:
lineRequestData
[
4
]
=
2
;
break
;
default
:
throw
new
IllegalArgumentException
(
"Unknown stopBits value: "
+
stopBits
);
}
switch
(
parity
)
{
case
PARITY_NONE:
lineRequestData
[
5
]
=
0
;
break
;
case
PARITY_ODD:
lineRequestData
[
5
]
=
1
;
break
;
case
PARITY_EVEN:
lineRequestData
[
5
]
=
2
;
break
;
case
PARITY_MARK:
lineRequestData
[
5
]
=
3
;
break
;
case
PARITY_SPACE:
lineRequestData
[
5
]
=
4
;
break
;
default
:
throw
new
IllegalArgumentException
(
"Unknown parity value: "
+
parity
);
}
lineRequestData
[
6
]
=
(
byte
)
dataBits
;
ctrlOut
(
SET_LINE_REQUEST
,
0
,
0
,
lineRequestData
);
resetDevice
();
mBaudRate
=
baudRate
;
mDataBits
=
dataBits
;
mStopBits
=
stopBits
;
mParity
=
parity
;
}
@Override
public
boolean
getCD
()
throws
IOException
{
return
testStatusFlag
(
STATUS_FLAG_CD
);
}
@Override
public
boolean
getCTS
()
throws
IOException
{
return
testStatusFlag
(
STATUS_FLAG_CTS
);
}
@Override
public
boolean
getDSR
()
throws
IOException
{
return
testStatusFlag
(
STATUS_FLAG_DSR
);
}
@Override
public
boolean
getDTR
()
throws
IOException
{
return
((
mControlLinesValue
&
CONTROL_DTR
)
==
CONTROL_DTR
);
}
@Override
public
void
setDTR
(
boolean
value
)
throws
IOException
{
int
newControlLinesValue
;
if
(
value
)
{
newControlLinesValue
=
mControlLinesValue
|
CONTROL_DTR
;
}
else
{
newControlLinesValue
=
mControlLinesValue
&
~
CONTROL_DTR
;
}
setControlLines
(
newControlLinesValue
);
}
@Override
public
boolean
getRI
()
throws
IOException
{
return
testStatusFlag
(
STATUS_FLAG_RI
);
}
@Override
public
boolean
getRTS
()
throws
IOException
{
return
((
mControlLinesValue
&
CONTROL_RTS
)
==
CONTROL_RTS
);
}
@Override
public
void
setRTS
(
boolean
value
)
throws
IOException
{
int
newControlLinesValue
;
if
(
value
)
{
newControlLinesValue
=
mControlLinesValue
|
CONTROL_RTS
;
}
else
{
newControlLinesValue
=
mControlLinesValue
&
~
CONTROL_RTS
;
}
setControlLines
(
newControlLinesValue
);
}
@Override
public
boolean
purgeHwBuffers
(
boolean
purgeReadBuffers
,
boolean
purgeWriteBuffers
)
throws
IOException
{
if
(
purgeReadBuffers
)
{
vendorOut
(
FLUSH_RX_REQUEST
,
0
,
null
);
}
if
(
purgeWriteBuffers
)
{
vendorOut
(
FLUSH_TX_REQUEST
,
0
,
null
);
}
return
true
;
}
public
static
Map
<
Integer
,
int
[]>
getSupportedDevices
()
{
final
Map
<
Integer
,
int
[]>
supportedDevices
=
new
LinkedHashMap
<
Integer
,
int
[]>();
supportedDevices
.
put
(
Integer
.
valueOf
(
UsbId
.
VENDOR_PROLIFIC
),
new
int
[]
{
UsbId
.
PROLIFIC_PL2303
,
});
return
supportedDevices
;
}
}
android/src/com/hoho/android/usbserial/driver/UsbId.java
0 → 100644
View file @
59ad9be7
/* Copyright 2012 Google Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* Project home page: http://code.google.com/p/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_FT231X
=
0x6015
;
public
static
final
int
VENDOR_PX4
=
0x26AC
;
public
static
final
int
DEVICE_PX4FMU
=
0x11
;
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
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_SILAB
=
0x10c4
;
public
static
final
int
SILAB_CP2102
=
0xea60
;
public
static
final
int
VENDOR_PROLIFIC
=
0x067b
;
public
static
final
int
PROLIFIC_PL2303
=
0x2303
;
private
UsbId
()
{
throw
new
IllegalAccessError
(
"Non-instantiable class."
);
}
}
android/src/com/hoho/android/usbserial/driver/UsbSerialDriver.java
0 → 100644
View file @
59ad9be7
/* Copyright 2011 Google Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* Project home page: http://code.google.com/p/usb-serial-for-android/
*/
package
com
.
hoho
.
android
.
usbserial
.
driver
;
import
java.io.IOException
;
import
android.hardware.usb.UsbDevice
;
import
android.hardware.usb.UsbDeviceConnection
;
/**
* Driver interface for a USB serial device.
*
* @author mike wakerly (opensource@hoho.com)
*/
public
interface
UsbSerialDriver
{
/** 5 data bits. */
public
static
final
int
DATABITS_5
=
5
;
/** 6 data bits. */
public
static
final
int
DATABITS_6
=
6
;
/** 7 data bits. */
public
static
final
int
DATABITS_7
=
7
;
/** 8 data bits. */
public
static
final
int
DATABITS_8
=
8
;
/** No flow control. */
public
static
final
int
FLOWCONTROL_NONE
=
0
;
/** RTS/CTS input flow control. */
public
static
final
int
FLOWCONTROL_RTSCTS_IN
=
1
;
/** RTS/CTS output flow control. */
public
static
final
int
FLOWCONTROL_RTSCTS_OUT
=
2
;
/** XON/XOFF input flow control. */
public
static
final
int
FLOWCONTROL_XONXOFF_IN
=
4
;
/** XON/XOFF output flow control. */
public
static
final
int
FLOWCONTROL_XONXOFF_OUT
=
8
;
/** No parity. */
public
static
final
int
PARITY_NONE
=
0
;
/** Odd parity. */
public
static
final
int
PARITY_ODD
=
1
;
/** Even parity. */
public
static
final
int
PARITY_EVEN
=
2
;
/** Mark parity. */
public
static
final
int
PARITY_MARK
=
3
;
/** Space parity. */
public
static
final
int
PARITY_SPACE
=
4
;
/** 1 stop bit. */
public
static
final
int
STOPBITS_1
=
1
;
/** 1.5 stop bits. */
public
static
final
int
STOPBITS_1_5
=
3
;
/** 2 stop bits. */
public
static
final
int
STOPBITS_2
=
2
;
/**
* Returns the currently-bound USB device.
*
* @return the device
*/
public
UsbDevice
getDevice
();
/**
* Returns the currently-bound USB device.
*
* @return the device
*/
public
UsbDeviceConnection
getDeviceConnection
();
/**
* Opens and initializes the device as a USB serial device. Upon success,
* caller must ensure that {@link #close()} is eventually called.
*
* @throws IOException on error opening or initializing the device.
*/
public
void
open
()
throws
IOException
;
/**
* Closes the serial device.
*
* @throws IOException on error closing the device.
*/
public
void
close
()
throws
IOException
;
/**
* Reads as many bytes as possible into the destination buffer.
*
* @param dest the destination byte buffer
* @param timeoutMillis the timeout for reading
* @return the actual number of bytes read
* @throws IOException if an error occurred during reading
*/
public
int
read
(
final
byte
[]
dest
,
final
int
timeoutMillis
)
throws
IOException
;
/**
* Writes as many bytes as possible from the source buffer.
*
* @param src the source byte buffer
* @param timeoutMillis the timeout for writing
* @return the actual number of bytes written
* @throws IOException if an error occurred during writing
*/
public
int
write
(
final
byte
[]
src
,
final
int
timeoutMillis
)
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
*/
public
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, or {@code false} if not supported.
* @throws IOException if an error occurred during reading
*/
public
boolean
getCD
()
throws
IOException
;
/**
* Gets the CTS (Clear To Send) bit from the underlying UART.
*
* @return the current state, or {@code false} if not supported.
* @throws IOException if an error occurred during reading
*/
public
boolean
getCTS
()
throws
IOException
;
/**
* Gets the DSR (Data Set Ready) bit from the underlying UART.
*
* @return the current state, or {@code false} if not supported.
* @throws IOException if an error occurred during reading
*/
public
boolean
getDSR
()
throws
IOException
;
/**
* Gets the DTR (Data Terminal Ready) bit from the underlying UART.
*
* @return the current state, or {@code false} if not supported.
* @throws IOException if an error occurred during reading
*/
public
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
*/
public
void
setDTR
(
boolean
value
)
throws
IOException
;
/**
* Gets the RI (Ring Indicator) bit from the underlying UART.
*
* @return the current state, or {@code false} if not supported.
* @throws IOException if an error occurred during reading
*/
public
boolean
getRI
()
throws
IOException
;
/**
* Gets the RTS (Request To Send) bit from the underlying UART.
*
* @return the current state, or {@code false} if not supported.
* @throws IOException if an error occurred during reading
*/
public
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
*/
public
void
setRTS
(
boolean
value
)
throws
IOException
;
/**
* Flush non-transmitted output data and / or non-read input data
* @param flushRX {@code true} to flush non-transmitted output data
* @param flushTX {@code true} to flush non-read input data
* @return {@code true} if the operation was successful, or
* {@code false} if the operation is not supported by the driver or device
* @throws IOException if an error occurred during flush
*/
public
boolean
purgeHwBuffers
(
boolean
flushRX
,
boolean
flushTX
)
throws
IOException
;
}
android/src/com/hoho/android/usbserial/driver/UsbSerialProber.java
0 → 100644
View file @
59ad9be7
/* Copyright 2011 Google Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* Project home page: http://code.google.com/p/usb-serial-for-android/
*/
package
com
.
hoho
.
android
.
usbserial
.
driver
;
import
android.hardware.usb.UsbDevice
;
import
android.hardware.usb.UsbDeviceConnection
;
import
android.hardware.usb.UsbManager
;
import
android.util.Log
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
/**
* Helper class which finds compatible {@link UsbDevice}s and creates
* {@link UsbSerialDriver} instances.
*
* <p/>
* You don't need a Prober to use the rest of the library: it is perfectly
* acceptable to instantiate driver instances manually. The Prober simply
* provides convenience functions.
*
* <p/>
* For most drivers, the corresponding {@link #probe(UsbManager, UsbDevice)}
* method will either return an empty list (device unknown / unsupported) or a
* singleton list. However, multi-port drivers may return multiple instances.
*
* @author mike wakerly (opensource@hoho.com)
*/
public
enum
UsbSerialProber
{
// TODO(mikey): Too much boilerplate.
/**
* Prober for {@link FtdiSerialDriver}.
*
* @see FtdiSerialDriver
*/
FTDI_SERIAL
{
@Override
public
List
<
UsbSerialDriver
>
probe
(
final
UsbManager
manager
,
final
UsbDevice
usbDevice
)
{
if
(!
testIfSupported
(
usbDevice
,
FtdiSerialDriver
.
getSupportedDevices
()))
{
return
Collections
.
emptyList
();
}
final
UsbDeviceConnection
connection
=
manager
.
openDevice
(
usbDevice
);
if
(
connection
==
null
)
{
return
Collections
.
emptyList
();
}
final
UsbSerialDriver
driver
=
new
FtdiSerialDriver
(
usbDevice
,
connection
);
return
Collections
.
singletonList
(
driver
);
}
},
CDC_ACM_SERIAL
{
@Override
public
List
<
UsbSerialDriver
>
probe
(
UsbManager
manager
,
UsbDevice
usbDevice
)
{
if
(!
testIfSupported
(
usbDevice
,
CdcAcmSerialDriver
.
getSupportedDevices
()))
{
return
Collections
.
emptyList
();
}
final
UsbDeviceConnection
connection
=
manager
.
openDevice
(
usbDevice
);
if
(
connection
==
null
)
{
return
Collections
.
emptyList
();
}
final
UsbSerialDriver
driver
=
new
CdcAcmSerialDriver
(
usbDevice
,
connection
);
return
Collections
.
singletonList
(
driver
);
}
},
SILAB_SERIAL
{
@Override
public
List
<
UsbSerialDriver
>
probe
(
final
UsbManager
manager
,
final
UsbDevice
usbDevice
)
{
if
(!
testIfSupported
(
usbDevice
,
Cp2102SerialDriver
.
getSupportedDevices
()))
{
return
Collections
.
emptyList
();
}
final
UsbDeviceConnection
connection
=
manager
.
openDevice
(
usbDevice
);
if
(
connection
==
null
)
{
return
Collections
.
emptyList
();
}
final
UsbSerialDriver
driver
=
new
Cp2102SerialDriver
(
usbDevice
,
connection
);
return
Collections
.
singletonList
(
driver
);
}
},
PROLIFIC_SERIAL
{
@Override
public
List
<
UsbSerialDriver
>
probe
(
final
UsbManager
manager
,
final
UsbDevice
usbDevice
)
{
if
(!
testIfSupported
(
usbDevice
,
ProlificSerialDriver
.
getSupportedDevices
()))
{
return
Collections
.
emptyList
();
}
final
UsbDeviceConnection
connection
=
manager
.
openDevice
(
usbDevice
);
if
(
connection
==
null
)
{
return
Collections
.
emptyList
();
}
final
UsbSerialDriver
driver
=
new
ProlificSerialDriver
(
usbDevice
,
connection
);
return
Collections
.
singletonList
(
driver
);
}
};
/**
* Tests the supplied {@link UsbDevice} for compatibility with this enum
* member, returning one or more driver instances if compatible.
*
* @param manager the {@link UsbManager} to use
* @param usbDevice the raw {@link UsbDevice} to use
* @return zero or more {@link UsbSerialDriver}, depending on compatibility
* (never {@code null}).
*/
protected
abstract
List
<
UsbSerialDriver
>
probe
(
final
UsbManager
manager
,
final
UsbDevice
usbDevice
);
/**
* Creates and returns a new {@link UsbSerialDriver} instance for the first
* compatible {@link UsbDevice} found on the bus. If none are found,
* returns {@code null}.
*
* <p/>
* The order of devices is undefined, therefore if there are multiple
* devices on the bus, the chosen device may not be predictable (clients
* should use {@link #findAllDevices(UsbManager)} instead).
*
* @param usbManager the {@link UsbManager} to use.
* @return the first available {@link UsbSerialDriver}, or {@code null} if
* none are available.
*/
public
static
UsbSerialDriver
findFirstDevice
(
final
UsbManager
usbManager
)
{
for
(
final
UsbDevice
usbDevice
:
usbManager
.
getDeviceList
().
values
())
{
for
(
final
UsbSerialProber
prober
:
values
())
{
final
List
<
UsbSerialDriver
>
probedDevices
=
prober
.
probe
(
usbManager
,
usbDevice
);
if
(!
probedDevices
.
isEmpty
())
{
return
probedDevices
.
get
(
0
);
}
}
}
return
null
;
}
/**
* Creates a new {@link UsbSerialDriver} instance for all compatible
* {@link UsbDevice}s found on the bus. If no compatible devices are found,
* the list will be empty.
*
* @param usbManager
* @return
*/
public
static
List
<
UsbSerialDriver
>
findAllDevices
(
final
UsbManager
usbManager
)
{
final
List
<
UsbSerialDriver
>
result
=
new
ArrayList
<
UsbSerialDriver
>();
Log
.
i
(
"QGC_UsbSerialProber"
,
"Looking for USB devices"
);
// For each UsbDevice, call probe() for each prober.
for
(
final
UsbDevice
usbDevice
:
usbManager
.
getDeviceList
().
values
())
{
Log
.
i
(
"QGC_UsbSerialProber"
,
"Probing device: "
+
usbDevice
.
getDeviceName
()
+
" mid: "
+
usbDevice
.
getVendorId
()
+
" pid: "
+
usbDevice
.
getDeviceId
());
result
.
addAll
(
probeSingleDevice
(
usbManager
,
usbDevice
));
}
return
result
;
}
/**
* Special method for testing a specific device for driver support,
* returning any compatible driver(s).
*
* <p/>
* Clients should ordinarily use {@link #findAllDevices(UsbManager)}, which
* operates against the entire bus of devices. This method is useful when
* testing against only a single target is desired.
*
* @param usbManager the {@link UsbManager} to use.
* @param usbDevice the device to test against.
* @return a list containing zero or more {@link UsbSerialDriver} instances.
*/
public
static
List
<
UsbSerialDriver
>
probeSingleDevice
(
final
UsbManager
usbManager
,
UsbDevice
usbDevice
)
{
final
List
<
UsbSerialDriver
>
result
=
new
ArrayList
<
UsbSerialDriver
>();
for
(
final
UsbSerialProber
prober
:
values
())
{
final
List
<
UsbSerialDriver
>
probedDevices
=
prober
.
probe
(
usbManager
,
usbDevice
);
result
.
addAll
(
probedDevices
);
}
return
result
;
}
/**
* Deprecated; Use {@link #findFirstDevice(UsbManager)}.
*
* @param usbManager
* @return
*/
@Deprecated
public
static
UsbSerialDriver
acquire
(
final
UsbManager
usbManager
)
{
return
findFirstDevice
(
usbManager
);
}
/**
* Deprecated; use {@link #probeSingleDevice(UsbManager, UsbDevice)}.
*
* @param usbManager
* @param usbDevice
* @return
*/
@Deprecated
public
static
UsbSerialDriver
acquire
(
final
UsbManager
usbManager
,
final
UsbDevice
usbDevice
)
{
final
List
<
UsbSerialDriver
>
probedDevices
=
probeSingleDevice
(
usbManager
,
usbDevice
);
if
(!
probedDevices
.
isEmpty
())
{
return
probedDevices
.
get
(
0
);
}
return
null
;
}
/**
* Returns {@code true} if the given device is found in the driver's
* vendor/product map.
*
* @param usbDevice the device to test
* @param supportedDevices map of vendor IDs to product ID(s)
* @return {@code true} if supported
*/
private
static
boolean
testIfSupported
(
final
UsbDevice
usbDevice
,
final
Map
<
Integer
,
int
[]>
supportedDevices
)
{
final
int
[]
supportedProducts
=
supportedDevices
.
get
(
Integer
.
valueOf
(
usbDevice
.
getVendorId
()));
if
(
supportedProducts
==
null
)
{
return
false
;
}
final
int
productId
=
usbDevice
.
getProductId
();
for
(
int
supportedProductId
:
supportedProducts
)
{
if
(
productId
==
supportedProductId
)
{
return
true
;
}
}
return
false
;
}
}
android/src/com/hoho/android/usbserial/driver/UsbSerialRuntimeException.java
0 → 100644
View file @
59ad9be7
/*
* Copyright 2011 Google Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
package
com
.
hoho
.
android
.
usbserial
.
driver
;
/**
* Generic unchecked exception for the usbserial package.
*
* @author mike wakerly (opensource@hoho.com)
*/
@SuppressWarnings
(
"serial"
)
public
class
UsbSerialRuntimeException
extends
RuntimeException
{
public
UsbSerialRuntimeException
()
{
super
();
}
public
UsbSerialRuntimeException
(
String
detailMessage
,
Throwable
throwable
)
{
super
(
detailMessage
,
throwable
);
}
public
UsbSerialRuntimeException
(
String
detailMessage
)
{
super
(
detailMessage
);
}
public
UsbSerialRuntimeException
(
Throwable
throwable
)
{
super
(
throwable
);
}
}
android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java
0 → 100644
View file @
59ad9be7
package
org
.
qgroundcontrol
.
qgchelper
;
/* Copyright 2013 Google Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* Project home page: http://code.google.com/p/usb-serial-for-android/
*/
///////////////////////////////////////////////////////////////////////////////////////////
// Written by: Mike Goza April 2014
//
// These routines interface with the Android USB Host devices for serial port communication.
// The code uses the usb-serial-for-android software library. The UsbDeviceJNI class is the
// interface to the C++ routines through jni calls. Do not change the functions without also
// changing the corresponding calls in the C++ routines or you will break the interface.
//
////////////////////////////////////////////////////////////////////////////////////////////
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.io.IOException
;
import
android.app.Activity
;
import
android.content.BroadcastReceiver
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.IntentFilter
;
import
android.hardware.usb.*
;
import
android.widget.Toast
;
import
android.util.Log
;
import
com.hoho.android.usbserial.driver.*
;
import
org.qtproject.qt5.android.bindings.QtActivity
;
import
org.qtproject.qt5.android.bindings.QtApplication
;
public
class
UsbDeviceJNI
extends
QtActivity
{
public
static
int
BAD_PORT
=
0
;
private
static
UsbDeviceJNI
m_instance
;
private
static
UsbManager
m_manager
;
// ANDROID USB HOST CLASS
private
static
List
<
UsbSerialDriver
>
m_devices
;
// LIST OF CURRENT DEVICES
private
static
HashMap
<
Integer
,
UsbSerialDriver
>
m_openedDevices
;
// LIST OF OPENED DEVICES
private
static
HashMap
<
Integer
,
UsbIoManager
>
m_ioManager
;
// THREADS FOR LISTENING FOR INCOMING DATA
private
static
HashMap
<
Integer
,
Integer
>
m_userData
;
// CORRESPONDING USER DATA FOR OPENED DEVICES. USED IN DISCONNECT CALLBACK
// USED TO DETECT WHEN A DEVICE HAS BEEN UNPLUGGED
private
BroadcastReceiver
m_UsbReceiver
=
null
;
private
final
static
ExecutorService
m_Executor
=
Executors
.
newSingleThreadExecutor
();
private
final
static
UsbIoManager
.
Listener
m_Listener
=
new
UsbIoManager
.
Listener
()
{
@Override
public
void
onRunError
(
Exception
eA
,
int
userDataA
)
{
nativeDeviceException
(
userDataA
,
eA
.
getMessage
());
}
@Override
public
void
onNewData
(
final
byte
[]
dataA
,
int
userDataA
)
{
nativeDeviceNewData
(
userDataA
,
dataA
);
}
};
private
static
final
String
TAG
=
"QGC_UsbDeviceJNI"
;
// NATIVE C++ FUNCTION THAT WILL BE CALLED IF THE DEVICE IS UNPLUGGED
private
static
native
void
nativeDeviceHasDisconnected
(
int
userDataA
);
private
static
native
void
nativeDeviceException
(
int
userDataA
,
String
messageA
);
private
static
native
void
nativeDeviceNewData
(
int
userDataA
,
byte
[]
dataA
);
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Constructor. Only used once to create the initial instance for the static functions.
//
////////////////////////////////////////////////////////////////////////////////////////////////
public
UsbDeviceJNI
()
{
m_instance
=
this
;
m_openedDevices
=
new
HashMap
<
Integer
,
UsbSerialDriver
>();
m_userData
=
new
HashMap
<
Integer
,
Integer
>();
m_ioManager
=
new
HashMap
<
Integer
,
UsbIoManager
>();
Log
.
i
(
TAG
,
"Instance created"
);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Find all current devices that match the device filter described in the androidmanifest.xml and the
// device_filter.xml
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
private
static
boolean
getCurrentDevices
()
{
if
(
m_instance
==
null
)
return
false
;
if
(
m_manager
==
null
)
m_manager
=
(
UsbManager
)
m_instance
.
getSystemService
(
Context
.
USB_SERVICE
);
if
(
m_devices
!=
null
)
m_devices
.
clear
();
m_devices
=
UsbSerialProber
.
findAllDevices
(
m_manager
);
return
true
;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// List all available devices that are not already open. It returns the serial port info
// in a : separated string array. Each string entry consists of the following:
//
// DeviceName:Company:ProductId:VendorId
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
public
static
String
[]
availableDevicesInfo
()
{
// GET THE LIST OF CURRENT DEVICES
if
(!
getCurrentDevices
())
{
Log
.
e
(
TAG
,
"UsbDeviceJNI instance not present"
);
return
null
;
}
// MAKE SURE WE HAVE ENTRIES
if
(
m_devices
.
size
()
<=
0
)
{
//Log.e(TAG, "No USB devices found");
return
null
;
}
if
(
m_openedDevices
==
null
)
{
Log
.
e
(
TAG
,
"m_openedDevices is null"
);
return
null
;
}
int
countL
=
0
;
int
iL
;
// CHECK FOR ALREADY OPENED DEVICES AND DON"T INCLUDE THEM IN THE COUNT
for
(
iL
=
0
;
iL
<
m_devices
.
size
();
iL
++)
{
if
(
m_openedDevices
.
get
(
m_devices
.
get
(
iL
).
getDevice
().
getDeviceId
())
!=
null
)
{
countL
++;
break
;
}
}
if
(
m_devices
.
size
()
-
countL
<=
0
)
{
//Log.e(TAG, "No open USB devices found");
return
null
;
}
String
[]
listL
=
new
String
[
m_devices
.
size
()
-
countL
];
UsbSerialDriver
driverL
;
String
tempL
;
// GET THE DATA ON THE INDIVIDUAL DEVICES SKIPPING THE ONES THAT ARE ALREADY OPEN
countL
=
0
;
for
(
iL
=
0
;
iL
<
m_devices
.
size
();
iL
++)
{
driverL
=
m_devices
.
get
(
iL
);
if
(
m_openedDevices
.
get
(
driverL
.
getDevice
().
getDeviceId
())
==
null
)
{
UsbDevice
deviceL
=
driverL
.
getDevice
();
tempL
=
deviceL
.
getDeviceName
()
+
":"
;
if
(
driverL
instanceof
FtdiSerialDriver
)
tempL
=
tempL
+
"FTDI:"
;
else
if
(
driverL
instanceof
CdcAcmSerialDriver
)
tempL
=
tempL
+
"Cdc Acm:"
;
else
if
(
driverL
instanceof
Cp2102SerialDriver
)
tempL
=
tempL
+
"Cp2102:"
;
else
if
(
driverL
instanceof
ProlificSerialDriver
)
tempL
=
tempL
+
"Prolific:"
;
else
tempL
=
tempL
+
"Unknown:"
;
tempL
=
tempL
+
Integer
.
toString
(
deviceL
.
getProductId
())
+
":"
;
tempL
=
tempL
+
Integer
.
toString
(
deviceL
.
getVendorId
())
+
":"
;
listL
[
countL
]
=
tempL
;
countL
++;
Log
.
i
(
TAG
,
"Found "
+
tempL
);
}
}
return
listL
;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Open a device based on the name.
//
// Args: nameA - name of the device to open
// userDataA - C++ pointer to the QSerialPort that is trying to open the device. This is
// used by the detector to inform the C++ side if it is unplugged
//
// Returns: ID number of opened port. This number is used to reference the correct port in subsequent
// calls like close(), read(), and write().
//
/////////////////////////////////////////////////////////////////////////////////////////////////
public
static
int
open
(
String
nameA
,
int
userDataA
)
{
int
idL
=
BAD_PORT
;
Log
.
i
(
TAG
,
"Getting device list"
);
if
(!
getCurrentDevices
())
return
BAD_PORT
;
// CHECK THAT PORT IS NOT ALREADY OPENED
if
(
m_openedDevices
!=
null
)
{
for
(
UsbSerialDriver
driverL:
m_openedDevices
.
values
())
{
if
(
nameA
.
equals
(
driverL
.
getDevice
().
getDeviceName
()))
{
Log
.
e
(
TAG
,
"Device already opened"
);
return
BAD_PORT
;
}
}
}
else
return
BAD_PORT
;
if
(
m_devices
==
null
)
return
BAD_PORT
;
// OPEN THE DEVICE
try
{
for
(
int
iL
=
0
;
iL
<
m_devices
.
size
();
iL
++)
{
Log
.
i
(
TAG
,
"Checking device "
+
m_devices
.
get
(
iL
).
getDevice
().
getDeviceName
()
+
" id: "
+
m_devices
.
get
(
iL
).
getDevice
().
getDeviceId
());
if
(
nameA
.
equals
(
m_devices
.
get
(
iL
).
getDevice
().
getDeviceName
()))
{
idL
=
m_devices
.
get
(
iL
).
getDevice
().
getDeviceId
();
m_openedDevices
.
put
(
idL
,
m_devices
.
get
(
iL
));
m_userData
.
put
(
idL
,
userDataA
);
if
(
m_instance
.
m_UsbReceiver
==
null
)
{
m_instance
.
m_UsbReceiver
=
new
BroadcastReceiver
()
{
public
void
onReceive
(
Context
contextA
,
Intent
intentA
)
{
String
actionL
=
intentA
.
getAction
();
if
(
UsbManager
.
ACTION_USB_DEVICE_DETACHED
.
equals
(
actionL
))
{
UsbDevice
deviceL
=
(
UsbDevice
)
intentA
.
getParcelableExtra
(
UsbManager
.
EXTRA_DEVICE
);
if
(
deviceL
!=
null
)
{
if
(
m_userData
.
containsKey
(
deviceL
.
getDeviceId
()))
{
// UsbDeviceJNI.close(deviceL.getDeviceId());
nativeDeviceHasDisconnected
(
m_userData
.
get
(
deviceL
.
getDeviceId
()));
}
}
}
}
};
// TURN ON THE INTENT FILTER SO IT WILL DETECT AN UNPLUG SIGNAL
IntentFilter
filterL
=
new
IntentFilter
();
filterL
.
addAction
(
UsbManager
.
ACTION_USB_DEVICE_DETACHED
);
m_instance
.
registerReceiver
(
m_instance
.
m_UsbReceiver
,
filterL
);
}
m_openedDevices
.
get
(
idL
).
open
();
// START UP THE IO MANAGER TO READ/WRITE DATA TO THE DEVICE
UsbIoManager
managerL
=
new
UsbIoManager
(
m_openedDevices
.
get
(
idL
),
m_Listener
,
userDataA
);
if
(
managerL
==
null
)
Log
.
e
(
TAG
,
"UsbIoManager instance is null"
);
m_ioManager
.
put
(
idL
,
managerL
);
m_Executor
.
submit
(
managerL
);
return
idL
;
}
}
return
BAD_PORT
;
}
catch
(
IOException
exA
)
{
if
(
idL
!=
BAD_PORT
)
{
m_openedDevices
.
remove
(
idL
);
m_userData
.
remove
(
idL
);
if
(
m_ioManager
.
get
(
idL
)
!=
null
)
m_ioManager
.
get
(
idL
).
stop
();
m_ioManager
.
remove
(
idL
);
}
return
BAD_PORT
;
}
}
public
static
void
startIoManager
(
int
idA
)
{
if
(
m_ioManager
.
get
(
idA
)
!=
null
)
return
;
UsbSerialDriver
driverL
=
m_openedDevices
.
get
(
idA
);
if
(
driverL
==
null
)
return
;
UsbIoManager
managerL
=
new
UsbIoManager
(
driverL
,
m_Listener
,
m_userData
.
get
(
idA
));
m_ioManager
.
put
(
idA
,
managerL
);
m_Executor
.
submit
(
managerL
);
}
public
static
void
stopIoManager
(
int
idA
)
{
if
(
m_ioManager
.
get
(
idA
)
==
null
)
return
;
m_ioManager
.
get
(
idA
).
stop
();
m_ioManager
.
remove
(
idA
);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Sets the parameters on an open port.
//
// Args: idA - ID number from the open command
// baudRateA - Decimal value of the baud rate. I.E. 9600, 57600, 115200, etc.
// dataBitsA - number of data bits. Valid numbers are 5, 6, 7, 8
// stopBitsA - number of stop bits. Valid numbers are 1, 2
// parityA - No Parity=0, Odd Parity=1, Even Parity=2
//
// Returns: T/F Success/Failure
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
public
static
boolean
setParameters
(
int
idA
,
int
baudRateA
,
int
dataBitsA
,
int
stopBitsA
,
int
parityA
)
{
UsbSerialDriver
driverL
=
m_openedDevices
.
get
(
idA
);
if
(
driverL
==
null
)
return
false
;
try
{
driverL
.
setParameters
(
baudRateA
,
dataBitsA
,
stopBitsA
,
parityA
);
return
true
;
}
catch
(
IOException
eA
)
{
return
false
;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Close the device.
//
// Args: idA - ID number from the open command
//
// Returns: T/F Success/Failure
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
public
static
boolean
close
(
int
idA
)
{
UsbSerialDriver
driverL
=
m_openedDevices
.
get
(
idA
);
if
(
driverL
==
null
)
return
false
;
try
{
stopIoManager
(
idA
);
m_userData
.
remove
(
idA
);
m_openedDevices
.
remove
(
idA
);
driverL
.
close
();
return
true
;
}
catch
(
IOException
eA
)
{
return
false
;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Write data to the device.
//
// Args: idA - ID number from the open command
// sourceA - byte array of data to write
// timeoutMsecA - amount of time in milliseconds to wait for the write to occur
//
// Returns: number of bytes written
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
public
static
int
write
(
int
idA
,
byte
[]
sourceA
,
int
timeoutMSecA
)
{
UsbSerialDriver
driverL
=
m_openedDevices
.
get
(
idA
);
if
(
driverL
==
null
)
return
0
;
try
{
return
driverL
.
write
(
sourceA
,
timeoutMSecA
);
}
catch
(
IOException
eA
)
{
return
0
;
}
/*
UsbIoManager managerL = m_ioManager.get(idA);
if(managerL != null)
{
managerL.writeAsync(sourceA);
return sourceA.length;
}
else
return 0;
*/
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Determine if a device name if valid. Note, it does not look for devices that are already open
//
// Args: nameA - name of device to look for
//
// Returns: T/F
//
////////////////////////////////////////////////////////////////////////////////////////////////////
public
static
boolean
isDeviceNameValid
(
String
nameA
)
{
if
(
m_devices
.
size
()
<=
0
)
return
false
;
for
(
int
iL
=
0
;
iL
<
m_devices
.
size
();
iL
++)
{
if
(
m_devices
.
get
(
iL
).
getDevice
().
getDeviceName
()
==
nameA
)
return
true
;
}
return
false
;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Check if the device is open
//
// Args: nameA - name of device
//
// Returns: T/F
//
//////////////////////////////////////////////////////////////////////////////////////////////////////
public
static
boolean
isDeviceNameOpen
(
String
nameA
)
{
if
(
m_openedDevices
==
null
)
return
false
;
for
(
UsbSerialDriver
driverL:
m_openedDevices
.
values
())
{
if
(
nameA
.
equals
(
driverL
.
getDevice
().
getDeviceName
()))
return
true
;
}
return
false
;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set the Data Terminal Ready flag on the device
//
// Args: idA - ID number from the open command
// onA - on=T, off=F
//
// Returns: T/F Success/Failure
//
////////////////////////////////////////////////////////////////////////////////////////////////////
public
static
boolean
setDataTerminalReady
(
int
idA
,
boolean
onA
)
{
try
{
UsbSerialDriver
driverL
=
m_openedDevices
.
get
(
idA
);
if
(
driverL
==
null
)
return
false
;
driverL
.
setDTR
(
onA
);
return
true
;
}
catch
(
IOException
eA
)
{
return
false
;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
//
// Set the Request to Send flag
//
// Args: idA - ID number from the open command
// onA - on=T, off=F
//
// Returns: T/F Success/Failure
//
////////////////////////////////////////////////////////////////////////////////////////////
public
static
boolean
setRequestToSend
(
int
idA
,
boolean
onA
)
{
try
{
UsbSerialDriver
driverL
=
m_openedDevices
.
get
(
idA
);
if
(
driverL
==
null
)
return
false
;
driverL
.
setRTS
(
onA
);
return
true
;
}
catch
(
IOException
eA
)
{
return
false
;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
//
// Purge the hardware buffers based on the input and output flags
//
// Args: idA - ID number from the open command
// inputA - input buffer purge. purge=T
// outputA - output buffer purge. purge=T
//
// Returns: T/F Success/Failure
//
///////////////////////////////////////////////////////////////////////////////////////////////
public
static
boolean
purgeBuffers
(
int
idA
,
boolean
inputA
,
boolean
outputA
)
{
try
{
UsbSerialDriver
driverL
=
m_openedDevices
.
get
(
idA
);
if
(
driverL
==
null
)
return
false
;
return
driverL
.
purgeHwBuffers
(
inputA
,
outputA
);
}
catch
(
IOException
eA
)
{
return
false
;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Get the native device handle (file descriptor)
//
// Args: idA - ID number from the open command
//
// Returns: device handle
//
///////////////////////////////////////////////////////////////////////////////////////////
public
static
int
getDeviceHandle
(
int
idA
)
{
UsbSerialDriver
driverL
=
m_openedDevices
.
get
(
idA
);
if
(
driverL
==
null
)
return
-
1
;
UsbDeviceConnection
connectL
=
driverL
.
getDeviceConnection
();
if
(
connectL
==
null
)
return
-
1
;
else
return
connectL
.
getFileDescriptor
();
}
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Get the open usb serial driver for the given id
//
// Args: idA - ID number from the open command
//
// Returns: usb device driver
//
/////////////////////////////////////////////////////////////////////////////////////////////
public
static
UsbSerialDriver
getUsbSerialDriver
(
int
idA
)
{
return
m_openedDevices
.
get
(
idA
);
}
}
android/src/org/qgroundcontrol/qgchelper/UsbIoManager.java
0 → 100644
View file @
59ad9be7
package
org
.
qgroundcontrol
.
qgchelper
;
/* Copyright 2011 Google Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* Project home page: http://code.google.com/p/usb-serial-for-android/
*/
import
com.hoho.android.usbserial.driver.*
;
import
java.io.IOException
;
import
java.nio.ByteBuffer
;
import
android.util.Log
;
/**
* Utility class which services a {@link UsbSerialDriver} in its {@link #run()}
* method.
*
* Original author mike wakerly (opensource@hoho.com)
* Modified by Mike Goza
*/
public
class
UsbIoManager
implements
Runnable
{
private
static
final
int
READ_WAIT_MILLIS
=
100
;
private
static
final
int
BUFSIZ
=
4096
;
private
static
final
String
TAG
=
"QGC_UsbIoManager"
;
private
final
UsbSerialDriver
mDriver
;
private
int
mUserData
;
private
final
ByteBuffer
mReadBuffer
=
ByteBuffer
.
allocate
(
BUFSIZ
);
private
final
ByteBuffer
mWriteBuffer
=
ByteBuffer
.
allocate
(
BUFSIZ
);
private
enum
State
{
STOPPED
,
RUNNING
,
STOPPING
}
// Synchronized by 'this'
private
State
mState
=
State
.
STOPPED
;
// Synchronized by 'this'
private
Listener
mListener
;
public
interface
Listener
{
/**
* Called when new incoming data is available.
*/
public
void
onNewData
(
byte
[]
data
,
int
userData
);
/**
* Called when {@link SerialInputOutputManager#run()} aborts due to an
* error.
*/
public
void
onRunError
(
Exception
e
,
int
userData
);
}
/**
* Creates a new instance with no listener.
*/
public
UsbIoManager
(
UsbSerialDriver
driver
)
{
this
(
driver
,
null
,
0
);
Log
.
i
(
TAG
,
"Instance created"
);
}
/**
* Creates a new instance with the provided listener.
*/
public
UsbIoManager
(
UsbSerialDriver
driver
,
Listener
listener
,
int
userData
)
{
mDriver
=
driver
;
mListener
=
listener
;
mUserData
=
userData
;
}
public
synchronized
void
setListener
(
Listener
listener
)
{
mListener
=
listener
;
}
public
synchronized
Listener
getListener
()
{
return
mListener
;
}
public
void
writeAsync
(
byte
[]
data
)
{
synchronized
(
mWriteBuffer
)
{
mWriteBuffer
.
put
(
data
);
}
}
public
synchronized
void
stop
()
{
if
(
getState
()
==
State
.
RUNNING
)
{
mState
=
State
.
STOPPING
;
mUserData
=
0
;
}
}
private
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
(
mState
!=
State
.
STOPPED
)
throw
new
IllegalStateException
(
"Already running."
);
mState
=
State
.
RUNNING
;
}
try
{
while
(
true
)
{
if
(
mState
!=
State
.
RUNNING
)
break
;
step
();
}
}
catch
(
Exception
e
)
{
final
Listener
listener
=
getListener
();
if
(
listener
!=
null
)
listener
.
onRunError
(
e
,
mUserData
);
}
finally
{
synchronized
(
this
)
{
mState
=
State
.
STOPPED
;
}
}
}
private
void
step
()
throws
IOException
{
// Handle incoming data.
int
len
=
mDriver
.
read
(
mReadBuffer
.
array
(),
READ_WAIT_MILLIS
);
if
(
len
>
0
)
{
final
Listener
listener
=
getListener
();
if
(
listener
!=
null
)
{
final
byte
[]
data
=
new
byte
[
len
];
mReadBuffer
.
get
(
data
,
0
,
len
);
listener
.
onNewData
(
data
,
mUserData
);
}
mReadBuffer
.
clear
();
}
/*
// Handle outgoing data.
byte[] outBuff = null;
synchronized (mWriteBuffer)
{
if (mWriteBuffer.position() > 0)
{
len = mWriteBuffer.position();
outBuff = new byte[len];
mWriteBuffer.rewind();
mWriteBuffer.get(outBuff, 0, len);
mWriteBuffer.clear();
}
}
if (outBuff != null)
mDriver.write(outBuff, READ_WAIT_MILLIS);
*/
}
}
libs/qextserialport/src/qextserialport_unix.cpp
View file @
59ad9be7
...
...
@@ -120,7 +120,11 @@ bool QextSerialPortPrivate::close_sys()
bool
QextSerialPortPrivate
::
flush_sys
()
{
#ifdef __android__
::
ioctl
(
fd
,
TCSADRAIN
,
&
currentTermios
);
#else
::
tcdrain
(
fd
);
#endif
return
true
;
}
...
...
libs/qtandroidserialport/src/qserialport.cpp
0 → 100644
View file @
59ad9be7
/****************************************************************************
**
** Copyright (C) 2011-2012 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2011 Sergey Belyashov <Sergey.Belyashov@gmail.com>
** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
** Copyright (C) 2012 Andre Hartmann <aha_1980@gmx.de>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qserialport.h"
#include "qserialportinfo.h"
#include "qserialportinfo_p.h"
#ifdef Q_OS_WINCE
#include "qserialport_wince_p.h"
#elif defined (Q_OS_WIN)
#include "qserialport_win_p.h"
#elif defined (Q_OS_SYMBIAN)
#include "qserialport_symbian_p.h"
#elif defined (Q_OS_ANDROID)
#include "qserialport_android_p.h"
#elif defined (Q_OS_UNIX)
#include "qserialport_unix_p.h"
#else
#error Unsupported OS
#endif
#ifndef SERIALPORT_BUFFERSIZE
# define SERIALPORT_BUFFERSIZE 16384
#endif
#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
QSerialPortPrivateData
::
QSerialPortPrivateData
(
QSerialPort
*
q
)
:
readBufferMaxSize
(
0
)
,
readBuffer
(
SERIALPORT_BUFFERSIZE
)
,
writeBuffer
(
SERIALPORT_BUFFERSIZE
)
,
error
(
QSerialPort
::
NoError
)
,
inputBaudRate
(
9600
)
,
outputBaudRate
(
9600
)
,
dataBits
(
QSerialPort
::
Data8
)
,
parity
(
QSerialPort
::
NoParity
)
,
stopBits
(
QSerialPort
::
OneStop
)
,
flowControl
(
QSerialPort
::
NoFlowControl
)
,
policy
(
QSerialPort
::
IgnorePolicy
)
#if QT_DEPRECATED_SINCE(5,3)
,
settingsRestoredOnClose
(
true
)
#endif
,
q_ptr
(
q
)
{
}
int
QSerialPortPrivateData
::
timeoutValue
(
int
msecs
,
int
elapsed
)
{
if
(
msecs
==
-
1
)
return
msecs
;
msecs
-=
elapsed
;
return
qMax
(
msecs
,
0
);
}
/*!
\class QSerialPort
\brief Provides functions to access serial ports.
\reentrant
\ingroup serialport-main
\inmodule QtSerialPort
\since 5.1
You can get information about the available serial ports using the
QSerialPortInfo helper class, which allows an enumeration of all the serial
ports in the system. This is useful to obtain the correct name of the
serial port you want to use. You can pass an object
of the helper class as an argument to the setPort() or setPortName()
methods to assign the desired serial device.
After setting the port, you can open it in read-only (r/o), write-only
(w/o), or read-write (r/w) mode using the open() method.
\note The serial port is always opened with exclusive access
(that is, no other process or thread can access an already opened serial port).
Having successfully opened, QSerialPort tries to determine the current
configuration of the port and initializes itself. You can reconfigure the
port to the desired setting using the setBaudRate(), setDataBits(),
setParity(), setStopBits(), and setFlowControl() methods.
There are a couple of properties to work with the pinout signals namely:
QSerialPort::dataTerminalReady, QSerialPort::requestToSend. It is also
possible to use the pinoutSignals() method to query the current pinout
signals set.
Once you know that the ports are ready to read or write, you can
use the read() or write() methods. Alternatively the
readLine() and readAll() convenience methods can also be invoked.
If not all the data is read at once, the remaining data will
be available for later as new incoming data is appended to the
QSerialPort's internal read buffer. You can limit the size of the read
buffer using setReadBufferSize().
Use the close() method to close the port and cancel the I/O operations.
See the following example:
\code
int numRead = 0, numReadTotal = 0;
char buffer[50];
forever {
numRead = serial.read(buffer, 50);
// Do whatever with the array
numReadTotal += numRead;
if (numRead == 0 && !serial.waitForReadyRead())
break;
}
\endcode
If \l{QIODevice::}{waitForReadyRead()} returns false, the
connection has been closed or an error has occurred.
Programming with a blocking serial port is radically different from
programming with a non-blocking serial port. A blocking serial port
does not require an event loop and typically leads to simpler code.
However, in a GUI application, blocking serial port should only be
used in non-GUI threads, to avoid freezing the user interface.
For more details about these approaches, refer to the
\l {Examples}{example} applications.
The QSerialPort class can also be used with QTextStream and QDataStream's
stream operators (operator<<() and operator>>()). There is one issue to be
aware of, though: make sure that enough data is available before attempting
to read by using the operator>>() overloaded operator.
\sa QSerialPortInfo
*/
/*!
\enum QSerialPort::Direction
This enum describes the possible directions of the data transmission.
\note This enumeration is used for setting the baud rate of the device
separately for each direction on some operating systems (for example,
POSIX-like).
\value Input Input direction.
\value Output Output direction.
\value AllDirections Simultaneously in two directions.
*/
/*!
\enum QSerialPort::BaudRate
This enum describes the baud rate which the communication device operates
with.
\note Only the most common standard baud rates are listed in this enum.
\value Baud1200 1200 baud.
\value Baud2400 2400 baud.
\value Baud4800 4800 baud.
\value Baud9600 9600 baud.
\value Baud19200 19200 baud.
\value Baud38400 38400 baud.
\value Baud57600 57600 baud.
\value Baud115200 115200 baud.
\value UnknownBaud Unknown baud. This value is obsolete. It is provided to
keep old source code working. We strongly advise against
using it in new code.
\sa QSerialPort::baudRate
*/
/*!
\enum QSerialPort::DataBits
This enum describes the number of data bits used.
\value Data5 The number of data bits in each character is 5. It
is used for Baudot code. It generally only makes
sense with older equipment such as teleprinters.
\value Data6 The number of data bits in each character is 6. It
is rarely used.
\value Data7 The number of data bits in each character is 7. It
is used for true ASCII. It generally only makes
sense with older equipment such as teleprinters.
\value Data8 The number of data bits in each character is 8. It
is used for most kinds of data, as this size matches
the size of a byte. It is almost universally used in
newer applications.
\value UnknownDataBits Unknown number of bits. This value is obsolete. It
is provided to keep old source code working. We
strongly advise against using it in new code.
\sa QSerialPort::dataBits
*/
/*!
\enum QSerialPort::Parity
This enum describes the parity scheme used.
\value NoParity No parity bit it sent. This is the most common
parity setting. Error detection is handled by the
communication protocol.
\value EvenParity The number of 1 bits in each character, including
the parity bit, is always even.
\value OddParity The number of 1 bits in each character, including
the parity bit, is always odd. It ensures that at
least one state transition occurs in each character.
\value SpaceParity Space parity. The parity bit is sent in the space
signal condition. It does not provide error
detection information.
\value MarkParity Mark parity. The parity bit is always set to the
mark signal condition (logical 1). It does not
provide error detection information.
\value UnknownParity Unknown parity. This value is obsolete. It is
provided to keep old source code working. We
strongly advise against using it in new code.
\sa QSerialPort::parity
*/
/*!
\enum QSerialPort::StopBits
This enum describes the number of stop bits used.
\value OneStop 1 stop bit.
\value OneAndHalfStop 1.5 stop bits. This is only for the Windows platform.
\value TwoStop 2 stop bits.
\value UnknownStopBits Unknown number of stop bits. This value is obsolete.
It is provided to keep old source code working. We
strongly advise against using it in new code.
\sa QSerialPort::stopBits
*/
/*!
\enum QSerialPort::FlowControl
This enum describes the flow control used.
\value NoFlowControl No flow control.
\value HardwareControl Hardware flow control (RTS/CTS).
\value SoftwareControl Software flow control (XON/XOFF).
\value UnknownFlowControl Unknown flow control. This value is obsolete. It
is provided to keep old source code working. We
strongly advise against using it in new code.
\sa QSerialPort::flowControl
*/
/*!
\enum QSerialPort::PinoutSignal
This enum describes the possible RS-232 pinout signals.
\value NoSignal No line active
\value TransmittedDataSignal TxD (Transmitted Data). This value is
obsolete. It is provided to keep old
source code working. We strongly
advise against using it in new code.
\value ReceivedDataSignal RxD (Received Data). This value is
obsolete. It is provided to keep old
source code working. We strongly
advise against using it in new code.
\value DataTerminalReadySignal DTR (Data Terminal Ready).
\value DataCarrierDetectSignal DCD (Data Carrier Detect).
\value DataSetReadySignal DSR (Data Set Ready).
\value RingIndicatorSignal RNG (Ring Indicator).
\value RequestToSendSignal RTS (Request To Send).
\value ClearToSendSignal CTS (Clear To Send).
\value SecondaryTransmittedDataSignal STD (Secondary Transmitted Data).
\value SecondaryReceivedDataSignal SRD (Secondary Received Data).
\sa pinoutSignals(), QSerialPort::dataTerminalReady,
QSerialPort::requestToSend
*/
/*!
\enum QSerialPort::DataErrorPolicy
\obsolete
This enum describes the policies for the received symbols
while parity errors were detected.
\value SkipPolicy Skips the bad character.
\value PassZeroPolicy Replaces bad character with zero.
\value IgnorePolicy Ignores the error for a bad character.
\value StopReceivingPolicy Stops data reception on error.
\value UnknownPolicy Unknown policy.
\sa QSerialPort::dataErrorPolicy
*/
/*!
\enum QSerialPort::SerialPortError
This enum describes the errors that may be contained by the
QSerialPort::error property.
\value NoError No error occurred.
\value DeviceNotFoundError An error occurred while attempting to
open an non-existing device.
\value PermissionError An error occurred while attempting to
open an already opened device by another
process or a user not having enough permission
and credentials to open.
\value OpenError An error occurred while attempting to open an
already opened device in this object.
\value NotOpenError This error occurs when an operation is executed
that can only be successfully performed if the
device is open. This value was introduced in
QtSerialPort 5.2.
\value ParityError Parity error detected by the hardware while
reading data.
\value FramingError Framing error detected by the hardware while
reading data.
\value BreakConditionError Break condition detected by the hardware on
the input line.
\value WriteError An I/O error occurred while writing the data.
\value ReadError An I/O error occurred while reading the data.
\value ResourceError An I/O error occurred when a resource becomes
unavailable, e.g. when the device is
unexpectedly removed from the system.
\value UnsupportedOperationError The requested device operation is not
supported or prohibited by the running operating
system.
\value TimeoutError A timeout error occurred. This value was
introduced in QtSerialPort 5.2.
\value UnknownError An unidentified error occurred.
\sa QSerialPort::error
*/
/*!
Constructs a new serial port object with the given \a parent.
*/
QSerialPort
::
QSerialPort
(
QObject
*
parent
)
:
QIODevice
(
parent
)
,
d_ptr
(
new
QSerialPortPrivate
(
this
))
{}
/*!
Constructs a new serial port object with the given \a parent
to represent the serial port with the specified \a name.
The name should have a specific format; see the setPort() method.
*/
QSerialPort
::
QSerialPort
(
const
QString
&
name
,
QObject
*
parent
)
:
QIODevice
(
parent
)
,
d_ptr
(
new
QSerialPortPrivate
(
this
))
{
setPortName
(
name
);
}
/*!
Constructs a new serial port object with the given \a parent
to represent the serial port with the specified helper class
\a serialPortInfo.
*/
QSerialPort
::
QSerialPort
(
const
QSerialPortInfo
&
serialPortInfo
,
QObject
*
parent
)
:
QIODevice
(
parent
)
,
d_ptr
(
new
QSerialPortPrivate
(
this
))
{
setPort
(
serialPortInfo
);
}
/*!
Closes the serial port, if necessary, and then destroys object.
*/
QSerialPort
::~
QSerialPort
()
{
/**/
if
(
isOpen
())
close
();
delete
d_ptr
;
}
/*!
Sets the \a name of the serial port.
The name of the serial port can be passed as either a short name or
the long system location if necessary.
\sa portName(), QSerialPortInfo
*/
void
QSerialPort
::
setPortName
(
const
QString
&
name
)
{
Q_D
(
QSerialPort
);
d
->
systemLocation
=
QSerialPortInfoPrivate
::
portNameToSystemLocation
(
name
);
}
/*!
Sets the port stored in the serial port info instance \a serialPortInfo.
\sa portName(), QSerialPortInfo
*/
void
QSerialPort
::
setPort
(
const
QSerialPortInfo
&
serialPortInfo
)
{
Q_D
(
QSerialPort
);
d
->
systemLocation
=
serialPortInfo
.
systemLocation
();
}
/*!
Returns the name set by setPort() or passed to the QSerialPort constructor.
This name is short, i.e. it is extracted and converted from the internal
variable system location of the device. The conversion algorithm is
platform specific:
\table
\header
\li Platform
\li Brief Description
\row
\li Windows
\li Removes the prefix "\\\\.\\" or "//./" from the system location
and returns the remainder of the string.
\row
\li Windows CE
\li Removes the suffix ":" from the system location
and returns the remainder of the string.
\row
\li Symbian
\li Returns the system location as it is,
as it is equivalent to the port name.
\row
\li Unix, BSD
\li Removes the prefix "/dev/" from the system location
and returns the remainder of the string.
\endtable
\sa setPort(), QSerialPortInfo::portName()
*/
QString
QSerialPort
::
portName
()
const
{
Q_D
(
const
QSerialPort
);
return
QSerialPortInfoPrivate
::
portNameFromSystemLocation
(
d
->
systemLocation
);
}
/*!
\reimp
Opens the serial port using OpenMode \a mode, and then returns true if
successful; otherwise returns false and sets an error code which can be
obtained by calling the error() method.
\note The method returns false if opening the port is successful, but could
not set any of the port settings successfully. In that case, the port is
closed automatically not to leave the port around with incorrect settings.
\warning The \a mode has to be QIODevice::ReadOnly, QIODevice::WriteOnly,
or QIODevice::ReadWrite. Other modes are unsupported.
\sa QIODevice::OpenMode, setPort()
*/
bool
QSerialPort
::
open
(
OpenMode
mode
)
{
Q_D
(
QSerialPort
);
if
(
isOpen
())
{
setError
(
QSerialPort
::
OpenError
);
return
false
;
}
// Define while not supported modes.
static
const
OpenMode
unsupportedModes
=
Append
|
Truncate
|
Text
|
Unbuffered
;
if
((
mode
&
unsupportedModes
)
||
mode
==
NotOpen
)
{
setError
(
QSerialPort
::
UnsupportedOperationError
);
return
false
;
}
clearError
();
if
(
!
d
->
open
(
mode
))
return
false
;
if
(
!
d
->
setBaudRate
()
||
!
d
->
setDataBits
(
d
->
dataBits
)
||
!
d
->
setParity
(
d
->
parity
)
||
!
d
->
setStopBits
(
d
->
stopBits
)
||
!
d
->
setFlowControl
(
d
->
flowControl
))
{
d
->
close
();
return
false
;
}
QIODevice
::
open
(
mode
);
return
true
;
}
/*!
\reimp
\note The serial port has to be open before trying to close it; otherwise
sets the NotOpenError error code.
\sa QIODevice::close()
*/
void
QSerialPort
::
close
()
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
())
{
setError
(
QSerialPort
::
NotOpenError
);
return
;
}
QIODevice
::
close
();
d
->
close
();
}
/*!
\property QSerialPort::settingsRestoredOnClose
\brief the flag which specifies to restore the previous settings when closing
the serial port.
\obsolete
If this flag is true, the settings will be restored; otherwise not.
The default state of the QSerialPort class is to restore the
settings.
*/
#if QT_DEPRECATED_SINCE(5,3)
void
QSerialPort
::
setSettingsRestoredOnClose
(
bool
restore
)
{
Q_D
(
QSerialPort
);
if
(
d
->
settingsRestoredOnClose
!=
restore
)
{
d
->
settingsRestoredOnClose
=
restore
;
emit
settingsRestoredOnCloseChanged
(
d
->
settingsRestoredOnClose
);
}
}
bool
QSerialPort
::
settingsRestoredOnClose
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
settingsRestoredOnClose
;
}
#endif // QT_DEPRECATED_SINCE(5,3)
/*!
\fn void QSerialPort::settingsRestoredOnCloseChanged(bool restore)
\obsolete
This signal is emitted after the flag which specifies to restore the
previous settings while closing the serial port has been changed. The new
flag which specifies to restore the previous settings while closing the serial
port is passed as \a restore.
\sa QSerialPort::settingsRestoredOnClose
*/
/*!
\property QSerialPort::baudRate
\brief the data baud rate for the desired direction
If the setting is successful or set before opening the port, returns true;
otherwise returns false and sets an error code which can be obtained by
accessing the value of the QSerialPort::error property. To set the baud
rate, use the enumeration QSerialPort::BaudRate or any positive qint32
value.
\note If the setting is set before opening the port, the actual serial port
setting is done automatically in the \l{QSerialPort::open()} method right
after that the opening of the port succeeds.
\warning Setting the AllDirections flag is only supported on
the Windows, Windows CE, and Symbian platforms.
\warning Returns equal baud rate in any direction on Windows, Windows CE, and
Symbian.
The default value is Baud9600, i.e. 9600 bits per second.
*/
bool
QSerialPort
::
setBaudRate
(
qint32
baudRate
,
Directions
directions
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
()
||
d
->
setBaudRate
(
baudRate
,
directions
))
{
if
(
directions
&
QSerialPort
::
Input
)
{
if
(
d
->
inputBaudRate
!=
baudRate
)
d
->
inputBaudRate
=
baudRate
;
else
directions
&=
~
QSerialPort
::
Input
;
}
if
(
directions
&
QSerialPort
::
Output
)
{
if
(
d
->
outputBaudRate
!=
baudRate
)
d
->
outputBaudRate
=
baudRate
;
else
directions
&=
~
QSerialPort
::
Output
;
}
if
(
directions
)
emit
baudRateChanged
(
baudRate
,
directions
);
return
true
;
}
return
false
;
}
qint32
QSerialPort
::
baudRate
(
Directions
directions
)
const
{
Q_D
(
const
QSerialPort
);
if
(
directions
==
QSerialPort
::
AllDirections
)
return
d
->
inputBaudRate
==
d
->
outputBaudRate
?
d
->
inputBaudRate
:
-
1
;
return
directions
&
QSerialPort
::
Input
?
d
->
inputBaudRate
:
d
->
outputBaudRate
;
}
/*!
\fn void QSerialPort::baudRateChanged(qint32 baudRate, Directions directions)
This signal is emitted after the baud rate has been changed. The new baud
rate is passed as \a baudRate and directions as \a directions.
\sa QSerialPort::baudRate
*/
/*!
\property QSerialPort::dataBits
\brief the data bits in a frame
If the setting is successful or set before opening the port, returns
true; otherwise returns false and sets an error code which can be obtained
by accessing the value of the QSerialPort::error property.
\note If the setting is set before opening the port, the actual serial port
setting is done automatically in the \l{QSerialPort::open()} method right
after that the opening of the port succeeds.
The default value is Data8, i.e. 8 data bits.
*/
bool
QSerialPort
::
setDataBits
(
DataBits
dataBits
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
()
||
d
->
setDataBits
(
dataBits
))
{
if
(
d
->
dataBits
!=
dataBits
)
{
d
->
dataBits
=
dataBits
;
emit
dataBitsChanged
(
d
->
dataBits
);
}
return
true
;
}
return
false
;
}
QSerialPort
::
DataBits
QSerialPort
::
dataBits
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
dataBits
;
}
/*!
\fn void QSerialPort::dataBitsChanged(DataBits dataBits)
This signal is emitted after the data bits in a frame has been changed. The
new data bits in a frame is passed as \a dataBits.
\sa QSerialPort::dataBits
*/
/*!
\property QSerialPort::parity
\brief the parity checking mode
If the setting is successful or set before opening the port, returns true;
otherwise returns false and sets an error code which can be obtained by
accessing the value of the QSerialPort::error property.
\note If the setting is set before opening the port, the actual serial port
setting is done automatically in the \l{QSerialPort::open()} method right
after that the opening of the port succeeds.
The default value is NoParity, i.e. no parity.
*/
bool
QSerialPort
::
setParity
(
Parity
parity
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
()
||
d
->
setParity
(
parity
))
{
if
(
d
->
parity
!=
parity
)
{
d
->
parity
=
parity
;
emit
parityChanged
(
d
->
parity
);
}
return
true
;
}
return
false
;
}
QSerialPort
::
Parity
QSerialPort
::
parity
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
parity
;
}
/*!
\fn void QSerialPort::parityChanged(Parity parity)
This signal is emitted after the parity checking mode has been changed. The
new parity checking mode is passed as \a parity.
\sa QSerialPort::parity
*/
/*!
\property QSerialPort::stopBits
\brief the number of stop bits in a frame
If the setting is successful or set before opening the port, returns true;
otherwise returns false and sets an error code which can be obtained by
accessing the value of the QSerialPort::error property.
\note If the setting is set before opening the port, the actual serial port
setting is done automatically in the \l{QSerialPort::open()} method right
after that the opening of the port succeeds.
The default value is OneStop, i.e. 1 stop bit.
*/
bool
QSerialPort
::
setStopBits
(
StopBits
stopBits
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
()
||
d
->
setStopBits
(
stopBits
))
{
if
(
d
->
stopBits
!=
stopBits
)
{
d
->
stopBits
=
stopBits
;
emit
stopBitsChanged
(
d
->
stopBits
);
}
return
true
;
}
return
false
;
}
QSerialPort
::
StopBits
QSerialPort
::
stopBits
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
stopBits
;
}
/*!
\fn void QSerialPort::stopBitsChanged(StopBits stopBits)
This signal is emitted after the number of stop bits in a frame has been
changed. The new number of stop bits in a frame is passed as \a stopBits.
\sa QSerialPort::stopBits
*/
/*!
\property QSerialPort::flowControl
\brief the desired flow control mode
If the setting is successful or set before opening the port, returns true;
otherwise returns false and sets an error code which can be obtained by
accessing the value of the QSerialPort::error property.
\note If the setting is set before opening the port, the actual serial port
setting is done automatically in the \l{QSerialPort::open()} method right
after that the opening of the port succeeds.
The default value is NoFlowControl, i.e. no flow control.
*/
bool
QSerialPort
::
setFlowControl
(
FlowControl
flowControl
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
()
||
d
->
setFlowControl
(
flowControl
))
{
if
(
d
->
flowControl
!=
flowControl
)
{
d
->
flowControl
=
flowControl
;
emit
flowControlChanged
(
d
->
flowControl
);
}
return
true
;
}
return
false
;
}
QSerialPort
::
FlowControl
QSerialPort
::
flowControl
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
flowControl
;
}
/*!
\fn void QSerialPort::flowControlChanged(FlowControl flow)
This signal is emitted after the flow control mode has been changed. The
new flow control mode is passed as \a flow.
\sa QSerialPort::flowControl
*/
/*!
\property QSerialPort::dataTerminalReady
\brief the state (high or low) of the line signal DTR
Returns true on success, false otherwise.
If the flag is true then the DTR signal is set to high; otherwise low.
\note The serial port has to be open before trying to set or get this
property; otherwise false is returned and the error code is set to
NotOpenError.
\sa pinoutSignals()
*/
bool
QSerialPort
::
setDataTerminalReady
(
bool
set
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
())
{
setError
(
QSerialPort
::
NotOpenError
);
qWarning
(
"%s: device not open"
,
Q_FUNC_INFO
);
return
false
;
}
const
bool
dataTerminalReady
=
isDataTerminalReady
();
const
bool
retval
=
d
->
setDataTerminalReady
(
set
);
if
(
retval
&&
(
dataTerminalReady
!=
set
))
emit
dataTerminalReadyChanged
(
set
);
return
retval
;
}
bool
QSerialPort
::
isDataTerminalReady
()
{
Q_D
(
QSerialPort
);
return
d
->
pinoutSignals
()
&
QSerialPort
::
DataTerminalReadySignal
;
}
/*!
\fn void QSerialPort::dataTerminalReadyChanged(bool set)
This signal is emitted after the state (high or low) of the line signal DTR
has been changed. The new the state (high or low) of the line signal DTR is
passed as \a set.
\sa QSerialPort::dataTerminalReady
*/
/*!
\property QSerialPort::requestToSend
\brief the state (high or low) of the line signal RTS
Returns true on success, false otherwise.
If the flag is true then the RTS signal is set to high; otherwise low.
\note The serial port has to be open before trying to set or get this
property; otherwise false is returned and the error code is set to
NotOpenError.
\sa pinoutSignals()
*/
bool
QSerialPort
::
setRequestToSend
(
bool
set
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
())
{
setError
(
QSerialPort
::
NotOpenError
);
qWarning
(
"%s: device not open"
,
Q_FUNC_INFO
);
return
false
;
}
const
bool
requestToSend
=
isRequestToSend
();
const
bool
retval
=
d
->
setRequestToSend
(
set
);
if
(
retval
&&
(
requestToSend
!=
set
))
emit
requestToSendChanged
(
set
);
return
retval
;
}
bool
QSerialPort
::
isRequestToSend
()
{
Q_D
(
QSerialPort
);
return
d
->
pinoutSignals
()
&
QSerialPort
::
RequestToSendSignal
;
}
/*!
\fn void QSerialPort::requestToSendChanged(bool set)
This signal is emitted after the state (high or low) of the line signal RTS
has been changed. The new the state (high or low) of the line signal RTS is
passed as \a set.
\sa QSerialPort::requestToSend
*/
/*!
Returns the state of the line signals in a bitmap format.
From this result, it is possible to allocate the state of the
desired signal by applying a mask "AND", where the mask is
the desired enumeration value from QSerialPort::PinoutSignals.
\note This method performs a system call, thus ensuring that the line signal
states are returned properly. This is necessary when the underlying
operating systems cannot provide proper notifications about the changes.
\note The serial port has to be open before trying to get the pinout
signals; otherwise returns NoSignal and sets the NotOpenError error code.
\sa QSerialPort::dataTerminalReady, QSerialPort::requestToSend
*/
QSerialPort
::
PinoutSignals
QSerialPort
::
pinoutSignals
()
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
())
{
setError
(
QSerialPort
::
NotOpenError
);
qWarning
(
"%s: device not open"
,
Q_FUNC_INFO
);
return
QSerialPort
::
NoSignal
;
}
return
d
->
pinoutSignals
();
}
/*!
This function writes as much as possible from the internal write
buffer to the underlying serial port without blocking. If any data
was written, this function returns true; otherwise returns false.
Call this function for sending the buffered data immediately to the serial
port. The number of bytes successfully written depends on the operating
system. In most cases, this function does not need to be called, because the
QSerialPort class will start sending data automatically once control is
returned to the event loop. In the absence of an event loop, call
waitForBytesWritten() instead.
\note The serial port has to be open before trying to flush any buffered
data; otherwise returns false and sets the NotOpenError error code.
\sa write(), waitForBytesWritten()
*/
bool
QSerialPort
::
flush
()
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
())
{
setError
(
QSerialPort
::
NotOpenError
);
qWarning
(
"%s: device not open"
,
Q_FUNC_INFO
);
return
false
;
}
return
d
->
flush
();
}
/*!
Discards all characters from the output or input buffer, depending on
given directions \a directions. This includes clearing the internal class buffers and
the UART (driver) buffers. Also terminate pending read or write operations.
If successful, returns true; otherwise returns false.
\note The serial port has to be open before trying to clear any buffered
data; otherwise returns false and sets the NotOpenError error code.
*/
bool
QSerialPort
::
clear
(
Directions
directions
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
())
{
setError
(
QSerialPort
::
NotOpenError
);
qWarning
(
"%s: device not open"
,
Q_FUNC_INFO
);
return
false
;
}
if
(
directions
&
Input
)
d
->
readBuffer
.
clear
();
if
(
directions
&
Output
)
d
->
writeBuffer
.
clear
();
return
d
->
clear
(
directions
);
}
/*!
\reimp
Returns true if no more data is currently available for reading; otherwise
returns false.
This function is most commonly used when reading data from the
serial port in a loop. For example:
\code
// This slot is connected to QSerialPort::readyRead()
void QSerialPortClass::readyReadSlot()
{
while (!port.atEnd()) {
QByteArray data = port.read(100);
....
}
}
\endcode
\sa bytesAvailable(), readyRead()
*/
bool
QSerialPort
::
atEnd
()
const
{
Q_D
(
const
QSerialPort
);
return
QIODevice
::
atEnd
()
&&
(
!
isOpen
()
||
(
d
->
readBuffer
.
size
()
==
0
));
}
/*!
\property QSerialPort::dataErrorPolicy
\brief the error policy for how the process receives characters in the case where
a parity error is detected.
\obsolete
If the setting is successful, returns true; otherwise returns false. The
default policy set is IgnorePolicy.
\note The serial port has to be open before trying to set this property;
otherwise returns false and sets the NotOpenError error code. This is a bit
unusual as opposed to the regular Qt property settings of a class. However,
this is a special use case since the property is set through the interaction
with the kernel and hardware. Hence, the two scenarios cannot be completely
compared to each other.
*/
#if QT_DEPRECATED_SINCE(5, 2)
bool
QSerialPort
::
setDataErrorPolicy
(
DataErrorPolicy
policy
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
())
{
setError
(
QSerialPort
::
NotOpenError
);
qWarning
(
"%s: device not open"
,
Q_FUNC_INFO
);
return
false
;
}
const
bool
ret
=
d
->
policy
==
policy
||
d
->
setDataErrorPolicy
(
policy
);
if
(
ret
&&
(
d
->
policy
!=
policy
))
{
d
->
policy
=
policy
;
emit
dataErrorPolicyChanged
(
d
->
policy
);
}
return
ret
;
}
QSerialPort
::
DataErrorPolicy
QSerialPort
::
dataErrorPolicy
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
policy
;
}
#endif // QT_DEPRECATED_SINCE(5, 2)
/*!
\fn void QSerialPort::dataErrorPolicyChanged(DataErrorPolicy policy)
\obsolete
This signal is emitted after the error policy for how the process receives
characters in case of parity error detection has been changed. The new error
policy for how the process receives the character in case of parity error
detection is passed as \a policy.
\sa QSerialPort::dataErrorPolicy
*/
/*!
\property QSerialPort::error
\brief the error status of the serial port
The I/O device status returns an error code. For example, if open()
returns false, or a read/write operation returns -1, this property can
be used to figure out the reason why the operation failed.
The error code is set to the default QSerialPort::NoError after a call to
clearError()
*/
QSerialPort
::
SerialPortError
QSerialPort
::
error
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
error
;
}
void
QSerialPort
::
clearError
()
{
setError
(
QSerialPort
::
NoError
);
}
/*!
\fn void QSerialPort::error(SerialPortError error)
This signal is emitted after the error has been changed. The new error
is passed as \a error.
\sa QSerialPort::error
*/
/*!
Returns the size of the internal read buffer. This limits the
amount of data that the client can receive before calling the read()
or readAll() methods.
A read buffer size of 0 (the default) means that the buffer has
no size limit, ensuring that no data is lost.
\sa setReadBufferSize(), read()
*/
qint64
QSerialPort
::
readBufferSize
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
readBufferMaxSize
;
}
/*!
Sets the size of QSerialPort's internal read buffer to be \a
size bytes.
If the buffer size is limited to a certain size, QSerialPort
will not buffer more than this size of data. The special case of a buffer
size of 0 means that the read buffer is unlimited and all
incoming data is buffered. This is the default.
This option is useful if the data is only read at certain points
in time (for instance in a real-time streaming application) or if the serial
port should be protected against receiving too much data, which may
eventually cause the application to run out of memory.
\sa readBufferSize(), read()
*/
void
QSerialPort
::
setReadBufferSize
(
qint64
size
)
{
Q_D
(
QSerialPort
);
if
(
d
->
readBufferMaxSize
==
size
)
return
;
d
->
readBufferMaxSize
=
size
;
}
/*!
\reimp
Always returns true. The serial port is a sequential device.
*/
bool
QSerialPort
::
isSequential
()
const
{
return
true
;
}
/*!
\reimp
Returns the number of incoming bytes that are waiting to be read.
\sa bytesToWrite(), read()
*/
qint64
QSerialPort
::
bytesAvailable
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
readBuffer
.
size
()
+
QIODevice
::
bytesAvailable
();
}
/*!
\reimp
Returns the number of bytes that are waiting to be written. The
bytes are written when control goes back to the event loop or
when flush() is called.
\sa bytesAvailable(), flush()
*/
qint64
QSerialPort
::
bytesToWrite
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
bytesToWrite
()
+
QIODevice
::
bytesToWrite
();
}
/*!
\reimp
Returns true if a line of data can be read from the serial port;
otherwise returns false.
\sa readLine()
*/
bool
QSerialPort
::
canReadLine
()
const
{
Q_D
(
const
QSerialPort
);
const
bool
hasLine
=
(
d
->
readBuffer
.
size
()
>
0
)
&&
d
->
readBuffer
.
canReadLine
();
return
hasLine
||
QIODevice
::
canReadLine
();
}
/*!
\reimp
This function blocks until new data is available for reading and the
\l{QIODevice::}{readyRead()} signal has been emitted. The function
will timeout after \a msecs milliseconds.
The function returns true if the readyRead() signal is emitted and
there is new data available for reading; otherwise it returns false
(if an error occurred or the operation timed out).
\sa waitForBytesWritten()
*/
bool
QSerialPort
::
waitForReadyRead
(
int
msecs
)
{
Q_D
(
QSerialPort
);
return
d
->
waitForReadyRead
(
msecs
);
}
/*!
\fn Handle QSerialPort::handle() const
\since 5.2
If the platform is supported and the serial port is open, returns the native
serial port handle; otherwise returns -1.
\warning This function is for expert use only; use it at your own risk.
Furthermore, this function carries no compatibility promise between minor
Qt releases.
*/
/*!
\reimp
*/
bool
QSerialPort
::
waitForBytesWritten
(
int
msecs
)
{
Q_D
(
QSerialPort
);
return
d
->
waitForBytesWritten
(
msecs
);
}
/*!
Sends a continuous stream of zero bits during a specified period
of time \a duration in msec if the terminal is using asynchronous
serial data. If successful, returns true; otherwise returns false.
If the duration is zero then zero bits are transmitted by at least
0.25 seconds, but no more than 0.5 seconds.
If the duration is non zero then zero bits are transmitted within a certain
period of time depending on the implementation.
\note The serial port has to be open before trying to send a break
duration; otherwise returns false and sets the NotOpenError error code.
\sa setBreakEnabled()
*/
bool
QSerialPort
::
sendBreak
(
int
duration
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
())
{
setError
(
QSerialPort
::
NotOpenError
);
qWarning
(
"%s: device not open"
,
Q_FUNC_INFO
);
return
false
;
}
return
d
->
sendBreak
(
duration
);
}
/*!
Controls the signal break, depending on the flag \a set.
If successful, returns true; otherwise returns false.
If \a set is true then enables the break transmission; otherwise disables.
\note The serial port has to be open before trying to set break enabled;
otherwise returns false and sets the NotOpenError error code.
\sa sendBreak()
*/
bool
QSerialPort
::
setBreakEnabled
(
bool
set
)
{
Q_D
(
QSerialPort
);
if
(
!
isOpen
())
{
setError
(
QSerialPort
::
NotOpenError
);
qWarning
(
"%s: device not open"
,
Q_FUNC_INFO
);
return
false
;
}
return
d
->
setBreakEnabled
(
set
);
}
/*!
\reimp
*/
qint64
QSerialPort
::
readData
(
char
*
data
,
qint64
maxSize
)
{
Q_D
(
QSerialPort
);
#ifdef Q_OS_ANDROID
qint64
retL
=
d
->
readBuffer
.
read
(
data
,
maxSize
);
d
->
startReadThread
();
return
retL
;
#else
return
d
->
readData
(
data
,
maxSize
);
#endif
}
/*!
\reimp
*/
qint64
QSerialPort
::
readLineData
(
char
*
data
,
qint64
maxSize
)
{
#ifdef Q_OS_ANDROID
qint64
retL
=
QIODevice
::
readLineData
(
data
,
maxSize
);
Q_D
(
QSerialPort
);
d
->
startReadThread
();
return
retL
;
#else
return
QIODevice
::
readLineData
(
data
,
maxSize
);
#endif
}
/*!
\reimp
*/
qint64
QSerialPort
::
writeData
(
const
char
*
data
,
qint64
maxSize
)
{
Q_D
(
QSerialPort
);
return
d
->
writeData
(
data
,
maxSize
);
}
void
QSerialPort
::
setError
(
QSerialPort
::
SerialPortError
serialPortError
,
const
QString
&
errorString
)
{
Q_D
(
QSerialPort
);
d
->
error
=
serialPortError
;
if
(
errorString
.
isNull
())
setErrorString
(
qt_error_string
(
-
1
));
else
setErrorString
(
errorString
);
emit
error
(
serialPortError
);
}
#include "moc_qserialport.cpp"
QT_END_NAMESPACE
libs/qtandroidserialport/src/qserialport.h
0 → 100644
View file @
59ad9be7
/****************************************************************************
**
** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSERIALPORT_H
#define QSERIALPORT_H
#include <QtCore/qiodevice.h>
QT_BEGIN_NAMESPACE
class
QSerialPortInfo
;
class
QSerialPortPrivate
;
class
QSerialPort
:
public
QIODevice
{
Q_OBJECT
Q_DECLARE_PRIVATE
(
QSerialPort
)
Q_PROPERTY
(
qint32
baudRate
READ
baudRate
WRITE
setBaudRate
NOTIFY
baudRateChanged
)
Q_PROPERTY
(
DataBits
dataBits
READ
dataBits
WRITE
setDataBits
NOTIFY
dataBitsChanged
)
Q_PROPERTY
(
Parity
parity
READ
parity
WRITE
setParity
NOTIFY
parityChanged
)
Q_PROPERTY
(
StopBits
stopBits
READ
stopBits
WRITE
setStopBits
NOTIFY
stopBitsChanged
)
Q_PROPERTY
(
FlowControl
flowControl
READ
flowControl
WRITE
setFlowControl
NOTIFY
flowControlChanged
)
#if QT_DEPRECATED_SINCE(5, 2)
Q_PROPERTY
(
DataErrorPolicy
dataErrorPolicy
READ
dataErrorPolicy
WRITE
setDataErrorPolicy
NOTIFY
dataErrorPolicyChanged
)
#endif
Q_PROPERTY
(
bool
dataTerminalReady
READ
isDataTerminalReady
WRITE
setDataTerminalReady
NOTIFY
dataTerminalReadyChanged
)
Q_PROPERTY
(
bool
requestToSend
READ
isRequestToSend
WRITE
setRequestToSend
NOTIFY
requestToSendChanged
)
Q_PROPERTY
(
SerialPortError
error
READ
error
RESET
clearError
NOTIFY
error
)
#if QT_DEPRECATED_SINCE(5, 3)
Q_PROPERTY
(
bool
settingsRestoredOnClose
READ
settingsRestoredOnClose
WRITE
setSettingsRestoredOnClose
NOTIFY
settingsRestoredOnCloseChanged
)
#endif
Q_ENUMS
(
BaudRate
DataBits
Parity
StopBits
FlowControl
DataErrorPolicy
SerialPortError
)
Q_FLAGS
(
Directions
PinoutSignals
)
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
typedef
void
*
Handle
;
#else
typedef
int
Handle
;
#endif
public:
enum
Direction
{
Input
=
1
,
Output
=
2
,
AllDirections
=
Input
|
Output
};
Q_DECLARE_FLAGS
(
Directions
,
Direction
)
enum
BaudRate
{
Baud1200
=
1200
,
Baud2400
=
2400
,
Baud4800
=
4800
,
Baud9600
=
9600
,
Baud19200
=
19200
,
Baud38400
=
38400
,
Baud57600
=
57600
,
Baud115200
=
115200
,
UnknownBaud
=
-
1
};
enum
DataBits
{
Data5
=
5
,
Data6
=
6
,
Data7
=
7
,
Data8
=
8
,
UnknownDataBits
=
-
1
};
enum
Parity
{
NoParity
=
0
,
EvenParity
=
2
,
OddParity
=
3
,
SpaceParity
=
4
,
MarkParity
=
5
,
UnknownParity
=
-
1
};
enum
StopBits
{
OneStop
=
1
,
OneAndHalfStop
=
3
,
TwoStop
=
2
,
UnknownStopBits
=
-
1
};
enum
FlowControl
{
NoFlowControl
,
HardwareControl
,
SoftwareControl
,
UnknownFlowControl
=
-
1
};
enum
PinoutSignal
{
NoSignal
=
0x00
,
TransmittedDataSignal
=
0x01
,
ReceivedDataSignal
=
0x02
,
DataTerminalReadySignal
=
0x04
,
DataCarrierDetectSignal
=
0x08
,
DataSetReadySignal
=
0x10
,
RingIndicatorSignal
=
0x20
,
RequestToSendSignal
=
0x40
,
ClearToSendSignal
=
0x80
,
SecondaryTransmittedDataSignal
=
0x100
,
SecondaryReceivedDataSignal
=
0x200
};
Q_DECLARE_FLAGS
(
PinoutSignals
,
PinoutSignal
)
#if QT_DEPRECATED_SINCE(5, 2)
#if defined _MSC_VER
#pragma deprecated(UnknownBaud)
#pragma deprecated(UnknownDataBits)
#pragma deprecated(UnknownParity)
#pragma deprecated(UnknownStopBits)
#pragma deprecated(UnknownFlowControl)
#pragma deprecated(TransmittedDataSignal)
#pragma deprecated(ReceivedDataSignal)
#endif
#endif
#if QT_DEPRECATED_SINCE(5, 2)
enum
DataErrorPolicy
{
SkipPolicy
,
PassZeroPolicy
,
IgnorePolicy
,
StopReceivingPolicy
,
UnknownPolicy
=
-
1
};
#endif
enum
SerialPortError
{
NoError
,
DeviceNotFoundError
,
PermissionError
,
OpenError
,
ParityError
,
FramingError
,
BreakConditionError
,
WriteError
,
ReadError
,
ResourceError
,
UnsupportedOperationError
,
UnknownError
,
TimeoutError
,
NotOpenError
};
explicit
QSerialPort
(
QObject
*
parent
=
Q_NULLPTR
);
explicit
QSerialPort
(
const
QString
&
name
,
QObject
*
parent
=
Q_NULLPTR
);
explicit
QSerialPort
(
const
QSerialPortInfo
&
info
,
QObject
*
parent
=
Q_NULLPTR
);
virtual
~
QSerialPort
();
void
setPortName
(
const
QString
&
name
);
QString
portName
()
const
;
void
setPort
(
const
QSerialPortInfo
&
info
);
bool
open
(
OpenMode
mode
)
Q_DECL_OVERRIDE
;
void
close
()
Q_DECL_OVERRIDE
;
#if QT_DEPRECATED_SINCE(5, 3)
QT_DEPRECATED
void
setSettingsRestoredOnClose
(
bool
restore
);
QT_DEPRECATED
bool
settingsRestoredOnClose
()
const
;
#endif
bool
setBaudRate
(
qint32
baudRate
,
Directions
directions
=
AllDirections
);
qint32
baudRate
(
Directions
directions
=
AllDirections
)
const
;
bool
setDataBits
(
DataBits
dataBits
);
DataBits
dataBits
()
const
;
bool
setParity
(
Parity
parity
);
Parity
parity
()
const
;
bool
setStopBits
(
StopBits
stopBits
);
StopBits
stopBits
()
const
;
bool
setFlowControl
(
FlowControl
flowControl
);
FlowControl
flowControl
()
const
;
bool
setDataTerminalReady
(
bool
set
);
bool
isDataTerminalReady
();
bool
setRequestToSend
(
bool
set
);
bool
isRequestToSend
();
PinoutSignals
pinoutSignals
();
bool
flush
();
bool
clear
(
Directions
directions
=
AllDirections
);
bool
atEnd
()
const
Q_DECL_OVERRIDE
;
#if QT_DEPRECATED_SINCE(5, 2)
QT_DEPRECATED
bool
setDataErrorPolicy
(
DataErrorPolicy
policy
=
IgnorePolicy
);
QT_DEPRECATED
DataErrorPolicy
dataErrorPolicy
()
const
;
#endif
SerialPortError
error
()
const
;
void
clearError
();
qint64
readBufferSize
()
const
;
void
setReadBufferSize
(
qint64
size
);
bool
isSequential
()
const
Q_DECL_OVERRIDE
;
qint64
bytesAvailable
()
const
Q_DECL_OVERRIDE
;
qint64
bytesToWrite
()
const
Q_DECL_OVERRIDE
;
bool
canReadLine
()
const
Q_DECL_OVERRIDE
;
bool
waitForReadyRead
(
int
msecs
)
Q_DECL_OVERRIDE
;
bool
waitForBytesWritten
(
int
msecs
)
Q_DECL_OVERRIDE
;
bool
sendBreak
(
int
duration
=
0
);
bool
setBreakEnabled
(
bool
set
=
true
);
Handle
handle
()
const
;
Q_SIGNALS:
void
baudRateChanged
(
qint32
baudRate
,
QSerialPort
::
Directions
directions
);
void
dataBitsChanged
(
QSerialPort
::
DataBits
dataBits
);
void
parityChanged
(
QSerialPort
::
Parity
parity
);
void
stopBitsChanged
(
QSerialPort
::
StopBits
stopBits
);
void
flowControlChanged
(
QSerialPort
::
FlowControl
flowControl
);
void
dataErrorPolicyChanged
(
QSerialPort
::
DataErrorPolicy
policy
);
void
dataTerminalReadyChanged
(
bool
set
);
void
requestToSendChanged
(
bool
set
);
void
error
(
QSerialPort
::
SerialPortError
serialPortError
);
void
settingsRestoredOnCloseChanged
(
bool
restore
);
protected:
qint64
readData
(
char
*
data
,
qint64
maxSize
)
Q_DECL_OVERRIDE
;
qint64
readLineData
(
char
*
data
,
qint64
maxSize
)
Q_DECL_OVERRIDE
;
qint64
writeData
(
const
char
*
data
,
qint64
maxSize
)
Q_DECL_OVERRIDE
;
private:
void
setError
(
QSerialPort
::
SerialPortError
error
,
const
QString
&
errorString
=
QString
());
QSerialPortPrivate
*
const
d_ptr
;
Q_DISABLE_COPY
(
QSerialPort
)
#if defined (Q_OS_WIN32)
Q_PRIVATE_SLOT
(
d_func
(),
bool
_q_completeAsyncCommunication
())
Q_PRIVATE_SLOT
(
d_func
(),
bool
_q_completeAsyncRead
())
Q_PRIVATE_SLOT
(
d_func
(),
bool
_q_completeAsyncWrite
())
Q_PRIVATE_SLOT
(
d_func
(),
bool
_q_startAsyncWrite
())
#endif
};
Q_DECLARE_OPERATORS_FOR_FLAGS
(
QSerialPort
::
Directions
)
Q_DECLARE_OPERATORS_FOR_FLAGS
(
QSerialPort
::
PinoutSignals
)
QT_END_NAMESPACE
#endif // QSERIALPORT_H
libs/qtandroidserialport/src/qserialport_android.cpp
0 → 100644
View file @
59ad9be7
/****************************************************************************
**
** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
** Copyright (C) 2012 Andre Hartmann <aha_1980@gmx.de>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
// Written by: S. Michael Goza 2014
// Adapted for QGC by: Gus Grubba 2015
#include <errno.h>
#include <stdio.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qsocketnotifier.h>
#include <QtCore/qmap.h>
#include <QtAndroidExtras/QtAndroidExtras>
#include <QtAndroidExtras/QAndroidJniObject>
#include <android/log.h>
#include "qserialport_android_p.h"
QT_BEGIN_NAMESPACE
#define BAD_PORT 0
static
const
char
V_jniClassName
[]
{
"org/qgroundcontrol/qgchelper/UsbDeviceJNI"
};
static
const
char
V_TAG
[]
{
"QGC_QSerialPort"
};
static
void
jniDeviceHasDisconnected
(
JNIEnv
*
envA
,
jobject
thizA
,
jint
userDataA
)
{
Q_UNUSED
(
envA
);
Q_UNUSED
(
thizA
);
if
(
userDataA
!=
0
)
((
QSerialPortPrivate
*
)
userDataA
)
->
q_ptr
->
close
();
}
static
void
jniDeviceNewData
(
JNIEnv
*
envA
,
jobject
thizA
,
jint
userDataA
,
jbyteArray
dataA
)
{
Q_UNUSED
(
thizA
);
if
(
userDataA
!=
0
)
{
jbyte
*
bytesL
=
envA
->
GetByteArrayElements
(
dataA
,
NULL
);
jsize
lenL
=
envA
->
GetArrayLength
(
dataA
);
((
QSerialPortPrivate
*
)
userDataA
)
->
newDataArrived
((
char
*
)
bytesL
,
lenL
);
envA
->
ReleaseByteArrayElements
(
dataA
,
bytesL
,
JNI_ABORT
);
}
}
static
void
jniDeviceException
(
JNIEnv
*
envA
,
jobject
thizA
,
jint
userDataA
,
jstring
messageA
)
{
Q_UNUSED
(
thizA
);
if
(
userDataA
!=
0
)
{
const
char
*
stringL
=
envA
->
GetStringUTFChars
(
messageA
,
NULL
);
QString
strL
=
QString
::
fromUtf8
(
stringL
);
envA
->
ReleaseStringUTFChars
(
messageA
,
stringL
);
if
(
envA
->
ExceptionCheck
())
envA
->
ExceptionClear
();
((
QSerialPortPrivate
*
)
userDataA
)
->
exceptionArrived
(
strL
);
}
}
QSerialPortPrivate
::
QSerialPortPrivate
(
QSerialPort
*
q
)
:
QSerialPortPrivateData
(
q
)
,
descriptor
(
-
1
)
,
isCustomBaudRateSupported
(
false
)
,
emittedBytesWritten
(
false
)
,
pendingBytesWritten
(
0
)
,
hasRegisteredFunctions
(
false
)
,
jniDataBits
(
8
)
,
jniStopBits
(
1
)
,
jniParity
(
0
)
,
internalWriteTimeoutMsec
(
0
)
,
isReadStopped
(
true
)
{
}
bool
QSerialPortPrivate
::
open
(
QIODevice
::
OpenMode
mode
)
{
rwMode
=
mode
;
__android_log_print
(
ANDROID_LOG_INFO
,
V_TAG
,
"Opening %s"
,
systemLocation
.
toLatin1
().
data
());
QAndroidJniObject
jnameL
=
QAndroidJniObject
::
fromString
(
systemLocation
);
deviceId
=
QAndroidJniObject
::
callStaticMethod
<
jint
>
(
V_jniClassName
,
"open"
,
"(Ljava/lang/String;I)I"
,
jnameL
.
object
<
jstring
>
(),
(
jint
)
this
);
isReadStopped
=
false
;
if
(
deviceId
==
BAD_PORT
)
{
__android_log_print
(
ANDROID_LOG_ERROR
,
V_TAG
,
"Error opening %s"
,
systemLocation
.
toLatin1
().
data
());
q_ptr
->
setError
(
QSerialPort
::
DeviceNotFoundError
);
return
false
;
}
descriptor
=
QAndroidJniObject
::
callStaticMethod
<
jint
>
(
V_jniClassName
,
"getDeviceHandle"
,
"(I)I"
,
deviceId
);
if
(
!
hasRegisteredFunctions
)
{
// REGISTER THE C++ FUNCTION WITH JNI
QAndroidJniEnvironment
envL
;
JNINativeMethod
methodsL
[]
{
{
"nativeDeviceHasDisconnected"
,
"(I)V"
,
reinterpret_cast
<
void
*>
(
jniDeviceHasDisconnected
)},
{
"nativeDeviceNewData"
,
"(I[B)V"
,
reinterpret_cast
<
void
*>
(
jniDeviceNewData
)},
{
"nativeDeviceException"
,
"(ILjava/lang/String;)V"
,
reinterpret_cast
<
void
*>
(
jniDeviceException
)}
};
QAndroidJniObject
javaClassL
(
V_jniClassName
);
jclass
objectClassL
=
envL
->
GetObjectClass
(
javaClassL
.
object
<
jobject
>
());
jint
valL
=
envL
->
RegisterNatives
(
objectClassL
,
methodsL
,
sizeof
(
methodsL
)
/
sizeof
(
methodsL
[
0
]));
envL
->
DeleteLocalRef
(
objectClassL
);
hasRegisteredFunctions
=
true
;
if
(
envL
->
ExceptionCheck
())
envL
->
ExceptionClear
();
if
(
valL
<
0
)
{
__android_log_print
(
ANDROID_LOG_ERROR
,
V_TAG
,
"Error registering methods"
);
q_ptr
->
setError
(
QSerialPort
::
OpenError
);
return
false
;
}
}
if
(
rwMode
==
QIODevice
::
WriteOnly
)
stopReadThread
();
return
true
;
}
void
QSerialPortPrivate
::
close
()
{
if
(
deviceId
==
BAD_PORT
)
return
;
__android_log_print
(
ANDROID_LOG_INFO
,
V_TAG
,
"Closing %s"
,
systemLocation
.
toLatin1
().
data
());
jboolean
resultL
=
QAndroidJniObject
::
callStaticMethod
<
jboolean
>
(
V_jniClassName
,
"close"
,
"(I)Z"
,
deviceId
);
descriptor
=
-
1
;
isCustomBaudRateSupported
=
false
;
pendingBytesWritten
=
0
;
deviceId
=
BAD_PORT
;
if
(
!
resultL
)
q_ptr
->
setErrorString
(
QStringLiteral
(
"Closing device failed"
));
}
bool
QSerialPortPrivate
::
setParameters
(
int
baudRateA
,
int
dataBitsA
,
int
stopBitsA
,
int
parityA
)
{
if
(
deviceId
==
BAD_PORT
)
{
q_ptr
->
setError
(
QSerialPort
::
NotOpenError
);
return
false
;
}
jboolean
resultL
=
QAndroidJniObject
::
callStaticMethod
<
jboolean
>
(
V_jniClassName
,
"setParameters"
,
"(IIIII)Z"
,
deviceId
,
baudRateA
,
dataBitsA
,
stopBitsA
,
parityA
);
if
(
resultL
)
{
// SET THE JNI VALUES TO WHAT WAS SENT
inputBaudRate
=
outputBaudRate
=
baudRateA
;
jniDataBits
=
dataBitsA
;
jniStopBits
=
stopBitsA
;
jniParity
=
parityA
;
}
return
resultL
;
}
void
QSerialPortPrivate
::
stopReadThread
()
{
if
(
isReadStopped
)
return
;
QAndroidJniObject
::
callStaticMethod
<
void
>
(
V_jniClassName
,
"stopIoManager"
,
"(I)V"
,
deviceId
);
isReadStopped
=
true
;
}
void
QSerialPortPrivate
::
startReadThread
()
{
if
(
!
isReadStopped
)
return
;
QAndroidJniObject
::
callStaticMethod
<
void
>
(
V_jniClassName
,
"startIoManager"
,
"(I)V"
,
deviceId
);
isReadStopped
=
false
;
}
QSerialPort
::
PinoutSignals
QSerialPortPrivate
::
pinoutSignals
()
{
return
QSerialPort
::
NoSignal
;
}
bool
QSerialPortPrivate
::
setDataTerminalReady
(
bool
set
)
{
if
(
deviceId
==
BAD_PORT
)
{
q_ptr
->
setError
(
QSerialPort
::
NotOpenError
);
return
false
;
}
return
QAndroidJniObject
::
callStaticMethod
<
jboolean
>
(
V_jniClassName
,
"setDataTerminalReady"
,
"(IZ)Z"
,
deviceId
,
set
);
}
bool
QSerialPortPrivate
::
setRequestToSend
(
bool
set
)
{
if
(
deviceId
==
BAD_PORT
)
{
q_ptr
->
setError
(
QSerialPort
::
NotOpenError
);
return
false
;
}
return
QAndroidJniObject
::
callStaticMethod
<
jboolean
>
(
V_jniClassName
,
"setRequestToSend"
,
"(IZ)Z"
,
deviceId
,
set
);
}
bool
QSerialPortPrivate
::
flush
()
{
return
writeDataOneShot
();
}
bool
QSerialPortPrivate
::
clear
(
QSerialPort
::
Directions
directions
)
{
if
(
deviceId
==
BAD_PORT
)
{
q_ptr
->
setError
(
QSerialPort
::
NotOpenError
);
return
false
;
}
bool
inputL
=
false
;
bool
outputL
=
false
;
if
(
directions
==
QSerialPort
::
AllDirections
)
inputL
=
outputL
=
true
;
else
{
if
(
directions
&
QSerialPort
::
Input
)
inputL
=
true
;
if
(
directions
&
QSerialPort
::
Output
)
outputL
=
true
;
}
return
QAndroidJniObject
::
callStaticMethod
<
jboolean
>
(
V_jniClassName
,
"purgeBuffers"
,
"(IZZ)Z"
,
deviceId
,
inputL
,
outputL
);
}
bool
QSerialPortPrivate
::
sendBreak
(
int
duration
)
{
Q_UNUSED
(
duration
);
return
true
;
}
bool
QSerialPortPrivate
::
setBreakEnabled
(
bool
set
)
{
Q_UNUSED
(
set
);
return
true
;
}
void
QSerialPortPrivate
::
startWriting
()
{
writeDataOneShot
();
}
bool
QSerialPortPrivate
::
waitForReadyRead
(
int
msecs
)
{
int
origL
=
readBuffer
.
size
();
if
(
origL
>
0
)
return
true
;
for
(
int
iL
=
0
;
iL
<
msecs
;
iL
++
)
{
if
(
origL
<
readBuffer
.
size
())
return
true
;
else
QThread
::
msleep
(
1
);
}
return
false
;
}
bool
QSerialPortPrivate
::
waitForBytesWritten
(
int
msecs
)
{
internalWriteTimeoutMsec
=
msecs
;
bool
retL
=
writeDataOneShot
();
internalWriteTimeoutMsec
=
0
;
return
retL
;
}
bool
QSerialPortPrivate
::
setBaudRate
()
{
setBaudRate
(
inputBaudRate
,
QSerialPort
::
AllDirections
);
return
true
;
}
bool
QSerialPortPrivate
::
setBaudRate
(
qint32
baudRate
,
QSerialPort
::
Directions
directions
)
{
Q_UNUSED
(
directions
);
return
setParameters
(
baudRate
,
jniDataBits
,
jniStopBits
,
jniParity
);
}
bool
QSerialPortPrivate
::
setDataBits
(
QSerialPort
::
DataBits
dataBits
)
{
int
numBitsL
=
8
;
switch
(
dataBits
)
{
case
QSerialPort
:
:
Data5
:
numBitsL
=
5
;
break
;
case
QSerialPort
:
:
Data6
:
numBitsL
=
6
;
break
;
case
QSerialPort
:
:
Data7
:
numBitsL
=
7
;
break
;
case
QSerialPort
:
:
Data8
:
default:
numBitsL
=
8
;
break
;
}
return
setParameters
(
inputBaudRate
,
numBitsL
,
jniStopBits
,
jniParity
);
}
bool
QSerialPortPrivate
::
setParity
(
QSerialPort
::
Parity
parity
)
{
int
parL
=
0
;
switch
(
parity
)
{
case
QSerialPort
:
:
SpaceParity
:
parL
=
4
;
break
;
case
QSerialPort
:
:
MarkParity
:
parL
=
3
;
break
;
case
QSerialPort
:
:
EvenParity
:
parL
=
2
;
break
;
case
QSerialPort
:
:
OddParity
:
parL
=
1
;
break
;
case
QSerialPort
:
:
NoParity
:
default:
parL
=
0
;
break
;
}
return
setParameters
(
inputBaudRate
,
jniDataBits
,
jniStopBits
,
parL
);
}
bool
QSerialPortPrivate
::
setStopBits
(
QSerialPort
::
StopBits
stopBits
)
{
int
stopL
=
1
;
switch
(
stopBits
)
{
case
QSerialPort
:
:
TwoStop
:
stopL
=
2
;
break
;
case
QSerialPort
:
:
OneAndHalfStop
:
stopL
=
3
;
break
;
case
QSerialPort
:
:
OneStop
:
default:
stopL
=
1
;
break
;
}
return
setParameters
(
inputBaudRate
,
jniDataBits
,
stopL
,
jniParity
);
}
bool
QSerialPortPrivate
::
setFlowControl
(
QSerialPort
::
FlowControl
flowControl
)
{
Q_UNUSED
(
flowControl
);
return
true
;
}
bool
QSerialPortPrivate
::
setDataErrorPolicy
(
QSerialPort
::
DataErrorPolicy
policy
)
{
this
->
policy
=
policy
;
return
true
;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
QSerialPortPrivate
::
newDataArrived
(
char
*
bytesA
,
int
lengthA
)
{
Q_Q
(
QSerialPort
);
int
bytesToReadL
=
lengthA
;
// Always buffered, read data from the port into the read buffer
if
(
readBufferMaxSize
&&
(
bytesToReadL
>
(
readBufferMaxSize
-
readBuffer
.
size
())))
{
bytesToReadL
=
readBufferMaxSize
-
readBuffer
.
size
();
if
(
bytesToReadL
<=
0
)
{
// Buffer is full. User must read data from the buffer
// before we can read more from the port.
stopReadThread
();
return
;
}
}
char
*
ptr
=
readBuffer
.
reserve
(
bytesToReadL
);
memcpy
(
ptr
,
bytesA
,
bytesToReadL
);
emit
q
->
readyRead
();
}
void
QSerialPortPrivate
::
exceptionArrived
(
QString
strA
)
{
q_ptr
->
setErrorString
(
strA
);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool
QSerialPortPrivate
::
writeDataOneShot
()
{
Q_Q
(
QSerialPort
);
pendingBytesWritten
=
-
1
;
while
(
!
writeBuffer
.
isEmpty
())
{
pendingBytesWritten
=
writeToPort
(
writeBuffer
.
readPointer
(),
writeBuffer
.
nextDataBlockSize
());
if
(
pendingBytesWritten
<=
0
)
{
QSerialPort
::
SerialPortError
errorL
=
decodeSystemError
();
if
(
errorL
!=
QSerialPort
::
ResourceError
)
errorL
=
QSerialPort
::
WriteError
;
q
->
setError
(
errorL
);
return
false
;
}
writeBuffer
.
free
(
pendingBytesWritten
);
emit
q
->
bytesWritten
(
pendingBytesWritten
);
}
return
(
pendingBytesWritten
<
0
)
?
false
:
true
;
}
QSerialPort
::
SerialPortError
QSerialPortPrivate
::
decodeSystemError
()
const
{
QSerialPort
::
SerialPortError
error
;
switch
(
errno
)
{
case
ENODEV
:
error
=
QSerialPort
::
DeviceNotFoundError
;
break
;
case
EACCES
:
error
=
QSerialPort
::
PermissionError
;
break
;
case
EBUSY
:
error
=
QSerialPort
::
PermissionError
;
break
;
case
EAGAIN
:
error
=
QSerialPort
::
ResourceError
;
break
;
case
EIO
:
error
=
QSerialPort
::
ResourceError
;
break
;
case
EBADF
:
error
=
QSerialPort
::
ResourceError
;
break
;
default:
error
=
QSerialPort
::
UnknownError
;
break
;
}
return
error
;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
qint64
QSerialPortPrivate
::
writeToPort
(
const
char
*
data
,
qint64
maxSize
)
{
if
(
deviceId
==
BAD_PORT
)
{
q_ptr
->
setError
(
QSerialPort
::
NotOpenError
);
return
0
;
}
QAndroidJniEnvironment
envL
;
jbyteArray
jarrayL
=
envL
->
NewByteArray
(
maxSize
);
envL
->
SetByteArrayRegion
(
jarrayL
,
0
,
maxSize
,
(
jbyte
*
)
data
);
int
resultL
=
QAndroidJniObject
::
callStaticMethod
<
jint
>
(
V_jniClassName
,
"write"
,
"(I[BI)I"
,
deviceId
,
jarrayL
,
internalWriteTimeoutMsec
);
if
(
envL
->
ExceptionCheck
())
{
envL
->
ExceptionClear
();
q_ptr
->
setErrorString
(
QStringLiteral
(
"Writing to the device threw an exception"
));
envL
->
DeleteLocalRef
(
jarrayL
);
return
0
;
}
envL
->
DeleteLocalRef
(
jarrayL
);
return
resultL
;
}
static
inline
bool
evenParity
(
quint8
c
)
{
c
^=
c
>>
4
;
//(c7 ^ c3)(c6 ^ c2)(c5 ^ c1)(c4 ^ c0)
c
^=
c
>>
2
;
//[(c7 ^ c3)(c5 ^ c1)][(c6 ^ c2)(c4 ^ c0)]
c
^=
c
>>
1
;
return
c
&
1
;
//(c7 ^ c3)(c5 ^ c1)(c6 ^ c2)(c4 ^ c0)
}
typedef
QMap
<
qint32
,
qint32
>
BaudRateMap
;
// The OS specific defines can be found in termios.h
static
const
BaudRateMap
createStandardBaudRateMap
()
{
BaudRateMap
baudRateMap
;
#ifdef B50
baudRateMap
.
insert
(
50
,
B50
);
#endif
#ifdef B75
baudRateMap
.
insert
(
75
,
B75
);
#endif
#ifdef B110
baudRateMap
.
insert
(
110
,
B110
);
#endif
#ifdef B134
baudRateMap
.
insert
(
134
,
B134
);
#endif
#ifdef B150
baudRateMap
.
insert
(
150
,
B150
);
#endif
#ifdef B200
baudRateMap
.
insert
(
200
,
B200
);
#endif
#ifdef B300
baudRateMap
.
insert
(
300
,
B300
);
#endif
#ifdef B600
baudRateMap
.
insert
(
600
,
B600
);
#endif
#ifdef B1200
baudRateMap
.
insert
(
1200
,
B1200
);
#endif
#ifdef B1800
baudRateMap
.
insert
(
1800
,
B1800
);
#endif
#ifdef B2400
baudRateMap
.
insert
(
2400
,
B2400
);
#endif
#ifdef B4800
baudRateMap
.
insert
(
4800
,
B4800
);
#endif
#ifdef B7200
baudRateMap
.
insert
(
7200
,
B7200
);
#endif
#ifdef B9600
baudRateMap
.
insert
(
9600
,
B9600
);
#endif
#ifdef B14400
baudRateMap
.
insert
(
14400
,
B14400
);
#endif
#ifdef B19200
baudRateMap
.
insert
(
19200
,
B19200
);
#endif
#ifdef B28800
baudRateMap
.
insert
(
28800
,
B28800
);
#endif
#ifdef B38400
baudRateMap
.
insert
(
38400
,
B38400
);
#endif
#ifdef B57600
baudRateMap
.
insert
(
57600
,
B57600
);
#endif
#ifdef B76800
baudRateMap
.
insert
(
76800
,
B76800
);
#endif
#ifdef B115200
baudRateMap
.
insert
(
115200
,
B115200
);
#endif
#ifdef B230400
baudRateMap
.
insert
(
230400
,
B230400
);
#endif
#ifdef B460800
baudRateMap
.
insert
(
460800
,
B460800
);
#endif
#ifdef B500000
baudRateMap
.
insert
(
500000
,
B500000
);
#endif
#ifdef B576000
baudRateMap
.
insert
(
576000
,
B576000
);
#endif
#ifdef B921600
baudRateMap
.
insert
(
921600
,
B921600
);
#endif
#ifdef B1000000
baudRateMap
.
insert
(
1000000
,
B1000000
);
#endif
#ifdef B1152000
baudRateMap
.
insert
(
1152000
,
B1152000
);
#endif
#ifdef B1500000
baudRateMap
.
insert
(
1500000
,
B1500000
);
#endif
#ifdef B2000000
baudRateMap
.
insert
(
2000000
,
B2000000
);
#endif
#ifdef B2500000
baudRateMap
.
insert
(
2500000
,
B2500000
);
#endif
#ifdef B3000000
baudRateMap
.
insert
(
3000000
,
B3000000
);
#endif
#ifdef B3500000
baudRateMap
.
insert
(
3500000
,
B3500000
);
#endif
#ifdef B4000000
baudRateMap
.
insert
(
4000000
,
B4000000
);
#endif
return
baudRateMap
;
}
static
const
BaudRateMap
&
standardBaudRateMap
()
{
static
const
BaudRateMap
baudRateMap
=
createStandardBaudRateMap
();
return
baudRateMap
;
}
qint32
QSerialPortPrivate
::
baudRateFromSetting
(
qint32
setting
)
{
return
standardBaudRateMap
().
key
(
setting
);
}
qint32
QSerialPortPrivate
::
settingFromBaudRate
(
qint32
baudRate
)
{
return
standardBaudRateMap
().
value
(
baudRate
);
}
QList
<
qint32
>
QSerialPortPrivate
::
standardBaudRates
()
{
return
standardBaudRateMap
().
keys
();
}
QSerialPort
::
Handle
QSerialPort
::
handle
()
const
{
Q_D
(
const
QSerialPort
);
return
d
->
descriptor
;
}
qint64
QSerialPortPrivate
::
bytesToWrite
()
const
{
return
writeBuffer
.
size
();
}
qint64
QSerialPortPrivate
::
writeData
(
const
char
*
data
,
qint64
maxSize
)
{
return
writeToPort
(
data
,
maxSize
);
}
QT_END_NAMESPACE
libs/qtandroidserialport/src/qserialport_android_p.h
0 → 100644
View file @
59ad9be7
#ifndef QSERIALPORT_ANDROID_P_H
#define QSERIALPORT_ANDROID_P_H
/****************************************************************************
**
** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qserialport_p.h"
#include <QtCore/qscopedpointer.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qthread.h>
QT_BEGIN_NAMESPACE
class
QSerialPortPrivate
:
public
QSerialPortPrivateData
{
Q_DECLARE_PUBLIC
(
QSerialPort
)
public:
QSerialPortPrivate
(
QSerialPort
*
q
);
bool
open
(
QIODevice
::
OpenMode
mode
);
void
close
();
QSerialPort
::
PinoutSignals
pinoutSignals
();
bool
setDataTerminalReady
(
bool
set
);
bool
setRequestToSend
(
bool
set
);
bool
flush
();
bool
clear
(
QSerialPort
::
Directions
directions
);
bool
sendBreak
(
int
duration
);
bool
setBreakEnabled
(
bool
set
);
void
startWriting
();
bool
waitForReadyRead
(
int
msecs
);
bool
waitForBytesWritten
(
int
msecs
);
bool
setBaudRate
();
bool
setBaudRate
(
qint32
baudRate
,
QSerialPort
::
Directions
directions
);
bool
setDataBits
(
QSerialPort
::
DataBits
dataBits
);
bool
setParity
(
QSerialPort
::
Parity
parity
);
bool
setStopBits
(
QSerialPort
::
StopBits
stopBits
);
bool
setFlowControl
(
QSerialPort
::
FlowControl
flowControl
);
bool
setDataErrorPolicy
(
QSerialPort
::
DataErrorPolicy
policy
);
bool
startAsyncWrite
();
bool
completeAsyncWrite
();
void
newDataArrived
(
char
*
bytesA
,
int
lengthA
);
void
exceptionArrived
(
QString
strA
);
void
stopReadThread
();
void
startReadThread
();
qint64
bytesToWrite
()
const
;
qint64
writeData
(
const
char
*
data
,
qint64
maxSize
);
static
qint32
baudRateFromSetting
(
qint32
setting
);
static
qint32
settingFromBaudRate
(
qint32
baudRate
);
static
QList
<
qint32
>
standardBaudRates
();
int
descriptor
;
bool
isCustomBaudRateSupported
;
bool
emittedBytesWritten
;
qint64
pendingBytesWritten
;
private:
QIODevice
::
OpenMode
rwMode
;
int
deviceId
;
bool
hasRegisteredFunctions
;
int
jniDataBits
;
int
jniStopBits
;
int
jniParity
;
qint64
internalWriteTimeoutMsec
;
bool
isReadStopped
;
bool
setParameters
(
int
baudRateA
,
int
dataBitsA
,
int
stopBitsA
,
int
parityA
);
QSerialPort
::
SerialPortError
decodeSystemError
()
const
;
qint64
writeToPort
(
const
char
*
data
,
qint64
maxSize
);
bool
writeDataOneShot
();
};
QT_END_NAMESPACE
#endif // QSERIALPORT_ANDROID_P_H
libs/qtandroidserialport/src/qserialport_p.h
0 → 100644
View file @
59ad9be7
/****************************************************************************
**
** Copyright (C) 2011-2012 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2011 Sergey Belyashov <Sergey.Belyashov@gmail.com>
** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSERIALPORT_P_H
#define QSERIALPORT_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qserialport.h"
QT_BEGIN_NAMESPACE
class
QGCRingBuffer
{
public:
explicit
inline
QGCRingBuffer
(
int
growth
=
4096
)
:
head
(
0
),
tail
(
0
),
tailBuffer
(
0
),
basicBlockSize
(
growth
),
bufferSize
(
0
)
{
buffers
.
append
(
QByteArray
());
}
inline
int
nextDataBlockSize
()
const
{
return
(
tailBuffer
==
0
?
tail
:
buffers
.
first
().
size
())
-
head
;
}
inline
const
char
*
readPointer
()
const
{
return
buffers
.
isEmpty
()
?
0
:
(
buffers
.
first
().
constData
()
+
head
);
}
// access the bytes at a specified position
// the out-variable length will contain the amount of bytes readable
// from there, e.g. the amount still the same QByteArray
inline
const
char
*
readPointerAtPosition
(
qint64
pos
,
qint64
&
length
)
const
{
if
(
pos
>=
0
)
{
pos
+=
head
;
for
(
int
i
=
0
;
i
<
buffers
.
size
();
++
i
)
{
length
=
(
i
==
tailBuffer
?
tail
:
buffers
[
i
].
size
());
if
(
length
>
pos
)
{
length
-=
pos
;
return
buffers
[
i
].
constData
()
+
pos
;
}
pos
-=
length
;
}
}
length
=
0
;
return
0
;
}
inline
void
free
(
int
bytes
)
{
while
(
bytes
>
0
)
{
int
blockSize
=
buffers
.
first
().
size
()
-
head
;
if
(
tailBuffer
==
0
||
blockSize
>
bytes
)
{
bufferSize
-=
bytes
;
if
(
bufferSize
<=
0
)
clear
();
// try to minify/squeeze us
else
head
+=
bytes
;
return
;
}
bufferSize
-=
blockSize
;
bytes
-=
blockSize
;
buffers
.
removeFirst
();
--
tailBuffer
;
head
=
0
;
}
}
inline
char
*
reserve
(
int
bytes
)
{
if
(
bytes
<=
0
)
return
0
;
// if need buffer reallocation
if
(
tail
+
bytes
>
buffers
.
last
().
size
())
{
if
(
tail
>=
basicBlockSize
)
{
// shrink this buffer to its current size
buffers
.
last
().
resize
(
tail
);
// create a new QByteArray
buffers
.
append
(
QByteArray
());
++
tailBuffer
;
tail
=
0
;
}
buffers
.
last
().
resize
(
qMax
(
basicBlockSize
,
tail
+
bytes
));
}
char
*
writePtr
=
buffers
.
last
().
data
()
+
tail
;
bufferSize
+=
bytes
;
tail
+=
bytes
;
return
writePtr
;
}
inline
void
truncate
(
int
pos
)
{
if
(
pos
<
size
())
chop
(
size
()
-
pos
);
}
inline
void
chop
(
int
bytes
)
{
while
(
bytes
>
0
)
{
if
(
tailBuffer
==
0
||
tail
>
bytes
)
{
bufferSize
-=
bytes
;
if
(
bufferSize
<=
0
)
clear
();
// try to minify/squeeze us
else
tail
-=
bytes
;
return
;
}
bufferSize
-=
tail
;
bytes
-=
tail
;
buffers
.
removeLast
();
--
tailBuffer
;
tail
=
buffers
.
last
().
size
();
}
}
inline
bool
isEmpty
()
const
{
return
tailBuffer
==
0
&&
tail
==
0
;
}
inline
int
getChar
()
{
if
(
isEmpty
())
return
-
1
;
char
c
=
*
readPointer
();
free
(
1
);
return
int
(
uchar
(
c
));
}
inline
void
putChar
(
char
c
)
{
char
*
ptr
=
reserve
(
1
);
*
ptr
=
c
;
}
inline
void
ungetChar
(
char
c
)
{
--
head
;
if
(
head
<
0
)
{
buffers
.
prepend
(
QByteArray
());
buffers
.
first
().
resize
(
basicBlockSize
);
head
=
basicBlockSize
-
1
;
++
tailBuffer
;
}
buffers
.
first
()[
head
]
=
c
;
++
bufferSize
;
}
inline
int
size
()
const
{
return
bufferSize
;
}
inline
void
clear
()
{
buffers
.
erase
(
buffers
.
begin
()
+
1
,
buffers
.
end
());
buffers
.
first
().
clear
();
head
=
tail
=
0
;
tailBuffer
=
0
;
bufferSize
=
0
;
}
inline
int
indexOf
(
char
c
)
const
{
int
index
=
0
;
int
j
=
head
;
for
(
int
i
=
0
;
i
<
buffers
.
size
();
++
i
)
{
const
char
*
ptr
=
buffers
[
i
].
constData
()
+
j
;
j
=
index
+
(
i
==
tailBuffer
?
tail
:
buffers
[
i
].
size
())
-
j
;
while
(
index
<
j
)
{
if
(
*
ptr
++
==
c
)
return
index
;
++
index
;
}
j
=
0
;
}
return
-
1
;
}
inline
int
indexOf
(
char
c
,
int
maxLength
)
const
{
int
index
=
0
;
int
j
=
head
;
for
(
int
i
=
0
;
index
<
maxLength
&&
i
<
buffers
.
size
();
++
i
)
{
const
char
*
ptr
=
buffers
[
i
].
constData
()
+
j
;
j
=
qMin
(
index
+
(
i
==
tailBuffer
?
tail
:
buffers
[
i
].
size
())
-
j
,
maxLength
);
while
(
index
<
j
)
{
if
(
*
ptr
++
==
c
)
return
index
;
++
index
;
}
j
=
0
;
}
return
-
1
;
}
inline
int
read
(
char
*
data
,
int
maxLength
)
{
int
bytesToRead
=
qMin
(
size
(),
maxLength
);
int
readSoFar
=
0
;
while
(
readSoFar
<
bytesToRead
)
{
int
bytesToReadFromThisBlock
=
qMin
(
bytesToRead
-
readSoFar
,
nextDataBlockSize
());
if
(
data
)
memcpy
(
data
+
readSoFar
,
readPointer
(),
bytesToReadFromThisBlock
);
readSoFar
+=
bytesToReadFromThisBlock
;
free
(
bytesToReadFromThisBlock
);
}
return
readSoFar
;
}
// read an unspecified amount (will read the first buffer)
inline
QByteArray
read
()
{
if
(
bufferSize
==
0
)
return
QByteArray
();
QByteArray
qba
(
buffers
.
takeFirst
());
qba
.
reserve
(
0
);
// avoid that resizing needlessly reallocates
if
(
tailBuffer
==
0
)
{
qba
.
resize
(
tail
);
tail
=
0
;
buffers
.
append
(
QByteArray
());
}
else
{
--
tailBuffer
;
}
qba
.
remove
(
0
,
head
);
// does nothing if head is 0
head
=
0
;
bufferSize
-=
qba
.
size
();
return
qba
;
}
// append a new buffer to the end
inline
void
append
(
const
QByteArray
&
qba
)
{
if
(
tail
==
0
)
{
buffers
.
last
()
=
qba
;
}
else
{
buffers
.
last
().
resize
(
tail
);
buffers
.
append
(
qba
);
++
tailBuffer
;
}
tail
=
qba
.
size
();
bufferSize
+=
tail
;
}
inline
int
skip
(
int
length
)
{
return
read
(
0
,
length
);
}
inline
int
readLine
(
char
*
data
,
int
maxLength
)
{
if
(
!
data
||
--
maxLength
<=
0
)
return
-
1
;
int
i
=
indexOf
(
'\n'
,
maxLength
);
i
=
read
(
data
,
i
>=
0
?
(
i
+
1
)
:
maxLength
);
// Terminate it.
data
[
i
]
=
'\0'
;
return
i
;
}
inline
bool
canReadLine
()
const
{
return
indexOf
(
'\n'
)
>=
0
;
}
private:
QList
<
QByteArray
>
buffers
;
int
head
,
tail
;
int
tailBuffer
;
// always buffers.size() - 1
const
int
basicBlockSize
;
int
bufferSize
;
};
class
QSerialPortPrivateData
{
public:
enum
IoConstants
{
ReadChunkSize
=
512
};
QSerialPortPrivateData
(
QSerialPort
*
q
);
int
timeoutValue
(
int
msecs
,
int
elapsed
);
qint64
readBufferMaxSize
;
QGCRingBuffer
readBuffer
;
QGCRingBuffer
writeBuffer
;
QSerialPort
::
SerialPortError
error
;
QString
systemLocation
;
qint32
inputBaudRate
;
qint32
outputBaudRate
;
QSerialPort
::
DataBits
dataBits
;
QSerialPort
::
Parity
parity
;
QSerialPort
::
StopBits
stopBits
;
QSerialPort
::
FlowControl
flowControl
;
QSerialPort
::
DataErrorPolicy
policy
;
bool
settingsRestoredOnClose
;
QSerialPort
*
const
q_ptr
;
};
QT_END_NAMESPACE
#endif // QSERIALPORT_P_H
libs/qtandroidserialport/src/qserialportinfo.cpp
0 → 100644
View file @
59ad9be7
/****************************************************************************
**
** Copyright (C) 2011-2012 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2011 Sergey Belyashov <Sergey.Belyashov@gmail.com>
** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qserialportinfo.h"
#include "qserialportinfo_p.h"
#include "qserialport.h"
QT_BEGIN_NAMESPACE
/*!
\class QSerialPortInfo
\brief Provides information about existing serial ports.
\ingroup serialport-main
\inmodule QtSerialPort
\since 5.1
Use the static functions to generate a list of QSerialPortInfo
objects. Each QSerialPortInfo object in the list represents a single
serial port and can be queried for the port name, system location,
description, and manufacturer. The QSerialPortInfo class can also be
used as an input parameter for the setPort() method of the QSerialPort
class.
\sa QSerialPort
*/
/*!
Constructs an empty QSerialPortInfo object.
\sa isNull()
*/
QSerialPortInfo
::
QSerialPortInfo
()
{
}
/*!
Constructs a copy of \a other.
*/
QSerialPortInfo
::
QSerialPortInfo
(
const
QSerialPortInfo
&
other
)
:
d_ptr
(
other
.
d_ptr
?
new
QSerialPortInfoPrivate
(
*
other
.
d_ptr
)
:
Q_NULLPTR
)
{
}
/*!
Constructs a QSerialPortInfo object from serial \a port.
*/
QSerialPortInfo
::
QSerialPortInfo
(
const
QSerialPort
&
port
)
{
foreach
(
const
QSerialPortInfo
&
serialPortInfo
,
availablePorts
())
{
if
(
port
.
portName
()
==
serialPortInfo
.
portName
())
{
*
this
=
serialPortInfo
;
break
;
}
}
}
/*!
Constructs a QSerialPortInfo object from serial port \a name.
This constructor finds the relevant serial port among the available ones
according to the port name \a name, and constructs the serial port info
instance for that port.
*/
QSerialPortInfo
::
QSerialPortInfo
(
const
QString
&
name
)
{
foreach
(
const
QSerialPortInfo
&
serialPortInfo
,
availablePorts
())
{
if
(
name
==
serialPortInfo
.
portName
())
{
*
this
=
serialPortInfo
;
break
;
}
}
}
QSerialPortInfo
::
QSerialPortInfo
(
const
QSerialPortInfoPrivate
&
dd
)
:
d_ptr
(
new
QSerialPortInfoPrivate
(
dd
))
{
}
/*!
Destroys the QSerialPortInfo object. References to the values in the
object become invalid.
*/
QSerialPortInfo
::~
QSerialPortInfo
()
{
}
/*! \fn void QSerialPortInfo::swap(QSerialPortInfo &other)
Swaps QSerialPortInfo \a other with this QSerialPortInfo. This operation is
very fast and never fails.
*/
void
QSerialPortInfo
::
swap
(
QSerialPortInfo
&
other
)
{
d_ptr
.
swap
(
other
.
d_ptr
);
}
/*!
Sets the QSerialPortInfo object to be equal to \a other.
*/
QSerialPortInfo
&
QSerialPortInfo
::
operator
=
(
const
QSerialPortInfo
&
other
)
{
QSerialPortInfo
(
other
).
swap
(
*
this
);
return
*
this
;
}
/*!
Returns the name of the serial port.
\sa systemLocation()
*/
QString
QSerialPortInfo
::
portName
()
const
{
Q_D
(
const
QSerialPortInfo
);
return
!
d
?
QString
()
:
d
->
portName
;
}
/*!
Returns the system location of the serial port.
\sa portName()
*/
QString
QSerialPortInfo
::
systemLocation
()
const
{
Q_D
(
const
QSerialPortInfo
);
return
!
d
?
QString
()
:
d
->
device
;
}
/*!
Returns the description string of the serial port,
if available; otherwise returns an empty string.
\sa manufacturer(), serialNumber()
*/
QString
QSerialPortInfo
::
description
()
const
{
Q_D
(
const
QSerialPortInfo
);
return
!
d
?
QString
()
:
d
->
description
;
}
/*!
Returns the manufacturer string of the serial port,
if available; otherwise returns an empty string.
\sa description(), serialNumber()
*/
QString
QSerialPortInfo
::
manufacturer
()
const
{
Q_D
(
const
QSerialPortInfo
);
return
!
d
?
QString
()
:
d
->
manufacturer
;
}
/*!
\since 5.3
Returns the serial number string of the serial port,
if available; otherwise returns an empty string.
\note The serial number may include letters.
\sa description(), manufacturer()
*/
QString
QSerialPortInfo
::
serialNumber
()
const
{
Q_D
(
const
QSerialPortInfo
);
return
!
d
?
QString
()
:
d
->
serialNumber
;
}
/*!
Returns the 16-bit vendor number for the serial port, if available;
otherwise returns zero.
\sa hasVendorIdentifier(), productIdentifier(), hasProductIdentifier()
*/
quint16
QSerialPortInfo
::
vendorIdentifier
()
const
{
Q_D
(
const
QSerialPortInfo
);
return
!
d
?
0
:
d
->
vendorIdentifier
;
}
/*!
Returns the 16-bit product number for the serial port, if available;
otherwise returns zero.
\sa hasProductIdentifier(), vendorIdentifier(), hasVendorIdentifier()
*/
quint16
QSerialPortInfo
::
productIdentifier
()
const
{
Q_D
(
const
QSerialPortInfo
);
return
!
d
?
0
:
d
->
productIdentifier
;
}
/*!
Returns true if there is a valid 16-bit vendor number present; otherwise
returns false.
\sa vendorIdentifier(), productIdentifier(), hasProductIdentifier()
*/
bool
QSerialPortInfo
::
hasVendorIdentifier
()
const
{
Q_D
(
const
QSerialPortInfo
);
return
!
d
?
false
:
d
->
hasVendorIdentifier
;
}
/*!
Returns true if there is a valid 16-bit product number present; otherwise
returns false.
\sa productIdentifier(), vendorIdentifier(), hasVendorIdentifier()
*/
bool
QSerialPortInfo
::
hasProductIdentifier
()
const
{
Q_D
(
const
QSerialPortInfo
);
return
!
d
?
false
:
d
->
hasProductIdentifier
;
}
/*!
\fn bool QSerialPortInfo::isNull() const
Returns whether this QSerialPortInfo object holds a
serial port definition.
\sa isBusy()
*/
/*!
\fn bool QSerialPortInfo::isBusy() const
Returns true if serial port is busy;
otherwise returns false.
\sa isNull()
*/
/*!
\fn bool QSerialPortInfo::isValid() const
\obsolete
Returns true if serial port is present on system;
otherwise returns false.
\sa isNull(), isBusy()
*/
/*!
\fn QList<qint32> QSerialPortInfo::standardBaudRates()
Returns a list of available standard baud rates supported by
the current serial port.
*/
/*!
\fn QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
Returns a list of available serial ports on the system.
*/
QT_END_NAMESPACE
libs/qtandroidserialport/src/qserialportinfo.h
0 → 100644
View file @
59ad9be7
/****************************************************************************
**
** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSERIALPORTINFO_H
#define QSERIALPORTINFO_H
#include <QtCore/qlist.h>
#include <QtCore/qscopedpointer.h>
QT_BEGIN_NAMESPACE
class
QSerialPort
;
class
QSerialPortInfoPrivate
;
class
QSerialPortInfoPrivateDeleter
;
class
QSerialPortInfo
{
Q_DECLARE_PRIVATE
(
QSerialPortInfo
)
public:
QSerialPortInfo
();
explicit
QSerialPortInfo
(
const
QSerialPort
&
port
);
explicit
QSerialPortInfo
(
const
QString
&
name
);
QSerialPortInfo
(
const
QSerialPortInfo
&
other
);
~
QSerialPortInfo
();
QSerialPortInfo
&
operator
=
(
const
QSerialPortInfo
&
other
);
void
swap
(
QSerialPortInfo
&
other
);
QString
portName
()
const
;
QString
systemLocation
()
const
;
QString
description
()
const
;
QString
manufacturer
()
const
;
QString
serialNumber
()
const
;
quint16
vendorIdentifier
()
const
;
quint16
productIdentifier
()
const
;
bool
hasVendorIdentifier
()
const
;
bool
hasProductIdentifier
()
const
;
bool
isNull
()
const
;
bool
isBusy
()
const
;
#if QT_DEPRECATED_SINCE(5, 2)
QT_DEPRECATED
bool
isValid
()
const
;
#endif
static
QList
<
qint32
>
standardBaudRates
();
static
QList
<
QSerialPortInfo
>
availablePorts
();
QScopedPointer
<
QSerialPortInfoPrivate
,
QSerialPortInfoPrivateDeleter
>
d_ptr
;
private:
QSerialPortInfo
(
const
QSerialPortInfoPrivate
&
dd
);
friend
QList
<
QSerialPortInfo
>
availablePortsByUdev
(
bool
&
ok
);
friend
QList
<
QSerialPortInfo
>
availablePortsBySysfs
(
bool
&
ok
);
friend
QList
<
QSerialPortInfo
>
availablePortsByFiltersOfDevices
(
bool
&
ok
);
};
inline
bool
QSerialPortInfo
::
isNull
()
const
{
return
!
d_ptr
;
}
QT_END_NAMESPACE
#endif // QSERIALPORTINFO_H
libs/qtandroidserialport/src/qserialportinfo_android.cpp
0 → 100644
View file @
59ad9be7
/****************************************************************************
**
** Copyright (C) 2011-2012 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2011 Sergey Belyashov <Sergey.Belyashov@gmail.com>
** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qserialportinfo.h"
#include "qserialportinfo_p.h"
#include "qserialport_android_p.h"
#include <QtCore/qscopedpointer.h>
#include <QtCore/qstringlist.h>
#include <QtAndroidExtras/QtAndroidExtras>
#include <QtAndroidExtras/QAndroidJniObject>
#include <android/log.h>
QT_BEGIN_NAMESPACE
static
const
char
V_jniClassName
[]
{
"org/qgroundcontrol/qgchelper/UsbDeviceJNI"
};
static
const
char
V_TAG
[]
{
"QGC_QSerialPortInfo"
};
QList
<
QSerialPortInfo
>
availablePortsByFiltersOfDevices
()
{
QList
<
QSerialPortInfo
>
serialPortInfoList
;
__android_log_print
(
ANDROID_LOG_INFO
,
V_TAG
,
"Collecting device list"
);
QAndroidJniObject
resultL
=
QAndroidJniObject
::
callStaticObjectMethod
(
V_jniClassName
,
"availableDevicesInfo"
,
"()[Ljava/lang/String;"
);
if
(
!
resultL
.
isValid
())
{
__android_log_print
(
ANDROID_LOG_ERROR
,
V_TAG
,
"Error from availableDevicesInfo"
);
return
serialPortInfoList
;
}
QAndroidJniEnvironment
envL
;
jobjectArray
objArrayL
=
resultL
.
object
<
jobjectArray
>
();
int
countL
=
envL
->
GetArrayLength
(
objArrayL
);
for
(
int
iL
=
0
;
iL
<
countL
;
iL
++
)
{
QSerialPortInfo
infoL
;
jstring
stringL
=
(
jstring
)(
envL
->
GetObjectArrayElement
(
objArrayL
,
iL
));
const
char
*
rawStringL
=
envL
->
GetStringUTFChars
(
stringL
,
0
);
__android_log_print
(
ANDROID_LOG_INFO
,
V_TAG
,
"Adding device: %s"
,
rawStringL
);
QStringList
strListL
=
QString
::
fromUtf8
(
rawStringL
).
split
(
QStringLiteral
(
":"
));
envL
->
ReleaseStringUTFChars
(
stringL
,
rawStringL
);
infoL
.
d_ptr
->
portName
=
strListL
[
0
];
infoL
.
d_ptr
->
device
=
strListL
[
0
];
infoL
.
d_ptr
->
manufacturer
=
strListL
[
1
];
infoL
.
d_ptr
->
productIdentifier
=
strListL
[
2
].
toInt
();
infoL
.
d_ptr
->
hasProductIdentifier
=
(
infoL
.
d_ptr
->
productIdentifier
!=
0
)
?
true
:
false
;
infoL
.
d_ptr
->
vendorIdentifier
=
strListL
[
3
].
toInt
();
infoL
.
d_ptr
->
hasVendorIdentifier
=
(
infoL
.
d_ptr
->
vendorIdentifier
!=
0
)
?
true
:
false
;
serialPortInfoList
.
append
(
infoL
);
}
return
serialPortInfoList
;
}
QList
<
QSerialPortInfo
>
availablePortsBySysfs
()
{
return
availablePortsByFiltersOfDevices
();
}
QList
<
QSerialPortInfo
>
availablePortsByUdev
()
{
return
availablePortsByFiltersOfDevices
();
}
QList
<
QSerialPortInfo
>
QSerialPortInfo
::
availablePorts
()
{
return
availablePortsByFiltersOfDevices
();
}
QList
<
qint32
>
QSerialPortInfo
::
standardBaudRates
()
{
return
QSerialPortPrivate
::
standardBaudRates
();
}
bool
QSerialPortInfo
::
isBusy
()
const
{
QAndroidJniObject
jstrL
=
QAndroidJniObject
::
fromString
(
d_ptr
->
portName
);
jboolean
resultL
=
QAndroidJniObject
::
callStaticMethod
<
jboolean
>
(
V_jniClassName
,
"isDeviceNameOpen"
,
"(Ljava/lang/String;)Z"
,
jstrL
.
object
<
jstring
>
());
return
resultL
;
}
bool
QSerialPortInfo
::
isValid
()
const
{
QAndroidJniObject
jstrL
=
QAndroidJniObject
::
fromString
(
d_ptr
->
portName
);
jboolean
resultL
=
QAndroidJniObject
::
callStaticMethod
<
jboolean
>
(
V_jniClassName
,
"isDeviceNameValid"
,
"(Ljava/lang/String;)Z"
,
jstrL
.
object
<
jstring
>
());
return
resultL
;
}
QString
QSerialPortInfoPrivate
::
portNameToSystemLocation
(
const
QString
&
source
)
{
return
(
source
.
startsWith
(
QLatin1Char
(
'/'
))
||
source
.
startsWith
(
QStringLiteral
(
"./"
))
||
source
.
startsWith
(
QStringLiteral
(
"../"
)))
?
source
:
(
QStringLiteral
(
"/dev/"
)
+
source
);
}
QString
QSerialPortInfoPrivate
::
portNameFromSystemLocation
(
const
QString
&
source
)
{
return
source
.
startsWith
(
QStringLiteral
(
"/dev/"
))
?
source
.
mid
(
5
)
:
source
;
}
QT_END_NAMESPACE
libs/qtandroidserialport/src/qserialportinfo_p.h
0 → 100644
View file @
59ad9be7
/****************************************************************************
**
** Copyright (C) 2011-2012 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2011 Sergey Belyashov <Sergey.Belyashov@gmail.com>
** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSERIALPORTINFO_P_H
#define QSERIALPORTINFO_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
class
Q_AUTOTEST_EXPORT
QSerialPortInfoPrivate
{
public:
QSerialPortInfoPrivate
()
:
vendorIdentifier
(
0
)
,
productIdentifier
(
0
)
,
hasVendorIdentifier
(
false
)
,
hasProductIdentifier
(
false
)
{
}
~
QSerialPortInfoPrivate
()
{
}
static
QString
portNameToSystemLocation
(
const
QString
&
source
);
static
QString
portNameFromSystemLocation
(
const
QString
&
source
);
QString
portName
;
QString
device
;
QString
description
;
QString
manufacturer
;
QString
serialNumber
;
quint16
vendorIdentifier
;
quint16
productIdentifier
;
bool
hasVendorIdentifier
;
bool
hasProductIdentifier
;
};
class
QSerialPortInfoPrivateDeleter
{
public:
static
void
cleanup
(
QSerialPortInfoPrivate
*
p
)
{
delete
p
;
}
};
QT_END_NAMESPACE
#endif // QSERIALPORTINFO_P_H
libs/qtandroidserialport/src/qtandroidserialport.pri
0 → 100644
View file @
59ad9be7
android {
QT += androidextras
INCLUDEPATH += $$PWD
PUBLIC_HEADERS += \
$$PWD/qserialport.h \
$$PWD/qserialportinfo.h
PRIVATE_HEADERS += \
$$PWD/qserialport_p.h \
$$PWD/qserialportinfo_p.h \
$$PWD/qserialport_android_p.h
SOURCES += \
$$PWD/qserialport.cpp \
$$PWD/qserialportinfo.cpp \
$$PWD/qserialport_android.cpp \
$$PWD/qserialportinfo_android.cpp
CONFIG += mobility
INCLUDEPATH += $$PWD/qt4support/include
HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
}
src/QGC.h
View file @
59ad9be7
...
...
@@ -60,6 +60,9 @@ inline bool isinf(T value)
#define isinf(x) std::isinf(x)
#endif
#endif
#ifdef __android__
#define isinf(x) std::isinf(x)
#endif
namespace
QGC
{
...
...
src/QGCFileDialog.cc
View file @
59ad9be7
...
...
@@ -26,8 +26,10 @@
#include <QRegularExpression>
#include "MainWindow.h"
#ifdef QT_DEBUG
#ifndef __android__
#include "UnitTest.h"
#endif
#endif
QString
QGCFileDialog
::
getExistingDirectory
(
QWidget
*
parent
,
...
...
@@ -38,9 +40,11 @@ QString QGCFileDialog::getExistingDirectory(
_validate
(
options
);
#ifdef QT_DEBUG
#ifndef __android__
if
(
qgcApp
()
->
runningUnitTests
())
{
return
UnitTest
::
_getExistingDirectory
(
parent
,
caption
,
dir
,
options
);
}
else
#endif
#endif
{
return
QFileDialog
::
getExistingDirectory
(
parent
,
caption
,
dir
,
options
);
...
...
@@ -57,9 +61,11 @@ QString QGCFileDialog::getOpenFileName(
_validate
(
options
);
#ifdef QT_DEBUG
#ifndef __android__
if
(
qgcApp
()
->
runningUnitTests
())
{
return
UnitTest
::
_getOpenFileName
(
parent
,
caption
,
dir
,
filter
,
options
);
}
else
#endif
#endif
{
return
QFileDialog
::
getOpenFileName
(
parent
,
caption
,
dir
,
filter
,
NULL
,
options
);
...
...
@@ -76,9 +82,11 @@ QStringList QGCFileDialog::getOpenFileNames(
_validate
(
options
);
#ifdef QT_DEBUG
#ifndef __android__
if
(
qgcApp
()
->
runningUnitTests
())
{
return
UnitTest
::
_getOpenFileNames
(
parent
,
caption
,
dir
,
filter
,
options
);
}
else
#endif
#endif
{
return
QFileDialog
::
getOpenFileNames
(
parent
,
caption
,
dir
,
filter
,
NULL
,
options
);
...
...
@@ -97,9 +105,11 @@ QString QGCFileDialog::getSaveFileName(
_validate
(
options
);
#ifdef QT_DEBUG
#ifndef __android__
if
(
qgcApp
()
->
runningUnitTests
())
{
return
UnitTest
::
_getSaveFileName
(
parent
,
caption
,
dir
,
filter
,
defaultSuffix
,
options
);
}
else
#endif
#endif
{
QString
defaultSuffixCopy
(
defaultSuffix
);
...
...
src/QGCMessageBox.h
View file @
59ad9be7
...
...
@@ -29,8 +29,10 @@
#include "MainWindow.h"
#include "QGCApplication.h"
#ifdef QT_DEBUG
#ifndef __android__
#include "UnitTest.h"
#endif
#endif
/// @file
/// @brief Subclass of QMessageBox which re-implements the static public functions. There are two reasons for this:
...
...
@@ -104,10 +106,12 @@ private:
}
#ifdef QT_DEBUG
#ifndef __android__
if
(
qgcApp
()
->
runningUnitTests
())
{
qDebug
()
<<
"QGCMessageBox (unit testing)"
<<
title
<<
text
;
return
UnitTest
::
_messageBox
(
icon
,
title
,
text
,
buttons
,
defaultButton
);
}
else
#endif
#endif
{
#ifdef Q_OS_MAC
...
...
src/VehicleSetup/PX4Bootloader.cc
View file @
59ad9be7
...
...
@@ -28,7 +28,11 @@
#include "PX4Bootloader.h"
#include <QFile>
#ifdef __android__
#include "qserialportinfo.h"
#else
#include <QSerialPortInfo>
#endif
#include <QDebug>
#include <QTime>
...
...
src/VehicleSetup/PX4FirmwareUpgradeThread.cc
View file @
59ad9be7
...
...
@@ -29,7 +29,11 @@
#include "PX4Bootloader.h"
#include <QTimer>
#ifdef __android__
#include "qserialportinfo.h"
#else
#include <QSerialPortInfo>
#endif
#include <QDebug>
PX4FirmwareUpgradeThreadWorker
::
PX4FirmwareUpgradeThreadWorker
(
QObject
*
parent
)
:
...
...
src/comm/LinkConfiguration.cc
View file @
59ad9be7
...
...
@@ -33,8 +33,10 @@ This file is part of the QGROUNDCONTROL project
#include "TCPLink.h"
#ifdef UNITTEST_BUILD
#ifndef __android__
#include "MockLink.h"
#endif
#endif
#define LINK_SETTING_ROOT "LinkConfigurations"
...
...
@@ -92,9 +94,11 @@ LinkConfiguration* LinkConfiguration::createSettings(int type, const QString& na
config
=
new
TCPConfiguration
(
name
);
break
;
#ifdef UNITTEST_BUILD
#ifndef __android__
case
LinkConfiguration
:
:
TypeMock
:
config
=
new
MockConfiguration
(
name
);
break
;
#endif
#endif
}
return
config
;
...
...
@@ -118,9 +122,11 @@ LinkConfiguration* LinkConfiguration::duplicateSettings(LinkConfiguration* sourc
dupe
=
new
TCPConfiguration
(
dynamic_cast
<
TCPConfiguration
*>
(
source
));
break
;
#ifdef UNITTEST_BUILD
#ifndef __android__
case
TypeMock
:
dupe
=
new
MockConfiguration
(
dynamic_cast
<
MockConfiguration
*>
(
source
));
break
;
#endif
#endif
}
return
dupe
;
...
...
src/comm/LinkManager.cc
View file @
59ad9be7
...
...
@@ -32,7 +32,11 @@ This file is part of the QGROUNDCONTROL project
#include <QList>
#include <QApplication>
#include <QDebug>
#ifdef __android__
#include "qserialportinfo.h"
#else
#include <QSerialPortInfo>
#endif
#include "LinkManager.h"
#include "MainWindow.h"
...
...
@@ -85,9 +89,11 @@ LinkInterface* LinkManager::createConnectedLink(LinkConfiguration* config)
pLink
=
new
TCPLink
(
dynamic_cast
<
TCPConfiguration
*>
(
config
));
break
;
#ifdef UNITTEST_BUILD
#ifndef __android__
case
LinkConfiguration
:
:
TypeMock
:
pLink
=
new
MockLink
(
dynamic_cast
<
MockConfiguration
*>
(
config
));
break
;
#endif
#endif
}
if
(
pLink
)
{
...
...
@@ -379,10 +385,12 @@ void LinkManager::loadLinkConfigurationList()
pLink
->
setPreferred
(
preferred
);
break
;
#ifdef UNITTEST_BUILD
#ifndef __android__
case
LinkConfiguration
:
:
TypeMock
:
pLink
=
(
LinkConfiguration
*
)
new
MockConfiguration
(
name
);
pLink
->
setPreferred
(
false
);
break
;
#endif
#endif
}
if
(
pLink
)
{
...
...
src/comm/LinkManager.h
View file @
59ad9be7
...
...
@@ -40,8 +40,10 @@ This file is part of the PIXHAWK project
#include "TCPLink.h"
#ifdef UNITTEST_BUILD
#ifndef __android__
#include "MockLink.h"
#endif
#endif
#include "ProtocolInterface.h"
#include "QGCSingleton.h"
...
...
src/comm/SerialLink.cc
View file @
59ad9be7
...
...
@@ -12,8 +12,14 @@
#include <QDebug>
#include <QSettings>
#include <QMutexLocker>
#ifdef __android__
#include "qserialport.h"
#include "qserialportinfo.h"
#else
#include <QSerialPort>
#include <QSerialPortInfo>
#endif
#include "SerialLink.h"
#include "QGC.h"
...
...
src/comm/SerialLink.h
View file @
59ad9be7
...
...
@@ -40,7 +40,11 @@ class SerialLink;
#include <QThread>
#include <QMutex>
#include <QString>
#ifdef __android__
#include "qserialport.h"
#else
#include <QSerialPort>
#endif
#include <QMetaType>
#include <QLoggingCategory>
...
...
src/main.cc
View file @
59ad9be7
...
...
@@ -35,7 +35,9 @@ This file is part of the QGROUNDCONTROL project
#include "MainWindow.h"
#include "configuration.h"
#ifdef QT_DEBUG
#ifndef __android__
#include "UnitTest.h"
#endif
#include "CmdLineOptParser.h"
#ifdef Q_OS_WIN
#include <crtdbg.h>
...
...
@@ -156,6 +158,7 @@ int main(int argc, char *argv[])
int
exitCode
;
#ifndef __android__
#ifdef QT_DEBUG
if
(
runUnitTests
)
{
if
(
!
app
->
_initForUnitTests
())
{
...
...
@@ -171,6 +174,7 @@ int main(int argc, char *argv[])
}
exitCode
=
-
failures
;
}
else
#endif
#endif
{
if
(
!
app
->
_initForNormalAppBoot
())
{
...
...
src/qgcunittest/UnitTest.h
View file @
59ad9be7
...
...
@@ -28,6 +28,7 @@
#ifndef UNITTEST_H
#define UNITTEST_H
#ifndef __android__
#include <QObject>
#include <QtTest>
...
...
@@ -186,4 +187,5 @@ private:
QSharedPointer
<
T
>
_unitTest
;
};
#endif // Android
#endif
src/ui/MainWindow.cc
View file @
59ad9be7
...
...
@@ -45,7 +45,9 @@ This file is part of the QGROUNDCONTROL project
#include "MAVLinkProtocol.h"
#include "QGCWaypointListMulti.h"
#include "MainWindow.h"
#ifndef __android__
#include "JoystickWidget.h"
#endif
#include "GAudioOutput.h"
#include "QGCToolWidget.h"
#include "QGCMAVLinkLogPlayer.h"
...
...
@@ -193,8 +195,9 @@ MainWindow::MainWindow(QSplashScreen* splashScreen)
connectCommonActions
();
// Connect user interface devices
emit
initStatusChanged
(
tr
(
"Initializing joystick interface"
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
#ifndef __android__
joystick
=
new
JoystickInput
();
#endif
#ifdef QGC_MOUSE_ENABLED_WIN
emit
initStatusChanged
(
tr
(
"Initializing 3D mouse interface"
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
mouseInput
=
new
Mouse3DInput
(
this
);
...
...
@@ -315,6 +318,7 @@ MainWindow::~MainWindow()
delete
_simulationLink
;
_simulationLink
=
NULL
;
}
#ifndef __android__
if
(
joystick
)
{
joystick
->
shutdown
();
...
...
@@ -322,6 +326,7 @@ MainWindow::~MainWindow()
delete
joystick
;
joystick
=
NULL
;
}
#endif
// Delete all UAS objects
for
(
int
i
=
0
;
i
<
_commsWidgetList
.
size
();
i
++
)
{
...
...
@@ -945,7 +950,11 @@ void MainWindow::showRoadMap()
void
MainWindow
::
showSettings
()
{
#ifndef __android__
SettingsDialog
settings
(
joystick
,
this
);
#else
SettingsDialog
settings
(
this
);
#endif
settings
.
exec
();
}
...
...
@@ -1268,7 +1277,11 @@ void MainWindow::hideSplashScreen(void)
void
MainWindow
::
manageLinks
()
{
#ifndef __android__
SettingsDialog
settings
(
joystick
,
this
,
SettingsDialog
::
ShowCommLinks
);
#else
SettingsDialog
settings
(
this
,
SettingsDialog
::
ShowCommLinks
);
#endif
settings
.
exec
();
}
...
...
src/ui/MainWindow.h
View file @
59ad9be7
...
...
@@ -48,7 +48,9 @@ This file is part of the QGROUNDCONTROL project
#include "CameraView.h"
#include "UASListWidget.h"
#include "MAVLinkSimulationLink.h"
#ifndef __android__
#include "input/JoystickInput.h"
#endif
#if (defined QGC_MOUSE_ENABLED_WIN) | (defined QGC_MOUSE_ENABLED_LINUX)
#include "Mouse6dofInput.h"
#endif // QGC_MOUSE_ENABLED_WIN
...
...
@@ -252,7 +254,9 @@ protected:
QPointer
<
QGCUASFileViewMulti
>
fileWidget
;
#ifndef __android__
JoystickInput
*
joystick
;
///< The joystick manager for QGC
#endif
#ifdef QGC_MOUSE_ENABLED_WIN
/** @brief 3d Mouse support (WIN only) */
...
...
src/ui/SerialConfigurationWindow.cc
View file @
59ad9be7
...
...
@@ -32,7 +32,12 @@ This file is part of the QGROUNDCONTROL project
#include <QSettings>
#include <QFileInfoList>
#include <QDebug>
#ifdef __android__
#include "qserialportinfo.h"
#else
#include <QSerialPortInfo>
#endif
#include <SerialConfigurationWindow.h>
#include <SerialLink.h>
...
...
src/ui/SettingsDialog.cc
View file @
59ad9be7
...
...
@@ -28,7 +28,9 @@
#include "MainWindow.h"
#include "ui_SettingsDialog.h"
#ifndef __android__
#include "JoystickWidget.h"
#endif
#include "LinkManager.h"
#include "MAVLinkProtocol.h"
#include "MAVLinkSettingsWidget.h"
...
...
@@ -39,7 +41,11 @@
#include "QGCMessageBox.h"
#include "MainToolBar.h"
#ifndef __android__
SettingsDialog
::
SettingsDialog
(
JoystickInput
*
joystick
,
QWidget
*
parent
,
int
showTab
,
Qt
::
WindowFlags
flags
)
:
#else
SettingsDialog
::
SettingsDialog
(
QWidget
*
parent
,
int
showTab
,
Qt
::
WindowFlags
flags
)
:
#endif
QDialog
(
parent
,
flags
),
_mainWindow
(
MainWindow
::
instance
()),
_ui
(
new
Ui
::
SettingsDialog
)
...
...
@@ -52,13 +58,17 @@ _ui(new Ui::SettingsDialog)
move
(
position
.
topLeft
());
QGCLinkConfiguration
*
pLinkConf
=
new
QGCLinkConfiguration
(
this
);
#ifndef __android__
JoystickWidget
*
pJoystickConf
=
new
JoystickWidget
(
joystick
,
this
);
#endif
MAVLinkSettingsWidget
*
pMavsettings
=
new
MAVLinkSettingsWidget
(
MAVLinkProtocol
::
instance
(),
this
);
// Add the link settings pane
_ui
->
tabWidget
->
addTab
(
pLinkConf
,
"Comm Links"
);
#ifndef __android__
// Add the joystick settings pane
_ui
->
tabWidget
->
addTab
(
pJoystickConf
,
"Controllers"
);
#endif
// Add the MAVLink settings pane
_ui
->
tabWidget
->
addTab
(
pMavsettings
,
"MAVLink"
);
...
...
@@ -102,9 +112,11 @@ _ui(new Ui::SettingsDialog)
case
ShowCommLinks
:
_ui
->
tabWidget
->
setCurrentWidget
(
pLinkConf
);
break
;
#ifndef __android__
case
ShowControllers
:
_ui
->
tabWidget
->
setCurrentWidget
(
pJoystickConf
);
break
;
#endif
case
ShowMavlink
:
_ui
->
tabWidget
->
setCurrentWidget
(
pMavsettings
);
break
;
...
...
src/ui/SettingsDialog.h
View file @
59ad9be7
...
...
@@ -45,7 +45,11 @@ public:
ShowMavlink
};
#ifdef __android__
SettingsDialog
(
QWidget
*
parent
=
0
,
int
showTab
=
ShowDefault
,
Qt
::
WindowFlags
flags
=
Qt
::
Sheet
);
#else
SettingsDialog
(
JoystickInput
*
joystick
,
QWidget
*
parent
=
0
,
int
showTab
=
ShowDefault
,
Qt
::
WindowFlags
flags
=
Qt
::
Sheet
);
#endif
~
SettingsDialog
();
public
slots
:
...
...
src/ui/configuration/SerialSettingsDialog.cc
View file @
59ad9be7
...
...
@@ -37,8 +37,13 @@ This file is part of the APM_PLANNER project
#include "terminalconsole.h"
#include "ui_SerialSettingsDialog.h"
#ifdef __android__
#include "qserialport.h"
#include "qserialportinfo.h"
#else
#include <QSerialPort>
#include <QSerialPortInfo>
#endif
#include <QIntValidator>
#include <QLineEdit>
...
...
src/ui/configuration/SerialSettingsDialog.h
View file @
59ad9be7
...
...
@@ -37,7 +37,11 @@ This file is part of the APM_PLANNER project
#define SERIALSETTINGSDIALOG_H
#include <QDialog>
#ifdef __android__
#include "qserialport.h"
#else
#include <QSerialPort>
#endif
namespace
Ui
{
class
SerialSettingsDialog
;
...
...
src/ui/configuration/terminalconsole.cpp
View file @
59ad9be7
...
...
@@ -45,8 +45,13 @@ This file is part of the APM_PLANNER project
#include <QStatusBar>
#include <QVBoxLayout>
#include <QComboBox>
#ifdef __android__
#include "qserialport.h"
#include "qserialportinfo.h"
#else
#include <QSerialPort>
#include <QSerialPortInfo>
#endif
TerminalConsole
::
TerminalConsole
(
QWidget
*
parent
)
:
QWidget
(
parent
),
...
...
src/ui/configuration/terminalconsole.h
View file @
59ad9be7
...
...
@@ -39,7 +39,11 @@ This file is part of the APM_PLANNER project
#include "SerialSettingsDialog.h"
#include <QWidget>
#ifdef __android__
#include "qserialport.h"
#else
#include <QSerialPort>
#endif
namespace
Ui
{
class
TerminalConsole
;
...
...
src/ui/designer/QGCParamSlider.h
View file @
59ad9be7
...
...
@@ -3,7 +3,9 @@
#include <QWidget>
#include <QAction>
#ifndef __android__
#include <QtDesigner/QDesignerExportWidget>
#endif
#include "QGCToolWidgetItem.h"
...
...
src/ui/designer/QGCToolWidgetComboBox.h
View file @
59ad9be7
...
...
@@ -3,8 +3,9 @@
#include <QWidget>
#include <QAction>
#ifndef __android__
#include <QtDesigner/QDesignerExportWidget>
#endif
#include "QGCToolWidgetItem.h"
class
QGCUASParamManagerInterface
;
...
...
src/ui/toolbar/MainToolBar.cc
View file @
59ad9be7
...
...
@@ -64,8 +64,13 @@ MainToolBar::MainToolBar(QWidget* parent)
{
setSizePolicy
(
QSizePolicy
::
MinimumExpanding
,
QSizePolicy
::
MinimumExpanding
);
setObjectName
(
"MainToolBar"
);
#ifdef __android__
setMinimumHeight
(
120
);
setMaximumHeight
(
120
);
#else
setMinimumHeight
(
40
);
setMaximumHeight
(
40
);
#endif
setMinimumWidth
(
MainWindow
::
instance
()
->
minimumWidth
());
// Get rid of layout default margins
QLayout
*
pl
=
layout
();
...
...
src/ui/toolbar/MainToolBar.qml
View file @
59ad9be7
...
...
@@ -38,13 +38,14 @@ import QGroundControl.MainToolBar 1.0
import
QGroundControl
.
ScreenTools
1.0
Rectangle
{
id
:
toolBarHolder
property
var
qgcPal
:
QGCPalette
{
id
:
palette
;
colorGroupEnabled
:
true
}
property
ScreenTools
screenTools
:
ScreenTools
{
}
property
int
cellSpacerSize
:
4
property
int
cellHeight
:
30
property
int
cellRadius
:
3
property
int
cellSpacerSize
:
getProportionalDimmension
(
4
)
property
int
cellHeight
:
getProportionalDimmension
(
30
)
property
int
cellRadius
:
getProportionalDimmension
(
3
)
property
var
colorBlue
:
"
#1a6eaa
"
property
var
colorGreen
:
"
#079527
"
...
...
@@ -57,9 +58,16 @@ Rectangle {
property
var
colorGreenText
:
(
qgcPal
.
globalTheme
===
QGCPalette
.
Light
)
?
"
#046b1b
"
:
"
#00d930
"
property
var
colorWhiteText
:
(
qgcPal
.
globalTheme
===
QGCPalette
.
Light
)
?
"
#343333
"
:
"
#f0f0f0
"
id
:
toolBarHolder
color
:
qgcPal
.
windowShade
Component.onCompleted
:
{
console
.
log
(
cellSpacerSize
,
cellHeight
,
cellRadius
);
}
function
getProportionalDimmension
(
val
)
{
return
toolBarHolder
.
height
*
val
/
40
}
function
getMessageColor
()
{
if
(
mainToolBar
.
messageType
===
MainToolBar
.
MessageNone
)
return
qgcPal
.
button
;
...
...
@@ -126,14 +134,14 @@ Rectangle {
id
:
row1
height
:
cellHeight
anchors.left
:
parent
.
left
spacing
:
4
spacing
:
getProportionalDimmension
(
4
)
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.leftMargin
:
10
anchors.leftMargin
:
getProportionalDimmension
(
10
)
Row
{
id
:
row11
height
:
cellHeight
spacing
:
-
12
spacing
:
-
getProportionalDimmension
(
12
)
anchors.verticalCenter
:
parent
.
verticalCenter
Connections
{
target
:
screenTools
...
...
@@ -149,7 +157,7 @@ Rectangle {
QGCToolBarButton
{
id
:
setupButton
width
:
90
width
:
getProportionalDimmension
(
90
)
height
:
cellHeight
exclusiveGroup
:
mainActionGroup
text
:
qsTr
(
"
Setup
"
)
...
...
@@ -163,7 +171,7 @@ Rectangle {
QGCToolBarButton
{
id
:
planButton
width
:
90
width
:
getProportionalDimmension
(
90
)
height
:
cellHeight
exclusiveGroup
:
mainActionGroup
text
:
qsTr
(
"
Plan
"
)
...
...
@@ -177,7 +185,7 @@ Rectangle {
QGCToolBarButton
{
id
:
flyButton
width
:
90
width
:
getProportionalDimmension
(
90
)
height
:
cellHeight
exclusiveGroup
:
mainActionGroup
text
:
qsTr
(
"
Fly
"
)
...
...
@@ -191,7 +199,7 @@ Rectangle {
QGCToolBarButton
{
id
:
analyzeButton
width
:
90
width
:
getProportionalDimmension
(
90
)
height
:
cellHeight
exclusiveGroup
:
mainActionGroup
text
:
qsTr
(
"
Analyze
"
)
...
...
@@ -213,7 +221,7 @@ Rectangle {
Rectangle
{
id
:
messages
width
:
(
mainToolBar
.
messageCount
>
99
)
?
70
:
60
width
:
(
mainToolBar
.
messageCount
>
99
)
?
getProportionalDimmension
(
70
)
:
getProportionalDimmension
(
60
)
height
:
cellHeight
visible
:
(
mainToolBar
.
connectionCount
>
0
)
&&
(
mainToolBar
.
showMessages
)
anchors.verticalCenter
:
parent
.
verticalCenter
...
...
@@ -226,11 +234,11 @@ Rectangle {
Image
{
id
:
messageIcon
source
:
getMessageIcon
();
height
:
16
height
:
getProportionalDimmension
(
16
)
fillMode
:
Image
.
PreserveAspectFit
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.left
:
parent
.
left
anchors.leftMargin
:
10
anchors.leftMargin
:
getProportionalDimmension
(
10
)
}
Rectangle
{
...
...
@@ -256,8 +264,8 @@ Rectangle {
visible
:
(
messages
.
showTriangle
)
&&
(
mainToolBar
.
messageCount
>
0
)
anchors.bottom
:
parent
.
bottom
anchors.right
:
parent
.
right
anchors.bottomMargin
:
3
anchors.rightMargin
:
3
anchors.bottomMargin
:
getProportionalDimmension
(
3
)
anchors.rightMargin
:
getProportionalDimmension
(
3
)
}
Timer
{
...
...
@@ -306,7 +314,7 @@ Rectangle {
Rectangle
{
id
:
satelitte
width
:
60
width
:
getProportionalDimmension
(
60
)
height
:
cellHeight
visible
:
showMavStatus
()
&&
(
mainToolBar
.
showGPS
)
anchors.verticalCenter
:
parent
.
verticalCenter
...
...
@@ -317,11 +325,11 @@ Rectangle {
Image
{
source
:
"
qrc:/res/Gps
"
;
height
:
24
height
:
getProportionalDimmension
(
24
)
fillMode
:
Image
.
PreserveAspectFit
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.left
:
parent
.
left
anchors.leftMargin
:
10
anchors.leftMargin
:
getProportionalDimmension
(
10
)
mipmap
:
true
smooth
:
true
}
...
...
@@ -333,7 +341,7 @@ Rectangle {
font.weight
:
Font
.
DemiBold
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.right
:
parent
.
right
anchors.rightMargin
:
10
anchors.rightMargin
:
getProportionalDimmension
(
10
)
horizontalAlignment
:
Text
.
AlignRight
color
:
colorWhite
}
...
...
@@ -341,7 +349,7 @@ Rectangle {
Rectangle
{
id
:
battery
width
:
80
width
:
getProportionalDimmension
(
80
)
height
:
cellHeight
visible
:
showMavStatus
()
&&
(
mainToolBar
.
showBattery
)
anchors.verticalCenter
:
parent
.
verticalCenter
...
...
@@ -352,11 +360,11 @@ Rectangle {
Image
{
source
:
getBatteryIcon
();
height
:
20
height
:
getProportionalDimmension
(
20
)
fillMode
:
Image
.
PreserveAspectFit
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.left
:
parent
.
left
anchors.leftMargin
:
6
anchors.leftMargin
:
getProportionalDimmension
(
6
)
mipmap
:
true
smooth
:
true
}
...
...
@@ -368,7 +376,7 @@ Rectangle {
font.weight
:
Font
.
DemiBold
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.right
:
parent
.
right
anchors.rightMargin
:
8
anchors.rightMargin
:
getProportionalDimmension
(
8
)
horizontalAlignment
:
Text
.
AlignRight
color
:
colorWhite
}
...
...
@@ -377,7 +385,7 @@ Rectangle {
Column
{
visible
:
showMavStatus
()
height
:
cellHeight
*
0.85
width
:
80
width
:
getProportionalDimmension
(
80
)
anchors.verticalCenter
:
parent
.
verticalCenter
Rectangle
{
...
...
@@ -422,7 +430,7 @@ Rectangle {
Rectangle
{
id
:
modeStatus
width
:
90
width
:
getProportionalDimmension
(
90
)
height
:
cellHeight
visible
:
showMavStatus
()
color
:
"
#00000000
"
...
...
@@ -442,7 +450,7 @@ Rectangle {
Rectangle
{
id
:
connectionStatus
width
:
160
width
:
getProportionalDimmension
(
160
)
height
:
cellHeight
visible
:
(
mainToolBar
.
connectionCount
>
0
&&
mainToolBar
.
mavPresent
&&
mainToolBar
.
heartbeatTimeout
!=
0
)
anchors.verticalCenter
:
parent
.
verticalCenter
...
...
@@ -469,8 +477,8 @@ Rectangle {
spacing
:
cellSpacerSize
anchors.right
:
parent
.
right
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.leftMargin
:
10
anchors.rightMargin
:
10
anchors.leftMargin
:
getProportionalDimmension
(
10
)
anchors.rightMargin
:
getProportionalDimmension
(
10
)
Menu
{
id
:
connectMenu
...
...
@@ -501,7 +509,7 @@ Rectangle {
QGCButton
{
id
:
connectButton
width
:
100
width
:
getProportionalDimmension
(
100
)
visible
:
mainToolBar
.
connectionCount
===
0
text
:
qsTr
(
"
Connect
"
)
menu
:
connectMenu
...
...
@@ -510,7 +518,7 @@ Rectangle {
QGCButton
{
id
:
disconnectButton
width
:
100
width
:
getProportionalDimmension
(
100
)
visible
:
mainToolBar
.
connectionCount
===
1
text
:
qsTr
(
"
Disconnect
"
)
anchors.verticalCenter
:
parent
.
verticalCenter
...
...
@@ -539,7 +547,7 @@ Rectangle {
QGCButton
{
id
:
multidisconnectButton
width
:
100
width
:
getProportionalDimmension
(
100
)
text
:
"
Disconnect
"
visible
:
mainToolBar
.
connectionCount
>
1
menu
:
disconnectMenu
...
...
@@ -550,8 +558,7 @@ Rectangle {
// Progress bar
Rectangle
{
readonly
property
int
progressBarHeight
:
3
readonly
property
int
progressBarHeight
:
getProportionalDimmension
(
3
)
y
:
parent
.
height
-
progressBarHeight
height
:
progressBarHeight
width
:
parent
.
width
*
mainToolBar
.
progressBarValue
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment