WebAPI/WebNFC

From MozillaWiki
Jump to navigation Jump to search

First iteration: NDEF

Scope

  • Technologies:
    • Focus on NDEF standard only for now
    • Others (e.g. proprietary MIFARE) to be investigated later.
  • Capabilities:
    • Read/write NDEF records on tags
    • P2P NDEF push/receive
  • Implementation:
    • NDEF-only API available on navigator.mozNfc object
    • Discovered NDEF tags are automatically parsed and dispatched to content in the "ndefdiscovered" event on navigator.mozNfc
    • navigator.mozNfc only available to a specific privileged content page (cf. WebTelephony, WebSMS).
    • For now, content is expected to do filtering and dispatching to handlers e.g. via WebIntents/WebActions/postMessage

Proposed API

navigator.mozNfc has one event related to NDEF discovery. The "techdiscovered" NFC event will be fired when a new NFC technology is discovered either via reading a tag or receiving it via P2P communication. The event will contain an array of technologies discovered. Calling ndefDetails will retrieve information, such as the length of the NDEF record, and the maximum size of the NDEF. ndefRead will read the NDEF record, and return it to the caller. ndefWrite allows writing a NDEF message to a Tag, subject to storage limits. ndefPush does a P2P Push of an NDEF formatted message to another NFC enabled device.

 interface nsIDOMMozNfc : nsIDOMEventTarget {
   [implicit_jscontext] attribute jsval ontechdiscovered;
   [implicit_jscontext] attribute jsval ontechlost;
   /**
    * NDEF Functions
    */
   /* Get metadata details of the discovered and connected NDEF message */
   [implicit_jscontext] nsIDOMDOMRequest ndefDetails();
   /**
    * NDEF Read returns an array of NDEF Records consisting of 1 or more elements
    */
   [implicit_jscontext] nsIDOMDOMRequest ndefRead();
   /* NDEF Write records that is an array of 1 or more records */
   [implicit_jscontext] nsIDOMDOMRequest ndefWrite(in jsval records);
   /* P2P Push NDEF records that is an array of 1 or more records */
   [implicit_jscontext] nsIDOMDOMRequest ndefPush(in jsval records);
   /**
    * NFCA functions (future)
    */
   [implicit_jscontext] nsIDOMDOMRequest nfcATagDetails();
   [implicit_jscontext] nsIDOMDOMRequest nfcATagTransceive(in jsval params);
   /**
    * Generic tag/tech functions
    */
   [implicit_jscontext] nsIDOMDOMRequest connect(in unsigned long techType);
   [implicit_jscontext] nsIDOMDOMRequest close();
 };

NDEF records contain a bunch of metadata and a payload that is exposed as a string.

 interface nsIDOMNdefRecord : nsISupports {
   /**
    * Type Name Field (3-bits) - Specifies the NDEF record type in general.
    * tnf_empty: 0x00
    * tnf_well_known: 0x01
    * tnf_mime_media: 0x02
    * tnf_absolute_uri: 0x03
    * tnf_external type: 0x04
    * tnf_unknown: 0x05
    * tnf_unchanged: 0x06
    * tnf_reserved: 0x06
    */
   readonly attribute octet tnf;
   /**
    * type - Describes the content of the payload. This can be a mime type.
    */
   readonly attribute DOMString type;
   /**
    * id - Identifer is application dependent.
    */
   readonly attribute DOMString id;
   /**
    * payload - Binary data blob. The meaning of this field is application dependent.
    */
   readonly attribute jsval payload;
 };

NDEF Read Example

 navigator.mozNfc.ontechdiscovered = function (event) {
 
   var tech = event.message.content.tech;
 
   for (var i in tech) {
     if (tech[i] == 'NDEF') {
       var req = navigator.mozNfc.ndefRead();
       req.onsuccess = function(e) {
         // NDEF Message with array of NDEFRecords
         var records = e.target.result;
         handleNdefDiscovered(records);
       };
       req.onerror = function() {
         console.log('ERROR: Failed to read NDEF on tag.');
       };
     }
   }
 
   function handleNdefDiscovered(records) {
     records.forEach(function (record) {
       console.log("Found a " + record.tnf + " record" +
                 " of type " + record.type +
                 " with ID " + record.id +
                 " and payload " + record.payload);
       // Could dispatch event.message here to other web apps based on MIME type, URI, etc.
     });
   }
 }

NDEF Write Tag Example

 navigator.mozNfc.onndefdiscovered = function (event) {
   var ndefRecords = [ new MozNdefRecord(1, "U", "", "\u0000http://mozilla.org") ];
   var domreq = navigator.mozNfc.writeNdefTag(ndefRecords);
   domreq.onsuccess = function(e) {
     console.log("Successfully wrote records to tag");
   }
   domreq.onerror = function(e) {
     console.log("Write failed!");
   }
 };

NDEF P2P Push Example

 var ndefRecords = [ new MozNdefRecord(1, "U", "", "\u0000http://mozilla.org") ];
 var domreq = navigator.mozNfc.ndefPush = function (event) {
 domreq.onsuccess = function(e) {
   console.log("Successfully pushed P2P message");
 }
 domreq.onerror = function(e) {
   console.log("P2P push failed!");
 }

Implementation

  • See bug 674741
  • Engineers: Markus Neubrand, Arno Puder, Garner Lee, Siddartha Pothapragada, Philipp von Weitershausen