1
/* $Id: addr_resolv_symbian.cpp 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
#include <pj/addr_resolv.h>
21
#include <pj/assert.h>
23
#include <pj/ip_helper.h>
26
#include <pj/string.h>
27
#include <pj/unicode.h>
29
#include "os_symbian.h"
31
#define THIS_FILE "addr_resolv_symbian.cpp"
35
// PJLIB API: resolve hostname
36
PJ_DEF(pj_status_t) pj_gethostbyname(const pj_str_t *name, pj_hostent *he)
38
static pj_addrinfo ai;
39
static char *aliases[2];
40
static char *addrlist[2];
44
status = pj_getaddrinfo(PJ_AF_INET, name, &count, &ai);
45
if (status != PJ_SUCCESS)
48
aliases[0] = ai.ai_canonname;
51
addrlist[0] = (char*) &ai.ai_addr.ipv4.sin_addr;
54
pj_bzero(he, sizeof(*he));
55
he->h_name = aliases[0];
56
he->h_aliases = aliases;
57
he->h_addrtype = PJ_AF_INET;
59
he->h_addr_list = addrlist;
65
// Resolve for specific address family
66
static pj_status_t getaddrinfo_by_af(int af, const pj_str_t *name,
67
unsigned *count, pj_addrinfo ai[])
72
PJ_ASSERT_RETURN(name && count && ai, PJ_EINVAL);
74
#if !defined(PJ_HAS_IPV6) || !PJ_HAS_IPV6
75
if (af == PJ_AF_INET6)
76
return PJ_EIPV6NOTSUP;
79
// Return failure if access point is marked as down by app.
80
PJ_SYMBIAN_CHECK_CONNECTION();
82
// Get resolver for the specified address family
83
RHostResolver &resv = PjSymbianOS::Instance()->GetResolver(af);
85
// Convert name to Unicode
86
wchar_t name16[PJ_MAX_HOSTNAME];
87
pj_ansi_to_unicode(name->ptr, name->slen, name16, PJ_ARRAY_SIZE(name16));
88
TPtrC16 data((const TUint16*)name16);
92
TRequestStatus reqStatus;
94
resv.GetByName(data, nameEntry, reqStatus);
95
User::WaitForRequest(reqStatus);
97
// Iterate each result
99
while (reqStatus == KErrNone && i < *count) {
101
// Get the resolved TInetAddr
102
TInetAddr inetAddr(nameEntry().iAddr);
108
char ipaddr[PJ_INET6_ADDRSTRLEN+2];
111
namelen = sizeof(pj_sockaddr);
112
if (PjSymbianOS::Addr2pj(inetAddr, a, &namelen,
113
PJ_FALSE) == PJ_SUCCESS)
115
PJ_LOG(5,(THIS_FILE, "resolve %.*s: %s",
116
(int)name->slen, name->ptr,
117
pj_sockaddr_print(&a, ipaddr, sizeof(ipaddr), 2)));
122
// Ignore if this is not the same address family
123
// Not a good idea, as Symbian mapps IPv4 to IPv6.
124
//fam = inetAddr.Family();
126
// resv.Next(nameEntry, reqStatus);
127
// User::WaitForRequest(reqStatus);
131
// Convert IP address first to get IPv4 mapped address
132
addrlen = sizeof(ai[i].ai_addr);
133
status = PjSymbianOS::Addr2pj(inetAddr, ai[i].ai_addr,
135
if (status != PJ_SUCCESS)
138
// Ignore if address family doesn't match
139
if (ai[i].ai_addr.addr.sa_family != af) {
140
resv.Next(nameEntry, reqStatus);
141
User::WaitForRequest(reqStatus);
145
// Convert the official address to ANSI.
146
pj_unicode_to_ansi((const wchar_t*)nameEntry().iName.Ptr(),
147
nameEntry().iName.Length(),
148
ai[i].ai_canonname, sizeof(ai[i].ai_canonname));
152
resv.Next(nameEntry, reqStatus);
153
User::WaitForRequest(reqStatus);
160
/* Resolve IPv4/IPv6 address */
161
PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,
162
unsigned *count, pj_addrinfo ai[])
165
pj_status_t status = PJ_EAFNOTSUP;
167
PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6 || af==PJ_AF_UNSPEC,
169
PJ_ASSERT_RETURN(nodename && count && *count && ai, PJ_EINVAL);
173
if (af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) {
174
unsigned max = *count;
175
status = getaddrinfo_by_af(PJ_AF_INET6, nodename,
177
if (status == PJ_SUCCESS) {
183
if (af==PJ_AF_INET || af==PJ_AF_UNSPEC) {
184
unsigned max = *count;
185
status = getaddrinfo_by_af(PJ_AF_INET, nodename,
187
if (status == PJ_SUCCESS) {
198
return status!=PJ_SUCCESS ? status : PJ_ENOTFOUND;