Index: pjproject/trunk/pjlib-util/build/pjlib_util.dsp
===================================================================
--- pjproject/trunk/pjlib-util/build/pjlib_util.dsp	(revision 1006)
+++ pjproject/trunk/pjlib-util/build/pjlib_util.dsp	(revision 1008)
@@ -162,4 +162,8 @@
 # Begin Source File
 
+SOURCE="..\src\pjlib-util\stun_session.c"
+# End Source File
+# Begin Source File
+
 SOURCE="..\src\pjlib-util\stun_simple.c"
 # End Source File
@@ -259,4 +263,8 @@
 
 SOURCE="..\include\pjlib-util\stun_server.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\pjlib-util\stun_session.h"
 # End Source File
 # Begin Source File
Index: pjproject/trunk/pjlib-util/build/pjstun_client.dsp
===================================================================
--- pjproject/trunk/pjlib-util/build/pjstun_client.dsp	(revision 1006)
+++ pjproject/trunk/pjlib-util/build/pjstun_client.dsp	(revision 1008)
@@ -90,16 +90,8 @@
 SOURCE="..\src\pjstun-client\client_main.c"
 # End Source File
-# Begin Source File
-
-SOURCE="..\src\pjstun-client\stun_session.c"
-# End Source File
 # End Group
 # Begin Group "Header Files"
 
 # PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\src\pjstun-client\stun_session.h"
-# End Source File
 # End Group
 # Begin Group "Resource Files"
Index: pjproject/trunk/pjlib-util/include/pjlib-util.h
===================================================================
--- pjproject/trunk/pjlib-util/include/pjlib-util.h	(revision 1006)
+++ pjproject/trunk/pjlib-util/include/pjlib-util.h	(revision 1008)
@@ -53,4 +53,5 @@
 #include <pjlib-util/stun_msg.h>
 #include <pjlib-util/stun_server.h>
+#include <pjlib-util/stun_session.h>
 #include <pjlib-util/stun_transaction.h>
 
