diff --git a/dom/system/gonk/Nfc.js b/dom/system/gonk/Nfc.js index 4ea40d75d00..5a6ab9ad005 100644 --- a/dom/system/gonk/Nfc.js +++ b/dom/system/gonk/Nfc.js @@ -501,7 +501,11 @@ Nfc.prototype = { } switch (message.type) { - case "techDiscovered": + case "InitializedNotification": + // Do nothing. + break; + case "TechDiscoveredNotification": + message.type = "techDiscovered"; this._currentSessionId = message.sessionId; // Check if the session token already exists. If exists, continue to use the same one. @@ -516,7 +520,8 @@ Nfc.prototype = { gSystemMessenger.broadcastMessage("nfc-manager-tech-discovered", message); break; - case "techLost": + case "TechLostNotification": + message.type = "techLost"; gMessageManager._unregisterMessageTarget(this.sessionTokenMap[this._currentSessionId], null); // Update the upper layers with a session token (alias) diff --git a/dom/system/gonk/NfcGonkMessage.h b/dom/system/gonk/NfcGonkMessage.h new file mode 100644 index 00000000000..12f32fdf4da --- /dev/null +++ b/dom/system/gonk/NfcGonkMessage.h @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef NfcGonkMessage_h +#define NfcGonkMessage_h + +namespace mozilla { + +#define NFCD_MAJOR_VERSION 1 +#define NFCD_MINOR_VERSION 7 + +enum NfcRequest { + eNfcRequest_Config = 0, + eNfcRequest_Connect, + eNfcRequest_Close, + eNfcRequest_GetDetailsNDEF, + eNfcRequest_ReadNDEF, + eNfcRequest_WriteNDEF, + eNfcRequest_MakeReadOnlyNDEF, +}; + +enum NfcResponse { + eNfcResponse_General = 1000, + eNfcResponse_Config, + eNfcResponse_GetDetailsNDEF, + eNfcResponse_ReadNDEF, +}; + +enum NfcNotification { + eNfcNotification_Initialized = 2000, + eNfcNotification_TechDiscovered, + eNfcNotification_TechLost, +}; + +enum NfcTechlogy { + eNfcTechlogy_NDEF = 0, + eNfcTechlogy_NDEFWritable, + eNfcTechlogy_NDEFFormattable, + eNfcTechlogy_P2P, +}; + +} // namespace mozilla + +#endif // NfcGonkMessage_h diff --git a/dom/system/gonk/NfcMessageHandler.cpp b/dom/system/gonk/NfcMessageHandler.cpp index 311c6715094..702c557d845 100644 --- a/dom/system/gonk/NfcMessageHandler.cpp +++ b/dom/system/gonk/NfcMessageHandler.cpp @@ -3,17 +3,65 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "NfcMessageHandler.h" - #include +#include "nsDebug.h" +#include "NfcGonkMessage.h" +#include "NfcOptions.h" + +#include +#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "NfcMessageHandler", args) using namespace android; using namespace mozilla; +static const char* kConfigRequest = "config"; +static const char* kGetDetailsNDEF = "getDetailsNDEF"; +static const char* kReadNDEFRequest = "readNDEF"; +static const char* kWriteNDEFRequest = "writeNDEF"; +static const char* kMakeReadOnlyNDEFRequest = "makeReadOnlyNDEF"; +static const char* kConnectRequest = "connect"; +static const char* kCloseRequest = "close"; + +static const char* kConfigResponse = "ConfigResponse"; +static const char* kGetDetailsNDEFResponse = "GetDetailsNDEFResponse"; +static const char* kReadNDEFResponse = "ReadNDEFResponse"; +static const char* kWriteNDEFResponse = "WriteNDEFResponse"; +static const char* kMakeReadOnlyNDEFResponse = "MakeReadOnlyNDEFResponse"; +static const char* kConnectResponse = "ConnectResponse"; +static const char* kCloseResponse = "CloseResponse"; + +static const char* kInitializedNotification = "InitializedNotification"; +static const char* kTechDiscoveredNotification = "TechDiscoveredNotification"; +static const char* kTechLostNotification = "TechLostNotification"; + bool NfcMessageHandler::Marshall(Parcel& aParcel, const CommandOptions& aOptions) { bool result; - // TODO: Implementation will be Bug 933588 - Part 2. + const char* type = NS_ConvertUTF16toUTF8(aOptions.mType).get(); + + if (!strcmp(type, kConfigRequest)) { + result = ConfigRequest(aParcel, aOptions); + } else if (!strcmp(type, kGetDetailsNDEF)) { + result = GetDetailsNDEFRequest(aParcel, aOptions); + } else if (!strcmp(type, kReadNDEFRequest)) { + result = ReadNDEFRequest(aParcel, aOptions); + } else if (!strcmp(type, kWriteNDEFRequest)) { + result = WriteNDEFRequest(aParcel, aOptions); + mPendingReqQueue.AppendElement(eNfcRequest_WriteNDEF); + } else if (!strcmp(type, kMakeReadOnlyNDEFRequest)) { + result = MakeReadOnlyNDEFRequest(aParcel, aOptions); + mPendingReqQueue.AppendElement(eNfcRequest_MakeReadOnlyNDEF); + } else if (!strcmp(type, kConnectRequest)) { + result = ConnectRequest(aParcel, aOptions); + mPendingReqQueue.AppendElement(eNfcRequest_Connect); + } else if (!strcmp(type, kCloseRequest)) { + result = CloseRequest(aParcel, aOptions); + mPendingReqQueue.AppendElement(eNfcRequest_Close); + } else { + result = false; + } + return result; } @@ -21,7 +69,279 @@ bool NfcMessageHandler::Unmarshall(const Parcel& aParcel, EventOptions& aOptions) { bool result; - // TODO: Implementation will be Bug 933588 - Part 2. + uint32_t parcelSize = htonl(aParcel.readInt32()); + int32_t type = aParcel.readInt32(); + + switch (type) { + case eNfcResponse_General: + result = GeneralResponse(aParcel, aOptions); + break; + case eNfcResponse_Config: + result = ConfigResponse(aParcel, aOptions); + break; + case eNfcResponse_GetDetailsNDEF: + result = GetDetailsNDEFResponse(aParcel, aOptions); + break; + case eNfcResponse_ReadNDEF: + result = ReadNDEFResponse(aParcel, aOptions); + break; + case eNfcNotification_Initialized: + result = InitializeNotification(aParcel, aOptions); + break; + case eNfcNotification_TechDiscovered: + result = TechDiscoveredNotification(aParcel, aOptions); + break; + case eNfcNotification_TechLost: + result = TechLostNotification(aParcel, aOptions); + break; + default: + result = false; + break; + } + return result; } +bool +NfcMessageHandler::GeneralResponse(const Parcel& aParcel, EventOptions& aOptions) +{ + const char* type; + NS_ENSURE_TRUE(!mPendingReqQueue.IsEmpty(), false); + int pendingReq = mPendingReqQueue[0]; + mPendingReqQueue.RemoveElementAt(0); + + switch (pendingReq) { + case eNfcRequest_WriteNDEF: + type = kWriteNDEFResponse; + break; + case eNfcRequest_MakeReadOnlyNDEF: + type = kMakeReadOnlyNDEFResponse; + break; + case eNfcRequest_Connect: + type = kConnectResponse; + break; + case eNfcRequest_Close: + type = kCloseResponse; + break; + } + + aOptions.mType = NS_ConvertUTF8toUTF16(type); + aOptions.mStatus = aParcel.readInt32(); + aOptions.mSessionId = aParcel.readInt32(); + + NS_ENSURE_TRUE(!mRequestIdQueue.IsEmpty(), false); + aOptions.mRequestId = mRequestIdQueue[0]; + mRequestIdQueue.RemoveElementAt(0); + return true; +} + +bool +NfcMessageHandler::ConfigRequest(Parcel& aParcel, const CommandOptions& aOptions) +{ + aParcel.writeInt32(eNfcRequest_Config); + aParcel.writeInt32(aOptions.mPowerLevel); + mRequestIdQueue.AppendElement(aOptions.mRequestId); + mPowerLevelQueue.AppendElement(aOptions.mPowerLevel); + return true; +} + +bool +NfcMessageHandler::ConfigResponse(const Parcel& aParcel, EventOptions& aOptions) +{ + aOptions.mType = NS_ConvertUTF8toUTF16(kConfigResponse); + aOptions.mStatus = aParcel.readInt32(); + + NS_ENSURE_TRUE(!mRequestIdQueue.IsEmpty(), false); + aOptions.mRequestId = mRequestIdQueue[0]; + mRequestIdQueue.RemoveElementAt(0); + + NS_ENSURE_TRUE(!mPowerLevelQueue.IsEmpty(), false); + aOptions.mPowerLevel = mPowerLevelQueue[0]; + mPowerLevelQueue.RemoveElementAt(0); + return true; +} + +bool +NfcMessageHandler::GetDetailsNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions) +{ + aParcel.writeInt32(eNfcRequest_GetDetailsNDEF); + aParcel.writeInt32(aOptions.mSessionId); + mRequestIdQueue.AppendElement(aOptions.mRequestId); + return true; +} + +bool +NfcMessageHandler::GetDetailsNDEFResponse(const Parcel& aParcel, EventOptions& aOptions) +{ + aOptions.mType = NS_ConvertUTF8toUTF16(kGetDetailsNDEFResponse); + aOptions.mStatus = aParcel.readInt32(); + aOptions.mSessionId = aParcel.readInt32(); + int readOnly = aParcel.readInt32(); + aOptions.mIsReadOnly = readOnly & 0xff; + aOptions.mCanBeMadeReadOnly = (readOnly >> 8) & 0xff; + aOptions.mMaxSupportedLength = aParcel.readInt32(); + + NS_ENSURE_TRUE(!mRequestIdQueue.IsEmpty(), false); + aOptions.mRequestId = mRequestIdQueue[0]; + mRequestIdQueue.RemoveElementAt(0); + return true; +} + +bool +NfcMessageHandler::ReadNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions) +{ + aParcel.writeInt32(eNfcRequest_ReadNDEF); + aParcel.writeInt32(aOptions.mSessionId); + mRequestIdQueue.AppendElement(aOptions.mRequestId); + return true; +} + +bool +NfcMessageHandler::ReadNDEFResponse(const Parcel& aParcel, EventOptions& aOptions) +{ + aOptions.mType = NS_ConvertUTF8toUTF16(kReadNDEFResponse); + aOptions.mStatus = aParcel.readInt32(); + aOptions.mSessionId = aParcel.readInt32(); + + NS_ENSURE_TRUE(!mRequestIdQueue.IsEmpty(), false); + aOptions.mRequestId = mRequestIdQueue[0]; + mRequestIdQueue.RemoveElementAt(0); + ReadNDEFMessage(aParcel, aOptions); + return true; +} + +bool +NfcMessageHandler::WriteNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions) +{ + aParcel.writeInt32(eNfcRequest_WriteNDEF); + aParcel.writeInt32(aOptions.mSessionId); + WriteNDEFMessage(aParcel, aOptions); + mRequestIdQueue.AppendElement(aOptions.mRequestId); + return true; +} + +bool +NfcMessageHandler::MakeReadOnlyNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions) +{ + aParcel.writeInt32(eNfcRequest_MakeReadOnlyNDEF); + aParcel.writeInt32(aOptions.mSessionId); + mRequestIdQueue.AppendElement(aOptions.mRequestId); + return true; +} + +bool +NfcMessageHandler::ConnectRequest(Parcel& aParcel, const CommandOptions& aOptions) +{ + aParcel.writeInt32(eNfcRequest_Connect); + aParcel.writeInt32(aOptions.mSessionId); + aParcel.writeInt32(aOptions.mTechType); + mRequestIdQueue.AppendElement(aOptions.mRequestId); + return true; +} + +bool +NfcMessageHandler::CloseRequest(Parcel& aParcel, const CommandOptions& aOptions) +{ + aParcel.writeInt32(eNfcRequest_Close); + aParcel.writeInt32(aOptions.mSessionId); + mRequestIdQueue.AppendElement(aOptions.mRequestId); + return true; +} + +bool +NfcMessageHandler::InitializeNotification(const Parcel& aParcel, EventOptions& aOptions) +{ + aOptions.mType = NS_ConvertUTF8toUTF16(kInitializedNotification); + aOptions.mStatus = aParcel.readInt32(); + aOptions.mMajorVersion = aParcel.readInt32(); + aOptions.mMinorVersion = aParcel.readInt32(); + + if (aOptions.mMajorVersion != NFCD_MAJOR_VERSION && + aOptions.mMinorVersion != NFCD_MAJOR_VERSION) { + CHROMIUM_LOG("NFCD version mismatched. majorVersion: %d, minorVersion: %d", + aOptions.mMajorVersion, aOptions.mMinorVersion); + } + + return true; +} + +bool +NfcMessageHandler::TechDiscoveredNotification(const Parcel& aParcel, EventOptions& aOptions) +{ + aOptions.mType = NS_ConvertUTF8toUTF16(kTechDiscoveredNotification); + aOptions.mSessionId = aParcel.readInt32(); + + int32_t techCount = aParcel.readInt32(); + aOptions.mTechList.AppendElements( + static_cast(aParcel.readInplace(techCount)), techCount); + + int32_t ndefMsgCount = aParcel.readInt32(); + if (ndefMsgCount != 0) { + ReadNDEFMessage(aParcel, aOptions); + } + return true; +} + +bool +NfcMessageHandler::TechLostNotification(const Parcel& aParcel, EventOptions& aOptions) +{ + aOptions.mType = NS_ConvertUTF8toUTF16(kTechLostNotification); + aOptions.mSessionId = aParcel.readInt32(); + return true; +} + +bool +NfcMessageHandler::ReadNDEFMessage(const Parcel& aParcel, EventOptions& aOptions) +{ + int32_t recordCount = aParcel.readInt32(); + aOptions.mRecords.SetCapacity(recordCount); + + for (int i = 0; i < recordCount; i++) { + int32_t tnf = aParcel.readInt32(); + NDEFRecordStruct record; + record.mTnf = tnf; + + int32_t typeLength = aParcel.readInt32(); + record.mType.AppendElements( + static_cast(aParcel.readInplace(typeLength)), typeLength); + + int32_t idLength = aParcel.readInt32(); + record.mId.AppendElements( + static_cast(aParcel.readInplace(idLength)), idLength); + + int32_t payloadLength = aParcel.readInt32(); + record.mPayload.AppendElements( + static_cast(aParcel.readInplace(payloadLength)), payloadLength); + + aOptions.mRecords.AppendElement(record); + } + + return true; +} + +bool +NfcMessageHandler::WriteNDEFMessage(Parcel& aParcel, const CommandOptions& aOptions) +{ + int recordCount = aOptions.mRecords.Length(); + aParcel.writeInt32(recordCount); + for (int i = 0; i < recordCount; i++) { + const NDEFRecordStruct& record = aOptions.mRecords[i]; + aParcel.writeInt32(record.mTnf); + + void* data; + + aParcel.writeInt32(record.mType.Length()); + data = aParcel.writeInplace(record.mType.Length()); + memcpy(data, record.mType.Elements(), record.mType.Length()); + + aParcel.writeInt32(record.mId.Length()); + data = aParcel.writeInplace(record.mId.Length()); + memcpy(data, record.mId.Elements(), record.mId.Length()); + + aParcel.writeInt32(record.mPayload.Length()); + data = aParcel.writeInplace(record.mPayload.Length()); + memcpy(data, record.mPayload.Elements(), record.mPayload.Length()); + } + + return true; +} diff --git a/dom/system/gonk/NfcMessageHandler.h b/dom/system/gonk/NfcMessageHandler.h index a6516d0deb1..c98c0872840 100644 --- a/dom/system/gonk/NfcMessageHandler.h +++ b/dom/system/gonk/NfcMessageHandler.h @@ -5,6 +5,9 @@ #ifndef NfcMessageHandler_h #define NfcMessageHandler_h +#include "nsString.h" +#include "nsTArray.h" + namespace android { class MOZ_EXPORT Parcel; } // namespace android @@ -19,6 +22,31 @@ class NfcMessageHandler public: bool Marshall(android::Parcel& aParcel, const CommandOptions& aOptions); bool Unmarshall(const android::Parcel& aParcel, EventOptions& aOptions); + +private: + bool GeneralResponse(const android::Parcel& aParcel, EventOptions& aOptions); + bool ConfigRequest(android::Parcel& aParcel, const CommandOptions& options); + bool ConfigResponse(const android::Parcel& aParcel, EventOptions& aOptions); + bool GetDetailsNDEFRequest(android::Parcel& aParcel, const CommandOptions& options); + bool GetDetailsNDEFResponse(const android::Parcel& aParcel, EventOptions& aOptions); + bool ReadNDEFRequest(android::Parcel& aParcel, const CommandOptions& options); + bool ReadNDEFResponse(const android::Parcel& aParcel, EventOptions& aOptions); + bool WriteNDEFRequest(android::Parcel& aParcel, const CommandOptions& options); + bool MakeReadOnlyNDEFRequest(android::Parcel& aParcel, const CommandOptions& options); + bool ConnectRequest(android::Parcel& aParcel, const CommandOptions& options); + bool CloseRequest(android::Parcel& aParcel, const CommandOptions& options); + + bool InitializeNotification(const android::Parcel& aParcel, EventOptions& aOptions); + bool TechDiscoveredNotification(const android::Parcel& aParcel, EventOptions& aOptions); + bool TechLostNotification(const android::Parcel& aParcel, EventOptions& aOptions); + + bool ReadNDEFMessage(const android::Parcel& aParcel, EventOptions& aOptions); + bool WriteNDEFMessage(android::Parcel& aParcel, const CommandOptions& aOptions); + +private: + nsTArray mPendingReqQueue; + nsTArray mRequestIdQueue; + nsTArray mPowerLevelQueue; }; } // namespace mozilla diff --git a/dom/system/gonk/moz.build b/dom/system/gonk/moz.build index a12cc060577..9d5df3c05e3 100644 --- a/dom/system/gonk/moz.build +++ b/dom/system/gonk/moz.build @@ -110,8 +110,7 @@ if CONFIG['MOZ_NFC']: 'NfcContentHelper.js', ] EXTRA_JS_MODULES += [ - 'nfc_consts.js', - 'nfc_worker.js', + 'nfc_consts.js', ] FAIL_ON_WARNINGS = True diff --git a/dom/system/gonk/nfc_consts.js b/dom/system/gonk/nfc_consts.js index b44e6422fa4..bdec4f7b3b0 100644 --- a/dom/system/gonk/nfc_consts.js +++ b/dom/system/gonk/nfc_consts.js @@ -19,7 +19,6 @@ this.DEBUG_ALL = false; // Set individually to debug specific layers -this.DEBUG_WORKER = false || DEBUG_ALL; this.DEBUG_CONTENT_HELPER = false || DEBUG_ALL; this.DEBUG_NFC = false || DEBUG_ALL; diff --git a/dom/system/gonk/nfc_worker.js b/dom/system/gonk/nfc_worker.js deleted file mode 100644 index 192e93121a2..00000000000 --- a/dom/system/gonk/nfc_worker.js +++ /dev/null @@ -1,426 +0,0 @@ -/* Copyright 2012 Mozilla Foundation and Mozilla contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Copyright © 2013, Deutsche Telekom, Inc. */ - -"use strict"; - -importScripts("systemlibs.js", "nfc_consts.js"); -importScripts("resource://gre/modules/workers/require.js"); - -// set to true in nfc_consts.js to see debug messages -let DEBUG = DEBUG_WORKER; - -function getPaddingLen(len) { - return (len % 4) ? (4 - len % 4) : 0; -} - -let Buf = { - __proto__: (function(){ - return require("resource://gre/modules/workers/worker_buf.js").Buf; - })(), - - init: function init() { - this._init(); - }, - - /** - * Process one parcel. - */ - processParcel: function processParcel() { - let pduType = this.readInt32(); - if (DEBUG) debug("Number of bytes available in Parcel : " + this.readAvailable); - NfcWorker.handleParcel(pduType, this.mCallback); - }, - - /** - * Start a new outgoing parcel. - * - * @param type - * Integer specifying the request type. - * @param callback - */ - newParcel: function newParcel(type, callback) { - if (DEBUG) debug("New outgoing parcel of type " + type); - this.mCallback = callback; - // We're going to leave room for the parcel size at the beginning. - this.outgoingIndex = this.PARCEL_SIZE_SIZE; - this.writeInt32(type); - }, - - simpleRequest: function simpleRequest(type) { - this.newParcel(type); - this.sendParcel(); - }, - - onSendParcel: function onSendParcel(parcel) { - postNfcMessage(parcel); - }, - - /** - * TODO: Bug 933593. Callback map of NFC_RESPONSE_XXX and RequestID - * needs to be maintained - */ - mCallback: null, -}; - -/** - * Provide a high-level API representing NFC capabilities. - * Rensponsible for converting NFC requests from Content process to binary data - * and NFC Responses from binary data to dictionary objects. - */ -let NfcWorker = { - /** - * Handle incoming messages from the main UI thread. - * - * @param message - * Object containing the message. Messages are supposed - */ - handleDOMMessage: function handleMessage(message) { - if (DEBUG) debug("Received DOM message " + JSON.stringify(message)); - let method = this[message.type]; - if (typeof method != "function") { - if (DEBUG) { - debug("Don't know what to do with message " + JSON.stringify(message)); - } - return; - } - method.call(this, message); - }, - - /** - * Unmarshals a NDEF message - */ - unMarshallNdefMessage: function unMarshallNdefMessage() { - let numOfRecords = Buf.readInt32(); - debug("numOfRecords = " + numOfRecords); - if (numOfRecords <= 0) { - return null; - } - let records = []; - - for (let i = 0; i < numOfRecords; i++) { - let tnf = Buf.readInt32() & 0xff; - let typeLength = Buf.readInt32(); - let type = Buf.readUint8Array(typeLength); - let padding = getPaddingLen(typeLength); - for (let i = 0; i < padding; i++) { - Buf.readUint8(); - } - - let idLength = Buf.readInt32(); - let id = Buf.readUint8Array(idLength); - padding = getPaddingLen(idLength); - for (let i = 0; i < padding; i++) { - Buf.readUint8(); - } - - let payloadLength = Buf.readInt32(); - let payload = Buf.readUint8Array(payloadLength); - padding = getPaddingLen(payloadLength); - for (let i = 0; i < padding; i++) { - Buf.readUint8(); - } - records.push({tnf: tnf, - type: type, - id: id, - payload: payload}); - } - return records; - }, - - /** - * Read and return NDEF data, if present. - */ - readNDEF: function readNDEF(message) { - let cb = function callback() { - let error = Buf.readInt32(); - let sessionId = Buf.readInt32(); - let records = this.unMarshallNdefMessage(); - - message.type = "ReadNDEFResponse"; - message.sessionId = sessionId; - message.records = records; - message.status = error; - this.sendDOMMessage(message); - } - - Buf.newParcel(NFC_REQUEST_READ_NDEF, cb); - Buf.writeInt32(message.sessionId); - Buf.sendParcel(); - }, - - /** - * Write to a target that accepts NDEF formattable data - */ - writeNDEF: function writeNDEF(message) { - let cb = function callback() { - let error = Buf.readInt32(); - let sessionId = Buf.readInt32(); - - message.type = "WriteNDEFResponse"; - message.sessionId = sessionId; - message.status = error; - this.sendDOMMessage(message); - }; - - Buf.newParcel(NFC_REQUEST_WRITE_NDEF, cb); - Buf.writeInt32(message.sessionId); - let records = message.records; - let numRecords = records.length; - Buf.writeInt32(numRecords); - for (let i = 0; i < numRecords; i++) { - let record = records[i]; - Buf.writeInt32(record.tnf); - - let typeLength = record.type ? record.type.length : 0; - Buf.writeInt32(typeLength); - for (let j = 0; j < typeLength; j++) { - Buf.writeUint8(record.type[j]); - } - let padding = getPaddingLen(typeLength); - for (let i = 0; i < padding; i++) { - Buf.writeUint8(0x00); - } - - let idLength = record.id ? record.id.length : 0; - Buf.writeInt32(idLength); - for (let j = 0; j < idLength; j++) { - Buf.writeUint8(record.id[j]); - } - padding = getPaddingLen(idLength); - for (let i = 0; i < padding; i++) { - Buf.writeUint8(0x00); - } - - let payloadLength = record.payload ? record.payload.length : 0; - Buf.writeInt32(payloadLength); - for (let j = 0; j < payloadLength; j++) { - Buf.writeUint8(record.payload[j]); - } - padding = getPaddingLen(payloadLength); - for (let i = 0; i < padding; i++) { - Buf.writeUint8(0x00); - } - } - - Buf.sendParcel(); - }, - - /** - * Make the NFC NDEF tag permanently read only - */ - makeReadOnlyNDEF: function makeReadOnlyNDEF(message) { - let cb = function callback() { - let error = Buf.readInt32(); - let sessionId = Buf.readInt32(); - - message.type = "MakeReadOnlyNDEFResponse"; - message.sessionId = sessionId; - message.status = error; - this.sendDOMMessage(message); - }; - - Buf.newParcel(NFC_REQUEST_MAKE_NDEF_READ_ONLY, cb); - Buf.writeInt32(message.sessionId); - Buf.sendParcel(); - }, - - /** - * Retrieve metadata describing the NDEF formatted data, if present. - */ - getDetailsNDEF: function getDetailsNDEF(message) { - let cb = function callback() { - let error = Buf.readInt32(); - let sessionId = Buf.readInt32(); - let isReadOnly = Buf.readUint8(); - let canBeMadeReadOnly = Buf.readUint8(); - // Ensure that padding is taken care here after reading two successive uint8's - Buf.readUint8(); - Buf.readUint8(); - let maxSupportedLength = Buf.readInt32(); - - message.type = "GetDetailsNDEFResponse"; - message.sessionId = sessionId; - message.isReadOnly = isReadOnly; - message.canBeMadeReadOnly = canBeMadeReadOnly; - message.maxSupportedLength = maxSupportedLength; - message.status = error; - this.sendDOMMessage(message); - }; - Buf.newParcel(NFC_REQUEST_GET_DETAILS, cb); - Buf.writeInt32(message.sessionId); - Buf.sendParcel(); - }, - - - /** - * Open a connection to the NFC target. - */ - connect: function connect(message) { - let cb = function callback() { - let error = Buf.readInt32(); - let sessionId = Buf.readInt32(); - - message.type = "ConnectResponse"; - message.sessionId = sessionId; - message.status = error; - this.sendDOMMessage(message); - }; - - Buf.newParcel(NFC_REQUEST_CONNECT, cb); - Buf.writeInt32(message.sessionId); - Buf.writeInt32(message.techType); - Buf.sendParcel(); - }, - - /** - * NFC Configuration - */ - config: function config(message) { - let cb = function callback() { - let error = Buf.readInt32(); - - message.type = "ConfigResponse"; - message.status = error; - this.sendDOMMessage(message); - }; - - Buf.newParcel(NFC_REQUEST_CONFIG , cb); - Buf.writeInt32(message.powerLevel); - Buf.sendParcel(); - }, - - /** - * Close connection to the NFC target. - */ - close: function close(message) { - let cb = function callback() { - let error = Buf.readInt32(); - let sessionId = Buf.readInt32(); - - message.type = "CloseResponse"; - message.sessionId = sessionId; - message.status = error; - this.sendDOMMessage(message); - }; - - Buf.newParcel(NFC_REQUEST_CLOSE , cb); - Buf.writeInt32(message.sessionId); - Buf.sendParcel(); - }, - - handleParcel: function handleParcel(request_type, callback) { - let method = this[request_type]; - if (typeof method == "function") { - if (DEBUG) debug("Handling parcel as " + method.name); - method.call(this); - } else if (typeof callback == "function") { - callback.call(this, request_type); - this.mCallback = null; - } else { - debug("Unable to handle ReqType:"+request_type); - } - }, - - /** - * Send messages to the main UI thread. - */ - sendDOMMessage: function sendDOMMessage(message) { - postMessage(message); - } -}; - -/** - * Notification Handlers - */ -NfcWorker[NFC_NOTIFICATION_INITIALIZED] = function NFC_NOTIFICATION_INITIALIZED () { - let status = Buf.readInt32(); - let majorVersion = Buf.readInt32(); - let minorVersion = Buf.readInt32(); - debug("NFC_NOTIFICATION_INITIALIZED status:" + status); - if ((majorVersion != NFC_MAJOR_VERSION) || (minorVersion != NFC_MINOR_VERSION)) { - debug("Version Mismatch! Current Supported Version : " + - NFC_MAJOR_VERSION + "." + NFC_MINOR_VERSION + - " Received Version : " + majorVersion + "." + minorVersion); - } -}; - -NfcWorker[NFC_NOTIFICATION_TECH_DISCOVERED] = function NFC_NOTIFICATION_TECH_DISCOVERED() { - debug("NFC_NOTIFICATION_TECH_DISCOVERED"); - let techList = []; - let records = null; - - let sessionId = Buf.readInt32(); - let techCount = Buf.readInt32(); - for (let count = 0; count < techCount; count++) { - let tech = NFC_TECHS[Buf.readUint8()]; - if (tech) { - techList.push(tech); - } - } - - let padding = getPaddingLen(techCount); - for (let i = 0; i < padding; i++) { - Buf.readUint8(); - } - - let ndefMsgCount = Buf.readInt32(); - if (ndefMsgCount > 0) { - records = this.unMarshallNdefMessage(); - } - this.sendDOMMessage({type: "techDiscovered", - sessionId: sessionId, - techList: techList, - records: records}); -}; - -NfcWorker[NFC_NOTIFICATION_TECH_LOST] = function NFC_NOTIFICATION_TECH_LOST() { - debug("NFC_NOTIFICATION_TECH_LOST"); - let sessionId = Buf.readInt32(); - debug("sessionId = " + sessionId); - this.sendDOMMessage({type: "techLost", - sessionId: sessionId, - }); -}; - -/** - * Global stuff. - */ - -if (!this.debug) { - // Debugging stub that goes nowhere. - this.debug = function debug(message) { - dump("Nfc Worker: " + message + "\n"); - }; -} - -// Initialize buffers. This is a separate function so that unit tests can -// re-initialize the buffers at will. -Buf.init(); - -function onNfcMessage(data) { - Buf.processIncoming(data); -}; - -onmessage = function onmessage(event) { - NfcWorker.handleDOMMessage(event.data); -}; - -onerror = function onerror(event) { - debug("OnError: event: " + JSON.stringify(event)); - debug("NFC Worker error " + event.message + " " + event.filename + ":" + - event.lineno + ":\n"); -};