Index: /pjproject/trunk/pjlib/src/pj/addr_resolv_symbian.cpp
===================================================================
--- /pjproject/trunk/pjlib/src/pj/addr_resolv_symbian.cpp	(revision 1646)
+++ /pjproject/trunk/pjlib/src/pj/addr_resolv_symbian.cpp	(revision 1647)
@@ -21,4 +21,5 @@
 #include <pj/errno.h>
 #include <pj/ip_helper.h>
+#include <pj/log.h>
 #include <pj/sock.h>
 #include <pj/string.h>
@@ -27,4 +28,6 @@
 #include "os_symbian.h"
  
+#define THIS_FILE 	"addr_resolv_symbian.cpp"
+#define TRACE_ME	0
 
 
@@ -87,30 +90,57 @@
     while (reqStatus == KErrNone && i < *count) {
     	
-	// Get the resolved TInetAddr
-	TInetAddr inetAddr(nameEntry().iAddr);
-	int addrlen;
+		// Get the resolved TInetAddr
+		TInetAddr inetAddr(nameEntry().iAddr);
+		int addrlen;
 
-	// Ignore if this is not the same address family
-	if (inetAddr.Family() != (unsigned)af) {
-	    resv.Next(nameEntry, reqStatus);
-	    User::WaitForRequest(reqStatus);
-	    continue;
-	}
+#if TRACE_ME
+		if (1) {
+			pj_sockaddr a;
+			char ipaddr[PJ_INET6_ADDRSTRLEN+2];
+			int namelen;
+			
+			namelen = sizeof(pj_sockaddr);
+			if (PjSymbianOS::Addr2pj(inetAddr, a, &namelen, 
+									 PJ_FALSE) == PJ_SUCCESS) 
+			{
+				PJ_LOG(5,(THIS_FILE, "resolve %.*s: %s", 
+						(int)name->slen, name->ptr,
+						pj_sockaddr_print(&a, ipaddr, sizeof(ipaddr), 2)));
+			}
+		}
+#endif
+		
+		// Ignore if this is not the same address family
+		// Not a good idea, as Symbian mapps IPv4 to IPv6.
+		//fam = inetAddr.Family();
+		//if (fam != af) {
+		//    resv.Next(nameEntry, reqStatus);
+		//    User::WaitForRequest(reqStatus);
+		//    continue;
+		//}
+		
+		// Convert IP address first to get IPv4 mapped address
+		addrlen = sizeof(ai[i].ai_addr);
+		status = PjSymbianOS::Addr2pj(inetAddr, ai[i].ai_addr, 
+									  &addrlen, PJ_TRUE);
+		if (status != PJ_SUCCESS)
+		    return status;
+		
+		// Ignore if address family doesn't match
+		if (ai[i].ai_addr.addr.sa_family != af) {
+		    resv.Next(nameEntry, reqStatus);
+		    User::WaitForRequest(reqStatus);
+		    continue;
+		}
+
+		// Convert the official address to ANSI.
+		pj_unicode_to_ansi((const wchar_t*)nameEntry().iName.Ptr(), 
+				   nameEntry().iName.Length(),
+			       	   ai[i].ai_canonname, sizeof(ai[i].ai_canonname));
 	
-	// Convert the official address to ANSI.
-	pj_unicode_to_ansi((const wchar_t*)nameEntry().iName.Ptr(), 
-			   nameEntry().iName.Length(),
-		       	   ai[i].ai_canonname, sizeof(ai[i].ai_canonname));
-
-	// Convert IP address
-	addrlen = sizeof(ai[i].ai_addr);
-	status = PjSymbianOS::Addr2pj(inetAddr, ai[i].ai_addr, &addrlen);
-	if (status != PJ_SUCCESS)
-	    return status;
-	
-	// Next
-	++i;
-	resv.Next(nameEntry, reqStatus);
-	User::WaitForRequest(reqStatus);
+		// Next
+		++i;
+		resv.Next(nameEntry, reqStatus);
+		User::WaitForRequest(reqStatus);
     }
 
Index: /pjproject/trunk/pjlib/src/pj/ip_helper_symbian.cpp
===================================================================
--- /pjproject/trunk/pjlib/src/pj/ip_helper_symbian.cpp	(revision 1646)
+++ /pjproject/trunk/pjlib/src/pj/ip_helper_symbian.cpp	(revision 1647)
@@ -21,4 +21,5 @@
 #include <pj/assert.h>
 #include <pj/errno.h>
