123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- /*
- * Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
- * All rights reserved.
- * This component and the accompanying materials are made available
- * under the terms of "Eclipse Public License v1.0"
- * which accompanies this distribution, and is available
- * at the URL "http://www.eclipse.org/legal/epl-v10.html".
- *
- * Initial Contributors:
- * Nokia Corporation - initial contribution.
- *
- * Contributors:
- *
- * Description: NfcNppExample.
- */
- #include "nfcnppexample.h"
- #include <QUrl>
- #include <qllcpserver.h>
- #include <qndefrecord.h>
- #include <qndefnfctextrecord.h>
- #include <qndefnfcurirecord.h>
- #include <qnearfieldmanager.h>
- // Constants
- const quint8 NPPVersion = 1;
- const quint8 NPPActionCode = 1;
- const QLatin1String NPPServiceName("com.android.npp");
- NfcNppExample::NfcNppExample(QObject *parent) :
- QObject(parent)
- {
- nfcManager = new QNearFieldManager(this);
- connect(nfcManager, SIGNAL(targetDetected(QNearFieldTarget*)),
- this, SLOT(handleTargetDetected(QNearFieldTarget*)));
- connect(nfcManager, SIGNAL(targetLost(QNearFieldTarget*)),
- this, SLOT(handleTargetLost(QNearFieldTarget*)));
- // Only detect other NFC devices. Leave the phone to handle NFC tags.
- nfcManager->setTargetAccessModes(QNearFieldManager::NdefReadTargetAccess | QNearFieldManager::NdefWriteTargetAccess);
- nfcManager->startTargetDetection(QNearFieldTarget::NfcForumDevice);
- nfcServer = new QLlcpServer(this);
- connect(nfcServer, SIGNAL(newConnection()), this, SLOT(handleNewConnection()));
- nfcServer->listen(NPPServiceName);
- nfcClientSocket = new QLlcpSocket(this);
- connect(nfcClientSocket, SIGNAL(stateChanged(QLlcpSocket::SocketState)), this, SLOT(handleSocketStateChanged(QLlcpSocket::SocketState)));
- // QueuedConnection is used to close the connection on the next event loop event.
- connect(this, SIGNAL(closeConnection()), this, SLOT(handleCloseConnection()), Qt::QueuedConnection);
- }
- NfcNppExample::~NfcNppExample()
- {
- // empty implementation.
- }
- void NfcNppExample::handleTargetDetected(QNearFieldTarget *target)
- {
- // Check if the target supports LLCP access
- QNearFieldTarget::AccessMethods accessMethods = target->accessMethods();
- if (accessMethods.testFlag(QNearFieldTarget::LlcpAccess)) {
- nfcClientSocket->connectToService(target, NPPServiceName);
- }
- }
- void NfcNppExample::handleTargetLost(QNearFieldTarget *target)
- {
- nfcClientSocket->disconnectFromService();
- target->deleteLater();
- }
- void NfcNppExample::handleNewConnection()
- {
- if (nfcServerSocket) {
- nfcServerSocket->deleteLater();
- }
- // The socket is a child of the server and will therefore be deleted automatically
- nfcServerSocket = nfcServer->nextPendingConnection();
- connect(nfcServerSocket, SIGNAL(readyRead()), this, SLOT(readMessage()));
- }
- void NfcNppExample::handleSocketStateChanged(QLlcpSocket::SocketState socketState)
- {
- switch ( socketState )
- {
- case QLlcpSocket::ConnectedState:
- // Connection opened.
- emit targetConnected();
-
- //Try to send the message.
- if (nfcClientSocket && nfcClientSocket->isOpen()) {
- nfcClientSocket->write(ndefMessage);
- emit closeConnection();
- }
- break;
- default:
- break;
- }
- }
- void NfcNppExample::readMessage()
- {
- QByteArray rawData = nfcServerSocket->readAll();
- QList<QNdefMessage> messages;
- messages = parseNppMessage(rawData);
- QNdefMessage message = messages[0];
- foreach (const QNdefRecord &record, message) {
- if (record.isRecordType<QNdefNfcUriRecord>()) {
- QNdefNfcUriRecord uriRecord(record);
- emit messageReceived(record.type(), uriRecord.uri().toString());
- } else if (record.isRecordType<QNdefNfcTextRecord>()) {
- QNdefNfcTextRecord textRecord(record);
- emit messageReceived(record.type(), textRecord.text());
- }
- }
- }
- void NfcNppExample::sendMessage(const QString &type, const QString &text)
- {
- // Buffers the message.
- QNdefMessage message;
- if (type.compare("U") == 0) {
- QNdefNfcUriRecord uriRecord;
- uriRecord.setUri(QUrl(text));
- message.append(uriRecord);
- } else {
- QNdefNfcTextRecord textRecord;
- textRecord.setText(text);
- message.append(textRecord);
- }
- QList<QNdefMessage> messageArray;
- messageArray.append(message);
- ndefMessage = createNppMessage(messageArray);
- }
- QList<QNdefMessage> NfcNppExample::parseNppMessage(const QByteArray &array) const
- {
- QList<QNdefMessage> messages;
- QByteArray::const_iterator i = array.begin();
- while (i < array.constEnd()) {
- quint8 version = *i;
- if (version != NPPVersion) {
- return messages;
- }
- quint32 messageCount = 0;
- messageCount = quint8(*(++i)) << 24;
- messageCount |= quint8(*(++i)) << 16;
- messageCount |= quint8(*(++i)) << 8;
- messageCount |= quint8(*(++i)) << 0;
- if (messageCount == 1) {
- quint8 actionCode = *(++i);
- quint32 ndefLength = quint8(*(++i)) << 24;
- ndefLength |= quint8(*(++i)) << 16;
- ndefLength |= quint8(*(++i)) << 8;
- ndefLength |= quint8(*(++i)) << 0;
- QByteArray ndef(++i, ndefLength);
- QNdefMessage message = QNdefMessage::fromByteArray(ndef);
- messages.append(message);
- i += ndefLength;
- }
- }
- return messages;
- }
- QByteArray NfcNppExample::createNppMessage(const QList<QNdefMessage> &messages) const
- {
- QByteArray message;
- if (messages.count() != 1) {
- return message;
- }
- message.append(NPPVersion);
- quint32 messageCount = messages.count();
- message.append(messageCount >> 24);
- message.append(messageCount >> 16);
- message.append(messageCount >> 8);
- message.append(messageCount);
- // Only supported action code is 0x01 and only one NDEF entry
- // with the action code 0x01 is allowed.
- message.append(NPPActionCode);
- QByteArray entry = messages[0].toByteArray();
- quint32 ndefLength = entry.length();
- message.append(ndefLength >> 24);
- message.append(ndefLength >> 16);
- message.append(ndefLength >> 8);
- message.append(ndefLength);
- message.append(entry);
- return message;
- }
- void NfcNppExample::handleCloseConnection()
- {
- // Disconnect the open connection.
- if (nfcClientSocket && nfcClientSocket->isOpen()) {
- nfcClientSocket->disconnectFromService();
- }
- }
|