Started errno framework in pjlib-util

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@217 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjlib-util/build/pjlib_util.dsp b/pjlib-util/build/pjlib_util.dsp
index 692e32d..74ed0ca 100644
--- a/pjlib-util/build/pjlib_util.dsp
+++ b/pjlib-util/build/pjlib_util.dsp
@@ -41,7 +41,7 @@
 # PROP Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-release"

 # PROP Target_Dir ""

 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c

-# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /Oy /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c

+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c

 # ADD BASE RSC /l 0x409 /d "NDEBUG"

 # ADD RSC /l 0x409 /d "NDEBUG"

 BSC32=bscmake.exe

@@ -85,6 +85,10 @@
 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

 # Begin Source File

 

+SOURCE="..\src\pjlib-util\errno.c"

+# End Source File

+# Begin Source File

+

 SOURCE="..\src\pjlib-util\md5.c"

 # End Source File

 # Begin Source File

@@ -127,6 +131,10 @@
 # PROP Default_Filter "h;hpp;hxx;hm;inl"

 # Begin Source File

 

+SOURCE="..\include\pjlib-util\errno.h"

+# End Source File

+# Begin Source File

+

 SOURCE="..\include\pjlib-util\md5.h"

 # End Source File

 # Begin Source File

diff --git a/pjlib-util/include/pjlib-util.h b/pjlib-util/include/pjlib-util.h
index 0040d45..6ef9119 100644
--- a/pjlib-util/include/pjlib-util.h
+++ b/pjlib-util/include/pjlib-util.h
@@ -16,7 +16,27 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  */
+#ifndef __PJLIB_UTIL_H__
+#define __PJLIB_UTIL_H__
+
+#include <pjlib-util/errno.h>
 #include <pjlib-util/md5.h>
 #include <pjlib-util/scanner.h>
 #include <pjlib-util/stun.h>
 #include <pjlib-util/xml.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * Initialize PJLIB UTIL (defined in errno.c)
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjlib_util_init(void);
+
+
+PJ_END_DECL
+
+
+#endif	/* __PJLIB_UTIL_H__ */
diff --git a/pjlib-util/include/pjlib-util/errno.h b/pjlib-util/include/pjlib-util/errno.h
new file mode 100644
index 0000000..7846fac
--- /dev/null
+++ b/pjlib-util/include/pjlib-util/errno.h
@@ -0,0 +1,93 @@
+/* $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 
+ */
+#ifndef __PJLIB_UTIL_ERRNO_H__
+#define __PJLIB_UTIL_ERRNO_H__
+
+
+#include <pj/errno.h>
+
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ */
+#define PJLIB_UTIL_ERRNO_START    (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3)
+
+
+/************************************************************
+ * STUN ERROR
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Unable to resolve STUN server
+ */
+#define PJLIB_UTIL_ESTUNRESOLVE	    (PJLIB_UTIL_ERRNO_START+1)
+/**
+ * @hideinitializer
+ * Unknown STUN message type.
+ */
+#define PJLIB_UTIL_ESTUNINMSGTYPE   (PJLIB_UTIL_ERRNO_START+2)
+/**
+ * @hideinitializer
+ * Invalid STUN message length.
+ */
+#define PJLIB_UTIL_ESTUNINMSGLEN    (PJLIB_UTIL_ERRNO_START+3)
+/**
+ * @hideinitializer
+ * STUN attribute length error.
+ */
+#define PJLIB_UTIL_ESTUNINATTRLEN   (PJLIB_UTIL_ERRNO_START+4)
+/**
+ * @hideinitializer
+ * Invalid STUN attribute type
+ */
+#define PJLIB_UTIL_ESTUNINATTRTYPE  (PJLIB_UTIL_ERRNO_START+5)
+/**
+ * @hideinitializer
+ * Invalid STUN server/socket index
+ */
+#define PJLIB_UTIL_ESTUNININDEX     (PJLIB_UTIL_ERRNO_START+6)
+/**
+ * @hideinitializer
+ * No STUN binding response in the message
+ */
+#define PJLIB_UTIL_ESTUNNOBINDRES   (PJLIB_UTIL_ERRNO_START+7)
+/**
+ * @hideinitializer
+ * Received STUN error attribute
+ */
+#define PJLIB_UTIL_ESTUNRECVERRATTR (PJLIB_UTIL_ERRNO_START+8)
+/**
+ * @hideinitializer
+ * No STUN mapped address attribute
+ */
+#define PJLIB_UTIL_ESTUNNOMAP       (PJLIB_UTIL_ERRNO_START+9)
+/**
+ * @hideinitializer
+ * Received no response from STUN server
+ */
+#define PJLIB_UTIL_ESTUNNOTRESPOND  (PJLIB_UTIL_ERRNO_START+10)
+/**
+ * @hideinitializer
+ * Symetric NAT detected by STUN
+ */
+#define PJLIB_UTIL_ESTUNSYMMETRIC   (PJLIB_UTIL_ERRNO_START+11)
+
+
+
+#endif	/* __PJLIB_UTIL_ERRNO_H__ */
diff --git a/pjlib-util/include/pjlib-util/stun.h b/pjlib-util/include/pjlib-util/stun.h
index 353e07f..0a43103 100644
--- a/pjlib-util/include/pjlib-util/stun.h
+++ b/pjlib-util/include/pjlib-util/stun.h
@@ -118,22 +118,11 @@
 				        pj_stun_msg *msg);
 PJ_DECL(void*) pj_stun_msg_find_attr( pj_stun_msg *msg, pj_stun_attr_type t);
 
