8f427b2 by axis at 2009-04-24 1
/****************************************************************************
2
**
89c08c0 by Jason McDonald at 2012-01-11 3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
04e3b30 by Jason McDonald at 2009-09-09 4
** All rights reserved.
da8dc76 by axis at 2009-08-06 5
** Contact: Nokia Corporation (qt-info@nokia.com)
8f427b2 by axis at 2009-04-24 6
**
bec7a9c by Jason McDonald at 2009-10-06 7
** This file is part of the QtCore module of the Qt Toolkit.
8f427b2 by axis at 2009-04-24 8
**
a014c07 by axis at 2009-06-03 9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
1eea52e by Jyri Tahtela at 2011-05-13 11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
a014c07 by axis at 2009-06-03 17
**
04e3b30 by Jason McDonald at 2009-09-09 18
** In addition, as a special exception, Nokia gives you certain additional
1eea52e by Jyri Tahtela at 2011-05-13 19
** rights. These rights are described in the Nokia Qt LGPL Exception
04e3b30 by Jason McDonald at 2009-09-09 20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
a014c07 by axis at 2009-06-03 21
**
1eea52e by Jyri Tahtela at 2011-05-13 22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
115a995 by Jason McDonald at 2009-08-31 29
**
1eea52e by Jyri Tahtela at 2011-05-13 30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
115a995 by Jason McDonald at 2009-08-31 33
**
34
**
35
**
36
**
a014c07 by axis at 2009-06-03 37
**
38
** $QT_END_LICENSE$
8f427b2 by axis at 2009-04-24 39
**
40
****************************************************************************/
41
7604f80 by Robert Griebl at 2009-06-10 42
#include <exception>
8f427b2 by axis at 2009-04-24 43
#include <e32base.h>
44
#include <e32uid.h>
45
#include "qcore_symbian_p.h"
7604f80 by Robert Griebl at 2009-06-10 46
#include <string>
8dacbcc by Shane Kearns at 2010-12-06 47
#include <in_sock.h>
9304619 by Shane Kearns at 2011-09-23 48
#include "qdebug.h"
8f427b2 by axis at 2009-04-24 49
50
QT_BEGIN_NAMESPACE
51
52
/*
53
    Helper function for calling into Symbian classes that expect a TDes&.
54
    This function converts a QString to a TDes by allocating memory that
55
    must be deleted by the caller.
56
*/
57
7604f80 by Robert Griebl at 2009-06-10 58
Q_CORE_EXPORT HBufC* qt_QString2HBufC(const QString& aString)
8f427b2 by axis at 2009-04-24 59
{
60
    HBufC *buffer;
61
#ifdef QT_NO_UNICODE
62
    TPtrC8 ptr(reinterpret_cast<const TUint8*>(aString.toLocal8Bit().constData()));
63
#else
7604f80 by Robert Griebl at 2009-06-10 64
    TPtrC16 ptr(qt_QString2TPtrC(aString));
8f427b2 by axis at 2009-04-24 65
#endif
c6cc767 by João Abecasis at 2010-08-19 66
    buffer = HBufC::New(ptr.Length());
67
    Q_CHECK_PTR(buffer);
7604f80 by Robert Griebl at 2009-06-10 68
    buffer->Des().Copy(ptr);
8f427b2 by axis at 2009-04-24 69
    return buffer;
70
}
71
41a83e1 by Harald Fernengel at 2009-08-03 72
Q_CORE_EXPORT QString qt_TDesC2QString(const TDesC& aDescriptor)
8f427b2 by axis at 2009-04-24 73
{
74
#ifdef QT_NO_UNICODE
75
    return QString::fromLocal8Bit(aDescriptor.Ptr(), aDescriptor.Length());
76
#else
e0fda52 by Oswald Buddenhagen at 2010-02-01 77
    return QString(reinterpret_cast<const QChar *>(aDescriptor.Ptr()), aDescriptor.Length());
8f427b2 by axis at 2009-04-24 78
#endif
79
}
80
81
QHBufC::QHBufC()
82
    : m_hBufC(0)
83
{
84
}
85
86
QHBufC::QHBufC(const QHBufC &src)
c6cc767 by João Abecasis at 2010-08-19 87
	: m_hBufC(src.m_hBufC->Alloc())
8f427b2 by axis at 2009-04-24 88
{
c6cc767 by João Abecasis at 2010-08-19 89
    Q_CHECK_PTR(m_hBufC);
8f427b2 by axis at 2009-04-24 90
}
91
92
/*!
93
  \internal
94
  Constructs a QHBufC from an HBufC. Note that the QHBufC instance takes
95
  ownership of the HBufC.
96
*/
97
QHBufC::QHBufC(HBufC *src)
98
    : m_hBufC(src)
