Initial Symbian integration to trunk for pjlib

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1235 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjlib/src/pj/addr_resolv_symbian.cpp b/pjlib/src/pj/addr_resolv_symbian.cpp
new file mode 100644
index 0000000..c9a776c
--- /dev/null
+++ b/pjlib/src/pj/addr_resolv_symbian.cpp
@@ -0,0 +1,147 @@
+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include <pj/addr_resolv.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/string.h>
+#include <pj/unicode.h>
+
+#include "os_symbian.h"
+ 
+
+// PJLIB API: resolve hostname
+PJ_DEF(pj_status_t) pj_gethostbyname(const pj_str_t *name, pj_hostent *he)
+{
+    PJ_ASSERT_RETURN(name && he, PJ_EINVAL);
+
+    RHostResolver &resv = PjSymbianOS::Instance()->GetResolver();
+
+    // Convert name to Unicode
+    wchar_t name16[PJ_MAX_HOSTNAME];
+    pj_ansi_to_unicode(name->ptr, name->slen, name16, PJ_ARRAY_SIZE(name16));
+    TPtrC16 data(name16);
+
+    // Resolve!
+    TNameEntry nameEntry;
+    TRequestStatus reqStatus;
+    
+    resv.GetByName(data, nameEntry, reqStatus);
+    User::WaitForRequest(reqStatus);
+    
+    if (reqStatus != KErrNone)
+	return PJ_RETURN_OS_ERROR(reqStatus.Int());
+
+    // Get the resolved TInetAddr
+    // This doesn't work, see Martin email on 28/3/2007:
+    // const TNameRecord &rec = (const TNameRecord&) nameEntry;
+    // TInetAddr inetAddr(rec.iAddr);
+    TInetAddr inetAddr(nameEntry().iAddr);
+
+    //
+    // This where we keep static variables.
+    // These should be kept in TLS probably, to allow multiple threads
+    // to call pj_gethostbyname() without interfering each other.
+    // But again, we don't support threads in Symbian!
+    //
+    static char resolved_name[PJ_MAX_HOSTNAME];
+    static char *no_aliases[1];
+    static pj_in_addr *addr_list[2];
+    static pj_sockaddr_in resolved_addr;
+
+    // Convert the official address to ANSI.
+    pj_unicode_to_ansi(nameEntry().iName.Ptr(), nameEntry().iName.Length(),
+		       resolved_name, sizeof(resolved_name));
+
+    // Convert IP address
+    
+    PjSymbianOS::Addr2pj(inetAddr, resolved_addr);
+    addr_list[0] = &resolved_addr.sin_addr;
+
+    // Return hostent
+    he->h_name = resolved_name;
+    he->h_aliases = no_aliases;
+    he->h_addrtype = PJ_AF_INET;
+    he->h_length = 4;
+    he->h_addr_list = (char**) addr_list;
+
+    return PJ_SUCCESS;
+}
+
+
+/* Resolve the IP address of local machine */
+pj_status_t pj_gethostip(pj_in_addr *addr)
+{
+    const pj_str_t *hostname = pj_gethostname();
+    struct pj_hostent he;
+    pj_str_t cp;
+    pj_in_addr loopip;
+    pj_status_t status;
+
+    cp = pj_str("127.0.0.1");
+    loopip = pj_inet_addr(&cp);
+
+    /* Try with resolving local hostname first */
+    status = pj_gethostbyname(hostname, &he);
+    if (status == PJ_SUCCESS) {
+	*addr = *(pj_in_addr*)he.h_addr;
+    }
+
+
+    /* If we end up with 127.0.0.1 or 0.0.0.0, resolve the IP by getting 
+     * the default interface to connect to some public host.
+     */
+    if (status!=PJ_SUCCESS || addr->s_addr == loopip.s_addr || !addr->s_addr) {
+	pj_sock_t fd;
+	pj_sockaddr_in a;
+	int len;
+
+	status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &fd);
+	if (status != PJ_SUCCESS) {
+	    return status;
+	}
+
+	cp = pj_str("1.1.1.1");
+	pj_sockaddr_in_init(&a, &cp, 53);
+
+	status = pj_sock_connect(fd, &a, sizeof(a));
+	if (status != PJ_SUCCESS) {
+	    pj_sock_close(fd);
+	    return status;
+	}
+
+	len = sizeof(a);
+	status = pj_sock_getsockname(fd, &a, &len);
+	if (status != PJ_SUCCESS) {
+	    pj_sock_close(fd);
+	    return status;
+	}
+
+	pj_sock_close(fd);
+	
+	*addr = a.sin_addr;
+
+	if (a.sin_addr.s_addr == 0)
+	    return PJ_ENOTFOUND;
+    }
+
+    return status;
+}
+
+
+