+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index db956d4..331b7f8 100644
--- a/README.md
+++ b/README.md
@@ -15,13 +15,11 @@ functions for use with your own protocols.
## Quick Start
-**1.** Download [usb-serial-for-android-v010.jar](https://github.com/mik3y/usb-serial-for-android/releases/download/v0.1.0/usb-serial-for-android-v010.jar)
+**1.** [Link your project](https://github.com/mik3y/usb-serial-for-android/wiki/Building-From-Source) to the library.
-**2.** Copy the jar to your Android project's `libs/` directory. (See [Android's FAQ](http://developer.android.com/guide/faq/commontasks.html#addexternallibrary) for help).
+**2.** Copy [device_filter.xml](http://usb-serial-for-android.googlecode.com/git/UsbSerialExamples/res/xml/device_filter.xml) to your project's `res/xml/` directory.
-**3.** Copy [device_filter.xml](http://usb-serial-for-android.googlecode.com/git/UsbSerialExamples/res/xml/device_filter.xml) to your project's `res/xml/` directory.
-
-**4.** Configure your `AndroidManifest.xml` to notify your app when a device is attached (see [Android USB Host documentation](http://developer.android.com/guide/topics/connectivity/usb/host.html#discovering-d) for help).
+**3.** Configure your `AndroidManifest.xml` to notify your app when a device is attached (see [Android USB Host documentation](http://developer.android.com/guide/topics/connectivity/usb/host.html#discovering-d) for help).
```xml
availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
+if (availableDrivers.isEmpty()) {
+ return;
+}
-// Find the first available driver.
-UsbSerialDriver driver = UsbSerialProber.acquire(manager);
+// Open a connection to the first available driver.
+UsbSerialDriver driver = availableDrivers.get(0);
+UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
+if (connection == null) {
+ // You probably need to call UsbManager.requestPermission(driver.getDevice(), ..)
+ return;
+}
-if (driver != null) {
- driver.open();
- try {
- driver.setBaudRate(115200);
-
- byte buffer[] = new byte[16];
- int numBytesRead = driver.read(buffer, 1000);
- Log.d(TAG, "Read " + numBytesRead + " bytes.");
- } catch (IOException e) {
- // Deal with error.
- } finally {
- driver.close();
- }
+// Read some data! Most have just one port (port 0).
+UsbSerialPort port = driver.getPort(0);
+port.open(connection);
+try {
+ port.setBaudRate(115200);
+ byte buffer[] = new byte[16];
+ int numBytesRead = port.read(buffer, 1000);
+ Log.d(TAG, "Read " + numBytesRead + " bytes.");
+} catch (IOException e) {
+ // Deal with error.
+} finally {
+ port.close();
}
```
@@ -68,6 +74,39 @@ in git, which is a simple application for reading and showing serial data.
A [simple Arduino application](https://github.com/mik3y/usb-serial-for-android/blob/master/arduino)
is also available which can be used for testing.
+
+## Probing for Unrecognized Devices
+
+Sometimes you may need to do a little extra work to support devices which
+usb-serial-for-android doesn't [yet] know about -- but which you know to be
+compatible with one of the built-in drivers. This may be the case for a brand
+new device or for one using a custom VID/PID pair.
+
+UsbSerialProber is a class to help you find and instantiate compatible
+UsbSerialDrivers from the tree of connected UsbDevices. Normally, you will use
+the default prober returned by ``UsbSerialProber.getDefaultProber()``, which
+uses the built-in list of well-known VIDs and PIDs that are supported by our
+drivers.
+
+To use your own set of rules, create and use a custom prober:
+
+```java
+// Probe for our custom CDC devices, which use VID 0x1234
+// and PIDS 0x0001 and 0x0002.
+ProbeTable customTable = new ProbeTable();
+probeTable.addProduct(0x1234, 0x0001, CdcAcmSerialDriver.class);
+probeTable.addProduct(0x1234, 0x0002, CdcAcmSerialDriver.class);
+
+UsbSerialProber prober = new UsbSerialProber(customTable);
+List drivers = prober.findAllDrivers(usbManager);
+// ...
+```
+
+Of course, nothing requires you to use UsbSerialProber at all: you can
+instantiate driver classes directly if you know what you're doing; just supply
+a compatible UsbDevice.
+
+
## Compatible Devices
* *Serial chips:* FT232R, CDC/ACM (eg Arduino Uno) and possibly others.
diff --git a/UsbSerialExamples/.classpath b/UsbSerialExamples/.classpath
deleted file mode 100644
index 202cbff..0000000
--- a/UsbSerialExamples/.classpath
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/UsbSerialExamples/.project b/UsbSerialExamples/.project
deleted file mode 100644
index a74aedb..0000000
--- a/UsbSerialExamples/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- UsbSerialExamples
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/UsbSerialExamples/.settings/org.eclipse.jdt.core.prefs b/UsbSerialExamples/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index d811575..0000000
--- a/UsbSerialExamples/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,280 +0,0 @@
-#Thu Jun 02 12:32:09 PDT 2011
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.6
-org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_assignment=0
-org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
-org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
-org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
-org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
-org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
-org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
-org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_after_package=1
-org.eclipse.jdt.core.formatter.blank_lines_before_field=0
-org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
-org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
-org.eclipse.jdt.core.formatter.blank_lines_before_method=1
-org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
-org.eclipse.jdt.core.formatter.blank_lines_before_package=1
-org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
-org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
-org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
-org.eclipse.jdt.core.formatter.comment.format_block_comments=true
-org.eclipse.jdt.core.formatter.comment.format_header=false
-org.eclipse.jdt.core.formatter.comment.format_html=true
-org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
-org.eclipse.jdt.core.formatter.comment.format_line_comments=true
-org.eclipse.jdt.core.formatter.comment.format_source_code=true
-org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
-org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
-org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
-org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
-org.eclipse.jdt.core.formatter.comment.line_length=80
-org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
-org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
-org.eclipse.jdt.core.formatter.compact_else_if=true
-org.eclipse.jdt.core.formatter.continuation_indentation=2
-org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
-org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
-org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
-org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
-org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
-org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_empty_lines=false
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
-org.eclipse.jdt.core.formatter.indentation.size=4
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
-org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.join_lines_in_comments=true
-org.eclipse.jdt.core.formatter.join_wrapped_lines=false
-org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.lineSplit=100
-org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
-org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
-org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
-org.eclipse.jdt.core.formatter.tabulation.char=space
-org.eclipse.jdt.core.formatter.tabulation.size=4
-org.eclipse.jdt.core.formatter.use_on_off_tags=false
-org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
-org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
-org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/UsbSerialExamples/.settings/org.eclipse.jdt.ui.prefs b/UsbSerialExamples/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 74f510c..0000000
--- a/UsbSerialExamples/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,7 +0,0 @@
-eclipse.preferences.version=1
-formatter_profile=_Android
-formatter_settings_version=11
-org.eclipse.jdt.ui.ignorelowercasenames=true
-org.eclipse.jdt.ui.importorder=android;com;dalvik;gov;junit;libcore;net;org;java;javax;
-org.eclipse.jdt.ui.ondemandthreshold=99
-org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/UsbSerialExamples/proguard.cfg b/UsbSerialExamples/proguard.cfg
deleted file mode 100644
index b1cdf17..0000000
--- a/UsbSerialExamples/proguard.cfg
+++ /dev/null
@@ -1,40 +0,0 @@
--optimizationpasses 5
--dontusemixedcaseclassnames
--dontskipnonpubliclibraryclasses
--dontpreverify
--verbose
--optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-
--keep public class * extends android.app.Activity
--keep public class * extends android.app.Application
--keep public class * extends android.app.Service
--keep public class * extends android.content.BroadcastReceiver
--keep public class * extends android.content.ContentProvider
--keep public class * extends android.app.backup.BackupAgentHelper
--keep public class * extends android.preference.Preference
--keep public class com.android.vending.licensing.ILicensingService
-
--keepclasseswithmembernames class * {
- native ;
-}
-
--keepclasseswithmembers class * {
- public (android.content.Context, android.util.AttributeSet);
-}
-
--keepclasseswithmembers class * {
- public (android.content.Context, android.util.AttributeSet, int);
-}
-
--keepclassmembers class * extends android.app.Activity {
- public void *(android.view.View);
-}
-
--keepclassmembers enum * {
- public static **[] values();
- public static ** valueOf(java.lang.String);
-}
-
--keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
-}
diff --git a/UsbSerialExamples/project.properties b/UsbSerialExamples/project.properties
deleted file mode 100644
index 117494e..0000000
--- a/UsbSerialExamples/project.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-12
-android.library.reference.1=../UsbSerialLibrary
diff --git a/UsbSerialLibrary/.classpath b/UsbSerialLibrary/.classpath
deleted file mode 100644
index 6aed2eb..0000000
--- a/UsbSerialLibrary/.classpath
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/UsbSerialLibrary/.project b/UsbSerialLibrary/.project
deleted file mode 100644
index b8b86d8..0000000
--- a/UsbSerialLibrary/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- UsbSerialLibrary
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/UsbSerialLibrary/.settings/org.eclipse.jdt.core.prefs b/UsbSerialLibrary/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 1ecab4a..0000000
--- a/UsbSerialLibrary/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,349 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
-org.eclipse.jdt.core.compiler.problem.deadCode=error
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=error
-org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=error
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=error
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=error
-org.eclipse.jdt.core.compiler.problem.unusedLabel=error
-org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=error
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
-org.eclipse.jdt.core.compiler.source=1.6
-org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_assignment=0
-org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
-org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
-org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
-org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
-org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
-org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
-org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_after_package=1
-org.eclipse.jdt.core.formatter.blank_lines_before_field=0
-org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
-org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
-org.eclipse.jdt.core.formatter.blank_lines_before_method=1
-org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
-org.eclipse.jdt.core.formatter.blank_lines_before_package=1
-org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
-org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
-org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
-org.eclipse.jdt.core.formatter.comment.format_block_comments=true
-org.eclipse.jdt.core.formatter.comment.format_header=false
-org.eclipse.jdt.core.formatter.comment.format_html=true
-org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
-org.eclipse.jdt.core.formatter.comment.format_line_comments=true
-org.eclipse.jdt.core.formatter.comment.format_source_code=true
-org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
-org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
-org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
-org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
-org.eclipse.jdt.core.formatter.comment.line_length=80
-org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
-org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
-org.eclipse.jdt.core.formatter.compact_else_if=true
-org.eclipse.jdt.core.formatter.continuation_indentation=2
-org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
-org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
-org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
-org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
-org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
-org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_empty_lines=false
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
-org.eclipse.jdt.core.formatter.indentation.size=4
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
-org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.join_lines_in_comments=true
-org.eclipse.jdt.core.formatter.join_wrapped_lines=false
-org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.lineSplit=100
-org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
-org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
-org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
-org.eclipse.jdt.core.formatter.tabulation.char=space
-org.eclipse.jdt.core.formatter.tabulation.size=4
-org.eclipse.jdt.core.formatter.use_on_off_tags=false
-org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
-org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
-org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/UsbSerialLibrary/.settings/org.eclipse.jdt.ui.prefs b/UsbSerialLibrary/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 74f510c..0000000
--- a/UsbSerialLibrary/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,7 +0,0 @@
-eclipse.preferences.version=1
-formatter_profile=_Android
-formatter_settings_version=11
-org.eclipse.jdt.ui.ignorelowercasenames=true
-org.eclipse.jdt.ui.importorder=android;com;dalvik;gov;junit;libcore;net;org;java;javax;
-org.eclipse.jdt.ui.ondemandthreshold=99
-org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/UsbSerialLibrary/proguard.cfg b/UsbSerialLibrary/proguard.cfg
deleted file mode 100644
index 12dd039..0000000
--- a/UsbSerialLibrary/proguard.cfg
+++ /dev/null
@@ -1,36 +0,0 @@
--optimizationpasses 5
--dontusemixedcaseclassnames
--dontskipnonpubliclibraryclasses
--dontpreverify
--verbose
--optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-
--keep public class * extends android.app.Activity
--keep public class * extends android.app.Application
--keep public class * extends android.app.Service
--keep public class * extends android.content.BroadcastReceiver
--keep public class * extends android.content.ContentProvider
--keep public class * extends android.app.backup.BackupAgentHelper
--keep public class * extends android.preference.Preference
--keep public class com.android.vending.licensing.ILicensingService
-
--keepclasseswithmembernames class * {
- native ;
-}
-
--keepclasseswithmembernames class * {
- public (android.content.Context, android.util.AttributeSet);
-}
-
--keepclasseswithmembernames class * {
- public (android.content.Context, android.util.AttributeSet, int);
-}
-
--keepclassmembers enum * {
- public static **[] values();
- public static ** valueOf(java.lang.String);
-}
-
--keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
-}
diff --git a/UsbSerialLibrary/project.properties b/UsbSerialLibrary/project.properties
deleted file mode 100644
index 786389e..0000000
--- a/UsbSerialLibrary/project.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-12
-android.library=true
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java
deleted file mode 100644
index 34fa14a..0000000
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java
+++ /dev/null
@@ -1,248 +0,0 @@
-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 Universal
- * Serial Bus Class Definitions for Communication Devices, v1.1
- */
-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 getSupportedDevices() {
- final Map supportedDevices = new LinkedHashMap();
- 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,
- });
- return supportedDevices;
- }
-
-}
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/Cp2102SerialDriver.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/Cp2102SerialDriver.java
deleted file mode 100644
index 7e9118b..0000000
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/Cp2102SerialDriver.java
+++ /dev/null
@@ -1,291 +0,0 @@
-package com.hoho.android.usbserial.driver;
-
-import java.io.IOException;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-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;
-
-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 getSupportedDevices() {
- final Map supportedDevices = new LinkedHashMap();
- supportedDevices.put(Integer.valueOf(UsbId.VENDOR_SILAB),
- new int[] {
- UsbId.SILAB_CP2102
- });
- return supportedDevices;
- }
-
-
-}
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java
deleted file mode 100644
index caaa4ec..0000000
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java
+++ /dev/null
@@ -1,548 +0,0 @@
-/* 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 com.hoho.android.usbserial.util.HexDump;
-
-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
- *
- * This driver is based on
- * libftdi, and is
- * copyright and subject to the following terms:
- *
- *
- * 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
- *
- *
- *
- *
- * Some FTDI devices have not been tested; see later listing of supported and
- * unsupported devices. Devices listed as "supported" support the following
- * features:
- *
- *
Read and write of serial data (see {@link #read(byte[], int)} and
- * {@link #write(byte[], int)}.
- *
Setting baud rate (see {@link #setBaudRate(int)}).
- *
- *
- *
- * Supported and tested devices:
- *
- *
{@value DeviceType#TYPE_R}
- *
- *
- *
- * Unsupported but possibly working devices (please contact the author with
- * feedback or patches):
- *
- *
{@value DeviceType#TYPE_2232C}
- *
{@value DeviceType#TYPE_2232H}
- *
{@value DeviceType#TYPE_4232H}
- *
{@value DeviceType#TYPE_AM}
- *
{@value DeviceType#TYPE_BM}
- *
- *
- *
- * @author mike wakerly (opensource@hoho.com)
- * @see USB Serial
- * for Android project page
- * @see FTDI Homepage
- * @see libftdi
- */
-public class FtdiSerialDriver extends CommonUsbSerialDriver {
-
- public static final int USB_TYPE_STANDARD = 0x00 << 5;
- public static final int USB_TYPE_CLASS = 0x01 << 5;
- public static final int USB_TYPE_VENDOR = 0x02 << 5;
- public static final int USB_TYPE_RESERVED = 0x03 << 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) {
- Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
- 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 getSupportedDevices() {
- final Map supportedDevices = new LinkedHashMap();
- supportedDevices.put(Integer.valueOf(UsbId.VENDOR_FTDI),
- new int[] {
- UsbId.FTDI_FT232R,
- UsbId.FTDI_FT231X,
- });
- return supportedDevices;
- }
-
-}
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/ProlificSerialDriver.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/ProlificSerialDriver.java
deleted file mode 100644
index 611498a..0000000
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/ProlificSerialDriver.java
+++ /dev/null
@@ -1,522 +0,0 @@
-/* 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
- *
- * Based on the pyprolific driver written
- * by Emmanuel Blot
- * 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 getSupportedDevices() {
- final Map supportedDevices = new LinkedHashMap();
- supportedDevices.put(Integer.valueOf(UsbId.VENDOR_PROLIFIC),
- new int[] { UsbId.PROLIFIC_PL2303, });
- return supportedDevices;
- }
-}
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java
deleted file mode 100644
index 420a8c2..0000000
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/* 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 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.
- *
- *
- * 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.
- *
- *
- * 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 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 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 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 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 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}.
- *
- *
- * 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 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 findAllDevices(final UsbManager usbManager) {
- final List result = new ArrayList();
-
- // For each UsbDevice, call probe() for each prober.
- for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
- result.addAll(probeSingleDevice(usbManager, usbDevice));
- }
- return result;
- }
-
- /**
- * Special method for testing a specific device for driver support,
- * returning any compatible driver(s).
- *
- *
- * 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 probeSingleDevice(final UsbManager usbManager,
- UsbDevice usbDevice) {
- final List result = new ArrayList();
- for (final UsbSerialProber prober : values()) {
- final List 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 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 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;
- }
-
-}
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..0ffc737
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,15 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.9.+'
+ }
+}
+
+allprojects {
+ repositories {
+ mavenCentral()
+ }
+}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..5de946b
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..454abb1
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include 'usbSerialForAndroid', 'usbSerialExamples'
diff --git a/usbSerialExamples/build.gradle b/usbSerialExamples/build.gradle
new file mode 100644
index 0000000..d23c5f5
--- /dev/null
+++ b/usbSerialExamples/build.gradle
@@ -0,0 +1,24 @@
+apply plugin: 'android'
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.3"
+
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 19
+
+ testPackageName "com.hoho.android.usbserial.examples"
+ testInstrumentationRunner "android.test.InstrumentationTestRunner"
+ }
+
+ buildTypes {
+ release {
+ runProguard true
+ }
+ }
+}
+
+dependencies {
+ compile project(':usbSerialForAndroid')
+}
diff --git a/UsbSerialExamples/AndroidManifest.xml b/usbSerialExamples/src/main/AndroidManifest.xml
similarity index 100%
rename from UsbSerialExamples/AndroidManifest.xml
rename to usbSerialExamples/src/main/AndroidManifest.xml
diff --git a/UsbSerialExamples/src/com/hoho/android/usbserial/examples/DeviceListActivity.java b/usbSerialExamples/src/main/java/src/com/hoho/android/usbserial/examples/DeviceListActivity.java
similarity index 69%
rename from UsbSerialExamples/src/com/hoho/android/usbserial/examples/DeviceListActivity.java
rename to usbSerialExamples/src/main/java/src/com/hoho/android/usbserial/examples/DeviceListActivity.java
index fd2429a..c7804e0 100644
--- a/UsbSerialExamples/src/com/hoho/android/usbserial/examples/DeviceListActivity.java
+++ b/usbSerialExamples/src/main/java/src/com/hoho/android/usbserial/examples/DeviceListActivity.java
@@ -1,4 +1,5 @@
-/* Copyright 2011 Google Inc.
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
- * Project home page: http://code.google.com/p/usb-serial-for-android/
+ * Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.examples;
@@ -41,6 +42,7 @@ import android.widget.TextView;
import android.widget.TwoLineListItem;
import com.hoho.android.usbserial.driver.UsbSerialDriver;
+import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
import com.hoho.android.usbserial.util.HexDump;
@@ -80,19 +82,8 @@ public class DeviceListActivity extends Activity {
};
- /** Simple container for a UsbDevice and its driver. */
- private static class DeviceEntry {
- public UsbDevice device;
- public UsbSerialDriver driver;
-
- DeviceEntry(UsbDevice device, UsbSerialDriver driver) {
- this.device = device;
- this.driver = driver;
- }
- }
-
- private List mEntries = new ArrayList();
- private ArrayAdapter mAdapter;
+ private List mEntries = new ArrayList();
+ private ArrayAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -104,7 +95,8 @@ public class DeviceListActivity extends Activity {
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mProgressBarTitle = (TextView) findViewById(R.id.progressBarTitle);
- mAdapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_2, mEntries) {
+ mAdapter = new ArrayAdapter(this,
+ android.R.layout.simple_expandable_list_item_2, mEntries) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final TwoLineListItem row;
@@ -116,14 +108,16 @@ public class DeviceListActivity extends Activity {
row = (TwoLineListItem) convertView;
}
- final DeviceEntry entry = mEntries.get(position);
+ final UsbSerialPort port = mEntries.get(position);
+ final UsbSerialDriver driver = port.getDriver();
+ final UsbDevice device = driver.getDevice();
+
final String title = String.format("Vendor %s Product %s",
- HexDump.toHexString((short) entry.device.getVendorId()),
- HexDump.toHexString((short) entry.device.getProductId()));
+ HexDump.toHexString((short) device.getVendorId()),
+ HexDump.toHexString((short) device.getProductId()));
row.getText1().setText(title);
- final String subtitle = entry.driver != null ?
- entry.driver.getClass().getSimpleName() : "No Driver";
+ final String subtitle = driver.getClass().getSimpleName();
row.getText2().setText(subtitle);
return row;
@@ -141,14 +135,8 @@ public class DeviceListActivity extends Activity {
return;
}
- final DeviceEntry entry = mEntries.get(position);
- final UsbSerialDriver driver = entry.driver;
- if (driver == null) {
- Log.d(TAG, "No driver.");
- return;
- }
-
- showConsoleActivity(driver);
+ final UsbSerialPort port = mEntries.get(position);
+ showConsoleActivity(port);
}
});
}
@@ -168,31 +156,28 @@ public class DeviceListActivity extends Activity {
private void refreshDeviceList() {
showProgressBar();
- new AsyncTask>() {
+ new AsyncTask>() {
@Override
- protected List doInBackground(Void... params) {
+ protected List doInBackground(Void... params) {
Log.d(TAG, "Refreshing device list ...");
SystemClock.sleep(1000);
- final List result = new ArrayList();
- for (final UsbDevice device : mUsbManager.getDeviceList().values()) {
- final List drivers =
- UsbSerialProber.probeSingleDevice(mUsbManager, device);
- Log.d(TAG, "Found usb device: " + device);
- if (drivers.isEmpty()) {
- Log.d(TAG, " - No UsbSerialDriver available.");
- result.add(new DeviceEntry(device, null));
- } else {
- for (UsbSerialDriver driver : drivers) {
- Log.d(TAG, " + " + driver);
- result.add(new DeviceEntry(device, driver));
- }
- }
+
+ final List drivers =
+ UsbSerialProber.getDefaultProber().findAllDrivers(mUsbManager);
+
+ final List result = new ArrayList();
+ for (final UsbSerialDriver driver : drivers) {
+ final List ports = driver.getPorts();
+ Log.d(TAG, String.format("+ %s: %s port%s",
+ driver, Integer.valueOf(ports.size()), ports.size() == 1 ? "" : "s"));
+ result.addAll(ports);
}
+
return result;
}
@Override
- protected void onPostExecute(List result) {
+ protected void onPostExecute(List result) {
mEntries.clear();
mEntries.addAll(result);
mAdapter.notifyDataSetChanged();
@@ -214,8 +199,8 @@ public class DeviceListActivity extends Activity {
mProgressBar.setVisibility(View.INVISIBLE);
}
- private void showConsoleActivity(UsbSerialDriver driver) {
- SerialConsoleActivity.show(this, driver);
+ private void showConsoleActivity(UsbSerialPort port) {
+ SerialConsoleActivity.show(this, port);
}
}
diff --git a/UsbSerialExamples/src/com/hoho/android/usbserial/examples/SerialConsoleActivity.java b/usbSerialExamples/src/main/java/src/com/hoho/android/usbserial/examples/SerialConsoleActivity.java
similarity index 77%
rename from UsbSerialExamples/src/com/hoho/android/usbserial/examples/SerialConsoleActivity.java
rename to usbSerialExamples/src/main/java/src/com/hoho/android/usbserial/examples/SerialConsoleActivity.java
index 7ccb406..d30ff51 100644
--- a/UsbSerialExamples/src/com/hoho/android/usbserial/examples/SerialConsoleActivity.java
+++ b/usbSerialExamples/src/main/java/src/com/hoho/android/usbserial/examples/SerialConsoleActivity.java
@@ -1,4 +1,5 @@
-/* Copyright 2011 Google Inc.
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
- * Project home page: http://code.google.com/p/usb-serial-for-android/
+ * Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.examples;
@@ -23,12 +24,14 @@ package com.hoho.android.usbserial.examples;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.ScrollView;
import android.widget.TextView;
-import com.hoho.android.usbserial.driver.UsbSerialDriver;
+import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.util.HexDump;
import com.hoho.android.usbserial.util.SerialInputOutputManager;
@@ -37,7 +40,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
- * Monitors a single {@link UsbSerialDriver} instance, showing all data
+ * Monitors a single {@link UsbSerialPort} instance, showing all data
* received.
*
* @author mike wakerly (opensource@hoho.com)
@@ -48,7 +51,7 @@ public class SerialConsoleActivity extends Activity {
/**
* Driver instance, passed in statically via
- * {@link #show(Context, UsbSerialDriver)}.
+ * {@link #show(Context, UsbSerialPort)}.
*
*
* This is a devious hack; it'd be cleaner to re-create the driver using
@@ -56,7 +59,7 @@ public class SerialConsoleActivity extends Activity {
* can get away with it because both activities will run in the same
* process, and this is a simple demo.
*/
- private static UsbSerialDriver sDriver = null;
+ private static UsbSerialPort sPort = null;
private TextView mTitleTextView;
private TextView mDumpTextView;
@@ -98,13 +101,13 @@ public class SerialConsoleActivity extends Activity {
protected void onPause() {
super.onPause();
stopIoManager();
- if (sDriver != null) {
+ if (sPort != null) {
try {
- sDriver.close();
+ sPort.close();
} catch (IOException e) {
// Ignore.
}
- sDriver = null;
+ sPort = null;
}
finish();
}
@@ -112,25 +115,33 @@ public class SerialConsoleActivity extends Activity {
@Override
protected void onResume() {
super.onResume();
- Log.d(TAG, "Resumed, sDriver=" + sDriver);
- if (sDriver == null) {
+ Log.d(TAG, "Resumed, port=" + sPort);
+ if (sPort == null) {
mTitleTextView.setText("No serial device.");
} else {
+ final UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
+
+ UsbDeviceConnection connection = usbManager.openDevice(sPort.getDriver().getDevice());
+ if (connection == null) {
+ mTitleTextView.setText("Opening device failed");
+ return;
+ }
+
try {
- sDriver.open();
- sDriver.setParameters(115200, 8, UsbSerialDriver.STOPBITS_1, UsbSerialDriver.PARITY_NONE);
+ sPort.open(connection);
+ sPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
} catch (IOException e) {
Log.e(TAG, "Error setting up device: " + e.getMessage(), e);
mTitleTextView.setText("Error opening device: " + e.getMessage());
try {
- sDriver.close();
+ sPort.close();
} catch (IOException e2) {
// Ignore.
}
- sDriver = null;
+ sPort = null;
return;
}
- mTitleTextView.setText("Serial device: " + sDriver.getClass().getSimpleName());
+ mTitleTextView.setText("Serial device: " + sPort.getClass().getSimpleName());
}
onDeviceStateChange();
}
@@ -144,9 +155,9 @@ public class SerialConsoleActivity extends Activity {
}
private void startIoManager() {
- if (sDriver != null) {
+ if (sPort != null) {
Log.i(TAG, "Starting io manager ..");
- mSerialIoManager = new SerialInputOutputManager(sDriver, mListener);
+ mSerialIoManager = new SerialInputOutputManager(sPort, mListener);
mExecutor.submit(mSerialIoManager);
}
}
@@ -169,8 +180,8 @@ public class SerialConsoleActivity extends Activity {
* @param context
* @param driver
*/
- static void show(Context context, UsbSerialDriver driver) {
- sDriver = driver;
+ static void show(Context context, UsbSerialPort port) {
+ sPort = port;
final Intent intent = new Intent(context, SerialConsoleActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
context.startActivity(intent);
diff --git a/UsbSerialExamples/res/drawable-hdpi/ic_launcher.png b/usbSerialExamples/src/main/res/drawable-hdpi/ic_launcher.png
similarity index 100%
rename from UsbSerialExamples/res/drawable-hdpi/ic_launcher.png
rename to usbSerialExamples/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/UsbSerialExamples/res/drawable-ldpi/ic_launcher.png b/usbSerialExamples/src/main/res/drawable-ldpi/ic_launcher.png
similarity index 100%
rename from UsbSerialExamples/res/drawable-ldpi/ic_launcher.png
rename to usbSerialExamples/src/main/res/drawable-ldpi/ic_launcher.png
diff --git a/UsbSerialExamples/res/drawable-mdpi/ic_launcher.png b/usbSerialExamples/src/main/res/drawable-mdpi/ic_launcher.png
similarity index 100%
rename from UsbSerialExamples/res/drawable-mdpi/ic_launcher.png
rename to usbSerialExamples/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/UsbSerialExamples/res/layout/main.xml b/usbSerialExamples/src/main/res/layout/main.xml
similarity index 100%
rename from UsbSerialExamples/res/layout/main.xml
rename to usbSerialExamples/src/main/res/layout/main.xml
diff --git a/UsbSerialExamples/res/layout/serial_console.xml b/usbSerialExamples/src/main/res/layout/serial_console.xml
similarity index 100%
rename from UsbSerialExamples/res/layout/serial_console.xml
rename to usbSerialExamples/src/main/res/layout/serial_console.xml
diff --git a/UsbSerialExamples/res/values/strings.xml b/usbSerialExamples/src/main/res/values/strings.xml
similarity index 100%
rename from UsbSerialExamples/res/values/strings.xml
rename to usbSerialExamples/src/main/res/values/strings.xml
diff --git a/UsbSerialExamples/res/xml/device_filter.xml b/usbSerialExamples/src/main/res/xml/device_filter.xml
similarity index 100%
rename from UsbSerialExamples/res/xml/device_filter.xml
rename to usbSerialExamples/src/main/res/xml/device_filter.xml
diff --git a/usbSerialForAndroid/build.gradle b/usbSerialForAndroid/build.gradle
new file mode 100644
index 0000000..ed38c0f
--- /dev/null
+++ b/usbSerialForAndroid/build.gradle
@@ -0,0 +1,18 @@
+apply plugin: 'android-library'
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.1"
+
+ defaultConfig {
+ minSdkVersion 12
+ targetSdkVersion 19
+ }
+
+ buildTypes {
+ release {
+ runProguard false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+ }
+ }
+}
diff --git a/UsbSerialLibrary/AndroidManifest.xml b/usbSerialForAndroid/src/main/AndroidManifest.xml
similarity index 100%
rename from UsbSerialLibrary/AndroidManifest.xml
rename to usbSerialForAndroid/src/main/AndroidManifest.xml
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/BuildInfo.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/BuildInfo.java
similarity index 100%
rename from UsbSerialLibrary/src/com/hoho/android/usbserial/BuildInfo.java
rename to usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/BuildInfo.java
diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java
new file mode 100644
index 0000000..dc26ceb
--- /dev/null
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java
@@ -0,0 +1,353 @@
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
+ *
+ * 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: https://github.com/mik3y/usb-serial-for-android
+ */
+
+package com.hoho.android.usbserial.driver;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbRequest;
+import android.os.Build;
+import android.util.Log;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * USB CDC/ACM serial driver implementation.
+ *
+ * @author mike wakerly (opensource@hoho.com)
+ * @see Universal
+ * Serial Bus Class Definitions for Communication Devices, v1.1
+ */
+public class CdcAcmSerialDriver implements UsbSerialDriver {
+
+ private final String TAG = CdcAcmSerialDriver.class.getSimpleName();
+
+ private final UsbDevice mDevice;
+ private final UsbSerialPort mPort;
+
+ public CdcAcmSerialDriver(UsbDevice device) {
+ mDevice = device;
+ mPort = new CdcAcmSerialPort(device, 0);
+ }
+
+ @Override
+ public UsbDevice getDevice() {
+ return mDevice;
+ }
+
+ @Override
+ public List getPorts() {
+ return Collections.singletonList(mPort);
+ }
+
+ class CdcAcmSerialPort extends CommonUsbSerialPort {
+
+ private final boolean mEnableAsyncReads;
+ 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 CdcAcmSerialPort(UsbDevice device, int portNumber) {
+ super(device, portNumber);
+ mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
+ }
+
+ @Override
+ public UsbSerialDriver getDriver() {
+ return CdcAcmSerialDriver.this;
+ }
+
+ @Override
+ public void open(UsbDeviceConnection connection) throws IOException {
+ if (mConnection != null) {
+ throw new IOException("Already open");
+ }
+
+ mConnection = connection;
+ boolean opened = false;
+ try {
+ Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());
+ 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());
+ if (mEnableAsyncReads) {
+ Log.d(TAG, "Async reads enabled");
+ } else {
+ Log.d(TAG, "Async reads disabled.");
+ }
+ opened = true;
+ } finally {
+ if (!opened) {
+ mConnection = null;
+ }
+ }
+ }
+
+ 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 {
+ if (mConnection == null) {
+ throw new IOException("Already closed");
+ }
+ mConnection.close();
+ mConnection = null;
+ }
+
+ @Override
+ public int read(byte[] dest, int timeoutMillis) throws IOException {
+ if (mEnableAsyncReads) {
+ final UsbRequest request = new UsbRequest();
+ try {
+ request.initialize(mConnection, mReadEndpoint);
+ final ByteBuffer buf = ByteBuffer.wrap(dest);
+ if (!request.queue(buf, dest.length)) {
+ throw new IOException("Error queueing request.");
+ }
+
+ final UsbRequest response = mConnection.requestWait();
+ if (response == null) {
+ throw new IOException("Null response");
+ }
+
+ final int nread = buf.position();
+ if (nread > 0) {
+ //Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
+ return nread;
+ } else {
+ return 0;
+ }
+ } finally {
+ request.close();
+ }
+ }
+
+ 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
+ if (timeoutMillis == Integer.MAX_VALUE) {
+ // Hack: Special case "~infinite timeout" as an error.
+ return -1;
+ }
+ 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 getSupportedDevices() {
+ final Map supportedDevices = new LinkedHashMap();
+ 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,
+ });
+ return supportedDevices;
+ }
+
+}
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CommonUsbSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java
similarity index 82%
rename from UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CommonUsbSerialDriver.java
rename to usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java
index 7c61704..3a83913 100644
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CommonUsbSerialDriver.java
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java
@@ -1,4 +1,5 @@
-/* Copyright 2013 Google Inc.
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
- * Project home page: http://code.google.com/p/usb-serial-for-android/
+ * Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
@@ -30,13 +31,16 @@ import java.io.IOException;
*
* @author mike wakerly (opensource@hoho.com)
*/
-abstract class CommonUsbSerialDriver implements UsbSerialDriver {
+abstract class CommonUsbSerialPort implements UsbSerialPort {
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 int mPortNumber;
+
+ // non-null when open()
+ protected UsbDeviceConnection mConnection = null;
protected final Object mReadBufferLock = new Object();
protected final Object mWriteBufferLock = new Object();
@@ -47,13 +51,20 @@ abstract class CommonUsbSerialDriver implements UsbSerialDriver {
/** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
protected byte[] mWriteBuffer;
- public CommonUsbSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
+ public CommonUsbSerialPort(UsbDevice device, int portNumber) {
mDevice = device;
- mConnection = connection;
+ mPortNumber = portNumber;
mReadBuffer = new byte[DEFAULT_READ_BUFFER_SIZE];
mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
}
+
+ @Override
+ public String toString() {
+ return String.format("<%s device_name=%s device_id=%s port_number=%s>",
+ getClass().getSimpleName(), mDevice.getDeviceName(),
+ mDevice.getDeviceId(), mPortNumber);
+ }
/**
* Returns the currently-bound USB device.
@@ -64,6 +75,11 @@ abstract class CommonUsbSerialDriver implements UsbSerialDriver {
return mDevice;
}
+ @Override
+ public int getPortNumber() {
+ return mPortNumber;
+ }
+
/**
* 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.
@@ -95,7 +111,7 @@ abstract class CommonUsbSerialDriver implements UsbSerialDriver {
}
@Override
- public abstract void open() throws IOException;
+ public abstract void open(UsbDeviceConnection connection) throws IOException;
@Override
public abstract void close() throws IOException;
diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Cp21xxSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Cp21xxSerialDriver.java
new file mode 100644
index 0000000..e9c812c
--- /dev/null
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Cp21xxSerialDriver.java
@@ -0,0 +1,360 @@
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
+ *
+ * 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: https://github.com/mik3y/usb-serial-for-android
+ */
+
+package com.hoho.android.usbserial.driver;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbInterface;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Cp21xxSerialDriver implements UsbSerialDriver {
+
+ private static final String TAG = Cp21xxSerialDriver.class.getSimpleName();
+
+ private final UsbDevice mDevice;
+ private final UsbSerialPort mPort;
+
+ public Cp21xxSerialDriver(UsbDevice device) {
+ mDevice = device;
+ mPort = new Cp21xxSerialPort(mDevice, 0);
+ }
+
+ @Override
+ public UsbDevice getDevice() {
+ return mDevice;
+ }
+
+ @Override
+ public List getPorts() {
+ return Collections.singletonList(mPort);
+ }
+
+ public class Cp21xxSerialPort extends CommonUsbSerialPort {
+
+ 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 Cp21xxSerialPort(UsbDevice device, int portNumber) {
+ super(device, portNumber);
+ }
+
+ @Override
+ public UsbSerialDriver getDriver() {
+ return Cp21xxSerialDriver.this;
+ }
+
+ 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(UsbDeviceConnection connection) throws IOException {
+ if (mConnection != null) {
+ throw new IOException("Already opened.");
+ }
+
+ mConnection = connection;
+ 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) {
+ try {
+ close();
+ } catch (IOException e) {
+ // Ignore IOExceptions during close()
+ }
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (mConnection == null) {
+ throw new IOException("Already closed");
+ }
+ try {
+ setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_DISABLE);
+ mConnection.close();
+ } finally {
+ mConnection = null;
+ }
+ }
+
+ @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 void setRTS(boolean value) throws IOException {
+ }
+
+ @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;
+ }
+
+ }
+
+ public static Map getSupportedDevices() {
+ final Map supportedDevices = new LinkedHashMap();
+ supportedDevices.put(Integer.valueOf(UsbId.VENDOR_SILABS),
+ new int[] {
+ UsbId.SILABS_CP2102,
+ UsbId.SILABS_CP2105,
+ UsbId.SILABS_CP2108,
+ UsbId.SILABS_CP2110
+ });
+ return supportedDevices;
+ }
+
+}
diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java
new file mode 100644
index 0000000..3950ddd
--- /dev/null
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java
@@ -0,0 +1,581 @@
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
+ *
+ * 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: https://github.com/mik3y/usb-serial-for-android
+ */
+
+package com.hoho.android.usbserial.driver;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbRequest;
+import android.util.Log;
+
+import com.hoho.android.usbserial.util.HexDump;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A {@link CommonUsbSerialPort} implementation for a variety of FTDI devices
+ *
+ * This driver is based on libftdi, and is
+ * copyright and subject to the following terms:
+ *
+ *
+ * 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
+ *
+ *
+ *
+ *
+ * Some FTDI devices have not been tested; see later listing of supported and
+ * unsupported devices. Devices listed as "supported" support the following
+ * features:
+ *
+ *
Read and write of serial data (see
+ * {@link CommonUsbSerialPort#read(byte[], int)} and
+ * {@link CommonUsbSerialPort#write(byte[], int)}.
+ *
Setting serial line parameters (see
+ * {@link CommonUsbSerialPort#setParameters(int, int, int, int)}.
+ *
+ *
+ *
+ * Supported and tested devices:
+ *
+ *
{@value DeviceType#TYPE_R}
+ *
+ *
+ *
+ * Unsupported but possibly working devices (please contact the author with
+ * feedback or patches):
+ *
+ *
{@value DeviceType#TYPE_2232C}
+ *
{@value DeviceType#TYPE_2232H}
+ *
{@value DeviceType#TYPE_4232H}
+ *
{@value DeviceType#TYPE_AM}
+ *
{@value DeviceType#TYPE_BM}
+ *
+ *
+ *
+ * @author mike wakerly (opensource@hoho.com)
+ * @see USB Serial
+ * for Android project page
+ * @see FTDI Homepage
+ * @see libftdi
+ */
+public class FtdiSerialDriver implements UsbSerialDriver {
+
+ private final UsbDevice mDevice;
+ private final UsbSerialPort mPort;
+
+ /**
+ * FTDI chip types.
+ */
+ private static enum DeviceType {
+ TYPE_BM, TYPE_AM, TYPE_2232C, TYPE_R, TYPE_2232H, TYPE_4232H;
+ }
+
+ public FtdiSerialDriver(UsbDevice device) {
+ mDevice = device;
+ mPort = new FtdiSerialPort(mDevice, 0);
+ }
+ @Override
+ public UsbDevice getDevice() {
+ return mDevice;
+ }
+
+ @Override
+ public List getPorts() {
+ return Collections.singletonList(mPort);
+ }
+
+ private class FtdiSerialPort extends CommonUsbSerialPort {
+
+ 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;
+
+ 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;
+
+ public FtdiSerialPort(UsbDevice device, int portNumber) {
+ super(device, portNumber);
+ }
+
+ @Override
+ public UsbSerialDriver getDriver() {
+ return FtdiSerialDriver.this;
+ }
+
+ /**
+ * 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);
+ }
+
+ 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(UsbDeviceConnection connection) throws IOException {
+ if (mConnection != null) {
+ throw new IOException("Already open");
+ }
+ mConnection = connection;
+
+ boolean opened = false;
+ try {
+ for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
+ if (connection.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();
+ mConnection = null;
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (mConnection == null) {
+ throw new IOException("Already closed");
+ }
+ try {
+ mConnection.close();
+ } finally {
+ mConnection = null;
+ }
+ }
+
+ @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) {
+ Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
+ 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 getSupportedDevices() {
+ final Map supportedDevices = new LinkedHashMap();
+ supportedDevices.put(Integer.valueOf(UsbId.VENDOR_FTDI),
+ new int[] {
+ UsbId.FTDI_FT232R,
+ UsbId.FTDI_FT231X,
+ });
+ return supportedDevices;
+ }
+
+}
diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProbeTable.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProbeTable.java
new file mode 100644
index 0000000..db08019
--- /dev/null
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProbeTable.java
@@ -0,0 +1,108 @@
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
+ *
+ * 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: https://github.com/mik3y/usb-serial-for-android
+ */
+
+package com.hoho.android.usbserial.driver;
+
+import android.util.Pair;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Maps (vendor id, product id) pairs to the corresponding serial driver.
+ *
+ * @author mike wakerly (opensource@hoho.com)
+ */
+public class ProbeTable {
+
+ private final Map, Class extends UsbSerialDriver>> mProbeTable =
+ new LinkedHashMap, Class extends UsbSerialDriver>>();
+
+ /**
+ * Adds or updates a (vendor, product) pair in the table.
+ *
+ * @param vendorId the USB vendor id
+ * @param productId the USB product id
+ * @param driverClass the driver class responsible for this pair
+ * @return {@code this}, for chaining
+ */
+ public ProbeTable addProduct(int vendorId, int productId,
+ Class extends UsbSerialDriver> driverClass) {
+ mProbeTable.put(Pair.create(vendorId, productId), driverClass);
+ return this;
+ }
+
+ /**
+ * Internal method to add all supported products from
+ * {@code getSupportedProducts} static method.
+ *
+ * @param driverClass
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ ProbeTable addDriver(Class extends UsbSerialDriver> driverClass) {
+ final Method method;
+
+ try {
+ method = driverClass.getMethod("getSupportedDevices");
+ } catch (SecurityException e) {
+ throw new RuntimeException(e);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+
+ final Map devices;
+ try {
+ devices = (Map) method.invoke(null);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+
+ for (Map.Entry entry : devices.entrySet()) {
+ final int vendorId = entry.getKey().intValue();
+ for (int productId : entry.getValue()) {
+ addProduct(vendorId, productId, driverClass);
+ }
+ }
+
+ return this;
+ }
+
+ /**
+ * Returns the driver for the given (vendor, product) pair, or {@code null}
+ * if no match.
+ *
+ * @param vendorId the USB vendor id
+ * @param productId the USB product id
+ * @return the driver class matching this pair, or {@code null}
+ */
+ public Class extends UsbSerialDriver> findDriver(int vendorId, int productId) {
+ final Pair pair = Pair.create(vendorId, productId);
+ return mProbeTable.get(pair);
+ }
+
+}
diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java
new file mode 100644
index 0000000..249cf4f
--- /dev/null
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java
@@ -0,0 +1,556 @@
+/* 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: https://github.com/mik3y/usb-serial-for-android
+ */
+
+/*
+ * Ported to usb-serial-for-android
+ * by Felix Hädicke
+ *
+ * Based on the pyprolific driver written
+ * by Emmanuel Blot
+ * 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.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ProlificSerialDriver implements UsbSerialDriver {
+
+ private final String TAG = ProlificSerialDriver.class.getSimpleName();
+
+ private final UsbDevice mDevice;
+ private final UsbSerialPort mPort;
+
+ public ProlificSerialDriver(UsbDevice device) {
+ mDevice = device;
+ mPort = new ProlificSerialPort(mDevice, 0);
+ }
+
+ @Override
+ public List getPorts() {
+ return Collections.singletonList(mPort);
+ }
+
+ @Override
+ public UsbDevice getDevice() {
+ return mDevice;
+ }
+
+ class ProlificSerialPort extends CommonUsbSerialPort {
+
+ 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;
+
+
+ public ProlificSerialPort(UsbDevice device, int portNumber) {
+ super(device, portNumber);
+ }
+
+ @Override
+ public UsbSerialDriver getDriver() {
+ return ProlificSerialDriver.this;
+ }
+
+ 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 void resetDevice() throws IOException {
+ purgeHwBuffers(true, true);
+ }
+
+ 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 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);
+ }
+
+ @Override
+ public void open(UsbDeviceConnection connection) throws IOException {
+ if (mConnection != null) {
+ throw new IOException("Already open");
+ }
+
+ UsbInterface usbInterface = mDevice.getInterface(0);
+
+ if (!connection.claimInterface(usbInterface, true)) {
+ throw new IOException("Error claiming Prolific interface 0");
+ }
+
+ mConnection = connection;
+ boolean opened = 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();
+ opened = true;
+ } finally {
+ if (!opened) {
+ mConnection = null;
+ connection.releaseInterface(usbInterface);
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (mConnection == null) {
+ throw new IOException("Already closed");
+ }
+ 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 {
+ try {
+ mConnection.releaseInterface(mDevice.getInterface(0));
+ } finally {
+ mConnection = null;
+ }
+ }
+ }
+
+ @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_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 purgeReadBuffers || purgeWriteBuffers;
+ }
+ }
+
+ public static Map getSupportedDevices() {
+ final Map supportedDevices = new LinkedHashMap();
+ supportedDevices.put(Integer.valueOf(UsbId.VENDOR_PROLIFIC),
+ new int[] { UsbId.PROLIFIC_PL2303, });
+ return supportedDevices;
+ }
+}
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbId.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbId.java
similarity index 84%
rename from UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbId.java
rename to usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbId.java
index 2b228aa..ae92a41 100644
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbId.java
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbId.java
@@ -1,4 +1,5 @@
-/* Copyright 2012 Google Inc.
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,8 +16,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
- * Project home page: http://code.google.com/p/usb-serial-for-android/
+ * Project home page: https://github.com/mik3y/usb-serial-for-android
*/
+
package com.hoho.android.usbserial.driver;
/**
@@ -52,9 +54,12 @@ public final class UsbId {
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_SILABS = 0x10c4;
+ public static final int SILABS_CP2102 = 0xea60;
+ public static final int SILABS_CP2105 = 0xea70;
+ public static final int SILABS_CP2108 = 0xea71;
+ public static final int SILABS_CP2110 = 0xea80;
public static final int VENDOR_PROLIFIC = 0x067b;
public static final int PROLIFIC_PL2303 = 0x2303;
diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialDriver.java
new file mode 100644
index 0000000..9130d97
--- /dev/null
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialDriver.java
@@ -0,0 +1,48 @@
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
+ *
+ * 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: https://github.com/mik3y/usb-serial-for-android
+ */
+
+package com.hoho.android.usbserial.driver;
+
+import android.hardware.usb.UsbDevice;
+
+import java.util.List;
+
+/**
+ *
+ * @author mike wakerly (opensource@hoho.com)
+ */
+public interface UsbSerialDriver {
+
+ /**
+ * Returns the raw {@link UsbDevice} backing this port.
+ *
+ * @return the device
+ */
+ public UsbDevice getDevice();
+
+ /**
+ * Returns all available ports for this device. This list must have at least
+ * one entry.
+ *
+ * @return the ports
+ */
+ public List getPorts();
+}
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialPort.java
similarity index 88%
rename from UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialDriver.java
rename to usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialPort.java
index d70712d..d4fa4a0 100644
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialDriver.java
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialPort.java
@@ -1,4 +1,5 @@
-/* Copyright 2011 Google Inc.
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,19 +16,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
- * Project home page: http://code.google.com/p/usb-serial-for-android/
+ * Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.driver;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbManager;
+
import java.io.IOException;
/**
- * Driver interface for a USB serial device.
+ * Interface for a single serial port.
*
* @author mike wakerly (opensource@hoho.com)
*/
-public interface UsbSerialDriver {
+public interface UsbSerialPort {
/** 5 data bits. */
public static final int DATABITS_5 = 5;
@@ -80,18 +84,27 @@ public interface UsbSerialDriver {
/** 2 stop bits. */
public static final int STOPBITS_2 = 2;
+ public UsbSerialDriver getDriver();
+
/**
- * 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.
+ * Port number within driver.
*/
- public void open() throws IOException;
+ public int getPortNumber();
/**
- * Closes the serial device.
+ * Opens and initializes the port. Upon success, caller must ensure that
+ * {@link #close()} is eventually called.
*
- * @throws IOException on error closing the device.
+ * @param connection an open device connection, acquired with
+ * {@link UsbManager#openDevice(android.hardware.usb.UsbDevice)}
+ * @throws IOException on error opening or initializing the port.
+ */
+ public void open(UsbDeviceConnection connection) throws IOException;
+
+ /**
+ * Closes the port.
+ *
+ * @throws IOException on error closing the port.
*/
public void close() throws IOException;
diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialProber.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialProber.java
new file mode 100644
index 0000000..5fa935c
--- /dev/null
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialProber.java
@@ -0,0 +1,113 @@
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
+ *
+ * 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: https://github.com/mik3y/usb-serial-for-android
+ */
+
+package com.hoho.android.usbserial.driver;
+
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbManager;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author mike wakerly (opensource@hoho.com)
+ */
+public class UsbSerialProber {
+
+ private final ProbeTable mProbeTable;
+
+ public UsbSerialProber(ProbeTable probeTable) {
+ mProbeTable = probeTable;
+ }
+
+ public static UsbSerialProber getDefaultProber() {
+ return new UsbSerialProber(getDefaultProbeTable());
+ }
+
+ public static ProbeTable getDefaultProbeTable() {
+ final ProbeTable probeTable = new ProbeTable();
+ probeTable.addDriver(CdcAcmSerialDriver.class);
+ probeTable.addDriver(Cp21xxSerialDriver.class);
+ probeTable.addDriver(FtdiSerialDriver.class);
+ probeTable.addDriver(ProlificSerialDriver.class);
+ return probeTable;
+ }
+
+ /**
+ * Finds and builds all possible {@link UsbSerialDriver UsbSerialDrivers}
+ * from the currently-attached {@link UsbDevice} hierarchy. This method does
+ * not require permission from the Android USB system, since it does not
+ * open any of the devices.
+ *
+ * @param usbManager
+ * @return a list, possibly empty, of all compatible drivers
+ */
+ public List findAllDrivers(final UsbManager usbManager) {
+ final List result = new ArrayList();
+
+ for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
+ final UsbSerialDriver driver = probeDevice(usbDevice);
+ if (driver != null) {
+ result.add(driver);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Probes a single device for a compatible driver.
+ *
+ * @param usbDevice the usb device to probe
+ * @return a new {@link UsbSerialDriver} compatible with this device, or
+ * {@code null} if none available.
+ */
+ public UsbSerialDriver probeDevice(final UsbDevice usbDevice) {
+ final int vendorId = usbDevice.getVendorId();
+ final int productId = usbDevice.getProductId();
+
+ final Class extends UsbSerialDriver> driverClass =
+ mProbeTable.findDriver(vendorId, productId);
+ if (driverClass != null) {
+ final UsbSerialDriver driver;
+ try {
+ final Constructor extends UsbSerialDriver> ctor =
+ driverClass.getConstructor(UsbDevice.class);
+ driver = ctor.newInstance(usbDevice);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (InstantiationException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ return driver;
+ }
+ return null;
+ }
+
+}
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialRuntimeException.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialRuntimeException.java
similarity index 100%
rename from UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialRuntimeException.java
rename to usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialRuntimeException.java
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/util/HexDump.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/HexDump.java
similarity index 100%
rename from UsbSerialLibrary/src/com/hoho/android/usbserial/util/HexDump.java
rename to usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/HexDump.java
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/util/SerialInputOutputManager.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/SerialInputOutputManager.java
similarity index 91%
rename from UsbSerialLibrary/src/com/hoho/android/usbserial/util/SerialInputOutputManager.java
rename to usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/SerialInputOutputManager.java
index d0be45e..d85a592 100644
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/util/SerialInputOutputManager.java
+++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/SerialInputOutputManager.java
@@ -1,4 +1,5 @@
-/* Copyright 2011 Google Inc.
+/* Copyright 2011-2013 Google Inc.
+ * Copyright 2013 mike wakerly
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
- * Project home page: http://code.google.com/p/usb-serial-for-android/
+ * Project home page: https://github.com/mik3y/usb-serial-for-android
*/
package com.hoho.android.usbserial.util;
@@ -23,13 +24,13 @@ package com.hoho.android.usbserial.util;
import android.hardware.usb.UsbRequest;
import android.util.Log;
-import com.hoho.android.usbserial.driver.UsbSerialDriver;
+import com.hoho.android.usbserial.driver.UsbSerialPort;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
- * Utility class which services a {@link UsbSerialDriver} in its {@link #run()}
+ * Utility class which services a {@link UsbSerialPort} in its {@link #run()}
* method.
*
* @author mike wakerly (opensource@hoho.com)
@@ -42,7 +43,7 @@ public class SerialInputOutputManager implements Runnable {
private static final int READ_WAIT_MILLIS = 200;
private static final int BUFSIZ = 4096;
- private final UsbSerialDriver mDriver;
+ private final UsbSerialPort mDriver;
private final ByteBuffer mReadBuffer = ByteBuffer.allocate(BUFSIZ);
@@ -77,14 +78,14 @@ public class SerialInputOutputManager implements Runnable {
/**
* Creates a new instance with no listener.
*/
- public SerialInputOutputManager(UsbSerialDriver driver) {
+ public SerialInputOutputManager(UsbSerialPort driver) {
this(driver, null);
}
/**
* Creates a new instance with the provided listener.
*/
- public SerialInputOutputManager(UsbSerialDriver driver, Listener listener) {
+ public SerialInputOutputManager(UsbSerialPort driver, Listener listener) {
mDriver = driver;
mListener = listener;
}