Index: pjproject/trunk/pjlib/src/pj/ip_helper_win32.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/ip_helper_win32.c	(revision 1109)
+++ pjproject/trunk/pjlib/src/pj/ip_helper_win32.c	(revision 1110)
@@ -63,9 +63,12 @@
     /* Now fill out the entries */
     count = (pTab->dwNumEntries < *p_cnt) ? pTab->dwNumEntries : *p_cnt;
+    *p_cnt = 0;
     for (i=0; i<count; ++i) {
-	ifs[i].s_addr = pTab->table[i].dwAddr;
+	/* Some Windows returns 0.0.0.0! */
+	if (pTab->table[i].dwAddr == 0)
+	    continue;
+	ifs[*p_cnt].s_addr = pTab->table[i].dwAddr;
+	(*p_cnt)++;
     }
-
-    *p_cnt = count;
 
     return PJ_SUCCESS;
Index: pjproject/trunk/pjnath/build/pjnath.dsp
===================================================================
--- pjproject/trunk/pjnath/build/pjnath.dsp	(revision 1109)
+++ pjproject/trunk/pjnath/build/pjnath.dsp	(revision 1110)
@@ -43,5 +43,5 @@
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
 # ADD CPP /nologo /MD /W4 /GX /O1 /Ob2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
-# SUBTRACT CPP /Z<none> /YX
+# SUBTRACT CPP /YX
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
 # ADD RSC /l 0x409 /d "NDEBUG"
@@ -152,8 +152,4 @@
 # Begin Source File
 
-SOURCE=..\include\pjnath\stun_doc.h
-# End Source File
-# Begin Source File
-
 SOURCE=..\include\pjnath\stun_msg.h
 # End Source File
@@ -168,8 +164,4 @@
 # Begin Source File
 
-SOURCE=..\include\pjnath\turn_client.h
-# End Source File
-# Begin Source File
-
 SOURCE=..\include\pjnath\types.h
 # End Source File
