WebAPI/WebNFC: Difference between revisions

 
(170 intermediate revisions by 7 users not shown)
Line 1: Line 1:
= Introduction =
= Introduction =
== Current Status (As to Firefox OS v1.4) ==
== Current Status (As to Firefox OS v2.2) ==
* Gecko meta bug, {{bug|860906}}
* Gecko b2g-nfc meta bug, {{bug|860906}}
* Gecko b2g-secure-element meta bug {{bug|1044428}}
* Gaia meta bug,  {{bug|933640}}
* Gaia meta bug,  {{bug|933640}}
* nfcd meta bug, {{bug|1044425}}
* Gonk
* Gonk
** Use a native daemon nfcd which links to native NFC library. [https://github.com/mozilla-b2g/platform_system_nfcd nfcd github]
** Use a native daemon nfcd which links to native NFC library. [https://github.com/mozilla-b2g/platform_system_nfcd nfcd github]
* Hardware
* Hardware
** Using Nexus-4, which uses Broadcom NFC chipset with libnfc-nci library.
** Using Nexus-4/Nexus-5, which uses Broadcom NFC chipset with libnfc-nci library.
** Flame, NXP chipsets with libnfc-nci library.


== Security Review (By Paul Theriault) ==
== Security Review (By Paul Theriault and Stephanie Ouillon) ==
* https://wiki.mozilla.org/Security/Reviews/B2G/WebNFC
* https://wiki.mozilla.org/Security/Reviews/B2G/WebNFC
* {{bug|948280}}
* Security Review for WebNFC: {{bug|749325}}
* {{bug|749325}}
* Security Review for NFC Payment: {{bug|948280}}
* Security Review for NFC privilege API: {{bug|1095417}}
 
== Contributors ==
* Gecko Engineers: Arno Puder, Garner Lee, Siddartha Pothapragada, Yoshi Huang, Dimi Lee
* Early Contributors: Markus Neubrand, Philipp von Weitershausen


== Contributers ==
* Gecko Engineers: Markus Neubrand, Arno Puder, Garner Lee, Siddartha Pothapragada, Philipp von Weitershausen, Yoshi Huang, Dimi Lee.
= Roadmap =
= Roadmap =
== First iteration: NDEF (Firefox OS v1.3) ==
== First iteration: NDEF (Firefox OS v1.3) ==
* meta bug, {{Bug|959692}} - (b2g-NFC-1.3) [meta] FxOS v1.3 NFC feature
* Technologies:
* Technologies:
** Focus on NDEF standard only for now
** Focus on NDEF standard only for now
Line 22: Line 29:
* Capabilities:
* Capabilities:
** Read/write NDEF records on tags
** Read/write NDEF records on tags
** P2P mode. {{bug|933136}}
** {{bug|933136}} - [Gecko] NFC onpeerready, onpeerlost callbacks
* Implementation:
* Implementation:
** See {{bug|674741}}
** See {{bug|674741}}
Line 30: Line 37:
** For now, content is expected to do filtering and dispatching to handlers e.g. via WebActivity.
** For now, content is expected to do filtering and dispatching to handlers e.g. via WebActivity.
* Gonk
* Gonk
** A native daemon is forked. {{bug|906579}}
** {{bug|906579}} - B2G NFC: NFC Daemon for supporting libnfc-nci
* Hardware
* Hardware
** Using Nexus-4, which uses Broadcom NFC chipset with libnfc-nci library.
** Using Nexus-4, which uses Broadcom NFC chipset with libnfc-nci library.


== Second iteration: Handover, Secure Element (Firefox OS v1.4) ==
== Second iteration: Handover and other bug fixes (Firefox OS v1.4) ==
* Technologies:
* meta bug : {{Bug|949293}} - (b2g-NFC-1.4) [meta] FxOS v1.4 NFC feature
** ISO 14443-4, aka ISO-DEP, {{bug|916428}}
** Secure Element. {{bug|879861}}
* Capabilities:
* Capabilities:
** NFC handover. {{bug|933093}}
** {{bug|933093}} NFC handover.
 
** {{bug|916863}} - [NFC] NFC support in emulator
= Proposed API =
** NFC Manager API
 
*** {{Bug|952217}} - [B2G][NFC] Have a separate NFC application API and NFC Manager API
== MozNFCTag.webidl ==
*** {{Bug|959437}} - Refactor NfcManager APIs and implementation details to support sendFile , notifyUserAcceptedP2P and other privileged Nfc operations
 
  enum NFCTechType {
    "NFC_A",
    "NFC_B",
    "NFC_ISO_DEP",
    "NFC_F",
    "NFC_V",
    "NDEF",
    "NDEF_FORMATABLE",
    "MIFARE_CLASSIC",
    "MIFARE_ULTRALIGHT",
    "NFC_BARCODE",
    "P2P",
    "UNKNOWN_TECH"
  };
  interface MozNFCTag : EventTarget {
    DOMRequest getDetailsNDEF();
    DOMRequest readNDEF();
    DOMRequest writeNDEF(sequence<MozNDEFRecord> records);
    DOMRequest makeReadOnlyNDEF();
    DOMRequest connect(NFCTechType techType);
    DOMRequest close();
  };
 
== MozNFCPeer.webidl ==
'''sendNDEF''' does a P2P send of an NDEF formatted message to another NFC enabled device. NFCPeer will also handle send a generic blob in handover requests where a NDEF formatted "handover" message will conditionally trigger pairing with another device over an available Bluetooth or Wifi connection.
 
  interface MozNFCPeer : EventTarget {
    DOMRequest sendNDEF(sequence<MozNDEFRecord> records);
    DOMRequest sendFile(Blob blob);
  };
 
TODO: sendFile is still being implemented in {{bug|933093}} (As of 2013.12.20)
 
== MozNDEFRecord.webidl ==
NDEF records contain a bunch of metadata and a payload that is exposed as a Uint8Array.


  interface MozNDEFRecord {
== Third iteration: NFC Sharing feature, P2P, emulator support, test cases (Firefox OS v2.0) ==
    /**
* meta bug : {{Bug|949293}} - (b2g-NFC-2.0) [meta] FxOS v2.0 NFC feature
    * Type Name Field (3-bits) - Specifies the NDEF record type in general.
* NFC emulator: {{Bug|973133}}
    * tnf_empty: 0x00
* More Gaia unit tests for NFC in apps/system/test/unit/
    * tnf_well_known: 0x01
    * tnf_mime_media: 0x02
    * tnf_absolute_uri: 0x03
    * tnf_external type: 0x04
    * tnf_unknown: 0x05
    * tnf_unchanged: 0x06
    * tnf_reserved: 0x07
    */
    readonly attribute octet tnf;
    /**
    * type - Describes the content of the payload. This can be a mime type.
    */
    readonly attribute Uint8Array type;
    /**
    * id - Identifer is application dependent.
    */
    readonly attribute Uint8Array id;
    /**
    * payload - Binary data blob. The meaning of this field is application dependent.
    */
    readonly attribute Uint8Array payload;
  };


== MozNfc.webidl ==
== Fourth iteration: HCI transaction event (Firefox OS v2.1) ==
* {{bug|979767}}


  interface mozNfc {
== Fifth iteration: Secure Element and NFC Privileged API (Firefox OS v2.2) ==
    /* Get the NFCTag */
* {{bug|1044428}} b2g-secure-element
    DOMRequest getNFCTag(DOMString sessionToken);
** {{Bug|879861}} - NFC Secure Element Support
* {{Bug|1042851}} - (b2g-nfc-privilege) (meta) [NFC] Make NFC APIs available to privileged webapps
    /* Get the NFCPeer for Peer to Peer interactions */
** Slide: http://bit.ly/1x7nWp5
    DOMRequest getNFCPeer(DOMString sessionToken);
    /**
    * API to update chrome about the top-most (visible)
    * application's manifest URL that is capable of
    * handling peer notifications.
    *
    * Users of this API should have valid permissions 'nfc-manager'
    * and 'nfc-write'
    */
    DOMRequest checkP2PRegistration(DOMString manifestUrl);
    /* Sets a callback to notifiy when NDEF Push message communication is available for use. */
    attribute EventHandler onpeerready();
    attribute EventHandler onpeerlost();
    /* Foreground dispatch allows the app, if in the foreground, to get routed all
      NFC messages. Useful for applications that write NFC tags. Privilaged API. */
    attribute EventHandler onforegrounddispatch();
  };


Check {{bug|933136}}, or
= Current API =
[https://docs.google.com/a/mozilla.com/drawings/d/1_7rHuYCE6roM8Dx6sDF6or3xjGKSz5CYW_w2a4uJthA/ onpeerready] for how onpeerready is called.
Check DXR for latest NFC IDL


foreground dispatch is still being implemented, {{bug|937430}}
* [https://dxr.mozilla.org/mozilla-central/source/dom/webidl/MozNDEFRecord.webidl MozNDEFRecord.webidl]
== Receiving NDEF messages, via MozActivity ==
* [https://dxr.mozilla.org/mozilla-central/source/dom/webidl/MozNFC.webidl MozNFC.webidl]
Setup an Activity handler for incoming NDEF messages. The web activity chooser UI will route the messsage to the user selected application if there is more than one match. Currently, only NDEF is supported, although individual nfc tags can actually be compatible with multiple legacy and proprietary technology types.
* [https://dxr.mozilla.org/mozilla-central/source/dom/webidl/MozNFCPeer.webidl MozNFCPeer.webidl]
* [https://dxr.mozilla.org/mozilla-central/source/dom/webidl/MozNFCPeerEvent.webidl MozNFCPeerEvent.webidl]
* [https://dxr.mozilla.org/mozilla-central/source/dom/webidl/MozNFCTag.webidl MozNFCTag.webidl]
* [https://dxr.mozilla.org/mozilla-central/source/dom/webidl/MozNFCTagEvent.webidl MozNFCTagEvent.webidl]


Applications that do not have "'''nfc'''" read or write permissions can still get NDEF events via activities, and act on the data. The raw NDEF data is included with the activity, should the application wish to process any special properties of more complex NDEF data structures.
= Usage of APIs =


If the NFC NDEF tag type is well known, such as URIs, the activity will be delievered with some extra fields already parsed.
https://developer.mozilla.org/en-US/docs/Web/API/NFC_API


In the application manifest, declare the following in the activities block to get nfc ndef discovered events.
= Application Permissions =


  "nfc-ndef-discovered": {
NFC API has three permissions.
    "filters": {
* '''nfc''', which will be used by privileged applications.
      "type": "uri",
* '''nfc-share''', which will be used by ceritified(internal) applications.
      "uri": { "required":true, "regexp":"/^https?:.{1,16384}$/i" }
* '''nfc-manager', which will be used by System app.
    }
  },


Then implement an activity handler in the application:
'''nfc''' permission could be used for  general tag reading/writing, or sending NDEF to NFC Peer.
'''nfc-share''' could be used to send large file (Blob) to another NFC peer.
'''nfc-manager''' is used to control the RF state of NFC hardware.


  navigator.mozSetMessageHandler('activity', NfcActivityHandler);
= Application Dispatch Order =
 
1) Foreground App, if the callback ontagfound/onpeerfound is set.
  function NfcActivityHandler(activity) {
2) If the foreground app doesn't register NFC callbacks or cannot process the event, the event will be redirected to System app, and System app will fire a nfc-ndef-discovered MozActivity.
    var activityName = activity.source.name;
    var data = activity.source.data;
 
    switch (activityName) {
      case 'nfc-ndef-discovered':
        console.log('nfc ndef message records(s): ' + JSON.stringify(data.records));
        console.log('Session Token: ' + JSON.stringify(data.sessionToken));
        console.log('Technology Detected: ' + JSON.stringify(data.tech));
        handleNdefDiscovered(data);
        break;
  }


TODO: Add a diagram to illustrate how tag is dispatched.
= NFC on B2G emulator =
* See Kami's notes : https://bitbucket.org/kamituel/b2g-notepad/wiki/Using%20emulator


== Application Permissions ==
= NFC Resources =
 
NFC API can be used only by certified app.
 
To use general reading NDEF API, at least '''nfc-read''' permission is required.
To write NDEF or to use NFCPeer, '''nfc-write''' is required.
 
Application Usage Example:
 
  "permissions": {
    "nfc": { "access": "readwrite" }
  }
 
 
For those APIs used by the nfc_manager in System app, '''nfc-manager''' permission is required, and is available to certified applications only. It must '''not''' be used in any other application besides System App.
 
System level apps declare an additional certified system message permissions, as it fires the nfc-ndef-discovered WebActivities to applications that declare NFC NDEF support.
 
= NFC example =
 
== NDEF Utilitiy function ==
 
MozNDEFRecord is a binary format, and the data is packed into Uint8Array fields. In the following examples, we'll just refer to this helper function to convert javascript strings to Uint8Array buffers.
 
  var NfcUtil = {
    fromUTF8: function nu_fromUTF8(str) {
      var buf = new Uint8Array(str.length);
      for (var i = 0; i < str.length; i++) {
        buf[i] = str.charCodeAt(i);
      }
      return buf;
    }
  }
 
== NDEF Connect Example ==
 
To establish an NFC application session, all NFCTag operations require an initial connect. It also selects the technology to use for subsequent operations until close/disconnect.
 
  nfctag = window.navigator.mozNfc.getNFCTag(sessionToken);
 
  var connectreq = nfctag.connect("NDEF");
  connectreq.onsuccess = function() {
    console.log('Connect success!');
  };
  connectreq.onerror = function() {
    console.log('ERROR: Failed to connect.');
  };
 
== NFC Close Example ==
 
Applications should close() the tag when done to release resources.
 
  var closereq = nfctag.close();
  closereq.onsuccess = function() {
    console.log('NFC tag close success!');
  };
  closereq.onerror = function() {
    console.log('ERROR: Failed to close.');
  };
 
== NDEF Details Example ==
 
  var detailreq = nfctag.getDetailsNDEF();
  detailreq.onsuccess = function() {
    console.log('Max NDEF Message Length: ' + detailreq.result.maxNdefMsgLen);
  };
  detailreq.onerror = function() {
    console.log('ERROR: Failed to get NDEF details.');
  };
 
== NDEF Read Example ==
The array of ndef records should be passed along in the web activity already read, but applications can still directly read the tag. The session token arrives from a MozActivity. NdefRecord fields are in Uint8Array format, they must first be unpacked in order to be read by applications.
 
  var conn = nfctag.connect("NDEF");
  conn.onsuccess = function() {
    var req = nfctag.readNDEF();
    req.onsuccess = function() {
      var records = req.result;
      showRecords(records);
      nfctag.close(); // This is a DOMRequest call, truncated code here.
    };
    req.onerror = function() {
      nfctag.close(); // This is a DOMRequest call, truncated code here.
    };
  };
 
  function showRecords(records) {
    records.forEach(function (record) {
      console.log("Found a " + record.tnf + " record" +
                  " of type " + record.type +
                  " with ID " + record.id +
                  " and payload " + record.payload);
    });
  };
 
== NDEF Write Tag Example ==
 
  var tnf    = 1;                                                            // NFC Forum Well Known type
  var type    = new Uint8Array(NfcUtil.fromUTF8("U"));                        // URL type
  var id      = new Uint8Array(NfcUtil.fromUTF8(""));                        // id
  var payload = new Uint8Array(NfcUtil.fromUTF8("\u0000http://mozilla.org")); // URL data
 
  var ndefRecords = new MozNDEFRecord(tnf, type, id, payload);
 
  var writereq = nfctag.writeNDEF(ndefRecords);
  writereq.onsuccess = function(e) {
    console.log("Successfully wrote records to tag");
  };
  writereq.onerror = function(e) {
    console.log("Write failed!");
  };
 
== NDEF P2P Push Example ==
Peer to Peer communications to another NFC enabled device does not need a connect, as it will automatically connect implicitly. It also only supports NDEF, which is a common standard data format across different NFC devices.
 
  var tnf    = 1;                                                            // NFC Forum Well Known type
  var type    = new Uint8Array(NfcUtil.fromUTF8("U"));                        // URL type
  var id      = new Uint8Array(NfcUtil.fromUTF8(""));                        // id
  var payload = new Uint8Array(NfcUtil.fromUTF8("\u0000http://mozilla.org")); // URL data
 
  var ndefRecords = new MozNDEFRecord(tnf, type, id, payload);
 
  // TODO: UPDATE ME. NFCPeer isn't passed in the onpeerready callback.
  window.navigator.onpeerready = function(nfcpeer) {
    var peerreq = nfcpeer.sendNDEF(ndefRecords); // push NDEF message to other NFC device.
    peerreq.onsuccess = function(e) {
      console.log("Successfully pushed P2P message");
    };
    peerreq.onerror = function(e) {
      console.log("P2P push failed!");
    };
  };
 
== NDEF P2P SendFile Example ==
In order to send a file,
  var nfcdom = window.navigator.mozNfc;
  nfcdom.onpeerready = function(event) {
    var nfcPeer = nfcdom.getNFCPeer(event.detail);
    // Below is only an example to illustrate that sendfile accepts 'blob'.
    var fakeBlob = new Blob([], {type: 'image/png'});
    var sendfilereq = nfcPeer.sendFile(fakeBlob);
    sendfilereq.onsuccess = function(e) {
      console.log("Successfully sent file");
    };
    sendfilereq.onerror = function(e) {
      console.log("Send file failed!");
    };
  };
Note: 'blob' that is being sent by nfc gaia applications will be 'handed-over' to bluetooth interface. (Only handover to BT is supported for now,
TBD: WiFi is to be supported). Gaia application that uses this API, should have 'nfc-write' permissions
 
== Handover Example ==
TODO: UPDATE ME
There is some example landed in {{bug|903305}},
however it will be refactored in {{bug|933093}}.
 
== Application Dispatch Order ==
 
TBD.
 
Priority (low is highest):
 
Declared support levels:
 
1) Foreground App with declared type support (NFC writing apps need to be able to hold the screen so it can write the message, privilaged nfc permisisons).
2) Handover Types (BT transfers, WiFi direct connection, etc.)
3) Specific declared Type support
 
= NFC Resouces =
== Reference ==
== Reference ==
* Introduction to NFC: http://www.adafruit.com/datasheets/Introduction_to_NFC_v1_0_en.pdf
* Introduction to NFC: http://www.adafruit.com/datasheets/Introduction_to_NFC_v1_0_en.pdf
* NDEF specification: NFCForum-TS-NDEF_1.0.pdf
* NDEF specification: NFCForum-TS-NDEF_1.0.pdf
* Understand NDEF messages : http://developer.nokia.com/Community/Wiki/Inside_NFC:_Understanding_NDEF_message
* Understand NDEF messages : http://developer.nokia.com/Community/Wiki/Inside_NFC:_Understanding_NDEF_message
* NFC forum specificaitons: http://members.nfc-forum.org/specs/
* NFC forum specifications: http://members.nfc-forum.org/specs/
* Handover specification: NFCForum-TS-ConnectionHandover_1_2.pdf
* Handover specification: NFCForum-TS-ConnectionHandover_1_2.pdf


Line 360: Line 108:
* Tizen NFC API: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.web.device.apireference/tizen/nfc.html
* Tizen NFC API: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.web.device.apireference/tizen/nfc.html
* Android NFC API: http://developer.android.com/reference/android/nfc/package-summary.html
* Android NFC API: http://developer.android.com/reference/android/nfc/package-summary.html
[[Category:Web APIs]]

Latest revision as of 05:16, 16 March 2015

Introduction

Current Status (As to Firefox OS v2.2)

  • Gecko b2g-nfc meta bug, bug 860906
  • Gecko b2g-secure-element meta bug bug 1044428
  • Gaia meta bug, bug 933640
  • nfcd meta bug, bug 1044425
  • Gonk
    • Use a native daemon nfcd which links to native NFC library. nfcd github
  • Hardware
    • Using Nexus-4/Nexus-5, which uses Broadcom NFC chipset with libnfc-nci library.
    • Flame, NXP chipsets with libnfc-nci library.

Security Review (By Paul Theriault and Stephanie Ouillon)

Contributors

  • Gecko Engineers: Arno Puder, Garner Lee, Siddartha Pothapragada, Yoshi Huang, Dimi Lee
  • Early Contributors: Markus Neubrand, Philipp von Weitershausen

Roadmap

First iteration: NDEF (Firefox OS v1.3)

  • meta bug, bug 959692 - (b2g-NFC-1.3) [meta] FxOS v1.3 NFC feature
  • Technologies:
    • Focus on NDEF standard only for now
    • Others (e.g. proprietary MIFARE) to be investigated later.
  • Capabilities:
    • Read/write NDEF records on tags
    • bug 933136 - [Gecko] NFC onpeerready, onpeerlost callbacks
  • Implementation:
    • See bug 674741
    • NDEF-only API is available on MozNFCTag object.
    • Discovered NDEF tags are automatically parsed and dispatched to content in the "nfc-manager-tech-discovered" system message.
    • 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 WebActivity.
  • Gonk
    • bug 906579 - B2G NFC: NFC Daemon for supporting libnfc-nci
  • Hardware
    • Using Nexus-4, which uses Broadcom NFC chipset with libnfc-nci library.

Second iteration: Handover and other bug fixes (Firefox OS v1.4)

  • meta bug : bug 949293 - (b2g-NFC-1.4) [meta] FxOS v1.4 NFC feature
  • Capabilities:
    • bug 933093 NFC handover.
    • bug 916863 - [NFC] NFC support in emulator
    • NFC Manager API
      • bug 952217 - [B2G][NFC] Have a separate NFC application API and NFC Manager API
      • bug 959437 - Refactor NfcManager APIs and implementation details to support sendFile , notifyUserAcceptedP2P and other privileged Nfc operations

Third iteration: NFC Sharing feature, P2P, emulator support, test cases (Firefox OS v2.0)

  • meta bug : bug 949293 - (b2g-NFC-2.0) [meta] FxOS v2.0 NFC feature
  • NFC emulator: bug 973133
  • More Gaia unit tests for NFC in apps/system/test/unit/

Fourth iteration: HCI transaction event (Firefox OS v2.1)

Fifth iteration: Secure Element and NFC Privileged API (Firefox OS v2.2)

Current API

Check DXR for latest NFC IDL

Usage of APIs

https://developer.mozilla.org/en-US/docs/Web/API/NFC_API

Application Permissions

NFC API has three permissions.

  • nfc, which will be used by privileged applications.
  • nfc-share, which will be used by ceritified(internal) applications.
  • nfc-manager', which will be used by System app.

nfc permission could be used for general tag reading/writing, or sending NDEF to NFC Peer. nfc-share could be used to send large file (Blob) to another NFC peer. nfc-manager is used to control the RF state of NFC hardware.

Application Dispatch Order

1) Foreground App, if the callback ontagfound/onpeerfound is set.
2) If the foreground app doesn't register NFC callbacks or cannot process the event, the event will be redirected to System app, and System app will fire a nfc-ndef-discovered MozActivity.

NFC on B2G emulator

NFC Resources

Reference

Similar APIs