-/* STUN simple client API (stun_client.c) */
-enum pj_stun_err_code {
-    PJ_STUN_ERR_MEMORY		= (-2),
-    PJ_STUN_ERR_RESOLVE		= (-3),
-    PJ_STUN_ERR_TRANSPORT	= (-4),
-    PJ_STUN_ERR_INVALID_MSG	= (-5),
-    PJ_STUN_ERR_NO_RESPONSE	= (-6),
-    PJ_STUN_ERR_SYMETRIC	= (-7),
-};
-
 PJ_DECL(pj_status_t) pj_stun_get_mapped_addr( pj_pool_factory *pf,
 					      int sock_cnt, pj_sock_t sock[],
 					      const pj_str_t *srv1, int port1,
 					      const pj_str_t *srv2, int port2,
 					      pj_sockaddr_in mapped_addr[]);
-PJ_DECL(const char*) pj_stun_get_err_msg(pj_status_t status);
 
 PJ_END_DECL
 
diff --git a/pjlib-util/src/pjlib-util/errno.c b/pjlib-util/src/pjlib-util/errno.c
new file mode 100644
index 0000000..5384aab
--- /dev/null
+++ b/pjlib-util/src/pjlib-util/errno.c
@@ -0,0 +1,112 @@
+/* $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 <pjlib-util/errno.h>
+#include <pj/string.h>
+
+
+
+/* PJLIB_UTIL's own error codes/messages 
+ * MUST KEEP THIS ARRAY SORTED!!
+ * Message must be limited to 64 chars!
+ */
+static const struct 
+{
+    int code;
+    const char *msg;
+} err_str[] = 
+{
+    /* STUN errors */
+    { PJLIB_UTIL_ESTUNRESOLVE,	    "Unable to resolve STUN server" },
+    { PJLIB_UTIL_ESTUNINMSGTYPE,    "Unknown STUN message type" },
+    { PJLIB_UTIL_ESTUNINMSGLEN,	    "Invalid STUN message length" },
+    { PJLIB_UTIL_ESTUNINATTRLEN,    "STUN attribute length error" },
+    { PJLIB_UTIL_ESTUNINATTRTYPE,   "Invalid STUN attribute type" },
+    { PJLIB_UTIL_ESTUNININDEX,	    "Invalid STUN server/socket index" },
+    { PJLIB_UTIL_ESTUNNOBINDRES,    "No STUN binding response in the message" },
+    { PJLIB_UTIL_ESTUNRECVERRATTR,  "Received STUN error attribute" },
+    { PJLIB_UTIL_ESTUNNOMAP,	    "No STUN mapped address attribute" },
+    { PJLIB_UTIL_ESTUNNOTRESPOND,   "Received no response from STUN server" },
+    { PJLIB_UTIL_ESTUNSYMMETRIC,    "Symetric NAT detected by STUN" },
+
+};
+
+
+
+/*
+ * pjlib_util_strerror()
+ */
+PJ_DEF(pj_str_t) pjlib_util_strerror( pj_status_t statcode, 
+				      char *buf, pj_size_t bufsize )
+{
+    pj_str_t errstr;
+
+    if (statcode >= PJLIB_UTIL_ERRNO_START && 
+	statcode < PJLIB_UTIL_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
+    {
+	/* Find the error in the table.
+	 * Use binary search!
+	 */
+	int first = 0;
+	int n = PJ_ARRAY_SIZE(err_str);
+
+	while (n > 0) {
+	    int half = n/2;
+	    int mid = first + half;
+
+	    if (err_str[mid].code < statcode) {
+		first = mid+1;
+		n -= (half+1);
+	    } else if (err_str[mid].code > statcode) {
+		n = half;
+	    } else {
+		first = mid;
+		break;
+	    }
+	}
+
+
+	if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
+	    pj_str_t msg;
+	    
+	    msg.ptr = (char*)err_str[first].msg;
+	    msg.slen = pj_ansi_strlen(err_str[first].msg);
+
+	    errstr.ptr = buf;
+	    pj_strncpy_with_null(&errstr, &msg, bufsize);
+	    return errstr;
+
+	} 
+    }
+
+    /* Error not found. */
+    errstr.ptr = buf;
+    errstr.slen = pj_snprintf(buf, bufsize, 
+			      "Unknown error %d",
+			      statcode);
+
+    return errstr;
+}
+
+
+PJ_DEF(pj_status_t) pjlib_util_init(void)
+{
+    return pj_register_strerror(PJLIB_UTIL_ERRNO_START, 
+				PJ_ERRNO_SPACE_SIZE, 
+				&pjlib_util_strerror);
+}
diff --git a/pjlib-util/src/pjlib-util/stun.c b/pjlib-util/src/pjlib-util/stun.c
index 52c5bf5..13cb4b2 100644
--- a/pjlib-util/src/pjlib-util/stun.c
+++ b/pjlib-util/src/pjlib-util/stun.c
@@ -17,12 +17,13 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  */
 #include <pjlib-util/stun.h>
