From a6eada4aec4f029bce178845755fc64f74370c0c Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Tue, 24 Mar 2015 15:46:55 +0100 Subject: Fix implementation of and improve NdefFilter usage Updated QML docu: describe typeNameFormat, defaults of min/max/orderMatch Removed mention of "both minimum and maximum -1 means matches any numbers": it is unimplemented and QNdefFilter::Record uses unsigned int for min/max Adapt filter logic from QNearFieldManagerPrivateVirtualBase for Android and QNX backends to add support for orderMatch, minimum and maximum properties Adapt filters and examples to use empty type as wildcard (eg Mime records) Change-Id: Id9d51514bb593bd38c3fed89b612af54dffceff0 Reviewed-by: Alex Blasche --- src/imports/nfc/qdeclarativendeffilter.cpp | 12 ++++-- src/imports/nfc/qdeclarativenearfield.cpp | 2 + src/nfc/qnearfieldmanager_android.cpp | 59 +++++++++++++++++++++++++----- src/nfc/qnearfieldmanager_qnx.cpp | 59 +++++++++++++++++++++++++----- src/nfc/qnearfieldmanagervirtualbase.cpp | 3 +- 5 files changed, 111 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/imports/nfc/qdeclarativendeffilter.cpp b/src/imports/nfc/qdeclarativendeffilter.cpp index a3fb1581..508b9d2d 100644 --- a/src/imports/nfc/qdeclarativendeffilter.cpp +++ b/src/imports/nfc/qdeclarativendeffilter.cpp @@ -69,13 +69,19 @@ \c {urn:nfc:wkt:U} to match NFC RTD-URI records. */ +/*! + \qmlproperty QQmlNdefRecord::TypeNameFormat NdefFilter::typeNameFormat + + This property holds the NDEF record name format type \enum QQmlNdefRecord::TypeNameFormat. +*/ + /*! \qmlproperty int NdefFilter::minimum This property holds the minimum number of records of the given type that must be in the NDEF message for it match. - To match any number of records set both the minimum and maximum properties to -1. + The default minimum is 1. \sa maximum */ @@ -86,13 +92,13 @@ This property holds the maximum number of records of the given type that must be in the NDEF message for it match. - To match any number of records set both the minimum and maximum properties to -1. + The default maximum is UINT_MAX. \sa minimum */ QDeclarativeNdefFilter::QDeclarativeNdefFilter(QObject *parent) -: QObject(parent), m_minimum(-1), m_maximum(-1) +: QObject(parent), m_minimum(1), m_maximum(UINT_MAX) { } diff --git a/src/imports/nfc/qdeclarativenearfield.cpp b/src/imports/nfc/qdeclarativenearfield.cpp index 3e45047b..17e6b177 100644 --- a/src/imports/nfc/qdeclarativenearfield.cpp +++ b/src/imports/nfc/qdeclarativenearfield.cpp @@ -92,6 +92,8 @@ This property indicates whether the order of records should be taken into account when matching messages. This is not supported when using neard. + + The default of orderMatch is false. */ /*! diff --git a/src/nfc/qnearfieldmanager_android.cpp b/src/nfc/qnearfieldmanager_android.cpp index 7cb1829f..d1434840 100644 --- a/src/nfc/qnearfieldmanager_android.cpp +++ b/src/nfc/qnearfieldmanager_android.cpp @@ -88,6 +88,12 @@ void QNearFieldManagerPrivateImpl::handlerTargetLost(QNearFieldTarget *target) m_idToTarget.remove(m_idToTarget.key(target)); } +struct VerifyRecord +{ + QNdefFilter::Record filterRecord; + unsigned int count; +}; + void QNearFieldManagerPrivateImpl::handlerNdefMessageRead(const QNdefMessage &message, const QNearFieldTarget::RequestId &id) { QNearFieldTarget *target = m_idToTarget.value(id); @@ -98,20 +104,53 @@ void QNearFieldManagerPrivateImpl::handlerNdefMessageRead(const QNdefMessage &me //For message handlers that specified a filter for (int i = 0; i < ndefFilterHandlers.count(); ++i) { + bool matched = true; + QNdefFilter filter = ndefFilterHandlers.at(i).second.first; - if (filter.recordCount() > message.count()) - continue; - - int j; - for (j = 0; j < filter.recordCount();) { - if (message.at(j).typeNameFormat() != filter.recordAt(j).typeNameFormat - || message.at(j).type() != filter.recordAt(j).type ) { - break; + + QList filterRecords; + for (int j = 0; j < filter.recordCount(); ++j) { + VerifyRecord vr; + vr.count = 0; + vr.filterRecord = filter.recordAt(j); + + filterRecords.append(vr); + } + + foreach (const QNdefRecord &record, message) { + for (int j = 0; matched && (j < filterRecords.count()); ++j) { + VerifyRecord &vr = filterRecords[j]; + + if (vr.filterRecord.typeNameFormat == record.typeNameFormat() && + ( vr.filterRecord.type == record.type() || + vr.filterRecord.type.isEmpty()) ) { + ++vr.count; + break; + } else { + if (filter.orderMatch()) { + if (vr.filterRecord.minimum <= vr.count && + vr.count <= vr.filterRecord.maximum) { + continue; + } else { + matched = false; + } + } + } } - ++j; } - if (j == filter.recordCount()) + + for (int j = 0; matched && (j < filterRecords.count()); ++j) { + const VerifyRecord &vr = filterRecords.at(j); + + if (vr.filterRecord.minimum <= vr.count && vr.count <= vr.filterRecord.maximum) + continue; + else + matched = false; + } + + if (matched) { ndefFilterHandlers.at(i).second.second.invoke(ndefFilterHandlers.at(i).first.second, Q_ARG(QNdefMessage, message), Q_ARG(QNearFieldTarget*, target)); + } } } diff --git a/src/nfc/qnearfieldmanager_qnx.cpp b/src/nfc/qnearfieldmanager_qnx.cpp index 2c3c7077..f4508bd8 100644 --- a/src/nfc/qnearfieldmanager_qnx.cpp +++ b/src/nfc/qnearfieldmanager_qnx.cpp @@ -140,6 +140,12 @@ void QNearFieldManagerPrivateImpl::releaseAccess(QNearFieldManager::TargetAccess //Do nothing, because we don't have access modes for the target } +struct VerifyRecord +{ + QNdefFilter::Record filterRecord; + unsigned int count; +}; + void QNearFieldManagerPrivateImpl::handleMessage(const QNdefMessage &message, QNearFieldTarget *target) { qQNXNFCDebug() << "Handling message in near field manager. Filtercount:" @@ -151,20 +157,53 @@ void QNearFieldManagerPrivateImpl::handleMessage(const QNdefMessage &message, QN //For message handlers that specified a filter for (int i = 0; i < ndefFilterHandlers.count(); i++) { + bool matched = true; + QNdefFilter filter = ndefFilterHandlers.at(i).second.first; - if (filter.recordCount() > message.count()) - continue; - - int j=0; - for (j = 0; j < filter.recordCount();) { - if (message.at(j).typeNameFormat() != filter.recordAt(j).typeNameFormat - || message.at(j).type() != filter.recordAt(j).type ) { - break; + + QList filterRecords; + for (int j = 0; j < filter.recordCount(); ++j) { + VerifyRecord vr; + vr.count = 0; + vr.filterRecord = filter.recordAt(j); + + filterRecords.append(vr); + } + + foreach (const QNdefRecord &record, message) { + for (int j = 0; matched && (j < filterRecords.count()); ++j) { + VerifyRecord &vr = filterRecords[j]; + + if (vr.filterRecord.typeNameFormat == record.typeNameFormat() && + ( vr.filterRecord.type == record.type() || + vr.filterRecord.type.isEmpty()) ) { + ++vr.count; + break; + } else { + if (filter.orderMatch()) { + if (vr.filterRecord.minimum <= vr.count && + vr.count <= vr.filterRecord.maximum) { + continue; + } else { + matched = false; + } + } + } } - j++; } - if (j == filter.recordCount()) + + for (int j = 0; matched && (j < filterRecords.count()); ++j) { + const VerifyRecord &vr = filterRecords.at(j); + + if (vr.filterRecord.minimum <= vr.count && vr.count <= vr.filterRecord.maximum) + continue; + else + matched = false; + } + + if (matched) { ndefFilterHandlers.at(i).second.second.invoke(ndefFilterHandlers.at(i).first.second, Q_ARG(QNdefMessage, message), Q_ARG(QNearFieldTarget*, target)); + } } } diff --git a/src/nfc/qnearfieldmanagervirtualbase.cpp b/src/nfc/qnearfieldmanagervirtualbase.cpp index cf25ed2b..b0f77e2f 100644 --- a/src/nfc/qnearfieldmanagervirtualbase.cpp +++ b/src/nfc/qnearfieldmanagervirtualbase.cpp @@ -172,7 +172,8 @@ void QNearFieldManagerPrivateVirtualBase::ndefReceived(const QNdefMessage &messa VerifyRecord &vr = filterRecords[j]; if (vr.filterRecord.typeNameFormat == record.typeNameFormat() && - vr.filterRecord.type == record.type()) { + ( vr.filterRecord.type == record.type() || + vr.filterRecord.type.isEmpty()) ) { ++vr.count; break; } else { -- cgit v1.2.3