Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ This is a driver library to allow your Microsoft Android app to communicate with
available on Android 3.1+.

No root access, ADK, or special kernel drivers are required; all drivers are implemented in
c#. You get a raw serial port with `Read()`, `Write()`, and other basic
C#. You get a raw serial port with `Read()`, `Write()`, and other basic
functions for use with your own protocols. The appropriate driver is picked based on the device's Vendor ID and Product ID.

This is a Xamarin C# port of Mike Wakerly's Java [usb-serial-for-android](https://github.com/mik3y/usb-serial-for-android) library. It followed that library very closely when it was ported. The main changes were to make the method names follow C# standard naming conventions. Some Java specific data types were replaced with .NET types and the reflection code is .NET specific. Code examples written for the Java version of the library should translate more or less faithfully to C#.
This is a C# port of Mike Wakerly's Java [usb-serial-for-android](https://github.com/mik3y/usb-serial-for-android) library. It followed that library very closely when it was ported. The main changes were to make the method names follow C# standard naming conventions. Some Java specific data types were replaced with .NET types and the reflection code is .NET specific. Code examples written for the Java version of the library should translate more or less faithfully to C#.

It also includes code derived from a portion of LusoVU's [XamarinUsbSerial](https://bitbucket.org/lusovu/xamarinusbserial) library. XamarinUsbSerial was a C# wrapper for the Java usb-serial-for-android. It used an older version of the usb-serial-for-android .jar file. Only the C# code was used, the Java library is not referenced.
It also includes code derived from a portion of LusoVU's [XamarinUsbSerial](https://bitbucket.org/lusovu/xamarinusbserial) library. XamarinUsbSerial was a C# wrapper for the Java usb-serial-for-android. It used an older version of the usb-serial-for-android .jar file. Only the C# code was used, the Java library is not referenced.

The default branch has been renamed from master to main. if you have a local clone, you can run the following commands to update the name of the default branch