Index: pjproject/trunk/pjlib-util/include/pjlib-util/stun_session.h
===================================================================
--- pjproject/trunk/pjlib-util/include/pjlib-util/stun_session.h	(revision 1008)
+++ pjproject/trunk/pjlib-util/include/pjlib-util/stun_session.h	(revision 1008)
@@ -0,0 +1,419 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2005 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_STUN_SESSION_H__
+#define __PJLIB_UTIL_STUN_SESSION_H__
+
+#include <pjlib-util/stun_msg.h>
+#include <pjlib-util/stun_endpoint.h>
+#include <pjlib-util/stun_transaction.h>
+#include <pj/list.h>
+
+
+/** Forward declaration for pj_stun_tx_data */
+typedef struct pj_stun_tx_data pj_stun_tx_data;
+
+/** Forward declaration for pj_stun_session */
+typedef struct pj_stun_session pj_stun_session;
+
+/**
+ * This is the callback to be registered to pj_stun_session, to send
+ * outgoing message and to receive various notifications from the STUN
+ * session.
+ */
+typedef struct pj_stun_session_cb
+{
+    /**
+     * Callback to be called by the STUN session to send outgoing message.
+     *
+     * @param tdata	    The STUN transmit data containing the original
+     *			    STUN message
+     * @param pkt	    Packet to be sent.
+     * @param pkt_size	    Size of the packet to be sent.
+     * @param addr_len	    Length of destination address.
+     * @param dst_addr	    The destination address.
+     *
+     * @return		    The callback should return the status of the
+     *			    packet sending.
+     */
+    pj_status_t (*on_send_msg)(pj_stun_tx_data *tdata,
+			       const void *pkt,
+			       pj_size_t pkt_size,
+			       unsigned addr_len, 
+			       const pj_sockaddr_t *dst_addr);
+
+    /**
+     * Callback to be called when Binding response is received or the 
+     * transaction has timed out.
+     *
+     * @param sess	    The STUN session.
+     * @param status	    Status of the request. If the value if not
+     *			    PJ_SUCCESS, the transaction has timed-out
+     *			    or other error has occurred, and the response
+     *			    argument may be NULL.
+     * @param request	    The original STUN request.
+     * @param response	    The response message, on successful transaction.
+     */
+    void (*on_bind_response)(pj_stun_session *sess, 
+			     pj_status_t status, 
+			     pj_stun_tx_data *request,
+			     const pj_stun_msg *response);
+
+    /**
+     * Callback to be called when Allocate response is received or the 
+     * transaction has timed out.
+     *
+     * @param sess	    The STUN session.
+     * @param status	    Status of the request. If the value if not
+     *			    PJ_SUCCESS, the transaction has timed-out
+     *			    or other error has occurred, and the response
+     *			    argument may be NULL.
+     * @param request	    The original STUN request.
+     * @param response	    The response message, on successful transaction.
+     */
+    void (*on_allocate_response)(pj_stun_session *sess, 
+				 pj_status_t status, 
+				 pj_stun_tx_data *request,
+				 const pj_stun_msg *response);
+
+    /**
+     * Callback to be called when Set Active Destination response is received
+     * or the transaction has timed out.
+     *
+     * @param sess	    The STUN session.
+     * @param status	    Status of the request. If the value if not
+     *			    PJ_SUCCESS, the transaction has timed-out
+     *			    or other error has occurred, and the response
+     *			    argument may be NULL.
+     * @param request	    The original STUN request.
+     * @param response	    The response message, on successful transaction.
+     */
+    void (*on_set_active_destination_response)(pj_stun_session *sess, 
+					       pj_status_t status, 
+					       pj_stun_tx_data *request,
+					       const pj_stun_msg *response);
+
+    /**
+     * Callback to be called when Connect response is received or the 
+     * transaction has timed out.
+     *
+     * @param sess	    The STUN session.
+     * @param status	    Status of the request. If the value if not
+     *			    PJ_SUCCESS, the transaction has timed-out
+     *			    or other error has occurred, and the response
+     *			    argument may be NULL.
+     * @param request	    The original STUN request.
+     * @param response	    The response message, on successful transaction.
+     */
+    void (*on_connect_response)( pj_stun_session *sess, 
+				 pj_status_t status, 
+				 pj_stun_tx_data *request,
+				 const pj_stun_msg *response);
+} pj_stun_session_cb;
+
+
+/**
+ * This structure describe the outgoing STUN transmit data to carry the
+ * message to be sent.
+ */
+struct pj_stun_tx_data
+{
+    PJ_DECL_LIST_MEMBER(struct pj_stun_tx_data);
+
+    pj_pool_t		*pool;		/**< Pool.			    */
+    pj_stun_session	*sess;		/**< The STUN session.		    */
+    pj_stun_msg		*msg;		/**< The STUN message.		    */
+    void		*user_data;	/**< Arbitrary user data.	    */
+
+    pj_stun_client_tsx	*client_tsx;	/**< Client STUN transaction.	    */
+    pj_uint8_t		 client_key[12];/**< Client transaction key.	    */
+
+    void		*pkt;		/**< The STUN packet.		    */
+    unsigned		 max_len;	/**< Length of packet buffer.	    */
+    unsigned		 pkt_size;	/**< The actual length of STUN pkt. */
+
+    unsigned		 addr_len;	/**< Length of destination address. */
+    const pj_sockaddr_t	*dst_addr;	/**< Destination address.	    */
+};
+
+
+/**
+ * Options that can be specified when creating or sending outgoing STUN
+ * messages. These options may be specified as bitmask.
+ */
+enum pj_stun_session_option
+{
+    /**
+     * Add short term credential to the message. This option may not be used
+     * together with PJ_STUN_USE_LONG_TERM_CRED option.
+     */
+    PJ_STUN_USE_SHORT_TERM_CRED	= 1,
+
+    /**
+     * Add long term credential to the message. This option may not be used
+     * together with PJ_STUN_USE_SHORT_TERM_CRED option.
+     */
+    PJ_STUN_USE_LONG_TERM_CRED	= 2,
+
+    /**
+     * Add STUN fingerprint to the message.
+     */
+    PJ_STUN_USE_FINGERPRINT	= 4
+};
+
+
+/**
+ * Create a STUN session.
+ *
+ * @param endpt	    The STUN endpoint, to be used to register timers etc.
+ * @param name	    Optional name to be associated with this instance. The
+ *		    name will be used for example for logging purpose.
+ * @param cb	    Session callback.
+ * @param p_sess    Pointer to receive STUN session instance.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create(pj_stun_endpoint *endpt,
+					    const char *name,
+					    const pj_stun_session_cb *cb,
+					    pj_stun_session **p_sess);
+
+/**
+ * Destroy the STUN session.
+ *
+ * @param sess	    The STUN session instance.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess);
+
+/**
+ * Associated an arbitrary data with this STUN session. The user data may
+ * be retrieved later with pj_stun_session_get_user_data() function.
+ *
+ * @param sess	    The STUN session instance.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_set_user_data(pj_stun_session *sess,
+						   void *user_data);
+
+/**
+ * Retrieve the user data previously associated to this STUN session with
+ * pj_stun_session_set_user_data().
+ *
+ * @param sess	    The STUN session instance.
+ *
+ * @return	    The user data associated with this STUN session.
+ */
+PJ_DECL(void*) pj_stun_session_get_user_data(pj_stun_session *sess);
+
+/**
+ * Save a long term credential to be used by this STUN session when sending
+ * outgoing messages. After long term credential is configured, application
+ * may specify PJ_STUN_USE_LONG_TERM_CRED option when sending outgoing STUN
+ * message to send the long term credential in the message.
+ *
+ * @param sess	    The STUN session instance.
+ * @param realm	    Realm of the long term credential.
+ * @param user	    The user name.
+ * @param passwd    The pain-text password.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) 
+pj_stun_session_set_long_term_credential(pj_stun_session *sess,
+					 const pj_str_t *realm,
+					 const pj_str_t *user,
+					 const pj_str_t *passwd);
+
+
+/**
+ * Save a short term credential to be used by this STUN session when sending
+ * outgoing messages. After short term credential is configured, application
+ * may specify PJ_STUN_USE_SHORT_TERM_CRED option when sending outgoing STUN
+ * message to send the short term credential in the message.
+ *
+ * @param sess	    The STUN session instance.
+ * @param user	    The user name.
+ * @param passwd    The pain-text password.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) 
+pj_stun_session_set_short_term_credential(pj_stun_session *sess,
+					  const pj_str_t *user,
+					  const pj_str_t *passwd);
+
+/**
+ * Create a STUN Bind request message. After the message has been 
+ * successfully created, application can send the message by calling 
+ * pj_stun_session_send_msg().
+ *
+ * @param sess	    The STUN session instance.
+ * @param p_tdata   Pointer to receive STUN transmit data instance containing
+ *		    the request.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create_bind_req(pj_stun_session *sess,
+						     pj_stun_tx_data **p_tdata);
+
+/**
+ * Create a STUN Allocate request message. After the message has been
+ * successfully created, application can send the message by calling  
+ * pj_stun_session_send_msg().
+ *
+ * @param sess	    The STUN session instance.
+ * @param p_tdata   Pointer to receive STUN transmit data instance containing
+ *		    the request.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create_allocate_req(pj_stun_session *sess,
+							 pj_stun_tx_data **p_tdata);
+
+/**
+ * Create a STUN Set Active Destination request message. After the message 
+ * has been successfully created, application can send the message by calling
+ * pj_stun_session_send_msg().
+ *
+ * @param sess	    The STUN session instance.
+ * @param p_tdata   Pointer to receive STUN transmit data instance containing
+ *		    the request.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) 
+pj_stun_session_create_set_active_destination_req(pj_stun_session *sess,
+						  pj_stun_tx_data **p_tdata);
+
+/**
+ * Create a STUN Connect request message. After the message has been 
+ * successfully created, application can send the message by calling 
+ * pj_stun_session_send_msg().
+ *
+ * @param sess	    The STUN session instance.
+ * @param p_tdata   Pointer to receive STUN transmit data instance containing
+ *		    the request.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create_connect_req(pj_stun_session *sess,
+							pj_stun_tx_data **p_tdata);
+
+/**
+ * Create a STUN Connection Status Indication message. After the message 
+ * has been successfully created, application can send the message by calling
+ * pj_stun_session_send_msg().
+ *
+ * @param sess	    The STUN session instance.
+ * @param p_tdata   Pointer to receive STUN transmit data instance containing
+ *		    the message.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pj_stun_session_create_connection_status_ind(pj_stun_session *sess,
+					     pj_stun_tx_data **p_tdata);
+
+/**
+ * Create a STUN Send Indication message. After the message has been 
+ * successfully created, application can send the message by calling 
+ * pj_stun_session_send_msg().
+ *
+ * @param sess	    The STUN session instance.
+ * @param p_tdata   Pointer to receive STUN transmit data instance containing
+ *		    the message.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create_send_ind(pj_stun_session *sess,
+						     pj_stun_tx_data **p_tdata);
+
+/**
+ * Create a STUN Data Indication message. After the message has been 
+ * successfully created, application can send the message by calling 
+ * pj_stun_session_send_msg().
+ *
+ * @param sess	    The STUN session instance.
+ * @param p_tdata   Pointer to receive STUN transmit data instance containing
+ *		    the message.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create_data_ind(pj_stun_session *sess,
+						     pj_stun_tx_data **p_tdata);
+
+/**
+ * Send STUN message to the specified destination. This function will encode
+ * the pj_stun_msg instance to a packet buffer, and add credential or
+ * fingerprint if necessary. If the message is a request, the session will
+ * also create and manage a STUN client transaction to be used to manage the
+ * retransmission of the request. After the message has been encoded and
+ * transaction is setup, the \a on_send_msg() callback of pj_stun_session_cb
+ * (which is registered when the STUN session is created) will be called
+ * to actually send the message to the wire.
+ *
+ * @param sess	    The STUN session instance.
+ * @param options   Optional flags, from pj_stun_session_option.
+ * @param addr_len  Length of destination address.
+ * @param dst_addr  The destination socket address.
+ * @param tdata	    The STUN transmit data containing the STUN message to
+ *		    be sent.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess,
+					      unsigned options,
+					      unsigned addr_len,
+					      const pj_sockaddr_t *dst_addr,
+					      pj_stun_tx_data *tdata);
+
+/**
+ * Application must call this function to notify the STUN session about
+ * the arrival of STUN packet. The STUN packet MUST have been checked
+ * first with #pj_stun_msg_check() to verify that this is indeed a valid
+ * STUN packet.
+ *
+ * The STUN session will decode the packet into pj_stun_msg, and process
+ * the message accordingly. If the message is a response, it will search
+ * through the outstanding STUN client transactions for a matching
+ * transaction ID and hand over the response to the transaction.
+ *
+ * On successful message processing, application will be notified about
+ * the message via one of the pj_stun_session_cb callback.
+ *
+ * @param sess	     The STUN session instance.
+ * @param packet     The packet containing STUN message.
+ * @param pkt_size   Size of the packet.
+ * @param parsed_len Optional pointer to receive the size of the parsed
+ *		     STUN message (useful if packet is received via a
+ *		     stream oriented protocol).
+ *
+ * @return	     PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
+					       const void *packet,
+					       pj_size_t pkt_size,
+					       unsigned *parsed_len);
+
+
+
+#endif	/* __PJLIB_UTIL_STUN_SESSION_H__ */
+
Index: pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c
===================================================================
--- pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c	(revision 1008)
+++ pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c	(revision 1008)
@@ -0,0 +1,627 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2005 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/stun_session.h>
+#include <pjlib.h>
+
+struct pj_stun_session
+{
+    pj_stun_endpoint	*endpt;
+    pj_pool_t		*pool;
+    pj_stun_session_cb	 cb;
+    void		*user_data;
+
+    /* Long term credential */
+    pj_str_t		 l_realm;
+    pj_str_t		 l_username;
+    pj_str_t		 l_password;
+
+    /* Short term credential */
+    pj_str_t		 s_username;
+    pj_str_t		 s_password;
+
+    pj_stun_tx_data	 pending_request_list;
+};
+
+#define SNAME(s_)		    ((s_)->pool->obj_name)
+
+#if PJ_LOG_MAX_LEVEL >= 5
+#   define TRACE_(expr)		    PJ_LOG(5,expr)
+#else
+#   define TRACE_(expr)
+#endif
+
+#if PJ_LOG_MAX_LEVEL >= 4
+#   define LOG_ERR_(sess, title, rc)
+static void stun_perror(pj_stun_session *sess, const char *title, 
+			pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+
+    PJ_LOG(4,(SNAME(sess), "%s: %s", title, errmsg));
+}
+
+#else
+#   define ERR_(sess, title, rc)
+#endif
+
+#define TDATA_POOL_SIZE		    1024
+#define TDATA_POOL_INC		    1024
+
+
+static void tsx_on_complete(pj_stun_client_tsx *tsx,
+			    pj_status_t status, 
+			    const pj_stun_msg *response);
+static pj_status_t tsx_on_send_msg(pj_stun_client_tsx *tsx,
+				   const void *stun_pkt,
+				   pj_size_t pkt_size);
+
+static pj_stun_tsx_cb tsx_cb = 
+{
+    &tsx_on_complete,
+    &tsx_on_send_msg
+};
+
+
+static pj_status_t tsx_add(pj_stun_session *sess,
+			   pj_stun_tx_data *tdata)
+{
+    pj_list_push_back(&sess->pending_request_list, tdata);
+    return PJ_SUCCESS;
+}
+
+static pj_status_t tsx_erase(pj_stun_session *sess,
+			     pj_stun_tx_data *tdata)
+{
+    PJ_UNUSED_ARG(sess);
+    pj_list_erase(tdata);
+    return PJ_SUCCESS;
+}
+
+static pj_stun_tx_data* tsx_lookup(pj_stun_session *sess,
+				   const pj_stun_msg *msg)
+{
+    pj_stun_tx_data *tdata;
+
+    tdata = sess->pending_request_list.next;
+    while (tdata != &sess->pending_request_list) {
+	pj_assert(sizeof(tdata->client_key)==sizeof(msg->hdr.tsx_id));
+	if (pj_memcmp(tdata->client_key, msg->hdr.tsx_id, 
+		      sizeof(msg->hdr.tsx_id))==0)
+	{
+	    return tdata;
+	}
+	tdata = tdata->next;
+    }
+
+    return NULL;
+}
+
+static pj_status_t create_tdata(pj_stun_session *sess,
+				unsigned msg_type,
+				void *user_data,
+			        pj_stun_tx_data **p_tdata)
+{
+    pj_pool_t *pool;
+    pj_status_t status;
+    pj_stun_tx_data *tdata;
+
+    /* Create pool and initialize basic tdata attributes */
+    pool = pj_pool_create(sess->endpt->pf, "tdata%p", 
+			  TDATA_POOL_SIZE, TDATA_POOL_INC, NULL);
+    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);
+
+    tdata = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_tx_data);
+    tdata->pool = pool;
+    tdata->sess = sess;
+    tdata->user_data = user_data;
+
+    /* Create STUN message */
+    status = pj_stun_msg_create(pool, msg_type,  PJ_STUN_MAGIC, 
+				NULL, &tdata->msg);
+    if (status != PJ_SUCCESS) {
+	pj_pool_release(pool);
+	return status;
+    }
+
+    /* If this is a request, then copy the request's transaction ID
+     * as the transaction key.
+     */
+    if (PJ_STUN_IS_REQUEST(msg_type)) {
+	pj_assert(sizeof(tdata->client_key)==sizeof(tdata->msg->hdr.tsx_id));
+	pj_memcpy(tdata->client_key, tdata->msg->hdr.tsx_id,
+		  sizeof(tdata->msg->hdr.tsx_id));
+    }
+
+    *p_tdata = tdata;
+
+    return PJ_SUCCESS;
+}
+
+static void destroy_tdata(pj_stun_tx_data *tdata)
+{
+    if (tdata->client_tsx) {
+	tsx_erase(tdata->sess, tdata);
+	pj_stun_client_tsx_destroy(tdata->client_tsx);
+	tdata->client_tsx = NULL;
+    }
+
+    pj_pool_release(tdata->pool);
+}
+
+static pj_status_t session_apply_req(pj_stun_session *sess,
+				     pj_pool_t *pool,
+				     unsigned options,
+				     pj_stun_msg *msg)
+{
+    pj_status_t status;
+
+    /* From draft-ietf-behave-rfc3489bis-05.txt
+     * Section 8.3.1.  Formulating the Request Message
+     */
+    if (options & PJ_STUN_USE_LONG_TERM_CRED) {
+	pj_stun_generic_string_attr *auname;
+	pj_stun_msg_integrity_attr *amsgi;
+	pj_stun_generic_string_attr *arealm;
+
+	/* Create and add USERNAME attribute */
+	status = pj_stun_generic_string_attr_create(sess->pool, 
+						    PJ_STUN_ATTR_USERNAME,
+						    &sess->l_username,
+						    &auname);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	status = pj_stun_msg_add_attr(msg, &auname->hdr);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	/* Add REALM only when long term credential is used */
+	status = pj_stun_generic_string_attr_create(sess->pool, 
+						    PJ_STUN_ATTR_REALM,
+						    &sess->l_realm,
+						    &arealm);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	status = pj_stun_msg_add_attr(msg, &arealm->hdr);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	/* Add MESSAGE-INTEGRITY attribute */
+	status = pj_stun_msg_integrity_attr_create(sess->pool, &amsgi);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	status = pj_stun_msg_add_attr(msg, &amsgi->hdr);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	PJ_TODO(COMPUTE_MESSAGE_INTEGRITY1);
+
+    } else if (options & PJ_STUN_USE_SHORT_TERM_CRED) {
+	pj_stun_generic_string_attr *auname;
+	pj_stun_msg_integrity_attr *amsgi;
+
+	/* Create and add USERNAME attribute */
+	status = pj_stun_generic_string_attr_create(sess->pool, 
+						    PJ_STUN_ATTR_USERNAME,
+						    &sess->s_username,
+						    &auname);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	status = pj_stun_msg_add_attr(msg, &auname->hdr);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	/* Add MESSAGE-INTEGRITY attribute */
+	status = pj_stun_msg_integrity_attr_create(sess->pool, &amsgi);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	status = pj_stun_msg_add_attr(msg, &amsgi->hdr);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	PJ_TODO(COMPUTE_MESSAGE_INTEGRITY2);
+    }
+
+    /* Add FINGERPRINT attribute if necessary */
+    if (options & PJ_STUN_USE_FINGERPRINT) {
+	pj_stun_fingerprint_attr *af;
+
+	status = pj_stun_generic_uint_attr_create(sess->pool, 
+						  PJ_STUN_ATTR_FINGERPRINT,
+						  0, &af);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+	status = pj_stun_msg_add_attr(msg, &af->hdr);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+static void tsx_on_complete(pj_stun_client_tsx *tsx,
+			    pj_status_t status, 
+			    const pj_stun_msg *response)
+{
+    pj_stun_tx_data *tdata;
+
+    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);
+
+    switch (PJ_STUN_GET_METHOD(tdata->msg->hdr.type)) {
+    case PJ_STUN_BINDING_METHOD:
+	tdata->sess->cb.on_bind_response(tdata->sess, status, tdata, response);
+	break;
+    case PJ_STUN_ALLOCATE_METHOD:
+	tdata->sess->cb.on_allocate_response(tdata->sess, status,
+					     tdata, response);
+	break;
+    case PJ_STUN_SET_ACTIVE_DESTINATION_METHOD:
+	tdata->sess->cb.on_set_active_destination_response(tdata->sess, status,
+							   tdata, response);
+	break;
+    case PJ_STUN_CONNECT_METHOD:
+	tdata->sess->cb.on_connect_response(tdata->sess, status, tdata,
+					    response);
+	break;
+    default:
+	pj_assert(!"Unknown method");
+	break;
+    }
+}
+
+static pj_status_t tsx_on_send_msg(pj_stun_client_tsx *tsx,
+				   const void *stun_pkt,
+				   pj_size_t pkt_size)
+{
+    pj_stun_tx_data *tdata;
+
+    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);
+
+    return tdata->sess->cb.on_send_msg(tdata, stun_pkt, pkt_size,
+				       tdata->addr_len, tdata->dst_addr);
+}
+
+/* **************************************************************************/
+
+PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_endpoint *endpt,
+					    const char *name,
+					    const pj_stun_session_cb *cb,
+					    pj_stun_session **p_sess)
+{
+    pj_pool_t	*pool;
+    pj_stun_session *sess;
+
+    PJ_ASSERT_RETURN(endpt && cb && p_sess, PJ_EINVAL);
+
+    pool = pj_pool_create(endpt->pf, name, 4000, 4000, NULL);
+    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);
+
+    sess = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_session);
+    sess->endpt = endpt;
+    sess->pool = pool;
+    pj_memcpy(&sess->cb, cb, sizeof(*cb));
+
+    pj_list_init(&sess->pending_request_list);
+
+    *p_sess = sess;
+
+    PJ_TODO(MUTEX_PROTECTION);
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess)
+{
+    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
+
+    pj_pool_release(sess->pool);
+
+    return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pj_stun_session_set_user_data( pj_stun_session *sess,
+						   void *user_data)
+{
+    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
+    sess->user_data = user_data;
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(void*) pj_stun_session_get_user_data(pj_stun_session *sess)
+{
+    PJ_ASSERT_RETURN(sess, NULL);
+    return sess->user_data;
+}
+
+PJ_DEF(pj_status_t) 
+pj_stun_session_set_long_term_credential(pj_stun_session *sess,
+					 const pj_str_t *realm,
+					 const pj_str_t *user,
+					 const pj_str_t *passwd)
+{
+    pj_str_t nil = { NULL, 0 };
+
+    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
+    pj_strdup_with_null(sess->pool, &sess->l_realm, realm ? realm : &nil);
+    pj_strdup_with_null(sess->pool, &sess->l_username, user ? user : &nil);
+    pj_strdup_with_null(sess->pool, &sess->l_password, passwd ? passwd : &nil);
+
+    return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) 
+pj_stun_session_set_short_term_credential(pj_stun_session *sess,
+					  const pj_str_t *user,
+					  const pj_str_t *passwd)
+{
+    pj_str_t nil = { NULL, 0 };
+
+    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
+    pj_strdup_with_null(sess->pool, &sess->s_username, user ? user : &nil);
+    pj_strdup_with_null(sess->pool, &sess->s_password, passwd ? passwd : &nil);
+
+    return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pj_stun_session_create_bind_req(pj_stun_session *sess,
+						    pj_stun_tx_data **p_tdata)
+{
+    pj_stun_tx_data *tdata;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(sess && p_tdata, PJ_EINVAL);
+
+    status = create_tdata(sess, PJ_STUN_BINDING_REQUEST, NULL, &tdata);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    *p_tdata = tdata;
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_stun_session_create_allocate_req(pj_stun_session *sess,
+							pj_stun_tx_data **p_tdata)
+{
+    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
+}
+
+
+PJ_DEF(pj_status_t) 
+pj_stun_session_create_set_active_destination_req(pj_stun_session *sess,
+						  pj_stun_tx_data **p_tdata)
+{
+    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
+}
+
+PJ_DEF(pj_status_t) pj_stun_session_create_connect_req(	pj_stun_session *sess,
+						        pj_stun_tx_data **p_tdata)
+{
+    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
+}
+
+PJ_DEF(pj_status_t) 
+pj_stun_session_create_connection_status_ind(pj_stun_session *sess,
+					     pj_stun_tx_data **p_tdata)
+{
+    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
+}
+
+PJ_DEF(pj_status_t) pj_stun_session_create_send_ind( pj_stun_session *sess,
+						     pj_stun_tx_data **p_tdata)
+{
+    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
+}
+
+PJ_DEF(pj_status_t) pj_stun_session_create_data_ind( pj_stun_session *sess,
+						     pj_stun_tx_data **p_tdata)
+{
+    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
+}
+
+PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess,
+					      unsigned options,
+					      unsigned addr_len,
+					      const pj_sockaddr_t *server,
+					      pj_stun_tx_data *tdata)
+{
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(sess && addr_len && server && tdata, PJ_EINVAL);
+
+    /* Allocate packet */
+    tdata->max_len = PJ_STUN_MAX_PKT_LEN;
+    tdata->pkt = pj_pool_alloc(tdata->pool, tdata->max_len);
+
+    if (PJ_LOG_MAX_LEVEL >= 5) {
+	char *buf = (char*) tdata->pkt;
+	const char *dst_name;
+	int dst_port;
+	const pj_sockaddr *dst = (const pj_sockaddr*)server;
+	
+	if (dst->sa_family == PJ_AF_INET) {
+	    const pj_sockaddr_in *dst4 = (const pj_sockaddr_in*)dst;
+	    dst_name = pj_inet_ntoa(dst4->sin_addr);
+	    dst_port = pj_ntohs(dst4->sin_port);
+	} else if (dst->sa_family == PJ_AF_INET6) {
+	    const pj_sockaddr_in6 *dst6 = (const pj_sockaddr_in6*)dst;
+	    dst_name = "IPv6";
+	    dst_port = pj_ntohs(dst6->sin6_port);
+	} else {
+	    LOG_ERR_(sess, "Invalid address family", PJ_EINVAL);
+	    return PJ_EINVAL;
+	}
+
+	PJ_LOG(5,(SNAME(sess), 
+		  "Sending STUN message to %s:%d:\n"
+		  "--- begin STUN message ---\n"
+		  "%s"
+		  "--- end of STUN message ---\n",
+		  dst_name, dst_port,
+		  pj_stun_msg_dump(tdata->msg, buf, tdata->max_len, NULL)));
+    }
+
+    /* Apply options */
+    status = session_apply_req(sess, tdata->pool, options, tdata->msg);
+    if (status != PJ_SUCCESS) {
+	LOG_ERR_(sess, "Error applying options", status);
+	destroy_tdata(tdata);
+	return status;
+    }
+
+    /* Encode message */
+    status = pj_stun_msg_encode(tdata->msg, tdata->pkt, tdata->max_len,
+			        0, NULL, &tdata->pkt_size);
+    if (status != PJ_SUCCESS) {
+	LOG_ERR_(sess, "STUN encode() error", status);
+	destroy_tdata(tdata);
+	return status;
+    }
+
+    /* If this is a STUN request message, then send the request with
+     * a new STUN client transaction.
+     */
+    if (PJ_STUN_IS_REQUEST(tdata->msg->hdr.type)) {
+
+	/* Create STUN client transaction */
+	status = pj_stun_client_tsx_create(sess->endpt, tdata->pool, 
+					   &tsx_cb, &tdata->client_tsx);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+	pj_stun_client_tsx_set_data(tdata->client_tsx, (void*)tdata);
+
+	/* Save the remote address */
+	tdata->addr_len = addr_len;
+	tdata->dst_addr = server;
+
+	/* Send the request! */
+	status = pj_stun_client_tsx_send_msg(tdata->client_tsx, PJ_TRUE,
+					     tdata->pkt, tdata->pkt_size);
+	if (status != PJ_SUCCESS && status != PJ_EPENDING) {
+	    LOG_ERR_(sess, "Error sending STUN request", status);
+	    destroy_tdata(tdata);
+	    return status;
+	}
+
+	/* Add to pending request list */
+	tsx_add(sess, tdata);
+
+    } else {
+	/* Otherwise for non-request message, send directly to transport. */
+	status = sess->cb.on_send_msg(tdata, tdata->pkt, tdata->pkt_size,
+				      addr_len, server);
+
+	if (status != PJ_SUCCESS && status != PJ_EPENDING) {
+	    LOG_ERR_(sess, "Error sending STUN request", status);
+	    destroy_tdata(tdata);
+	    return status;
+	}
+    }
+
+
+    return status;
+}
+
+
+PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
+					      const void *packet,
+					      pj_size_t pkt_size,
+					      unsigned *parsed_len)
+{
+    pj_stun_msg *msg, *response;
+    pj_pool_t *tmp_pool;
+    char *dump;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL);
+
+    tmp_pool = pj_pool_create(sess->endpt->pf, "tmpstun", 1024, 1024, NULL);
+    if (!tmp_pool)
+	return PJ_ENOMEM;
+
+    /* Try to parse the message */
+    status = pj_stun_msg_decode(tmp_pool, (const pj_uint8_t*)packet,
+			        pkt_size, 0, &msg, parsed_len,
+				&response);
+    if (status != PJ_SUCCESS) {
+	LOG_ERR_(sess, "STUN msg_decode() error", status);
+	if (response) {
+	    PJ_TODO(SEND_RESPONSE);
+	}
+	pj_pool_release(tmp_pool);
+	return status;
+    }
+
+    dump = pj_pool_alloc(tmp_pool, PJ_STUN_MAX_PKT_LEN);
+
+    PJ_LOG(4,(SNAME(sess), 
+	      "RX STUN message:\n"
+	      "--- begin STUN message ---"
+	      "%s"
+	      "--- end of STUN message ---\n",
+	      pj_stun_msg_dump(msg, dump, PJ_STUN_MAX_PKT_LEN, NULL)));
+
+
+    if (PJ_STUN_IS_RESPONSE(msg->hdr.type) ||
+	PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))
+    {
+	pj_stun_tx_data *tdata;
+
+	/* Lookup pending client transaction */
+	tdata = tsx_lookup(sess, msg);
+	if (tdata == NULL) {
+	    LOG_ERR_(sess, "STUN error finding transaction", PJ_ENOTFOUND);
+	    pj_pool_release(tmp_pool);
+	    return PJ_ENOTFOUND;
+	}
+
+	/* Pass the response to the transaction. 
+	 * If the message is accepted, transaction callback will be called,
+	 * and this will call the session callback too.
+	 */
+	status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg);
+	if (status != PJ_SUCCESS) {
+	    pj_pool_release(tmp_pool);
+	    return status;
+	}
+
+	/* If transaction has completed, destroy the transmit data.
+	 * This will remove the transaction from the pending list too.
+	 */
+	if (pj_stun_client_tsx_is_complete(tdata->client_tsx)) {
+	    destroy_tdata(tdata);
+	    tdata = NULL;
+	}
+
+	pj_pool_release(tmp_pool);
+	return PJ_SUCCESS;
+
+    } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) {
+
+	PJ_TODO(HANDLE_INCOMING_STUN_REQUEST);
+
+    } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) {
+
+	PJ_TODO(HANDLE_INCOMING_STUN_INDICATION);
+
+    } else {
+	pj_assert(!"Unexpected!");
+    }
+
+    pj_pool_release(tmp_pool);
+    return PJ_ENOTSUP;
+}
+
Index: pjproject/trunk/pjlib-util/src/pjstun-client/client_main.c
===================================================================
--- pjproject/trunk/pjlib-util/src/pjstun-client/client_main.c	(revision 1006)
+++ pjproject/trunk/pjlib-util/src/pjstun-client/client_main.c	(revision 1008)
@@ -19,5 +19,4 @@
 #include <pjlib-util.h>
 #include <pjlib.h>
