Index: /pjproject/trunk/pjnath/include/pjnath/stun_msg.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/stun_msg.h	(revision 2043)
+++ /pjproject/trunk/pjnath/include/pjnath/stun_msg.h	(revision 2044)
@@ -1226,4 +1226,22 @@
 
 /**
+ * Initialize a generic STUN message.
+ *
+ * @param msg		The message structure to be initialized.
+ * @param msg_type	The 14bit message type (see pj_stun_msg_type 
+ *			constants).
+ * @param magic		Magic value to be put to the mesage; for requests,
+ *			the value normally should be PJ_STUN_MAGIC.
+ * @param tsx_id	Optional transaction ID, or NULL to let the
+ *			function generates a random transaction ID.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_init(pj_stun_msg *msg,
+				      unsigned msg_type,
+				      pj_uint32_t magic,
+				      const pj_uint8_t tsx_id[12]);
+
+/**
  * Create a generic STUN message.
  *
@@ -1436,4 +1454,24 @@
 
 /**
+ * Initialize generic STUN IP address attribute. The \a addr_len and
+ * \a addr parameters specify whether the address is IPv4 or IPv4
+ * address.
+ *
+ * @param attr		The socket address attribute to initialize.
+ * @param attr_type	Attribute type, from #pj_stun_attr_type.
+ * @param xor_ed	If non-zero, the port and address will be XOR-ed
+ *			with magic, to make the XOR-MAPPED-ADDRESS attribute.
+ * @param addr		A pj_sockaddr_in or pj_sockaddr_in6 structure.
+ * @param addr_len	Length of \a addr parameter.
+ *
+ * @return		PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_sockaddr_attr_init(pj_stun_sockaddr_attr *attr,
+						int attr_type, 
+						pj_bool_t xor_ed,
+						const pj_sockaddr_t *addr,
+						unsigned addr_len);
+
+/**
  * Create a generic STUN IP address attribute. The \a addr_len and
  * \a addr parameters specify whether the address is IPv4 or IPv4
@@ -1481,4 +1519,20 @@
 
 /**
+ * Initialize a STUN generic string attribute.
+ *
+ * @param attr		The string attribute to be initialized.
+ * @param pool		Pool to duplicate the value into the attribute,
+ *			if value is not NULL or empty.
+ * @param attr_type	Attribute type, from #pj_stun_attr_type.
+ * @param value		The string value to be assigned to the attribute.
+ *
+ * @return		PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_string_attr_init(pj_stun_string_attr *attr,
+					      pj_pool_t *pool,
+					      int attr_type,
+					      const pj_str_t *value);
+
+/**
  * Create a STUN generic string attribute.
  *
@@ -1657,4 +1711,23 @@
 						  unsigned attr_cnt,
 						  const pj_uint16_t attr[]);
+
+/**
+ * Initialize STUN binary attribute.
+ *
+ * @param attr		The attribute to be initialized.
+ * @param pool		Pool to copy data, if the data and length are set.
+ * @param attr_type	The attribute type, from #pj_stun_attr_type.
+ * @param data		Data to be coped to the attribute, or NULL
+ *			if no data to be copied now.
+ * @param length	Length of data, or zero if no data is to be
+ *			copied now.
+ *
+ * @return		PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_binary_attr_init(pj_stun_binary_attr *attr,
+					      pj_pool_t *pool,
+					      int attr_type,
+					      const pj_uint8_t *data,
+					      unsigned length);
 
 /**
Index: /pjproject/trunk/pjnath/src/pjnath/stun_msg.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/stun_msg.c	(revision 2043)
+++ /pjproject/trunk/pjnath/src/pjnath/stun_msg.c	(revision 2044)
@@ -713,4 +713,26 @@
 
 /*
+ * Init sockaddr attr
+ */
+PJ_DEF(pj_status_t) pj_stun_sockaddr_attr_init( pj_stun_sockaddr_attr *attr,
+						int attr_type, 
+						pj_bool_t xor_ed,
+						const pj_sockaddr_t *addr,
+						unsigned addr_len)
+{
+    PJ_ASSERT_RETURN(attr && addr_len && addr, PJ_EINVAL);
+    PJ_ASSERT_RETURN(addr_len == sizeof(pj_sockaddr_in) ||
+		     addr_len == sizeof(pj_sockaddr_in6), PJ_EINVAL);
+
+    INIT_ATTR(attr, attr_type, STUN_GENERIC_IP_ADDR_LEN);
+
+    pj_memcpy(&attr->sockaddr, addr, addr_len);
+    attr->xor_ed = xor_ed;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
  * Create a generic STUN IP address attribute for IPv4 address.
  */
@@ -724,17 +746,9 @@
     pj_stun_sockaddr_attr *attr;
 
-    PJ_ASSERT_RETURN(pool && addr_len && addr && p_attr, PJ_EINVAL);
-    PJ_ASSERT_RETURN(addr_len == sizeof(pj_sockaddr_in) ||
-		     addr_len == sizeof(pj_sockaddr_in6), PJ_EINVAL);
-
+    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL);
     attr = PJ_POOL_ZALLOC_T(pool, pj_stun_sockaddr_attr);