Expand All @@ -21,6 +21,11 @@ git remote set-head origin -a
```
This library supports .NET 10 and Microsoft Android. Support for Xamarin Android and previous versions of .NET have been dropped. Sample application has been replaced with a new app demo. If you need the old demo or want to support older versions of .NET, please use [verson 1.1.1](https://github.com/anotherlab/UsbSerialForAndroid/releases/tag/v1.1.1).

## Breaking changes
I'm cleaning up the code in order to publish this as a nuget package. Someone created a nuget package based on a two year old version of this code base and published to nuget under their own name (and without credit to the original authors). I changed the root namespace from `Hoho.Android.UsbSerial` to `Anotherlab.UsbSerialForAndroid` to make it easier to find on nuget.

The "Hoho" namespace came from original Java library package name, [usb-serial-for-android](https://github.com/mik3y/usb-serial-for-android), and while I based this code from that library, they are separate.

## Structure

This solution contains two projects and a slnx solution file.
Expand All @@ -34,7 +39,7 @@ The original demo and the .sln format solution file are deprecated and will be r
## Getting Started
**1.** Reference the library to your project

**2.** Copy the [device_filter.axml](https://github.com/anotherlab/UsbSerialForAndroid/blob/master/UsbSerialExampleApp/Resources/xml/device_filter.xml) from the example app to your Resources/xml folder. Make sure that the Build Action is set to AndroidResource
**2.** Copy the [device_filter.axml](https://github.com/anotherlab/UsbSerialForAndroid/blob/main/UsbSerialForAndroidDemo/Resources/xml/device_filter.xml) from the example app to your Resources/xml folder. Make sure that the Build Action is set to AndroidResource

**3.** Add the following attribute to the main activity to enable the USB Host
```C#
Expand All @@ -51,16 +56,12 @@ The original demo and the .sln format solution file are deprecated and will be r
[MetaData(UsbManager.ActionUsbDeviceAttached, Resource = "@xml/device_filter")]
```

**6.** Refer to [MainActivity.cs](https://github.com/anotherlab/UsbSerialForAndroid/blob/master/UsbSerialExampleApp/MainActivity.cs) in the example app to see how connect to a serial device and read data from it.
**6.** Refer to [MainActivity.cs](https://github.com/anotherlab/UsbSerialForAndroid/blob/main/UsbSerialForAndroidDemo/MainActivity.cs) in the example app to see how connect to a serial device and read data from it.

## Working with unrecognized devices
The UsbSerialForAndroid has been compiled with the Vendor ID/Product ID pairs for many common serial devices. If you have a device that is not defined by the library, but will work with one of the drivers, you can manually add the VID/PID pair. If you have a device that is not in the GetSupportedDevices() method for that driver, you can submit a pull request that adds the vendor and product IDs to that driver.

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.
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:

Expand Down Expand Up @@ -89,7 +90,7 @@ Of course, nothing requires you to use UsbSerialProber at all: you can instantia

## Additional information

This is a port of the usb-serial-for-android library and code examples written for it can be adapted to C# without much effort.
This is a port of the [usb-serial-for-android](https://github.com/mik3y/usb-serial-for-android) library and code examples written for it can be adapted to C# without much effort.

For common problems, see the
[Troubleshooting](https://github.com/mik3y/usb-serial-for-android/wiki/Troubleshooting)
Expand All @@ -98,14 +99,14 @@ wiki page for usb-serial-for-android library. For other help and discussion, ple

Pull Requests are welcome, but please include what hardware was used for testing. We do not have the hardware or the bandwidth to test the various chipsets supported by the library.

We will do our best to repond to reported issues. If you have a code fix or suggestion, we are only looking at changes submitted as pull requests.
We will do our best to respond to reported issues. If you have a code fix or suggestion, we are only looking at changes submitted as pull requests.

For more information about contributing or reporting an issue, please see [](https://github.com/anotherlab/UsbSerialForAndroid/blob/main/CONTRIBUTING.md) for more information for what we are looking for and how to get started.
For more information about contributing or reporting an issue, please see [CONTRIBUTING.md](https://github.com/anotherlab/UsbSerialForAndroid/blob/main/CONTRIBUTING.md) for more information for what we are looking for and how to get started.

## Author, License, and Copyright

This library is licensed under the MIT License. Please see [LICENSE.txt](https://github.com/anotherlab/UsbSerialForAndroid/blob/main/LICENSE.txt) for the complete license.

Copyright 2017, Tyler Technologies. All Rights Reserved. Portions of this library are based on the [usb-serial-for-android](https://github.com/mik3y/usb-serial-for-android) and [XamarinUsbSerial](https://bitbucket.org/lusovu/xamarinusbserial) libraries. Their rights remain intact.

The icon used for the demo app was derived from [Serial to USB by Bonegolem](https://thenounproject.com/browse/icons/term/serial-to-usb/) from <a href="https://thenounproject.com/browse/icons/term/serial-to-usb/" (CC BY 3.0)
The icon used for the demo app was derived from [Serial to USB by Bonegolem](https://thenounproject.com/browse/icons/term/serial-to-usb/) (CC BY 3.0)
23 changes: 11 additions & 12 deletions UsbSerialForAndroid/Extensions/AsyncExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@
using System.Threading.Tasks;
using Android.Hardware.Usb;

using Hoho.Android.UsbSerial.Driver;
using Anotherlab.UsbSerialForAndroid.Driver;

namespace Hoho.Android.UsbSerial.Extensions
namespace Anotherlab.UsbSerialForAndroid.Extensions;

public static partial class AsyncExtensions
{
public static partial class AsyncExtensions
public static Task<IList<IUsbSerialDriver>> FindAllDriversAsync(this UsbSerialProber prober, UsbManager manager)
{
public static Task<IList<IUsbSerialDriver>> FindAllDriversAsync(this UsbSerialProber prober, UsbManager manager)
{
var tcs = new TaskCompletionSource<IList<IUsbSerialDriver>>();
var tcs = new TaskCompletionSource<IList<IUsbSerialDriver>>();

Task.Run(() =>
{
tcs.TrySetResult(prober.FindAllDrivers(manager));
});
return tcs.Task;
}
Task.Run(() =>
{
tcs.TrySetResult(prober.FindAllDrivers(manager));
});
return tcs.Task;
}
}
71 changes: 35 additions & 36 deletions UsbSerialForAndroid/Extensions/BufferExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,48 @@
using Android.Runtime;
using Java.Nio;

namespace Hoho.Android.UsbSerial.Extensions
namespace Anotherlab.UsbSerialForAndroid.Extensions;

/// <summary>
/// Work around for faulty JNI wrapping in Xamarin library. Fixes a bug
/// where binding for Java.Nio.ByteBuffer.Get(byte[], int, int) allocates a new temporary
/// Java byte array on every call
/// See https://bugzilla.xamarin.com/show_bug.cgi?id=31260
/// and http://stackoverflow.com/questions/30268400/xamarin-implementation-of-bytebuffer-get-wrong
/// </summary>
public static class BufferExtensions
{
/// <summary>
/// Work around for faulty JNI wrapping in Xamarin library. Fixes a bug
/// where binding for Java.Nio.ByteBuffer.Get(byte[], int, int) allocates a new temporary
/// Java byte array on every call
/// See https://bugzilla.xamarin.com/show_bug.cgi?id=31260
/// and http://stackoverflow.com/questions/30268400/xamarin-implementation-of-bytebuffer-get-wrong
/// </summary>
public static class BufferExtensions
{
static IntPtr _byteBufferClassRef;
static IntPtr _byteBufferGetBii;
static IntPtr _byteBufferClassRef;
static IntPtr _byteBufferGetBii;

public static ByteBuffer Get(this ByteBuffer buffer, JavaArray<Java.Lang.Byte> dst, int dstOffset, int byteCount)
public static ByteBuffer Get(this ByteBuffer buffer, JavaArray<Java.Lang.Byte> dst, int dstOffset, int byteCount)
{
if (_byteBufferClassRef == IntPtr.Zero)
{
if (_byteBufferClassRef == IntPtr.Zero)
{
_byteBufferClassRef = JNIEnv.FindClass("java/nio/ByteBuffer");
}
if (_byteBufferGetBii == IntPtr.Zero)
{
_byteBufferGetBii = JNIEnv.GetMethodID(_byteBufferClassRef, "get", "([BII)Ljava/nio/ByteBuffer;");
}

return Java.Lang.Object.GetObject<ByteBuffer>(JNIEnv.CallObjectMethod(buffer.Handle, _byteBufferGetBii, new JValue[] {
new JValue(dst),
new JValue(dstOffset),
new JValue(byteCount)
}), JniHandleOwnership.TransferLocalRef);
_byteBufferClassRef = JNIEnv.FindClass("java/nio/ByteBuffer");
}

public static byte[] ToByteArray(this ByteBuffer buffer)
if (_byteBufferGetBii == IntPtr.Zero)
{
IntPtr classHandle = JNIEnv.FindClass("java/nio/ByteBuffer");
IntPtr methodId = JNIEnv.GetMethodID(classHandle, "array", "()[B");
IntPtr resultHandle = JNIEnv.CallObjectMethod(buffer.Handle, methodId);
_byteBufferGetBii = JNIEnv.GetMethodID(_byteBufferClassRef, "get", "([BII)Ljava/nio/ByteBuffer;");
}

byte[] result = JNIEnv.GetArray<byte>(resultHandle);
return Java.Lang.Object.GetObject<ByteBuffer>(JNIEnv.CallObjectMethod(buffer.Handle, _byteBufferGetBii, new JValue[] {
new JValue(dst),
new JValue(dstOffset),
new JValue(byteCount)
}), JniHandleOwnership.TransferLocalRef);
}

JNIEnv.DeleteLocalRef(resultHandle);
public static byte[] ToByteArray(this ByteBuffer buffer)
{
IntPtr classHandle = JNIEnv.FindClass("java/nio/ByteBuffer");
IntPtr methodId = JNIEnv.GetMethodID(classHandle, "array", "()[B");
IntPtr resultHandle = JNIEnv.CallObjectMethod(buffer.Handle, methodId);

return result;
}
byte[] result = JNIEnv.GetArray<byte>(resultHandle);

JNIEnv.DeleteLocalRef(resultHandle);

return result;
}
}
19 changes: 9 additions & 10 deletions UsbSerialForAndroid/Extensions/EventHandlerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@
using System;
using System.Threading;

namespace Hoho.Android.UsbSerial.Extensions
namespace Anotherlab.UsbSerialForAndroid.Extensions;

static class EventHandlerExtensions
{
static class EventHandlerExtensions
public static void Raise(this EventHandler handler, object sender, EventArgs e)
{
public static void Raise(this EventHandler handler, object sender, EventArgs e)
{
Volatile.Read(ref handler)?.Invoke(sender, e);
}
Volatile.Read(ref handler)?.Invoke(sender, e);
}

public static void Raise<T>(this EventHandler<T> handler, object sender, T e) where T : EventArgs
{
Volatile.Read(ref handler)?.Invoke(sender, e);
}
public static void Raise<T>(this EventHandler<T> handler, object sender, T e) where T : EventArgs
{
Volatile.Read(ref handler)?.Invoke(sender, e);
}
}
15 changes: 7 additions & 8 deletions UsbSerialForAndroid/Extensions/SerialDataReceivedArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@

using System;

namespace Hoho.Android.UsbSerial.Extensions
namespace Anotherlab.UsbSerialForAndroid.Extensions;

public class SerialDataReceivedArgs : EventArgs
{
public class SerialDataReceivedArgs : EventArgs
public SerialDataReceivedArgs(byte[] data)
{
public SerialDataReceivedArgs(byte[] data)
{
Data = data;
}

public byte[] Data { get; private set; }
Data = data;
}

public byte[] Data { get; private set; }
}
4 changes: 2 additions & 2 deletions UsbSerialForAndroid/Extensions/SerialInputOutputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
using Android.Hardware.Usb;
using Android.Util;
using System.Threading.Tasks;
using Hoho.Android.UsbSerial.Driver;
using Anotherlab.UsbSerialForAndroid.Driver;

namespace Hoho.Android.UsbSerial.Extensions
namespace Anotherlab.UsbSerialForAndroid.Extensions
{
public class SerialInputOutputManager : IDisposable
{
Expand Down
Loading