+#include <pj/log.h>
 #include <pj/string.h>
 #include <pj/compat/socket.h>
@@ -26,4 +27,7 @@
 
 #include "os_symbian.h"
+
+#define THIS_FILE	"ip_helper_symbian.cpp"
+#define TRACE_ME	0
 
 static pj_status_t rsock_enum_interface(int af,
@@ -59,12 +63,29 @@
     	TInetAddr &iAddress = info().iAddress;
     	int namelen;
+
+#if TRACE_ME
+		if (1) {
+			pj_sockaddr a;
+			char ipaddr[PJ_INET6_ADDRSTRLEN+2];
+			
+			namelen = sizeof(pj_sockaddr);
+			if (PjSymbianOS::Addr2pj(iAddress, a, &namelen, 
+									 PJ_FALSE) == PJ_SUCCESS) 
+			{
+				PJ_LOG(5,(THIS_FILE, "Enum: found address %s", 
+						pj_sockaddr_print(&a, ipaddr, sizeof(ipaddr), 2)));
+			}
+		}
+#endif
     	
-    	if (iAddress.Family() != (unsigned)af) {
+    	namelen = sizeof(ifs[i]);
+    	if (PjSymbianOS::Addr2pj(iAddress, ifs[i], &namelen, 
+    							 PJ_TRUE) != PJ_SUCCESS)
+    	{
     	    continue;
     	}
-    	
-    	namelen = sizeof(ifs[i]);
-    	if (PjSymbianOS::Addr2pj(iAddress, ifs[i], &namelen) != PJ_SUCCESS)
-    	    continue;
+
+    	if (ifs[i].addr.sa_family != af)
+		    continue;
     	
     	++i;
Index: /pjproject/trunk/pjlib/src/pj/os_symbian.h
===================================================================
--- /pjproject/trunk/pjlib/src/pj/os_symbian.h	(revision 1646)
+++ /pjproject/trunk/pjlib/src/pj/os_symbian.h	(revision 1647)
@@ -240,16 +240,23 @@
     static inline pj_status_t Addr2pj(const TInetAddr & sym_addr,
 			       	      pj_sockaddr &pj_addr,
-			       	      int *addr_len)
-    {
+			       	      int *addr_len,
+			       	      pj_bool_t convert_ipv4_mapped_addr = PJ_FALSE)
+    {
+    TUint fam = sym_addr.Family();
 	pj_bzero(&pj_addr, *addr_len);
-	pj_addr.addr.sa_family = (pj_uint16_t)sym_addr.Family();
-	if (pj_addr.addr.sa_family == PJ_AF_INET) {
+	if (fam == PJ_AF_INET || 
+			(convert_ipv4_mapped_addr && 
+			 fam == PJ_AF_INET6 && 
+			 sym_addr.IsV4Mapped())) 
+	{
+		pj_addr.addr.sa_family = PJ_AF_INET;
 	    PJ_ASSERT_RETURN(*addr_len>=(int)sizeof(pj_sockaddr_in), PJ_ETOOSMALL);
 	    pj_addr.ipv4.sin_addr.s_addr = pj_htonl(sym_addr.Address());
 	    pj_addr.ipv4.sin_port = pj_htons((pj_uint16_t) sym_addr.Port());
 	    *addr_len = sizeof(pj_sockaddr_in);
-	} else if (pj_addr.addr.sa_family == PJ_AF_INET6) {
+	} else if (fam == PJ_AF_INET6) {
 	    PJ_ASSERT_RETURN(*addr_len>=(int)sizeof(pj_sockaddr_in6), PJ_ETOOSMALL);
 	    const TIp6Addr & ip6 = sym_addr.Ip6Address();
+	    pj_addr.addr.sa_family = PJ_AF_INET6;
 	    pj_memcpy(&pj_addr.ipv6.sin6_addr, ip6.u.iAddr8, 16);
 	    pj_addr.ipv6.sin6_port = pj_htons((pj_uint16_t) sym_addr.Port());
Index: /pjproject/trunk/pjlib/src/pj/sock_common.c
===================================================================
--- /pjproject/trunk/pjlib/src/pj/sock_common.c	(revision 1646)
+++ /pjproject/trunk/pjlib/src/pj/sock_common.c	(revision 1647)
@@ -456,7 +456,6 @@
     status = pj_getaddrinfo(af, pj_gethostname(), &count, &ai);
     if (status == PJ_SUCCESS) {
-	pj_memcpy(pj_sockaddr_get_addr(addr),
-		  pj_sockaddr_get_addr(&ai.ai_addr),
-		  pj_sockaddr_get_addr_len(&ai.ai_addr));
+    	pj_assert(ai.ai_addr.addr.sa_family == (pj_uint16_t)af);
+    	pj_sockaddr_copy_addr(addr, &ai.ai_addr);
     }
 
@@ -466,35 +465,33 @@
      */
     if (status != PJ_SUCCESS || !pj_sockaddr_has_addr(addr) ||
-	(af==PJ_AF_INET && (pj_ntohl(addr->ipv4.sin_addr.s_addr) >> 24)==127))
+		(af==PJ_AF_INET && (pj_ntohl(addr->ipv4.sin_addr.s_addr) >> 24)==127))
     {
-	status = pj_getdefaultipinterface(af, addr);
+		status = pj_getdefaultipinterface(af, addr);
     }
 
     /* If failed, get the first available interface */
     if (status != PJ_SUCCESS) {
-	pj_sockaddr itf[1];
-	unsigned count = PJ_ARRAY_SIZE(itf);
-
-	status = pj_enum_ip_interface(af, &count, itf);
-	if (status == PJ_SUCCESS) {
-	    itf[0].addr.sa_family = (pj_uint16_t)af;
-	    pj_memcpy(pj_sockaddr_get_addr(addr),
-		      pj_sockaddr_get_addr(&itf[0]),
-		      pj_sockaddr_get_addr_len(&itf[0]));
-	}
+		pj_sockaddr itf[1];
+		unsigned count = PJ_ARRAY_SIZE(itf);
+	
+		status = pj_enum_ip_interface(af, &count, itf);
+		if (status == PJ_SUCCESS) {
+		    pj_assert(itf[0].addr.sa_family == (pj_uint16_t)af);
+		    pj_sockaddr_copy_addr(addr, &itf[0]);
+		}
     }
 
     /* If else fails, returns loopback interface as the last resort */
     if (status != PJ_SUCCESS) {
-	if (af==PJ_AF_INET) {
-	    addr->ipv4.sin_addr.s_addr = pj_htonl (0x7f000001);
-	} else {
-	    pj_in6_addr *s6_addr;
-
-	    s6_addr = (pj_in6_addr*) pj_sockaddr_get_addr(addr);
-	    pj_bzero(s6_addr, sizeof(pj_in6_addr));
-	    s6_addr->s6_addr[15] = 1;
-	}
-	status = PJ_SUCCESS;
+		if (af==PJ_AF_INET) {
+		    addr->ipv4.sin_addr.s_addr = pj_htonl (0x7f000001);
+		} else {
+		    pj_in6_addr *s6_addr;
+	
+		    s6_addr = (pj_in6_addr*) pj_sockaddr_get_addr(addr);
+		    pj_bzero(s6_addr, sizeof(pj_in6_addr));
+		    s6_addr->s6_addr[15] = 1;
+		}
+		status = PJ_SUCCESS;
     }
 
@@ -553,7 +550,5 @@
     }
 
-    pj_memcpy(pj_sockaddr_get_addr(addr),
-	      pj_sockaddr_get_addr(&a),
-	      pj_sockaddr_get_addr_len(&a));
+    pj_sockaddr_copy_addr(addr, &a);
 
     /* Success */
Index: /pjproject/trunk/pjlib/src/pj/sock_symbian.cpp
===================================================================
--- /pjproject/trunk/pjlib/src/pj/sock_symbian.cpp	(revision 1646)
+++ /pjproject/trunk/pjlib/src/pj/sock_symbian.cpp	(revision 1647)
@@ -406,5 +406,5 @@
 	pj_in_addr inaddr;
 
-	if (size <= PJ_INET_ADDRSTRLEN)
+	if (size < PJ_INET_ADDRSTRLEN)
 	    return PJ_ETOOSMALL;
 
@@ -422,5 +422,5 @@
 	TBuf<PJ_INET6_ADDRSTRLEN> str16;
 
-	if (size <= PJ_INET6_ADDRSTRLEN)
+	if (size < PJ_INET6_ADDRSTRLEN)
 	    return PJ_ETOOSMALL;
 