+#include <pjlib-util/errno.h>
 #include <pj/pool.h>
 #include <pj/log.h>
 #include <pj/sock.h>
 #include <pj/os.h>
 
-#define THIS_FILE   "stun"
+#define THIS_FILE   "stun.c"
 
 PJ_DEF(pj_status_t) pj_stun_create_bind_req( pj_pool_t *pool, 
 					     void **msg, pj_size_t *len,
@@ -33,13 +34,10 @@
     
     PJ_CHECK_STACK();
 
-    PJ_LOG(5,(THIS_FILE, "pj_stun_create_bind_req"));
 
     hdr = pj_pool_calloc(pool, 1, sizeof(pj_stun_msg_hdr));
-    if (!hdr) {
-	PJ_LOG(5,(THIS_FILE, "Error allocating memory!"));
-	return -1;
-    }
+    if (!hdr)
+	return PJ_ENOMEM;
 
     hdr->type = pj_htons(PJ_STUN_BINDING_REQUEST);
     hdr->tsx[2] = pj_htonl(id_hi);
@@ -47,7 +45,7 @@
     *msg = hdr;
     *len = sizeof(pj_stun_msg_hdr);
 
-    return 0;
+    return PJ_SUCCESS;
 }
 
 PJ_DEF(pj_status_t) pj_stun_parse_msg( void *buf, pj_size_t len, 
@@ -58,8 +56,6 @@
 
     PJ_CHECK_STACK();
 
-    PJ_LOG(5,(THIS_FILE, "pj_stun_parse_msg %p, len=%d", buf, len));
-
     msg->hdr = (pj_stun_msg_hdr*)buf;
     msg_type = pj_ntohs(msg->hdr->type);
 
@@ -72,15 +68,15 @@
     case PJ_STUN_SHARED_SECRET_ERROR_RESPONSE:
 	break;
     default:
-	PJ_LOG(5,(THIS_FILE, "Error: unknown msg type %d", msg_type));
-	return -1;
+	PJ_LOG(4,(THIS_FILE, "Error: unknown msg type %d", msg_type));
+	return PJLIB_UTIL_ESTUNINMSGTYPE;
     }
 
     msg_len = pj_ntohs(msg->hdr->length);
     if (msg_len != len - sizeof(pj_stun_msg_hdr)) {
-	PJ_LOG(5,(THIS_FILE, "Error: invalid msg_len %d (expecting %d)", 
+	PJ_LOG(4,(THIS_FILE, "Error: invalid msg_len %d (expecting %d)", 
 			     msg_len, len - sizeof(pj_stun_msg_hdr)));
-	return -1;
+	return PJLIB_UTIL_ESTUNINMSGLEN;
     }
 
     msg->attr_count = 0;
@@ -94,15 +90,15 @@
 	len = pj_ntohs((pj_uint16_t) ((*attr)->length)) + sizeof(pj_stun_attr_hdr);
 
 	if (msg_len < len) {
-	    PJ_LOG(5,(THIS_FILE, "Error: length mismatch in attr %d", 
+	    PJ_LOG(4,(THIS_FILE, "Error: length mismatch in attr %d", 
 				 msg->attr_count));
-	    return -1;
+	    return PJLIB_UTIL_ESTUNINATTRLEN;
 	}
 
 	if (pj_ntohs((*attr)->type) > PJ_STUN_ATTR_REFLECTED_FORM) {
-	    PJ_LOG(5,(THIS_FILE, "Error: invalid attr type %d in attr %d",
+	    PJ_LOG(4,(THIS_FILE, "Error: invalid attr type %d in attr %d",
 				 pj_ntohs((*attr)->type), msg->attr_count));
-	    return -1;
+	    return PJLIB_UTIL_ESTUNINATTRTYPE;
 	}
 
 	msg_len = (pj_uint16_t)(msg_len - len);
@@ -110,7 +106,7 @@
 	++msg->attr_count;
     }
 
-    return 0;
+    return PJ_SUCCESS;
 }
 
 PJ_DEF(void*) pj_stun_msg_find_attr( pj_stun_msg *msg, pj_stun_attr_type t)
diff --git a/pjlib-util/src/pjlib-util/stun_client.c b/pjlib-util/src/pjlib-util/stun_client.c
index 9771145..d8f2246 100644
--- a/pjlib-util/src/pjlib-util/stun_client.c
+++ b/pjlib-util/src/pjlib-util/stun_client.c
@@ -17,16 +17,18 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  */
 #include <pjlib-util/stun.h>
-#include <pj/pool.h>
-#include <pj/log.h>
-#include <pj/string.h>
+#include <pjlib-util/errno.h>
 #include <pj/os.h>
+#include <pj/pool.h>
+#include <pj/rand.h>
 #include <pj/sock_select.h>
+#include <pj/string.h>
+
 
 enum { MAX_REQUEST = 3 };
 static int stun_timer[] = {1600, 1600, 1600 };
 
-#define THIS_FILE	"stunclient"
+#define THIS_FILE	"stun_client.c"
 #define LOG_ADDR(addr)	pj_inet_ntoa(addr.sin_addr), pj_ntohs(addr.sin_port)
 
 
@@ -37,7 +39,7 @@
 					      pj_sockaddr_in mapped_addr[])
 {
     pj_sockaddr_in srv_addr[2];
-    int i, j, rc, send_cnt = 0;
+    int i, j, send_cnt = 0;
     pj_pool_t *pool;
     struct {
 	struct {
@@ -48,40 +50,38 @@
     void       *out_msg;
     pj_size_t	out_msg_len;
     int wait_resp = 0;
-    int mapped_status = 0;
+    pj_status_t status;
 
     PJ_CHECK_STACK();
 
     /* Create pool. */
     pool = pj_pool_create(pf, "stun%p", 1024, 1024, NULL);
-    if (!pool) {
-	mapped_status = PJ_STUN_ERR_MEMORY; 
-	return -1;
-    }
+    if (!pool)
+	return PJ_ENOMEM;
+
 
     /* Allocate client records */
     rec = pj_pool_calloc(pool, sock_cnt, sizeof(*rec));
     if (!rec) {
-	mapped_status = PJ_STUN_ERR_MEMORY; 
+	status = PJ_ENOMEM;
 	goto on_error;
     }
 
+
     /* Create the outgoing BIND REQUEST message template */
-    rc = pj_stun_create_bind_req( pool, &out_msg, &out_msg_len, 0, 0);
-    if (rc != 0) {
-	mapped_status = -1;
+    status = pj_stun_create_bind_req( pool, &out_msg, &out_msg_len, 
+				      pj_rand(), pj_rand());
+    if (status != PJ_SUCCESS)
 	goto on_error;
-    }
 
     /* Resolve servers. */
-    if (pj_sockaddr_in_init(&srv_addr[0], srv1, (pj_uint16_t)port1) != 0) {
-	mapped_status = PJ_STUN_ERR_RESOLVE; 
+    status = pj_sockaddr_in_init(&srv_addr[0], srv1, (pj_uint16_t)port1);
+    if (status != PJ_SUCCESS)
 	goto on_error;
-    }
-    if (pj_sockaddr_in_init(&srv_addr[1], srv2, (pj_uint16_t)port2) != 0) {
-	mapped_status = PJ_STUN_ERR_RESOLVE;
+
+    status = pj_sockaddr_in_init(&srv_addr[1], srv2, (pj_uint16_t)port2);
+    if (status != PJ_SUCCESS)
 	goto on_error;
-    }
 
     /* Init mapped addresses to zero */
     pj_memset(mapped_addr, 0, sock_cnt * sizeof(pj_sockaddr_in));
@@ -92,14 +92,11 @@
 	pj_fd_set_t r;
 	int select_rc;
 
-	PJ_LOG(4,(THIS_FILE, "STUN retransmit %d, wait_resp=%d", 
-			     send_cnt, wait_resp));
-
 	PJ_FD_ZERO(&r);
 
 	/* Send messages to servers that has not given us response. */
-	for (i=0; i<sock_cnt && mapped_status==0; ++i) {
-	    for (j=0; j<2 && mapped_status==0; ++j) {
+	for (i=0; i<sock_cnt && status==PJ_SUCCESS; ++i) {
+	    for (j=0; j<2 && status==PJ_SUCCESS; ++j) {
 		pj_stun_msg_hdr *msg_hdr = out_msg;
                 pj_ssize_t sent_len;
 
@@ -112,17 +109,11 @@
 
 		/* Send! */
                 sent_len = out_msg_len;
-		rc = pj_sock_sendto(sock[i], out_msg, &sent_len, 0,
-				    (pj_sockaddr_t*)&srv_addr[j], 
-				    sizeof(pj_sockaddr_in));
-		if (sent_len != (int)out_msg_len) {
-		    PJ_LOG(4,(THIS_FILE, 
-			      "Error sending STUN request to %s:%d",
-			      LOG_ADDR(srv_addr[j])));
-		    mapped_status = PJ_STUN_ERR_TRANSPORT; 
-		} else {
+		status = pj_sock_sendto(sock[i], out_msg, &sent_len, 0,
+					(pj_sockaddr_t*)&srv_addr[j], 
+					sizeof(pj_sockaddr_in));
+		if (status == PJ_SUCCESS)
 		    ++wait_resp;
-		}
 	    }
 	}
 
@@ -139,7 +130,8 @@
 	pj_time_val_normalize(&next_tx);
 
 	for (pj_gettimeofday(&now), select_rc=1; 
-	     mapped_status==0 && select_rc==1 && wait_resp>0 && PJ_TIME_VAL_LT(now, next_tx); 
+	     status==PJ_SUCCESS && select_rc==1 && wait_resp>0 
+	       && PJ_TIME_VAL_LT(now, next_tx); 
 	     pj_gettimeofday(&now)) 
 	{
 	    pj_time_val timeout;
@@ -168,59 +160,43 @@
 		    continue;
 
                 len = sizeof(recv_buf);
-		pj_sock_recvfrom( sock[i], recv_buf, 
-				  &len, 0,
-				  (pj_sockaddr_t*)&addr,
-				  &addrlen);
+		status = pj_sock_recvfrom( sock[i], recv_buf, 
+				           &len, 0,
+				           (pj_sockaddr_t*)&addr,
+					   &addrlen);
 
 		--wait_resp;
 
-		if (len < 1) {
-		    mapped_status = PJ_STUN_ERR_TRANSPORT; 
+		if (status != PJ_SUCCESS)
+		    continue;
+
+		status = pj_stun_parse_msg(recv_buf, len, &msg);
+		if (status != PJ_SUCCESS) {
 		    continue;
 		}
 
-		if (pj_stun_parse_msg(recv_buf, len, &msg) != 0) {
-		    PJ_LOG(4,(THIS_FILE, 
-				"Error parsing STUN response from %s:%d",
-				LOG_ADDR(addr)));
-		    mapped_status = PJ_STUN_ERR_INVALID_MSG;
-		    continue;
-		}
 
 		sock_idx = pj_ntohl(msg.hdr->tsx[2]);
 		srv_idx = pj_ntohl(msg.hdr->tsx[3]);
 
 		if (sock_idx<0 || sock_idx>=sock_cnt || srv_idx<0 || srv_idx>=2) {
-		    PJ_LOG(4,(THIS_FILE, 
-				"Invalid transaction ID from %s:%d", 
-				LOG_ADDR(addr)));
-		    mapped_status = PJ_STUN_ERR_INVALID_MSG;
+		    status = PJLIB_UTIL_ESTUNININDEX;
 		    continue;
 		}
 
 		if (pj_ntohs(msg.hdr->type) != PJ_STUN_BINDING_RESPONSE) {
-		    PJ_LOG(4,(THIS_FILE, 
-				"Non binding response %d from %s:%d", 
-				pj_ntohs(msg.hdr->type), LOG_ADDR(addr)));
-		    mapped_status = PJ_STUN_ERR_INVALID_MSG;
+		    status = PJLIB_UTIL_ESTUNNOBINDRES;
 		    continue;
 		}
 
 		if (pj_stun_msg_find_attr(&msg, PJ_STUN_ATTR_ERROR_CODE) != NULL) {
-		    PJ_LOG(4,(THIS_FILE, 
-				"Got STUN error attribute from %s:%d",
-				LOG_ADDR(addr)));
-		    mapped_status = PJ_STUN_ERR_INVALID_MSG;
+		    status = PJLIB_UTIL_ESTUNRECVERRATTR;
 		    continue;
 		}
 
 		attr = (void*)pj_stun_msg_find_attr(&msg, PJ_STUN_ATTR_MAPPED_ADDR);
 		if (!attr) {
-		    PJ_LOG(4,(THIS_FILE,
-				"No mapped address in response from %s:%d",
-				LOG_ADDR(addr)));
-		    mapped_status = PJ_STUN_ERR_INVALID_MSG;
+		    status = PJLIB_UTIL_ESTUNNOMAP;
 		    continue;
 		}
 
@@ -236,7 +212,7 @@
 	    break;
     }
 
-    for (i=0; i<sock_cnt && mapped_status==0; ++i) {
+    for (i=0; i<sock_cnt && status==PJ_SUCCESS; ++i) {
 	if (rec[i].srv[0].mapped_addr == rec[i].srv[1].mapped_addr &&
 	    rec[i].srv[0].mapped_port == rec[i].srv[1].mapped_port)
 	{
@@ -245,35 +221,21 @@
 	    mapped_addr[i].sin_port = (pj_uint16_t)rec[i].srv[0].mapped_port;
 
 	    if (rec[i].srv[0].mapped_addr == 0 || rec[i].srv[0].mapped_port == 0) {
-		mapped_status = PJ_STUN_ERR_NO_RESPONSE;
+		status = PJLIB_UTIL_ESTUNNOTRESPOND;
 		break;
 	    }
 	} else {
-	    mapped_status = PJ_STUN_ERR_SYMETRIC;
+	    status = PJLIB_UTIL_ESTUNSYMMETRIC;
 	    break;
 	}
     }
 
     pj_pool_release(pool);
 
-    return mapped_status;
+    return status;
 
 on_error:
     if (pool) pj_pool_release(pool);
-    return -1;
+    return status;
 }
 
-PJ_DEF(const char*) pj_stun_get_err_msg(pj_status_t status)
-{
-    switch (status) {
-    case 0:			    return "No error";
-    case -1:			    return "General error";
-    case PJ_STUN_ERR_MEMORY:	    return "Memory allocation failed";
-    case PJ_STUN_ERR_RESOLVE:	    return "Invalid IP or unable to resolve STUN server";
-    case PJ_STUN_ERR_TRANSPORT:	    return "Unable to contact STUN server";
-    case PJ_STUN_ERR_INVALID_MSG:   return "Invalid response from STUN server";
-    case PJ_STUN_ERR_NO_RESPONSE:   return "No response from STUN server";
-    case PJ_STUN_ERR_SYMETRIC:	    return "Different mappings are returned from servers";
-    }
-    return "Unknown error";
-}