diff options
Diffstat (limited to 'src/connectivity/bluetooth/ql2capserver_symbian.cpp')
-rw-r--r-- | src/connectivity/bluetooth/ql2capserver_symbian.cpp | 215 |
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 |