99
{
100
}
101
102
QHBufC::QHBufC(const QString &src)
103
{
7604f80 by Robert Griebl at 2009-06-10 104
    m_hBufC = qt_QString2HBufC(src);
8f427b2 by axis at 2009-04-24 105
}
106
107
QHBufC::~QHBufC()
108
{
109
    if (m_hBufC)
110
        delete m_hBufC;
111
}
112
6dade01 by Shane Kearns at 2009-08-24 113
class QS60RFsSession
114
{
115
public:
116
    QS60RFsSession() {
117
        qt_symbian_throwIfError(iFs.Connect());
118
        qt_symbian_throwIfError(iFs.ShareProtected());
9304619 by Shane Kearns at 2011-09-23 119
        //BC with 4.7: create private path on system drive
120
        TInt sysdrive = iFs.GetSystemDrive();
121
        TInt err = iFs.CreatePrivatePath(sysdrive);
122
        if (err != KErrNone && err != KErrAlreadyExists)
123
            qWarning("Failed to create private path on system drive.");
124
        TFileName pfn = RProcess().FileName();
125
        TInt drive;
126
        if (pfn.Length() > 0 && iFs.CharToDrive(pfn[0], drive) == KErrNone) {
001c01e by Shane Kearns at 2011-10-17 127
            //BC with 4.7: create private path on application drive (except rom or system drive which is done above)
9304619 by Shane Kearns at 2011-09-23 128
            if (drive != sysdrive && drive != EDriveZ) {
129
                err = iFs.CreatePrivatePath(drive);
001c01e by Shane Kearns at 2011-10-17 130
                if (err != KErrNone && err != KErrAlreadyExists)
9304619 by Shane Kearns at 2011-09-23 131
                    qWarning("Failed to create private path on application drive.");
132
            }
001c01e by Shane Kearns at 2011-10-17 133
            //BC with 4.7: set working directory to same drive as application
134
            iFs.SetSessionToPrivate(drive);
9304619 by Shane Kearns at 2011-09-23 135
        }
6dade01 by Shane Kearns at 2009-08-24 136
    }
137
138
    ~QS60RFsSession() {
139
        iFs.Close();
140
    }
141
142
    RFs& GetRFs() {
143
        return iFs;
144
    }
145
146
private:
147
148
    RFs iFs;
149
};
150
de55502 by Shane Kearns at 2010-12-06 151
uint qHash(const RSubSessionBase& key)
152
{
153
    return qHash(key.SubSessionHandle());
154
}
155
6dade01 by Shane Kearns at 2009-08-24 156
Q_GLOBAL_STATIC(QS60RFsSession, qt_s60_RFsSession);
157
158
Q_CORE_EXPORT RFs& qt_s60GetRFs()
159
{
160
    return qt_s60_RFsSession()->GetRFs();
161
}
7604f80 by Robert Griebl at 2009-06-10 162
5c7c126 by Shane Kearns at 2010-12-01 163
QSymbianSocketManager::QSymbianSocketManager() :
8adba78 by Shane Kearns at 2010-12-07 164
    iNextSocket(0), iDefaultConnection(0)
