summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-03-27 23:29:27 +0000
committerBenny Prijono <bennylp@teluu.com>2007-03-27 23:29:27 +0000
commit047dad8b9f0e7ef5c92ce4e750bcfbb20d4c4796 (patch)
tree863809344d7f4f0577d2a237748bb806f1f89d77
parenteb531db72bd93280e47a6a03782da093eb8b2505 (diff)
Created doxygen documentation for PJNATH
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1110 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib/src/pj/ip_helper_win32.c9
-rw-r--r--pjnath/build/pjnath.dsp10
-rw-r--r--pjnath/docs/doxygen.cfg1047
-rw-r--r--pjnath/docs/doxygen.css305
-rw-r--r--pjnath/docs/footer.html11
-rw-r--r--pjnath/docs/header.html9
-rw-r--r--pjnath/include/pjnath/config.h109
-rw-r--r--pjnath/include/pjnath/errno.h6
-rw-r--r--pjnath/include/pjnath/ice.h478
-rw-r--r--pjnath/include/pjnath/ice_stream_transport.h468
-rw-r--r--pjnath/include/pjnath/stun_auth.h10
-rw-r--r--pjnath/include/pjnath/stun_doc.h100
-rw-r--r--pjnath/include/pjnath/stun_msg.h48
-rw-r--r--pjnath/include/pjnath/stun_session.h26
-rw-r--r--pjnath/include/pjnath/stun_transaction.h8
-rw-r--r--pjnath/include/pjnath/turn_client.h132
-rw-r--r--pjnath/include/pjnath/types.h151
-rw-r--r--pjnath/src/pjnath/ice.c9
-rw-r--r--pjnath/src/pjnath/ice_stream_transport.c28
19 files changed, 2546 insertions, 418 deletions
diff --git a/pjlib/src/pj/ip_helper_win32.c b/pjlib/src/pj/ip_helper_win32.c
index 094cfc9f..1dcff23d 100644
--- a/pjlib/src/pj/ip_helper_win32.c
+++ b/pjlib/src/pj/ip_helper_win32.c
@@ -62,12 +62,15 @@ PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt,
/* 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;
}
diff --git a/pjnath/build/pjnath.dsp b/pjnath/build/pjnath.dsp
index 4ea74abd..b700ba42 100644
--- a/pjnath/build/pjnath.dsp
+++ b/pjnath/build/pjnath.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /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"
BSC32=bscmake.exe
@@ -151,10 +151,6 @@ SOURCE=..\include\pjnath\stun_config.h
# End Source File
# Begin Source File
-SOURCE=..\include\pjnath\stun_doc.h
-# End Source File
-# Begin Source File
-
SOURCE=..\include\pjnath\stun_msg.h
# End Source File
# Begin Source File
@@ -167,10 +163,6 @@ SOURCE=..\include\pjnath\stun_transaction.h
# End Source File
# Begin Source File
-SOURCE=..\include\pjnath\turn_client.h
-# End Source File
-# Begin Source File
-
SOURCE=..\include\pjnath\types.h
# End Source File
# End Group
diff --git a/pjnath/docs/doxygen.cfg b/pjnath/docs/doxygen.cfg
new file mode 100644
index 00000000..b5ebfaa8
--- /dev/null
+++ b/pjnath/docs/doxygen.cfg
@@ -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 =
diff --git a/pjnath/docs/doxygen.css b/pjnath/docs/doxygen.css
new file mode 100644
index 00000000..015c0c27
--- /dev/null
+++ b/pjnath/docs/doxygen.css
@@ -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;
+}
diff --git a/pjnath/docs/footer.html b/pjnath/docs/footer.html
new file mode 100644
index 00000000..b2b7f567
--- /dev/null
+++ b/pjnath/docs/footer.html
@@ -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>
diff --git a/pjnath/docs/header.html b/pjnath/docs/header.html
new file mode 100644
index 00000000..7d890a62
--- /dev/null
+++ b/pjnath/docs/header.html
@@ -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>
+
+
diff --git a/pjnath/include/pjnath/config.h b/pjnath/include/pjnath/config.h
index fc3e004e..3bc5afaf 100644
--- a/pjnath/include/pjnath/config.h
+++ b/pjnath/include/pjnath/config.h
@@ -27,7 +27,7 @@
/**
* @defgroup PJNATH_CONFIG Configuration
- * @ingroup PJNATH
+ * @brief Various compile time settings
* @{
*/
@@ -36,28 +36,121 @@
*/
/**
- * Maximum number of attributes in the STUN packet (for the old STUN
+ * Maximum number of attributes in the STUN packet (for the new STUN
* library).
*
* Default: 16
*/
-#ifndef PJSTUN_MAX_ATTR
-# define PJSTUN_MAX_ATTR 16
+#ifndef PJ_STUN_MAX_ATTR
+# define PJ_STUN_MAX_ATTR 16
+#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
/**
- * Maximum number of attributes in the STUN packet (for the new STUN
- * library).
+ * 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_STUN_MAX_ATTR
-# define PJ_STUN_MAX_ATTR 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
+
+
+
+/**
* @}
*/
diff --git a/pjnath/include/pjnath/errno.h b/pjnath/include/pjnath/errno.h
index c5a2afa5..cb470747 100644
--- a/pjnath/include/pjnath/errno.h
+++ b/pjnath/include/pjnath/errno.h
@@ -19,12 +19,16 @@
#ifndef __PJNATH_ERRNO_H__
#define __PJNATH_ERRNO_H__
+/**
+ * @file errno.h
+ * @brief PJNATH specific error codes
+ */
#include <pj/errno.h>
/**
* @defgroup PJNATH_ERROR NAT Helper Library Error Codes
- * @ingroup PJNATH
+ * @brief PJNATH specific error code constants
* @{
*/
diff --git a/pjnath/include/pjnath/ice.h b/pjnath/include/pjnath/ice.h
index cc8b7918..02c05882 100644
--- a/pjnath/include/pjnath/ice.h
+++ b/pjnath/include/pjnath/ice.h
@@ -21,7 +21,7 @@
/**
* @file ice.h
- * @brief ICE.
+ * @brief ICE session management
*/
#include <pjnath/types.h>
#include <pjnath/stun_session.h>
@@ -31,7 +31,6 @@
/**
* @defgroup PJNATH_ICE Interactive Connectivity Establishment (ICE)
* @brief Interactive Connectivity Establishment (ICE)
- * @ingroup PJNATH
*/
@@ -39,10 +38,30 @@ PJ_BEGIN_DECL
/**
- * @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.
*/
/**
@@ -50,105 +69,318 @@ PJ_BEGIN_DECL
*/
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;
/**
* 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,
const void *pkt, pj_size_t size,
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,
const pj_sockaddr_t *src_addr,
@@ -156,59 +388,110 @@ typedef struct pj_ice_cb
} pj_ice_cb;
+/**
+ * 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];
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Object 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_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;
+ 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,
pj_ice_role role,
@@ -217,7 +500,34 @@ PJ_DECL(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
const pj_str_t *local_ufrag,
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,
pj_ice_cand_type type,
@@ -227,23 +537,101 @@ PJ_DECL(pj_status_t) pj_ice_add_cand(pj_ice *ice,
const pj_sockaddr_t *base_addr,
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,
const pj_str_t *rem_passwd,
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,
unsigned cand_id,
diff --git a/pjnath/include/pjnath/ice_stream_transport.h b/pjnath/include/pjnath/ice_stream_transport.h
index c42476b4..0403d841 100644
--- a/pjnath/include/pjnath/ice_stream_transport.h
+++ b/pjnath/include/pjnath/ice_stream_transport.h
@@ -21,8 +21,8 @@
/**
- * @file ice_mt.h
- * @brief ICE Media Transport.
+ * @file ice_stream_transport.h
+ * @brief ICE Stream Transport
*/
#include <pjnath/ice.h>
#include <pjlib-util/resolver.h>
@@ -37,114 +37,427 @@ PJ_BEGIN_DECL
* @brief Transport for media stream using ICE
* @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,
void *pkt, pj_size_t size,
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);
} pj_ice_st_cb;
-#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_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;
+ pj_stun_session *stun_sess; /**< STUN session. */
- pj_sockaddr local_addr;
+ pj_sockaddr local_addr; /**< Local/base address. */
- unsigned pending_cnt;
- pj_status_t last_status;
+ unsigned pending_cnt; /**< Pending resolution cnt. */
+ pj_status_t last_status; /**< Last status. */
- unsigned cand_cnt;
- pj_ice_st_cand cand_list[PJ_ICE_ST_MAX_ALIASES];
- int default_cand;
+ 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;
- 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_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;
+ 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;
+ pj_ice *ice; /**< ICE session. */
- unsigned comp_cnt;
- pj_ice_st_comp **comp;
+ unsigned comp_cnt; /**< Number of components. */
+ pj_ice_st_comp **comp; /**< Components array. */
- pj_dns_resolver *resolver;
- pj_bool_t has_resolver_job;
- pj_sockaddr_in stun_srv;
- pj_sockaddr_in turn_srv;
+ 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,
unsigned comp_cnt,
void *user_data,
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,
pj_ice_cand_type type,
@@ -152,22 +465,105 @@ PJ_DECL(pj_status_t) pj_ice_st_add_cand(pj_ice_st *ice_st,
const pj_sockaddr_in *addr,
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,
const pj_str_t *rem_passwd,
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,
const void *data,
diff --git a/pjnath/include/pjnath/stun_auth.h b/pjnath/include/pjnath/stun_auth.h
index 1a9f6a0c..6914036d 100644
--- a/pjnath/include/pjnath/stun_auth.h
+++ b/pjnath/include/pjnath/stun_auth.h
@@ -33,6 +33,7 @@ PJ_BEGIN_DECL
/* **************************************************************************/
/**
* @defgroup PJNATH_STUN_AUTH STUN Authentication
+ * @brief STUN authentication helper
* @ingroup PJNATH_STUN
* @{
*/
@@ -298,8 +299,15 @@ PJ_DECL(pj_status_t) pj_stun_verify_credential(const pj_uint8_t *pkt,
*/
-/* 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],
const pj_str_t *realm,
diff --git a/pjnath/include/pjnath/stun_doc.h b/pjnath/include/pjnath/stun_doc.h
deleted file mode 100644
index 7b5e6511..00000000
--- a/pjnath/include/pjnath/stun_doc.h
+++ /dev/null
@@ -1,100 +0,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__ */
-
diff --git a/pjnath/include/pjnath/stun_msg.h b/pjnath/include/pjnath/stun_msg.h
index 3362703c..a63fb7a0 100644
--- a/pjnath/include/pjnath/stun_msg.h
+++ b/pjnath/include/pjnath/stun_msg.h
@@ -41,54 +41,6 @@ PJ_BEGIN_DECL
/**
- * 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
-
-/**
* STUN magic cookie.
*/
#define PJ_STUN_MAGIC 0x2112A442
diff --git a/pjnath/include/pjnath/stun_session.h b/pjnath/include/pjnath/stun_session.h
index 18d07c0f..9f5a0d60 100644
--- a/pjnath/include/pjnath/stun_session.h
+++ b/pjnath/include/pjnath/stun_session.h
@@ -19,6 +19,11 @@
#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>
#include <pjnath/stun_auth.h>
#include <pjnath/stun_config.h>
@@ -187,6 +192,7 @@ PJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess);
* be retrieved later with pj_stun_session_get_user_data() function.
*
* @param sess The STUN session instance.
+ * @param user_data The user data.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
@@ -351,15 +357,17 @@ PJ_DECL(pj_status_t) pj_stun_session_cancel_req(pj_stun_session *sess,
* On successful message processing, application will be notified about
* the message via one of the pj_stun_session_cb callback.
*
- * @param sess The STUN session instance.
- * @param packet The packet containing STUN message.
- * @param pkt_size Size of the packet.
- * @param 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,
const void *packet,
diff --git a/pjnath/include/pjnath/stun_transaction.h b/pjnath/include/pjnath/stun_transaction.h
index 02b0af9e..f296c9f5 100644
--- a/pjnath/include/pjnath/stun_transaction.h
+++ b/pjnath/include/pjnath/stun_transaction.h
@@ -191,13 +191,7 @@ PJ_DECL(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx,
* with a final response later to allow the transaction to complete.
*
* @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.
*/
diff --git a/pjnath/include/pjnath/turn_client.h b/pjnath/include/pjnath/turn_client.h
deleted file mode 100644
index b9cfacc0..00000000
--- a/pjnath/include/pjnath/turn_client.h
+++ /dev/null
@@ -1,132 +0,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__ */
-
diff --git a/pjnath/include/pjnath/types.h b/pjnath/include/pjnath/types.h
index 0d9dc61c..bc47c9a2 100644
--- a/pjnath/include/pjnath/types.h
+++ b/pjnath/include/pjnath/types.h
@@ -28,7 +28,7 @@
#include <pjnath/config.h>
/**
- * @defgroup PJNATH NAT Helper Library
+ * @defgroup PJNATH NAT Traversal Helper Library
* @{
*/
@@ -51,17 +51,156 @@ PJ_END_DECL
/* Doxygen documentation below: */
/**
- * @mainpage NAT Helper Library
+ * @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
- * This is the documentation of PJNATH, an auxiliary library providing
- * NAT helper functionalities such as STUN and ICE.
+ *
+ * \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
*
- * Please go to the <A HREF="modules.htm"><B>Modules</B></A> page for list
- * of modules.
+ * 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.
*/
#endif /* __PJNATH_TYPES_H__ */
diff --git a/pjnath/src/pjnath/ice.c b/pjnath/src/pjnath/ice.c
index 3dc92646..4512bddc 100644
--- a/pjnath/src/pjnath/ice.c
+++ b/pjnath/src/pjnath/ice.c
@@ -533,11 +533,12 @@ PJ_DEF(pj_status_t) pj_ice_find_default_cand(pj_ice *ice,
}
}
- /* 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);
pj_mutex_unlock(ice->mutex);
@@ -797,7 +798,9 @@ static void on_ice_complete(pj_ice *ice, pj_status_t status)
dump_checklist("Valid list", ice, &ice->valid_list);
/* Call callback */
- (*ice->cb.on_ice_complete)(ice, status);
+ if (ice->cb.on_ice_complete) {
+ (*ice->cb.on_ice_complete)(ice, status);
+ }
}
}
diff --git a/pjnath/src/pjnath/ice_stream_transport.c b/pjnath/src/pjnath/ice_stream_transport.c
index f9748d25..911c1c8a 100644
--- a/pjnath/src/pjnath/ice_stream_transport.c
+++ b/pjnath/src/pjnath/ice_stream_transport.c
@@ -194,7 +194,7 @@ PJ_DEF(pj_status_t) pj_ice_st_set_stun_srv( pj_ice_st *ice_st,
{
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) {
pj_memcpy(&ice_st->stun_srv, stun_srv, sizeof(pj_sockaddr_in));
@@ -240,7 +240,7 @@ static pj_status_t add_cand( pj_ice_st *ice_st,
pj_ice_st_cand *cand;
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];
@@ -248,7 +248,7 @@ static pj_status_t add_cand( pj_ice_st *ice_st,
cand->type = type;
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);
@@ -347,7 +347,7 @@ static pj_status_t create_component(pj_ice_st *ice_st,
{
/* 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 */
comp->default_cand = -1;
@@ -473,7 +473,7 @@ static void on_read_complete(pj_ioqueue_key_t *key,
if (ice_st->ice) {
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);
} else if (comp->stun_sess) {
@@ -549,7 +549,7 @@ static pj_status_t get_stun_mapped_addr(pj_ice_st *ice_st,
PJ_ASSERT_RETURN(ice_st && comp, PJ_EINVAL);
/* Bail out if STUN server is still being resolved */
- if (ice_st->has_resolver_job)
+ if (ice_st->has_rjob)
return PJ_EBUSY;
/* Just return (successfully) if STUN server is not configured */
@@ -590,7 +590,7 @@ static pj_status_t get_stun_mapped_addr(pj_ice_st *ice_st,
/* Add new alias to this component */
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,
&comp->local_addr.ipv4.sin_addr);
@@ -625,7 +625,7 @@ PJ_DEF(pj_status_t) pj_ice_st_create_comp(pj_ice_st *ice_st,
PJ_ASSERT_RETURN(ice_st->ice == NULL, PJ_EBUSY);
/* 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);
/* Create component */
@@ -748,7 +748,7 @@ PJ_DEF(pj_status_t) pj_ice_st_init_ice(pj_ice_st *ice_st,
cand->local_pref, &cand->foundation,
&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;
}
@@ -827,7 +827,7 @@ PJ_DECL(pj_status_t) pj_ice_st_stop_ice(pj_ice_st *ice_st)
for (i=0; i<ice_st->comp_cnt; ++i) {
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;
}
}
@@ -858,6 +858,13 @@ PJ_DEF(pj_status_t) pj_ice_st_sendto( pj_ice_st *ice_st,
return pj_ice_send_data(ice_st->ice, comp_id, data, data_len);
}
+#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;
status = pj_ioqueue_sendto(comp->key, &comp->write_op,
@@ -865,6 +872,7 @@ PJ_DEF(pj_status_t) pj_ice_st_sendto( pj_ice_st *ice_st,
dst_addr, dst_addr_len);
return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status;
+#endif
}
/*