summaryrefslogtreecommitdiffstats
path: root/chicken-wranglers/src/network/bluetoothhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chicken-wranglers/src/network/bluetoothhandler.cpp')
-rw-r--r--chicken-wranglers/src/network/bluetoothhandler.cpp198
1 files changed, 198 insertions, 0 deletions
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();
+}