3#if __has_include(<QNearFieldManager>)
6#include <ossia-qt/protocols/utils.hpp>
10#include <QNdefNfcTextRecord>
11#include <QNdefNfcUriRecord>
13#include <QNearFieldManager>
14#include <QNearFieldTarget>
20#include <nano_observer.hpp>
29 ,
public Nano::Observer
31 W_OBJECT(qml_nfc_target)
33 explicit qml_nfc_target(QNearFieldTarget* target, QObject* parent =
nullptr)
38 m_target, &QNearFieldTarget::ndefMessageRead,
this,
39 [
this](
const QNdefMessage& message) {
40 if(!onNdefMessage.isCallable())
42 auto* engine = qjsEngine(
this);
46 auto arr = engine->newArray(message.size());
47 for(qsizetype i = 0; i < message.size(); ++i)
49 const auto& record = message[i];
50 auto obj = engine->newObject();
52 if(record.isRecordType<QNdefNfcTextRecord>())
54 QNdefNfcTextRecord textRecord(record);
55 obj.setProperty(
"type", QStringLiteral(
"text"));
56 obj.setProperty(
"text", textRecord.text());
57 obj.setProperty(
"locale", textRecord.locale());
60 textRecord.encoding() == QNdefNfcTextRecord::Utf8
61 ? QStringLiteral(
"UTF-8")
62 : QStringLiteral(
"UTF-16"));
64 else if(record.isRecordType<QNdefNfcUriRecord>())
66 QNdefNfcUriRecord uriRecord(record);
67 obj.setProperty(
"type", QStringLiteral(
"uri"));
68 obj.setProperty(
"uri", uriRecord.uri().toString());
72 obj.setProperty(
"type", QStringLiteral(
"raw"));
75 static_cast<int>(record.typeNameFormat()));
77 "recordType", engine->toScriptValue(record.type()));
79 "payload", engine->toScriptValue(record.payload()));
80 obj.setProperty(
"id", engine->toScriptValue(record.id()));
83 arr.setProperty(i, obj);
85 onNdefMessage.call({arr});
89 m_target, &QNearFieldTarget::error,
this,
91 QNearFieldTarget::Error error,
92 const QNearFieldTarget::RequestId&) {
93 if(!onError.isCallable())
98 case QNearFieldTarget::NoError:
100 case QNearFieldTarget::UnsupportedError:
101 msg = QStringLiteral(
"Unsupported operation");
103 case QNearFieldTarget::TargetOutOfRangeError:
104 msg = QStringLiteral(
"Target out of range");
106 case QNearFieldTarget::NoResponseError:
107 msg = QStringLiteral(
"No response");
109 case QNearFieldTarget::ChecksumMismatchError:
110 msg = QStringLiteral(
"Checksum mismatch");
112 case QNearFieldTarget::InvalidParametersError:
113 msg = QStringLiteral(
"Invalid parameters");
115 case QNearFieldTarget::ConnectionError:
116 msg = QStringLiteral(
"Connection error");
118 case QNearFieldTarget::NdefReadError:
119 msg = QStringLiteral(
"NDEF read error");
121 case QNearFieldTarget::NdefWriteError:
122 msg = QStringLiteral(
"NDEF write error");
124 case QNearFieldTarget::CommandError:
125 msg = QStringLiteral(
"Command error");
127 case QNearFieldTarget::TimeoutError:
128 msg = QStringLiteral(
"Timeout");
131 msg = QStringLiteral(
"Unknown NFC error");
142 return m_target->uid().toHex(
':');
150 return static_cast<int>(m_target->type());
157 m_target->readNdefMessages();
161 void writeNdef(QJSValue records)
165 auto* engine = qjsEngine(
this);
166 if(!engine || !records.isArray())
169 QNdefMessage message;
170 auto length = records.property(
"length").toInt();
171 for(
int i = 0; i < length; ++i)
173 auto rec = records.property(i);
174 auto recType = rec.property(
"type").toString();
175 if(recType ==
"text")
177 QNdefNfcTextRecord textRecord;
178 textRecord.setText(rec.property(
"text").toString());
179 if(rec.hasProperty(
"locale"))
180 textRecord.setLocale(rec.property(
"locale").toString());
182 textRecord.setLocale(QStringLiteral(
"en"));
183 message.append(textRecord);
185 else if(recType ==
"uri")
187 QNdefNfcUriRecord uriRecord;
188 uriRecord.setUri(QUrl(rec.property(
"uri").toString()));
189 message.append(uriRecord);
191 else if(recType ==
"raw")
193 QNdefRecord rawRecord;
194 rawRecord.setTypeNameFormat(
static_cast<QNdefRecord::TypeNameFormat
>(
195 rec.property(
"typeNameFormat").toInt()));
196 rawRecord.setType(rec.property(
"recordType").toVariant().toByteArray());
197 rawRecord.setPayload(
198 rec.property(
"payload").toVariant().toByteArray());
199 if(rec.hasProperty(
"id"))
200 rawRecord.setId(rec.property(
"id").toVariant().toByteArray());
201 message.append(rawRecord);
205 m_target->writeNdefMessages({message});
209 void sendCommand(QByteArray command)
212 m_target->sendCommand(command);
216 QJSValue onNdefMessage;
220 QPointer<QNearFieldTarget> m_target;
225 ,
public Nano::Observer
227 W_OBJECT(qml_nfc_scanner)
231 m_manager =
new QNearFieldManager(
this);
234 m_manager, &QNearFieldManager::targetDetected,
this,
235 [
this](QNearFieldTarget* target) {
236 if(!onTargetDetected.isCallable())
238 auto* engine = qjsEngine(
this);
249 auto existing = target->findChildren<qml_nfc_target*>(
250 QString(), Qt::FindDirectChildrenOnly);
251 if(!existing.isEmpty())
253 onTargetDetected.call({engine->newQObject(existing.first())});
261 auto* wrapper =
new qml_nfc_target(target, target);
262 auto jsWrapper = engine->newQObject(wrapper);
264 if(onNdefMessage.isCallable())
265 wrapper->onNdefMessage = onNdefMessage;
266 if(onError.isCallable())
267 wrapper->onError = onError;
269 onTargetDetected.call({jsWrapper});
273 m_manager, &QNearFieldManager::targetLost,
this,
274 [
this](QNearFieldTarget*) {
275 if(onTargetLost.isCallable())
280 m_manager, &QNearFieldManager::adapterStateChanged,
this,
281 [
this](QNearFieldManager::AdapterState state) {
282 if(!onAdapterStateChanged.isCallable())
287 case QNearFieldManager::AdapterState::Offline:
288 stateStr = QStringLiteral(
"offline");
290 case QNearFieldManager::AdapterState::TurningOn:
291 stateStr = QStringLiteral(
"turning_on");
293 case QNearFieldManager::AdapterState::Online:
294 stateStr = QStringLiteral(
"online");
296 case QNearFieldManager::AdapterState::TurningOff:
297 stateStr = QStringLiteral(
"turning_off");
300 onAdapterStateChanged.call({stateStr});
304 ~qml_nfc_scanner() { stop(); }
308 m_manager->startTargetDetection(QNearFieldTarget::NdefAccess);
314 m_manager->startTargetDetection(QNearFieldTarget::TagTypeSpecificAccess);
318 void stop() { m_manager->stopTargetDetection(); }
321 bool isEnabled()
const {
return m_manager->isEnabled(); }
324 QJSValue onTargetDetected;
325 QJSValue onTargetLost;
326 QJSValue onNdefMessage;
327 QJSValue onAdapterStateChanged;
331 QNearFieldManager* m_manager{};
Definition qml_device.cpp:43