зеркало из https://github.com/mozilla/gecko-dev.git
Bug 933588 - Part 2: NfcMessageHandler. r=dimi
This commit is contained in:
Родитель
c3e7baef48
Коммит
d489a4a5ba
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -3,17 +3,65 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "NfcMessageHandler.h"
|
||||
|
||||
#include <binder/Parcel.h>
|
||||
#include "nsDebug.h"
|
||||
#include "NfcGonkMessage.h"
|
||||
#include "NfcOptions.h"
|
||||
|
||||
#include <android/log.h>
|
||||
#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<const uint8_t*>(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<const uint8_t*>(aParcel.readInplace(typeLength)), typeLength);
|
||||
|
||||
int32_t idLength = aParcel.readInt32();
|
||||
record.mId.AppendElements(
|
||||
static_cast<const uint8_t*>(aParcel.readInplace(idLength)), idLength);
|
||||
|
||||
int32_t payloadLength = aParcel.readInt32();
|
||||
record.mPayload.AppendElements(
|
||||
static_cast<const uint8_t*>(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;
|
||||
}
|
||||
|
|
|
@ -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<int32_t> mPendingReqQueue;
|
||||
nsTArray<nsString> mRequestIdQueue;
|
||||
nsTArray<int32_t> mPowerLevelQueue;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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");
|
||||
};
|
Загрузка…
Ссылка в новой задаче