summaryrefslogtreecommitdiffstats
path: root/src/connectivity/bluetooth/ql2capserver_symbian.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/connectivity/bluetooth/ql2capserver_symbian.cpp')
-rw-r--r--src/connectivity/bluetooth/ql2capserver_symbian.cpp215
1 files changed, 133 insertions, 82 deletions
diff --git a/src/connectivity/bluetooth/ql2capserver_symbian.cpp b/src/connectivity/bluetooth/ql2capserver_symbian.cpp
index 2b5a765310..38e9f2b959 100644
--- a/src/connectivity/bluetooth/ql2capserver_symbian.cpp
+++ b/src/connectivity/bluetooth/ql2capserver_symbian.cpp
@@ -53,11 +53,8 @@
QTM_BEGIN_NAMESPACE
QL2capServerPrivate::QL2capServerPrivate()
-: pending(false),maxPendingConnections(1)
+: socket(0),pending(false),maxPendingConnections(1),securityFlags(QBluetooth::NoSecurity)
{
- socket = new QBluetoothSocket(QBluetoothSocket::L2capSocket);
- ds = socket->d_ptr;
- ds->iSocket->SetNotifier(*this);
}
QL2capServerPrivate::~QL2capServerPrivate()
@@ -68,9 +65,14 @@ QL2capServerPrivate::~QL2capServerPrivate()
void QL2capServer::close()
{
Q_D(QL2capServer);
-
+ if(!d->socket)
+ {
+ // there is no way to propagate the error to user
+ // so just ignore the problem.
+ return;
+ }
+ d->socket->setSocketState(QBluetoothSocket::ClosingState);
d->socket->close();
-
// force active object (socket) to run and shutdown socket.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
}
@@ -78,8 +80,40 @@ void QL2capServer::close()
bool QL2capServer::listen(const QBluetoothAddress &address, quint16 port)
{
Q_D(QL2capServer);
-
+ // listen has already been called before
+ if(d->socket)
+ return true;
+
+ d->socket = new QBluetoothSocket(QBluetoothSocket::L2capSocket,this);
+
+ if(!d->socket)
+ {
+ return false;
+ }
+
+ d->ds = d->socket->d_ptr;
+
+ if(!d->ds)
+ {
+ delete d->socket;
+ d->socket = 0;
+ return false;
+ }
+
TL2CAPSockAddr addr;
+
+ if(!address.isNull())
+ {
+ // TBTDevAddr constructor may panic
+ TRAPD(err,addr.SetBTAddr(TBTDevAddr(address.toUInt64())));
+ if(err != KErrNone)
+ {
+ delete d->socket;
+ d->socket = 0;
+ return false;
+ }
+ }
+
if (port == 0)
addr.SetPort(KL2CAPPassiveAutoBind);
else
@@ -88,12 +122,16 @@ bool QL2capServer::listen(const QBluetoothAddress &address, quint16 port)
TBTServiceSecurity security;
switch (d->securityFlags) {
case QBluetooth::Authentication:
- security.SetAuthentication(ETrue);
+ security.SetAuthentication(EMitmDesired);
break;
case QBluetooth::Authorization:
security.SetAuthorisation(ETrue);
break;
case QBluetooth::Encryption:
+ // "Secure" is BlueZ specific we just make sure the code remain compatible
+ case QBluetooth::Secure:
+ // authentication required
+ security.SetAuthentication(EMitmDesired);
security.SetEncryption(ETrue);
break;
case QBluetooth::NoSecurity:
@@ -101,35 +139,59 @@ bool QL2capServer::listen(const QBluetoothAddress &address, quint16 port)
break;
}
addr.SetSecurity(security);
- d->ds->iSocket->Bind(addr);
- d->socket->setSocketState(QBluetoothSocket::BoundState);
-
- d->ds->iSocket->Listen(d->maxPendingConnections);
-
- d->pendingSocket = new QBluetoothSocket(QBluetoothSocket::L2capSocket, this);
-
- QBluetoothSocketPrivate *pd = d->pendingSocket->d_ptr;
- pd->ensureBlankNativeSocket();
- if (d->ds->iSocket->Accept(*pd->iBlankSocket) == KErrNone)
+ if(d->ds->iSocket->Bind(addr) == KErrNone)
+ {
+ d->socket->setSocketState(QBluetoothSocket::BoundState);
+ }
+ else
+ {
+ delete d->socket;
+ d->socket = 0;
+ return false;
+ }
+
+ if(d->ds->iSocket->Listen(d->maxPendingConnections) != KErrNone)
+ {
+ delete d->socket;
+ d->socket = 0;
+ return false;
+ }
+ // unknown socket type is used for blank socket
+ QBluetoothSocket *pendingSocket = new QBluetoothSocket(QBluetoothSocket::UnknownSocketType, this);
+ if(!pendingSocket)
+ {
+ delete d->socket;
+ d->socket = 0;
+ return false;
+ }
+ QBluetoothSocketPrivate *pd = pendingSocket->d_ptr;
+ pd->ensureBlankNativeSocket(QBluetoothSocket::L2capSocket);
+ connect(d->socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
+ connect(d->socket, SIGNAL(connected()), this, SLOT(connected()));
+ connect(d->socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(socketError(QBluetoothSocket::SocketError)));
+ if (d->ds->iSocket->Accept(*pd->iSocket) == KErrNone)
+ {
d->socket->setSocketState(QBluetoothSocket::ListeningState);
+ d->activeSockets.append(pendingSocket);
+ return true;
+ }
else
- d->socket->close();
-
- return d->socket->state() == QBluetoothSocket::ListeningState;
+ {
+ delete d->socket, pendingSocket;
+ d->socket = 0;
+ return false;
+ }
}
void QL2capServer::setMaxPendingConnections(int numConnections)
{
Q_D(QL2capServer);
-
- if (d->socket->state() == QBluetoothSocket::UnconnectedState)
- d->maxPendingConnections = numConnections;
+ d->maxPendingConnections = numConnections;
}
bool QL2capServer::hasPendingConnections() const
{
Q_D(const QL2capServer);
-
return !d->activeSockets.isEmpty();
}
@@ -141,98 +203,87 @@ QBluetoothSocket *QL2capServer::nextPendingConnection()
return 0;
QBluetoothSocket *next = d->activeSockets.takeFirst();
- QBluetoothSocketPrivate *n = next->d_ptr;
-
- n->startServerSideReceive();
-
return next;
}
QBluetoothAddress QL2capServer::serverAddress() const
{
Q_D(const QL2capServer);
-
- return d->socket->localAddress();
+ if(d->socket)
+ return d->socket->localAddress();
+ else
+ return QBluetoothAddress();
}
quint16 QL2capServer::serverPort() const
{
Q_D(const QL2capServer);
-
- return d->socket->localPort();
+ if(d->socket)
+ return d->socket->localPort();
+ else
+ return 0;
}
-void QL2capServerPrivate::HandleAcceptCompleteL(TInt aErr)
+void QL2capServerPrivate::_q_connected()
{
Q_Q(QL2capServer);
-
- if (aErr == KErrNone) {
- pendingSocket->setSocketState(QBluetoothSocket::ConnectedState);
+ if(!activeSockets.isEmpty())
+ {
+ // update state of the pending socket and start receiving
+ (activeSockets.last())->setSocketState(QBluetoothSocket::ConnectedState);
+ (activeSockets.last())->d_ptr->startReceive();
+ }
+ else
+ return;
+ emit q->newConnection();
+ QBluetoothSocket *pendingSocket = new QBluetoothSocket(QBluetoothSocket::UnknownSocketType);
+ if(!pendingSocket)
+ {
+ delete socket;
+ socket = 0;
+ return;
+ }
+ QBluetoothSocketPrivate *pd = pendingSocket->d_ptr;
+ pd->ensureBlankNativeSocket(QBluetoothSocket::L2capSocket);
+ if (ds->iSocket->Accept(*pd->iSocket) == KErrNone)
+ {
+ socket->setSocketState(QBluetoothSocket::ListeningState);
activeSockets.append(pendingSocket);
-
- QBluetoothSocketPrivate *pd = pendingSocket->d_ptr;
-
- pd->iSocket->Accept(*pd->iBlankSocket);
-
- emit q->newConnection();
- } else if (aErr == KErrCancel) {
- // server is closing
- delete pendingSocket;
- pendingSocket = 0;
- socket->setSocketState(QBluetoothSocket::BoundState);
- } else {
- qDebug() << __PRETTY_FUNCTION__ << aErr;
return;
- }
-}
-
-void QL2capServerPrivate::HandleActivateBasebandEventNotifierCompleteL(TInt aErr, TBTBasebandEventNotification &aEventNotification)
-{
- qDebug() << __PRETTY_FUNCTION__ << aErr;
-}
-
-void QL2capServerPrivate::HandleConnectCompleteL(TInt aErr)
-{
- qDebug() << __PRETTY_FUNCTION__ << aErr;
-}
-
-void QL2capServerPrivate::HandleIoctlCompleteL(TInt aErr)
-{
- qDebug() << __PRETTY_FUNCTION__ << aErr;
-}
-
-void QL2capServerPrivate::HandleReceiveCompleteL(TInt aErr)
-{
- qDebug() << __PRETTY_FUNCTION__ << aErr;
+ }
+ else
+ {
+ // we might reach this statement if we have reach
+ // maxPendingConnections
+ qDebug() << "QL2capServer::connected accept failed";
+ delete socket, pendingSocket;
+ socket = 0;
+ return;
+ }
}
-void QL2capServerPrivate::HandleSendCompleteL(TInt aErr)
+void QL2capServerPrivate::_q_disconnected()
{
- qDebug() << __PRETTY_FUNCTION__ << aErr;
+ delete socket;
+ socket = 0;
}
-void QL2capServerPrivate::HandleShutdownCompleteL(TInt aErr)
+void QL2capServerPrivate::_q_socketError(QBluetoothSocket::SocketError err)
{
- if (aErr == KErrNone)
- socket->setSocketState(QBluetoothSocket::UnconnectedState);
- else
- qDebug() << __PRETTY_FUNCTION__ << aErr;
+ delete socket;
+ socket = 0;
}
void QL2capServer::setSecurityFlags(QBluetooth::SecurityFlags security)
{
Q_D(QL2capServer);
-
d->securityFlags = security;
}
QBluetooth::SecurityFlags QL2capServer::securityFlags() const
{
Q_D(const QL2capServer);
-
return d->securityFlags;
}
-
-
QTM_END_NAMESPACE