-#include "stun_session.h"
 
 #include <conio.h>
Index: pjproject/trunk/pjlib-util/src/pjstun-client/stun_session.c
===================================================================
--- pjproject/trunk/pjlib-util/src/pjstun-client/stun_session.c	(revision 1006)
+++ 	(revision )
@@ -1,626 +1,0 @@
-/* $Id$ */
-/* 
- * Copyright (C) 2003-2005 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 "stun_session.h"
-#include <pjlib.h>
-
-struct pj_stun_session
-{
-    pj_stun_endpoint	*endpt;
-    pj_pool_t		*pool;
-    pj_stun_session_cb	 cb;
-    void		*user_data;
-
-    /* Long term credential */
-    pj_str_t		 l_realm;
-    pj_str_t		 l_username;
-    pj_str_t		 l_password;
-
-    /* Short term credential */
-    pj_str_t		 s_username;
-    pj_str_t		 s_password;
-
-    pj_stun_tx_data	 pending_request_list;
-};
-
-#define SNAME(s_)		    ((s_)->pool->obj_name)
-
-#if PJ_LOG_MAX_LEVEL >= 5
-#   define TRACE_(expr)		    PJ_LOG(5,expr)
-#else
-#   define TRACE_(expr)
-#endif
-
-#if PJ_LOG_MAX_LEVEL >= 4
-#   define LOG_ERR_(sess, title, rc)
-static void stun_perror(pj_stun_session *sess, const char *title, 
-			pj_status_t status)
-{
-    char errmsg[PJ_ERR_MSG_SIZE];
-
-    pj_strerror(status, errmsg, sizeof(errmsg));
-
-    PJ_LOG(4,(SNAME(sess), "%s: %s", title, errmsg));
-}
-
-#else
-#   define ERR_(sess, title, rc)
-#endif
-
-#define TDATA_POOL_SIZE		    1024
-#define TDATA_POOL_INC		    1024
-
-
-static void tsx_on_complete(pj_stun_client_tsx *tsx,
-			    pj_status_t status, 
-			    const pj_stun_msg *response);
-static pj_status_t tsx_on_send_msg(pj_stun_client_tsx *tsx,
-				   const void *stun_pkt,
-				   pj_size_t pkt_size);
-
-static pj_stun_tsx_cb tsx_cb = 
-{
-    &tsx_on_complete,
-    &tsx_on_send_msg
-};
-
-
-static pj_status_t tsx_add(pj_stun_session *sess,
-			   pj_stun_tx_data *tdata)
-{
-    pj_list_push_back(&sess->pending_request_list, tdata);
-    return PJ_SUCCESS;
-}
-
-static pj_status_t tsx_erase(pj_stun_session *sess,
-			     pj_stun_tx_data *tdata)
-{
-    pj_list_erase(tdata);
-    return PJ_SUCCESS;
-}
-
-static pj_stun_tx_data* tsx_lookup(pj_stun_session *sess,
-				   const pj_stun_msg *msg)
-{
-    pj_stun_tx_data *tdata;
-
-    tdata = sess->pending_request_list.next;
-    while (tdata != &sess->pending_request_list) {
-	pj_assert(sizeof(tdata->client_key)==sizeof(msg->hdr.tsx_id));
-	if (pj_memcmp(tdata->client_key, msg->hdr.tsx_id, 
-		      sizeof(msg->hdr.tsx_id))==0)
-	{
-	    return tdata;
-	}
-	tdata = tdata->next;
-    }
-
-    return NULL;
-}
-
-static pj_status_t create_tdata(pj_stun_session *sess,
-				unsigned msg_type,
-				void *user_data,
-			        pj_stun_tx_data **p_tdata)
-{
-    pj_pool_t *pool;
-    pj_status_t status;
-    pj_stun_tx_data *tdata;
-
-    /* Create pool and initialize basic tdata attributes */
-    pool = pj_pool_create(sess->endpt->pf, "tdata%p", 
-			  TDATA_POOL_SIZE, TDATA_POOL_INC, NULL);
-    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);
-
-    tdata = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_tx_data);
-    tdata->pool = pool;
-    tdata->sess = sess;
-    tdata->user_data = tdata;
-
-    /* Create STUN message */
-    status = pj_stun_msg_create(pool, msg_type,  PJ_STUN_MAGIC, 
-				NULL, &tdata->msg);
-    if (status != PJ_SUCCESS) {
-	pj_pool_release(pool);
-	return status;
-    }
-
-    /* If this is a request, then copy the request's transaction ID
-     * as the transaction key.
-     */
-    if (PJ_STUN_IS_REQUEST(msg_type)) {
-	pj_assert(sizeof(tdata->client_key)==sizeof(tdata->msg->hdr.tsx_id));
-	pj_memcpy(tdata->client_key, tdata->msg->hdr.tsx_id,
-		  sizeof(tdata->msg->hdr.tsx_id));
-    }
-
-    *p_tdata = tdata;
-
-    return PJ_SUCCESS;
-}
-
-static void destroy_tdata(pj_stun_tx_data *tdata)
-{
-    if (tdata->client_tsx) {
-	tsx_erase(tdata->sess, tdata);
-	pj_stun_client_tsx_destroy(tdata->client_tsx);
-	tdata->client_tsx = NULL;
-    }
-
-    pj_pool_release(tdata->pool);
-}
-
-static pj_status_t session_apply_req(pj_stun_session *sess,
-				     pj_pool_t *pool,
-				     unsigned options,
-				     pj_stun_msg *msg)
-{
-    pj_status_t status;
-
-    /* From draft-ietf-behave-rfc3489bis-05.txt
-     * Section 8.3.1.  Formulating the Request Message
-     */
-    if (options & PJ_STUN_USE_LONG_TERM_CRED) {
-	pj_stun_generic_string_attr *auname;
-	pj_stun_msg_integrity_attr *amsgi;
-	pj_stun_generic_string_attr *arealm;
-
-	/* Create and add USERNAME attribute */
-	status = pj_stun_generic_string_attr_create(sess->pool, 
-						    PJ_STUN_ATTR_USERNAME,
-						    &sess->l_username,
-						    &auname);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	status = pj_stun_msg_add_attr(msg, &auname->hdr);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	/* Add REALM only when long term credential is used */
-	status = pj_stun_generic_string_attr_create(sess->pool, 
-						    PJ_STUN_ATTR_REALM,
-						    &sess->l_realm,
-						    &arealm);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	status = pj_stun_msg_add_attr(msg, &arealm->hdr);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	/* Add MESSAGE-INTEGRITY attribute */
-	status = pj_stun_msg_integrity_attr_create(sess->pool, &amsgi);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	status = pj_stun_msg_add_attr(msg, &amsgi->hdr);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	PJ_TODO(COMPUTE_MESSAGE_INTEGRITY1);
-
-    } else if (options & PJ_STUN_USE_SHORT_TERM_CRED) {
-	pj_stun_generic_string_attr *auname;
-	pj_stun_msg_integrity_attr *amsgi;
-
-	/* Create and add USERNAME attribute */
-	status = pj_stun_generic_string_attr_create(sess->pool, 
-						    PJ_STUN_ATTR_USERNAME,
-						    &sess->s_username,
-						    &auname);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	status = pj_stun_msg_add_attr(msg, &auname->hdr);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	/* Add MESSAGE-INTEGRITY attribute */
-	status = pj_stun_msg_integrity_attr_create(sess->pool, &amsgi);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	status = pj_stun_msg_add_attr(msg, &amsgi->hdr);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	PJ_TODO(COMPUTE_MESSAGE_INTEGRITY2);
-    }
-
-    /* Add FINGERPRINT attribute if necessary */
-    if (options & PJ_STUN_USE_FINGERPRINT) {
-	pj_stun_fingerprint_attr *af;
-
-	status = pj_stun_generic_uint_attr_create(sess->pool, 
-						  PJ_STUN_ATTR_FINGERPRINT,
-						  0, &af);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-
-	status = pj_stun_msg_add_attr(msg, &af->hdr);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-    }
-
-    return PJ_SUCCESS;
-}
-
-
-static void tsx_on_complete(pj_stun_client_tsx *tsx,
-			    pj_status_t status, 
-			    const pj_stun_msg *response)
-{
-    pj_stun_tx_data *tdata;
-
-    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);
-
-    switch (PJ_STUN_GET_METHOD(tdata->msg->hdr.type)) {
-    case PJ_STUN_BINDING_METHOD:
-	tdata->sess->cb.on_bind_response(tdata->sess, status, tdata, response);
-	break;
-    case PJ_STUN_ALLOCATE_METHOD:
-	tdata->sess->cb.on_allocate_response(tdata->sess, status,
-					     tdata, response);
-	break;
-    case PJ_STUN_SET_ACTIVE_DESTINATION_METHOD:
-	tdata->sess->cb.on_set_active_destination_response(tdata->sess, status,
-							   tdata, response);
-	break;
-    case PJ_STUN_CONNECT_METHOD:
-	tdata->sess->cb.on_connect_response(tdata->sess, status, tdata,
-					    response);
-	break;
-    default:
-	pj_assert(!"Unknown method");
-	break;
-    }
-}
-
-static pj_status_t tsx_on_send_msg(pj_stun_client_tsx *tsx,
-				   const void *stun_pkt,
-				   pj_size_t pkt_size)
-{
-    pj_stun_tx_data *tdata;
-
-    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx);
-
-    return tdata->sess->cb.on_send_msg(tdata, stun_pkt, pkt_size,
-				       tdata->addr_len, tdata->dst_addr);
-}
-
-/* **************************************************************************/
-
-PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_endpoint *endpt,
-					    const char *name,
-					    const pj_stun_session_cb *cb,
-					    pj_stun_session **p_sess)
-{
-    pj_pool_t	*pool;
-    pj_stun_session *sess;
-
-    PJ_ASSERT_RETURN(endpt && cb && p_sess, PJ_EINVAL);
-
-    pool = pj_pool_create(endpt->pf, name, 4000, 4000, NULL);
-    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);
-
-    sess = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_session);
-    sess->endpt = endpt;
-    sess->pool = pool;
-    pj_memcpy(&sess->cb, cb, sizeof(*cb));
-
-    pj_list_init(&sess->pending_request_list);
-
-    *p_sess = sess;
-
-    PJ_TODO(MUTEX_PROTECTION);
-
-    return PJ_SUCCESS;
-}
-
-PJ_DEF(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess)
-{
-    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
-
-    pj_pool_release(sess->pool);
-
-    return PJ_SUCCESS;
-}
-
-
-PJ_DEF(pj_status_t) pj_stun_session_set_user_data( pj_stun_session *sess,
-						   void *user_data)
-{
-    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
-    sess->user_data = user_data;
-    return PJ_SUCCESS;
-}
-
-PJ_DEF(void*) pj_stun_session_get_user_data(pj_stun_session *sess)
-{
-    PJ_ASSERT_RETURN(sess, NULL);
-    return sess->user_data;
-}
-
-PJ_DEF(pj_status_t) 
-pj_stun_session_set_long_term_credential(pj_stun_session *sess,
-					 const pj_str_t *realm,
-					 const pj_str_t *user,
-					 const pj_str_t *passwd)
-{
-    pj_str_t nil = { NULL, 0 };
-
-    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
-    pj_strdup_with_null(sess->pool, &sess->l_realm, realm ? realm : &nil);
-    pj_strdup_with_null(sess->pool, &sess->l_username, user ? user : &nil);
-    pj_strdup_with_null(sess->pool, &sess->l_password, passwd ? passwd : &nil);
-
-    return PJ_SUCCESS;
-}
-
-
-PJ_DEF(pj_status_t) 
-pj_stun_session_set_short_term_credential(pj_stun_session *sess,
-					  const pj_str_t *user,
-					  const pj_str_t *passwd)
-{
-    pj_str_t nil = { NULL, 0 };
-
-    PJ_ASSERT_RETURN(sess, PJ_EINVAL);
-    pj_strdup_with_null(sess->pool, &sess->s_username, user ? user : &nil);
-    pj_strdup_with_null(sess->pool, &sess->s_password, passwd ? passwd : &nil);
-
-    return PJ_SUCCESS;
-}
-
-
-PJ_DEF(pj_status_t) pj_stun_session_create_bind_req(pj_stun_session *sess,
-						    pj_stun_tx_data **p_tdata)
-{
-    pj_stun_tx_data *tdata;
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(sess && p_tdata, PJ_EINVAL);
-
-    status = create_tdata(sess, PJ_STUN_BINDING_REQUEST, NULL, &tdata);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    *p_tdata = tdata;
-    return PJ_SUCCESS;
-}
-
-PJ_DEF(pj_status_t) pj_stun_session_create_allocate_req(pj_stun_session *sess,
-							pj_stun_tx_data **p_tdata)
-{
-    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
-}
-
-
-PJ_DEF(pj_status_t) 
-pj_stun_session_create_set_active_destination_req(pj_stun_session *sess,
-						  pj_stun_tx_data **p_tdata)
-{
-    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
-}
-
-PJ_DEF(pj_status_t) pj_stun_session_create_connect_req(	pj_stun_session *sess,
-						        pj_stun_tx_data **p_tdata)
-{
-    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
-}
-
-PJ_DEF(pj_status_t) 
-pj_stun_session_create_connection_status_ind(pj_stun_session *sess,
-					     pj_stun_tx_data **p_tdata)
-{
-    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
-}
-
-PJ_DEF(pj_status_t) pj_stun_session_create_send_ind( pj_stun_session *sess,
-						     pj_stun_tx_data **p_tdata)
-{
-    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
-}
-
-PJ_DEF(pj_status_t) pj_stun_session_create_data_ind( pj_stun_session *sess,
-						     pj_stun_tx_data **p_tdata)
-{
-    PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP);
-}
-
-PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess,
-					      unsigned options,
-					      unsigned addr_len,
-					      const pj_sockaddr_t *server,
-					      pj_stun_tx_data *tdata)
-{
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(sess && addr_len && server && tdata, PJ_EINVAL);
-
-    /* Allocate packet */
-    tdata->max_len = PJ_STUN_MAX_PKT_LEN;
-    tdata->pkt = pj_pool_alloc(tdata->pool, tdata->max_len);
-
-    if (PJ_LOG_MAX_LEVEL >= 5) {
-	char *buf = (char*) tdata->pkt;
-	const char *dst_name;
-	int dst_port;
-	const pj_sockaddr *dst = (const pj_sockaddr*)server;
-	
-	if (dst->sa_family == PJ_AF_INET) {
-	    const pj_sockaddr_in *dst4 = (const pj_sockaddr_in*)dst;
-	    dst_name = pj_inet_ntoa(dst4->sin_addr);
-	    dst_port = pj_ntohs(dst4->sin_port);
-	} else if (dst->sa_family == PJ_AF_INET6) {
-	    const pj_sockaddr_in6 *dst6 = (const pj_sockaddr_in6*)dst;
-	    dst_name = "IPv6";
-	    dst_port = pj_ntohs(dst6->sin6_port);
-	} else {
-	    LOG_ERR_(sess, "Invalid address family", PJ_EINVAL);
-	    return PJ_EINVAL;
-	}
-
-	PJ_LOG(5,(SNAME(sess), 
-		  "Sending STUN message to %s:%d:\n"
-		  "--- begin STUN message ---\n"
-		  "%s"
-		  "--- end of STUN message ---\n",
-		  dst_name, dst_port,
-		  pj_stun_msg_dump(tdata->msg, buf, tdata->max_len, NULL)));
-    }
-
-    /* Apply options */
-    status = session_apply_req(sess, tdata->pool, options, tdata->msg);
-    if (status != PJ_SUCCESS) {
-	LOG_ERR_(sess, "Error applying options", status);
-	destroy_tdata(tdata);
-	return status;
-    }
-
-    /* Encode message */
-    status = pj_stun_msg_encode(tdata->msg, tdata->pkt, tdata->max_len,
-			        0, NULL, &tdata->pkt_size);
-    if (status != PJ_SUCCESS) {
-	LOG_ERR_(sess, "STUN encode() error", status);
-	destroy_tdata(tdata);
-	return status;
-    }
-
-    /* If this is a STUN request message, then send the request with
-     * a new STUN client transaction.
-     */
-    if (PJ_STUN_IS_REQUEST(tdata->msg->hdr.type)) {
-
-	/* Create STUN client transaction */
-	status = pj_stun_client_tsx_create(sess->endpt, tdata->pool, 
-					   &tsx_cb, &tdata->client_tsx);
-	PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
-	pj_stun_client_tsx_set_data(tdata->client_tsx, (void*)tdata);
-
-	/* Save the remote address */
-	tdata->addr_len = addr_len;
-	tdata->dst_addr = server;
-
-	/* Send the request! */
-	status = pj_stun_client_tsx_send_msg(tdata->client_tsx, PJ_TRUE,
-					     tdata->pkt, tdata->pkt_size);
-	if (status != PJ_SUCCESS && status != PJ_EPENDING) {
-	    LOG_ERR_(sess, "Error sending STUN request", status);
-	    destroy_tdata(tdata);
-	    return status;
-	}
-
-	/* Add to pending request list */
-	tsx_add(sess, tdata);
-
-    } else {
-	/* Otherwise for non-request message, send directly to transport. */
-	status = sess->cb.on_send_msg(tdata, tdata->pkt, tdata->pkt_size,
-				      addr_len, server);
-
-	if (status != PJ_SUCCESS && status != PJ_EPENDING) {
-	    LOG_ERR_(sess, "Error sending STUN request", status);
-	    destroy_tdata(tdata);
-	    return status;
-	}
-    }
-
-
-    return status;
-}
-
-
-PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
-					      const void *packet,
-					      pj_size_t pkt_size,
-					      unsigned *parsed_len)
-{
-    pj_stun_msg *msg, *response;
-    pj_pool_t *tmp_pool;
-    char *dump;
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL);
-
-    tmp_pool = pj_pool_create(sess->endpt->pf, "tmpstun", 1024, 1024, NULL);
-    if (!tmp_pool)
-	return PJ_ENOMEM;
-
-    /* Try to parse the message */
-    status = pj_stun_msg_decode(tmp_pool, (const pj_uint8_t*)packet,
-			        pkt_size, 0, &msg, parsed_len,
-				&response);
-    if (status != PJ_SUCCESS) {
-	LOG_ERR_(sess, "STUN msg_decode() error", status);
-	if (response) {
-	    PJ_TODO(SEND_RESPONSE);
-	}
-	pj_pool_release(tmp_pool);
-	return status;
-    }
-
-    dump = pj_pool_alloc(tmp_pool, PJ_STUN_MAX_PKT_LEN);
-
-    PJ_LOG(4,(SNAME(sess), 
-	      "RX STUN message:\n"
-	      "--- begin STUN message ---"
-	      "%s"
-	      "--- end of STUN message ---\n",
-	      pj_stun_msg_dump(msg, dump, PJ_STUN_MAX_PKT_LEN, NULL)));
-
-
-    if (PJ_STUN_IS_RESPONSE(msg->hdr.type) ||
-	PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))
-    {
-	pj_stun_tx_data *tdata;
-
-	/* Lookup pending client transaction */
-	tdata = tsx_lookup(sess, msg);
-	if (tdata == NULL) {
-	    LOG_ERR_(sess, "STUN error finding transaction", PJ_ENOTFOUND);
-	    pj_pool_release(tmp_pool);
-	    return PJ_ENOTFOUND;
-	}
-
-	/* Pass the response to the transaction. 
-	 * If the message is accepted, transaction callback will be called,
-	 * and this will call the session callback too.
-	 */
-	status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg);
-	if (status != PJ_SUCCESS) {
-	    pj_pool_release(tmp_pool);
-	    return status;
-	}
-
-	/* If transaction has completed, destroy the transmit data.
-	 * This will remove the transaction from the pending list too.
-	 */
-	if (pj_stun_client_tsx_is_complete(tdata->client_tsx)) {
-	    destroy_tdata(tdata);
-	    tdata = NULL;
-	}
-
-	pj_pool_release(tmp_pool);
-	return PJ_SUCCESS;
-
-    } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) {
-
-	PJ_TODO(HANDLE_INCOMING_STUN_REQUEST);
-
-    } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) {
-
-	PJ_TODO(HANDLE_INCOMING_STUN_INDICATION);
-
-    } else {
-	pj_assert(!"Unexpected!");
-    }
-
-    pj_pool_release(tmp_pool);
-    return PJ_ENOTSUP;
-}
-
Index: pjproject/trunk/pjlib-util/src/pjstun-client/stun_session.h
===================================================================
--- pjproject/trunk/pjlib-util/src/pjstun-client/stun_session.h	(revision 1006)
+++ 	(revision )
@@ -1,419 +1,0 @@
-/* $Id$ */
-/* 
- * Copyright (C) 2003-2005 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_STUN_SESSION_H__
-#define __PJLIB_UTIL_STUN_SESSION_H__
-
-#include <pjlib-util/stun_msg.h>
-#include <pjlib-util/stun_endpoint.h>
-#include <pjlib-util/stun_transaction.h>
-#include <pj/list.h>
-
-
-/** Forward declaration for pj_stun_tx_data */
-typedef struct pj_stun_tx_data pj_stun_tx_data;
-
-/** Forward declaration for pj_stun_session */
-typedef struct pj_stun_session pj_stun_session;
-
-/**
- * This is the callback to be registered to pj_stun_session, to send
- * outgoing message and to receive various notifications from the STUN
- * session.
- */
-typedef struct pj_stun_session_cb
-{
-    /**
-     * Callback to be called by the STUN session to send outgoing message.
-     *
-     * @param tdata	    The STUN transmit data containing the original
-     *			    STUN message
-     * @param pkt	    Packet to be sent.
-     * @param pkt_size	    Size of the packet to be sent.
-     * @param addr_len	    Length of destination address.
-     * @param dst_addr	    The destination address.
-     *
-     * @return		    The callback should return the status of the
-     *			    packet sending.
-     */
-    pj_status_t (*on_send_msg)(pj_stun_tx_data *tdata,
-			       const void *pkt,
-			       pj_size_t pkt_size,
-			       unsigned addr_len, 
-			       const pj_sockaddr_t *dst_addr);
-
-    /**
-     * Callback to be called when Binding response is received or the 
-     * transaction has timed out.
-     *
-     * @param sess	    The STUN session.
-     * @param status	    Status of the request. If the value if not
-     *			    PJ_SUCCESS, the transaction has timed-out
-     *			    or other error has occurred, and the response
-     *			    argument may be NULL.
-     * @param request	    The original STUN request.
-     * @param response	    The response message, on successful transaction.
-     */
-    void (*on_bind_response)(pj_stun_session *sess, 
-			     pj_status_t status, 
-			     pj_stun_tx_data *request,
-			     const pj_stun_msg *response);
-
-    /**
-     * Callback to be called when Allocate response is received or the 
-     * transaction has timed out.
-     *
-     * @param sess	    The STUN session.
-     * @param status	    Status of the request. If the value if not
-     *			    PJ_SUCCESS, the transaction has timed-out
-     *			    or other error has occurred, and the response
-     *			    argument may be NULL.
-     * @param request	    The original STUN request.
-     * @param response	    The response message, on successful transaction.
-     */
-    void (*on_allocate_response)(pj_stun_session *sess, 
-				 pj_status_t status, 
-				 pj_stun_tx_data *request,
-				 const pj_stun_msg *response);
-
-    /**
-     * Callback to be called when Set Active Destination response is received
-     * or the transaction has timed out.
-     *
-     * @param sess	    The STUN session.
-     * @param status	    Status of the request. If the value if not
-     *			    PJ_SUCCESS, the transaction has timed-out
-     *			    or other error has occurred, and the response
-     *			    argument may be NULL.
-     * @param request	    The original STUN request.
-     * @param response	    The response message, on successful transaction.
-     */
-    void (*on_set_active_destination_response)(pj_stun_session *sess, 
-					       pj_status_t status, 
-					       pj_stun_tx_data *request,
-					       const pj_stun_msg *response);
-
-    /**
-     * Callback to be called when Connect response is received or the 
-     * transaction has timed out.
-     *
-     * @param sess	    The STUN session.
-     * @param status	    Status of the request. If the value if not
-     *			    PJ_SUCCESS, the transaction has timed-out
-     *			    or other error has occurred, and the response
-     *			    argument may be NULL.
-     * @param request	    The original STUN request.
-     * @param response	    The response message, on successful transaction.
-     */
-    void (*on_connect_response)( pj_stun_session *sess, 
-				 pj_status_t status, 
-				 pj_stun_tx_data *request,
-				 const pj_stun_msg *response);
-} pj_stun_session_cb;
-
-
-/**
- * This structure describe the outgoing STUN transmit data to carry the
- * message to be sent.
- */
-struct pj_stun_tx_data
-{
-    PJ_DECL_LIST_MEMBER(struct pj_stun_tx_data);
-
-    pj_pool_t		*pool;		/**< Pool.			    */
-    pj_stun_session	*sess;		/**< The STUN session.		    */
-    pj_stun_msg		*msg;		/**< The STUN message.		    */
-    void		*user_data;	/**< Arbitrary user data.	    */
-
-    pj_stun_client_tsx	*client_tsx;	/**< Client STUN transaction.	    */
-    pj_uint8_t		 client_key[12];/**< Client transaction key.	    */
-
-    void		*pkt;		/**< The STUN packet.		    */
-    unsigned		 max_len;	/**< Length of packet buffer.	    */
-    unsigned		 pkt_size;	/**< The actual length of STUN pkt. */
-
-    unsigned		 addr_len;	/**< Length of destination address. */
-    const pj_sockaddr_t	*dst_addr;	/**< Destination address.	    */
-};
-
-
-/**
- * Options that can be specified when creating or sending outgoing STUN
- * messages. These options may be specified as bitmask.
- */
-enum pj_stun_session_option
-{
-    /**
-     * Add short term credential to the message. This option may not be used
-     * together with PJ_STUN_USE_LONG_TERM_CRED option.
-     */
-    PJ_STUN_USE_SHORT_TERM_CRED	= 1,
-
-    /**
-     * Add long term credential to the message. This option may not be used
-     * together with PJ_STUN_USE_SHORT_TERM_CRED option.
-     */
-    PJ_STUN_USE_LONG_TERM_CRED	= 2,
-
-    /**
-     * Add STUN fingerprint to the message.
-     */
-    PJ_STUN_USE_FINGERPRINT	= 4
-};
-
-
-/**
- * Create a STUN session.
- *
- * @param endpt	    The STUN endpoint, to be used to register timers etc.
- * @param name	    Optional name to be associated with this instance. The
- *		    name will be used for example for logging purpose.
- * @param cb	    Session callback.
- * @param p_sess    Pointer to receive STUN session instance.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_create(pj_stun_endpoint *endpt,
-					    const char *name,
-					    const pj_stun_session_cb *cb,
-					    pj_stun_session **p_sess);
-
-/**
- * Destroy the STUN session.
- *
- * @param sess	    The STUN session instance.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess);
-
-/**
- * Associated an arbitrary data with this STUN session. The user data may
- * be retrieved later with pj_stun_session_get_user_data() function.
- *
- * @param sess	    The STUN session instance.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_set_user_data(pj_stun_session *sess,
-						   void *user_data);
-
-/**
- * Retrieve the user data previously associated to this STUN session with
- * pj_stun_session_set_user_data().
- *
- * @param sess	    The STUN session instance.
- *
- * @return	    The user data associated with this STUN session.
- */
-PJ_DECL(void*) pj_stun_session_get_user_data(pj_stun_session *sess);
-
-/**
- * Save a long term credential to be used by this STUN session when sending
- * outgoing messages. After long term credential is configured, application
- * may specify PJ_STUN_USE_LONG_TERM_CRED option when sending outgoing STUN
- * message to send the long term credential in the message.
- *
- * @param sess	    The STUN session instance.
- * @param realm	    Realm of the long term credential.
- * @param user	    The user name.
- * @param passwd    The pain-text password.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) 
-pj_stun_session_set_long_term_credential(pj_stun_session *sess,
-					 const pj_str_t *realm,
-					 const pj_str_t *user,
-					 const pj_str_t *passwd);
-
-
-/**
- * Save a short term credential to be used by this STUN session when sending
- * outgoing messages. After short term credential is configured, application
- * may specify PJ_STUN_USE_SHORT_TERM_CRED option when sending outgoing STUN
- * message to send the short term credential in the message.
- *
- * @param sess	    The STUN session instance.
- * @param user	    The user name.
- * @param passwd    The pain-text password.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) 
-pj_stun_session_set_short_term_credential(pj_stun_session *sess,
-					  const pj_str_t *user,
-					  const pj_str_t *passwd);
-
-/**
- * Create a STUN Bind request message. After the message has been 
- * successfully created, application can send the message by calling 
- * pj_stun_session_send_msg().
- *
- * @param sess	    The STUN session instance.
- * @param p_tdata   Pointer to receive STUN transmit data instance containing
- *		    the request.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_create_bind_req(pj_stun_session *sess,
-						     pj_stun_tx_data **p_tdata);
-
-/**
- * Create a STUN Allocate request message. After the message has been
- * successfully created, application can send the message by calling  
- * pj_stun_session_send_msg().
- *
- * @param sess	    The STUN session instance.
- * @param p_tdata   Pointer to receive STUN transmit data instance containing
- *		    the request.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_create_allocate_req(pj_stun_session *sess,
-							 pj_stun_tx_data **p_tdata);
-
-/**
- * Create a STUN Set Active Destination request message. After the message 
- * has been successfully created, application can send the message by calling
- * pj_stun_session_send_msg().
- *
- * @param sess	    The STUN session instance.
- * @param p_tdata   Pointer to receive STUN transmit data instance containing
- *		    the request.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) 
-pj_stun_session_create_set_active_destination_req(pj_stun_session *sess,
-						  pj_stun_tx_data **p_tdata);
-
-/**
- * Create a STUN Connect request message. After the message has been 
- * successfully created, application can send the message by calling 
- * pj_stun_session_send_msg().
- *
- * @param sess	    The STUN session instance.
- * @param p_tdata   Pointer to receive STUN transmit data instance containing
- *		    the request.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_create_connect_req(pj_stun_session *sess,
-							pj_stun_tx_data **p_tdata);
-
-/**
- * Create a STUN Connection Status Indication message. After the message 
- * has been successfully created, application can send the message by calling
- * pj_stun_session_send_msg().
- *
- * @param sess	    The STUN session instance.
- * @param p_tdata   Pointer to receive STUN transmit data instance containing
- *		    the message.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t)
-pj_stun_session_create_connection_status_ind(pj_stun_session *sess,
-					     pj_stun_tx_data **p_tdata);
-
-/**
- * Create a STUN Send Indication message. After the message has been 
- * successfully created, application can send the message by calling 
- * pj_stun_session_send_msg().
- *
- * @param sess	    The STUN session instance.
- * @param p_tdata   Pointer to receive STUN transmit data instance containing
- *		    the message.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_create_send_ind(pj_stun_session *sess,
-						     pj_stun_tx_data **p_tdata);
-
-/**
- * Create a STUN Data Indication message. After the message has been 
- * successfully created, application can send the message by calling 
- * pj_stun_session_send_msg().
- *
- * @param sess	    The STUN session instance.
- * @param p_tdata   Pointer to receive STUN transmit data instance containing
- *		    the message.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_create_data_ind(pj_stun_session *sess,
-						     pj_stun_tx_data **p_tdata);
-
-/**
- * Send STUN message to the specified destination. This function will encode
- * the pj_stun_msg instance to a packet buffer, and add credential or
- * fingerprint if necessary. If the message is a request, the session will
- * also create and manage a STUN client transaction to be used to manage the
- * retransmission of the request. After the message has been encoded and
- * transaction is setup, the \a on_send_msg() callback of pj_stun_session_cb
- * (which is registered when the STUN session is created) will be called
- * to actually send the message to the wire.
- *
- * @param sess	    The STUN session instance.
- * @param options   Optional flags, from pj_stun_session_option.
- * @param addr_len  Length of destination address.
- * @param dst_addr  The destination socket address.
- * @param tdata	    The STUN transmit data containing the STUN message to
- *		    be sent.
- *
- * @return	    PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess,
-					      unsigned options,
-					      unsigned addr_len,
-					      const pj_sockaddr_t *dst_addr,
-					      pj_stun_tx_data *tdata);
-
-/**
- * Application must call this function to notify the STUN session about
- * the arrival of STUN packet. The STUN packet MUST have been checked
- * first with #pj_stun_msg_check() to verify that this is indeed a valid
- * STUN packet.
- *
- * The STUN session will decode the packet into pj_stun_msg, and process
- * the message accordingly. If the message is a response, it will search
- * through the outstanding STUN client transactions for a matching
- * transaction ID and hand over the response to the transaction.
- *
- * On successful message processing, application will be notified about
- * the message via one of the pj_stun_session_cb callback.
- *
- * @param sess	     The STUN session instance.
- * @param packet     The packet containing STUN message.
- * @param pkt_size   Size of the packet.
- * @param parsed_len Optional pointer to receive the size of the parsed
- *		     STUN message (useful if packet is received via a
- *		     stream oriented protocol).
- *
- * @return	     PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
-					       const void *packet,
-					       pj_size_t pkt_size,
-					       unsigned *parsed_len);
-
-
-
-#endif	/* __PJLIB_UTIL_STUN_SESSION_H__ */
-
