1
/* $Id: os_symbian.h 3553 2011-05-05 06:14:19Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
#ifndef __OS_SYMBIAN_H__
21
#define __OS_SYMBIAN_H__
23
#include <pj/assert.h>
27
#include <pj/string.h>
38
// Forward declarations
39
class CPjSocketReader;
41
#ifndef PJ_SYMBIAN_TIMER_PRIORITY
42
# define PJ_SYMBIAN_TIMER_PRIORITY EPriorityNormal
46
// PJLIB Symbian's Socket
56
// Construct CPjSocket
57
CPjSocket(int af, int sock_type, RSocket &sock)
58
: af_(af), sock_(sock), sock_type_(sock_type), connected_(false),
72
// Get the internal RSocket
78
// Get socket connected flag.
79
bool IsConnected() const
84
// Set socket connected flag.
85
void SetConnected(bool connected)
87
connected_ = connected;
91
int GetSockType() const
96
// Returns true if socket is a datagram
97
bool IsDatagram() const
99
return sock_type_ == KSockDatagram;
102
// Get socket reader, if any.
104
CPjSocketReader *Reader()
109
// Create socket reader.
110
CPjSocketReader *CreateReader(unsigned max_len=CPjSocket::MAX_LEN);
112
// Delete socket reader when it's not wanted.
113
void DestroyReader();
117
RSocket sock_; // Must not be reference, or otherwise
118
// it may point to local variable!
122
CPjSocketReader *sockReader_;
127
// Socket reader, used by select() and ioqueue abstraction
129
class CPjSocketReader : public CActive
133
static CPjSocketReader *NewL(CPjSocket &sock, unsigned max_len=CPjSocket::MAX_LEN);
138
// Start asynchronous read from the socket.
139
void StartRecv(void (*cb)(void *key)=NULL,
144
// Start asynchronous read from the socket.
145
void StartRecvFrom(void (*cb)(void *key)=NULL,
149
TSockAddr *fromAddr = NULL);
151
// Cancel asynchronous read.
154
// Implementation: called when read has completed.
157
// Check if there's pending data.
160
return buffer_.Length() != 0;
163
// Append data to aDesc, up to aDesc's maximum size.
164
// If socket is datagram based, buffer_ will be clared.
165
void ReadData(TDes8 &aDesc, TInetAddr *addr=NULL);
173
void (*readCb_)(void *key);
179
CPjSocketReader(CPjSocket &sock);
180
void ConstructL(unsigned max_len);
186
// Time-out Timer Active Object
188
class CPjTimeoutTimer : public CActive
191
static CPjTimeoutTimer *NewL();
194
void StartTimer(TUint miliSeconds);
195
bool HasTimedOut() const;
199
virtual void DoCancel();
200
virtual TInt RunError(TInt aError);
204
pj_bool_t hasTimedOut_;
213
// Symbian OS helper for PJLIB
219
// Get the singleton instance of PjSymbianOS
221
static PjSymbianOS *Instance();
226
void SetParameters(pj_symbianos_params *params);
243
// Get RSocketServ instance to be used by all sockets.
244
RSocketServ &SocketServ()
246
return appSocketServ_ ? *appSocketServ_ : socketServ_;
249
// Get RConnection instance, if any.
250
RConnection *Connection()
252
return appConnection_;
255
// Convert TInetAddr to pj_sockaddr_in
256
static inline pj_status_t Addr2pj(const TInetAddr & sym_addr,
257
pj_sockaddr &pj_addr,
259
pj_bool_t convert_ipv4_mapped_addr = PJ_FALSE)
261
TUint fam = sym_addr.Family();
262
pj_bzero(&pj_addr, *addr_len);
263
if (fam == PJ_AF_INET ||
264
(convert_ipv4_mapped_addr &&
265
fam == PJ_AF_INET6 &&
266
sym_addr.IsV4Mapped()))
268
pj_addr.addr.sa_family = PJ_AF_INET;
269
PJ_ASSERT_RETURN(*addr_len>=(int)sizeof(pj_sockaddr_in), PJ_ETOOSMALL);
270
pj_addr.ipv4.sin_addr.s_addr = pj_htonl(sym_addr.Address());
271
pj_addr.ipv4.sin_port = pj_htons((pj_uint16_t) sym_addr.Port());
272
*addr_len = sizeof(pj_sockaddr_in);
273
} else if (fam == PJ_AF_INET6) {
274
PJ_ASSERT_RETURN(*addr_len>=(int)sizeof(pj_sockaddr_in6), PJ_ETOOSMALL);
275
const TIp6Addr & ip6 = sym_addr.Ip6Address();
276
pj_addr.addr.sa_family = PJ_AF_INET6;
277
pj_memcpy(&pj_addr.ipv6.sin6_addr, ip6.u.iAddr8, 16);
278
pj_addr.ipv6.sin6_port = pj_htons((pj_uint16_t) sym_addr.Port());
279
pj_addr.ipv6.sin6_scope_id = pj_htonl(sym_addr.Scope());
280
pj_addr.ipv6.sin6_flowinfo = pj_htonl(sym_addr.FlowLabel());
281
*addr_len = sizeof(pj_sockaddr_in6);
283
pj_assert(!"Unsupported address family");
291
// Convert pj_sockaddr_in to TInetAddr
292
static inline pj_status_t pj2Addr(const pj_sockaddr &pj_addr,
294
TInetAddr & sym_addr)
296
if (pj_addr.addr.sa_family == PJ_AF_INET) {
297
PJ_ASSERT_RETURN(addrlen >= (int)sizeof(pj_sockaddr_in), PJ_EINVAL);
298
sym_addr.Init(KAfInet);
299
sym_addr.SetAddress((TUint32)pj_ntohl(pj_addr.ipv4.sin_addr.s_addr));
300
sym_addr.SetPort(pj_ntohs(pj_addr.ipv4.sin_port));
301
} else if (pj_addr.addr.sa_family == PJ_AF_INET6) {
304
PJ_ASSERT_RETURN(addrlen>=(int)sizeof(pj_sockaddr_in6), PJ_EINVAL);
305
pj_memcpy(ip6.u.iAddr8, &pj_addr.ipv6.sin6_addr, 16);
306
sym_addr.Init(KAfInet6);
307
sym_addr.SetAddress(ip6);
308
sym_addr.SetScope(pj_ntohl(pj_addr.ipv6.sin6_scope_id));
309
sym_addr.SetFlowLabel(pj_ntohl(pj_addr.ipv6.sin6_flowinfo));
311
pj_assert(!"Unsupported address family");
321
// Get RHostResolver instance
322
RHostResolver & GetResolver(int af)
324
if (af==PJ_AF_INET6) {
325
return appHostResolver6_ ? *appHostResolver6_ : hostResolver6_;
327
return appHostResolver_ ? *appHostResolver_ : hostResolver_;
332
// Return true if the access point connection is up
334
bool IsConnectionUp() const
336
return isConnectionUp_;
340
// Set access point connection status
342
void SetConnectionStatus(bool up)
344
isConnectionUp_ = up;
351
// Convert to Unicode
352
TInt ConvertToUnicode(TDes16 &aUnicode, const TDesC8 &aForeign);
354
// Convert from Unicode
355
TInt ConvertFromUnicode(TDes8 &aForeign, const TDesC16 &aUnicode);
362
CConsoleBase *Console()
368
// Get select() timeout timer.
370
CPjTimeoutTimer *SelectTimeoutTimer()
372
return selectTimeoutTimer_;
376
// Wait for any active objects to run.
378
void WaitForActiveObjects(TInt aPriority = CActive::EPriorityStandard)
381
CActiveScheduler::Current()->WaitForAnyRequest();
382
CActiveScheduler::RunIfReady(aError, aPriority);
386
bool isConnectionUp_;
388
bool isSocketServInitialized_;
389
RSocketServ socketServ_;
391
bool isResolverInitialized_;
392
RHostResolver hostResolver_;
393
RHostResolver hostResolver6_;
395
CConsoleBase* console_;
397
CPjTimeoutTimer *selectTimeoutTimer_;
400
RSocketServ *appSocketServ_;
401
RConnection *appConnection_;
402
RHostResolver *appHostResolver_;
403
RHostResolver *appHostResolver6_;
409
// This macro is used to check the access point connection status and return
410
// failure if the AP connection is down or unusable. See the documentation
411
// of pj_symbianos_set_connection_status() for more info
412
#define PJ_SYMBIAN_CHECK_CONNECTION() \
413
PJ_SYMBIAN_CHECK_CONNECTION2(PJ_ECANCELLED)
415
#define PJ_SYMBIAN_CHECK_CONNECTION2(retval) \
417
if (!PjSymbianOS::Instance()->IsConnectionUp()) \
421
#endif /* __OS_SYMBIAN_H__ */