5c7c126 by Shane Kearns at 2010-12-01 165
{
8dacbcc by Shane Kearns at 2010-12-06 166
    TSessionPref preferences;
167
    // ### In future this could be changed to KAfInet6 when that is more common than IPv4
168
    preferences.iAddrFamily = KAfInet;
169
    preferences.iProtocol = KProtocolInetIp;
47ac901 by Shane Kearns at 2011-01-21 170
    //use global message pool, as we do not know how many sockets app will use
171
    //TODO: is this the right choice?
172
    qt_symbian_throwIfError(iSocketServ.Connect(preferences, -1));
5c7c126 by Shane Kearns at 2010-12-01 173
    qt_symbian_throwIfError(iSocketServ.ShareAuto());
174
}
175
176
QSymbianSocketManager::~QSymbianSocketManager()
177
{
178
    iSocketServ.Close();
179
    if(!socketMap.isEmpty()) {
180
        qWarning("leaked %d sockets on exit", socketMap.count());
181
    }
182
}
183
184
RSocketServ& QSymbianSocketManager::getSocketServer() {
185
    return iSocketServ;
186
}
187
de55502 by Shane Kearns at 2010-12-06 188
int QSymbianSocketManager::addSocket(const RSocket& socket) {
189
    QHashableSocket sock(static_cast<const QHashableSocket &>(socket));
5c7c126 by Shane Kearns at 2010-12-01 190
    QMutexLocker l(&iMutex);
191
    Q_ASSERT(!socketMap.contains(sock));
192
    if(socketMap.contains(sock))
193
        return socketMap.value(sock);
194
    // allocate socket number
195
    int guard = 0;
196
    while(reverseSocketMap.contains(iNextSocket)) {
197
        iNextSocket++;
198
        iNextSocket %= max_sockets;
199
        guard++;
200
        if(guard > max_sockets)
201
            return -1;
202
    }
203
    int id = iNextSocket;
204
205
    socketMap[sock] = id;
206
    reverseSocketMap[id] = sock;
207
    return id + socket_offset;
208
}
209
de55502 by Shane Kearns at 2010-12-06 210
bool QSymbianSocketManager::removeSocket(const RSocket &socket) {
211
    QHashableSocket sock(static_cast<const QHashableSocket &>(socket));
5c7c126 by Shane Kearns at 2010-12-01 212
    QMutexLocker l(&iMutex);
213
    if(!socketMap.contains(sock))
214
        return false;
215
    int id = socketMap.value(sock);
216
    socketMap.remove(sock);
217
    reverseSocketMap.remove(id);
218
    return true;
219
}
220
de55502 by Shane Kearns at 2010-12-06 221
int QSymbianSocketManager::lookupSocket(const RSocket& socket) const {
222
    QHashableSocket sock(static_cast<const QHashableSocket &>(socket));
5c7c126 by Shane Kearns at 2010-12-01 223
    QMutexLocker l(&iMutex);
224
    if(!socketMap.contains(sock))
225
        return -1;
226
    int id = socketMap.value(sock);
227
    return id + socket_offset;
228
}
229
de55502 by Shane Kearns at 2010-12-06 230
bool QSymbianSocketManager::lookupSocket(int fd, RSocket& socket) const {
5c7c126 by Shane Kearns at 2010-12-01 231
    QMutexLocker l(&iMutex);
cb7a890 by Shane Kearns at 2010-12-10 232
    int id = fd - socket_offset;
5c7c126 by Shane Kearns at 2010-12-01 233
    if(!reverseSocketMap.contains(id))
de55502 by Shane Kearns at 2010-12-06 234
        return false;
235
    socket = reverseSocketMap.value(id);
236
    return true;
5c7c126 by Shane Kearns at 2010-12-01 237
}
238
8adba78 by Shane Kearns at 2010-12-07 239
void QSymbianSocketManager::setDefaultConnection(RConnection* con)
240
{
241
    iDefaultConnection = con;
242
}
243
244
RConnection* QSymbianSocketManager::defaultConnection() const
245
{
246
    return iDefaultConnection;
247
}
248
916076b by Shane Kearns at 2011-11-30 249
void QSymbianSocketManager::addActiveConnection(TUint32 identifier)
250
{
251
    QMutexLocker l(&iMutex);
252
    activeConnectionsMap[identifier]++;
253
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
254
    qDebug() << "addActiveConnection" << identifier << activeConnectionsMap[identifier];
255
#endif
256
}
257
258
void QSymbianSocketManager::removeActiveConnection(TUint32 identifier)
259
{
260
    QMutexLocker l(&iMutex);
261
    int& val(activeConnectionsMap[identifier]);
262
    Q_ASSERT(val > 0);
263
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
264
    qDebug() << "removeActiveConnection" << identifier << val - 1;
265
#endif
266
    if (val <= 1)
267
        activeConnectionsMap.remove(identifier);
268
    else
269
        val--;
270
}
271
272
QList<TUint32> QSymbianSocketManager::activeConnections() const
273
{
274
    QMutexLocker l(&iMutex);
275
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
276
    qDebug() << "activeConnections" <<  activeConnectionsMap.keys();
277
#endif
278
    return activeConnectionsMap.keys();
279
}
280
5c7c126 by Shane Kearns at 2010-12-01 281
Q_GLOBAL_STATIC(QSymbianSocketManager, qt_symbianSocketManager);
282
283
QSymbianSocketManager& QSymbianSocketManager::instance()
284
{
285
    return *(qt_symbianSocketManager());
286
}
de55502 by Shane Kearns at 2010-12-06 287
288
Q_CORE_EXPORT RSocketServ& qt_symbianGetSocketServer()
289
{
290
    return QSymbianSocketManager::instance().getSocketServer();
291
}
292
8f427b2 by axis at 2009-04-24 293
QT_END_NAMESPACE