diff options
Diffstat (limited to 'chicken-wranglers/src/network')
24 files changed, 2734 insertions, 0 deletions
diff --git a/chicken-wranglers/src/network/bluetoothconnection.cpp b/chicken-wranglers/src/network/bluetoothconnection.cpp new file mode 100644 index 0000000..b315fbc --- /dev/null +++ b/chicken-wranglers/src/network/bluetoothconnection.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include <QBluetoothAddress> +#include <QtCore/QByteArray> + +#include "bluetoothconnection.h" + +BluetoothConnection::BluetoothConnection(QObject *parent, QBluetoothSocket *socket) + : NetworkConnection(parent), m_socket(socket) +{ + if (m_socket == 0) + m_socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket, this); + + connect(m_socket, SIGNAL(connected()), + this, SIGNAL(connected())); + connect(m_socket, SIGNAL(disconnected()), + this, SIGNAL(disconnected())); + connect(m_socket, SIGNAL(error(QBluetoothSocket::SocketError)), + this, SIGNAL(error(QBluetoothSocket::SocketError))); + connect(m_socket, SIGNAL(readyRead()), + this, SLOT(processReadyRead())); +} + +BluetoothConnection::~BluetoothConnection() +{ + if (m_socket) + m_socket->abort(); +} + +void BluetoothConnection::setId(const quint16 &newId) +{ + m_id = newId; +} + +quint16 BluetoothConnection::id() const +{ + return m_id; +} + +void BluetoothConnection::send(NetworkMessage message) +{ + if (m_socket->write(message.byteArray()) == -1) + qWarning("Bluetooth Socket write error: %s", m_socket->errorString().toUtf8().constData()); +} + +void BluetoothConnection::connectToHost(const QString &address, const quint16 &port) +{ + m_socket->connectToService(QBluetoothAddress(address), port); +} + +void BluetoothConnection::disconnectFromHost() +{ + m_socket->disconnectFromService(); +} + +QAbstractSocket::SocketState BluetoothConnection::state() const +{ + return static_cast<QAbstractSocket::SocketState>(m_socket->state()); +} + +QAbstractSocket::SocketError BluetoothConnection::error() const +{ + return static_cast<QAbstractSocket::SocketError>(m_socket->error()); +} + +QString BluetoothConnection::errorString() const +{ + return m_socket->errorString(); +} + +void BluetoothConnection::processReadyRead() +{ + processRead(m_socket); +} + +void BluetoothConnection::close() +{ + m_socket.data()->close(); +} diff --git a/chicken-wranglers/src/network/bluetoothconnection.h b/chicken-wranglers/src/network/bluetoothconnection.h new file mode 100644 index 0000000..a37c5d8 --- /dev/null +++ b/chicken-wranglers/src/network/bluetoothconnection.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef BLUETOOTHCONNECTION_H +#define BLUETOOTHCONNECTION_H + +#include "networkconnection.h" + +#include <QBluetoothSocket> +#include <QtCore/QObject> +#include <QtCore/QPointer> +#include <QtNetwork/QHostAddress> + +QTM_USE_NAMESPACE + +class BluetoothConnection : public NetworkConnection +{ + Q_OBJECT + +public: + BluetoothConnection(QObject *parent = 0, QBluetoothSocket *socket = 0); + ~BluetoothConnection(); + + void setId(const quint16 &newId); + quint16 id() const; + + void send(NetworkMessage message); + + void connectToHost(const QString &address, const quint16 &port); + void disconnectFromHost(); + + QAbstractSocket::SocketState state() const; + QAbstractSocket::SocketError error() const; + QString errorString() const; + + void close(); + +signals: + void connected(); + void disconnected(); + void error(QBluetoothSocket::SocketError socketError); + +private slots: + void processReadyRead(); + +private: + QPointer<QBluetoothSocket> m_socket; +}; + +#endif diff --git a/chicken-wranglers/src/network/bluetoothhandler.cpp b/chicken-wranglers/src/network/bluetoothhandler.cpp new file mode 100644 index 0000000..feb5244 --- /dev/null +++ b/chicken-wranglers/src/network/bluetoothhandler.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + +#include "bluetoothhandler.h" + +#include "connectionfactory.h" +#include "network.h" +#include "networkconnection.h" + +BluetoothHandler::BluetoothHandler(QObject *parent, int maxConnections) + : QRfcommServer(parent), m_serviceInfo(QBluetoothServiceInfo()) + , m_listenPort(14), m_maxConnections(maxConnections) +{ + connect(this, SIGNAL(newConnection()), this, SLOT(newClientConnection())); +} + +BluetoothHandler::~BluetoothHandler() +{ + closeAll(); + stop(); +} + +void BluetoothHandler::start() +{ + if (isListening()) { + emit started(); + return; + } + + QBluetoothAddress address; + + if (listen(address, m_listenPort)) { + qWarning("Server started on port: %d", serverPort()); + emit started(); + registerService(); + } else { + qWarning("Error: Unable to start server"); + emit startError(); + } +} + +void BluetoothHandler::stop() +{ + if (isListening()) + close(); + + m_serviceInfo.unregisterService(); +} + +void BluetoothHandler::setListenPort(const quint16 &port) +{ + if (m_listenPort != port) { + m_listenPort = port; + + emit listenPortChanged(); + } +} + +quint16 BluetoothHandler::listenPort() const +{ + return m_listenPort; +} + +void BluetoothHandler::newClientConnection() +{ + if (m_connections.size() == m_maxConnections) + return; + + NetworkConnection *connection; + connection = ConnectionFactory::create(ConnectionFactory::Bluetooth, + this, nextPendingConnection()); + + for (quint16 id = 0; id < m_maxConnections; id++) { + // If the peer ID is NOT on the dictionary, insert it + if (!m_connections.contains(id)) { + connection->setId(id); + + connect(connection, SIGNAL(disconnected()), + this, SLOT(peerDisconnected())); + connect(connection, SIGNAL(error(QBluetoothSocket::SocketError)), + this, SLOT(socketError(QBluetoothSocket::SocketError))); + connect(connection, SIGNAL(received(NetworkMessage)), + this, SIGNAL(received(NetworkMessage))); + + m_connections[id] = connection; + + // Signals that a new peer has connected + emit peerConnected(connection); + + break; + } + } +} + +void BluetoothHandler::closeAll() +{ + NetworkConnection *tmp; + int pos = 0; + while (m_connections.size()) { + tmp = m_connections[pos]; + tmp->close(); + delete tmp; + ++pos; + } + + m_connections.clear(); +} + +void BluetoothHandler::send(const NetworkMessage &message) +{ + m_connections[message.id()]->send(message); +} + +void BluetoothHandler::peerDisconnected() +{ + NetworkConnection *connection = qobject_cast<NetworkConnection *>(sender()); + m_connections.remove(connection->id()); + + // Signals that a peer has disconnected + emit peerDisconnected(connection); +} + +void BluetoothHandler::socketError(QBluetoothSocket::SocketError socketError) +{ + NetworkConnection *connection = qobject_cast<NetworkConnection *>(sender()); + quint16 id = connection->id(); + + qWarning("Bluetooth Socket error [ %d ]: %s", socketError, + connection->errorString().toUtf8().constData()); + emit peerError(static_cast<QAbstractSocket::SocketError>(socketError), id); +} + +void BluetoothHandler::registerService() +{ + m_serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceRecordHandle, (uint) 0x00010010); + + // TODO: Profile Descriptor List: "Serial Port" (0x1101) + QBluetoothServiceInfo::Sequence classId; + classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); + m_serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId); + + m_serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceName, + tr("ChickenWranglers")); + m_serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceDescription, + tr("Game bluetooth server")); + m_serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceProvider, + tr("Openbossa")); + m_serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList, + QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); + + QBluetoothServiceInfo::Sequence protocolDescriptorList; + QBluetoothServiceInfo::Sequence protocol; + protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) + << QVariant::fromValue(quint8(serverPort())); + protocolDescriptorList.append(QVariant::fromValue(protocol)); + m_serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, + protocolDescriptorList); + + m_serviceInfo.registerService(); +} diff --git a/chicken-wranglers/src/network/bluetoothhandler.h b/chicken-wranglers/src/network/bluetoothhandler.h new file mode 100644 index 0000000..5248fc3 --- /dev/null +++ b/chicken-wranglers/src/network/bluetoothhandler.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef BLUETOOTHHANDLER_H +#define BLUETOOTHHANDLER_H + +#include "networkmessage.h" + +#include <QBluetoothServiceInfo> +#include <QBluetoothSocket> +#include <QRfcommServer> +#include <QtCore/QHash> + +class NetworkConnection; + +QTM_USE_NAMESPACE + +class BluetoothHandler : public QRfcommServer +{ + Q_OBJECT + + Q_PROPERTY(quint16 listenPort READ listenPort WRITE setListenPort NOTIFY listenPortChanged) + +public: + BluetoothHandler(QObject *parent = 0, int maxConnections = 4); + ~BluetoothHandler(); + + void start(); + void stop(); + + void setListenPort(const quint16 &port); + quint16 listenPort() const; + + void send(const NetworkMessage &message); + void closeAll(); + +signals: + void peerConnected(NetworkConnection *connection); + void peerDisconnected(NetworkConnection *connection); + void peerError(QAbstractSocket::SocketError socketError, quint16 id); + void received(const NetworkMessage &message); + void started(); + void listenPortChanged(); + void startError(); + +private slots: + void newClientConnection(); + void peerDisconnected(); + void socketError(QBluetoothSocket::SocketError socketError); + +protected: + void registerService(); + +private: + QHash<quint16, NetworkConnection *> m_connections; + QBluetoothServiceInfo m_serviceInfo; + quint16 m_listenPort; + int m_maxConnections; +}; + +#endif diff --git a/chicken-wranglers/src/network/bthandler.cpp b/chicken-wranglers/src/network/bthandler.cpp new file mode 100644 index 0000000..60d8e08 --- /dev/null +++ b/chicken-wranglers/src/network/bthandler.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include <QBluetoothAddress> +#include <QBluetoothDeviceDiscoveryAgent> +#include <QBluetoothLocalDevice> + +#include "bthandler.h" + +BtHandler::BtHandler(QObject *parent) + : QObject(parent), m_discoveryAgent(new QBluetoothDeviceDiscoveryAgent(this)), + m_localDevice(new QBluetoothLocalDevice(this)), m_devices(new QList<BluetoothDevice>) +{ + connect(m_discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo &)), + this, SLOT(deviceDiscovered(const QBluetoothDeviceInfo &))); +} + +BtHandler::~BtHandler() +{ + delete m_devices; +} + +void BtHandler::enable() +{ + m_discoveryAgent->start(); +} + +void BtHandler::disable() +{ + m_discoveryAgent->stop(); +} + +void BtHandler::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo) +{ + BluetoothDevice device; + + device.setAddress(deviceInfo.address().toString()); + if (deviceInfo.name().isEmpty()) + device.setName(device.address()); + else + device.setName(deviceInfo.name()); + + device.setPaired(m_localDevice->pairingStatus(deviceInfo.address())); + device.setCategory(quint8(deviceInfo.majorDeviceClass())); + + m_devices->append(device); + + emit discovered(device); +} diff --git a/chicken-wranglers/src/network/bthandler.h b/chicken-wranglers/src/network/bthandler.h new file mode 100644 index 0000000..243bca5 --- /dev/null +++ b/chicken-wranglers/src/network/bthandler.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef BTHANDLER_H +#define BTHANDLER_H + +#include "bluetoothdevice.h" + +#include <QtCore/QList> +#include <QtCore/QObject> +#include <qmobilityglobal.h> + +QTM_BEGIN_NAMESPACE + +class QBluetoothDeviceDiscoveryAgent; +class QBluetoothDeviceInfo; +class QBluetoothLocalDevice; + +QTM_END_NAMESPACE + +QTM_USE_NAMESPACE + +class BtHandler : public QObject +{ + Q_OBJECT + +public: + BtHandler(QObject *parent = 0); + ~BtHandler(); + + void enable(); + void disable(); + +signals: + void finished(); + void discovered(const BluetoothDevice &device); + +private slots: + void deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo); + +private: + QBluetoothDeviceDiscoveryAgent *m_discoveryAgent; + QBluetoothLocalDevice *m_localDevice; + QList<BluetoothDevice> *m_devices; +}; + +#endif diff --git a/chicken-wranglers/src/network/connectionfactory.cpp b/chicken-wranglers/src/network/connectionfactory.cpp new file mode 100644 index 0000000..6926bcb --- /dev/null +++ b/chicken-wranglers/src/network/connectionfactory.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "connectionfactory.h" + +#include "bluetoothconnection.h" +#include "tcpconnection.h" + +#include <QtCore/QIODevice> +#include <QtCore/QObject> + +ConnectionFactory::ConnectionFactory() +{ +} + +NetworkConnection *ConnectionFactory::create(ConnectionType connection, QObject *parent, + QIODevice *socket) +{ + NetworkConnection *result = 0; + + switch (connection) { + case Lan: + result = new TcpConnection(parent, dynamic_cast<QTcpSocket *>(socket)); + break; + case Bluetooth: + result = new BluetoothConnection(parent, dynamic_cast<QBluetoothSocket *>(socket)); + break; + } + + return result; +} diff --git a/chicken-wranglers/src/network/connectionfactory.h b/chicken-wranglers/src/network/connectionfactory.h new file mode 100644 index 0000000..06333f0 --- /dev/null +++ b/chicken-wranglers/src/network/connectionfactory.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef CONNECTIONFACTORY_H +#define CONNECTIONFACTORY_H + +class QIODevice; +class QObject; +class NetworkConnection; + +class ConnectionFactory +{ +public: + enum ConnectionType { + Lan, + Bluetooth + }; + + static NetworkConnection *create(ConnectionType connection, QObject *parent = 0, + QIODevice *socket = 0); + +private: + ConnectionFactory(); +}; + +#endif diff --git a/chicken-wranglers/src/network/lanhandler.cpp b/chicken-wranglers/src/network/lanhandler.cpp new file mode 100644 index 0000000..ec1c12c --- /dev/null +++ b/chicken-wranglers/src/network/lanhandler.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + +#include "lanhandler.h" + +#include "connectionfactory.h" +#include "network.h" +#include "networkconnection.h" + +LanHandler::LanHandler(QObject *parent, int maxConnections) + : QTcpServer(parent), m_maxConnections(maxConnections) +{ + connect(this, SIGNAL(newConnection()), this, SLOT(newClientConnection())); +} +LanHandler::~LanHandler() +{ + closeAll(); + stop(); +} + +void LanHandler::newClientConnection() +{ + if (m_connections.size() == m_maxConnections) + return; + + NetworkConnection *connection; + connection = ConnectionFactory::create(ConnectionFactory::Lan, + this, nextPendingConnection()); + + for (quint16 id = 0; id < m_maxConnections; id++) { + // If the peer ID is NOT on the dictionary, insert it + if (!m_connections.contains(id)) { + connection->setId(id); + + connect(connection, SIGNAL(disconnected()), + this, SLOT(peerDisconnected())); + connect(connection, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(socketError(QAbstractSocket::SocketError))); + connect(connection, SIGNAL(received(NetworkMessage)), + this, SIGNAL(received(NetworkMessage))); + + m_connections[id] = connection; + + // Signals that a new peer has connected + emit peerConnected(connection); + + break; + } + } +} + +void LanHandler::closeAll() +{ + NetworkConnection *tmp; + int pos = 0; + while (m_connections.size()) { + tmp = m_connections[pos]; + tmp->close(); + delete tmp; + ++pos; + } + + m_connections.clear(); +} + +void LanHandler::send(const NetworkMessage &message) +{ + m_connections[message.id()]->send(message); +} + +void LanHandler::peerDisconnected() +{ + NetworkConnection *connection = qobject_cast<NetworkConnection *>(sender()); + m_connections.remove(connection->id()); + + // Signals that a peer has disconnected + emit peerDisconnected(connection); +} + +void LanHandler::socketError(QAbstractSocket::SocketError socketError) +{ + NetworkConnection *connection = qobject_cast<NetworkConnection *>(sender()); + quint16 id = connection->id(); + + qWarning("TCP Socket error [ %d ]: %s", socketError, + connection->errorString().toUtf8().constData()); + + emit peerError(socketError, id); +} + +void LanHandler::stop() +{ + if (isListening()) + close(); +} diff --git a/chicken-wranglers/src/network/lanhandler.h b/chicken-wranglers/src/network/lanhandler.h new file mode 100644 index 0000000..457b474 --- /dev/null +++ b/chicken-wranglers/src/network/lanhandler.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef LANHANDLER_H +#define LANHANDLER_H + +#include "networkmessage.h" + +#include <QtCore/QHash> +#include <QtNetwork/QTcpServer> + +class NetworkConnection; + +class LanHandler : public QTcpServer +{ + Q_OBJECT + +public: + LanHandler(QObject *parent = 0, int maxConnections = 4); + ~LanHandler(); + + void stop(); + void send(const NetworkMessage &message); + void closeAll(); + +signals: + void peerConnected(NetworkConnection *connection); + void peerDisconnected(NetworkConnection *connection); + void peerError(QAbstractSocket::SocketError socketError, quint16 id); + void received(const NetworkMessage &message); + void startError(); + +private slots: + void newClientConnection(); + void peerDisconnected(); + void socketError(QAbstractSocket::SocketError socketError); + +private: + QHash<quint16, NetworkConnection *> m_connections; + int m_maxConnections; +}; + +#endif diff --git a/chicken-wranglers/src/network/network.h b/chicken-wranglers/src/network/network.h new file mode 100644 index 0000000..2b86ded --- /dev/null +++ b/chicken-wranglers/src/network/network.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef NETWORK_H +#define NETWORK_H + +#include <QtCore/QByteArray> +#include <QtGlobal> + +namespace CW +{ + enum UdpSenderType { + UdpSenderNoType = 0, + UdpSenderClient = 1, + UdpSenderServer = 2, + UdpSenderAny = UdpSenderClient | UdpSenderServer + }; + + enum UdpContentType { + UdpNoContent = 200, + UdpContentDiscovery, + UdpContentAckDiscovery, + }; + + static const char udpMessageSeparator = '/'; +} + +#endif diff --git a/chicken-wranglers/src/network/network.pri b/chicken-wranglers/src/network/network.pri new file mode 100644 index 0000000..81f9d36 --- /dev/null +++ b/chicken-wranglers/src/network/network.pri @@ -0,0 +1,37 @@ +QT += network + +maemo5 { + CONFIG += mobility12 +} else { + CONFIG += mobility +} +MOBILITY += connectivity + +PATH = $$PWD + +HEADERS += \ + $$PATH/network.h \ + $$PATH/networkclient.h \ + $$PATH/networkserver.h \ + $$PATH/udphandler.h \ + $$PATH/networkmessage.h \ + $$PATH/networkconnection.h \ + $$PATH/bluetoothconnection.h \ + $$PATH/tcpconnection.h \ + $$PATH/connectionfactory.h \ + $$PATH/lanhandler.h \ + $$PATH/bluetoothhandler.h \ + $$PATH/bthandler.h + +SOURCES += \ + $$PATH/networkclient.cpp \ + $$PATH/networkserver.cpp \ + $$PATH/udphandler.cpp \ + $$PATH/networkmessage.cpp \ + $$PATH/networkconnection.cpp \ + $$PATH/bluetoothconnection.cpp \ + $$PATH/tcpconnection.cpp \ + $$PATH/connectionfactory.cpp \ + $$PATH/lanhandler.cpp \ + $$PATH/bluetoothhandler.cpp \ + $$PATH/bthandler.cpp diff --git a/chicken-wranglers/src/network/networkclient.cpp b/chicken-wranglers/src/network/networkclient.cpp new file mode 100644 index 0000000..58dba98 --- /dev/null +++ b/chicken-wranglers/src/network/networkclient.cpp @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + +#include "networkclient.h" + +#include "bthandler.h" +#include "connectionfactory.h" +#include "network.h" +#include "networkconnection.h" +#include "udphandler.h" + +#include <QtCore/QList> +#include <QtCore/QTimer> + + +NetworkClient::NetworkClient(const QString &connectivity, int discoveryTimeout, + int clientAttempts, QObject *parent) + : QObject(parent), m_udpHandler(0), m_btHandler(0), m_connection(0), + m_discoveryTimer(0), m_discoveryAttempts(0), + m_discoveryTimeout(discoveryTimeout), m_discoveryClientAttempts(clientAttempts) +{ + if (connectivity == "lan") { + m_udpHandler = new UdpHandler(this); + m_udpHandler->setListenPort(m_lanUdpPort); + + connect(m_udpHandler, SIGNAL(received(QHostAddress, QByteArray, quint16, QByteArray)), + this, SLOT(processUdp(QHostAddress, QByteArray, quint16, QByteArray))); + + m_connection = ConnectionFactory::create(ConnectionFactory::Lan, this); + connect(m_connection, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(tcpSocketError(QAbstractSocket::SocketError))); + + } else if (connectivity == "bluetooth") { + m_btHandler = new BtHandler(this); + connect(m_btHandler, SIGNAL(discovered(const BluetoothDevice &)), + this, SIGNAL(bluetoothDeviceDiscovered(const BluetoothDevice &))); + + m_connection = ConnectionFactory::create(ConnectionFactory::Bluetooth, this); + connect(m_connection, SIGNAL(error(QBluetoothSocket::SocketError)), + this, SLOT(bluetoothSocketError(QBluetoothSocket::SocketError))); + } + + // Timer for broadcasting the message + m_discoveryTimer = new QTimer(this); + // TODO: rename this settings name to DiscoveryTimeout + m_discoveryTimer->setInterval(m_discoveryTimeout); + connect(m_discoveryTimer, SIGNAL(timeout()), + this, SLOT(sendDiscovery())); + + connect(m_connection, SIGNAL(connected()), + this, SIGNAL(connected())); + connect(m_connection, SIGNAL(disconnected()), + this, SIGNAL(disconnected())); + connect(m_connection, SIGNAL(received(const NetworkMessage &)), + this, SIGNAL(messageReceived(const NetworkMessage &))); +} + +void NetworkClient::setLanPorts(int udpPort, int tcpPort) +{ + m_lanUdpPort = udpPort; + m_lanTcpPort = tcpPort; +} + +void NetworkClient::send(const NetworkMessage &message) +{ + m_connection->send(message); +} + +void NetworkClient::startDiscovery() +{ + if (m_udpHandler) { + // FIXME: Do not enable UdpHandler if it's already enabled + m_udpHandler->setListenPort(m_lanUdpPort + 1); + m_udpHandler->enable(); + + m_discoveryAttempts = 0; + m_discoveryTimer->start(); + } else { + m_btHandler->enable(); + } +} + +void NetworkClient::stopDiscovery() +{ + if (m_udpHandler) + m_discoveryTimer->stop(); + + if (m_btHandler) + m_btHandler->disable(); +} + +void NetworkClient::connectToBluetoothServer(const QString &address) +{ + m_connection->connectToHost(address, 14); +} + +void NetworkClient::processUdp(QHostAddress senderAddress, QByteArray content, + quint16 senderListenPort, QByteArray timestamp) +{ + Q_UNUSED(timestamp) + + quint16 contentData = content.toUShort(); + + if (contentData == CW::UdpContentAckDiscovery) + processAckDiscovery(senderAddress, senderListenPort); +} + +void NetworkClient::processAckDiscovery(QHostAddress senderAddress, quint16 senderListenPort) +{ + Q_UNUSED(senderListenPort) + + stopDiscovery(); + + if (m_connection->state() == QAbstractSocket::UnconnectedState) { + // Estabilish a connection to the server + m_connection->connectToHost(senderAddress.toString(), m_lanTcpPort); + } else { + qWarning("TCP Connection already open"); + } +} + +void NetworkClient::sendDiscovery() +{ + if (m_discoveryAttempts < m_discoveryClientAttempts) { + m_discoveryAttempts++; + + if (m_udpHandler) { + m_udpHandler->sendDatagram(QHostAddress::Broadcast, m_lanUdpPort, + CW::UdpSenderClient, CW::UdpContentDiscovery, + m_udpHandler->listenPort()); + } else { + // TODO: Notify upper layers about discovered bt + } + } else { + stopDiscovery(); + + if (m_udpHandler) { + m_udpHandler->disable(); + } else { + // TODO: Bluetooth stuff + } + + emit serverDiscoveryTimeout(); + } +} + +void NetworkClient::tcpSocketError(QAbstractSocket::SocketError error) +{ + qWarning("TCP Socket error [ %d ]: %s", error, + m_connection->errorString().toUtf8().constData()); + + emit socketError(error); +} + +void NetworkClient::bluetoothSocketError(QBluetoothSocket::SocketError error) +{ + emit socketError(static_cast<QAbstractSocket::SocketError>(error)); +} diff --git a/chicken-wranglers/src/network/networkclient.h b/chicken-wranglers/src/network/networkclient.h new file mode 100644 index 0000000..621fc2c --- /dev/null +++ b/chicken-wranglers/src/network/networkclient.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef NETWORKCLIENT_H +#define NETWORKCLIENT_H + +#include "bluetoothdevice.h" +#include "networkmessage.h" + +#include <QBluetoothSocket> +#include <QtNetwork/QAbstractSocket> +#include <QtNetwork/QHostAddress> +#include <QtCore/QByteArray> +#include <QtCore/QObject> + +class BtHandler; +class NetworkConnection; +class QTimer; +class UdpHandler; + +QTM_USE_NAMESPACE + +class NetworkClient : public QObject +{ + Q_OBJECT + +public: + NetworkClient(const QString &connectivity = "lan", int discoveryTimeout = 0, + int clientAttempts = 0, QObject *parent = 0); + + void send(const NetworkMessage &message); + void setLanPorts(int udpPort, int tcpPort); + +public slots: + void startDiscovery(); + void stopDiscovery(); + void connectToBluetoothServer(const QString &address); + +signals: + void connected(); + void disconnected(); + void socketError(QAbstractSocket::SocketError socketError); + void messageReceived(const NetworkMessage &message); + void serverDiscoveryTimeout(); + void bluetoothDeviceDiscovered(const BluetoothDevice &device); + +private slots: + void processUdp(QHostAddress senderAddress, QByteArray content, + quint16 senderListenPort, QByteArray timestamp); + void sendDiscovery(); + void tcpSocketError(QAbstractSocket::SocketError error); + void bluetoothSocketError(QBluetoothSocket::SocketError error); + +private: + void processAckDiscovery(QHostAddress senderAddress, quint16 senderListenPort); + + UdpHandler *m_udpHandler; + BtHandler *m_btHandler; + NetworkConnection *m_connection; + QTimer *m_discoveryTimer; + quint16 m_discoveryAttempts; + int m_discoveryTimeout; + int m_lanUdpPort; + int m_lanTcpPort; + int m_discoveryClientAttempts; +}; + +#endif diff --git a/chicken-wranglers/src/network/networkconnection.cpp b/chicken-wranglers/src/network/networkconnection.cpp new file mode 100644 index 0000000..6bebe58 --- /dev/null +++ b/chicken-wranglers/src/network/networkconnection.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "networkconnection.h" + +#include <QtCore/QByteArray> + +NetworkConnection::NetworkConnection(QObject *parent) + : QObject(parent), m_id(0), m_message(NetworkMessage()) +{ +} + +NetworkConnection::~NetworkConnection() +{ +} + +void NetworkConnection::setId(const quint16 &newId) +{ + m_id = newId; +} + +quint16 NetworkConnection::id() const +{ + return m_id; +} + +void NetworkConnection::processRead(QIODevice *m_socket) +{ + QByteArray buffer(m_socket->readAll()); + int counter = buffer.length(); + + QDataStream dataStream(&buffer, QIODevice::ReadOnly); + dataStream.setVersion(QDataStream::Qt_4_7); + + while (counter) { + // Type + if (m_message.type() == CW::NoMessageType) { + if (counter < ((int) sizeof(quint16))) + return; + + // Read the Message Type + quint16 type; + dataStream >> type; + counter -= sizeof(quint16); + + m_message.setType((CW::MessageType) type); + } + + // Content + if (m_message.content() == 0) { + if (counter < ((int) sizeof(quint16))) + return; + + // Read the Message Content + quint16 content; + dataStream >> content; + counter -= sizeof(quint16); + + m_message.setContent(content); + } + + if (m_message.data().size() == 0) { + if (counter < ((int) sizeof(quint32))) + return; + + quint32 dataSize; + dataStream >> dataSize; + counter -= sizeof(quint32); + + if (dataSize == 0xFFFFFFFF) { + m_message.setId(m_id); + + emit received(m_message); + + m_message = NetworkMessage(); + + continue; + } else { + QByteArray data; + data.resize(dataSize); + m_message.setData(data); + } + } + + if (m_message.data().size() > 0) { + if (counter < m_message.data().size()) + return; + + int dataSize = m_message.data().size(); + char *charData = new char[dataSize + 1]; + + dataStream.readRawData(charData, dataSize); + counter -= dataSize; + charData[dataSize] = '\0'; + QByteArray data(charData); + delete charData; + + m_message.setData(data); + + emit received(m_message); + + m_message = NetworkMessage(); + } + } +} diff --git a/chicken-wranglers/src/network/networkconnection.h b/chicken-wranglers/src/network/networkconnection.h new file mode 100644 index 0000000..5167804 --- /dev/null +++ b/chicken-wranglers/src/network/networkconnection.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef NETWORKCONNECTION_H +#define NETWORKCONNECTION_H + +#include "networkmessage.h" + +#include <QtCore/QObject> +#include <QtCore/QPointer> +#include <QtNetwork/QTcpSocket> + +class NetworkConnection : public QObject +{ + Q_OBJECT + +public: + NetworkConnection(QObject *parent = 0); + virtual ~NetworkConnection(); + + virtual void setId(const quint16 &newId); + virtual quint16 id() const; + + virtual void send(NetworkMessage message) = 0; + + virtual void connectToHost(const QString &address, const quint16 &port) = 0; + + virtual QAbstractSocket::SocketState state() const = 0; + + virtual QAbstractSocket::SocketError error() const = 0; + + virtual QString errorString() const = 0; + + virtual void close() = 0; + +signals: + void received(const NetworkMessage &message); + +protected: + void processRead(QIODevice *m_socket); + + quint16 m_id; + NetworkMessage m_message; +}; + +#endif diff --git a/chicken-wranglers/src/network/networkmessage.cpp b/chicken-wranglers/src/network/networkmessage.cpp new file mode 100644 index 0000000..55e31f9 --- /dev/null +++ b/chicken-wranglers/src/network/networkmessage.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include <QtCore/QDataStream> + +#include "networkmessage.h" + +NetworkMessage::NetworkMessage() + : m_id(0), m_type(CW::NoMessageType), + m_content(0), m_data(QByteArray()) +{ +} + +NetworkMessage::NetworkMessage(CW::MessageType type, quint16 content) + : m_id(0), m_type(type), + m_content(content), m_data(QByteArray()) +{ +} + +void NetworkMessage::setId(const quint16 &newId) +{ + m_id = newId; +} + +quint16 NetworkMessage::id() const +{ + return m_id; +} + +void NetworkMessage::setType(const CW::MessageType &newType) +{ + m_type = newType; +} + +CW::MessageType NetworkMessage::type() const +{ + return m_type; +} + +void NetworkMessage::setContent(const quint16 &newContent) +{ + m_content = newContent; +} + +quint16 NetworkMessage::content() const +{ + return m_content; +} + +void NetworkMessage::setData(const QByteArray &newData) +{ + m_data = newData; +} + +QByteArray NetworkMessage::data() const +{ + return m_data; +} + +QByteArray NetworkMessage::byteArray() const +{ + quint16 field; + QByteArray byteArray; + + QDataStream stream(&byteArray, QIODevice::WriteOnly); + stream.setVersion(QDataStream::Qt_4_0); + + // Type + field = m_type; + stream << field; + + // Content + stream << m_content; + + // Data (optional) + stream << m_data; + + return byteArray; +} diff --git a/chicken-wranglers/src/network/networkmessage.h b/chicken-wranglers/src/network/networkmessage.h new file mode 100644 index 0000000..da650be --- /dev/null +++ b/chicken-wranglers/src/network/networkmessage.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef NETWORKMESSAGE_H +#define NETWORKMESSAGE_H + +#include <QtCore/QByteArray> + +namespace CW +{ + enum MessageType { + NoMessageType = 1000, + PlayerControlMessageType, + PlayerInfoMessageType, + CharacterMessageType, + MatchMessageType + }; + + enum PlayerControl { + PlayerControlStop = 2000, + PlayerControlUp, + PlayerControlDown, + PlayerControlLeft, + PlayerControlRight, + PlayerControlLaserUp, + PlayerControlLaserDown, + PlayerControlLaserLeft, + PlayerControlLaserRight + }; + + enum PlayerInfo { + PlayerInfoScore = 3000, + PlayerInfoLeader + }; + + enum Character { + CharacterSelected = 4000, + CharacterReleased, + CharacterAvailableList, + CharacterIsAvailable + }; + + enum Match { + MatchReady = 5000, + MatchFinished + }; +} + +class NetworkMessage +{ +public: + NetworkMessage(); + NetworkMessage(CW::MessageType type, quint16 content); + + void setId(const quint16 &newId); + quint16 id() const; + + void setType(const CW::MessageType &newType); + CW::MessageType type() const; + + void setContent(const quint16 &newContent); + quint16 content() const; + + void setData(const QByteArray &newData); + QByteArray data() const; + + QByteArray byteArray() const; + +private: + quint16 m_id; + CW::MessageType m_type; + quint16 m_content; + QByteArray m_data; +}; + +#endif diff --git a/chicken-wranglers/src/network/networkserver.cpp b/chicken-wranglers/src/network/networkserver.cpp new file mode 100644 index 0000000..8f13259 --- /dev/null +++ b/chicken-wranglers/src/network/networkserver.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include "networkserver.h" + +#include "bluetoothhandler.h" +#include "lanhandler.h" +#include "network.h" +#include "udphandler.h" + +#include <QtCore/QList> +#include <QtCore/QTimer> + +NetworkServer::NetworkServer(const QString &connectivity, int discoveryTimeout, int hostAttempts, QObject *parent) + : QObject(parent), m_udpHandler(0), m_lanHandler(0) , m_blueHandler(0) + , m_discoveryAttempts(0), m_lookingForServers(true) + , m_discoveryTimeout(discoveryTimeout), m_discoveryHostAttempts(hostAttempts) + , m_serverBluetooth(true) +{ + createConnectionHandler(connectivity); +} + +void NetworkServer::createConnectionHandler(const QString &connectivity) +{ + if (connectivity == "lan") { + m_serverBluetooth = false; + if (m_udpHandler) + return; + + m_udpHandler = new UdpHandler(this); + m_udpHandler->setListenPort(m_lanUdpPort); + + connect(m_udpHandler, SIGNAL(received(QHostAddress, QByteArray, quint16, QByteArray)), + this, SLOT(processUdp(QHostAddress, QByteArray, quint16, QByteArray))); + + m_lanHandler = new LanHandler(this); + connect(m_lanHandler, SIGNAL(peerConnected(NetworkConnection *)), + this, SIGNAL(peerConnected(NetworkConnection *))); + connect(m_lanHandler, SIGNAL(peerDisconnected(NetworkConnection *)), + this, SIGNAL(peerDisconnected(NetworkConnection *))); + connect(m_lanHandler, SIGNAL(peerError(QAbstractSocket::SocketError, quint16)), + this, SIGNAL(peerError(QAbstractSocket::SocketError, quint16))); + connect(m_lanHandler, SIGNAL(received(NetworkMessage)), + this, SIGNAL(messageReceived(NetworkMessage))); + + m_discoveryTimer = new QTimer(this); + m_discoveryTimer->setInterval(m_discoveryTimeout); + connect(m_discoveryTimer, SIGNAL(timeout()), + this, SLOT(sendDiscovery())); + + } else if (connectivity == "bluetooth") { + m_serverBluetooth = true; + if (m_blueHandler) + return; + + m_blueHandler = new BluetoothHandler(this); + + connect(m_blueHandler, SIGNAL(started()), + this, SIGNAL(started())); + connect(m_blueHandler, SIGNAL(peerConnected(NetworkConnection *)), + this, SIGNAL(peerConnected(NetworkConnection *))); + connect(m_blueHandler, SIGNAL(peerDisconnected(NetworkConnection *)), + this, SIGNAL(peerDisconnected(NetworkConnection *))); + connect(m_blueHandler, SIGNAL(peerError(QAbstractSocket::SocketError, quint16)), + this, SIGNAL(peerError(QAbstractSocket::SocketError, quint16))); + connect(m_blueHandler, SIGNAL(received(NetworkMessage)), + this, SIGNAL(messageReceived(NetworkMessage))); + connect(m_blueHandler, SIGNAL(startError()), this, SLOT(startError())); + } +} + +NetworkServer::~NetworkServer() +{ +} + +void NetworkServer::send(const NetworkMessage &message) +{ + if (m_lanHandler) + m_lanHandler->send(message); + else if (m_blueHandler) + m_blueHandler->send(message); +} + +void NetworkServer::setLanPorts(int udpPort, int tcpPort) +{ + m_lanUdpPort = udpPort; + m_lanTcpPort = tcpPort; +} + +void NetworkServer::start() +{ + if (!m_serverBluetooth && m_lanHandler) { + m_udpHandler->setListenSenderType(CW::UdpSenderAny); + m_udpHandler->setListenPort(m_lanUdpPort + 1); + m_udpHandler->enable(); + // Server tries to find if there are other + // running servers in the same network + startDiscovery(); + } else if ((m_serverBluetooth == true) && m_blueHandler) { + m_blueHandler->start(); + } +} + +void NetworkServer::stop() +{ + if (!m_serverBluetooth && m_lanHandler) { + stopDiscovery(); + + if (m_lanHandler->isListening()) + m_lanHandler->close(); + + m_udpHandler->setListenSenderType(CW::UdpSenderNoType); + m_udpHandler->disable(); + } else if ((m_serverBluetooth == true) && m_blueHandler) { + m_blueHandler->stop(); + } +} + +void NetworkServer::closeAll() +{ + if (!m_serverBluetooth && m_lanHandler) { + stopDiscovery(); + + if (m_lanHandler->isListening()) + m_lanHandler->closeAll(); + + m_udpHandler->setListenSenderType(CW::UdpSenderNoType); + m_udpHandler->disable(); + } else if ((m_serverBluetooth == true) && m_blueHandler) { + m_blueHandler->closeAll(); + } + +} + + +void NetworkServer::startDiscovery() +{ + m_lookingForServers = true; + m_discoveryAttempts = 0; + m_discoveryTimer->start(); +} + +void NetworkServer::stopDiscovery() +{ + m_lookingForServers = false; + m_discoveryTimer->stop(); +} + +void NetworkServer::processUdp(QHostAddress senderAddress, QByteArray content, + quint16 senderListenPort, QByteArray timestamp) +{ + Q_UNUSED(timestamp) + + quint16 contentData = content.toUShort(); + + if (contentData == CW::UdpContentDiscovery) + processDiscovery(senderAddress, senderListenPort); + else if (contentData == CW::UdpContentAckDiscovery) + processAckDiscovery(senderAddress, senderListenPort); +} + +void NetworkServer::processDiscovery(QHostAddress senderAddress, quint16 senderListenPort) +{ + // While looking for other active servers, do not respond + // to Discovery messages. + if (m_lookingForServers) + return; + + // Received: "Discovery" --> Send: "AckDiscovery" + m_udpHandler->sendDatagram(senderAddress, senderListenPort, CW::UdpSenderServer, + CW::UdpContentAckDiscovery, m_udpHandler->listenPort()); +} + +void NetworkServer::processAckDiscovery(QHostAddress senderAddress, quint16 senderListenPort) +{ + Q_UNUSED(senderAddress) + Q_UNUSED(senderListenPort) + + stop(); + + emit error(AnotherServerRunningError); +} + +void NetworkServer::sendDiscovery() +{ + if (m_discoveryAttempts == m_discoveryHostAttempts) { + stopDiscovery(); + + m_udpHandler->disable(); + m_udpHandler->setListenSenderType(CW::UdpSenderAny); + m_udpHandler->setListenPort(m_lanUdpPort); + m_udpHandler->enable(); + + if (!m_lanHandler->isListening()) { + if (!m_lanHandler->listen(QHostAddress::Any, m_lanTcpPort)) { + startError(); + } + } + // TODO: Return the server to the stopped state in case of port binding error. + if (m_udpHandler->listenPort() != m_lanUdpPort) + qWarning("UDP Socket error: Unable to bind to port %d", m_lanUdpPort); + + started(); + return; + } + + m_discoveryAttempts++; + m_udpHandler->sendDatagram(QHostAddress::Broadcast, m_lanUdpPort, + CW::UdpSenderServer, CW::UdpContentDiscovery, + m_udpHandler->listenPort()); +} + +void NetworkServer::startError() +{ + emit error(AnotherServerRunningError); +} diff --git a/chicken-wranglers/src/network/networkserver.h b/chicken-wranglers/src/network/networkserver.h new file mode 100644 index 0000000..637a38f --- /dev/null +++ b/chicken-wranglers/src/network/networkserver.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef NETWORKSERVER_H +#define NETWORKSERVER_H + +#include "networkmessage.h" + +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QObject> +#include <QtNetwork/QHostAddress> + +class BluetoothHandler; +class LanHandler; +class NetworkConnection; +class QTimer; +class UdpHandler; + +class NetworkServer : public QObject +{ + Q_OBJECT + + Q_ENUMS(ServerError) + +public: + NetworkServer(const QString &connectivity = "lan", int hostAttempts = 0, int discoveryTimeout = 0, QObject *parent = 0); + ~NetworkServer(); + + void send(const NetworkMessage &message); + void setLanPorts(int udpPort, int tcpPort); + + enum ServerError { + AnotherServerRunningError, + UnknownError + }; + + void createConnectionHandler(const QString &connectivity); + + void closeAll(); + +public slots: + void start(); + void stop(); + +signals: + void peerConnected(NetworkConnection *connection); + void peerDisconnected(NetworkConnection *connection); + void peerError(QAbstractSocket::SocketError socketError, quint16 id); + void messageReceived(const NetworkMessage &message); + void error(NetworkServer::ServerError error); + void started(); + +private slots: + void processUdp(QHostAddress senderAddress, QByteArray content, + quint16 senderListenPort, QByteArray timestamp); + void sendDiscovery(); + + void startError(); + +private: + void startDiscovery(); + void stopDiscovery(); + void processDiscovery(QHostAddress senderAddress, quint16 senderListenPort); + void processAckDiscovery(QHostAddress senderAddress, quint16 senderListenPort); + + UdpHandler *m_udpHandler; + LanHandler *m_lanHandler; + BluetoothHandler *m_blueHandler; + QTimer *m_discoveryTimer; + quint16 m_discoveryAttempts; + bool m_lookingForServers; + int m_discoveryTimeout; + int m_lanUdpPort; + int m_lanTcpPort; + int m_discoveryHostAttempts; + bool m_serverBluetooth; + +}; + +#endif diff --git a/chicken-wranglers/src/network/tcpconnection.cpp b/chicken-wranglers/src/network/tcpconnection.cpp new file mode 100644 index 0000000..502962e --- /dev/null +++ b/chicken-wranglers/src/network/tcpconnection.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include <QtCore/QByteArray> +#include <QtNetwork/QHostAddress> + +#include "tcpconnection.h" + +TcpConnection::TcpConnection(QObject *parent, QTcpSocket *socket) + : NetworkConnection(parent), m_socket(socket) +{ + if (m_socket == 0) + m_socket = new QTcpSocket(this); + + connect(m_socket, SIGNAL(connected()), + this, SIGNAL(connected())); + connect(m_socket, SIGNAL(disconnected()), + this, SIGNAL(disconnected())); + connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SIGNAL(error(QAbstractSocket::SocketError))); + connect(m_socket, SIGNAL(readyRead()), + this, SLOT(processReadyRead())); +} + +TcpConnection::~TcpConnection() +{ + if (m_socket) + m_socket->close(); +} + +void TcpConnection::setId(const quint16 &newId) +{ + m_id = newId; +} + +quint16 TcpConnection::id() const +{ + return m_id; +} + +void TcpConnection::send(NetworkMessage message) +{ + if (m_socket->write(message.byteArray()) == -1) + qWarning("TCP Socket write error: %s", m_socket->errorString().toUtf8().constData()); +} + +void TcpConnection::connectToHost(const QString &address, const quint16 &port) +{ + m_socket->connectToHost(QHostAddress(address), port); +} + +QAbstractSocket::SocketState TcpConnection::state() const +{ + return m_socket->state(); +} + +QAbstractSocket::SocketError TcpConnection::error() const +{ + return m_socket->error(); +} + +QString TcpConnection::errorString() const +{ + return m_socket->errorString(); +} + +void TcpConnection::processReadyRead() +{ + processRead(m_socket); +} + +void TcpConnection::close() +{ + m_socket.data()->close(); +} diff --git a/chicken-wranglers/src/network/tcpconnection.h b/chicken-wranglers/src/network/tcpconnection.h new file mode 100644 index 0000000..464d276 --- /dev/null +++ b/chicken-wranglers/src/network/tcpconnection.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef TCPCONNECTION_H +#define TCPCONNECTION_H + +#include "networkconnection.h" + +#include <QtCore/QObject> +#include <QtCore/QPointer> +#include <QtNetwork/QTcpSocket> + +class TcpConnection : public NetworkConnection +{ + Q_OBJECT + +public: + TcpConnection(QObject *parent = 0, QTcpSocket *socket = 0); + ~TcpConnection(); + + void setId(const quint16 &newId); + quint16 id() const; + + void send(NetworkMessage message); + + void connectToHost(const QString &address, const quint16 &port); + + QAbstractSocket::SocketState state() const; + + QAbstractSocket::SocketError error() const; + + QString errorString() const; + + void close(); + +signals: + void connected(); + void disconnected(); + void error(QAbstractSocket::SocketError socketError); + +private slots: + void processReadyRead(); + +private: + QPointer<QTcpSocket> m_socket; +}; + +#endif diff --git a/chicken-wranglers/src/network/udphandler.cpp b/chicken-wranglers/src/network/udphandler.cpp new file mode 100644 index 0000000..2aa2635 --- /dev/null +++ b/chicken-wranglers/src/network/udphandler.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#include <QtCore/QTime> +#include <QtNetwork/QUdpSocket> + +#include "network.h" +#include "settings.h" + +#include "udphandler.h" + +UdpHandler::UdpHandler(QObject *parent) + : QObject(parent), m_listenSenderType(CW::UdpSenderServer), m_listenPort(0) +{ + m_socket = new QUdpSocket(this); + + connect(m_socket, SIGNAL(readyRead()), this, SLOT(processIncomingDatagrams())); +} + +UdpHandler::~UdpHandler() +{ + disable(); +} + +void UdpHandler::enable() +{ + for (quint16 i = 0; i < 100; i++) { + m_listenPort += i; + + if (m_socket->bind(QHostAddress::Any, m_listenPort, + QUdpSocket::DontShareAddress)) { + qWarning("UDP Socket bound to port %d", m_listenPort); + + break; + } + } +} + +void UdpHandler::disable() +{ + m_socket->close(); +} + +void UdpHandler::setListenSenderType(const CW::UdpSenderType &type) +{ + m_listenSenderType = type; +} + +CW::UdpSenderType UdpHandler::listenSenderType() const +{ + return m_listenSenderType; +} + +void UdpHandler::setListenPort(const quint16 &port) +{ + if (m_listenPort != port) + m_listenPort = port; +} + +quint16 UdpHandler::listenPort() const +{ + return m_listenPort; +} + +void UdpHandler::processIncomingDatagrams() +{ + QByteArray datagram; + QHostAddress senderAddress; + quint16 senderPort; + + while (m_socket->hasPendingDatagrams()) { + datagram.resize(m_socket->pendingDatagramSize()); + + if (m_socket->readDatagram(datagram.data(), datagram.size(), + &senderAddress, &senderPort) == -1) { + qWarning("UDP Error: Unable to read datagram."); + } else { + parseDatagram(senderAddress, senderPort, datagram); + } + + datagram.clear(); + } +} + +void UdpHandler::parseDatagram(QHostAddress address, quint16 port, QByteArray datagram) +{ + QList<QByteArray> fields = datagram.split(CW::udpMessageSeparator); + QTime time = QTime::currentTime(); + + // Message size correct (=4) + if (fields.size() == 4) { + // Message type received (='type specified') + if (fields.at(0).toUShort() & m_listenSenderType) { + qWarning("UDP Received:\t\"%s\"", datagram.constData()); + + emit received(address, fields.at(1), port, fields.at(2)); + } else { + qWarning("UDP Invalid sender type:\"%s\"", datagram.constData()); + } + } else { + qWarning("UDP Invalid message size:\"%s\"", datagram.constData()); + } +} + +void UdpHandler::sendDatagram(QHostAddress address, quint16 port, CW::UdpSenderType senderType, + CW::UdpContentType content, quint16 senderListenPort) +{ + QTime time; + QByteArray datagram; + + // Message format: + // "client/content/senderListenPort/11:22:33.444" + + // Timestamp + time = QTime::currentTime(); + + // Message type: Client or Server + datagram = QByteArray::number(senderType); + + // Message content: content + datagram += CW::udpMessageSeparator + QByteArray::number((quint16) content); + + // Message content: sender listen port + datagram += CW::udpMessageSeparator + QByteArray::number((quint16) senderListenPort); + + // Message timestamp: hours:minutes:seconds.miliseconds + datagram += CW::udpMessageSeparator + time.toString("hh:mm:ss.zzz").toUtf8(); + + m_socket->writeDatagram(datagram.data(), datagram.size(), address, port); +} diff --git a/chicken-wranglers/src/network/udphandler.h b/chicken-wranglers/src/network/udphandler.h new file mode 100644 index 0000000..6c26965 --- /dev/null +++ b/chicken-wranglers/src/network/udphandler.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** This file is a part of QtChickenWranglers. +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + + +#ifndef UDPHANDLER_H +#define UDPHANDLER_H + +#include "network.h" + +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QObject> +#include <QtNetwork/QHostAddress> + +class QUdpSocket; + +class UdpHandler : public QObject +{ + Q_OBJECT + +public: + UdpHandler(QObject *parent = 0); + ~UdpHandler(); + + void enable(); + void disable(); + + void setListenSenderType(const CW::UdpSenderType &type); + CW::UdpSenderType listenSenderType() const; + + void setListenPort(const quint16 &port); + quint16 listenPort() const; + + void sendDatagram(QHostAddress toAddress, quint16 toPort, CW::UdpSenderType senderType, + CW::UdpContentType content, quint16 senderListenPort); + +signals: + void received(QHostAddress senderAddress, QByteArray content, + quint16 senderListenPort, QByteArray timestamp); + +private slots: + void processIncomingDatagrams(); + +private: + void parseDatagram(QHostAddress address, quint16 port, QByteArray datagram); + + QUdpSocket *m_socket; + CW::UdpSenderType m_listenSenderType; + quint16 m_listenPort; +}; + +#endif |