-    INIT_ATTR(attr, attr_type, STUN_GENERIC_IP_ADDR_LEN);
-
-    pj_memcpy(&attr->sockaddr, addr, addr_len);
-    attr->xor_ed = xor_ed;
-
     *p_attr = attr;
-
-    return PJ_SUCCESS;
+    return pj_stun_sockaddr_attr_init(attr, attr_type, xor_ed, 
+				      addr, addr_len);
 }
 
@@ -898,4 +912,21 @@
 
 /*
+ * Initialize a STUN generic string attribute.
+ */
+PJ_DEF(pj_status_t) pj_stun_string_attr_init( pj_stun_string_attr *attr,
+					      pj_pool_t *pool,
+					      int attr_type,
+					      const pj_str_t *value)
+{
+    INIT_ATTR(attr, attr_type, value->slen);
+    if (value && value->slen)
+	pj_strdup(pool, &attr->value, value);
+    else
+	attr->value.slen = 0;
+    return PJ_SUCCESS;
+}
+
+
+/*
  * Create a STUN generic string attribute.
  */
@@ -910,10 +941,7 @@
 
     attr = PJ_POOL_ZALLOC_T(pool, pj_stun_string_attr);
-    INIT_ATTR(attr, attr_type, value->slen);
-    pj_strdup(pool, &attr->value, value);
-
     *p_attr = attr;
 
-    return PJ_SUCCESS;
+    return pj_stun_string_attr_init(attr, pool, attr_type, value);
 }
 
@@ -1642,4 +1670,32 @@
 
 /*
+ * Initialize STUN binary attribute.
+ */
+PJ_DEF(pj_status_t) pj_stun_binary_attr_init( pj_stun_binary_attr *attr,
+					      pj_pool_t *pool,
+					      int attr_type,
+					      const pj_uint8_t *data,
+					      unsigned length)
+{
+    PJ_ASSERT_RETURN(attr_type, PJ_EINVAL);
+
+    INIT_ATTR(attr, attr_type, length);
+
+    attr->magic = PJ_STUN_MAGIC;
+
+    if (data && length) {
+	attr->length = length;
+	attr->data = (pj_uint8_t*) pj_pool_alloc(pool, length);
+	pj_memcpy(attr->data, data, length);
+    } else {
+	attr->data = NULL;
+	attr->length = 0;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
  * Create a blank binary attribute.
  */
@@ -1653,19 +1709,7 @@
 
     PJ_ASSERT_RETURN(pool && attr_type && p_attr, PJ_EINVAL);
-
     attr = PJ_POOL_ZALLOC_T(pool, pj_stun_binary_attr);
-    INIT_ATTR(attr, attr_type, length);
-
-    attr->magic = PJ_STUN_MAGIC;
-
-    if (data && length) {
-	attr->length = length;
-	attr->data = (pj_uint8_t*) pj_pool_alloc(pool, length);
-	pj_memcpy(attr->data, data, length);
-    }
-
     *p_attr = attr;
-
-    return PJ_SUCCESS;
+    return pj_stun_binary_attr_init(attr, pool, attr_type, data, length);
 }
 
@@ -1754,19 +1798,17 @@
 
 /*
- * Create a blank STUN message.
- */
-PJ_DEF(pj_status_t) pj_stun_msg_create( pj_pool_t *pool,
-					unsigned msg_type,
-					pj_uint32_t magic,
-					const pj_uint8_t tsx_id[12],
-					pj_stun_msg **p_msg)
-{
-    pj_stun_msg *msg;
-
-    PJ_ASSERT_RETURN(pool && msg_type && p_msg, PJ_EINVAL);
-
-    msg = PJ_POOL_ZALLOC_T(pool, pj_stun_msg);
+ * Initialize a generic STUN message.
+ */
+PJ_DEF(pj_status_t) pj_stun_msg_init( pj_stun_msg *msg,
+				      unsigned msg_type,
+				      pj_uint32_t magic,
+				      const pj_uint8_t tsx_id[12])
+{
+    PJ_ASSERT_RETURN(msg && msg_type, PJ_EINVAL);
+
     msg->hdr.type = (pj_uint16_t) msg_type;
+    msg->hdr.length = 0;
     msg->hdr.magic = magic;
+    msg->attr_count = 0;
 
     if (tsx_id) {
@@ -1781,4 +1823,7 @@
 	static pj_uint32_t pj_stun_tsx_id_counter;
 
+	if (!pj_stun_tsx_id_counter)
+	    pj_stun_tsx_id_counter = pj_rand();
+
 	id.proc_id = pj_getpid();
 	id.random = pj_rand();
@@ -1788,7 +1833,24 @@
     }
 
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Create a blank STUN message.
+ */
+PJ_DEF(pj_status_t) pj_stun_msg_create( pj_pool_t *pool,
+					unsigned msg_type,
+					pj_uint32_t magic,
+					const pj_uint8_t tsx_id[12],
+					pj_stun_msg **p_msg)
+{
+    pj_stun_msg *msg;
+
+    PJ_ASSERT_RETURN(pool && msg_type && p_msg, PJ_EINVAL);
+
+    msg = PJ_POOL_ZALLOC_T(pool, pj_stun_msg);
     *p_msg = msg;
-
-    return PJ_SUCCESS;
+    return pj_stun_msg_init(msg, msg_type, magic, tsx_id);
 }
 
