Started to update the library to API 3.22 RC
Change-Id: I8eaf3151b1d405799eb582564f0e1e8fbcb7744c Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -52,10 +52,42 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* AnalogInput potentiometer = ioio.openAnalogInput(40);
|
||||
* float value = potentiometer.read();
|
||||
* ...
|
||||
* potentiometer.close(); // pin 40 can now be used for something else.
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* An alternate usage allows reading periodically sampled data without missing
|
||||
* samples. The {@link #setBuffer(int)} method must first be called, for setting
|
||||
* up an internal buffer for queuing samples. Then, samples can be obtained by
|
||||
* calling {@link #readBuffered()} or {@link #getVoltageBuffered()}. These
|
||||
* methods will block until a sample is available. If this is undesirable, the
|
||||
* {@link #available()} method can be called first to check how many samples are
|
||||
* ready in the buffer. In case the buffer overflows, as result of the client
|
||||
* not reading fast enough, old samples will be dropped, and the client can
|
||||
* check {@link #getOverflowCount()} to determine how many samples have been
|
||||
* lost. The sample rate used for capturing samples can be obtained by calling
|
||||
* {@link #getSampleRate()}.
|
||||
* <p>
|
||||
* The non-buffered versions of the read methods will still behave normally when
|
||||
* buffering is enabled. The {@link #read()} and {@link #getVoltage()} methods
|
||||
* will always return the most recent value, regardless of the buffer state.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* AnalogInput potentiometer = ioio.openAnalogInput(40);
|
||||
* potentiometer.setBuffer(256);
|
||||
* for (int i = 0; i < 1024; ++i) {
|
||||
* // next line will block until at least one sample is available
|
||||
* float sample = potentiometer.readBuffered();
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
* potentiometer.close(); // pin 40 can now be used for something else.
|
||||
* </pre>
|
||||
*
|
||||
* @see IOIO#openAnalogInput(int)
|
||||
@@ -69,11 +101,13 @@ public interface AnalogInput extends Closeable {
|
||||
* may block shortly. If this is a problem, the calling thread can be
|
||||
* interrupted.
|
||||
* <p>
|
||||
* If a scaled value is desired, consider using {@link #read()}.
|
||||
* If a scaled value is desired, consider using {@link #read()}.
|
||||
*
|
||||
* @return The voltage, in Volt units.
|
||||
* @throws InterruptedException The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException The connection with the IOIO is lost.
|
||||
* @throws InterruptedException
|
||||
* The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO is lost.
|
||||
* @see #read()
|
||||
*/
|
||||
public float getVoltage() throws InterruptedException,
|
||||
@@ -81,6 +115,7 @@ public interface AnalogInput extends Closeable {
|
||||
|
||||
/**
|
||||
* Gets the maximum value against which {@link #read()} values are scaled.
|
||||
*
|
||||
* @return The voltage, in Volts.
|
||||
*/
|
||||
public float getReference();
|
||||
@@ -96,9 +131,95 @@ public interface AnalogInput extends Closeable {
|
||||
* If an absolute value is desired, consider using {@link #getVoltage()}.
|
||||
*
|
||||
* @return The voltage, in scaled units.
|
||||
* @throws InterruptedException The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException The connection with the IOIO is lost.
|
||||
* @throws InterruptedException
|
||||
* The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO is lost.
|
||||
* @see #getVoltage()
|
||||
*/
|
||||
public float read() throws InterruptedException, ConnectionLostException;
|
||||
|
||||
/**
|
||||
* Initializes or destroys an internal buffer, used for queuing sampled
|
||||
* data. When called with a positive argument, an internal buffer will be
|
||||
* created, and start storing sampled data. The client can then call
|
||||
* {@link #readBuffered()} or {@link #getVoltageBuffered()} for obtaining
|
||||
* buffered samples.
|
||||
* <p>
|
||||
* When called with argument of 0, the internal buffer is destroyed.
|
||||
*
|
||||
* @param capacity
|
||||
* The maximum number of unread samples that can be buffered
|
||||
* before overflow occurs.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO is lost.
|
||||
*/
|
||||
public void setBuffer(int capacity) throws ConnectionLostException;
|
||||
|
||||
/**
|
||||
* Gets the number of samples that have been dropped as result of overflow,
|
||||
* since {@link #setBuffer(int)} has been called.
|
||||
*
|
||||
* @return The number of dropped samples.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO is lost.
|
||||
*/
|
||||
public int getOverflowCount() throws ConnectionLostException;
|
||||
|
||||
/**
|
||||
* Gets the number of samples currently in the buffer. Reading that many
|
||||
* samples is guaranteed not to block.
|
||||
*
|
||||
* @return The number of samples available in the buffer.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO is lost.
|
||||
*/
|
||||
public int available() throws ConnectionLostException;
|
||||
|
||||
/**
|
||||
* Read a sample from the internal buffer. This method will block until at
|
||||
* least one sample is available, the instance is closed (via
|
||||
* {@link #close()}), the thread is interrupted (via
|
||||
* {@link Thread#interrupt()} or connection is lost. {@link #setBuffer(int)}
|
||||
* must be called prior to this method for setting up an internal buffer for
|
||||
* storing samples.
|
||||
*
|
||||
* @see #getVoltageBuffered()
|
||||
* @return The earliest (oldest) sample available in the buffer, scaled to
|
||||
* the range [0,1].
|
||||
* @throws InterruptedException
|
||||
* The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO is lost.
|
||||
*/
|
||||
public float readBuffered() throws InterruptedException,
|
||||
ConnectionLostException;
|
||||
|
||||
/**
|
||||
* Read a sample from the internal buffer. This method will block until at
|
||||
* least one sample is available, the instance is closed (via
|
||||
* {@link #close()}), the thread is interrupted (via
|
||||
* {@link Thread#interrupt()} or connection is lost. {@link #setBuffer(int)}
|
||||
* must be called prior to this method for setting up an internal buffer for
|
||||
* storing samples.
|
||||
*
|
||||
* @see #readBuffered()
|
||||
* @return The earliest (oldest) sample available in the buffer, in Volt
|
||||
* units.
|
||||
* @throws InterruptedException
|
||||
* The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO is lost.
|
||||
*/
|
||||
public float getVoltageBuffered() throws InterruptedException,
|
||||
ConnectionLostException;
|
||||
|
||||
/**
|
||||
* Gets the sample rate used for obtaining buffered samples.
|
||||
*
|
||||
* @return The sample rate, in Hz units.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO is lost.
|
||||
*/
|
||||
public float getSampleRate() throws ConnectionLostException;
|
||||
}
|
||||
|
||||
@@ -1,140 +1,140 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A pin used for digital input.
|
||||
* <p>
|
||||
* A digital input pin can be used to read logic-level signals. DigitalInput
|
||||
* instances are obtained by calling {@link IOIO#openDigitalInput(Spec)}.
|
||||
* <p>
|
||||
* The value of the pin is obtained by calling {@link #read()}. It is also
|
||||
* possible for the client to block until a certain level is sensed, by using
|
||||
* {@link #waitForValue(boolean)}.
|
||||
* <p>
|
||||
* The instance is alive since its creation. The first {@link #read()} call
|
||||
* block for a few milliseconds until the initial value is updated. If the
|
||||
* connection with the IOIO drops at any point, the instance transitions to a
|
||||
* disconnected state, in which every attempt to use the pin (except
|
||||
* {@link #close()}) will throw a {@link ConnectionLostException}. Whenever
|
||||
* {@link #close()} is invoked the instance may no longer be used. Any resources
|
||||
* associated with it are freed and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* DigitalInput button = ioio.openDigitalInput(10); // used an external pull-up
|
||||
* button.waitForValue(false); // wait for press
|
||||
* ...
|
||||
* button.close(); // pin 10 can now be used for something else.
|
||||
* </pre>
|
||||
*/
|
||||
public interface DigitalInput extends Closeable {
|
||||
/**
|
||||
* A digital input pin specification, used when opening digital inputs.
|
||||
*/
|
||||
static public class Spec {
|
||||
/** Input pin mode. */
|
||||
public enum Mode {
|
||||
/**
|
||||
* Pin is floating. When the pin is left disconnected the value
|
||||
* sensed is undefined. Use this mode when an external pull-up or
|
||||
* pull-down resistor is used or when interfacing push-pull type
|
||||
* logic circuits.
|
||||
*/
|
||||
FLOATING,
|
||||
/**
|
||||
* Internal pull-up resistor is used. When the pin is left
|
||||
* disconnected, a logical "HIGH" (true) will be sensed. This is
|
||||
* useful for interfacing with open drain circuits or for
|
||||
* interacting with a switch connected between the pin and ground.
|
||||
*/
|
||||
PULL_UP,
|
||||
/**
|
||||
* Internal pull-down resistor is used. When the pin is left
|
||||
* disconnected, a logical "LOW" (false) will be sensed. This is
|
||||
* useful for interacting with a switch connected between the pin
|
||||
* and Vdd.
|
||||
*/
|
||||
PULL_DOWN
|
||||
}
|
||||
|
||||
/** The pin number, as labeled on the board. */
|
||||
public int pin;
|
||||
/** The pin mode. */
|
||||
public Mode mode;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pin
|
||||
* Pin number, as labeled on the board.
|
||||
* @param mode
|
||||
* Pin mode.
|
||||
*/
|
||||
public Spec(int pin, Mode mode) {
|
||||
this.pin = pin;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/** Shorthand for Spec(pin, Mode.FLOATING). */
|
||||
public Spec(int pin) {
|
||||
this(pin, Mode.FLOATING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the value sensed on the pin. May block for a few milliseconds if
|
||||
* called right after creation of the instance. If this is a problem, the
|
||||
* calling thread may be interrupted.
|
||||
*
|
||||
* @return True for logical "HIGH", false for logical "LOW".
|
||||
* @throws InterruptedException
|
||||
* The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO has been lost.
|
||||
*/
|
||||
public boolean read() throws InterruptedException, ConnectionLostException;
|
||||
|
||||
/**
|
||||
* Block until a desired logical level is sensed. The calling thread can be
|
||||
* interrupted for aborting this operation.
|
||||
*
|
||||
* @param value
|
||||
* The desired logical level. true for "HIGH", false for "LOW".
|
||||
* @throws InterruptedException
|
||||
* The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO has been lost.
|
||||
*/
|
||||
public void waitForValue(boolean value) throws InterruptedException,
|
||||
ConnectionLostException;
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A pin used for digital input.
|
||||
* <p>
|
||||
* A digital input pin can be used to read logic-level signals. DigitalInput
|
||||
* instances are obtained by calling {@link IOIO#openDigitalInput(DigitalInput.Spec)}.
|
||||
* <p>
|
||||
* The value of the pin is obtained by calling {@link #read()}. It is also
|
||||
* possible for the client to block until a certain level is sensed, by using
|
||||
* {@link #waitForValue(boolean)}.
|
||||
* <p>
|
||||
* The instance is alive since its creation. The first {@link #read()} call
|
||||
* block for a few milliseconds until the initial value is updated. If the
|
||||
* connection with the IOIO drops at any point, the instance transitions to a
|
||||
* disconnected state, in which every attempt to use the pin (except
|
||||
* {@link #close()}) will throw a {@link ConnectionLostException}. Whenever
|
||||
* {@link #close()} is invoked the instance may no longer be used. Any resources
|
||||
* associated with it are freed and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* DigitalInput button = ioio.openDigitalInput(10); // used an external pull-up
|
||||
* button.waitForValue(false); // wait for press
|
||||
* ...
|
||||
* button.close(); // pin 10 can now be used for something else.
|
||||
* </pre>
|
||||
*/
|
||||
public interface DigitalInput extends Closeable {
|
||||
/**
|
||||
* A digital input pin specification, used when opening digital inputs.
|
||||
*/
|
||||
static public class Spec {
|
||||
/** Input pin mode. */
|
||||
public enum Mode {
|
||||
/**
|
||||
* Pin is floating. When the pin is left disconnected the value
|
||||
* sensed is undefined. Use this mode when an external pull-up or
|
||||
* pull-down resistor is used or when interfacing push-pull type
|
||||
* logic circuits.
|
||||
*/
|
||||
FLOATING,
|
||||
/**
|
||||
* Internal pull-up resistor is used. When the pin is left
|
||||
* disconnected, a logical "HIGH" (true) will be sensed. This is
|
||||
* useful for interfacing with open drain circuits or for
|
||||
* interacting with a switch connected between the pin and ground.
|
||||
*/
|
||||
PULL_UP,
|
||||
/**
|
||||
* Internal pull-down resistor is used. When the pin is left
|
||||
* disconnected, a logical "LOW" (false) will be sensed. This is
|
||||
* useful for interacting with a switch connected between the pin
|
||||
* and Vdd.
|
||||
*/
|
||||
PULL_DOWN
|
||||
}
|
||||
|
||||
/** The pin number, as labeled on the board. */
|
||||
public int pin;
|
||||
/** The pin mode. */
|
||||
public Mode mode;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pin
|
||||
* Pin number, as labeled on the board.
|
||||
* @param mode
|
||||
* Pin mode.
|
||||
*/
|
||||
public Spec(int pin, Mode mode) {
|
||||
this.pin = pin;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/** Shorthand for Spec(pin, Mode.FLOATING). */
|
||||
public Spec(int pin) {
|
||||
this(pin, Mode.FLOATING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the value sensed on the pin. May block for a few milliseconds if
|
||||
* called right after creation of the instance. If this is a problem, the
|
||||
* calling thread may be interrupted.
|
||||
*
|
||||
* @return True for logical "HIGH", false for logical "LOW".
|
||||
* @throws InterruptedException
|
||||
* The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO has been lost.
|
||||
*/
|
||||
public boolean read() throws InterruptedException, ConnectionLostException;
|
||||
|
||||
/**
|
||||
* Block until a desired logical level is sensed. The calling thread can be
|
||||
* interrupted for aborting this operation.
|
||||
*
|
||||
* @param value
|
||||
* The desired logical level. true for "HIGH", false for "LOW".
|
||||
* @throws InterruptedException
|
||||
* The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO has been lost.
|
||||
*/
|
||||
public void waitForValue(boolean value) throws InterruptedException,
|
||||
ConnectionLostException;
|
||||
}
|
||||
|
||||
@@ -1,120 +1,120 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A pin used for digital output.
|
||||
* <p>
|
||||
* A digital input pin can be used to generate logic-level signals.
|
||||
* DigitalOutput instances are obtained by calling
|
||||
* {@link IOIO#openDigitalOutput(Spec, boolean)}.
|
||||
* <p>
|
||||
* The value of the pin is set by calling {@link #write(boolean)}.
|
||||
* <p>
|
||||
* The instance is alive since its creation. If the connection with the IOIO
|
||||
* drops at any point, the instance transitions to a disconnected state, in
|
||||
* which every attempt to use the pin (except {@link #close()}) will throw a
|
||||
* {@link ConnectionLostException}. Whenever {@link #close()} is invoked the
|
||||
* instance may no longer be used. Any resources associated with it are freed
|
||||
* and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* DigitalOutput led = ioio.openDigitalInput(2); // LED anode on pin 2.
|
||||
* led.write(true); // turn LED on.
|
||||
* ...
|
||||
* led.close(); // pin 2 can now be used for something else.
|
||||
* </pre>
|
||||
*/
|
||||
public interface DigitalOutput extends Closeable {
|
||||
/**
|
||||
* A digital output pin specification, used when opening digital outputs.
|
||||
*/
|
||||
public static class Spec {
|
||||
/** Output pin mode. */
|
||||
public enum Mode {
|
||||
/**
|
||||
* Pin operates in push-pull mode, i.e. a logical "HIGH" is
|
||||
* represented by a voltage of Vdd on the pin and a logical "LOW" by
|
||||
* a voltage of 0 (ground).
|
||||
*/
|
||||
NORMAL,
|
||||
/**
|
||||
* Pin operates in open-drain mode, i.e. a logical "HIGH" is
|
||||
* represented by a high impedance on the pin (as if it is
|
||||
* disconnected) and a logical "LOW" by a voltage of 0 (ground).
|
||||
* This mode is most commonly used for generating 5V logical signal
|
||||
* on a 3.3V pin: 5V tolerant pins must be used; a pull-up resistor
|
||||
* is connected between the pin and 5V, and the pin is used in open-
|
||||
* drain mode.
|
||||
*/
|
||||
OPEN_DRAIN,
|
||||
}
|
||||
|
||||
/** The pin number, as labeled on the board. */
|
||||
public int pin;
|
||||
/** The pin mode. */
|
||||
public Mode mode;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pin
|
||||
* Pin number, as labeled on the board.
|
||||
* @param mode
|
||||
* Pin mode.
|
||||
*/
|
||||
public Spec(int pin, Mode mode) {
|
||||
this.pin = pin;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand for Spec(pin, Mode.NORMAL).
|
||||
*
|
||||
* @see #Spec(int, Mode)
|
||||
*/
|
||||
public Spec(int pin) {
|
||||
this(pin, Mode.NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output of the pin.
|
||||
*
|
||||
* @param val
|
||||
* The output. true is logical "HIGH", false is logical "LOW".
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO has been lost.
|
||||
*/
|
||||
public void write(boolean val) throws ConnectionLostException;
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A pin used for digital output.
|
||||
* <p>
|
||||
* A digital input pin can be used to generate logic-level signals.
|
||||
* DigitalOutput instances are obtained by calling
|
||||
* {@link IOIO#openDigitalOutput(DigitalOutput.Spec, boolean)}.
|
||||
* <p>
|
||||
* The value of the pin is set by calling {@link #write(boolean)}.
|
||||
* <p>
|
||||
* The instance is alive since its creation. If the connection with the IOIO
|
||||
* drops at any point, the instance transitions to a disconnected state, in
|
||||
* which every attempt to use the pin (except {@link #close()}) will throw a
|
||||
* {@link ConnectionLostException}. Whenever {@link #close()} is invoked the
|
||||
* instance may no longer be used. Any resources associated with it are freed
|
||||
* and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* DigitalOutput led = ioio.openDigitalInput(2); // LED anode on pin 2.
|
||||
* led.write(true); // turn LED on.
|
||||
* ...
|
||||
* led.close(); // pin 2 can now be used for something else.
|
||||
* </pre>
|
||||
*/
|
||||
public interface DigitalOutput extends Closeable {
|
||||
/**
|
||||
* A digital output pin specification, used when opening digital outputs.
|
||||
*/
|
||||
public static class Spec {
|
||||
/** Output pin mode. */
|
||||
public enum Mode {
|
||||
/**
|
||||
* Pin operates in push-pull mode, i.e. a logical "HIGH" is
|
||||
* represented by a voltage of Vdd on the pin and a logical "LOW" by
|
||||
* a voltage of 0 (ground).
|
||||
*/
|
||||
NORMAL,
|
||||
/**
|
||||
* Pin operates in open-drain mode, i.e. a logical "HIGH" is
|
||||
* represented by a high impedance on the pin (as if it is
|
||||
* disconnected) and a logical "LOW" by a voltage of 0 (ground).
|
||||
* This mode is most commonly used for generating 5V logical signal
|
||||
* on a 3.3V pin: 5V tolerant pins must be used; a pull-up resistor
|
||||
* is connected between the pin and 5V, and the pin is used in open-
|
||||
* drain mode.
|
||||
*/
|
||||
OPEN_DRAIN,
|
||||
}
|
||||
|
||||
/** The pin number, as labeled on the board. */
|
||||
public int pin;
|
||||
/** The pin mode. */
|
||||
public Mode mode;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pin
|
||||
* Pin number, as labeled on the board.
|
||||
* @param mode
|
||||
* Pin mode.
|
||||
*/
|
||||
public Spec(int pin, Mode mode) {
|
||||
this.pin = pin;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand for Spec(pin, Mode.NORMAL).
|
||||
*
|
||||
* @see DigitalOutput.Spec#Spec(int, DigitalOutput.Spec.Mode)
|
||||
*/
|
||||
public Spec(int pin) {
|
||||
this(pin, Mode.NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output of the pin.
|
||||
*
|
||||
* @param val
|
||||
* The output. true is logical "HIGH", false is logical "LOW".
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO has been lost.
|
||||
*/
|
||||
public void write(boolean val) throws ConnectionLostException;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
0
IOIOLib/src/ioio/lib/api/IOIOConnection.java
Executable file → Normal file
0
IOIOLib/src/ioio/lib/api/IOIOConnection.java
Executable file → Normal file
@@ -28,10 +28,14 @@
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import ioio.lib.impl.IOIOImpl;
|
||||
import ioio.lib.impl.SocketIOIOConnection;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
import ioio.lib.util.IOIOConnectionRegistry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Factory class for creating instances of the IOIO interface.
|
||||
@@ -55,22 +59,21 @@ import ioio.lib.impl.SocketIOIOConnection;
|
||||
* </pre>
|
||||
*/
|
||||
public class IOIOFactory {
|
||||
/** The TCP port used for communicating with the IOIO board. */
|
||||
public static final int IOIO_PORT = 4545;
|
||||
|
||||
/**
|
||||
* Create a IOIO instance. This specific implementation creates a IOIO
|
||||
* instance which works with the actual IOIO board connected via a TCP
|
||||
* connection (typically over a wired USB connection).
|
||||
*
|
||||
*
|
||||
* @return The IOIO instance.
|
||||
*/
|
||||
public static IOIO create() {
|
||||
Collection<IOIOConnectionFactory> factories = IOIOConnectionRegistry
|
||||
.getConnectionFactories();
|
||||
try {
|
||||
return create(SocketIOIOConnection.class.getName(), IOIO_PORT);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// we shouldn't get here - this class must always exist.
|
||||
throw new RuntimeException("Something is very wrong here");
|
||||
return create(factories.iterator().next().createConnection());
|
||||
} catch (NoSuchElementException e) {
|
||||
Log.e(TAG, "No connection is available. This shouldn't happen.");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,44 +81,15 @@ public class IOIOFactory {
|
||||
* Create a IOIO instance with a user-provided underlying connection class.
|
||||
* This method should be used for establishing a non-standard connection to
|
||||
* the IOIO board.
|
||||
*
|
||||
* @param connectionClassName
|
||||
* The name of the connection class. Must have a public default
|
||||
* constructor.
|
||||
*
|
||||
*
|
||||
* @param connection
|
||||
* An instance of a IOIO connection.
|
||||
*
|
||||
* @return The IOIO instance.
|
||||
* @throws ClassNotFoundException The given class name was not found.
|
||||
*/
|
||||
public static IOIO create(String connectionClassName, Object... args) throws ClassNotFoundException {
|
||||
IOIOConnection connection = createConnectionDynamically(connectionClassName, args);
|
||||
return create(connection);
|
||||
}
|
||||
|
||||
public static IOIO create(IOIOConnection connection) {
|
||||
return new IOIOImpl(connection);
|
||||
}
|
||||
|
||||
public static IOIOConnection createConnectionDynamically(
|
||||
String connectionClassName, Object... args)
|
||||
throws ClassNotFoundException {
|
||||
Class<?> cls;
|
||||
cls = Class.forName(connectionClassName);
|
||||
Object instance;
|
||||
try {
|
||||
Class<?>[] argTypes = new Class<?>[args.length];
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
argTypes[i] = args[i].getClass();
|
||||
}
|
||||
Constructor<?> constructor = cls.getConstructor(argTypes);
|
||||
instance = constructor.newInstance(args);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Provided class does not have a public ctor with the right signature", e);
|
||||
}
|
||||
if (!(instance instanceof IOIOConnection)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Provided class does not implement IOIOConnection");
|
||||
}
|
||||
return (IOIOConnection) instance;
|
||||
}
|
||||
private static final String TAG = "IOIOFactory";
|
||||
}
|
||||
|
||||
0
IOIOLib/src/ioio/lib/api/IcspMaster.java
Executable file → Normal file
0
IOIOLib/src/ioio/lib/api/IcspMaster.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/api/PulseInput.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/api/PulseInput.java
Executable file → Normal file
@@ -46,7 +46,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* for measuring a turning shaft's speed.
|
||||
* <p>
|
||||
* {@link PulseInput} instances are obtained by calling
|
||||
* {@link IOIO#openPulseInput(ioio.lib.api.DigitalInput.Spec, ClockRate, PulseMode, boolean)}
|
||||
* {@link IOIO#openPulseInput(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.PulseInput.ClockRate, ioio.lib.api.PulseInput.PulseMode, boolean)}
|
||||
* . When created, some important configuration decisions have to be made: the
|
||||
* precision (single or double), the clock rate and the mode of operation. Modes
|
||||
* are straightforward: {@link PulseMode#POSITIVE} is used for measuring a
|
||||
|
||||
13
IOIOLib/src/ioio/lib/api/SpiMaster.java
Executable file → Normal file
13
IOIOLib/src/ioio/lib/api/SpiMaster.java
Executable file → Normal file
@@ -28,7 +28,6 @@
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.DigitalInput.Spec;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
@@ -41,7 +40,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* between this slave and a respective pin on the master. The MISO line should
|
||||
* operate in pull-up mode, using either the internal pull-up or an external
|
||||
* resistor. SpiMaster instances are obtained by calling
|
||||
* {@link IOIO#openSpiMaster(Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], Config)}.
|
||||
* {@link IOIO#openSpiMaster(DigitalInput.Spec, DigitalOutput.Spec, DigitalOutput.Spec, DigitalOutput.Spec[], SpiMaster.Config)}.
|
||||
* <p>
|
||||
* The SPI protocol is comprised of simultaneous sending and receiving of data
|
||||
* between the bus master and a single slave. By the very nature of this
|
||||
@@ -90,9 +89,11 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* spi.writeRead(request, 2, 4, response, 3);
|
||||
* ...
|
||||
* spi.close(); // free SPI module and pins
|
||||
* }</pre>
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see IOIO#openSpiMaster(Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], Config)
|
||||
* @see IOIO#openSpiMaster(DigitalInput.Spec, DigitalOutput.Spec,
|
||||
* DigitalOutput.Spec, DigitalOutput.Spec[], SpiMaster.Config)
|
||||
*/
|
||||
public interface SpiMaster extends Closeable {
|
||||
/** Possible data rates for SPI, in Hz. */
|
||||
@@ -148,7 +149,7 @@ public interface SpiMaster extends Closeable {
|
||||
* Constructor with common defaults. Equivalent to Config(rate, false,
|
||||
* false)
|
||||
*
|
||||
* @see #Config(Rate, boolean, boolean)
|
||||
* @see SpiMaster.Config#Config(SpiMaster.Config.Rate, boolean, boolean)
|
||||
*/
|
||||
public Config(Rate rate) {
|
||||
this(rate, false, false);
|
||||
@@ -165,7 +166,7 @@ public interface SpiMaster extends Closeable {
|
||||
* @param slave
|
||||
* The slave index. It is determined by the index of its
|
||||
* slave-select pin, as per the array passed to
|
||||
* {@link IOIO#openSpiMaster(Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], Config)}
|
||||
* {@link IOIO#openSpiMaster(DigitalInput.Spec, DigitalOutput.Spec, DigitalOutput.Spec, DigitalOutput.Spec[], SpiMaster.Config)}
|
||||
* .
|
||||
* @param writeData
|
||||
* A byte array of data to write. May be null if writeSize is 0.
|
||||
|
||||
4
IOIOLib/src/ioio/lib/api/TwiMaster.java
Executable file → Normal file
4
IOIOLib/src/ioio/lib/api/TwiMaster.java
Executable file → Normal file
@@ -39,7 +39,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* requires a physical connection of two lines (SDA, SCL) shared by all the bus
|
||||
* nodes, where the SDA is open-drain and externally pulled-up. TwiMaster
|
||||
* instances are obtained by calling
|
||||
* {@link IOIO#openTwiMaster(int, Rate, boolean)}.
|
||||
* {@link IOIO#openTwiMaster(int, ioio.lib.api.TwiMaster.Rate, boolean)}.
|
||||
* <p>
|
||||
* TWI is the generic name for the specific I2C and SMBus protocols, differing
|
||||
* mostly by the voltage levels they require. This module supports both.
|
||||
@@ -79,7 +79,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* twi.close(); // free TWI module and pins
|
||||
* }</pre>
|
||||
*
|
||||
* @see IOIO#openTwiMaster(int, Rate, boolean)
|
||||
* @see IOIO#openTwiMaster(int, ioio.lib.api.TwiMaster.Rate, boolean)
|
||||
*/
|
||||
public interface TwiMaster extends Closeable {
|
||||
enum Rate {
|
||||
|
||||
@@ -1,108 +1,107 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.DigitalInput.Spec;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An interface for controlling a UART module.
|
||||
* <p>
|
||||
* UART is a very common hardware communication protocol, enabling full- duplex,
|
||||
* asynchronous point-to-point data transfer. It typically serves for opening
|
||||
* consoles or as a basis for higher-level protocols, such as MIDI, RS-232 and
|
||||
* RS-485. Uart instances are obtained by calling
|
||||
* {@link IOIO#openUart(Spec, ioio.lib.api.DigitalOutput.Spec, int, Parity, StopBits)}.
|
||||
* <p>
|
||||
* The UART protocol is completely symmetric - there is no "master" and "slave"
|
||||
* at this layer. Each end may send any number of bytes at arbitrary times,
|
||||
* making it very useful for terminals and terminal-controllable devices.
|
||||
* <p>
|
||||
* Working with UART is very intuitive - it just provides a standard InputStream
|
||||
* and/or OutputStream. Optionally, one could create a read-only or write-only
|
||||
* UART instances, by passing null (or INVALID_PIN) for either TX or RX pins.
|
||||
* <p>
|
||||
* The instance is alive since its creation. If the connection with the IOIO
|
||||
* drops at any point, the instance transitions to a disconnected state, which
|
||||
* every attempt to use it (except {@link #close()}) will throw a
|
||||
* {@link ConnectionLostException}. Whenever {@link #close()} is invoked the
|
||||
* instance may no longer be used. Any resources associated with it are freed
|
||||
* and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* Uart uart = ioio.openUart(3, 4, 19200, Parity.NONE, StopBits.ONE);
|
||||
* InputStream in = uart.getInputStream();
|
||||
* OutputStream out = uart.getOutputStream();
|
||||
* out.write(new String("Hello").getBytes());
|
||||
* int i = in.read(); // blocking
|
||||
* ...
|
||||
* uart.close(); // free UART module and pins
|
||||
* </pre>
|
||||
*
|
||||
* @see IOIO#openUart(Spec, ioio.lib.api.DigitalOutput.Spec, int, Parity,
|
||||
* StopBits)
|
||||
*/
|
||||
public interface Uart extends Closeable {
|
||||
/** Parity-bit mode. */
|
||||
enum Parity {
|
||||
/** No parity. */
|
||||
NONE,
|
||||
/** Even parity. */
|
||||
EVEN,
|
||||
/** Odd parity. */
|
||||
ODD
|
||||
}
|
||||
|
||||
/** Number of stop-bits. */
|
||||
enum StopBits {
|
||||
/** One stop bit. */
|
||||
ONE,
|
||||
/** Two stop bits. */
|
||||
TWO
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input stream.
|
||||
*
|
||||
* @return An input stream.
|
||||
*/
|
||||
public InputStream getInputStream();
|
||||
|
||||
/**
|
||||
* Gets the output stream.
|
||||
*
|
||||
* @return An output stream.
|
||||
*/
|
||||
public OutputStream getOutputStream();
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An interface for controlling a UART module.
|
||||
* <p>
|
||||
* UART is a very common hardware communication protocol, enabling full- duplex,
|
||||
* asynchronous point-to-point data transfer. It typically serves for opening
|
||||
* consoles or as a basis for higher-level protocols, such as MIDI, RS-232 and
|
||||
* RS-485. Uart instances are obtained by calling
|
||||
* {@link IOIO#openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity, Uart.StopBits)}.
|
||||
* <p>
|
||||
* The UART protocol is completely symmetric - there is no "master" and "slave"
|
||||
* at this layer. Each end may send any number of bytes at arbitrary times,
|
||||
* making it very useful for terminals and terminal-controllable devices.
|
||||
* <p>
|
||||
* Working with UART is very intuitive - it just provides a standard InputStream
|
||||
* and/or OutputStream. Optionally, one could create a read-only or write-only
|
||||
* UART instances, by passing null (or INVALID_PIN) for either TX or RX pins.
|
||||
* <p>
|
||||
* The instance is alive since its creation. If the connection with the IOIO
|
||||
* drops at any point, the instance transitions to a disconnected state, which
|
||||
* every attempt to use it (except {@link #close()}) will throw a
|
||||
* {@link ConnectionLostException}. Whenever {@link #close()} is invoked the
|
||||
* instance may no longer be used. Any resources associated with it are freed
|
||||
* and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* Uart uart = ioio.openUart(3, 4, 19200, Parity.NONE, StopBits.ONE);
|
||||
* InputStream in = uart.getInputStream();
|
||||
* OutputStream out = uart.getOutputStream();
|
||||
* out.write(new String("Hello").getBytes());
|
||||
* int i = in.read(); // blocking
|
||||
* ...
|
||||
* uart.close(); // free UART module and pins
|
||||
* </pre>
|
||||
*
|
||||
* @see IOIO#openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity,
|
||||
* Uart.StopBits)
|
||||
*/
|
||||
public interface Uart extends Closeable {
|
||||
/** Parity-bit mode. */
|
||||
enum Parity {
|
||||
/** No parity. */
|
||||
NONE,
|
||||
/** Even parity. */
|
||||
EVEN,
|
||||
/** Odd parity. */
|
||||
ODD
|
||||
}
|
||||
|
||||
/** Number of stop-bits. */
|
||||
enum StopBits {
|
||||
/** One stop bit. */
|
||||
ONE,
|
||||
/** Two stop bits. */
|
||||
TWO
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input stream.
|
||||
*
|
||||
* @return An input stream.
|
||||
*/
|
||||
public InputStream getInputStream();
|
||||
|
||||
/**
|
||||
* Gets the output stream.
|
||||
*
|
||||
* @return An output stream.
|
||||
*/
|
||||
public OutputStream getOutputStream();
|
||||
}
|
||||
|
||||
0
IOIOLib/src/ioio/lib/api/exception/IncompatibilityException.java
Executable file → Normal file
0
IOIOLib/src/ioio/lib/api/exception/IncompatibilityException.java
Executable file → Normal file
@@ -1,3 +1,32 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.bluetooth;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
@@ -8,43 +37,41 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.UUID;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
public class BluetoothIOIOConnection implements IOIOConnection {
|
||||
private static final String TAG = "BluetoothIOIOConnection";
|
||||
private BluetoothSocket socket_ = null;
|
||||
private boolean disconnect_ = false;
|
||||
private final BluetoothDevice device_;
|
||||
private final String name_;
|
||||
private final String address_;
|
||||
|
||||
public BluetoothIOIOConnection(String name, String address) {
|
||||
name_ = name;
|
||||
address_ = address;
|
||||
public BluetoothIOIOConnection(BluetoothDevice device) {
|
||||
device_ = device;
|
||||
name_ = device.getName();
|
||||
address_ = device.getAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitForConnect() throws ConnectionLostException {
|
||||
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
final BluetoothDevice ioioDevice = adapter.getRemoteDevice(address_);
|
||||
synchronized (this) {
|
||||
if (disconnect_) {
|
||||
throw new ConnectionLostException();
|
||||
}
|
||||
Log.v(TAG, name_ + " Creating socket");
|
||||
try {
|
||||
socket_ = createSocket(ioioDevice);
|
||||
socket_ = createSocket(device_);
|
||||
} catch (IOException e) {
|
||||
throw new ConnectionLostException(e);
|
||||
}
|
||||
Log.v(TAG, name_ + " Created socket");
|
||||
}
|
||||
// keep trying to connect as long as we're not aborting
|
||||
while (true) {
|
||||
try {
|
||||
Log.v(TAG, name_ + "Connecting");
|
||||
Log.v(TAG, "Attempting to connect to Bluetooth device: " + name_);
|
||||
socket_.connect();
|
||||
Log.v(TAG, "Established connection to device " + name_
|
||||
+ " address: " + address_);
|
||||
@@ -61,17 +88,15 @@ public class BluetoothIOIOConnection implements IOIOConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public BluetoothSocket createSocket(final BluetoothDevice device)
|
||||
public static BluetoothSocket createSocket(final BluetoothDevice device)
|
||||
throws IOException {
|
||||
try {
|
||||
// We're trying to create an insecure socket, which is
|
||||
// only supported
|
||||
// in API 10 and up. If we fail, we try a secure socket
|
||||
// with is in API
|
||||
// 7 and up.
|
||||
if (Build.VERSION.SDK_INT >= 10 ) {
|
||||
// We're trying to create an insecure socket, which is only
|
||||
// supported in API 10 and up. Otherwise, we try a secure socket
|
||||
// which is in API 7 and up.
|
||||
return device.createInsecureRfcommSocketToServiceRecord(UUID
|
||||
.fromString("00001101-0000-1000-8000-00805F9B34FB"));
|
||||
} catch (NoSuchMethodError e) {
|
||||
} else {
|
||||
return device.createRfcommSocketToServiceRecord(UUID
|
||||
.fromString("00001101-0000-1000-8000-00805F9B34FB"));
|
||||
}
|
||||
@@ -82,7 +107,7 @@ public class BluetoothIOIOConnection implements IOIOConnection {
|
||||
if (disconnect_) {
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "Client initiated disconnect");
|
||||
Log.v(TAG, "Client initiated disconnect");
|
||||
disconnect_ = true;
|
||||
if (socket_ != null) {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.bluetooth;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
import ioio.lib.spi.NoRuntimeSupportException;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.util.Log;
|
||||
|
||||
public class BluetoothIOIOConnectionBootstrap implements
|
||||
IOIOConnectionBootstrap {
|
||||
|
||||
private static final String TAG = "BluetoothIOIOConnectionDiscovery";
|
||||
private final BluetoothAdapter adapter_;
|
||||
|
||||
public BluetoothIOIOConnectionBootstrap() throws NoRuntimeSupportException {
|
||||
try {
|
||||
adapter_ = BluetoothAdapter.getDefaultAdapter();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
throw new NoRuntimeSupportException(
|
||||
"Bluetooth is not supported on this device.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getFactories(Collection<IOIOConnectionFactory> result) {
|
||||
try {
|
||||
Set<BluetoothDevice> bondedDevices = adapter_.getBondedDevices();
|
||||
for (final BluetoothDevice device : bondedDevices) {
|
||||
if (device.getName().startsWith("IOIO")) {
|
||||
result.add(new IOIOConnectionFactory() {
|
||||
@Override
|
||||
public String getType() {
|
||||
return BluetoothIOIOConnection.class
|
||||
.getCanonicalName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getExtra() {
|
||||
return new Object[] { device.getName(),
|
||||
device.getAddress() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOIOConnection createConnection() {
|
||||
return new BluetoothIOIOConnection(device);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG,
|
||||
"Did you forget to declare uses-permission of android.permission.BLUETOOTH?");
|
||||
throw e;
|
||||
} catch (NoClassDefFoundError e) {
|
||||
Log.w(TAG, "Bluetooth is not supported on this device.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package ioio.lib.bluetooth;
|
||||
|
||||
import ioio.lib.util.IOIOConnectionDiscovery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.util.Log;
|
||||
|
||||
public class BluetoothIOIOConnectionDiscovery implements
|
||||
IOIOConnectionDiscovery {
|
||||
|
||||
private static final String TAG = "BluetoothIOIOConnectionDiscovery";
|
||||
|
||||
@Override
|
||||
public void getSpecs(Collection<IOIOConnectionSpec> result) {
|
||||
try {
|
||||
final BluetoothAdapter adapter = BluetoothAdapter
|
||||
.getDefaultAdapter();
|
||||
Set<BluetoothDevice> bondedDevices = adapter.getBondedDevices();
|
||||
for (BluetoothDevice device : bondedDevices) {
|
||||
if (device.getName().startsWith("IOIO")) {
|
||||
result.add(new IOIOConnectionSpec(
|
||||
BluetoothIOIOConnection.class.getName(),
|
||||
new Object[] { device.getName(),
|
||||
device.getAddress() }));
|
||||
}
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG,
|
||||
"Did you forget to declare uses-permission of android.permission.BLUETOOTH?");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
IOIOLib/src/ioio/lib/impl/AbstractPin.java
Executable file → Normal file
3
IOIOLib/src/ioio/lib/impl/AbstractPin.java
Executable file → Normal file
@@ -30,7 +30,7 @@ package ioio.lib.impl;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
public abstract class AbstractPin extends AbstractResource {
|
||||
abstract class AbstractPin extends AbstractResource {
|
||||
protected final int pinNum_;
|
||||
|
||||
AbstractPin(IOIOImpl ioio, int pinNum) throws ConnectionLostException {
|
||||
@@ -38,6 +38,7 @@ public abstract class AbstractPin extends AbstractResource {
|
||||
pinNum_ = pinNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void close() {
|
||||
super.close();
|
||||
ioio_.closePin(pinNum_);
|
||||
|
||||
3
IOIOLib/src/ioio/lib/impl/AbstractResource.java
Executable file → Normal file
3
IOIOLib/src/ioio/lib/impl/AbstractResource.java
Executable file → Normal file
@@ -32,7 +32,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.impl.IncomingState.DisconnectListener;
|
||||
import ioio.lib.api.Closeable;
|
||||
|
||||
public class AbstractResource implements Closeable, DisconnectListener {
|
||||
class AbstractResource implements Closeable, DisconnectListener {
|
||||
enum State {
|
||||
OPEN,
|
||||
CLOSED,
|
||||
@@ -53,6 +53,7 @@ public class AbstractResource implements Closeable, DisconnectListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void close() {
|
||||
if (state_ == State.CLOSED) {
|
||||
throw new IllegalStateException("Trying to use a closed resouce");
|
||||
|
||||
109
IOIOLib/src/ioio/lib/impl/AnalogInputImpl.java
Executable file → Normal file
109
IOIOLib/src/ioio/lib/impl/AnalogInputImpl.java
Executable file → Normal file
@@ -28,22 +28,31 @@
|
||||
*/
|
||||
package ioio.lib.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ioio.lib.api.AnalogInput;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.impl.IncomingState.InputPinListener;
|
||||
|
||||
public class AnalogInputImpl extends AbstractPin implements AnalogInput, InputPinListener {
|
||||
import java.io.IOException;
|
||||
|
||||
class AnalogInputImpl extends AbstractPin implements AnalogInput,
|
||||
InputPinListener {
|
||||
private int value_;
|
||||
private boolean valid_ = false;
|
||||
|
||||
|
||||
short[] buffer_;
|
||||
int bufferSize_;
|
||||
int bufferCapacity_;
|
||||
int bufferReadCursor_;
|
||||
int bufferWriteCursor_;
|
||||
int bufferOverflowCount_ = 0;
|
||||
|
||||
AnalogInputImpl(IOIOImpl ioio, int pin) throws ConnectionLostException {
|
||||
super(ioio, pin);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public float getVoltage() throws InterruptedException, ConnectionLostException {
|
||||
public float getVoltage() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
return read() * getReference();
|
||||
}
|
||||
|
||||
@@ -55,18 +64,20 @@ public class AnalogInputImpl extends AbstractPin implements AnalogInput, InputPi
|
||||
@Override
|
||||
synchronized public void setValue(int value) {
|
||||
// Log.v("AnalogInputImpl", "Pin " + pinNum_ + " value is " + value);
|
||||
assert(value >= 0 || value < 1024);
|
||||
value_ = value;
|
||||
assert (value >= 0 && value < 1024);
|
||||
value_ = value;
|
||||
if (!valid_) {
|
||||
valid_ = true;
|
||||
notifyAll();
|
||||
}
|
||||
bufferPush((short) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public float read() throws InterruptedException, ConnectionLostException {
|
||||
synchronized public float read() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
checkState();
|
||||
while (!valid_ && state_ != State.DISCONNECTED) {
|
||||
while (!valid_ && state_ == State.OPEN) {
|
||||
wait();
|
||||
}
|
||||
checkState();
|
||||
@@ -87,4 +98,82 @@ public class AnalogInputImpl extends AbstractPin implements AnalogInput, InputPi
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setBuffer(int capacity)
|
||||
throws ConnectionLostException {
|
||||
checkState();
|
||||
if (capacity <= 0) {
|
||||
buffer_ = null;
|
||||
} else {
|
||||
buffer_ = new short[capacity];
|
||||
}
|
||||
bufferCapacity_ = capacity;
|
||||
bufferSize_ = 0;
|
||||
bufferReadCursor_ = 0;
|
||||
bufferWriteCursor_ = 0;
|
||||
bufferOverflowCount_ = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readBuffered() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
checkState();
|
||||
return (float) bufferPull() / 1023.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getVoltageBuffered() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
return readBuffered() * getReference();
|
||||
}
|
||||
|
||||
private void bufferPush(short value) {
|
||||
if (buffer_ == null) {
|
||||
return;
|
||||
}
|
||||
if (bufferSize_ == bufferCapacity_) {
|
||||
++bufferOverflowCount_;
|
||||
} else {
|
||||
++bufferSize_;
|
||||
}
|
||||
buffer_[bufferWriteCursor_++] = value;
|
||||
if (bufferWriteCursor_ == bufferCapacity_) {
|
||||
bufferWriteCursor_ = 0;
|
||||
}
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
private synchronized short bufferPull() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
if (buffer_ == null) {
|
||||
throw new IllegalStateException(
|
||||
"Need to call setBuffer() before reading buffered values.");
|
||||
}
|
||||
while (bufferSize_ == 0 && state_ == State.OPEN) {
|
||||
wait();
|
||||
}
|
||||
checkState();
|
||||
short result = buffer_[bufferReadCursor_++];
|
||||
if (bufferReadCursor_ == bufferCapacity_) {
|
||||
bufferReadCursor_ = 0;
|
||||
}
|
||||
--bufferSize_;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOverflowCount() throws ConnectionLostException {
|
||||
return bufferOverflowCount_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSampleRate() throws ConnectionLostException {
|
||||
return 1000.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws ConnectionLostException {
|
||||
return bufferSize_;
|
||||
}
|
||||
}
|
||||
|
||||
90
IOIOLib/src/ioio/lib/impl/Constants.java
Executable file → Normal file
90
IOIOLib/src/ioio/lib/impl/Constants.java
Executable file → Normal file
@@ -1,45 +1,45 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.impl;
|
||||
|
||||
class Constants {
|
||||
static final int NUM_PINS = 49;
|
||||
static final int NUM_ANALOG_PINS = 16;
|
||||
static final int NUM_PWM_MODULES = 9;
|
||||
static final int NUM_UART_MODULES = 4;
|
||||
static final int NUM_SPI_MODULES = 3;
|
||||
static final int NUM_TWI_MODULES = 3;
|
||||
static final int[] INCAP_MODULES_DOUBLE = new int[] { 0, 2, 4};
|
||||
static final int[] INCAP_MODULES_SINGLE = new int[] { 6, 7, 8};
|
||||
static final int BUFFER_SIZE = 1024;
|
||||
static final int PACKET_BUFFER_SIZE = 256;
|
||||
|
||||
static final int[][] TWI_PINS = new int[][] {{ 4, 5 }, { 47, 48 }, { 26, 25 }};
|
||||
static final int[] ICSP_PINS = new int[] { 36, 37, 38 };
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.impl;
|
||||
|
||||
class Constants {
|
||||
static final int NUM_PINS = 49;
|
||||
static final int NUM_ANALOG_PINS = 16;
|
||||
static final int NUM_PWM_MODULES = 9;
|
||||
static final int NUM_UART_MODULES = 4;
|
||||
static final int NUM_SPI_MODULES = 3;
|
||||
static final int NUM_TWI_MODULES = 3;
|
||||
static final int[] INCAP_MODULES_DOUBLE = new int[] { 0, 2, 4};
|
||||
static final int[] INCAP_MODULES_SINGLE = new int[] { 6, 7, 8};
|
||||
static final int BUFFER_SIZE = 1024;
|
||||
static final int PACKET_BUFFER_SIZE = 256;
|
||||
|
||||
static final int[][] TWI_PINS = new int[][] {{ 4, 5 }, { 47, 48 }, { 26, 25 }};
|
||||
static final int[] ICSP_PINS = new int[] { 36, 37, 38 };
|
||||
}
|
||||
|
||||
3
IOIOLib/src/ioio/lib/impl/DigitalInputImpl.java
Executable file → Normal file
3
IOIOLib/src/ioio/lib/impl/DigitalInputImpl.java
Executable file → Normal file
@@ -34,7 +34,7 @@ import ioio.lib.impl.IncomingState.InputPinListener;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DigitalInputImpl extends AbstractPin implements DigitalInput,
|
||||
class DigitalInputImpl extends AbstractPin implements DigitalInput,
|
||||
InputPinListener {
|
||||
private boolean value_;
|
||||
private boolean valid_ = false;
|
||||
@@ -54,6 +54,7 @@ public class DigitalInputImpl extends AbstractPin implements DigitalInput,
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void waitForValue(boolean value)
|
||||
throws InterruptedException, ConnectionLostException {
|
||||
checkState();
|
||||
|
||||
18
IOIOLib/src/ioio/lib/impl/DigitalOutputImpl.java
Executable file → Normal file
18
IOIOLib/src/ioio/lib/impl/DigitalOutputImpl.java
Executable file → Normal file
@@ -33,18 +33,24 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DigitalOutputImpl extends AbstractPin implements DigitalOutput {
|
||||
DigitalOutputImpl(IOIOImpl ioio, int pin) throws ConnectionLostException {
|
||||
class DigitalOutputImpl extends AbstractPin implements DigitalOutput {
|
||||
boolean value_;
|
||||
|
||||
DigitalOutputImpl(IOIOImpl ioio, int pin, boolean startValue) throws ConnectionLostException {
|
||||
super(ioio, pin);
|
||||
value_ = startValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void write(boolean val) throws ConnectionLostException {
|
||||
checkState();
|
||||
try {
|
||||
ioio_.protocol_.setDigitalOutLevel(pinNum_, val);
|
||||
} catch (IOException e) {
|
||||
throw new ConnectionLostException(e);
|
||||
if (val != value_) {
|
||||
try {
|
||||
ioio_.protocol_.setDigitalOutLevel(pinNum_, val);
|
||||
value_ = val;
|
||||
} catch (IOException e) {
|
||||
throw new ConnectionLostException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
IOIOLib/src/ioio/lib/impl/FlowControlledOutputStream.java
Executable file → Normal file
9
IOIOLib/src/ioio/lib/impl/FlowControlledOutputStream.java
Executable file → Normal file
@@ -33,7 +33,7 @@ import java.io.OutputStream;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
public class FlowControlledOutputStream extends OutputStream {
|
||||
class FlowControlledOutputStream extends OutputStream {
|
||||
interface Sender {
|
||||
void send(byte[] data, int size);
|
||||
}
|
||||
@@ -91,15 +91,14 @@ public class FlowControlledOutputStream extends OutputStream {
|
||||
|
||||
@Override
|
||||
synchronized public void close() {
|
||||
if (closed_) {
|
||||
return;
|
||||
}
|
||||
closed_ = true;
|
||||
notifyAll();
|
||||
thread_.interrupt();
|
||||
}
|
||||
|
||||
synchronized public void kill() {
|
||||
thread_.interrupt();
|
||||
}
|
||||
|
||||
class FlushThread extends Thread {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/FlowControlledPacketSender.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/FlowControlledPacketSender.java
Executable file → Normal file
@@ -32,7 +32,7 @@ import java.io.IOException;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
public class FlowControlledPacketSender {
|
||||
class FlowControlledPacketSender {
|
||||
interface Packet {
|
||||
int getSize();
|
||||
}
|
||||
|
||||
1354
IOIOLib/src/ioio/lib/impl/IOIOImpl.java
Executable file → Normal file
1354
IOIOLib/src/ioio/lib/impl/IOIOImpl.java
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
1655
IOIOLib/src/ioio/lib/impl/IOIOProtocol.java
Executable file → Normal file
1655
IOIOLib/src/ioio/lib/impl/IOIOProtocol.java
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
2
IOIOLib/src/ioio/lib/impl/IcspMasterImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/IcspMasterImpl.java
Executable file → Normal file
@@ -36,7 +36,7 @@ import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class IcspMasterImpl extends AbstractResource implements IcspMaster,
|
||||
class IcspMasterImpl extends AbstractResource implements IcspMaster,
|
||||
DataModuleListener {
|
||||
private Queue<Integer> resultQueue_ = new LinkedList<Integer>();
|
||||
private int rxRemaining_ = 0;
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/IncapImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/IncapImpl.java
Executable file → Normal file
@@ -7,7 +7,7 @@ import ioio.lib.impl.IncomingState.DataModuleListener;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class IncapImpl extends AbstractPin implements DataModuleListener,
|
||||
class IncapImpl extends AbstractPin implements DataModuleListener,
|
||||
PulseInput {
|
||||
private static final int MAX_QUEUE_LEN = 32;
|
||||
private final PulseMode mode_;
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/IncomingState.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/IncomingState.java
Executable file → Normal file
@@ -38,7 +38,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class IncomingState implements IncomingHandler {
|
||||
class IncomingState implements IncomingHandler {
|
||||
enum ConnectionState {
|
||||
INIT, ESTABLISHED, CONNECTED, DISCONNECTED, UNSUPPORTED_IID
|
||||
}
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/ModuleAllocator.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/ModuleAllocator.java
Executable file → Normal file
@@ -44,7 +44,7 @@ import java.util.TreeSet;
|
||||
*
|
||||
* @author birmiwal
|
||||
*/
|
||||
public class ModuleAllocator {
|
||||
class ModuleAllocator {
|
||||
private final Set<Integer> availableModuleIds_;
|
||||
private final Set<Integer> allocatedModuleIds_;
|
||||
private final String name_;
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/PinFunctionMap.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/PinFunctionMap.java
Executable file → Normal file
@@ -29,7 +29,7 @@
|
||||
package ioio.lib.impl;
|
||||
|
||||
|
||||
public class PinFunctionMap {
|
||||
class PinFunctionMap {
|
||||
private static final boolean[] PERIPHERAL_OUT = new boolean[] { true,
|
||||
false, false, true, true, true, true, true, false, false, true,
|
||||
true, true, true, true, false, false, false, false, false, false,
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/PwmImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/PwmImpl.java
Executable file → Normal file
@@ -33,7 +33,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PwmImpl extends AbstractResource implements PwmOutput {
|
||||
class PwmImpl extends AbstractResource implements PwmOutput {
|
||||
private final int pwmNum_;
|
||||
private final int pinNum_;
|
||||
private final float baseUs_;
|
||||
|
||||
56
IOIOLib/src/ioio/lib/impl/QueueInputStream.java
Executable file → Normal file
56
IOIOLib/src/ioio/lib/impl/QueueInputStream.java
Executable file → Normal file
@@ -35,26 +35,60 @@ import java.util.concurrent.ArrayBlockingQueue;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class QueueInputStream extends InputStream {
|
||||
class QueueInputStream extends InputStream {
|
||||
private enum State {
|
||||
OPEN, CLOSED, KILLED
|
||||
};
|
||||
|
||||
private final Queue<Byte> queue_ = new ArrayBlockingQueue<Byte>(
|
||||
Constants.BUFFER_SIZE);
|
||||
private boolean closed_ = false;
|
||||
private State state_ = State.OPEN;
|
||||
|
||||
@Override
|
||||
synchronized public int read() throws IOException {
|
||||
try {
|
||||
while (!closed_ && queue_.isEmpty()) {
|
||||
while (state_ == State.OPEN && queue_.isEmpty()) {
|
||||
wait();
|
||||
}
|
||||
if (closed_) {
|
||||
if (state_ == State.KILLED) {
|
||||
throw new IOException("Stream has been closed");
|
||||
}
|
||||
if (state_ == State.CLOSED && queue_.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
return ((int) queue_.remove()) & 0xFF;
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException("Interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
while (state_ == State.OPEN && queue_.isEmpty()) {
|
||||
wait();
|
||||
}
|
||||
if (state_ == State.KILLED) {
|
||||
throw new IOException("Stream has been closed");
|
||||
}
|
||||
if (state_ == State.CLOSED && queue_.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
if (len > queue_.size()) {
|
||||
len = queue_.size();
|
||||
}
|
||||
for (int i = 0; i < len; ++i) {
|
||||
b[off++] = queue_.remove();
|
||||
}
|
||||
return len;
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException("Interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
synchronized public void write(byte[] data, int size) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (queue_.size() == Constants.BUFFER_SIZE) {
|
||||
@@ -73,7 +107,19 @@ public class QueueInputStream extends InputStream {
|
||||
|
||||
@Override
|
||||
synchronized public void close() {
|
||||
closed_ = true;
|
||||
if (state_ != State.OPEN) {
|
||||
return;
|
||||
}
|
||||
state_ = State.CLOSED;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
synchronized public void kill() {
|
||||
if (state_ != State.OPEN) {
|
||||
return;
|
||||
}
|
||||
state_ = State.KILLED;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
19
IOIOLib/src/ioio/lib/impl/SocketIOIOConnection.java
Executable file → Normal file
19
IOIOLib/src/ioio/lib/impl/SocketIOIOConnection.java
Executable file → Normal file
@@ -41,6 +41,7 @@ import java.net.SocketException;
|
||||
import android.util.Log;
|
||||
|
||||
public class SocketIOIOConnection implements IOIOConnection {
|
||||
private static final String TAG = "SocketIOIOConnection";
|
||||
private final int port_;
|
||||
private ServerSocket server_ = null;
|
||||
private Socket socket_ = null;
|
||||
@@ -48,7 +49,7 @@ public class SocketIOIOConnection implements IOIOConnection {
|
||||
private boolean server_owned_by_connect_ = true;
|
||||
private boolean socket_owned_by_connect_ = true;
|
||||
|
||||
public SocketIOIOConnection(Integer port) {
|
||||
public SocketIOIOConnection(int port) {
|
||||
port_ = port;
|
||||
}
|
||||
|
||||
@@ -59,13 +60,13 @@ public class SocketIOIOConnection implements IOIOConnection {
|
||||
if (disconnect_) {
|
||||
throw new ConnectionLostException();
|
||||
}
|
||||
Log.d("SocketIOIOConnection", "Creating server socket");
|
||||
Log.v(TAG, "Creating server socket");
|
||||
server_ = new ServerSocket(port_);
|
||||
server_owned_by_connect_ = false;
|
||||
}
|
||||
Log.d("SocketIOIOConnection", "Waiting for TCP connection");
|
||||
Log.v(TAG, "Waiting for TCP connection");
|
||||
socket_ = server_.accept();
|
||||
Log.d("SocketIOIOConnection", "TCP connected");
|
||||
Log.v(TAG, "TCP connected");
|
||||
synchronized (this) {
|
||||
if (disconnect_) {
|
||||
socket_.close();
|
||||
@@ -80,18 +81,18 @@ public class SocketIOIOConnection implements IOIOConnection {
|
||||
try {
|
||||
server_.close();
|
||||
} catch (IOException e1) {
|
||||
Log.e("SocketIOIOConnection", "Unexpected exception", e1);
|
||||
Log.e(TAG, "Unexpected exception", e1);
|
||||
}
|
||||
}
|
||||
if (socket_owned_by_connect_ && socket_ != null) {
|
||||
try {
|
||||
socket_.close();
|
||||
} catch (IOException e1) {
|
||||
Log.e("SocketIOIOConnection", "Unexpected exception", e1);
|
||||
Log.e(TAG, "Unexpected exception", e1);
|
||||
}
|
||||
}
|
||||
if (e instanceof SocketException && e.getMessage().equals("Permission denied")) {
|
||||
Log.e("SocketIOIOConnection", "Did you forget to declare uses-permission of android.permission.INTERNET?");
|
||||
Log.e(TAG, "Did you forget to declare uses-permission of android.permission.INTERNET?");
|
||||
}
|
||||
throw new ConnectionLostException(e);
|
||||
}
|
||||
@@ -103,13 +104,13 @@ public class SocketIOIOConnection implements IOIOConnection {
|
||||
if (disconnect_) {
|
||||
return;
|
||||
}
|
||||
Log.d("SocketIOIOConnection", "Client initiated disconnect");
|
||||
Log.v(TAG, "Client initiated disconnect");
|
||||
disconnect_ = true;
|
||||
if (!server_owned_by_connect_) {
|
||||
try {
|
||||
server_.close();
|
||||
} catch (IOException e1) {
|
||||
Log.e("SocketIOIOConnection", "Unexpected exception", e1);
|
||||
Log.e(TAG, "Unexpected exception", e1);
|
||||
}
|
||||
}
|
||||
if (!socket_owned_by_connect_) {
|
||||
|
||||
63
IOIOLib/src/ioio/lib/impl/SocketIOIOConnectionBootstrap.java
Normal file
63
IOIOLib/src/ioio/lib/impl/SocketIOIOConnectionBootstrap.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.impl;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class SocketIOIOConnectionBootstrap implements IOIOConnectionBootstrap {
|
||||
/** The TCP port used for communicating with the IOIO board. */
|
||||
public static final int IOIO_PORT = 4545;
|
||||
|
||||
@Override
|
||||
public void getFactories(Collection<IOIOConnectionFactory> result) {
|
||||
result.add(new IOIOConnectionFactory() {
|
||||
private Integer port_ = new Integer(IOIO_PORT);
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return SocketIOIOConnection.class.getCanonicalName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getExtra() {
|
||||
return port_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOIOConnection createConnection() {
|
||||
return new SocketIOIOConnection(IOIO_PORT);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
2
IOIOLib/src/ioio/lib/impl/SpiMasterImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/SpiMasterImpl.java
Executable file → Normal file
@@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class SpiMasterImpl extends AbstractResource implements SpiMaster,
|
||||
class SpiMasterImpl extends AbstractResource implements SpiMaster,
|
||||
DataModuleListener, Sender {
|
||||
public class SpiResult implements Result {
|
||||
boolean ready_;
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/TwiMasterImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/TwiMasterImpl.java
Executable file → Normal file
@@ -40,7 +40,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class TwiMasterImpl extends AbstractResource implements TwiMaster,
|
||||
class TwiMasterImpl extends AbstractResource implements TwiMaster,
|
||||
DataModuleListener, Sender {
|
||||
class TwiResult implements Result {
|
||||
boolean ready_ = false;
|
||||
|
||||
5
IOIOLib/src/ioio/lib/impl/UartImpl.java
Executable file → Normal file
5
IOIOLib/src/ioio/lib/impl/UartImpl.java
Executable file → Normal file
@@ -40,7 +40,7 @@ import java.io.OutputStream;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class UartImpl extends AbstractResource implements DataModuleListener, Sender, Uart {
|
||||
class UartImpl extends AbstractResource implements DataModuleListener, Sender, Uart {
|
||||
private static final int MAX_PACKET = 64;
|
||||
|
||||
private final int uartNum_;
|
||||
@@ -87,7 +87,8 @@ public class UartImpl extends AbstractResource implements DataModuleListener, Se
|
||||
@Override
|
||||
synchronized public void disconnected() {
|
||||
super.disconnected();
|
||||
outgoing_.kill();
|
||||
incoming_.kill();
|
||||
outgoing_.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
41
IOIOLib/src/ioio/lib/spi/IOIOConnectionBootstrap.java
Normal file
41
IOIOLib/src/ioio/lib/spi/IOIOConnectionBootstrap.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.spi;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Implementing class must have a default constructor. The default constructor
|
||||
* must throw a NoRuntimeSupportException in case the required libraries for
|
||||
* implementing the connections are not available in run-time.
|
||||
*/
|
||||
public interface IOIOConnectionBootstrap {
|
||||
public void getFactories(Collection<IOIOConnectionFactory> result);
|
||||
}
|
||||
21
IOIOLib/src/ioio/lib/spi/IOIOConnectionFactory.java
Normal file
21
IOIOLib/src/ioio/lib/spi/IOIOConnectionFactory.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package ioio.lib.spi;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
|
||||
public interface IOIOConnectionFactory {
|
||||
/**
|
||||
* A unique name of the connection type. Typically a fully-qualified
|
||||
* name of the connection class.
|
||||
*/
|
||||
public String getType();
|
||||
|
||||
/**
|
||||
* Extra information on the connection. This is specific to the
|
||||
* connection type. For example, for a Bluetooth connection, this is an
|
||||
* array containing the name and the Bluetooth address of the remote
|
||||
* IOIO.
|
||||
*/
|
||||
public Object getExtra();
|
||||
|
||||
public IOIOConnection createConnection();
|
||||
}
|
||||
9
IOIOLib/src/ioio/lib/spi/NoRuntimeSupportException.java
Normal file
9
IOIOLib/src/ioio/lib/spi/NoRuntimeSupportException.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package ioio.lib.spi;
|
||||
|
||||
public class NoRuntimeSupportException extends Exception {
|
||||
private static final long serialVersionUID = -6559208663699429514L;
|
||||
|
||||
public NoRuntimeSupportException(String desc) {
|
||||
super(desc);
|
||||
}
|
||||
}
|
||||
664
IOIOLib/src/ioio/lib/util/AbstractIOIOActivity.java
Executable file → Normal file
664
IOIOLib/src/ioio/lib/util/AbstractIOIOActivity.java
Executable file → Normal file
@@ -1,295 +1,369 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.api.exception.IncompatibilityException;
|
||||
import ioio.lib.util.IOIOConnectionDiscovery.IOIOConnectionSpec;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A convenience class for easy creation of IOIO-based applications.
|
||||
*
|
||||
* It is used by creating a concrete Activity in your application, which extends
|
||||
* this class. This class then takes care of proper creation and abortion of the
|
||||
* IOIO connection and of a dedicated thread for IOIO communication.
|
||||
*
|
||||
* In the basic usage the client should extend this class and implement
|
||||
* {@link #createIOIOThread()}, which should return an implementation of the
|
||||
* {@link IOIOThread} abstract class. In this implementation, the client
|
||||
* implements the {@link IOIOThread#setup()} method, which gets called as soon
|
||||
* as communication with the IOIO is established, and the {@link IOIOThread
|
||||
* #loop()} method, which gets called repetitively as long as the IOIO is
|
||||
* connected. Both methods should access the {@link IOIOThread#ioio_} field for
|
||||
* controlling the IOIO.
|
||||
*
|
||||
* In addition, the {@link IOIOThread#disconnected()} method may be overridden
|
||||
* in order to execute logic as soon as a disconnection occurs for whichever
|
||||
* reason. The {@link IOIOThread#incompatible()} method may be overridden in
|
||||
* order to take action in case where a IOIO whose firmware is incompatible with
|
||||
* the IOIOLib version that application is built with.
|
||||
*
|
||||
* In a more advanced use case, more than one IOIO is available. In this case, a
|
||||
* thread will be created for each IOIO, whose semantics are as defined above.
|
||||
* If the client needs to be able to distinguish between them, it is possible to
|
||||
* override {@link #createIOIOThread(String, Object[])} instead of
|
||||
* {@link #createIOIOThread()}. The first argument provided will contain the
|
||||
* connection class name, such as ioio.lib.impl.SocketIOIOConnection for a
|
||||
* connection established over a TCP socket (which is used over ADB). The second
|
||||
* argument will contain information specific to the connection type. For
|
||||
* example, in the case of SocketIOIOConnection, the array will contain an
|
||||
* {@link Integer} representing the local port number.
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractIOIOActivity extends Activity {
|
||||
private static final String TAG = "AbstractIOIOActivity";
|
||||
private IOIOConnectionSpec currentSpec_;
|
||||
private Collection<IOIOThread> threads_ = new LinkedList<IOIOThread>();
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onResume() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
createAllThreads();
|
||||
startAllThreads();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onPause() if
|
||||
* overloaded. It takes care of disconnecting from the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
abortAllThreads();
|
||||
try {
|
||||
joinAllThreads();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method by returning a concrete subclass
|
||||
* of {@link IOIOThread}. <code>null</code> may be returned if the client
|
||||
* is not interested to connect a thread for this IOIO. In multi-IOIO
|
||||
* scenarios, where you want to identify which IOIO the thread is for,
|
||||
* consider using {@link #createIOIOThread()} instead.
|
||||
*
|
||||
* @return An implementation of {@link IOIOThread}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOThread createIOIOThread() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method by returning a concrete subclass
|
||||
* of {@link IOIOThread}. This overload is useful in multi-IOIO scenarios,
|
||||
* where you want to identify which IOIO the thread is for. The provided
|
||||
* arguments should provide enough information to be unique per connection.
|
||||
* <code>null</code> may be returned if the client is not interested to
|
||||
* connect a thread for this IOIO. This can be used in order to filter out
|
||||
* unwanted connections, for example if the application is only intended for
|
||||
* wireless connection, any wired connection attempts may be rejected, thus
|
||||
* saving resources used for listening for incoming wired connections.
|
||||
*
|
||||
* @param connectionClass
|
||||
* The fully-qualified name of the connection class used to
|
||||
* connect to the IOIO.
|
||||
* @param connectionArgs
|
||||
* A list of arguments passed to the constructor of the
|
||||
* connection class. Should provide information that enables
|
||||
* distinguishing between different IOIO instances using the same
|
||||
* connection class.
|
||||
*
|
||||
* @return An implementation of {@link IOIOThread}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOThread createIOIOThread(String connectionClass,
|
||||
Object[] connectionArgs) {
|
||||
return createIOIOThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstract class, which facilitates a thread dedicated for communication
|
||||
* with a single physical IOIO device.
|
||||
*/
|
||||
protected abstract class IOIOThread extends Thread {
|
||||
/** Subclasses should use this field for controlling the IOIO. */
|
||||
protected IOIO ioio_;
|
||||
private boolean abort_ = false;
|
||||
private boolean connected_ = true;
|
||||
private final IOIOConnectionSpec spec_ = currentSpec_;
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done once as soon as IOIO communication is established. Typically,
|
||||
* this will include opening pins and modules using the openXXX()
|
||||
* methods of the {@link #ioio_} field.
|
||||
*/
|
||||
protected void setup() throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done repetitively as long as IOIO communication persists.
|
||||
* Typically, this will be the main logic of the application, processing
|
||||
* inputs and producing outputs.
|
||||
*/
|
||||
protected void loop() throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
sleep(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done once as soon as IOIO communication is lost or closed.
|
||||
* Typically, this will include GUI changes corresponding to the change.
|
||||
* This method will only be called if setup() has been called. The
|
||||
* {@link #ioio_} member must not be used from within this method.
|
||||
*/
|
||||
protected void disconnected() throws InterruptedException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done if an incompatible IOIO firmware is detected. The
|
||||
* {@link #ioio_} member must not be used from within this method. This
|
||||
* method will only be called once, until a compatible IOIO is connected
|
||||
* (i.e. {@link #setup()} gets called).
|
||||
*/
|
||||
protected void incompatible() {
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
@Override
|
||||
public final void run() {
|
||||
super.run();
|
||||
Looper.prepare();
|
||||
while (true) {
|
||||
try {
|
||||
synchronized (this) {
|
||||
if (abort_) {
|
||||
break;
|
||||
}
|
||||
ioio_ = IOIOFactory.create(spec_.className, spec_.args);
|
||||
}
|
||||
ioio_.waitForConnect();
|
||||
connected_ = true;
|
||||
setup();
|
||||
while (!abort_) {
|
||||
loop();
|
||||
}
|
||||
ioio_.disconnect();
|
||||
} catch (ConnectionLostException e) {
|
||||
if (abort_) {
|
||||
break;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
ioio_.disconnect();
|
||||
break;
|
||||
} catch (IncompatibilityException e) {
|
||||
Log.e(TAG, "Incompatible IOIO firmware", e);
|
||||
incompatible();
|
||||
// nothing to do - just wait until physical disconnection
|
||||
try {
|
||||
ioio_.waitForDisconnect();
|
||||
} catch (InterruptedException e1) {
|
||||
ioio_.disconnect();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unexpected exception caught", e);
|
||||
ioio_.disconnect();
|
||||
break;
|
||||
} finally {
|
||||
try {
|
||||
if (ioio_ != null) {
|
||||
ioio_.waitForDisconnect();
|
||||
if (connected_) {
|
||||
disconnected();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
public synchronized final void abort() {
|
||||
abort_ = true;
|
||||
if (ioio_ != null) {
|
||||
ioio_.disconnect();
|
||||
}
|
||||
if (connected_) {
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void abortAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.abort();
|
||||
}
|
||||
}
|
||||
|
||||
private void joinAllThreads() throws InterruptedException {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
private void createAllThreads() {
|
||||
threads_.clear();
|
||||
Collection<IOIOConnectionSpec> specs = getConnectionSpecs();
|
||||
for (IOIOConnectionSpec spec : specs) {
|
||||
currentSpec_ = spec;
|
||||
IOIOThread thread = createIOIOThread(spec.className, spec.args);
|
||||
if (thread != null) {
|
||||
threads_.add(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<IOIOConnectionSpec> getConnectionSpecs() {
|
||||
Collection<IOIOConnectionSpec> result = new LinkedList<IOIOConnectionSpec>();
|
||||
addConnectionSpecs("ioio.lib.util.SocketIOIOConnectionDiscovery",
|
||||
result);
|
||||
addConnectionSpecs(
|
||||
"ioio.lib.bluetooth.BluetoothIOIOConnectionDiscovery", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addConnectionSpecs(String discoveryClassName,
|
||||
Collection<IOIOConnectionSpec> result) {
|
||||
try {
|
||||
Class<?> cls = Class.forName(discoveryClassName);
|
||||
IOIOConnectionDiscovery discovery = (IOIOConnectionDiscovery) cls
|
||||
.newInstance();
|
||||
discovery.getSpecs(result);
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.d(TAG, "Discovery class not found: " + discoveryClassName
|
||||
+ ". Not adding.");
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG,
|
||||
"Exception caught while discovering connections - not adding connections of class "
|
||||
+ discoveryClassName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.api.exception.IncompatibilityException;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
import ioio.lib.util.android.ContextWrapperDependent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A convenience class for easy creation of IOIO-based applications.
|
||||
*
|
||||
* It is used by creating a concrete Activity in your application, which extends
|
||||
* this class. This class then takes care of proper creation and abortion of the
|
||||
* IOIO connection and of a dedicated thread for IOIO communication.
|
||||
*
|
||||
* In the basic usage the client should extend this class and implement
|
||||
* {@link #createIOIOThread()}, which should return an implementation of the
|
||||
* {@link AbstractIOIOActivity.IOIOThread} abstract class. In this
|
||||
* implementation, the client implements the
|
||||
* {@link AbstractIOIOActivity.IOIOThread#setup()} method, which gets called as
|
||||
* soon as communication with the IOIO is established, and the
|
||||
* {@link AbstractIOIOActivity.IOIOThread#loop()} method, which gets called
|
||||
* repetitively as long as the IOIO is connected. Both methods should access the
|
||||
* {@link AbstractIOIOActivity.IOIOThread#ioio_} field for controlling the IOIO.
|
||||
*
|
||||
* In addition, the {@link AbstractIOIOActivity.IOIOThread#disconnected()}
|
||||
* method may be overridden in order to execute logic as soon as a disconnection
|
||||
* occurs for whichever reason. The
|
||||
* {@link AbstractIOIOActivity.IOIOThread#incompatible()} method may be
|
||||
* overridden in order to take action in case where a IOIO whose firmware is
|
||||
* incompatible with the IOIOLib version that application is built with.
|
||||
*
|
||||
* In a more advanced use case, more than one IOIO is available. In this case, a
|
||||
* thread will be created for each IOIO, whose semantics are as defined above.
|
||||
* If the client needs to be able to distinguish between them, it is possible to
|
||||
* override {@link #createIOIOThread(String, Object)} instead of
|
||||
* {@link #createIOIOThread()}. The first argument provided will contain the
|
||||
* connection class name, such as ioio.lib.impl.SocketIOIOConnection for a
|
||||
* connection established over a TCP socket (which is used over ADB). The second
|
||||
* argument will contain information specific to the connection type. For
|
||||
* example, in the case of SocketIOIOConnection, the second argument will
|
||||
* contain an {@link Integer} representing the local port number.
|
||||
*
|
||||
* @deprecated Please use {@link ioio.lib.util.android.IOIOActivity} instead.
|
||||
*/
|
||||
public abstract class AbstractIOIOActivity extends Activity {
|
||||
private static final String TAG = "AbstractIOIOActivity";
|
||||
|
||||
static {
|
||||
IOIOConnectionRegistry
|
||||
.addBootstraps(new String[] {
|
||||
"ioio.lib.android.accessory.AccessoryConnectionBootstrap",
|
||||
"ioio.lib.android.bluetooth.BluetoothIOIOConnectionBootstrap" });
|
||||
}
|
||||
|
||||
private Collection<IOIOThread> threads_ = new LinkedList<IOIOThread>();
|
||||
private Collection<IOIOConnectionBootstrap> bootstraps_ = IOIOConnectionRegistry
|
||||
.getBootstraps();
|
||||
private IOIOConnectionFactory currentConnectionFactory_;
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onCreate() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).onCreate(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onDestroy() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).onDestroy();
|
||||
}
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStart() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).open();
|
||||
}
|
||||
}
|
||||
createAllThreads();
|
||||
startAllThreads();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStop() if overloaded.
|
||||
* It takes care of disconnecting from the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onStop() {
|
||||
abortAllThreads();
|
||||
try {
|
||||
joinAllThreads();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).close();
|
||||
}
|
||||
}
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must either implement this method or its other overload by
|
||||
* returning a concrete subclass of {@link IOIOThread}. <code>null</code>
|
||||
* may be returned if the client is not interested to create a thread for
|
||||
* this IOIO. In multi-IOIO scenarios, where you want to identify which IOIO
|
||||
* the thread is for, consider using {@link #createIOIOThread()} instead.
|
||||
*
|
||||
* @return An implementation of {@link IOIOThread}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOThread createIOIOThread() {
|
||||
throw new RuntimeException(
|
||||
"Client must override on of the createIOIOThread overloads!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method by returning a concrete subclass
|
||||
* of {@link IOIOThread}. This overload is useful in multi-IOIO scenarios,
|
||||
* where you want to identify which IOIO the thread is for. The provided
|
||||
* arguments should provide enough information to be unique per connection.
|
||||
* <code>null</code> may be returned if the client is not interested to
|
||||
* connect a thread for this IOIO. This can be used in order to filter out
|
||||
* unwanted connections, for example if the application is only intended for
|
||||
* wireless connection, any wired connection attempts may be rejected, thus
|
||||
* saving resources used for listening for incoming wired connections.
|
||||
*
|
||||
* @param connectionType
|
||||
* A unique name of the connection type. Typically, the
|
||||
* fully-qualified name of the connection class used to connect
|
||||
* to the IOIO.
|
||||
* @param extra
|
||||
* A connection-type-specific object with extra information on
|
||||
* the specific connection. Should provide information that
|
||||
* enables distinguishing between different IOIO instances using
|
||||
* the same connection class. For example, a Bluetooth connection
|
||||
* type, might have the remote IOIO's Bluetooth name as extra.
|
||||
*
|
||||
* @return An implementation of {@link IOIOThread}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOThread createIOIOThread(String connectionType, Object extra) {
|
||||
return createIOIOThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstract class, which facilitates a thread dedicated for communication
|
||||
* with a single physical IOIO device.
|
||||
*/
|
||||
protected abstract class IOIOThread extends Thread {
|
||||
/** Subclasses should use this field for controlling the IOIO. */
|
||||
protected IOIO ioio_;
|
||||
private boolean abort_ = false;
|
||||
private boolean connected_ = true;
|
||||
private final IOIOConnectionFactory connectionFactory_ = currentConnectionFactory_;
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done once as soon as IOIO communication is established. Typically,
|
||||
* this will include opening pins and modules using the openXXX()
|
||||
* methods of the {@link #ioio_} field.
|
||||
*/
|
||||
protected void setup() throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done repetitively as long as IOIO communication persists.
|
||||
* Typically, this will be the main logic of the application, processing
|
||||
* inputs and producing outputs.
|
||||
*/
|
||||
protected void loop() throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
sleep(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done once as soon as IOIO communication is lost or closed.
|
||||
* Typically, this will include GUI changes corresponding to the change.
|
||||
* This method will only be called if setup() has been called. The
|
||||
* {@link #ioio_} member must not be used from within this method. This
|
||||
* method should not block for long, since it may cause an ANR.
|
||||
*/
|
||||
protected void disconnected() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done if an incompatible IOIO firmware is detected. The
|
||||
* {@link #ioio_} member must not be used from within this method. This
|
||||
* method will only be called once, until a compatible IOIO is connected
|
||||
* (i.e. {@link #setup()} gets called).
|
||||
*/
|
||||
protected void incompatible() {
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
@Override
|
||||
public final void run() {
|
||||
super.run();
|
||||
while (!abort_) {
|
||||
try {
|
||||
synchronized (this) {
|
||||
if (abort_) {
|
||||
break;
|
||||
}
|
||||
ioio_ = IOIOFactory.create(connectionFactory_
|
||||
.createConnection());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to create IOIO, aborting IOIOThread!");
|
||||
return;
|
||||
}
|
||||
// if we got here, we have a ioio_!
|
||||
try {
|
||||
ioio_.waitForConnect();
|
||||
connected_ = true;
|
||||
setup();
|
||||
while (!abort_) {
|
||||
loop();
|
||||
}
|
||||
} catch (ConnectionLostException e) {
|
||||
} catch (InterruptedException e) {
|
||||
ioio_.disconnect();
|
||||
} catch (IncompatibilityException e) {
|
||||
Log.e(TAG, "Incompatible IOIO firmware", e);
|
||||
incompatible();
|
||||
// nothing to do - just wait until physical disconnection
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unexpected exception caught", e);
|
||||
ioio_.disconnect();
|
||||
break;
|
||||
} finally {
|
||||
try {
|
||||
ioio_.waitForDisconnect();
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
synchronized (this) {
|
||||
ioio_ = null;
|
||||
}
|
||||
if (connected_) {
|
||||
disconnected();
|
||||
connected_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "IOIOThread is exiting");
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
public synchronized final void abort() {
|
||||
abort_ = true;
|
||||
if (ioio_ != null) {
|
||||
ioio_.disconnect();
|
||||
}
|
||||
if (connected_) {
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void abortAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.abort();
|
||||
}
|
||||
}
|
||||
|
||||
private void joinAllThreads() throws InterruptedException {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
private void createAllThreads() {
|
||||
threads_.clear();
|
||||
Collection<IOIOConnectionFactory> factories = IOIOConnectionRegistry
|
||||
.getConnectionFactories();
|
||||
for (IOIOConnectionFactory factory : factories) {
|
||||
currentConnectionFactory_ = factory;
|
||||
IOIOThread thread = createIOIOThread(factory.getType(),
|
||||
factory.getExtra());
|
||||
if (thread != null) {
|
||||
threads_.add(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
48
IOIOLib/src/ioio/lib/util/BaseIOIOLooper.java
Normal file
48
IOIOLib/src/ioio/lib/util/BaseIOIOLooper.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A convenience implementation of {@link IOIOLooper}.
|
||||
*
|
||||
* This base class provides no-op implementations for all methods and provides
|
||||
* the {@link #ioio_} field for subclasses.
|
||||
*
|
||||
*/
|
||||
public class BaseIOIOLooper implements IOIOLooper {
|
||||
protected IOIO ioio_;
|
||||
|
||||
@Override
|
||||
public final void setup(IOIO ioio) throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
ioio_ = ioio;
|
||||
setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be called as soon as connection to the IOIO has been
|
||||
* established. Typically, this will include opening pins and modules using
|
||||
* the openXXX() methods of the {@link #ioio_} field.
|
||||
*
|
||||
* @throws ConnectionLostException
|
||||
* The connection to the IOIO has been lost.
|
||||
* @throws InterruptedException
|
||||
* The thread has been interrupted.
|
||||
*/
|
||||
protected void setup() throws ConnectionLostException, InterruptedException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loop() throws ConnectionLostException, InterruptedException {
|
||||
Thread.sleep(20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incompatible() {
|
||||
}
|
||||
}
|
||||
166
IOIOLib/src/ioio/lib/util/IOIOApplicationHelper.java
Normal file
166
IOIOLib/src/ioio/lib/util/IOIOApplicationHelper.java
Normal file
@@ -0,0 +1,166 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.api.exception.IncompatibilityException;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A helper class for creating different kinds of IOIO based applications.
|
||||
*
|
||||
* This class implements a common life-cycle for applications interacting with
|
||||
* IOIO devices.
|
||||
* <p>
|
||||
* When the application starts, call {@link #start()}, which will in turn
|
||||
* attempt to create a thread for each possible IOIO connection channel. Each
|
||||
* thread will have a respective {@link IOIOLooper}, which the client provides,
|
||||
* through which the client gets context for working with the IOIO.
|
||||
* <p>
|
||||
* When the application exits, call {@link #stop()}, which will disconnect all
|
||||
* open connections and will abort and join all the threads.
|
||||
*
|
||||
*/
|
||||
public class IOIOApplicationHelper {
|
||||
/**
|
||||
* An abstract class, which facilitates a thread dedicated for communication
|
||||
* with a single physical IOIO device.
|
||||
*/
|
||||
static private class IOIOThread extends Thread {
|
||||
protected IOIO ioio_;
|
||||
private boolean abort_ = false;
|
||||
private boolean connected_ = true;
|
||||
private final IOIOLooper looper_;
|
||||
private final IOIOConnectionFactory connectionFactory_;
|
||||
|
||||
IOIOThread(IOIOLooper looper, IOIOConnectionFactory factory) {
|
||||
looper_ = looper;
|
||||
connectionFactory_ = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
super.run();
|
||||
while (!abort_) {
|
||||
try {
|
||||
synchronized (this) {
|
||||
if (abort_) {
|
||||
break;
|
||||
}
|
||||
ioio_ = IOIOFactory.create(connectionFactory_
|
||||
.createConnection());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to create IOIO, aborting IOIOThread!");
|
||||
return;
|
||||
}
|
||||
// if we got here, we have a ioio_!
|
||||
try {
|
||||
ioio_.waitForConnect();
|
||||
connected_ = true;
|
||||
looper_.setup(ioio_);
|
||||
while (!abort_ && ioio_.getState() == IOIO.State.CONNECTED) {
|
||||
looper_.loop();
|
||||
}
|
||||
} catch (ConnectionLostException e) {
|
||||
} catch (InterruptedException e) {
|
||||
ioio_.disconnect();
|
||||
} catch (IncompatibilityException e) {
|
||||
Log.e(TAG, "Incompatible IOIO firmware", e);
|
||||
looper_.incompatible();
|
||||
// nothing to do - just wait until physical
|
||||
// disconnection
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unexpected exception caught", e);
|
||||
ioio_.disconnect();
|
||||
break;
|
||||
} finally {
|
||||
try {
|
||||
ioio_.waitForDisconnect();
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
synchronized (this) {
|
||||
ioio_ = null;
|
||||
}
|
||||
if (connected_) {
|
||||
looper_.disconnected();
|
||||
connected_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "IOIOThread is exiting");
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
public synchronized final void abort() {
|
||||
abort_ = true;
|
||||
if (ioio_ != null) {
|
||||
ioio_.disconnect();
|
||||
}
|
||||
if (connected_) {
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static final String TAG = "IOIOAndroidApplicationHelper";
|
||||
protected final IOIOLooperProvider looperProvider_;
|
||||
private Collection<IOIOThread> threads_ = new LinkedList<IOIOThread>();
|
||||
protected Collection<IOIOConnectionBootstrap> bootstraps_ = IOIOConnectionRegistry
|
||||
.getBootstraps();
|
||||
|
||||
public IOIOApplicationHelper(IOIOLooperProvider provider) {
|
||||
looperProvider_ = provider;
|
||||
}
|
||||
|
||||
protected void abortAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.abort();
|
||||
}
|
||||
}
|
||||
|
||||
protected void joinAllThreads() throws InterruptedException {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
protected void createAllThreads() {
|
||||
threads_.clear();
|
||||
Collection<IOIOConnectionFactory> factories = IOIOConnectionRegistry
|
||||
.getConnectionFactories();
|
||||
for (IOIOConnectionFactory factory : factories) {
|
||||
IOIOLooper looper = looperProvider_.createIOIOLooper(
|
||||
factory.getType(), factory.getExtra());
|
||||
if (looper != null) {
|
||||
threads_.add(new IOIOThread(looper, factory));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void startAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
createAllThreads();
|
||||
startAllThreads();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
abortAllThreads();
|
||||
try {
|
||||
joinAllThreads();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface IOIOConnectionDiscovery {
|
||||
public static class IOIOConnectionSpec {
|
||||
public final String className;
|
||||
public final Object[] args;
|
||||
|
||||
public IOIOConnectionSpec(String c, Object[] a) {
|
||||
className = c;
|
||||
args = a;
|
||||
}
|
||||
}
|
||||
|
||||
public void getSpecs(Collection<IOIOConnectionSpec> result);
|
||||
}
|
||||
133
IOIOLib/src/ioio/lib/util/IOIOConnectionRegistry.java
Normal file
133
IOIOLib/src/ioio/lib/util/IOIOConnectionRegistry.java
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A utility class for managing available connection types to IOIO.
|
||||
* <p>
|
||||
* <b>For advanced usage only!</b>
|
||||
* <p>
|
||||
* This class facilitates dynamic linkage and instantiation of different IOIO
|
||||
* connection types. {@link IOIOConnectionBootstrap} classes enable creation of
|
||||
* {@link IOIOConnectionFactory} instances, from which concrete
|
||||
* {@link IOIOConnection}s are created. The binding to
|
||||
* {@link IOIOConnectionBootstrap} is dynamic, thus enabling linkage to succeed
|
||||
* with or without those bootstraps. Likewise, during runtime, the absence of
|
||||
* bootstraps is handled gracefully.
|
||||
*
|
||||
* A typical usage will call {@link #addBootstraps(String[])} with a list of
|
||||
* class names to be sought from a static initializer block. It may then call
|
||||
* {@link #getBootstraps()} to obtain any bootstrap classes that are available
|
||||
* in runtime, in case the bootstrap classes themselves need some runtime
|
||||
* handling. Last, the {@link #getConnectionFactories()} will return a
|
||||
* collection of {@link IOIOConnectionFactory}, each representing one possible
|
||||
* communication channel to a IOIO.
|
||||
*
|
||||
*/
|
||||
public class IOIOConnectionRegistry {
|
||||
/**
|
||||
* Get all available connection specifications. This is a list of all
|
||||
* currently available communication channels in which a IOIO may be
|
||||
* available. The client typically passes elements of this collection to
|
||||
* {@link IOIOFactory#create(IOIOConnection)}, possibly after filtering based on the
|
||||
* specification's properties.
|
||||
*
|
||||
* @return A collection of specifications.
|
||||
*/
|
||||
public static Collection<IOIOConnectionFactory> getConnectionFactories() {
|
||||
Collection<IOIOConnectionFactory> result = new LinkedList<IOIOConnectionFactory>();
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
bootstrap.getFactories(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* For advanced usage only! Used for special runtime handling of bootstrap
|
||||
* classes.
|
||||
*
|
||||
* @return The bootstraps.
|
||||
*/
|
||||
public static Collection<IOIOConnectionBootstrap> getBootstraps() {
|
||||
return bootstraps_;
|
||||
}
|
||||
|
||||
/**
|
||||
* For advanced usage only! Add platform-specific connection bootstrap
|
||||
* classes. Call before calling {@link #getConnectionFactories()}.
|
||||
*/
|
||||
public static void addBootstraps(String[] classNames) {
|
||||
for (String className : classNames) {
|
||||
addBootstrap(className);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String TAG = "IOIOConnectionRegistry";
|
||||
|
||||
private static Collection<IOIOConnectionBootstrap> bootstraps_;
|
||||
|
||||
static {
|
||||
bootstraps_ = new LinkedList<IOIOConnectionBootstrap>();
|
||||
String[] classNames = new String[] { "ioio.lib.impl.SocketIOIOConnectionBootstrap" };
|
||||
addBootstraps(classNames);
|
||||
}
|
||||
|
||||
private static void addBootstrap(String className) {
|
||||
try {
|
||||
Class<? extends IOIOConnectionBootstrap> bootstrapClass = Class
|
||||
.forName(className).asSubclass(
|
||||
IOIOConnectionBootstrap.class);
|
||||
bootstraps_.add(bootstrapClass.newInstance());
|
||||
Log.d(TAG, "Successfully added bootstrap class: " + className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.d(TAG, "Bootstrap class not found: " + className
|
||||
+ ". Not adding.");
|
||||
} catch (RuntimeException e) {
|
||||
Log.e(TAG,
|
||||
"Runtime exception caught while attempting to initialize accessory connection factory",
|
||||
e);
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG,
|
||||
"Exception caught while attempting to initialize accessory connection factory",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
56
IOIOLib/src/ioio/lib/util/IOIOLooper.java
Normal file
56
IOIOLib/src/ioio/lib/util/IOIOLooper.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A handler implementing interaction with a single IOIO over a single
|
||||
* connection period. The interface utilizes a basic workflow for working with a
|
||||
* IOIO instance: as soon as a connection is established, {@link #setup(IOIO)}
|
||||
* will be called. Then, the {@link #loop()} method will be called repeatedly as
|
||||
* long as the connection is alive. Last, the {@link #disconnected()} method
|
||||
* will be called upon losing the connection (as result of physical
|
||||
* disconnection, closing the application, etc). In case a IOIO with an
|
||||
* incompatible firmware is encountered, {@link #incompatible()} will be called
|
||||
* instead of {@link #setup(IOIO)}, and the IOIO instance is entirely useless,
|
||||
* until eventually {@link #disconnected()} gets called.
|
||||
*
|
||||
*/
|
||||
public interface IOIOLooper {
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to be
|
||||
* done once as soon as IOIO communication is established.
|
||||
*/
|
||||
public abstract void setup(IOIO ioio) throws ConnectionLostException,
|
||||
InterruptedException;
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to be
|
||||
* done repetitively as long as IOIO communication persists. Typically, this
|
||||
* will be the main logic of the application, processing inputs and
|
||||
* producing outputs.
|
||||
*/
|
||||
public abstract void loop() throws ConnectionLostException,
|
||||
InterruptedException;
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to be
|
||||
* done once as soon as IOIO communication is lost or closed. Typically,
|
||||
* this will include GUI changes corresponding to the change. This method
|
||||
* will only be called if setup() has been called. The ioio argument passed
|
||||
* to {@link #setup(IOIO)} must not be used from within this method - it is
|
||||
* invalid. This method should not block for long, since it may cause an
|
||||
* ANR.
|
||||
*/
|
||||
public abstract void disconnected();
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to be
|
||||
* done if an incompatible IOIO firmware is detected. The ioio argument
|
||||
* passed to {@link #setup(IOIO)} must not be used from within this method -
|
||||
* it is invalid. This method will only be called once, until a compatible
|
||||
* IOIO is connected (i.e. {@link #setup(IOIO)} gets called).
|
||||
*/
|
||||
public abstract void incompatible();
|
||||
|
||||
}
|
||||
36
IOIOLib/src/ioio/lib/util/IOIOLooperProvider.java
Normal file
36
IOIOLib/src/ioio/lib/util/IOIOLooperProvider.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
/**
|
||||
* An entity that provides {@link IOIOLooper} instances on demand, per
|
||||
* connection specifications.
|
||||
*/
|
||||
public interface IOIOLooperProvider {
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method by returning an implementation of
|
||||
* {@link IOIOLooper}. The caller provide enough information to uniquely
|
||||
* identify the connection, through the parameters. <code>null</code> may be
|
||||
* returned if the client is not interested to create a thread for this
|
||||
* IOIO. This can be used in order to filter out unwanted connections, for
|
||||
* example if the application is only intended for wireless connection, any
|
||||
* wired connection attempts may be rejected, thus saving resources used for
|
||||
* listening for incoming wired connections.
|
||||
*
|
||||
* @param connectionType
|
||||
* A unique name of the connection type. Typically, the
|
||||
* fully-qualified name of the connection class used to connect
|
||||
* to the IOIO.
|
||||
* @param extra
|
||||
* A connection-type-specific object with extra information on
|
||||
* the specific connection. Should provide information that
|
||||
* enables distinguishing between different IOIO instances using
|
||||
* the same connection class. For example, a Bluetooth connection
|
||||
* type, might have the remote IOIO's Bluetooth name as extra.
|
||||
*
|
||||
* @return An implementation of {@link IOIOLooper}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
public abstract IOIOLooper createIOIOLooper(String connectionType,
|
||||
Object extra);
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.impl.SocketIOIOConnection;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class SocketIOIOConnectionDiscovery implements IOIOConnectionDiscovery {
|
||||
|
||||
@Override
|
||||
public void getSpecs(Collection<IOIOConnectionSpec> result) {
|
||||
result.add(new IOIOConnectionSpec(SocketIOIOConnection.class.getName(),
|
||||
new Object[] { new Integer(IOIOFactory.IOIO_PORT) }));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.util.android;
|
||||
|
||||
import android.content.ContextWrapper;
|
||||
|
||||
|
||||
public interface ContextWrapperDependent {
|
||||
public void onCreate(ContextWrapper wrapper);
|
||||
public void onDestroy();
|
||||
public void open();
|
||||
public void reopen();
|
||||
public void close();
|
||||
}
|
||||
148
IOIOLib/src/ioio/lib/util/android/IOIOActivity.java
Normal file
148
IOIOLib/src/ioio/lib/util/android/IOIOActivity.java
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.util.android;
|
||||
|
||||
import ioio.lib.impl.SocketIOIOConnection;
|
||||
import ioio.lib.util.IOIOLooper;
|
||||
import ioio.lib.util.IOIOLooperProvider;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* A convenience class for easy creation of IOIO-based activities.
|
||||
*
|
||||
* It is used by creating a concrete {@link Activity} in your application, which
|
||||
* extends this class. This class then takes care of proper creation and
|
||||
* abortion of the IOIO connection and of a dedicated thread for IOIO
|
||||
* communication.
|
||||
* <p>
|
||||
* In the basic usage the client should extend this class and implement
|
||||
* {@link #createIOIOLooper()}, which should return an implementation of the
|
||||
* {@link IOIOLooper} interface. In this implementation, the client implements
|
||||
* the {@link IOIOLooper#setup(ioio.lib.api.IOIO)} method, which gets called as
|
||||
* soon as communication with the IOIO is established, and the
|
||||
* {@link IOIOLooper#loop()} method, which gets called repetitively as long as
|
||||
* the IOIO is connected.
|
||||
* <p>
|
||||
* In addition, the {@link IOIOLooper#disconnected()} method may be overridden
|
||||
* in order to execute logic as soon as a disconnection occurs for whichever
|
||||
* reason. The {@link IOIOLooper#incompatible()} method may be overridden in
|
||||
* order to take action in case where a IOIO whose firmware is incompatible with
|
||||
* the IOIOLib version that application is built with.
|
||||
* <p>
|
||||
* In a more advanced use case, more than one IOIO is available. In this case, a
|
||||
* thread will be created for each IOIO, whose semantics are as defined above.
|
||||
* If the client needs to be able to distinguish between them, it is possible to
|
||||
* override {@link #createIOIOLooper(String, Object)} instead of
|
||||
* {@link #createIOIOLooper()}. The first argument provided will contain the
|
||||
* connection class name, such as ioio.lib.impl.SocketIOIOConnection for a
|
||||
* connection established over a TCP socket (which is used over ADB). The second
|
||||
* argument will contain information specific to the connection type. For
|
||||
* example, in the case of {@link SocketIOIOConnection}, the second argument
|
||||
* will contain an {@link Integer} representing the local port number.
|
||||
*/
|
||||
public abstract class IOIOActivity extends Activity implements
|
||||
IOIOLooperProvider {
|
||||
private final IOIOAndroidApplicationHelper helper_ = new IOIOAndroidApplicationHelper(
|
||||
this, this);
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onCreate() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
helper_.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onDestroy() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
helper_.destroy();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStart() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
helper_.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStop() if overloaded.
|
||||
* It takes care of disconnecting from the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onStop() {
|
||||
helper_.stop();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
|
||||
helper_.restart();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must either implement this method or its other overload by
|
||||
* returning an implementation of {@link IOIOLooper}. A dedicated thread
|
||||
* will be created for each available IOIO, from which the
|
||||
* {@link IOIOLooper}'s methods will be invoked. <code>null</code> may be
|
||||
* returned if the client is not interested to create a thread for this
|
||||
* IOIO. In multi-IOIO scenarios, where you want to identify which IOIO the
|
||||
* thread is for, consider overriding
|
||||
* {@link #createIOIOLooper(String, Object)} instead.
|
||||
*
|
||||
* @return An implementation of {@link IOIOLooper}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOLooper createIOIOLooper() {
|
||||
throw new RuntimeException(
|
||||
"Client must override one of the createIOIOLooper overloads!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOIOLooper createIOIOLooper(String connectionType, Object extra) {
|
||||
return createIOIOLooper();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package ioio.lib.util.android;
|
||||
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.util.IOIOApplicationHelper;
|
||||
import ioio.lib.util.IOIOConnectionRegistry;
|
||||
import ioio.lib.util.IOIOLooperProvider;
|
||||
|
||||
import android.content.ContextWrapper;
|
||||
|
||||
public class IOIOAndroidApplicationHelper extends IOIOApplicationHelper {
|
||||
private final ContextWrapper contextWrapper_;
|
||||
|
||||
public IOIOAndroidApplicationHelper(ContextWrapper wrapper,
|
||||
IOIOLooperProvider provider) {
|
||||
super(provider);
|
||||
contextWrapper_ = wrapper;
|
||||
}
|
||||
|
||||
static {
|
||||
IOIOConnectionRegistry
|
||||
.addBootstraps(new String[] {
|
||||
"ioio.lib.android.accessory.AccessoryConnectionBootstrap",
|
||||
"ioio.lib.android.bluetooth.BluetoothIOIOConnectionBootstrap" });
|
||||
}
|
||||
|
||||
public void create() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).onCreate(contextWrapper_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).onDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).open();
|
||||
}
|
||||
}
|
||||
super.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).reopen();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
149
IOIOLib/src/ioio/lib/util/android/IOIOService.java
Normal file
149
IOIOLib/src/ioio/lib/util/android/IOIOService.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.util.android;
|
||||
|
||||
import ioio.lib.impl.SocketIOIOConnection;
|
||||
import ioio.lib.util.IOIOLooper;
|
||||
import ioio.lib.util.IOIOLooperProvider;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* A convenience class for easy creation of IOIO-based services.
|
||||
*
|
||||
* It is used by creating a concrete {@link Service} in your application, which
|
||||
* extends this class. This class then takes care of proper creation and
|
||||
* abortion of the IOIO connection and of a dedicated thread for IOIO
|
||||
* communication.
|
||||
* <p>
|
||||
* In the basic usage the client should extend this class and implement
|
||||
* {@link #createIOIOLooper()}, which should return an implementation of the
|
||||
* {@link IOIOLooper} interface. In this implementation, the client implements
|
||||
* the {@link IOIOLooper#setup(ioio.lib.api.IOIO)} method, which gets called as
|
||||
* soon as communication with the IOIO is established, and the
|
||||
* {@link IOIOLooper#loop()} method, which gets called repetitively as long as
|
||||
* the IOIO is connected.
|
||||
* <p>
|
||||
* In addition, the {@link IOIOLooper#disconnected()} method may be overridden
|
||||
* in order to execute logic as soon as a disconnection occurs for whichever
|
||||
* reason. The {@link IOIOLooper#incompatible()} method may be overridden in
|
||||
* order to take action in case where a IOIO whose firmware is incompatible with
|
||||
* the IOIOLib version that application is built with.
|
||||
* <p>
|
||||
* In a more advanced use case, more than one IOIO is available. In this case, a
|
||||
* thread will be created for each IOIO, whose semantics are as defined above.
|
||||
* If the client needs to be able to distinguish between them, it is possible to
|
||||
* override {@link #createIOIOLooper(String, Object)} instead of
|
||||
* {@link #createIOIOLooper()}. The first argument provided will contain the
|
||||
* connection class name, such as ioio.lib.impl.SocketIOIOConnection for a
|
||||
* connection established over a TCP socket (which is used over ADB). The second
|
||||
* argument will contain information specific to the connection type. For
|
||||
* example, in the case of {@link SocketIOIOConnection}, the second argument
|
||||
* will contain an {@link Integer} representing the local port number.
|
||||
*/
|
||||
public abstract class IOIOService extends Service implements
|
||||
IOIOLooperProvider {
|
||||
private final IOIOAndroidApplicationHelper helper_ = new IOIOAndroidApplicationHelper(
|
||||
this, this);
|
||||
private boolean started_ = false;
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onCreate() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
helper_.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onDestroy() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
stop();
|
||||
helper_.destroy();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStart() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
public void onStart(Intent intent, int startId) {
|
||||
super.onStart(intent, startId);
|
||||
if (!started_) {
|
||||
helper_.start();
|
||||
started_ = true;
|
||||
} else {
|
||||
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
|
||||
helper_.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method if they wish to disconnect from the
|
||||
* IOIO(s) until the next onStart().
|
||||
*/
|
||||
protected void stop() {
|
||||
if (started_) {
|
||||
helper_.stop();
|
||||
started_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must either implement this method or its other overload by
|
||||
* returning an implementation of {@link IOIOLooper}. A dedicated thread
|
||||
* will be created for each available IOIO, from which the
|
||||
* {@link IOIOLooper}'s methods will be invoked. <code>null</code> may be
|
||||
* returned if the client is not interested to create a thread for this
|
||||
* IOIO. In multi-IOIO scenarios, where you want to identify which IOIO the
|
||||
* thread is for, consider overriding
|
||||
* {@link #createIOIOLooper(String, Object)} instead.
|
||||
*
|
||||
* @return An implementation of {@link IOIOLooper}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOLooper createIOIOLooper() {
|
||||
throw new RuntimeException(
|
||||
"Client must override one of the createIOIOLooper overloads!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOIOLooper createIOIOLooper(String connectionType, Object extra) {
|
||||
return createIOIOLooper();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user