Pinte
-
Upload
droidcon-berlin -
Category
Business
-
view
196 -
download
0
Transcript of Pinte
In Touch with Things: Programming NFC on Android with MORENA
Kevin PinteAndoni Lombide CarretonWolfgang De Meuter
DroidconApril 10, 2013Berlin, Germany
• NFC (touch range).
• Callback on activities to detect RFID tags with subscribed MIME-type in memory.
• File access abstraction
RFID in Android
NdefMessage: { , , }
NdefRecord byte array
read write
Drawbacks of the Android NFC API
• Manual failure handlingfailures are the rule rather than the exception:NFC causes A LOT of failures because of its hardware characteristics
• Blocking communicationAndroid documentation recommends to use a separate thread for many NFC operations
• Manual data conversion
• Tight coupling with activity-based architecture
Lessons Learnt from Previous Ambient-Oriented Programming Research
• Using objects as first class software representations for RFID-tagged “things” is a nice abstraction.
• These objects can be directly stored in the RFID tags’ memory to minimize data conversion.
• Event-driven discovery (fortunately built-in into Android).
• Asynchronous, fault tolerant reads and writes.experimental scripting
language for mobile apps in ad hoc networks
RFID tags as “mobile devices” and I/O as
network communication
Application
MORENA Middleware Architecture
Android
Tag level
Thing level One middlewarefor Android 4.0 or higher (API 14)
Evaluation: Wi-Fi Sharing Application
Evaluation: Wi-Fi Sharing Application
Things
public class WifiConfig extends Thing {
public String ssid_; public String key_;
public WifiConfig(ThingActivity<WifiConfig> activity, String ssid, String key) { super(activity); ssid_ = ssid; key_ = key; } public boolean connect(WifiManager wm) {
// Connect to ssid_ with password key_ };}
From now on, we don’t have to worry about the
activity anymore.
Supported serialization: - JSON-serializable fields. - Skipping transient fields. - Deep serialization, no cycles.
Initializing Things
@Overridepublic void whenDiscovered(EmptyRecord empty) { empty.initialize( myWifiThing, new ThingSavedListener<WifiConfig>() { @Override public void signal(WifiConfig thing) { toast("WiFi joiner created!"); } }, new ThingSaveFailedListener() { @Override public void signal() { toast("Creating WiFi joiner failed, try again."); } },
5000);}
As soon as an empty tag is detected
Discovering and Reading Things
@Overridepublic void whenDiscovered(WifiConfig wc) { toast("Joining Wifi network " + wc.ssid_); wc.connect();}
As soon as a WifiConfig tag is detected
Contains cached fields for synchronous access.
Physical reads must be asynchronous.
Saving Modified ThingsmyWifiConfig.ssid_ = "MyNewWifiName";myWifiConfig.key_ = "MyNewWifiPassword";
myWifiConfig.saveAsync( new ThingSavedListener<WifiConfig>() { @Override public void signal(WifiConfig wc) { toast("WiFi joiner saved!"); } }, new ThingSaveFailedListener() { @Override public void signal() { toast("Saving WiFi joiner failed, try again."); } }, 5000);
Broadcasting Things to Other Phones
myWifiConfig.broadcast( new ThingBroadcastSuccessListener<WifiConfig>() { @Override public void signal(WifiConfig wc) { toast("WiFi joiner shared!"); } }, new ThingBroadcastFailedListener<WifiConfig>() { @Override public void signal(WifiConfig wc) { toast("Failed to share WiFi joiner, try again."); } }, 5000);
Will trigger whenDiscovered on the receiving phone with the broadcasted thing
Evaluation: WiFi Sharing Application
MORENA Middleware Architecture
Android
Tag level
Thing level
Application
One middlewarefor Android 4.0 or higher (API 14)
Detecting RFID Tags
new TextTagDiscoverer(currentActivity, TEXT_TYPE, new NdefMessageToStringConverter(), new StringToNdefMessageConverter());
private class TextTagDiscoverer extends TagDiscoverer { @Override public void onTagDetected(TagReference tagReference) { readTagAndUpdateUI(tagReference); } @Override public void onTagRedetected(TagReference tagReference) { readTagAndUpdateUI(tagReference); }}
The Tag Reference Abstraction
Reading RFID Tags
tagReference.read( new TagReadListener() { @Override public void signal(TagReference tagReference) { // tagReference.getCachedData() } }, new TagReadFailedListener() { @Override public void signal(TagReference tagReference) { // Deal with failure } });
Writing RFID Tags
tagReference.write( toWrite, new TagWrittenListener() { @Override public void signal(TagReference tagReference) { // Handle write success } }, new TagWriteFailedListener() { @Override public void signal(TagReference tagReference) { // Deal with failure } });
Fine-grained Filtering
private class TextTagDiscoverer extends TagDiscoverer { @Override public void onTagDetected(TagReference tagReference) { readTagAndUpdateUI(tagReference); } @Override public void onTagRedetected(TagReference tagReference) { readTagAndUpdateUI(tagReference); }
@Override public boolean checkCondition(TagReference tagReference) { // Can be used to apply a predicate // on tagReference.getCachedData() }}
MORENA Conclusion
• Event-driven discovery.
• Non-blocking communication:
• Things: cached copy, asynchronous saving of cached data.
• TagReferences: first class references to RFID tags offering asynchronous reads and writes.
• Automatic data conversion
• Looser coupling from activity-based architecture
Current Research: Volatile Database
• Data structures over many tags?
• Querying collections of things?
• Stronger consistency guarantees?
• Transactions?
• Validations?
• ... Active Record (RoR) for RFID
Thing Associations
defmodel: Shelf properties: { number: Number} associations: { hasMany: `books};
defmodel: Book properties: { title: Text; authors: Text; isbn: Text;} proto: { def isMisplaced(currentShelf) { shelf != currentShelf; };} associations: {
belongsTo: `shelf};
a shelf contains many books
a book belongs to exactly one shelf in the library
Instantiating a Model and Saving to Tag
def newBook := Book.create: {title := “Agile Web Development with Rails”;authors := “Dave Thomas, ...”;isbn := “978-0-9776-1663-3”;
};def saveReq := newBook.saveAsync(10.seconds);when: saveReq succeeded: {
// the book was saved to a tag} catch: { |exc|
// book could not be saved within 10 sec};
newBook.shelf := shelf42;
shelf42.books << newBook; associate a book with a shelf:foreign key in book thing
Working with Many Things: Reactive Queries
def shelf42 := Shelf.all.first: { |s| s.number == 42 };def currentShelf := Shelf.all.last;
def misplacedBooks := Book.all.where: { |b|b.isMisplaced(currentShelf)
};
misplacedBooks.each: { |b|b.shelf := currentShelf;b.saveAsync(5.seconds)
};
most recently scanned shelf
synchronize misplaced books with current shelf
finding misplaced books in a library
all books not matching the last scanned shelf
In Touch with Things: Programming NFC on Android with MORENA
Droidcon, April 10, 2013, Berlin, Germany
@ambienttalk
soft.vub.ac.be/amopcode.google.com/p/ambienttalk
tinyurl.com/morena-android
@bommasaurus
tinyurl.com/kevinpinte