Index: pjproject/trunk/pjnath/docs/doxygen.cfg
===================================================================
--- pjproject/trunk/pjnath/docs/doxygen.cfg	(revision 1110)
+++ pjproject/trunk/pjnath/docs/doxygen.cfg	(revision 1110)
@@ -0,0 +1,1047 @@
+# Doxyfile 1.3-rc3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           =  "PJNATH Reference"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = docs
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, 
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en 
+# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, 
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these class will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = NO
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited 
+# members of a class in the documentation of that class as if those members were 
+# ordinary class members. Constructors, destructors and assignment operators of 
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        = "c:\project\pjproject"
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower case letters. If set to YES upper case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments  will behave just like the Qt-style comments (thus requiring an 
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# reimplements.
+
+INHERIT_DOCS           = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consist of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
+# only. Doxygen will then generate output that is more tailored for C. 
+# For instance some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  =  include/pjnath
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
+# *.h++ *.idl *.odl
+
+FILE_PATTERNS          = *.h *.c
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = "*_i.h" "*/compat/*"
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = .
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .htm
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = docs/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = docs/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet
+
+HTML_STYLESHEET        = docs/doxygen.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output dir.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non empty doxygen will try to run 
+# the html help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the Html help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 1
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimised for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assigments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_XML           = NO
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed.
+
+PREDEFINED             = PJ_DECL(x)=x PJ_DEF(x)=x PJ_IDECL(x)=x \
+			 PJ_IDEF(x)=x PJ_INLINE(x)=x \
+			 PJ_DECL_NO_RETURN(x)=x \
+			 PJ_HAS_HIGH_RES_TIMER=1 \
+			 PJ_LOG_MAX_LEVEL=4 \
+			 PJ_HAS_SEMAPHORE=1 \
+			 PJ_HAS_EVENT_OBJ=1
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or 
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yield more powerful graphs.
+
+CLASS_DIAGRAMS         = NO
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermedate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
+
+# The CGI_NAME tag should be the name of the CGI script that 
+# starts the search engine (doxysearch) with the correct parameters. 
+# A script with this name will be generated by doxygen.
+
+#CGI_NAME               = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the 
+# cgi binaries are located. See the documentation of your http daemon for 
+# details.
+
+#CGI_URL                = 
+
+# The DOC_URL tag should be the absolute URL to the directory where the 
+# documentation is located. If left blank the absolute path to the 
+# documentation, with file:// prepended to it, will be used.
+
+#DOC_URL                = 
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the 
+# documentation is located. If left blank the directory on the local machine 
+# will be used.
+
+#DOC_ABSPATH            = 
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary 
+# is installed.
+
+#BIN_ABSPATH            = /usr/local/bin/
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to 
+# documentation generated for other projects. This allows doxysearch to search 
+# the documentation for these projects as well.
+
+#EXT_DOC_PATHS          = 
Index: pjproject/trunk/pjnath/docs/doxygen.css
===================================================================
--- pjproject/trunk/pjnath/docs/doxygen.css	(revision 1110)
+++ pjproject/trunk/pjnath/docs/doxygen.css	(revision 1110)
@@ -0,0 +1,305 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+BODY,TD {
+       font-size: 80%;
+}
+CODE {
+	font-size: 120%;
+       font-family: monospace;
+}
+.fragment, pre {
+	font-size: 110%;
+       font-family: monospace;
+}
+H1 {
+	text-align: center;
+       font-size: 240%;
+}
+H2 {
+       	font-size: 200%;
+	margin-top     : 60px;
+}
+H3 {
+       font-size: 160%;
+}
+H4 {
+       font-size: 120%;
+}
+CAPTION { font-weight: bold }
+DIV.qindex {
+	width: 100%;
+	background-color: #eeeeff;
+	border: 1px solid #b0b0b0;
+	text-align: center;
+	margin: 2px;
+	padding: 2px;
+	line-height: 140%;
+}
+DIV.nav {
+	width: 100%;
+	background-color: #eeeeff;
+	border: 1px solid #b0b0b0;
+	text-align: center;
+	margin: 2px;
+	padding: 2px;
+	line-height: 140%;
+}
+A.qindex {
+       text-decoration: none;
+       font-size: 120%;
+       color: #1A419D;
+}
+A.qindex:visited {
+       text-decoration: none;
+       color: #1A419D
+}
+A.qindex:hover {
+	text-decoration: none;
+	background-color: #ddddff;
+}
+A.qindexHL {
+	text-decoration: none;
+	font-weight: bold;
+	background-color: #6666cc;
+	color: #ffffff;
+	border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+	text-decoration: none;
+	background-color: #6666cc;
+	color: #ffffff;
+}
+A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A.elRef { font-weight: bold }
+A.code:link { text-decoration: none; font-weight: normal; color: #0000FF; }
+A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
+A.codeRef:link { font-weight: normal; color: #0000FF}
+A.codeRef:visited { font-weight: normal; color: #0000FF}
+A:hover { text-decoration: none; background-color: #f2f2ff }
+DL.el { margin-left: -1cm }
+PRE.fragment {
+	border: 1px solid #CCCCCC;
+	background-color: #f5f5f5;
+	margin-top: 4px;
+	margin-bottom: 4px;
+	margin-left: 2px;
+	margin-right: 8px;
+	padding-left: 6px;
+	padding-right: 6px;
+	padding-top: 4px;
+	padding-bottom: 4px;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+TD.md { background-color: #F4F4FB; font-weight: bold; }
+TD.mdPrefix {
+       background-color: #F4F4FB;
+       color: #606060;
+	font-size: 80%;
+}
+TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }
+TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }
+DIV.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       margin-bottom: 6px;
+       font-weight: bold;
+}
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
+BODY {
+	background: white;
+	color: black;
+	margin-right: 20px;
+	margin-left: 20px;
+}
+TD.indexkey {
+	background-color: #eeeeff;
+	font-weight: bold;
+	padding-right  : 10px;
+	padding-top    : 2px;
+	padding-left   : 10px;
+	padding-bottom : 2px;
+	margin-left    : 0px;
+	margin-right   : 0px;
+	margin-top     : 2px;
+	margin-bottom  : 2px;
+	border: 1px solid #CCCCCC;
+}
+TD.indexvalue {
+	background-color: #eeeeff;
+	font-style: italic;
+	padding-right  : 10px;
+	padding-top    : 2px;
+	padding-left   : 10px;
+	padding-bottom : 2px;
+	margin-left    : 0px;
+	margin-right   : 0px;
+	margin-top     : 2px;
+	margin-bottom  : 2px;
+	border: 1px solid #CCCCCC;
+}
+TR.memlist {
+   background-color: #f0f0f0; 
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword       { color: #008000 }
+SPAN.keywordtype   { color: #604020 }
+SPAN.keywordflow   { color: #e08000 }
+SPAN.comment       { color: #800000 }
+SPAN.preprocessor  { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral   { color: #008080 }
+.mdTable {
+	border: 1px solid #868686;
+	background-color: #F4F4FB;
+}
+.mdRow {
+	padding: 8px 10px;
+}
+.mdescLeft {
+       padding: 0px 8px 4px 8px;
+	font-size: 80%;
+	font-style: italic;
+	background-color: #FAFAFA;
+	border-top: 1px none #E0E0E0;
+	border-right: 1px none #E0E0E0;
+	border-bottom: 1px none #E0E0E0;
+	border-left: 1px none #E0E0E0;
+	margin: 0px;
+}
+.mdescRight {
+       padding: 0px 8px 4px 8px;
+	font-size: 80%;
+	font-style: italic;
+	background-color: #FAFAFA;
+	border-top: 1px none #E0E0E0;
+	border-right: 1px none #E0E0E0;
+	border-bottom: 1px none #E0E0E0;
+	border-left: 1px none #E0E0E0;
+	margin: 0px;
+}
+.memItemLeft {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memItemRight {
+	padding: 1px 8px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplItemLeft {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: none;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplItemRight {
+	padding: 1px 8px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: none;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplParams {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+       color: #606060;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.search     { color: #003399;
+              font-weight: bold;
+}
+FORM.search {
+              margin-bottom: 0px;
+              margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+               color: #000080;
+               font-weight: normal;
+               background-color: #eeeeff;
+}
+TD.tiny      { font-size: 75%;
+}
+a {
+	color: #252E78;
+}
+a:visited {
+	color: #3D2185;
+}
+.dirtab { padding: 4px;
+          border-collapse: collapse;
+          border: 1px solid #b0b0b0;
+}
+TH.dirtab { background: #eeeeff;
+            font-weight: bold;
+}
+HR { height: 1px;
+     border: none;
+     border-top: 1px solid black;
+}
Index: pjproject/trunk/pjnath/docs/footer.html
===================================================================
--- pjproject/trunk/pjnath/docs/footer.html	(revision 1110)
+++ pjproject/trunk/pjnath/docs/footer.html	(revision 1110)
@@ -0,0 +1,11 @@
+<p>&nbsp;</p>
+<hr><center>
+PJNATH - Open Source NAT traversal helper library supporting STUN, TURN, and ICE<br>
+(C)2001-2007 Benny Prijono
+</center>
+
+
+<!--#include virtual="/footer.html" -->
+
+</BODY>
+</HTML>
Index: pjproject/trunk/pjnath/docs/header.html
===================================================================
--- pjproject/trunk/pjnath/docs/header.html	(revision 1110)
+++ pjproject/trunk/pjnath/docs/header.html	(revision 1110)
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>$title</title>
+<link href="/style/style.css" rel="stylesheet" type="text/css">
+</head><body>
+	<!--#include virtual="/header.html" -->
+	<p><A HREF="/">Home</A> --&gt; <A HREF="/docs.htm">Documentations</A> --&gt; <A HREF="/pjnath/docs/html/index.htm">PJNATH Reference</A></p>
+
+
Index: pjproject/trunk/pjnath/include/pjnath/config.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/config.h	(revision 1109)
+++ pjproject/trunk/pjnath/include/pjnath/config.h	(revision 1110)
@@ -28,5 +28,5 @@
 /**
  * @defgroup PJNATH_CONFIG Configuration
- * @ingroup PJNATH
+ * @brief Various compile time settings
  * @{
  */
@@ -35,15 +35,4 @@
  * STUN CLIENT CONFIGURATION
  */
-
-/**
- * Maximum number of attributes in the STUN packet (for the old STUN
- * library).
- *
- * Default: 16
- */
-#ifndef PJSTUN_MAX_ATTR
-#   define PJSTUN_MAX_ATTR			    16
-#endif
-
 
 /**
@@ -57,4 +46,108 @@
 #endif
 
+/**
+ * The default initial STUN round-trip time estimation (the RTO value
+ * in RFC 3489-bis), in miliseconds. 
+ * This value is used to control the STUN request 
+ * retransmit time. The initial value of retransmission interval 
+ * would be set to this value, and will be doubled after each
+ * retransmission.
+ */
+#ifndef PJ_STUN_RTO_VALUE
+#   define PJ_STUN_RTO_VALUE			    100
+#endif
+
+
+/**
+ * The STUN transaction timeout value, in miliseconds.
+ * After the last retransmission is sent and if no response is received 
+ * after this time, the STUN transaction will be considered to have failed.
+ *
+ * The default value is 1600 miliseconds (as per RFC 3489-bis).
+ */
+#ifndef PJ_STUN_TIMEOUT_VALUE
+#   define PJ_STUN_TIMEOUT_VALUE		    1600
+#endif
+
+
+/**
+ * Maximum number of STUN retransmission count.
+ *
+ * Default: 7 (as per RFC 3489-bis)
+ */
+#ifndef PJ_STUN_MAX_RETRANSMIT_COUNT
+#   define PJ_STUN_MAX_RETRANSMIT_COUNT		    7
+#endif
+
+
+/**
+ * Maximum size of STUN message.
+ */
+#ifndef PJ_STUN_MAX_PKT_LEN
+#   define PJ_STUN_MAX_PKT_LEN			    512
+#endif
+
+
+/**
+ * Default STUN port as defined by RFC 3489.
+ */
+#define PJ_STUN_PORT				    3478
+
+
+
+/* **************************************************************************
+ * ICE CONFIGURATION
+ */
+
+/**
+ * Maximum number of ICE candidates.
+ *
+ * Default: 16
+ */
+#ifndef PJ_ICE_MAX_CAND
+#   define PJ_ICE_MAX_CAND			    16
+#endif
+
+
+/**
+ * Maximum number of candidates for each ICE stream transport component.
+ *
+ * Default: 8
+ */
+#ifndef PJ_ICE_ST_MAX_CAND
+#   define PJ_ICE_ST_MAX_CAND			    8
+#endif
+
+
+/**
+ * Maximum number of ICE components.
+ *
+ * Default: 8
+ */
+#ifndef PJ_ICE_MAX_COMP
+#   define PJ_ICE_MAX_COMP			    8
+#endif
+
+
+/**
+ * Maximum number of ICE checks.
+ *
+ * Default: 32
+ */
+#ifndef PJ_ICE_MAX_CHECKS
+#   define PJ_ICE_MAX_CHECKS			    32
+#endif
+
+
+/**
+ * Default timer interval (in miliseconds) for starting ICE periodic checks.
+ *
+ * Default: 20
+ */
+#ifndef PJ_ICE_TA_VAL
+#   define PJ_ICE_TA_VAL			    20
+#endif
+
+
 
 /**
Index: pjproject/trunk/pjnath/include/pjnath/errno.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/errno.h	(revision 1109)
+++ pjproject/trunk/pjnath/include/pjnath/errno.h	(revision 1110)
@@ -20,4 +20,8 @@
 #define __PJNATH_ERRNO_H__
 
+/**
+ * @file errno.h
+ * @brief PJNATH specific error codes
+ */
 
 #include <pj/errno.h>
@@ -25,5 +29,5 @@
 /**
  * @defgroup PJNATH_ERROR NAT Helper Library Error Codes
- * @ingroup PJNATH
+ * @brief PJNATH specific error code constants
  * @{
  */
Index: pjproject/trunk/pjnath/include/pjnath/ice.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/ice.h	(revision 1109)
+++ pjproject/trunk/pjnath/include/pjnath/ice.h	(revision 1110)
@@ -22,5 +22,5 @@
 /**
  * @file ice.h
- * @brief ICE.
+ * @brief ICE session management
  */
 #include <pjnath/types.h>
@@ -32,5 +32,4 @@
  * @defgroup PJNATH_ICE Interactive Connectivity Establishment (ICE)
  * @brief Interactive Connectivity Establishment (ICE)
- * @ingroup PJNATH
  */
 
@@ -40,8 +39,28 @@
 
 /**
- * @defgroup PJNATH_ICE_STREAM Transport Independent ICE Media Stream
- * @brief Transport Independent ICE Media Stream
+ * @defgroup PJNATH_ICE_SESSION ICE Session
+ * @brief Transport Independent ICE Session
  * @ingroup PJNATH_ICE
  * @{
+ *
+ * This module describes #pj_ice, a transport independent ICE session,
+ * part of PJNATH - the Open Source NAT helper library.
+ *
+ * An ICE session, represented by #pj_ice structure, is the lowest 
+ * abstraction of ICE in PJNATH, and it is used to perform and manage
+ * connectivity checks of transport address candidates <b>within a
+ * single media stream</b> (note: this differs from what is described
+ * in ICE draft, where an ICE session manages the whole media sessions
+ * rather than just a single stream).
+ *
+ * The ICE session described here is independent from any transports,
+ * meaning that the actual network I/O for this session would have to
+ * be performed by the application, or higher layer abstraction. 
+ * Using this framework, application would give any incoming packets to
+ * the ICE session, and it would provide the ICE session with a callback
+ * to send outgoing message.
+ *
+ * For higher abstraction of ICE where transport is included, please 
+ * see \ref PJNATH_ICE_STREAM_TRANSPORT.
  */
 
@@ -51,35 +70,46 @@
 typedef enum pj_ice_cand_type
 {
-    PJ_ICE_CAND_TYPE_HOST,
-    PJ_ICE_CAND_TYPE_SRFLX,
-    PJ_ICE_CAND_TYPE_PRFLX,
-    PJ_ICE_CAND_TYPE_RELAYED
+    PJ_ICE_CAND_TYPE_HOST,	/**< ICE host candidate.		*/
+    PJ_ICE_CAND_TYPE_SRFLX,	/**< ICE server reflexive candidate.	*/
+    PJ_ICE_CAND_TYPE_PRFLX,	/**< ICE peer reflexive candidate.	*/
+    PJ_ICE_CAND_TYPE_RELAYED	/**< ICE relayed candidate.		*/
 } pj_ice_cand_type;
 
-/**
- *
+
+/**
+ * This enumeration describes the default preference for the ICE
+ * candidate types as described by ICE standard.
  */
 enum pj_ice_type_pref
 {
-    PJ_ICE_HOST_PREF	    = 126,
-    PJ_ICE_SRFLX_PREF	    = 100,
-    PJ_ICE_PRFLX_PREF	    = 110,
-    PJ_ICE_RELAYED_PREF	    = 0
+    PJ_ICE_HOST_PREF	    = 126,  /**< Preference value for host.	*/
+    PJ_ICE_SRFLX_PREF	    = 100,  /**< Preference value for SRFLX.	*/
+    PJ_ICE_PRFLX_PREF	    = 110,  /**< Preference value for PRFLX	*/
+    PJ_ICE_RELAYED_PREF	    = 0	    /**< Preference value for relay	*/
 };
 
+/** Forward declaration for pj_ice */
 typedef struct pj_ice pj_ice;
+
+/** Forward declaration for pj_ice_check */
 typedef struct pj_ice_check pj_ice_check;
 
-#define PJ_ICE_MAX_CAND	    16
-#define PJ_ICE_MAX_COMP	    8
-#define PJ_ICE_MAX_CHECKS   32
-#define PJ_ICE_TA_VAL	    20
-
-/**
- * ICE component
+
+/**
+ * This structure describes ICE component. 
+ * A media stream may require multiple components, each of which has 
+ * to work for the media stream as a whole to work.  For media streams
+ * based on RTP, there are two components per media stream - one for RTP,
+ * and one for RTCP.
  */
 typedef struct pj_ice_comp
 {
+    /**
+     * The pointer to ICE check which was nominated for this component.
+     * The value will be NULL if a nominated check has not been found
+     * for this component.
+     */
     pj_ice_check	*valid_check;
+
 } pj_ice_comp;
 
@@ -87,62 +117,251 @@
 /**
  * This structure describes an ICE candidate.
+ * ICE candidate is a transport address that is to be tested by ICE
+ * procedures in order to determine its suitability for usage for
+ * receipt of media.  Candidates also have properties - their type
+ * (server reflexive, relayed or host), priority, foundation, and
+ * base.
  */
 typedef struct pj_ice_cand
 {
+    /**
+     * The component ID of this candidate. Note that component IDs starts
+     * with one for RTP and two for RTCP. In other words, it's not zero
+     * based.
+     */
     pj_uint32_t		 comp_id;
+
+    /**
+     * The candidate type, as described in #pj_ice_cand_type enumeration.
+     */
     pj_ice_cand_type	 type;
+
+    /**
+     * The foundation string, which is an identifier which value will be
+     * equivalent for two candidates that are of the same type, share the 
+     * same base, and come from the same STUN server. The foundation is 
+     * used to optimize ICE performance in the Frozen algorithm.
+     */
     pj_str_t		 foundation;
+
+    /**
+     * The candidate's priority, a 32-bit unsigned value which value will be
+     * calculated by the ICE session when a candidate is registered to the
+     * ICE session.
+     */
     pj_uint32_t		 prio;
+
+    /**
+     * IP address of this candidate. For host candidates, this represents
+     * the local address of the socket. For reflexive candidates, the value
+     * will be the public address allocated in NAT router for the host
+     * candidate and as reported in MAPPED-ADDRESS or XOR-MAPPED-ADDRESS
+     * attribute of STUN Binding request. For relayed candidate, the value 
+     * will be the address allocated in the TURN server by STUN Allocate
+     * request.
+     */
     pj_sockaddr		 addr;
+
+    /**
+     * Base address of this candidate. "Base" refers to the address an agent 
+     * sends from for a particular candidate.  For host candidates, the base
+     * is the same as the host candidate itself. For reflexive candidates, 
+     * the base is the local IP address of the socket. For relayed candidates,
+     * the base address is the transport address allocated in the TURN server
+     * for this candidate.
+     */
     pj_sockaddr		 base_addr;
+
+    /**
+     * Related address, which is used for informational only and is not used
+     * in any way by the ICE session.
+     */
     pj_sockaddr		 rel_addr;
+
+    /**
+     * The STUN session to be used to send and receive STUN messages for this
+     * candidate.
+     */
     pj_stun_session	*stun_sess;
+
 } pj_ice_cand;
 
+
+/**
+ * This enumeration describes the state of ICE check.
+ */
 typedef enum pj_ice_check_state
 {
+    /**
+     * A check for this pair hasn't been performed, and it can't
+     * yet be performed until some other check succeeds, allowing this
+     * pair to unfreeze and move into the Waiting state.
+     */
     PJ_ICE_CHECK_STATE_FROZEN,
+
+    /**
+     * A check has not been performed for this pair, and can be
+     * performed as soon as it is the highest priority Waiting pair on
+     * the check list.
+     */
     PJ_ICE_CHECK_STATE_WAITING,
+
+    /**
+     * A check has not been performed for this pair, and can be
+     * performed as soon as it is the highest priority Waiting pair on
+     * the check list.
+     */
     PJ_ICE_CHECK_STATE_IN_PROGRESS,
+
+    /**
+     * A check has not been performed for this pair, and can be
+     * performed as soon as it is the highest priority Waiting pair on
+     * the check list.
+     */
     PJ_ICE_CHECK_STATE_SUCCEEDED,
+
+    /**
+     * A check for this pair was already done and failed, either
+     * never producing any response or producing an unrecoverable failure
+     * response.
+     */
     PJ_ICE_CHECK_STATE_FAILED
+
 } pj_ice_check_state;
 
 
+/**
+ * This structure describes an ICE connectivity check. An ICE check
+ * contains a candidate pair, and will involve sending STUN Binding 
+ * Request transaction for the purposes of verifying connectivity. 
+ * A check is sent from the local candidate to the remote candidate 
+ * of a candidate pair.
+ */
 struct pj_ice_check
 {
+    /**
+     * Pointer to local candidate entry of this check.
+     */
     pj_ice_cand		*lcand;
+
+    /**
+     * Pointer to remote candidate entry of this check.
+     */
     pj_ice_cand		*rcand;
 
+    /**
+     * Check priority.
+     */
     pj_uint64_t		 prio;
+
+    /**
+     * Connectivity check state.
+     */
     pj_ice_check_state	 state;
+
+    /**
+     * STUN transmit data containing STUN Binding request that was sent 
+     * as part of this check. The value will only be set when this check 
+     * has a pending transaction, and is used to cancel the transaction
+     * when other check has succeeded.
+     */
     pj_stun_tx_data	*tdata;
+
+    /**
+     * Flag to indicate whether this check is nominated. A nominated check
+     * contains USE-CANDIDATE attribute in its STUN Binding request.
+     */
     pj_bool_t		 nominated;
+
+    /**
+     * When the check failed, this will contain the failure status of the
+     * STUN transaction.
+     */
     pj_status_t		 err_code;
 };
 
 
+/**
+ * This enumeration describes ICE checklist state.
+ */
 typedef enum pj_ice_checklist_state
 {
+    /**
+     * The checklist is not yet running.
+     */
     PJ_ICE_CHECKLIST_ST_IDLE,
+
+    /**
+     * In this state, ICE checks are still in progress for this
+     * media stream.
+     */
     PJ_ICE_CHECKLIST_ST_RUNNING,
+
+    /**
+     * In this state, ICE checks have completed for this media stream,
+     * either successfully or with failure.
+     */
     PJ_ICE_CHECKLIST_ST_COMPLETED
+
 } pj_ice_checklist_state;
 
+
+/**
+ * This structure represents ICE check list, that is an ordered set of 
+ * candidate pairs that an agent will use to generate checks.
+ */
 typedef struct pj_ice_checklist
 {
+    /**
+     * The checklist state.
+     */
     pj_ice_checklist_state   state;
+
+    /**
+     * Number of candidate pairs (checks).
+     */
     unsigned		     count;
+
+    /**
+     * Array of candidate pairs (checks).
+     */
     pj_ice_check	     checks[PJ_ICE_MAX_CHECKS];
+
+    /**
+     * A timer used to perform periodic check for this checklist.
+     */
     pj_timer_entry	     timer;
+
 } pj_ice_checklist;
 
 
 /**
- * ICE sock callback.
+ * This structure contains callbacks that will be called by the ICE
+ * session.
  */
 typedef struct pj_ice_cb
 {
+    /**
+     * An optional callback that will be called by the ICE session when
+     * ICE negotiation has completed, successfully or with failure.
+     *
+     * @param ice	    The ICE session.
+     * @param status	    Will contain PJ_SUCCESS if ICE negotiation is
+     *			    successful, or some error code.
+     */
     void	(*on_ice_complete)(pj_ice *ice, pj_status_t status);
+
+    /**
+     * A mandatory callback which will be called by the ICE session when
+     * it needs to send outgoing STUN packet. 
+     *
+     * @param ice	    The ICE session.
+     * @param comp_id	    ICE component ID.
+     * @param cand_id	    ICE candidate ID.
+     * @param pkt	    The STUN packet.
+     * @param size	    The size of the packet.
+     * @param dst_addr	    Packet destination address.
+     * @param dst_addr_len  Length of destination address.
+     */
     pj_status_t (*on_tx_pkt)(pj_ice *ice, unsigned comp_id, 
 			     unsigned cand_id,
@@ -150,4 +369,17 @@
 			     const pj_sockaddr_t *dst_addr,
 			     unsigned dst_addr_len);
+
+    /**
+     * A mandatory callback which will be called by the ICE session when
+     * it receives packet which is not part of ICE negotiation.
+     *
+     * @param ice	    The ICE session.
+     * @param comp_id	    ICE component ID.
+     * @param pkt	    The whole packet.
+     * @param size	    Size of the packet.
+     * @param src_addr	    Source address where this packet was received 
+     *			    from.
+     * @param src_addr_len  The length of source address.
+     */
     void	(*on_rx_data)(pj_ice *ice, unsigned comp_id,
 			      void *pkt, pj_size_t size,
@@ -157,57 +389,108 @@
 
 
+/**
+ * This enumeration describes ICE role.
+ */
 typedef enum pj_ice_role
 {
+    /**
+     * The ICE agent is in controlled role.
+     */
     PJ_ICE_ROLE_CONTROLLED,
+
+    /**
+     * The ICE agent is in controlling role.
+     */
     PJ_ICE_ROLE_CONTROLLING
+
 } pj_ice_role;
 
-/**
- * ICE structure.
+
+/**
+ * This structure describes the ICE session. For this version of PJNATH,
+ * an ICE session corresponds to a single media stream (unlike the ICE
+ * session described in the ICE standard where an ICE session covers the
+ * whole media and may consist of multiple media streams). The decision
+ * to support only a single media session was chosen for simplicity,
+ * while still allowing application to utilize multiple media streams by
+ * creating multiple ICE sessions, one for each media stream.
  */
 struct pj_ice
 {
-    char		obj_name[PJ_MAX_OBJ_NAME];
-
-    pj_pool_t		*pool;
-    void		*user_data;
-    pj_mutex_t		*mutex;
-    pj_ice_role		 role;
-    pj_bool_t		 is_complete;
-    pj_status_t		 ice_status;
-    pj_ice_cb		 cb;
-
-    pj_stun_config	 stun_cfg;
+    char		obj_name[PJ_MAX_OBJ_NAME];  /**< Object name.	    */
+
+    pj_pool_t		*pool;			    /**< Pool instance.	    */
+    void		*user_data;		    /**< App. data.	    */
+    pj_mutex_t		*mutex;			    /**< Mutex.		    */
+    pj_ice_role		 role;			    /**< ICE role.	    */
+    pj_bool_t		 is_complete;		    /**< Complete?	    */
+    pj_status_t		 ice_status;		    /**< Error status.	    */
+    pj_ice_cb		 cb;			    /**< Callback.	    */
+
+    pj_stun_config	 stun_cfg;		    /**< STUN settings.	    */
 
     /* STUN credentials */
-    pj_str_t		 tx_ufrag;
-    pj_str_t		 tx_uname;
-    pj_str_t		 tx_pass;
-    pj_str_t		 rx_ufrag;
-    pj_str_t		 rx_uname;
-    pj_str_t		 rx_pass;
+    pj_str_t		 tx_ufrag;		    /**< Remote ufrag.	    */
+    pj_str_t		 tx_uname;		    /**< Uname for TX.	    */
+    pj_str_t		 tx_pass;		    /**< Remote password.   */
+    pj_str_t		 rx_ufrag;		    /**< Local ufrag.	    */
+    pj_str_t		 rx_uname;		    /**< Uname for RX	    */
+    pj_str_t		 rx_pass;		    /**< Local password.    */
 
     /* Components */
-    unsigned		 comp_cnt;
-    pj_ice_comp		 comp[PJ_ICE_MAX_COMP];
+    unsigned		 comp_cnt;		    /**< # of components.   */
+    pj_ice_comp		 comp[PJ_ICE_MAX_COMP];	    /**< Component array    */
 
     /* Local candidates */
-    unsigned		 lcand_cnt;
-    pj_ice_cand		 lcand[PJ_ICE_MAX_CAND];
+    unsigned		 lcand_cnt;		    /**< # of local cand.   */
+    pj_ice_cand		 lcand[PJ_ICE_MAX_CAND];    /**< Array of cand.	    */
 
     /* Remote candidates */
-    unsigned		 rcand_cnt;
-    pj_ice_cand		 rcand[PJ_ICE_MAX_CAND];
+    unsigned		 rcand_cnt;		    /**< # of remote cand.  */
+    pj_ice_cand		 rcand[PJ_ICE_MAX_CAND];    /**< Array of cand.	    */
 
     /* Checklist */
-    pj_ice_checklist	 clist;
+    pj_ice_checklist	 clist;			    /**< Active checklist   */
     
     /* Valid list */
-    pj_ice_checklist	 valid_list;
+    pj_ice_checklist	 valid_list;		    /**< Valid list.	    */
 };
 
+
+/**
+ * This is a utility function to retrieve the string name for the
+ * particular candidate type.
+ *
+ * @param type	    Candidate type.
+ *
+ * @return	    The string representation of the candidate type.
+ */
 PJ_DECL(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type);
 
 
+/**
+ * Create ICE session with the specified role and number of components.
+ * Application would typically need to create an ICE session before
+ * sending an offer or upon receiving one. After the session is created,
+ * application can register candidates to the ICE session by calling
+ * #pj_ice_add_cand() function.
+ *
+ * @param stun_cfg	The STUN configuration settings, containing among
+ *			other things the timer heap instance to be used
+ *			by the ICE session.
+ * @param name		Optional name to identify this ICE instance in
+ *			the log file.
+ * @param role		ICE role.
+ * @param comp_cnt	Number of components.
+ * @param cb		ICE callback.
+ * @param local_ufrag	Optional string to be used as local username to
+ *			authenticate incoming STUN binding request. If
+ *			the value is NULL, a random string will be 
+ *			generated.
+ * @param local_passwd	Optional string to be used as local password.
+ * @param p_ice		Pointer to receive the ICE session instance.
+ *
+ * @return		PJ_SUCCESS if ICE session is created successfully.
+ */
 PJ_DECL(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
 				   const char *name,
@@ -218,5 +501,32 @@
 				   const pj_str_t *local_passwd,
 				   pj_ice **p_ice);
+
+/**
+ * Destroy ICE session.
+ *
+ * @param ice		ICE session instance.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
 PJ_DECL(pj_status_t) pj_ice_destroy(pj_ice *ice);
+
+
+/**
+ * Add a candidate to this ICE session. 
+ *
+ * @param ice		ICE session instance.
+ * @param comp_id	Component ID of this candidate.
+ * @param type		Candidate type.
+ * @param local_pref	Local preference for this candidate, which
+ *			normally should be set to 65535.
+ * @param foundation	Foundation identification.
+ * @param addr		The candidate address.
+ * @param base_addr	The candidate's base address.
+ * @param rel_addr	Optional related address.
+ * @param addr_len	Length of addresses.
+ * @param p_cand_id	Optional pointer to receive the candidate ID.
+ *
+ * @return		PJ_SUCCESS if candidate is successfully added.
+ */
 PJ_DECL(pj_status_t) pj_ice_add_cand(pj_ice *ice,
 				     unsigned comp_id,
@@ -228,10 +538,45 @@
 				     const pj_sockaddr_t *rel_addr,
 				     int addr_len,
-				     unsigned *cand_id);
-
+				     unsigned *p_cand_id);
+
+/**
+ * Find default candidate for the specified component ID, using this
+ * rule:
+ *  - if the component has a successful candidate pair, then the
+ *    local candidate of this pair will be returned.
+ *  - otherwise a relay, reflexive, or host candidate will be selected 
+ *    on that specified order.
+ *
+ * @param ice		The ICE session instance.
+ * @param comp_id	The component ID.
+ * @param p_cand_id	Pointer to receive the candidate ID.
+ *
+ * @return		PJ_SUCCESS if a candidate has been selected.
+ */
 PJ_DECL(pj_status_t) pj_ice_find_default_cand(pj_ice *ice,
 					      unsigned comp_id,
-					      int *cand_id);
-
+					      int *p_cand_id);
+
+/**
+ * Pair the local and remote candidates to create check list. Application
+ * typically would call this function after receiving SDP containing ICE
+ * candidates from the remote host (either upon receiving the initial
+ * offer, for UAS, or upon receiving the answer, for UAC).
+ *
+ * Note that ICE connectivity check will not start until application calls
+ * #pj_ice_start_check().
+ *
+ * @param ice		ICE session instance.
+ * @param rem_ufrag	Remote ufrag, as seen in the SDP received from 
+ *			the remote agent.
+ * @param rem_passwd	Remote password, as seen in the SDP received from
+ *			the remote agent.
+ * @param rem_cand_cnt	Number of remote candidates.
+ * @param rem_cand	Remote candidate array. Remote candidates are
+ *			gathered from the SDP received from the remote 
+ *			agent.
+ *
+ * @return		PJ_SUCCESS or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_create_check_list(pj_ice *ice,
 					      const pj_str_t *rem_ufrag,
@@ -239,10 +584,53 @@
 					      unsigned rem_cand_cnt,
 					      const pj_ice_cand rem_cand[]);
+
+/**
+ * Start ICE periodic check. This function will return immediately, and
+ * application will be notified about the connectivity check status in
+ * #pj_ice_cb callback.
+ *
+ * @param ice		The ICE session instance.
+ *
+ * @return		PJ_SUCCESS or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_start_check(pj_ice *ice);
 
+
+/**
+ * Send data using this ICE session. If ICE checks have not produced a
+ * valid check for the specified component ID, this function will return
+ * with failure. Otherwise ICE session will send the packet to remote
+ * destination using the nominated local candidate for the specified
+ * component.
+ *
+ * @param ice		The ICE session.
+ * @param comp_id	Component ID.
+ * @param data		The data or packet to be sent.
+ * @param data_len	Size of data or packet, in bytes.
+ *
+ * @return		PJ_SUCCESS if data is sent successfully.
+ */
 PJ_DECL(pj_status_t) pj_ice_send_data(pj_ice *ice,
 				      unsigned comp_id,
 				      const void *data,
 				      pj_size_t data_len);
+
+/**
+ * Report the arrival of packet to the ICE session. Since ICE session
+ * itself doesn't have any transports, it relies on application or
+ * higher layer component to give incoming packets to the ICE session.
+ * If the packet is not a STUN packet, this packet will be given back
+ * to application via \a on_rx_data() callback in #pj_ice_cb.
+ *
+ * @param ice		The ICE session.
+ * @param comp_id	Component ID.
+ * @param cand_id	Candidate ID.
+ * @param pkt		Incoming packet.
+ * @param pkt_size	Size of incoming packet.
+ * @param src_addr	Source address of the packet.
+ * @param src_addr_len	Length of the address.
+ *
+ * @return		PJ_SUCCESS or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_on_rx_pkt(pj_ice *ice,
 				      unsigned comp_id,
Index: pjproject/trunk/pjnath/include/pjnath/ice_stream_transport.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/ice_stream_transport.h	(revision 1109)
+++ pjproject/trunk/pjnath/include/pjnath/ice_stream_transport.h	(revision 1110)
@@ -22,6 +22,6 @@
 
 /**
- * @file ice_mt.h
- * @brief ICE Media Transport.
+ * @file ice_stream_transport.h
+ * @brief ICE Stream Transport
  */
 #include <pjnath/ice.h>
@@ -38,10 +38,112 @@
  * @ingroup PJNATH_ICE
  * @{
- */
-
+ *
+ * This module describes ICE stream transport, as represented by #pj_ice_st
+ * structure, and is part of PJNATH - the Open Source NAT traversal helper
+ * library.
+ *
+ * ICE stream transport, as represented by #pj_ice_st structure, is an ICE
+ * capable component for transporting media within a media stream. 
+ * It consists of one or more transport sockets (typically two for RTP
+ * based communication - one for RTP and one for RTCP), and an 
+ * \ref PJNATH_ICE_SESSION for performing connectivity checks among the.
+ * various candidates of the transport addresses.
+ *
+ * \section PJNATH_ICE_STREAM_TRANSPORT_USING Using the ICE Stream Transport
+ *
+ * Application may use the ICE stream transport in two ways:
+ *  - it can create the ICE stream transports once during application 
+ *    initialization and keep them alive throughout application lifetime, or
+ *  - it can create and destroy the ICE stream transport as needed everytime 
+ *     a call is made and destroyed. 
+ *
+ * Keeping the ICE stream transport alive throughout
+ * application's lifetime is normally preferable, as initializing the
+ * ICE stream transport may incur delay because the ICE stream transport
+ * would need to communicate with the STUN/TURN server to get the
+ * server reflexive and relayed candidates for the transports.
+ *
+ * Regardless of which usage scenario is being used, the ICE stream
+ * transport is capable for restarting the ICE session being used and to
+ * send STUN keep-alives for its STUN server reflexive and relayed
+ * candidates.
+ *
+ * \subsection PJNATH_ICE_ST_TRA_INIT Stream Transport Initialization
+ *
+ * Application creates the ICE stream transport by calling 
+ * #pj_ice_st_create() function.
+ *
+ * After the ICE stream transport is created, application may set up the
+ * STUN servers to be used to obtain STUN server reflexive and relayed
+ * candidate, by calling #pj_ice_st_set_stun_domain() or 
+ * #pj_ice_st_set_stun_srv(). Then it has to create each component by
+ * calling #pj_ice_st_create_comp(); this would create an actual socket
+ * which listens to the specified local address, and it would also
+ * perform lookup to find various transport address candidates for this
+ * socket.
+ * 
+ * \subsection PJNATH_ICE_ST_TRA_INIT_ICE ICE Session Initialization
+ *
+ * When application is about to send an offer containing ICE capability,
+ * or when it receives an offer containing ICE capability, it would
+ * create the ICE session by calling #pj_ice_st_init_ice(). This would
+ * register all transport address aliases for each component to the ICE
+ * session as candidates. After this application can enumerate all local
+ * candidates by calling #pj_ice_st_enum_cands(), and encode these
+ * candidates in the SDP to be sent to remote agent.
+ *
+ * \subsection PJNATH_ICE_ST_TRA_START Starting Connectivity Checks
+ *
+ * Once application receives the SDP from remote, it can start ICE
+ * connectivity checks by calling #pj_ice_st_start_ice(), specifying
+ * the username, password, and candidates of the remote agent. The ICE
+ * session/transport will then notify the application via the callback
+ * when ICE connectivity checks completes, either successfully or with
+ * failure.
+ *
+ * \subsection PJNATH_ICE_ST_TRA_STOP Stopping ICE Session
+ *
+ * Once the call is terminated, application no longer needs to keep the
+ * ICE session, so it should call #pj_ice_st_stop_ice() to destroy the
+ * ICE session within this ICE stream transport. Note that this WILL NOT
+ * destroy the sockets/transports, it only destroys the ICE session
+ * within this ICE stream transport.
+ *
+ * \subsection PJNATH_ICE_ST_TRA_RESTART Restarting ICE Session
+ *
+ * When a new call is made, application can repeat the above
+ * #pj_ice_st_init_ice() to #pj_ice_st_stop_ice() cycle for the new call,
+ * using this same ICE stream transport.
+ *
+ * \subsection PJNATH_ICE_ST_TRA_DESTROY Destroying ICE Stream Transport
+ *
+ * Finally, when the ICE stream transport itself is no longer needed,
+ * for example when the application quits, application should call
+ * #pj_ice_st_destroy() to release back all resources allocated by this
+ * ICE stream transport.
+ *
+ */
+
+/** Forward declaration for ICE stream transport. */
 typedef struct pj_ice_st pj_ice_st;
 
+/** 
+ * This structure contains callbacks that will be called by the 
+ * ICE stream transport.
+ */
 typedef struct pj_ice_st_cb
 {
+    /**
+     * This callback will be called when the ICE transport receives
+     * incoming packet from the sockets which is not related to ICE
+     * (for example, normal RTP/RTCP packet destined for application).
+     *
+     * @param ice_st	    The ICE stream transport.
+     * @param comp_id	    The component ID.
+     * @param pkt	    The packet.
+     * @param size	    Size of the packet.
+     * @param src_addr	    Source address of the packet.
+     * @param src_addr_len  Length of the source address.
+     */
     void    (*on_rx_data)(pj_ice_st *ice_st,
 			  unsigned comp_id, 
@@ -49,4 +151,12 @@
 			  const pj_sockaddr_t *src_addr,
 			  unsigned src_addr_len);
+
+    /**
+     * This callback will be called when ICE checks have completed.
+     * This callback is optional.
+     * 
+     * @param ice_st	    The ICE stream transport.
+     * @param status	    The ICE connectivity check status.
+     */
     void    (*on_ice_complete)(pj_ice_st *ice_st, 
 			       pj_status_t status);
@@ -55,76 +165,176 @@
 
 
-#ifndef PJ_ICE_ST_MAX_ALIASES
-#   define PJ_ICE_ST_MAX_ALIASES	8
-#endif
-
+/**
+ * Various flags that can be specified when creating a component with
+ * #pj_ice_st_create_comp(). These options may be combined together
+ * with bitmask operation.
+ */
 enum pj_ice_st_option
 {
+    /**
+     * If this option is specified, only a listening socket will be
+     * created for the component, and no candidate will be added to
+     * the component. Application must add the component manually
+     * by inspecting the socket and transport address of the component.
+     */
     PJ_ICE_ST_OPT_DONT_ADD_CAND = 1,
+
+    /**
+     * If this option is specified, then no STUN reflexive candidate
+     * will be added to the component.
+     */
     PJ_ICE_ST_OPT_DISABLE_STUN	= 2,
+
+    /**
+     * If this option is specified, then no STUN relay candidate
+     * will be added to the component.
+     */
     PJ_ICE_ST_OPT_DISABLE_RELAY	= 4,
+
+    /**
+     * If this option is specified, then when the function fails to
+     * bind the socket to the specified port, it WILL NOT try to
+     * bind the socket to the next available port.
+     *
+     * If this option is NOT specified, then the function will try to
+     * bind the socket to next port+2, repetitively until the socket
+     * is bound successfully.
+     */
     PJ_ICE_ST_OPT_NO_PORT_RETRY	= 8,
 };
 
 
+/**
+ * This structure describes ICE stream transport candidate. A "candidate"
+ * in ICE stream transport can be viewed as alias transport address
+ * for the socket.
+ */
 typedef struct pj_ice_st_cand
 {
+    /**
+     * Candidate type.
+     */
     pj_ice_cand_type	type;
+
+    /** 
+     * Status of this candidate. This status is useful for ICE reflexive
+     * and relay candidate, where the address needs to be resolved 
+     * asynchronously by sending STUN request to STUN server.
+     *
+     * The value will be PJ_SUCCESS if candidate address has been resolved
+     * successfully, PJ_EPENDING when the address resolution process is
+     * in progress, or other value when the address resolution has
+     * completed with failure.
+     */
     pj_status_t		status;
+
+    /**
+     * The candidate transport address.
+     */
     pj_sockaddr		addr;
-    int			cand_id;
+
+    /**
+     * The ICE session candidate ID after this candidate has been registered
+     * to an ICE session. Before ICE session is created, or after ICE
+     * session has been destroyed, the value will be -1.
+     */
+    int			ice_cand_id;
+
+    /**
+     * Local preference value, which typically is 65535.
+     */
     pj_uint16_t		local_pref;
+
+    /**
+     * Foundation associated with this candidate, which value normally will be
+     * calculated by the function.
+     */
     pj_str_t		foundation;
+
 } pj_ice_st_cand;
 
 
+/**
+ * This structure describes an ICE stream transport component. A component
+ * in ICE stream transport typically corresponds to a single socket created
+ * for this component, and bound to a specific transport address. This
+ * component may have multiple alias addresses, for example one alias 
+ * address for each interfaces in multi-homed host, another for server
+ * reflexive alias, and another for relayed alias. For each transport
+ * address alias, an ICE stream transport candidate (#pj_ice_st_cand) will
+ * be created, and these candidates will eventually registered to the ICE
+ * session.
+ */
 typedef struct pj_ice_st_comp
 {
-    pj_ice_st		*ice_st;
-    unsigned		 comp_id;
-    pj_uint32_t		 options;
-    pj_sock_t		 sock;
-
-    pj_stun_session	*stun_sess;
-
-    pj_sockaddr		 local_addr;
-
-    unsigned		 pending_cnt;
-    pj_status_t		 last_status;
-
-    unsigned		 cand_cnt;
-    pj_ice_st_cand	 cand_list[PJ_ICE_ST_MAX_ALIASES];
-    int			 default_cand;
-
-    pj_ioqueue_key_t	*key;
-    pj_uint8_t		 pkt[1500];
-    pj_ioqueue_op_key_t	 read_op;
-    pj_ioqueue_op_key_t	 write_op;
-    pj_sockaddr		 src_addr;
-    int			 src_addr_len;
+    pj_ice_st		*ice_st;	/**< ICE stream transport.	*/
+    unsigned		 comp_id;	/**< Component ID.		*/
+    pj_uint32_t		 options;	/**< Option flags.		*/
+    pj_sock_t		 sock;		/**< Socket descriptor.		*/
+
+    pj_stun_session	*stun_sess;	/**< STUN session.		*/
+
+    pj_sockaddr		 local_addr;	/**< Local/base address.	*/
+
+    unsigned		 pending_cnt;	/**< Pending resolution cnt.	*/
+    pj_status_t		 last_status;	/**< Last status.		*/
+
+    unsigned		 cand_cnt;	/**< # of candidates/aliaes.	*/
+    pj_ice_st_cand	 cand_list[PJ_ICE_ST_MAX_CAND];	/**< Cand array	*/
+    int			 default_cand;	/**< Default candidate selected	*/
+
+    pj_ioqueue_key_t	*key;		/**< ioqueue key.		*/
+    pj_uint8_t		 pkt[1500];	/**< Incoming packet buffer.	*/
+    pj_ioqueue_op_key_t	 read_op;	/**< ioqueue read operation key	*/
+    pj_ioqueue_op_key_t	 write_op;	/**< ioqueue write op. key	*/
+    pj_sockaddr		 src_addr;	/**< source packet address buf.	*/
+    int			 src_addr_len;	/**< length of src addr. buf.	*/
 
 } pj_ice_st_comp;
 
 
+/**
+ * This structure represents the ICE stream transport.
+ */
 struct pj_ice_st
 {
-    char		     obj_name[PJ_MAX_OBJ_NAME];
-    pj_pool_t		    *pool;
-    void		    *user_data;
-    pj_stun_config	     stun_cfg;
-    pj_ice_st_cb	     cb;
-
-    pj_ice		    *ice;
-
-    unsigned		     comp_cnt;
-    pj_ice_st_comp	   **comp;
-
-    pj_dns_resolver	    *resolver;
-    pj_bool_t		     has_resolver_job;
-    pj_sockaddr_in	     stun_srv;
-    pj_sockaddr_in	     turn_srv;
+    char		     obj_name[PJ_MAX_OBJ_NAME];	/**< Log ID.	*/
+
+    pj_pool_t		    *pool;	/**< Pool used by this object.	*/
+    void		    *user_data;	/**< Application data.		*/
+    pj_stun_config	     stun_cfg;	/**< STUN settings.		*/
+    pj_ice_st_cb	     cb;	/**< Application callback.	*/
+
+    pj_ice		    *ice;	/**< ICE session.		*/
+
+    unsigned		     comp_cnt;	/**< Number of components.	*/
+    pj_ice_st_comp	   **comp;	/**< Components array.		*/
+
+    pj_dns_resolver	    *resolver;	/**< The resolver instance.	*/
+    pj_bool_t		     has_rjob;	/**< Has pending resolve?	*/
+    pj_sockaddr_in	     stun_srv;	/**< STUN server address.	*/
+    pj_sockaddr_in	     turn_srv;	/**< TURN server address.	*/
 };
 
 
+/**
+ * Create the ICE stream transport containing the specified number of
+ * components. After the ICE stream transport is created, application
+ * may initialize the STUN server settings, and after that it has to 
+ * initialize each components by calling #pj_ice_st_create_comp()
+ * function.
+ *
+ * @param stun_cfg	The STUN settings.
+ * @param name		Optional name for logging identification.
+ * @param comp_cnt	Number of components.
+ * @param user_data	Arbitrary user data to be associated with this
+ *			ICE stream transport.
+ * @param cb		Callback.
+ * @param p_ice_st	Pointer to receive the ICE stream transport
+ *			instance.
+ *
+ * @return		PJ_SUCCESS if ICE stream transport is created
+ *			successfully.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_create(pj_stun_config *stun_cfg,
 				      const char *name,
@@ -133,17 +343,120 @@
 				      const pj_ice_st_cb *cb,
 				      pj_ice_st **p_ice_st);
+
+/**
+ * Destroy the ICE stream transport. This will destroy the ICE session
+ * inside the ICE stream transport, close all sockets and release all
+ * other resources.
+ *
+ * @param ice_st	The ICE stream transport.
+ *
+ * @return		PJ_SUCCESS, or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_destroy(pj_ice_st *ice_st);
 
+
+/**
+ * Set the domain to be used when resolving the STUN servers. If application
+ * wants to utillize STUN, then STUN server must be specified, either by
+ * calling this function or by calling #pj_ice_st_set_stun_srv().
+ *
+ * If application calls this function, then the STUN/TURN servers will
+ * be resolved by querying DNS SRV records for the specified domain.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param resolver	The resolver instance that will be used to
+ *			resolve the STUN/TURN servers.
+ * @param domain	The target domain.
+ *
+ * @return		PJ_SUCCESS if DNS SRV resolution job can be
+ *			started. The resolution process itself will
+ *			complete asynchronously.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_set_stun_domain(pj_ice_st *ice_st,
 					       pj_dns_resolver *resolver,
 					       const pj_str_t *domain);
+
+/**
+ * Set the STUN and TURN server addresses. If application
+ * wants to utillize STUN, then STUN server must be specified, either by
+ * calling this function or by calling #pj_ice_st_set_stun_domain().
+ *
+ * With this function, the STUN and TURN server addresses will be 
+ * assigned immediately, that is no DNS resolution will need to be 
+ * performed.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param stun_srv	The STUN server address, or NULL if STUN
+ *			reflexive candidate is not to be used.
+ * @param turn_srv	The TURN server address, or NULL if STUN
+ *			relay candidate is not to be used.
+ *
+ * @return		PJ_SUCCESS, or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_set_stun_srv(pj_ice_st *ice_st,
 					    const pj_sockaddr_in *stun_srv,
 					    const pj_sockaddr_in *turn_srv);
 
+/**
+ * Create and initialize the specified component. This function will
+ * instantiate the socket descriptor for this component, optionally
+ * bind the socket to the specified address (or bind to any address/port
+ * if the \a addr parameter is NULL), and start finding all alias
+ * addresses for this socket. For each alias addresses that if finds,
+ * it will add an ICE stream transport candidate for this component.
+ *
+ * After all components have been initialized, application should poll
+ * the #pj_ice_st_get_comps_status() peridically to check if STUN
+ * server reflexive and relayed candidates have been obtained
+ * successfully.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param comp_id	The component ID, which value must be greater than
+ *			zero and less than or equal to the number of 
+ *			components in this ICE stream transport.
+ * @param options	Options, see #pj_ice_st_option.
+ * @param addr		Local address where socket will be bound to. This
+ *			address will be used as follows:
+ *			- if the value is NULL, then socket will be bound
+ *			  to any available port.
+ *			- if the value is not NULL, then if the port number
+ *			  is not zero, it will used as the starting port 
+ *			  where the socket will be bound to. If bind() to
+ *			  this port fails, this function will try to bind
+ *			  to port+2, repeatedly until it succeeded.
+ *			  If application doesn't want this function to 
+ *			  retry binding the socket to other port, it can
+ *			  specify PJ_ICE_ST_OPT_NO_PORT_RETRY option.
+ *			- if the value is not NULL, then if the address
+ *			  is not INADDR_ANY, this function will bind the
+ *			  socket to this particular interface only, and
+ *			  no other host candidates will be added for this
+ *			  socket.
+ *			
+ *
+ * @return		PJ_SUCCESS, or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_create_comp(pj_ice_st *ice_st,
 					   unsigned comp_id,
 					   pj_uint32_t options,
 					   const pj_sockaddr_in *addr);
+
+/**
+ * Manually add a candidate (transport address alias) for the specified
+ * component. Normally application shouldn't need to use this function,
+ * as candidates will be added automatically when component is created
+ * with #pj_ice_st_create_comp().
+ *
+ * @param ice_st	ICE stream transport.
+ * @param comp_id	The component ID.
+ * @param type		The candidate type.
+ * @param local_pref	The local preference for this candidate
+ *			(typically the value is 65535).
+ * @param addr		The candidate address.
+ * @param set_default	Set to non-zero to make this candidate the 
+ *			default candidate for this component.
+ *
+ * @return		PJ_SUCCESS, or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_add_cand(pj_ice_st *ice_st,
 					unsigned comp_id,
@@ -153,13 +466,71 @@
 					pj_bool_t set_default);
 
+/**
+ * Get the status of components in the ICE stream transports. Since
+ * some IP address candidates have to be obtained asynchronously (for
+ * example, the STUN reflexive or relay candidate), application can
+ * use this function to know whether the address resolution has 
+ * completed.
+ *
+ * @param ice_st	The ICE stream transport.
+ *
+ * @return		PJ_SUCCESS if all candidates have been resolved
+ *			successfully, PJ_EPENDING if transport resolution
+ *			is still in progress, or other status on failure.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_get_comps_status(pj_ice_st *ice_st);
 
+/**
+ * Initialize the ICE session in the ICE stream transport.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param role		ICE role.
+ * @param local_ufrag	Optional local username fragment.
+ * @param local_passwd	Optional local password.
+ *
+ * @return		PJ_SUCCESS, or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_init_ice(pj_ice_st *ice_st,
 					pj_ice_role role,
 					const pj_str_t *local_ufrag,
 					const pj_str_t *local_passwd);
+
+/**
+ * Enumerate the local candidates. This function can only be called
+ * after the ICE session has been created in the ICE stream transport.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param count		On input, it specifies the maximum number of
+ *			elements. On output, it will be filled with
+ *			the number of candidates copied to the
+ *			array.
+ * @param cand		Array of candidates.
+ *
+ * @return		PJ_SUCCESS, or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_enum_cands(pj_ice_st *ice_st,
 					  unsigned *count,
 					  pj_ice_cand cand[]);
+
+/**
+ * Start ICE connectivity checks. This function can only be called
+ * after the ICE session has been created in the ICE stream transport.
+ *
+ * This function will pair the local and remote candidates to create 
+ * check list. Once the check list is created and sorted based on the
+ * priority, ICE periodic checks will be started. This function will 
+ * return immediately, and application will be notified about the 
+ * connectivity check status in the callback.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param rem_ufrag	Remote ufrag, as seen in the SDP received from 
+ *			the remote agent.
+ * @param rem_passwd	Remote password, as seen in the SDP received from
+ *			the remote agent.
+ * @param rem_cand_cnt	Number of remote candidates.
+ * @param rem_cand	Remote candidate array.
+ *
+ * @return		PJ_SUCCESS, or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_start_ice(pj_ice_st *ice_st,
 					 const pj_str_t *rem_ufrag,
@@ -167,6 +538,31 @@
 					 unsigned rem_cand_cnt,
 					 const pj_ice_cand rem_cand[]);
+
+/**
+ * Stop and destroy the ICE session inside this media transport.
+ *
+ * @param ice_st	The ICE stream transport.
+ *
+ * @return		PJ_SUCCESS, or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_stop_ice(pj_ice_st *ice_st);
 
+
+/**
+ * Send outgoing packet using this transport. If ICE checks have not 
+ * produced a valid check for the specified component ID, this function 
+ * will return with failure. Otherwise it will send the packet to remote
+ * destination using the nominated local candidate as have been checked
+ * previously.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param comp_id	Component ID.
+ * @param data		The data or packet to be sent.
+ * @param data_len	Size of data or packet, in bytes.
+ * @param dst_addr	The destination address.
+ * @param dst_addr_len	Length of destination address.
+ *
+ * @return		PJ_SUCCESS if data is sent successfully.
+ */
 PJ_DECL(pj_status_t) pj_ice_st_sendto(pj_ice_st *ice_st,
 				      unsigned comp_id,
Index: pjproject/trunk/pjnath/include/pjnath/stun_auth.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/stun_auth.h	(revision 1109)
+++ pjproject/trunk/pjnath/include/pjnath/stun_auth.h	(revision 1110)
@@ -34,4 +34,5 @@
 /**
  * @defgroup PJNATH_STUN_AUTH STUN Authentication
+ * @brief STUN authentication helper
  * @ingroup PJNATH_STUN
  * @{
@@ -299,6 +300,13 @@
 
 
-/* Calculate HMAC-SHA1 key for long term credential, by getting
+/**
+ * Calculate HMAC-SHA1 key for long term credential, by getting
  * MD5 digest of username, realm, and password. 
+ *
+ * @param digest    The buffer for the digest.
+ * @param realm	    The realm of the credential, if long term credential
+ *		    is to be used.
+ * @param username  The username.
+ * @param passwd    The clear text password.
  */
 void pj_stun_calc_md5_key(pj_uint8_t digest[16],
Index: pjproject/trunk/pjnath/include/pjnath/stun_doc.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/stun_doc.h	(revision 1109)
+++ 	(revision )
@@ -1,100 +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 __PJ_STUN_SERVER_H__
-#define __PJ_STUN_SERVER_H__
-
-/*
- * STUN documentation. There is no code here.
- */
-
-/**
- * @defgroup PJNATH_STUN STUN and TURN
- * @ingroup PJNATH
-
- This is the implementation of STUN/TURN in PJLIB-UTIL library.
-
- The STUN/TURN implementation in PJLIB-UTIL has the following objectives:
- - standard based (of course)
- - supports both client and server side STUN/TURN services
- - independent (that is, only dependent to pjlib), and general purpose
-   enough to be used not only by pjsip applications but also by other 
-   types of applications
- - must be able to support ICE.
-
- The STUN/TURN implementation is based on the following standards:
- - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-05.txt">
-   draft-ietf-behave-rfc3489bis-05.txt</A>
- - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-02.txt">
-   draft-ietf-behave-turn-02.txt</A>
-
- But as STUN standards are currently defined as work in progress at IETF,
- the implementation will be updated as these standards are updated.
-
-  
-
- @section stun_org_sec Organization
-
- The implementation consists of the following components.
-
- @subsection stun_msg_sec Messaging and Parsing
-
- The lowest layer of the STUN implementation is the @ref PJNATH_STUN_MSG
- component. This part is responsible for encoding and decoding STUN messages.
-
- This layer only implements message representation and parsing. In particular,
- it does not provide any transport functionalities, therefore it can be used
- by different types of applications.
-
-
-
- @subsection stun_endpt_sec Endpoint
-
- The @ref PJNATH_STUN_ENDPOINT is used by the library to put together
- common settings for all STUN objects. For example, the STUN endpoint has a
- reference of timer heap to poll all STUN timers, reference to ioqueue to
- poll network events for STUN servers, and some common settings used by
- various STUN objects.
-
-
- @subsection stun_clt_tsx_sec Client Transaction
-
- The @ref PJNATH_STUN_TRANSACTION is used to manage outgoing STUN request,
- for example to retransmit the request and to notify application about the
- completion of the request.
-
- The @ref PJNATH_STUN_TRANSACTION does not use any networking operations,
- but instead application must supply the transaction with a callback to
- be used by the transaction to send outgoing requests. This way the STUN
- transaction is made more generic and can work with different types of
- networking codes in application.
-
-
-
- @subsection stun_srv_sec Server Components
-
- The @ref PJNATH_STUN_SERVER is used for:
- - implementing STUN servers, and/or
- - implementing server side STUN handling (for example for ICE).
-
- */
-
-
-
-#endif	/* __PJ_STUN_SERVER_H__ */
-
Index: pjproject/trunk/pjnath/include/pjnath/stun_msg.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/stun_msg.h	(revision 1109)
+++ pjproject/trunk/pjnath/include/pjnath/stun_msg.h	(revision 1110)
@@ -40,52 +40,4 @@
  */
 
-
-/**
- * The default initial STUN round-trip time estimation (the RTO value
- * in RFC 3489-bis), in miliseconds. 
- * This value is used to control the STUN request 
- * retransmit time. The initial value of retransmission interval 
- * would be set to this value, and will be doubled after each
- * retransmission.
- */
-#ifndef PJ_STUN_RTO_VALUE
-#   define PJ_STUN_RTO_VALUE		    100
-#endif
-
-
-/**
- * The STUN transaction timeout value, in miliseconds.
- * After the last retransmission is sent and if no response is received 
- * after this time, the STUN transaction will be considered to have failed.
- *
- * The default value is 1600 miliseconds (as per RFC 3489-bis).
- */
-#ifndef PJ_STUN_TIMEOUT_VALUE
-#   define PJ_STUN_TIMEOUT_VALUE	    1600
-#endif
-
-
-/**
- * Maximum number of STUN retransmission count.
- *
- * Default: 7 (as per RFC 3489-bis)
- */
-#ifndef PJ_STUN_MAX_RETRANSMIT_COUNT
-#   define PJ_STUN_MAX_RETRANSMIT_COUNT	    7
-#endif
-
-
-/**
- * Maximum size of STUN message.
- */
-#ifndef PJ_STUN_MAX_PKT_LEN
-#   define PJ_STUN_MAX_PKT_LEN		    512
-#endif
-
-
-/**
- * Default STUN port as defined by RFC 3489.
- */
-#define PJ_STUN_PORT			    3478
 
 /**
Index: pjproject/trunk/pjnath/include/pjnath/stun_session.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/stun_session.h	(revision 1109)
+++ pjproject/trunk/pjnath/include/pjnath/stun_session.h	(revision 1110)
@@ -19,4 +19,9 @@
 #ifndef __PJNATH_STUN_SESSION_H__
 #define __PJNATH_STUN_SESSION_H__
+
+/**
+ * @file stun_session.h
+ * @brief STUN session management for client/server.
+ */
 
 #include <pjnath/stun_msg.h>
@@ -188,4 +193,5 @@
  *
  * @param sess	    The STUN session instance.
+ * @param user_data The user data.
  *
  * @return	    PJ_SUCCESS on success, or the appropriate error code.
@@ -352,13 +358,15 @@
  * 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 options    Options, from #pj_stun_decode_options.
- * @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.
+ * @param sess		The STUN session instance.
+ * @param packet	The packet containing STUN message.
+ * @param pkt_size	Size of the packet.
+ * @param options	Options, from #pj_stun_decode_options.
+ * @param parsed_len	Optional pointer to receive the size of the parsed
+ *			STUN message (useful if packet is received via a
+ *			stream oriented protocol).
+ * @param src_addr	The source address of the packet.
+ * @param src_addr_len	Length of the source address.
+ *
+ * @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,
Index: pjproject/trunk/pjnath/include/pjnath/stun_transaction.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/stun_transaction.h	(revision 1109)
+++ pjproject/trunk/pjnath/include/pjnath/stun_transaction.h	(revision 1110)
@@ -192,11 +192,5 @@
  *
  * @param tsx		The STUN client transaction instance.
- * @param packet	The incoming packet.
- * @param pkt_size	Size of the incoming packet.
- * @param parsed_len	Optional pointer to receive the number of bytes
- *			that have been parsed from the incoming packet
- *			for the STUN message. This is useful if the
- *			STUN transaction is running over stream oriented
- *			socket such as TCP or TLS.
+ * @param msg		The incoming STUN message.
  *
  * @return		PJ_SUCCESS on success or the appropriate error code.
Index: pjproject/trunk/pjnath/include/pjnath/turn_client.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/turn_client.h	(revision 1109)
+++ 	(revision )
@@ -1,132 +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 __PJNATH_TURN_CLIENT_H__
-#define __PJNATH_TURN_CLIENT_H__
-
-/**
- * @file turn_client.h
- * @brief TURN client session.
- */
-
-#include <pjnath/stun_msg.h>
-
-
-PJ_BEGIN_DECL
-
-
-/**
- * @defgroup PJNATH_TURN_CLIENT TURN Client Session
- * @brief Management of STUN/TURN client session
- * @ingroup PJNATH_STUN
- * @{
- */
-
-typedef struct pj_turn_client pj_turn_client;
-
-/**
- * This describes TURN client config.
- */
-typedef struct pj_turn_client_cb
-{
-    /**
-     * Callback to be called by the TURN session to send outgoing message.
-     *
-     * @param client	    The TURN client session.
-     * @param pkt	    Packet to be sent.
-     * @param pkt_size	    Size of the packet to be sent.
-     * @param dst_addr	    The destination address.
-     * @param addr_len	    Length of destination address.
-     *
-     * @return		    The callback should return the status of the
-     *			    packet sending.
-     */
-    pj_status_t (*on_send_msg)(pj_turn_client *client,
-			       const void *pkt,
-			       pj_size_t pkt_size,
-			       const pj_sockaddr_t *dst_addr,
-			       unsigned addr_len);
-
-    /**
-     * Callback to be called by TURN session when its state has changed.
-     */
-    pj_status_t (*on_state_changed)(pj_turn_client *client);
-
-} pj_turn_client_cb;
-
-
-/**
- * Options
- */
-typedef struct pj_turn_client_config
-{
-    int	    bandwidth;
-    int	    lifetime;
-    int	    sock_type;
-    int	    port;
-} pj_turn_client_config;
-
-
-PJ_INLINE(void) pj_turn_client_config_default(pj_turn_client_config *cfg)
-{
-    pj_bzero(cfg, sizeof(*cfg));
-    cfg->bandwidth = -1;
-    cfg->lifetime = -1;
-    cfg->sock_type = -1;
-    cfg->port = -1;
-}
-
-
-/**
- * This describes the TURN client session.
- */
-struct pj_turn_client
-{
-    pj_pool_t	    *pool;
-    pj_stun_session *session;
-    pj_timer_entry   alloc_timer;
-    pj_sockaddr_in   mapped_addr;
-    pj_sockaddr_in   relay_addr;
-};
-
-
-
-
-/**
- * Create the TURN client session.
- */
-PJ_DECL(pj_status_t) pj_turn_client_create(pj_stun_endpoint *endpt,
-					   const pj_turn_client_config *cfg,
-					   const pj_turn_client_cb *cb,
-					   pj_turn_client **p_client);
-
-/**
- * Start the TURN client session by sending Allocate request to the server.
- */
-
-
-/**
- * @}
- */
-
-
-PJ_END_DECL
-
-
-#endif	/* __PJNATH_TURN_CLIENT_H__ */
-
Index: pjproject/trunk/pjnath/include/pjnath/types.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/types.h	(revision 1109)
+++ pjproject/trunk/pjnath/include/pjnath/types.h	(revision 1110)
@@ -29,5 +29,5 @@
 
 /**
- * @defgroup PJNATH NAT Helper Library
+ * @defgroup PJNATH NAT Traversal Helper Library
  * @{
  */
@@ -52,15 +52,154 @@
 
 /**
- * @mainpage NAT Helper Library
- *
- * \n
- * \n
- * \n
- * This is the documentation of PJNATH, an auxiliary library providing
- * NAT helper functionalities such as STUN and ICE.
- * 
- * Please go to the <A HREF="modules.htm"><B>Modules</B></A> page for list
- * of modules.
- *
+ * @mainpage PJNATH - Open Source STUN, TURN, and ICE Library
+ *
+ * \n
+ * This is the documentation of PJNATH, an Open Source library providing
+ * NAT traversal helper functionalities by using standard based protocols 
+ * such as:
+ *  - <b>STUN</b> (Session Traversal Utilities),
+ *  - <b>TURN</b> (Obtaining Relay Addresses from STUN)
+ *  - <b>ICE</b> (Interactive Connectivity Establishment).
+ * 
+ * The following sections will give a short overview about the protocols
+ * supported by this library, and how they are implemented in PJNATH.
+ *
+ * \n
+
+ * \section PJNATH_STUN STUN Protocol Library
+ *
+ * Session Traversal Utilities (STUN, or previously known as Simple 
+ * Traversal of User Datagram Protocol (UDP) Through Network Address 
+ * Translators (NAT)s), was previously released as IETF standard
+ * <A HREF="http://www.ietf.org/rfc/rfc3489.txt">RFC 3489</A>, but since
+ * then it has been revised into the following:
+ *  - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-06.txt">
+ *    <B>draft-ietf-behave-rfc3489bis-06</b></A> for the main STUN 
+ *    specification,
+ *  - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-03.txt">
+ *    <B>draft-ietf-behave-turn-03</B></A> for TURN usage of STUN,
+ *  - and several other drafts explaining other STUN usages.
+ * 
+ * The PJNATH library provides facilities to support both the core 
+ * <B>STUN-bis</B> specification and the <B>TURN</B> usage of STUN, 
+ * as well as other STUN usages. Please see #pj_stun_attr_type for 
+ * list of STUN attributes supported by this library.
+ *
+ * 
+ * The following are some design principles that have been utilized
+ * when implementing the STUN library in PJNATH:
+ *
+ *  - layered architecture, with \ref PJNATH_STUN_MSG as the lowest
+ *    layer and \ref PJNATH_STUN_SESSION as the highest abstraction
+ *    layer, to accommodate various usage scenario of the library.
+ *
+ *  - no transport -- the STUN library is pretty much transport
+ *    independent and all sending and receiving functionalities will
+ *    have to be implemented by application or higher level
+ *    abstraction (such as ICE). This helps facilitating an even
+ *    more usage scenarios of the library.
+ *
+ *  - common functionalities for both STUN client and server
+ *    development. All STUN components can be used to develop both
+ *    STUN client and STUN server application, and in fact, in ICE,
+ *    both STUN client and server functionality exist in a single
+ *    ICE session.
+ *
+ * \n
+ *
+ * \subsection PJNATH_STUN_ARCH STUN Library Organization
+ *
+
+ \verbatim
+
+    +-----------------------------------------------------------------+
+    |                                                                 |
+    |                   A P P L I C A T I O N                         |
+    |                                                                 |
+    +-----------------------------------------------------------------+
+         ^                          ^
+         |                          |
+         v                          v
+    +--------+    +-----------------------------------+    +----------+
+    |        |    |                                   |    |          |
+    |  Appl- |<-->|      S T U N   S E S S I O N      |<-->| S T U N  |
+    | ication|    |                                   |    |  Authen- |
+    | Trans- |    +-----------------------------------+    | tication |
+    |  port  |    |                                   |    |          |
+    |        |<-->|  S T U N   T R A N S A C T I O N  |    +----------+
+    |        |    |                                   |
+    |        |    +-----------------------------------+
+    |        |    |                                   |
+    |        |    |    STUN MESSAGE REPRESENTATION    |
+    +--------+    |            AND PARSING            |
+                  +-----------------------------------+
+
+ \endverbatim
+
+ * The STUN library is organized as follows:
+ *
+ *  - the lowest layer of the library is \ref PJNATH_STUN_MSG. This layer
+ *    provides STUN message representation, validation, parsing, and
+ *    debugging (dump to log) of STUN messages.
+ *
+ *  - for client, the next higher layer is \ref PJNATH_STUN_TRANSACTION,
+ *    which manages retransmissions of STUN request.
+ *
+ *  - \ref PJNATH_STUN_AUTH provides mechanism to verify STUN
+ *    credential in incoming STUN messages.
+ *
+ *  - for both client and server, the next higher abstraction is
+ *    \ref PJNATH_STUN_SESSION, which provides management of incoming
+ *    and outgoing messages and association of STUN credential to
+ *    a STUN session.
+ *
+ * As mentioned previously, all STUN library components are independent
+ * of any transports. Application gives incoming packet
+ * to the STUN components for processing. and it must supply the STUN 
+ * components with callback to send outgoing messages.
+ * 
+ * \n
+ *
+ * \section PJNATH_ICE ICE Implementation
+ *
+ * Interactive Connectivity Establishment (ICE) is a standard based 
+ * methodology for traversing Network Address Translator (NAT), and
+ * is described in 
+ * <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-14.txt">
+ * <B>draft-ietf-mmusic-ice-14.txt</B></A> draft. The PJNATH ICE
+ * implementation is aimed to provide a usable and generic ICE transports
+ * for different types of application, including but not limited to
+ * the usage of ICE in SIP/SDP offer/answer.
+ * 
+ * \subsection PJNATH_ICE_ARCH ICE Library Organization
+ * 
+ * The ICE library is organized as follows:
+ *
+ *  - the lowest layer is \ref PJNATH_ICE_SESSION, which provides 
+ *    ICE management and negotiation in a transport-independent way.
+ *    This layer contains the state machines to perform ICE
+ *    negotiation, and provides the most flexibility to control all
+ *    aspects of ICE session. This layer normally is only usable for
+ *    ICE implementors.
+ *
+ *  - higher in the hierarchy is \ref PJNATH_ICE_STREAM_TRANSPORT,
+ *    which binds ICE with UDP sockets, and provides STUN binding
+ *    and relay/TURN allocation for the sockets. This component can
+ *    be directly used by application, although normally application
+ *    should use the next higher abstraction below since it provides
+ *    SDP translations and better integration with other PJ libraries
+ *    such as PJSIP and PJMEDIA.
+ *
+ *  - the highest abstraction is ICE media transport, which maintains
+ *    ICE stream transport and provides SDP translations to be used
+ *    for SIP offer/answer exchanges.
+ */
+
+/**
+ * @defgroup PJNATH_STUN STUN Library
+ * @brief Open source STUN library
+ *
+ * This module contains implementation of STUN library in PJNATH -
+ * the open source NAT helper containing STUN and ICE.
  */
 
Index: pjproject/trunk/pjnath/src/pjnath/ice.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/ice.c	(revision 1109)
+++ pjproject/trunk/pjnath/src/pjnath/ice.c	(revision 1110)
@@ -534,9 +534,10 @@
     }
 
-    /* If there's no relayed candidate, find server reflexive candidate */
+    /* If there's no relayed candidate, find reflexive candidate */
     for (i=0; i<ice->lcand_cnt; ++i) {
 	pj_ice_cand *lcand = &ice->lcand[i];
 	if (lcand->comp_id==comp_id &&
-	    lcand->type == PJ_ICE_CAND_TYPE_SRFLX) 
+	    (lcand->type == PJ_ICE_CAND_TYPE_SRFLX ||
+	     lcand->type == PJ_ICE_CAND_TYPE_PRFLX)) 
 	{
 	    *cand_id = GET_LCAND_ID(lcand);
@@ -798,5 +799,7 @@
 
 	/* Call callback */
-	(*ice->cb.on_ice_complete)(ice, status);
+	if (ice->cb.on_ice_complete) {
+	    (*ice->cb.on_ice_complete)(ice, status);
+	}
     }
 }
Index: pjproject/trunk/pjnath/src/pjnath/ice_stream_transport.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/ice_stream_transport.c	(revision 1109)
+++ pjproject/trunk/pjnath/src/pjnath/ice_stream_transport.c	(revision 1110)
@@ -195,5 +195,5 @@
     PJ_ASSERT_RETURN(ice_st, PJ_EINVAL);
     /* Must not have pending resolver job */
-    PJ_ASSERT_RETURN(ice_st->has_resolver_job==PJ_FALSE, PJ_EINVALIDOP);
+    PJ_ASSERT_RETURN(ice_st->has_rjob==PJ_FALSE, PJ_EINVALIDOP);
 
     if (stun_srv) {
@@ -241,5 +241,5 @@
 
     PJ_ASSERT_RETURN(ice_st && comp && addr, PJ_EINVAL);
-    PJ_ASSERT_RETURN(comp->cand_cnt < PJ_ICE_ST_MAX_ALIASES, PJ_ETOOMANY);
+    PJ_ASSERT_RETURN(comp->cand_cnt < PJ_ICE_ST_MAX_CAND, PJ_ETOOMANY);
 
     cand = &comp->cand_list[comp->cand_cnt];
@@ -249,5 +249,5 @@
     cand->status = PJ_SUCCESS;
     pj_memcpy(&cand->addr, addr, sizeof(pj_sockaddr_in));
-    cand->cand_id = -1;
+    cand->ice_cand_id = -1;
     cand->local_pref = local_pref;
     cand->foundation = calc_foundation(ice_st->pool, type, &addr->sin_addr);
@@ -348,5 +348,5 @@
 	/* Socket is bound to INADDR_ANY */
 	unsigned i, ifs_cnt;
-	pj_in_addr ifs[PJ_ICE_ST_MAX_ALIASES-2];
+	pj_in_addr ifs[PJ_ICE_ST_MAX_CAND-2];
 
 	/* Reset default candidate */
@@ -474,5 +474,5 @@
 	    PJ_TODO(DISTINGUISH_BETWEEN_LOCAL_AND_RELAY);
 	    status = pj_ice_on_rx_pkt(ice_st->ice, comp->comp_id, 
-				      comp->cand_list[0].cand_id,
+				      comp->cand_list[0].ice_cand_id,
 				      comp->pkt, bytes_read,
 				      &comp->src_addr, comp->src_addr_len);
@@ -550,5 +550,5 @@
     
     /* Bail out if STUN server is still being resolved */
-    if (ice_st->has_resolver_job)
+    if (ice_st->has_rjob)
 	return PJ_EBUSY;
 
@@ -591,5 +591,5 @@
     cand->type = PJ_ICE_CAND_TYPE_SRFLX;
     cand->status = PJ_EPENDING;
-    cand->cand_id = -1;
+    cand->ice_cand_id = -1;
     cand->local_pref = 65535;
     cand->foundation = calc_foundation(ice_st->pool, PJ_ICE_CAND_TYPE_SRFLX,
@@ -626,5 +626,5 @@
     
     /* Can't add new component while resolver is running */
-    PJ_ASSERT_RETURN(ice_st->has_resolver_job == PJ_FALSE, PJ_EBUSY);
+    PJ_ASSERT_RETURN(ice_st->has_rjob == PJ_FALSE, PJ_EBUSY);
 
 
@@ -749,5 +749,5 @@
 				     &cand->addr, &comp->local_addr, NULL, 
 				     sizeof(pj_sockaddr_in), 
-				     (unsigned*)&cand->cand_id);
+				     (unsigned*)&cand->ice_cand_id);
 	    if (status != PJ_SUCCESS)
 		goto on_error;
@@ -828,5 +828,5 @@
 	unsigned j;
 	for (j=0; j<ice_st->comp[i]->cand_cnt; ++j) {
-	    ice_st->comp[i]->cand_list[j].cand_id = -1;
+	    ice_st->comp[i]->cand_list[j].ice_cand_id = -1;
 	}
     }
@@ -859,4 +859,11 @@
     }
 
+#if 1
+    PJ_UNUSED_ARG(pkt_size);
+    PJ_UNUSED_ARG(status);
+
+    /* Otherwise return error */
+    return PJNATH_EICEINPROGRESS;
+#else
     /* Otherwise send direcly with the socket */
     pkt_size = data_len;
@@ -866,4 +873,5 @@
     
     return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status;
+#endif
 }
 
