summaryrefslogtreecommitdiff
path: root/Protocols
diff options
context:
space:
mode:
Diffstat (limited to 'Protocols')
-rw-r--r--Protocols/SIP/SIPProto.cpp1015
-rw-r--r--Protocols/SIP/SIPProto.h109
-rw-r--r--Protocols/SIP/commons.h62
-rw-r--r--Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.libbin0 -> 10311026 bytes
-rw-r--r--Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug.libbin0 -> 10133706 bytes
-rw-r--r--Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Dynamic.libbin0 -> 3641098 bytes
-rw-r--r--Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.libbin0 -> 3598192 bytes
-rw-r--r--Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release.libbin0 -> 3635962 bytes
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util.h63
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/base64.h92
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/config.h263
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/crc32.h96
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns.h445
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns_server.h117
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/errno.h367
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/getopt.h146
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_md5.h109
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_sha1.h107
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/md5.h74
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/pcap.h196
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/resolver.h460
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner.h555
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h97
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_uint.h84
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/sha1.h80
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/srv_resolver.h215
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/string.h102
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/stun_simple.h208
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/types.h95
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/xml.h246
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/file.hpp188
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/hash.hpp156
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/list.hpp352
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/lock.hpp149
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/os.hpp870
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/pool.hpp279
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/proactor.hpp515
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/scanner.hpp246
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/sock.hpp444
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/string.hpp468
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/timer.hpp198
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/tree.hpp129
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj++/types.hpp175
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/activesock.h526
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/addr_resolv.h165
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/array.h96
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/assert.h95
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/assert.h44
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_armcc.h57
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_codew.h55
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcc.h75
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcce.h54
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_msvc.h84
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_mwcc.h55
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/ctype.h49
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/errno.h44
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/high_precision.h103
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_alpha.h36
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_armv4.h39
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_auto.h.in60
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_i386.h35
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_m68k.h35
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_powerpc.h36
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_sparc.h35
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_x86_64.h36
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/malloc.h34
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_auto.h.in191
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_darwinos.h145
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux.h129
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux_kernel.h149
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_palmos.h119
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_rtems.h139
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_sunos.h132
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_symbian.h162
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32.h139
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32_wince.h140
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/rand.h70
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/setjmp.h98
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/size_t.h32
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/socket.h231
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdarg.h32
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdfileio.h32
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/string.h144
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/time.h42
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/config.h1122
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site.h0
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site_sample.h345
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/ctype.h175
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/doxygen.h996
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/errno.h575
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/except.h421
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/fifobuf.h44
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/file_access.h109
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/file_io.h183
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/guid.h101
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/hash.h220
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/ioqueue.h805
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/ip_helper.h97
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/list.h273
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/list_i.h121
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/lock.h154
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/log.h402
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/math.h197
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/os.h1343
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/pool.h903
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_alt.h198
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_buf.h105
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_i.h94
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/rand.h66
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/rbtree.h210
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/sock.h1375
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_qos.h427
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_select.h152
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/ssl_sock.h874
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/string.h692
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/string_i.h371
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/timer.h276
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/types.h544
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pj/unicode.h141
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pjlib++.hpp35
-rw-r--r--Protocols/SIP/lib/pjsip/pjlib/include/pjlib.h63
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev.h667
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev_imp.h181
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiotest.h116
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/config.h394
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/errno.h198
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec.h39
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/amr_helper.h1222
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config.h316
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config_auto.h.in71
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g722.h74
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g7221.h128
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/gsm.h72
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ilbc.h76
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ipp_codecs.h73
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/l16.h69
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/passthrough.h106
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/speex.h121
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/types.h93
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia.h73
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/alaw_ulaw.h213
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/bidirectional.h67
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/circbuf.h435
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/clock.h208
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/codec.h879
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/conference.h511
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config.h833
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config_auto.h.in43
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/delaybuf.h158
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/doxygen.h174
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo.h247
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo_port.h74
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/endpoint.h177
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/errno.h631
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/g711.h70
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/jbuf.h314
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/master_port.h179
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/mem_port.h195
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/null_port.h70
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/plc.h115
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/port.h326
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/resample.h200
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp.h408
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp_xr.h467
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtp.h394
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp.h674
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp_neg.h674
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/session.h404
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/silencedet.h200
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound.h336
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound_port.h296
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/splitcomb.h140
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stereo.h206
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stream.h354
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/symbian_sound_aps.h48
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/tonegen.h293
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport.h820
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_adapter_sample.h73
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_ice.h194
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_loop.h82
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_srtp.h313
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_udp.h162
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/types.h533
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_playlist.h105
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_port.h250
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wave.h184
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wsola.h219
-rw-r--r--Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia_audiodev.h33
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath.h35
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/config.h476
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/errno.h221
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_session.h973
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_strans.h792
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/nat_detect.h208
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_auth.h457
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_config.h128
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_msg.h1820
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_session.h762
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_sock.h446
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_transaction.h276
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_session.h722
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_sock.h397
-rw-r--r--Protocols/SIP/lib/pjsip/pjnath/include/pjnath/types.h76
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/errno.h118
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub.h492
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub_msg.h119
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/iscomposing.h135
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/mwi.h208
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/pidf.h178
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/presence.h361
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/publish.h333
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/rpid.h149
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/types.h31
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/xpidf.h135
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_100rel.h245
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_inv.h875
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_regc.h373
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_replaces.h301
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_timer.h262
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_xfer.h208
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip.h60
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/print_util.h141
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth.h495
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_aka.h213
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_msg.h252
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_parser.h73
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_autoconf.h.in39
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_config.h924
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_dialog.h627
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_endpoint.h521
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_errno.h535
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_event.h230
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_module.h222
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_msg.h1988
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_parser.h412
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_private.h32
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_resolve.h291
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_tel_uri.h84
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transaction.h406
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport.h1193
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_loop.h147
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tcp.h210
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tls.h272
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_udp.h235
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_types.h257
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_ua_layer.h162
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_uri.h457
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_util.h861
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip_auth.h38
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip_simple.h46
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsip_ua.h32
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua.h4542
-rw-r--r--Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua_internal.h550
-rw-r--r--Protocols/SIP/resource.h16
-rw-r--r--Protocols/SIP/resource.rc52
-rw-r--r--Protocols/SIP/sip.cpp64
256 files changed, 74631 insertions, 185 deletions
diff --git a/Protocols/SIP/SIPProto.cpp b/Protocols/SIP/SIPProto.cpp
index 6485348..85e8515 100644
--- a/Protocols/SIP/SIPProto.cpp
+++ b/Protocols/SIP/SIPProto.cpp
@@ -109,9 +109,49 @@ private:
};
+static char * mir_pjstrdup(const pj_str_t *from)
+{
+ char *ret = (char *) mir_alloc(from->slen + 1);
+ strncpy(ret, from->ptr, from->slen);
+ ret[from->slen] = 0;
+ return ret;
+}
+
+
+static int FistGtZero(int n1, int n2)
+{
+ if (n1 > 0)
+ return n1;
+ return n2;
+}
+
+
+static TCHAR *CleanupSip(TCHAR *str)
+{
+ if (_tcsnicmp(_T("sip:"), str, 4) == 0)
+ return &str[4];
+ else
+ return str;
+}
+
+
+static const TCHAR *CleanupSip(const TCHAR *str)
+{
+ if (_tcsnicmp(_T("sip:"), str, 4) == 0)
+ return &str[4];
+ else
+ return str;
+}
+
+
+
+
+
SIPProto::SIPProto(const char *aProtoName, const TCHAR *aUserName)
{
- //hasToDestroy = false;
+ InitializeCriticalSection(&cs);
+
+ hasToDestroy = false;
transport_id = -1;
acc_id = -1;
hNetlibUser = 0;
@@ -124,7 +164,7 @@ SIPProto::SIPProto(const char *aProtoName, const TCHAR *aUserName)
static OptPageControl amCtrls[] = {
{ NULL, CONTROL_TEXT, IDC_HOST, "Host", NULL, 0, 0, 256 },
- { NULL, CONTROL_INT, IDC_PORT, "Port", 5060, 0, 1 },
+ { NULL, CONTROL_INT, IDC_PORT, "RegPort", 5060, 0, 1 },
{ NULL, CONTROL_TEXT, IDC_USERNAME, "Username", NULL, 0, 0, 16 },
{ NULL, CONTROL_PASSWORD, IDC_PASSWORD, "Password", NULL, IDC_SAVEPASSWORD, 0, 16 },
{ NULL, CONTROL_CHECKBOX, IDC_SAVEPASSWORD, "SavePassword", (BYTE) TRUE },
@@ -132,32 +172,65 @@ SIPProto::SIPProto(const char *aProtoName, const TCHAR *aUserName)
memmove(accountManagerCtrls, amCtrls, sizeof(accountManagerCtrls));
accountManagerCtrls[0].var = &opts.host;
- accountManagerCtrls[1].var = &opts.port;
+ accountManagerCtrls[1].var = &opts.reg.port;
accountManagerCtrls[2].var = &opts.username;
accountManagerCtrls[3].var = &opts.password;
accountManagerCtrls[4].var = &opts.savePassword;
static OptPageControl oCtrls[] = {
{ NULL, CONTROL_TEXT, IDC_HOST, "Host", NULL, 0, 0, 256 },
- { NULL, CONTROL_INT, IDC_PORT, "Port", 5060, 0, 1 },
{ NULL, CONTROL_TEXT, IDC_USERNAME, "Username", NULL, 0, 0, 16 },
{ NULL, CONTROL_PASSWORD, IDC_PASSWORD, "Password", NULL, IDC_SAVEPASSWORD, 0, 16 },
{ NULL, CONTROL_CHECKBOX, IDC_SAVEPASSWORD, "SavePassword", (BYTE) TRUE },
- { NULL, CONTROL_TEXT, IDC_STUN_HOST, "StunHost", _T("stun01.sipphone.com"), 0, 0, 256 },
- { NULL, CONTROL_INT, IDC_STUN_PORT, "StunPort", 0, 0, 1 },
+ { NULL, CONTROL_TEXT, IDC_REG_HOST, "RegHost", NULL, 0, 0, 256 },
+ { NULL, CONTROL_INT, IDC_REG_PORT, "RegPort", 5060, 0, 0 },
+ { NULL, CONTROL_TEXT, IDC_REALM, "Realm", NULL, 0, 0, 256 },
+ { NULL, CONTROL_TEXT, IDC_DNS_HOST, "DNSHost", NULL, 0, 0, 256 },
+ { NULL, CONTROL_INT, IDC_DNS_PORT, "DNSPort", 53, 0, 0 },
+ { NULL, CONTROL_TEXT, IDC_STUN_HOST, "STUNHost", (DWORD) _T("stun01.sipphone.com"), 0, 0, 256 },
+ { NULL, CONTROL_INT, IDC_STUN_PORT, "STUNPort", PJ_STUN_PORT, 0, 0 },
+ { NULL, CONTROL_TEXT, IDC_PROXY_HOST, "ProxyHost", NULL, 0, 0, 256 },
+ { NULL, CONTROL_INT, IDC_PROXY_PORT, "ProxyPort", 5060, 0, 0 },
+ { NULL, CONTROL_CHECKBOX, IDC_PUBLISH, "Publish", (BYTE) FALSE },
};
memmove(optionsCtrls, oCtrls, sizeof(optionsCtrls));
optionsCtrls[0].var = &opts.host;
- optionsCtrls[1].var = &opts.port;
- optionsCtrls[2].var = &opts.username;
- optionsCtrls[3].var = &opts.password;
- optionsCtrls[4].var = &opts.savePassword;
- optionsCtrls[5].var = &opts.stun.host;
- optionsCtrls[6].var = &opts.stun.port;
+ optionsCtrls[1].var = &opts.username;
+ optionsCtrls[2].var = &opts.password;
+ optionsCtrls[3].var = &opts.savePassword;
+ optionsCtrls[4].var = &opts.reg.host;
+ optionsCtrls[5].var = &opts.reg.port;
+ optionsCtrls[6].var = &opts.realm;
+ optionsCtrls[7].var = &opts.dns.host;
+ optionsCtrls[8].var = &opts.dns.port;
+ optionsCtrls[9].var = &opts.stun.host;
+ optionsCtrls[10].var = &opts.stun.port;
+ optionsCtrls[11].var = &opts.proxy.host;
+ optionsCtrls[12].var = &opts.proxy.port;
+ optionsCtrls[13].var = &opts.publish;
LoadOpts(optionsCtrls, MAX_REGS(optionsCtrls), m_szModuleName);
+ for(HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ hContact != NULL;
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0))
+ {
+ if (!IsMyContact(hContact))
+ continue;
+
+ DBDeleteContactSetting(hContact, m_szModuleName, "Status");
+ DBDeleteContactSetting(hContact, m_szModuleName, "ID");
+ }
+
+ char setting[256];
+ mir_snprintf(setting, MAX_REGS(setting), "%s/Status", m_szModuleName);
+ CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM) setting);
+
+ mir_snprintf(setting, sizeof(setting), "%s/ID", m_szModuleName);
+ CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM) setting);
+
+
CreateProtoService(PS_CREATEACCMGRUI, &SIPProto::CreateAccMgrUI);
CreateProtoService(PS_VOICE_CAPS, &SIPProto::VoiceCaps);
@@ -171,6 +244,7 @@ SIPProto::SIPProto(const char *aProtoName, const TCHAR *aUserName)
hCallStateEvent = CreateProtoEvent(PE_VOICE_CALL_STATE);
HookProtoEvent(ME_OPT_INITIALISE, &SIPProto::OnOptionsInit);
+ HookProtoEvent(ME_DB_CONTACT_DELETED, &SIPProto::OnContactDeleted);
}
@@ -181,6 +255,15 @@ SIPProto::~SIPProto()
mir_free(m_tszUserName);
mir_free(m_szProtoName);
mir_free(m_szModuleName);
+
+ DeleteCriticalSection(&cs);
+}
+
+
+bool SIPProto::IsMyContact(HANDLE hContact)
+{
+ char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ return proto != NULL && strcmp(m_szModuleName, proto) == 0;
}
@@ -189,20 +272,21 @@ DWORD_PTR __cdecl SIPProto::GetCaps( int type, HANDLE hContact )
switch(type)
{
case PFLAGNUM_1:
- return 0;
+ return PF1_MODEMSG | PF1_IM | PF1_AUTHREQ | PF1_BASICSEARCH | PF1_ADDSEARCHRES;
case PFLAGNUM_2:
return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND
| PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_INVISIBLE | PF2_IDLE;
case PFLAGNUM_3:
- return 0;
+ return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND
+ | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_INVISIBLE | PF2_IDLE;
case PFLAGNUM_4:
- return PF4_NOCUSTOMAUTH;
+ return PF4_SUPPORTTYPING | PF4_FORCEADDED | PF4_NOCUSTOMAUTH;
case PFLAG_UNIQUEIDTEXT:
- return (UINT_PTR) Translate("User");
+ return (UINT_PTR) Translate("Username");
case PFLAG_UNIQUEIDSETTING:
return (UINT_PTR) "Username";
@@ -215,33 +299,356 @@ DWORD_PTR __cdecl SIPProto::GetCaps( int type, HANDLE hContact )
}
+static void CALLBACK ProcessEvents(void *param)
+{
+ for(int i = 0; i < instances.getCount(); ++i)
+ {
+ SIPProto *proto = &instances[i];
+
+ EnterCriticalSection(&proto->cs);
+
+ std::vector<SIPEvent> events(proto->events);
+ proto->events.clear();
+
+ LeaveCriticalSection(&proto->cs);
+
+ if (proto->m_iStatus == ID_STATUS_OFFLINE)
+ continue;
+
+ for(unsigned int i = 0; i < events.size(); ++i)
+ {
+ SIPEvent &ev = events[i];
+ switch(ev.type)
+ {
+ case SIPEvent::reg_state:
+ proto->on_reg_state();
+ break;
+ case SIPEvent::incoming_call:
+ proto->on_incoming_call(ev.call_id);
+ break;
+ case SIPEvent::call_state:
+ proto->on_call_state(ev.call_id, ev.call_info);
+ break;
+ case SIPEvent::call_media_state:
+ proto->on_call_media_state(ev.call_id);
+ break;
+ case SIPEvent::incoming_subscribe:
+ proto->on_incoming_subscribe(ev.from, ev.text);
+ break;
+ case SIPEvent::buddy_state:
+ proto->on_buddy_state(ev.buddy_id);
+ break;
+ case SIPEvent::pager:
+ proto->on_pager(ev.from, ev.text, ev.mime);
+ break;
+ case SIPEvent::typing:
+ proto->on_typing(ev.from, ev.isTyping);
+ break;
+ }
+ mir_free(ev.from);
+ mir_free(ev.text);
+ mir_free(ev.mime);
+ }
+ }
+}
+
+
+static void static_on_reg_state(pjsua_acc_id acc_id)
+{
+ SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(acc_id);
+ if (proto == NULL)
+ return;
+
+ SIPEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = SIPEvent::reg_state;
+
+ EnterCriticalSection(&proto->cs);
+ proto->events.push_back(ev);
+ LeaveCriticalSection(&proto->cs);
+
+ CallFunctionAsync(&ProcessEvents, NULL);
+}
+
+
+static void static_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata)
+{
+ pjsua_call_info info;
+ pj_status_t status = pjsua_call_get_info(call_id, &info);
+ if (status != PJ_SUCCESS)
+ return;
+
+ SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(acc_id);
+ if (proto == NULL)
+ return;
+
+ SIPEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = SIPEvent::incoming_call;
+ ev.call_id = call_id;
+ ev.call_info = info;
+
+ EnterCriticalSection(&proto->cs);
+ proto->events.push_back(ev);
+ LeaveCriticalSection(&proto->cs);
+
+ CallFunctionAsync(&ProcessEvents, NULL);
+}
+
+
+static void static_on_call_state(pjsua_call_id call_id, pjsip_event *e)
+{
+ pjsua_call_info info;
+ pj_status_t status = pjsua_call_get_info(call_id, &info);
+ if (status != PJ_SUCCESS)
+ return;
+
+ SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(info.acc_id);
+ if (proto == NULL)
+ return;
+
+ SIPEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = SIPEvent::call_state;
+ ev.call_id = call_id;
+ ev.call_info = info;
+
+ EnterCriticalSection(&proto->cs);
+ proto->events.push_back(ev);
+ LeaveCriticalSection(&proto->cs);
+
+ CallFunctionAsync(&ProcessEvents, NULL);
+}
+
+
+static void static_on_call_media_state(pjsua_call_id call_id)
+{
+ pjsua_call_info info;
+ pj_status_t status = pjsua_call_get_info(call_id, &info);
+ if (status != PJ_SUCCESS)
+ return;
+
+ SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(info.acc_id);
+ if (proto == NULL)
+ return;
+
+ if (!proto->on_call_media_state_sync(call_id, info))
+ return;
+
+ SIPEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = SIPEvent::call_media_state;
+ ev.call_id = call_id;
+ ev.call_info = info;
+
+ EnterCriticalSection(&proto->cs);
+ proto->events.push_back(ev);
+ LeaveCriticalSection(&proto->cs);
+
+ CallFunctionAsync(&ProcessEvents, NULL);
+}
+
+
+// Handler for incoming presence subscription request
+static void static_on_incoming_subscribe(pjsua_acc_id acc_id, pjsua_srv_pres *srv_pres,
+ pjsua_buddy_id buddy_id, const pj_str_t *from,
+ pjsip_rx_data *rdata, pjsip_status_code *code,
+ pj_str_t *reason, pjsua_msg_data *msg_data)
+{
+ SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(acc_id);
+ if (proto == NULL)
+ return;
+
+ if (!proto->on_incoming_subscribe_sync(srv_pres, buddy_id, from, rdata, code, reason, msg_data))
+ return;
+
+ SIPEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = SIPEvent::incoming_subscribe;
+ ev.buddy_id = buddy_id;
+ ev.from = mir_pjstrdup(from);
+ ev.text = mir_pjstrdup(reason);
+
+ EnterCriticalSection(&proto->cs);
+ proto->events.push_back(ev);
+ LeaveCriticalSection(&proto->cs);
+
+ CallFunctionAsync(&ProcessEvents, NULL);
+}
+
+
+// Handler on buddy state changed.
+static void static_on_buddy_state(pjsua_buddy_id buddy_id)
+{
+ pjsua_buddy_info info;
+ pj_status_t status = pjsua_buddy_get_info(buddy_id, &info);
+ if (status != PJ_SUCCESS)
+ return;
+
+ HANDLE hContact = (HANDLE) pjsua_buddy_get_user_data(buddy_id);
+ if (hContact == NULL)
+ return;
+
+ SIPProto *proto = NULL;
+ for(int i = 0; i < instances.getCount(); ++i)
+ {
+ SIPProto *candidate = &instances[i];
+ if (candidate->IsMyContact(hContact))
+ {
+ proto = candidate;
+ break;
+ }
+ }
+
+ if (proto == NULL)
+ return;
+
+ SIPEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = SIPEvent::buddy_state;
+ ev.buddy_id = buddy_id;
+
+ EnterCriticalSection(&proto->cs);
+ proto->events.push_back(ev);
+ LeaveCriticalSection(&proto->cs);
+
+ CallFunctionAsync(&ProcessEvents, NULL);
+}
+
+
+static SIPProto * FindProto(const TCHAR *uri)
+{
+ for(int i = 0; i < instances.getCount(); ++i)
+ {
+ SIPProto *proto = &instances[i];
+
+ TCHAR tmp[1024];
+ mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s@%s"),
+ CleanupSip(proto->opts.username), proto->opts.host);
+
+ if (lstrcmpi(uri, tmp) == 0)
+ return proto;
+ }
+
+ return NULL;
+}
+
+
+// Incoming IM message (i.e. MESSAGE request)!
+static void static_on_pager(pjsua_call_id call_id, const pj_str_t *from,
+ const pj_str_t *to, const pj_str_t *contact,
+ const pj_str_t *mime_type, const pj_str_t *text,
+ pjsip_rx_data *rdata, pjsua_acc_id acc_id)
+{
+ SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(acc_id);
+ if (proto == NULL)
+ return;
+
+ SIPEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = SIPEvent::pager;
+ ev.from = mir_pjstrdup(from);
+ ev.text = mir_pjstrdup(text);
+ ev.mime = mir_pjstrdup(mime_type);
+
+ EnterCriticalSection(&proto->cs);
+ proto->events.push_back(ev);
+ LeaveCriticalSection(&proto->cs);
+
+ CallFunctionAsync(&ProcessEvents, NULL);
+}
+
+
+// Received typing indication
+static void static_on_typing(pjsua_call_id call_id, const pj_str_t *from,
+ const pj_str_t *to, const pj_str_t *contact,
+ pj_bool_t is_typing, pjsip_rx_data *rdata,
+ pjsua_acc_id acc_id)
+{
+ SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(acc_id);
+ if (proto == NULL)
+ return;
+
+ SIPEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = SIPEvent::typing;
+ ev.from = mir_pjstrdup(from);
+ ev.isTyping = (is_typing != PJ_FALSE);
+
+ EnterCriticalSection(&proto->cs);
+ proto->events.push_back(ev);
+ LeaveCriticalSection(&proto->cs);
+
+ CallFunctionAsync(&ProcessEvents, NULL);
+}
+
+
+static void static_on_log(int level, const char *data, int len)
+{
+ char tmp[1024];
+ mir_snprintf(tmp, MAX_REGS(tmp), "Level %d : %*s", level, len, data);
+ OutputDebugStringA(tmp);
+}
+
+
int SIPProto::Connect()
{
Trace(_T("Connecting..."));
BroadcastStatus(ID_STATUS_CONNECTING);
-/*
+
{
pj_status_t status = pjsua_create();
if (status != PJ_SUCCESS)
{
- Error(status, _T("Error creating pjsua!"));
+ Error(status, _T("Error creating pjsua"));
return -1;
}
hasToDestroy = true;
}
{
+ scoped_mir_free<char> stun;
+ scoped_mir_free<char> dns;
+
pjsua_config cfg;
pjsua_config_default(&cfg);
cfg.cb.on_incoming_call = &static_on_incoming_call;
cfg.cb.on_call_media_state = &static_on_call_media_state;
cfg.cb.on_call_state = &static_on_call_state;
cfg.cb.on_reg_state = &static_on_reg_state;
+ cfg.cb.on_incoming_subscribe = &static_on_incoming_subscribe;
+ cfg.cb.on_buddy_state = &static_on_buddy_state;
+ cfg.cb.on_pager2 = &static_on_pager;
+ cfg.cb.on_typing2 = &static_on_typing;
+
+
+ if (!IsEmpty(opts.stun.host))
+ {
+ TCHAR tmp[1024];
+ mir_sntprintf(tmp, MAX_REGS(tmp), _T("%s:%d"),
+ CleanupSip(opts.stun.host),
+ FistGtZero(opts.stun.port, PJ_STUN_PORT));
+ stun = TcharToUtf8(tmp).detach();
+
+ cfg.stun_srv_cnt = 1;
+ cfg.stun_srv[0] = pj_str(stun);
+ }
+
+ if (!IsEmpty(opts.dns.host))
+ {
+ TCHAR tmp[1024];
+ mir_sntprintf(tmp, MAX_REGS(tmp), _T("%s:%d"),
+ CleanupSip(opts.dns.host),
+ FistGtZero(opts.dns.port, 53));
+ dns = TcharToUtf8(tmp).detach();
+
+ cfg.nameserver_count = 1;
+ cfg.nameserver[0] = pj_str(dns);
+ }
pjsua_logging_config log_cfg;
pjsua_logging_config_default(&log_cfg);
- log_cfg.console_level = 4;
log_cfg.cb = &static_on_log;
pj_status_t status = pjsua_init(&cfg, &log_cfg, NULL);
@@ -252,7 +659,7 @@ int SIPProto::Connect()
return 1;
}
}
-*/
+
{
pjsua_transport_config cfg;
pjsua_transport_config_default(&cfg);
@@ -264,7 +671,7 @@ int SIPProto::Connect()
return 2;
}
}
-/*
+
{
pj_status_t status = pjsua_start();
if (status != PJ_SUCCESS)
@@ -274,27 +681,42 @@ int SIPProto::Connect()
return 3;
}
}
-*/
+
{
+ scoped_mir_free<char> proxy;
TCHAR tmp[1024];
pjsua_acc_config cfg;
pjsua_acc_config_default(&cfg);
cfg.user_data = this;
- cfg.transport_id = transport_id;
+ //cfg.transport_id = transport_id;
- mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s@%s"), opts.username, opts.host);
+ mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s@%s"), CleanupSip(opts.username), opts.host);
TcharToUtf8 id(tmp);
cfg.id = pj_str(id);
- mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s:%d"), opts.host, opts.port);
+ mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s:%d"),
+ CleanupSip(FirstNotEmpty(opts.reg.host, opts.host)),
+ FistGtZero(opts.reg.port, 5060));
TcharToUtf8 reg_uri(tmp);
cfg.reg_uri = pj_str(reg_uri);
- cfg.publish_enabled = PJ_TRUE;
+ if (!IsEmpty(opts.proxy.host))
+ {
+ mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s:%d"),
+ CleanupSip(opts.proxy.host),
+ FistGtZero(opts.proxy.port, 5060));
+ proxy = TcharToUtf8(tmp).detach();
+
+ cfg.proxy_cnt = 1;
+ cfg.proxy[0] = pj_str(proxy);
+ }
+
+ cfg.publish_enabled = (opts.publish ? PJ_TRUE : PJ_FALSE);
cfg.cred_count = 1;
- TcharToUtf8 host(opts.host);
+
+ TcharToUtf8 host(CleanupSip(FirstNotEmpty(opts.realm, opts.host)));
cfg.cred_info[0].realm = pj_str(host);
cfg.cred_info[0].scheme = pj_str("digest");
TcharToUtf8 username(opts.username);
@@ -311,6 +733,43 @@ int SIPProto::Connect()
}
}
+ // Add contacts to buddy list
+ for(HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ hContact != NULL;
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0))
+ {
+ if (!IsMyContact(hContact))
+ continue;
+
+ DBTString uri(hContact, m_szModuleName, "URI");
+ if (uri == NULL)
+ {
+ Error(_T("Contact %d has no URI!"), hContact);
+ continue;
+ }
+
+ TcharToUtf8 sip_uri(uri);
+
+ pjsua_buddy_config buddy_cfg;
+ pjsua_buddy_config_default(&buddy_cfg);
+
+ buddy_cfg.uri = pj_str(sip_uri);
+ buddy_cfg.subscribe = PJ_FALSE;
+ buddy_cfg.user_data = hContact;
+
+ pjsua_buddy_id buddy_id;
+ pj_status_t status = pjsua_buddy_add(&buddy_cfg, &buddy_id);
+ if (status != PJ_SUCCESS)
+ {
+ Error(status, _T("Error adding buddy '%s'"), uri);
+ continue;
+ }
+
+ Attach(hContact, buddy_id);
+
+ pjsua_buddy_subscribe_pres(buddy_id, PJ_TRUE);
+ }
+
return 0;
}
@@ -356,7 +815,7 @@ void SIPProto::BroadcastStatus(int newStatus)
}
-void SIPProto::CreateProtoService(const char* szService, SIPServiceFunc serviceProc)
+void SIPProto::CreateProtoService(const char *szService, SIPServiceFunc serviceProc)
{
char str[MAXMODULELABELLENGTH];
@@ -365,7 +824,7 @@ void SIPProto::CreateProtoService(const char* szService, SIPServiceFunc serviceP
}
-void SIPProto::CreateProtoService(const char* szService, SIPServiceFuncParam serviceProc, LPARAM lParam)
+void SIPProto::CreateProtoService(const char *szService, SIPServiceFuncParam serviceProc, LPARAM lParam)
{
char str[MAXMODULELABELLENGTH];
mir_snprintf(str, sizeof(str), "%s%s", m_szModuleName, szService);
@@ -373,7 +832,7 @@ void SIPProto::CreateProtoService(const char* szService, SIPServiceFuncParam ser
}
-HANDLE SIPProto::CreateProtoEvent(const char* szService)
+HANDLE SIPProto::CreateProtoEvent(const char *szService)
{
char str[MAXMODULELABELLENGTH];
mir_snprintf(str, sizeof(str), "%s%s", m_szModuleName, szService);
@@ -381,12 +840,19 @@ HANDLE SIPProto::CreateProtoEvent(const char* szService)
}
-void SIPProto::HookProtoEvent(const char* szEvent, SIPEventFunc pFunc)
+void SIPProto::HookProtoEvent(const char *szEvent, SIPEventFunc pFunc)
{
::HookEventObj(szEvent, (MIRANDAHOOKOBJ)*(void**)&pFunc, this);
}
+void SIPProto::ForkThread(SipThreadFunc pFunc, void* param)
+{
+ UINT threadID;
+ CloseHandle((HANDLE)mir_forkthreadowner((pThreadFuncOwner)*(void**)&pFunc, this, param, &threadID));
+}
+
+
int SIPProto::SendBroadcast(HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam)
{
@@ -479,6 +945,10 @@ void SIPProto::Disconnect()
{
Trace(_T("Disconnecting..."));
+ EnterCriticalSection(&cs);
+ events.clear();
+ LeaveCriticalSection(&cs);
+
if (acc_id >= 0)
{
SendPresence(ID_STATUS_OFFLINE);
@@ -491,13 +961,13 @@ void SIPProto::Disconnect()
pjsua_transport_close(transport_id, PJ_FALSE);
transport_id = -1;
}
-/*
+
if (hasToDestroy)
{
pjsua_destroy();
hasToDestroy = false;
}
-*/
+
BroadcastStatus(ID_STATUS_OFFLINE);
}
@@ -650,13 +1120,6 @@ bool SIPProto::SendPresence(int proto_status)
}
-void CALLBACK SIPProto::DisconnectProto(void *param)
-{
- SIPProto *proto = (SIPProto *) param;
- proto->Disconnect();
-}
-
-
void SIPProto::on_reg_state()
{
Trace(_T("on_reg_state"));
@@ -665,10 +1128,12 @@ void SIPProto::on_reg_state()
pj_status_t status = pjsua_acc_get_info(acc_id, &info);
if (status != PJ_SUCCESS)
{
- Error(status, _T("Error obtaining call info"));
+ Error(status, _T("Error obtaining account info"));
return;
}
+ Trace(_T("on_reg_state : info.status = %d"), info.status);
+
if (info.status == PJSIP_SC_OK)
{
int status = (m_iDesiredStatus > ID_STATUS_OFFLINE ? m_iDesiredStatus : ID_STATUS_ONLINE);
@@ -677,7 +1142,7 @@ void SIPProto::on_reg_state()
}
else
{
- CallFunctionAsync(&SIPProto::DisconnectProto, this);
+ Disconnect();
}
}
@@ -691,7 +1156,7 @@ static void RemoveLtGt(TCHAR *str)
}
}
-void SIPProto::on_incoming_call(pjsua_call_id call_id, pjsip_rx_data *rdata)
+void SIPProto::on_incoming_call(pjsua_call_id call_id)
{
Trace(_T("on_incoming_call: %d"), call_id);
@@ -703,9 +1168,9 @@ void SIPProto::on_incoming_call(pjsua_call_id call_id, pjsip_rx_data *rdata)
return;
}
- TCHAR numberBuff[1024];
- lstrcpyn(numberBuff, SipToTchar(info.remote_contact), MAX_REGS(numberBuff));
- RemoveLtGt(numberBuff);
+ TCHAR number[1024];
+ lstrcpyn(number, SipToTchar(info.remote_contact), MAX_REGS(number));
+ RemoveLtGt(number);
TCHAR name[256];
name[0] = 0;
@@ -716,44 +1181,26 @@ void SIPProto::on_incoming_call(pjsua_call_id call_id, pjsip_rx_data *rdata)
if (other != NULL)
{
lstrcpyn(name, &remote_info[1], min(MAX_REGS(name), other - remote_info));
- if (IsEmpty(numberBuff))
+ if (IsEmpty(number))
{
- lstrcpyn(numberBuff, other+2, MAX_REGS(numberBuff));
- RemoveLtGt(numberBuff);
+ lstrcpyn(number, other+2, MAX_REGS(number));
+ RemoveLtGt(number);
}
}
}
- if (IsEmpty(name) && IsEmpty(numberBuff))
- lstrcpyn(numberBuff, remote_info, MAX_REGS(numberBuff));
-
- TCHAR *number = numberBuff;
-
- if (_tcsnicmp(_T("sip:"), number, 4) == 0)
- {
- number += 4;
-
- TCHAR *host = _tcschr(number, _T('@'));
- if (host != NULL && _tcsicmp(opts.host, host+1) == 0)
- *host = 0;
- }
+ if (IsEmpty(name) && IsEmpty(number))
+ lstrcpyn(number, remote_info, MAX_REGS(number));
+ else
+ CleanupURI(number, MAX_REGS(number), number);
NotifyCall(call_id, VOICE_STATE_RINGING, NULL, name, number);
}
-void SIPProto::on_call_state(pjsua_call_id call_id, pjsip_event *e)
+void SIPProto::on_call_state(pjsua_call_id call_id, const pjsua_call_info &info)
{
Trace(_T("on_call_state: %d"), call_id);
-
- pjsua_call_info info;
- pj_status_t status = pjsua_call_get_info(call_id, &info);
- if (status != PJ_SUCCESS)
- {
- Error(status, _T("Error obtaining call info"));
- return;
- }
-
Trace(_T("Call info: %d / last: %d %s"), info.state, info.last_status, info.last_status_text);
switch(info.state)
@@ -774,17 +1221,9 @@ void SIPProto::on_call_state(pjsua_call_id call_id, pjsip_event *e)
}
-void SIPProto::on_call_media_state(pjsua_call_id call_id)
+bool SIPProto::on_call_media_state_sync(pjsua_call_id call_id, const pjsua_call_info &info)
{
- Trace(_T("on_call_media_state: %d"), call_id);
-
- pjsua_call_info info;
- pj_status_t status = pjsua_call_get_info(call_id, &info);
- if (status != PJ_SUCCESS)
- {
- Error(status, _T("Error obtaining call info"));
- return;
- }
+ Trace(_T("on_call_media_state_sync: %d"), call_id);
// Connect ports appropriately when media status is ACTIVE or REMOTE HOLD,
// otherwise we should NOT connect the ports.
@@ -796,6 +1235,22 @@ void SIPProto::on_call_media_state(pjsua_call_id call_id)
pjsua_conf_connect(0, info.conf_slot);
}
+ return true;
+}
+
+
+void SIPProto::on_call_media_state(pjsua_call_id call_id)
+{
+ Trace(_T("on_call_media_state: %d"), call_id);
+
+ pjsua_call_info info;
+ pj_status_t status = pjsua_call_get_info(call_id, &info);
+ if (status != PJ_SUCCESS)
+ {
+ Error(status, _T("Error obtaining call info"));
+ return;
+ }
+
if (info.media_status == PJSUA_CALL_MEDIA_ACTIVE)
{
NotifyCall(call_id, VOICE_STATE_TALKING);
@@ -882,6 +1337,20 @@ static void CleanupNumber(TCHAR *out, int outSize, const TCHAR *number)
}
+void SIPProto::CleanupURI(TCHAR *out, int outSize, const TCHAR *url)
+{
+ lstrcpyn(out, CleanupSip(url), outSize);
+
+ TCHAR *phone = _tcsstr(out, _T(";user=phone"));
+ if (phone != NULL)
+ *phone = 0;
+
+ TCHAR *host = _tcschr(out, _T('@'));
+ if (host != NULL && _tcsicmp(opts.host, host+1) == 0)
+ *host = 0;
+}
+
+
void SIPProto::BuildURI(TCHAR *out, int outSize, const TCHAR *number, bool isTel)
{
bool hasSip = (_tcsnicmp(_T("sip:"), number, 4) == 0);
@@ -897,10 +1366,8 @@ void SIPProto::BuildURI(TCHAR *out, int outSize, const TCHAR *number, bool isTel
CleanupNumber(tmp, MAX_REGS(tmp), number);
mir_sntprintf(out, outSize, _T("sip:%s@%s"), tmp, opts.host);
}
- else if (!hasSip)
- mir_sntprintf(out, outSize, _T("sip:%s"), number);
else
- mir_sntprintf(out, outSize, _T("%s"), number);
+ mir_sntprintf(out, outSize, _T("sip:%s"), CleanupSip(number));
if (!hasPhone)
{
@@ -912,10 +1379,8 @@ void SIPProto::BuildURI(TCHAR *out, int outSize, const TCHAR *number, bool isTel
{
if (!hasSip && !hasHost)
mir_sntprintf(out, outSize, _T("sip:%s@%s"), number, opts.host);
- else if (!hasSip)
- mir_sntprintf(out, outSize, _T("sip:%s"), number);
else
- mir_sntprintf(out, outSize, _T("%s"), number);
+ mir_sntprintf(out, outSize, _T("sip:%s"), CleanupSip(number));
}
}
@@ -1099,8 +1564,382 @@ int __cdecl SIPProto::VoiceCallStringValid(WPARAM wParam, LPARAM lParam)
}
+// Buddy ////////////////////////////////////////////////////////////////////////////////
+
+
+HANDLE __cdecl SIPProto::SearchBasic(const char *id)
+{
+ if (m_iStatus <= ID_STATUS_OFFLINE)
+ return 0;
+
+ TCHAR tmp[1024];
+ BuildURI(tmp, MAX_REGS(tmp), CharToTchar(id), false);
+
+ TCHAR *uri = mir_tstrdup(tmp);
+ ForkThread(&SIPProto::SearchUserThread, uri);
+
+ return uri;
+}
+
+
+void __cdecl SIPProto::SearchUserThread(void *param)
+{
+ TCHAR *uri = (TCHAR *) param;
+
+ pj_thread_desc desc;
+ pj_thread_t *this_thread;
+ pj_status_t status = pj_thread_register("SearchUserThread", desc, &this_thread);
+ if (status != PJ_SUCCESS)
+ {
+ Error(status, _T("Error registering thread"));
+ return;
+ }
+
+ TcharToUtf8 sip_uri(uri);
+ if (pjsua_verify_sip_url(sip_uri) != PJ_SUCCESS)
+ {
+ Error(_T("Not a valid SIP URL: %s"), uri);
+ SendBroadcast(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, param, 0);
+ return;
+ }
+
+ if (pjsua_buddy_find(&pj_str(sip_uri)) != PJSUA_INVALID_ID)
+ {
+ Info(_T("Contact already in your contact list"));
+ SendBroadcast(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, param, 0);
+ return;
+ }
+
+ TCHAR name[1024];
+ CleanupURI(name, MAX_REGS(name), uri);
+ TcharToChar name_char(name);
+
+ PROTOSEARCHRESULT isr = {0};
+ isr.cbSize = sizeof(isr);
+ isr.nick = (char *) name_char.get();
+
+ SendBroadcast(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, param, (LPARAM)&isr);
+ SendBroadcast(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, param, 0);
+}
+
+
+HANDLE __cdecl SIPProto::AddToList(int flags, PROTOSEARCHRESULT *psr)
+{
+ if (m_iStatus <= ID_STATUS_OFFLINE)
+ return NULL;
+
+ TCHAR uri[1024];
+ BuildURI(uri, MAX_REGS(uri), CharToTchar(psr->nick), false);
+ TcharToUtf8 sip_uri(uri);
+
+ HANDLE hContact;
+ pjsua_buddy_id buddy_id = pjsua_buddy_find(&pj_str(sip_uri));
+ if (buddy_id != PJSUA_INVALID_ID)
+ {
+ // Already on list
+ hContact = GetContact(buddy_id);
+ }
+ else
+ {
+ // Add to list
+ pjsua_buddy_config buddy_cfg;
+ pjsua_buddy_config_default(&buddy_cfg);
+
+ buddy_cfg.uri = pj_str(sip_uri);
+ buddy_cfg.subscribe = PJ_FALSE;
+
+ pj_status_t status = pjsua_buddy_add(&buddy_cfg, &buddy_id);
+ if (status != PJ_SUCCESS)
+ {
+ Error(status, _T("Error adding buddy '%s'"), uri);
+ return NULL;
+ }
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0);
+ CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) m_szModuleName);
+
+ DBWriteContactSettingTString(hContact, m_szModuleName, "URI", uri);
+
+ TCHAR name[1024];
+ CleanupURI(name, MAX_REGS(name), uri);
+ DBWriteContactSettingTString(hContact, m_szModuleName, "Nick", name);
+
+ Attach(hContact, buddy_id);
+
+ pjsua_buddy_subscribe_pres(buddy_id, PJ_TRUE);
+ }
+
+ if (flags & PALF_TEMPORARY)
+ {
+ DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1);
+ DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);
+ }
+ else
+ {
+ DBDeleteContactSetting(hContact, "CList", "NotOnList");
+ DBDeleteContactSetting(hContact, "CList", "Hidden");
+ }
+
+ return hContact;
+}
+
+
+// Handler for incoming presence subscription request
+bool SIPProto::on_incoming_subscribe_sync(pjsua_srv_pres *srv_pres,
+ pjsua_buddy_id buddy_id,
+ const pj_str_t *from,
+ pjsip_rx_data *rdata,
+ pjsip_status_code *code,
+ pj_str_t *reason,
+ pjsua_msg_data *msg_data)
+{
+ // Just accept the request (the default behavior)
+ return true;
+}
+
+
+void SIPProto::on_incoming_subscribe(char *from, char *text)
+{
+}
+
+
+void SIPProto::on_buddy_state(pjsua_buddy_id buddy_id)
+{
+ HANDLE hContact = GetContact(buddy_id);
+ if (hContact == NULL)
+ return;
+
+ pjsua_buddy_info info;
+ pj_status_t status = pjsua_buddy_get_info(buddy_id, &info);
+ if (status != PJ_SUCCESS)
+ {
+ Error(status, _T("Error obtaining buddy info"));
+ DBWriteContactSettingWord(hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE);
+ return;
+ }
+
+ if (info.sub_state == PJSIP_EVSUB_STATE_NULL && info.sub_term_code == 404)
+ {
+ DBTString nick(hContact, m_szModuleName, "Nick");
+ Info(_T("User '%s' not found on the server!"), nick.get());
+ DBWriteContactSettingWord(hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE);
+ return;
+ }
+
+ if (info.sub_state != PJSIP_EVSUB_STATE_ACTIVE)
+ {
+ DBWriteContactSettingWord(hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE);
+ return;
+ }
+
+ // TODO info.rpid
+
+ switch(info.status)
+ {
+ case PJSUA_BUDDY_STATUS_ONLINE:
+ {
+ DBWriteContactSettingWord(hContact, m_szModuleName, "Status", ID_STATUS_ONLINE);
+ break;
+ }
+ case PJSUA_BUDDY_STATUS_OFFLINE:
+ {
+ DBWriteContactSettingWord(hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void SIPProto::on_pager(char *from, char *text, char *mime_type)
+{
+ // Ignore empty messages
+ if (strlen(text) < 1)
+ return;
+
+ pjsua_buddy_id buddy_id = pjsua_buddy_find(&pj_str(from));
+ if (buddy_id == PJSUA_INVALID_ID)
+ {
+ // TODO
+ return;
+ }
+
+ HANDLE hContact = GetContact(buddy_id);
+ if (hContact == NULL)
+ return;
+
+ if (strcmp("text/plain", mime_type) != 0)
+ {
+ Error(_T("Unknown mime type: %s"), Utf8ToTchar(mime_type));
+ return;
+ }
+
+ CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, 0);
+
+ PROTORECVEVENT pre;
+ pre.szMessage = (char*) text;
+ pre.flags = PREF_UTF;
+ pre.timestamp = (DWORD) time(NULL);
+ pre.lParam = 0;
+
+ CCSDATA ccs = {0};
+ ccs.hContact = hContact;
+ ccs.szProtoService = PSR_MESSAGE;
+ ccs.wParam = 0;
+ ccs.lParam = (LPARAM) &pre;
+ CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs);
+}
+
+
+int __cdecl SIPProto::SendMsg(HANDLE hContact, int flags, const char *msg)
+{
+ if (m_iStatus <= ID_STATUS_OFFLINE)
+ return 0;
+
+ pjsua_buddy_id buddy_id = GetBuddy(hContact);
+ if (buddy_id == PJSUA_INVALID_ID)
+ return 0;
+
+ pjsua_buddy_info info;
+ pj_status_t status = pjsua_buddy_get_info(buddy_id, &info);
+ if (status != PJ_SUCCESS)
+ {
+ Error(status, _T("Error obtaining buddy info"));
+ return 0;
+ }
+
+ scoped_mir_free<char> text;
+ if (flags & PREF_UNICODE)
+ {
+ const char* p = strchr(msg, '\0');
+ if (p != msg)
+ {
+ while (*(++p) == '\0') {}
+ text = mir_utf8encodeW((wchar_t *) p);
+ }
+ else
+ {
+ text = mir_strdup(msg);
+ }
+ }
+ else
+ {
+ text = (flags & PREF_UTF) ? mir_strdup(msg) : mir_utf8encode(msg);
+ }
+
+ // TODO Send to call
+
+ status = pjsua_im_send(acc_id, &info.uri, NULL, &pj_str(text), NULL, NULL);
+ if (status != PJ_SUCCESS)
+ {
+ Error(status, _T("Error sending message"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+void SIPProto::on_typing(char *from, bool isTyping)
+{
+ pjsua_buddy_id buddy_id = pjsua_buddy_find(&pj_str(from));
+ if (buddy_id == PJSUA_INVALID_ID)
+ return;
+
+ HANDLE hContact = GetContact(buddy_id);
+ if (hContact == NULL)
+ return;
+
+ CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, isTyping ? 10 : 0);
+}
+
+
+int __cdecl SIPProto::UserIsTyping(HANDLE hContact, int type)
+{
+ if (m_iStatus <= ID_STATUS_OFFLINE)
+ return 0;
+
+ pjsua_buddy_id buddy_id = GetBuddy(hContact);
+ if (buddy_id == PJSUA_INVALID_ID)
+ return 0;
+
+ pjsua_buddy_info info;
+ pj_status_t status = pjsua_buddy_get_info(buddy_id, &info);
+ if (status != PJ_SUCCESS)
+ {
+ Error(status, _T("Error obtaining buddy info"));
+ return 0;
+ }
+
+ // TODO Send to call
+
+ status = pjsua_im_typing(acc_id, &info.uri, type == PROTOTYPE_SELFTYPING_ON ? PJ_TRUE : PJ_FALSE, NULL);
+ if (status != PJ_SUCCESS)
+ {
+ Error(status, _T("Error sending typing notification"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+pjsua_buddy_id SIPProto::GetBuddy(HANDLE hContact)
+{
+ pjsua_buddy_id id =(pjsua_buddy_id) DBGetContactSettingDword(hContact, m_szModuleName, "ID", PJSUA_INVALID_ID);
+
+ if (id == PJSUA_INVALID_ID)
+ Error(_T("hContact has no buddy: %d"), hContact);
+
+ return id;
+}
+
+
+HANDLE SIPProto::GetContact(pjsua_buddy_id buddy_id)
+{
+ HANDLE hContact = (HANDLE) pjsua_buddy_get_user_data(buddy_id);
+
+ if (hContact == NULL)
+ Error(_T("Buddy has no hContact: %d"), buddy_id);
+
+ return hContact;
+}
+
+
+void SIPProto::Attach(HANDLE hContact, pjsua_buddy_id buddy_id)
+{
+ DBWriteContactSettingDword(hContact, m_szModuleName, "ID", (DWORD) buddy_id);
+ pjsua_buddy_set_user_data(buddy_id, hContact);
+}
+
+
+int __cdecl SIPProto::OnContactDeleted(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE) wParam;
+
+ if (acc_id < 0)
+ return 0;
+
+ if (!IsMyContact(hContact))
+ return 0;
+
+ Trace(_T("Deleted contact"));
+
+ pjsua_buddy_id buddy_id = GetBuddy(hContact);
+ if (buddy_id == PJSUA_INVALID_ID)
+ return 0;
+
+ pjsua_buddy_subscribe_pres(buddy_id, PJ_FALSE);
+ pjsua_buddy_del(buddy_id);
+
+ return 0;
+}
+// Dialog procs /////////////////////////////////////////////////////////////////////////
static INT_PTR CALLBACK DlgProcAccMgrUI(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
diff --git a/Protocols/SIP/SIPProto.h b/Protocols/SIP/SIPProto.h
index 24055a4..23e0cf9 100644
--- a/Protocols/SIP/SIPProto.h
+++ b/Protocols/SIP/SIPProto.h
@@ -22,40 +22,79 @@ Boston, MA 02111-1307, USA.
class SIPProto;
+typedef void (__cdecl SIPProto::*SipThreadFunc)(void*);
typedef INT_PTR (__cdecl SIPProto::*SIPServiceFunc)(WPARAM, LPARAM);
typedef INT_PTR (__cdecl SIPProto::*SIPServiceFuncParam)(WPARAM, LPARAM, LPARAM);
typedef int (__cdecl SIPProto::*SIPEventFunc)(WPARAM, LPARAM);
+struct SIPEvent
+{
+ enum {
+ reg_state,
+ incoming_call,
+ call_state,
+ call_media_state,
+ incoming_subscribe,
+ buddy_state,
+ pager,
+ typing
+
+ } type;
+
+ pjsua_call_id call_id;
+ pjsua_call_info call_info;
+ pjsua_buddy_id buddy_id;
+ char *from;
+ char *text;
+ char *mime;
+ bool isTyping;
+};
+
class SIPProto : public PROTO_INTERFACE
{
private:
HANDLE hNetlibUser;
HANDLE hCallStateEvent;
- //bool hasToDestroy;
+ bool hasToDestroy;
pjsua_transport_id transport_id;
pjsua_acc_id acc_id;
+public:
struct {
TCHAR host[256];
- int port;
+ TCHAR realm[256];
TCHAR username[16];
char password[16];
BYTE savePassword;
-
struct {
TCHAR host[256];
- TCHAR port;
+ int port;
+ } reg;
+ struct {
+ TCHAR host[256];
+ int port;
+ } dns;
+ struct {
+ TCHAR host[256];
+ int port;
} stun;
+ struct {
+ TCHAR host[256];
+ int port;
+ } proxy;
+ BYTE publish;
+ BYTE sendKeepAlive;
} opts;
-public:
+ CRITICAL_SECTION cs;
+ std::vector<SIPEvent> events;
OptPageControl accountManagerCtrls[5];
- OptPageControl optionsCtrls[7];
+ OptPageControl optionsCtrls[15];
SIPProto(const char *aProtoName, const TCHAR *aUserName);
virtual ~SIPProto();
- virtual HANDLE __cdecl AddToList( int flags, PROTOSEARCHRESULT* psr ) { return 0; }
+ virtual HANDLE __cdecl AddToList( int flags, PROTOSEARCHRESULT* psr );
virtual HANDLE __cdecl AddToListByEvent( int flags, int iContact, HANDLE hDbEvent ) { return 0; }
virtual int __cdecl Authorize( HANDLE hDbEvent ) { return 1; }
@@ -75,7 +114,7 @@ public:
virtual HICON __cdecl GetIcon( int iconIndex ) { return 0; }
virtual int __cdecl GetInfo( HANDLE hContact, int infoType ) { return 1; }
- virtual HANDLE __cdecl SearchBasic( const char* id ) { return 0; }
+ virtual HANDLE __cdecl SearchBasic( const char* id );
virtual HANDLE __cdecl SearchByEmail( const char* email ) { return 0; }
virtual HANDLE __cdecl SearchByName( const char* nick, const char* firstName, const char* lastName ) { return 0; }
virtual HWND __cdecl SearchAdvanced( HWND owner ) { return 0; }
@@ -88,7 +127,7 @@ public:
virtual int __cdecl SendContacts( HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList ) { return 1; }
virtual HANDLE __cdecl SendFile( HANDLE hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles ) { return 0; }
- virtual int __cdecl SendMsg( HANDLE hContact, int flags, const char* msg ) { return 1; }
+ virtual int __cdecl SendMsg( HANDLE hContact, int flags, const char* msg );
virtual int __cdecl SendUrl( HANDLE hContact, int flags, const char* url ) { return 1; }
virtual int __cdecl SetApparentMode( HANDLE hContact, int mode ) { return 1; }
@@ -100,26 +139,39 @@ public:
virtual int __cdecl SendAwayMsg( HANDLE hContact, HANDLE hProcess, const char* msg ) { return 1; }
virtual int __cdecl SetAwayMsg( int iStatus, const char* msg ) { return 1; }
- virtual int __cdecl UserIsTyping( HANDLE hContact, int type ) { return 0; }
+ virtual int __cdecl UserIsTyping( HANDLE hContact, int type );
virtual int __cdecl OnEvent( PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam );
void on_reg_state();
- void on_incoming_call(pjsua_call_id call_id, pjsip_rx_data *rdata);
- void on_call_state(pjsua_call_id call_id, pjsip_event *e);
+ void on_incoming_call(pjsua_call_id call_id);
+ void on_call_state(pjsua_call_id call_id, const pjsua_call_info &info);
+ bool on_call_media_state_sync(pjsua_call_id call_id, const pjsua_call_info &info);
void on_call_media_state(pjsua_call_id call_id);
+ bool on_incoming_subscribe_sync(pjsua_srv_pres *srv_pres, pjsua_buddy_id buddy_id,
+ const pj_str_t *from, pjsip_rx_data *rdata,
+ pjsip_status_code *code, pj_str_t *reason,
+ pjsua_msg_data *msg_data);
+ void on_incoming_subscribe(char *from, char *text);
+ void on_buddy_state(pjsua_buddy_id buddy_id);
+ void on_pager(char *from, char *text, char *mime_type);
+ void on_typing(char *from, bool isTyping);
+
+ bool IsMyContact(HANDLE hContact);
private:
void BroadcastStatus(int newStatus);
- void CreateProtoService(const char* szService, SIPServiceFunc serviceProc);
- void CreateProtoService(const char* szService, SIPServiceFuncParam serviceProc, LPARAM lParam);
- HANDLE CreateProtoEvent(const char* szService);
- void HookProtoEvent(const char* szEvent, SIPEventFunc pFunc);
+ void CreateProtoService(const char *szService, SIPServiceFunc serviceProc);
+ void CreateProtoService(const char *szService, SIPServiceFuncParam serviceProc, LPARAM lParam);
+ HANDLE CreateProtoEvent(const char *szService);
+ void HookProtoEvent(const char *szEvent, SIPEventFunc pFunc);
+ void ForkThread(SipThreadFunc pFunc, void *param = NULL);
int SendBroadcast(HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam);
int __cdecl OnModulesLoaded(WPARAM wParam, LPARAM lParam);
- int __cdecl OnOptionsInit(WPARAM wParam,LPARAM lParam);
- int __cdecl OnPreShutdown(WPARAM wParam,LPARAM lParam);
+ int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam);
+ int __cdecl OnPreShutdown(WPARAM wParam, LPARAM lParam);
+ int __cdecl OnContactDeleted(WPARAM wParam, LPARAM lParam);
void Trace(TCHAR *fmt, ...);
void Info(TCHAR *fmt, ...);
@@ -134,16 +186,23 @@ private:
void ConfigureDevices();
void BuildURI(TCHAR *out, int outSize, const TCHAR *number, bool isTel);
+ void CleanupURI(TCHAR *out, int outSize, const TCHAR *url);
// Voice services
void NotifyCall(pjsua_call_id call_id, int state, HANDLE hContact = NULL, TCHAR *name = NULL, TCHAR *number = NULL);
- int __cdecl VoiceCaps(WPARAM wParam,LPARAM lParam);
- int __cdecl VoiceCall(WPARAM wParam,LPARAM lParam);
- int __cdecl VoiceAnswerCall(WPARAM wParam,LPARAM lParam);
- int __cdecl VoiceDropCall(WPARAM wParam,LPARAM lParam);
- int __cdecl VoiceHoldCall(WPARAM wParam,LPARAM lParam);
- int __cdecl VoiceSendDTMF(WPARAM wParam,LPARAM lParam);
- int __cdecl VoiceCallStringValid(WPARAM wParam,LPARAM lParam);
+ int __cdecl VoiceCaps(WPARAM wParam, LPARAM lParam);
+ int __cdecl VoiceCall(WPARAM wParam, LPARAM lParam);
+ int __cdecl VoiceAnswerCall(WPARAM wParam, LPARAM lParam);
+ int __cdecl VoiceDropCall(WPARAM wParam, LPARAM lParam);
+ int __cdecl VoiceHoldCall(WPARAM wParam, LPARAM lParam);
+ int __cdecl VoiceSendDTMF(WPARAM wParam, LPARAM lParam);
+ int __cdecl VoiceCallStringValid(WPARAM wParam, LPARAM lParam);
+
+ // Buddy
+ void __cdecl SearchUserThread(void *param);
+ pjsua_buddy_id GetBuddy(HANDLE hContact);
+ HANDLE GetContact(pjsua_buddy_id buddy_id);
+ void Attach(HANDLE hContact, pjsua_buddy_id buddy_id);
// Static callbacks
static void CALLBACK DisconnectProto(void *param);
diff --git a/Protocols/SIP/commons.h b/Protocols/SIP/commons.h
index a310667..e881107 100644
--- a/Protocols/SIP/commons.h
+++ b/Protocols/SIP/commons.h
@@ -72,6 +72,7 @@ Boston, MA 02111-1307, USA.
#include "../../plugins/utils/mir_options.h"
#include "../../plugins/utils/mir_icons.h"
#include "../../plugins/utils/mir_log.h"
+#include "../../plugins/utils/mir_dbutils.h"
#include "../../plugins/utils/utf8_helpers.h"
#include "../../plugins/utils/scope.h"
#include "../../plugins/voiceservice/m_voice.h"
@@ -131,5 +132,66 @@ static BOOL IsEmptyW(const WCHAR *str)
# define IsEmpty IsEmptyA
#endif
+static char * FirstNotEmptyA(char *str1, char *str2)
+{
+ if (!IsEmptyA(str1))
+ return str1;
+ return str2;
+}
+
+static char * FirstNotEmptyA(char *str1, char *str2, char *str3)
+{
+ if (!IsEmptyA(str1))
+ return str1;
+ if (!IsEmptyA(str2))
+ return str2;
+ return str3;
+}
+
+static char * FirstNotEmptyA(char *str1, char *str2, char *str3, char *str4)
+{
+ if (!IsEmptyA(str1))
+ return str1;
+ if (!IsEmptyA(str2))
+ return str2;
+ if (!IsEmptyA(str3))
+ return str3;
+ return str4;
+}
+
+
+static WCHAR * FirstNotEmptyW(WCHAR *str1, WCHAR *str2)
+{
+ if (!IsEmptyW(str1))
+ return str1;
+ return str2;
+}
+
+static WCHAR * FirstNotEmptyW(WCHAR *str1, WCHAR *str2, WCHAR *str3)
+{
+ if (!IsEmptyW(str1))
+ return str1;
+ if (!IsEmptyW(str2))
+ return str2;
+ return str3;
+}
+
+static WCHAR * FirstNotEmptyW(WCHAR *str1, WCHAR *str2, WCHAR *str3, WCHAR *str4)
+{
+ if (!IsEmptyW(str1))
+ return str1;
+ if (!IsEmptyW(str2))
+ return str2;
+ if (!IsEmptyW(str3))
+ return str3;
+ return str4;
+}
+
+#ifdef UNICODE
+# define FirstNotEmpty FirstNotEmptyW
+#else
+# define FirstNotEmpty FirstNotEmptyA
+#endif
+
#endif // __COMMONS_H__
diff --git a/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.lib b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.lib
new file mode 100644
index 0000000..e768fbc
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.lib
Binary files differ
diff --git a/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug.lib b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug.lib
new file mode 100644
index 0000000..4a3da69
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug.lib
Binary files differ
diff --git a/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Dynamic.lib b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Dynamic.lib
new file mode 100644
index 0000000..116131c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Dynamic.lib
Binary files differ
diff --git a/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.lib b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.lib
new file mode 100644
index 0000000..f67178c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.lib
Binary files differ
diff --git a/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release.lib b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release.lib
new file mode 100644
index 0000000..2f77608
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release.lib
Binary files differ
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util.h
new file mode 100644
index 0000000..d62f72e
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util.h
@@ -0,0 +1,63 @@
+/* $Id: pjlib-util.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_H__
+#define __PJLIB_UTIL_H__
+
+/**
+ * @file pjlib-util.h
+ * @brief pjlib-util.h
+ */
+
+/* Base */
+#include <pjlib-util/errno.h>
+#include <pjlib-util/types.h>
+
+/* Getopt */
+#include <pjlib-util/getopt.h>
+
+/* Crypto */
+#include <pjlib-util/base64.h>
+#include <pjlib-util/crc32.h>
+#include <pjlib-util/hmac_md5.h>
+#include <pjlib-util/hmac_sha1.h>
+#include <pjlib-util/md5.h>
+#include <pjlib-util/sha1.h>
+
+/* DNS and resolver */
+#include <pjlib-util/dns.h>
+#include <pjlib-util/resolver.h>
+#include <pjlib-util/srv_resolver.h>
+
+/* Simple DNS server */
+#include <pjlib-util/dns_server.h>
+
+/* Text scanner */
+#include <pjlib-util/scanner.h>
+
+/* XML */
+#include <pjlib-util/xml.h>
+
+/* Old STUN */
+#include <pjlib-util/stun_simple.h>
+
+/* PCAP */
+#include <pjlib-util/pcap.h>
+
+#endif /* __PJLIB_UTIL_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/base64.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/base64.h
new file mode 100644
index 0000000..25b7700
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/base64.h
@@ -0,0 +1,92 @@
+/* $Id: base64.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_BASE64_H__
+#define __PJLIB_UTIL_BASE64_H__
+
+/**
+ * @file base64.h
+ * @brief Base64 encoding and decoding
+ */
+
+#include <pjlib-util/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJLIB_UTIL_BASE64 Base64 Encoding/Decoding
+ * @ingroup PJLIB_UTIL_ENCRYPTION
+ * @{
+ * This module implements base64 encoding and decoding.
+ */
+
+/**
+ * Helper macro to calculate the approximate length required for base256 to
+ * base64 conversion.
+ */
+#define PJ_BASE256_TO_BASE64_LEN(len) (len * 4 / 3 + 3)
+
+/**
+ * Helper macro to calculate the approximage length required for base64 to
+ * base256 conversion.
+ */
+#define PJ_BASE64_TO_BASE256_LEN(len) (len * 3 / 4)
+
+
+/**
+ * Encode a buffer into base64 encoding.
+ *
+ * @param input The input buffer.
+ * @param in_len Size of the input buffer.
+ * @param output Output buffer. Caller must allocate this buffer with
+ * the appropriate size.
+ * @param out_len On entry, it specifies the length of the output buffer.
+ * Upon return, this will be filled with the actual
+ * length of the output buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_base64_encode(const pj_uint8_t *input, int in_len,
+ char *output, int *out_len);
+
+
+/**
+ * Decode base64 string.
+ *
+ * @param input Input string.
+ * @param out Buffer to store the output. Caller must allocate
+ * this buffer with the appropriate size.
+ * @param out_len On entry, it specifies the length of the output buffer.
+ * Upon return, this will be filled with the actual
+ * length of the output.
+ */
+PJ_DECL(pj_status_t) pj_base64_decode(const pj_str_t *input,
+ pj_uint8_t *out, int *out_len);
+
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_BASE64_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/config.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/config.h
new file mode 100644
index 0000000..2994598
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/config.h
@@ -0,0 +1,263 @@
+/* $Id: config.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_CONFIG_H__
+#define __PJLIB_UTIL_CONFIG_H__
+
+
+/**
+ * @file config.h
+ * @brief Compile time settings
+ */
+
+/**
+ * @defgroup PJLIB_UTIL_CONFIG Configuration
+ * @ingroup PJLIB_UTIL_BASE
+ * @{
+ */
+
+
+/* **************************************************************************
+ * DNS CONFIGURATION
+ */
+
+/**
+ * Maximum number of IP addresses in DNS A response.
+ */
+#ifndef PJ_DNS_MAX_IP_IN_A_REC
+# define PJ_DNS_MAX_IP_IN_A_REC 8
+#endif
+
+
+/**
+ * Maximum server address entries per one SRV record
+ */
+#ifndef PJ_DNS_SRV_MAX_ADDR
+# define PJ_DNS_SRV_MAX_ADDR 8
+#endif
+
+
+/**
+ * This constant specifies the maximum names to keep in the temporary name
+ * table when performing name compression scheme when duplicating DNS packet
+ * (the #pj_dns_packet_dup() function).
+ *
+ * Generally name compression is desired, since it saves some memory (see
+ * PJ_DNS_RESOLVER_RES_BUF_SIZE setting). However it comes at the expense of
+ * a little processing overhead to perform name scanning and also a little
+ * bit more stack usage (8 bytes per entry on 32bit platform).
+ *
+ * Default: 16
+ */
+#ifndef PJ_DNS_MAX_NAMES_IN_NAMETABLE
+# define PJ_DNS_MAX_NAMES_IN_NAMETABLE 16
+#endif
+
+
+/* **************************************************************************
+ * RESOLVER CONFIGURATION
+ */
+
+
+/**
+ * Maximum numbers of DNS nameservers that can be configured in resolver.
+ */
+#ifndef PJ_DNS_RESOLVER_MAX_NS
+# define PJ_DNS_RESOLVER_MAX_NS 16
+#endif
+
+
+/**
+ * Default retransmission delay, in miliseconds. The combination of
+ * retransmission delay and count determines the query timeout.
+ *
+ * Default: 2000 (2 seconds, according to RFC 1035)
+ */
+#ifndef PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY
+# define PJ_DNS_RESOLVER_QUERY_RETRANSMIT_DELAY 2000
+#endif
+
+
+/**
+ * Maximum number of transmissions before timeout is declared for
+ * the query.
+ *
+ * Default: 5
+ */
+#ifndef PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT
+# define PJ_DNS_RESOLVER_QUERY_RETRANSMIT_COUNT 5
+#endif
+
+
+/**
+ * Maximum life-time of DNS response in the resolver response cache,
+ * in seconds. If the value is zero, then DNS response caching will be
+ * disabled.
+ *
+ * Default is 300 seconds (5 minutes).
+ *
+ * @see PJ_DNS_RESOLVER_INVALID_TTL
+ */
+#ifndef PJ_DNS_RESOLVER_MAX_TTL
+# define PJ_DNS_RESOLVER_MAX_TTL (5*60)
+#endif
+
+/**
+ * The life-time of invalid DNS response in the resolver response cache.
+ * An invalid DNS response is a response which RCODE is non-zero and
+ * response without any answer section. These responses can be put in
+ * the cache too to minimize message round-trip.
+ *
+ * Default: 60 (one minute).
+ *
+ * @see PJ_DNS_RESOLVER_MAX_TTL
+ */
+#ifndef PJ_DNS_RESOLVER_INVALID_TTL
+# define PJ_DNS_RESOLVER_INVALID_TTL 60
+#endif
+
+/**
+ * The interval on which nameservers which are known to be good to be
+ * probed again to determine whether they are still good. Note that
+ * this applies to both active nameserver (the one currently being used)
+ * and idle nameservers (good nameservers that are not currently selected).
+ * The probing to query the "goodness" of nameservers involves sending
+ * the same query to multiple servers, so it's probably not a good idea
+ * to send this probing too often.
+ *
+ * Default: 600 (ten minutes)
+ *
+ * @see PJ_DNS_RESOLVER_BAD_NS_TTL
+ */
+#ifndef PJ_DNS_RESOLVER_GOOD_NS_TTL
+# define PJ_DNS_RESOLVER_GOOD_NS_TTL (10*60)
+#endif
+
+/**
+ * The interval on which nameservers which known to be bad to be probed
+ * again to determine whether it is still bad.
+ *
+ * Default: 60 (one minute)
+ *
+ * @see PJ_DNS_RESOLVER_GOOD_NS_TTL
+ */
+#ifndef PJ_DNS_RESOLVER_BAD_NS_TTL
+# define PJ_DNS_RESOLVER_BAD_NS_TTL (1*60)
+#endif
+
+
+/**
+ * Maximum size of UDP packet. RFC 1035 states that maximum size of
+ * DNS packet carried over UDP is 512 bytes.
+ *
+ * Default: 512 byes
+ */
+#ifndef PJ_DNS_RESOLVER_MAX_UDP_SIZE
+# define PJ_DNS_RESOLVER_MAX_UDP_SIZE 512
+#endif
+
+
+/**
+ * Size of memory pool allocated for each individual DNS response cache.
+ * This value here should be more or less the same as maximum UDP packet
+ * size (PJ_DNS_RESOLVER_MAX_UDP_SIZE), since the DNS replicator function
+ * (#pj_dns_packet_dup()) is also capable of performing name compressions.
+ *
+ * Default: 512
+ */
+#ifndef PJ_DNS_RESOLVER_RES_BUF_SIZE
+# define PJ_DNS_RESOLVER_RES_BUF_SIZE 512
+#endif
+
+
+/**
+ * Size of temporary pool buffer for parsing DNS packets in resolver.
+ *
+ * default: 4000
+ */
+#ifndef PJ_DNS_RESOLVER_TMP_BUF_SIZE
+# define PJ_DNS_RESOLVER_TMP_BUF_SIZE 4000
+#endif
+
+
+/* **************************************************************************
+ * SCANNER CONFIGURATION
+ */
+
+
+/**
+ * Macro PJ_SCANNER_USE_BITWISE is defined and non-zero (by default yes)
+ * will enable the use of bitwise for character input specification (cis).
+ * This would save several kilobytes of .bss memory in the SIP parser.
+ */
+#ifndef PJ_SCANNER_USE_BITWISE
+# define PJ_SCANNER_USE_BITWISE 1
+#endif
+
+
+
+/* **************************************************************************
+ * STUN CLIENT CONFIGURATION
+ */
+
+/**
+ * Maximum number of attributes in the STUN packet (for the old STUN
+ * library).
+ *
+ * Default: 16
+ */
+#ifndef PJSTUN_MAX_ATTR
+# define PJSTUN_MAX_ATTR 16
+#endif
+
+
+/**
+ * Maximum number of attributes in the STUN packet (for the new STUN
+ * library).
+ *
+ * Default: 16
+ */
+#ifndef PJ_STUN_MAX_ATTR
+# define PJ_STUN_MAX_ATTR 16
+#endif
+
+
+/* **************************************************************************
+ * ENCRYPTION
+ */
+
+/**
+ * Specifies whether CRC32 algorithm should use the table based lookup table
+ * for faster calculation, at the expense of about 1KB table size on the
+ * executable. If zero, the CRC32 will use non-table based which is more than
+ * an order of magnitude slower.
+ *
+ * Default: 1
+ */
+#ifndef PJ_CRC32_HAS_TABLES
+# define PJ_CRC32_HAS_TABLES 1
+#endif
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJLIB_UTIL_CONFIG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/crc32.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/crc32.h
new file mode 100644
index 0000000..6f7a917
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/crc32.h
@@ -0,0 +1,96 @@
+/* $Id: crc32.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_CRC32_H__
+#define __PJLIB_UTIL_CRC32_H__
+
+/**
+ * @file crc32.h
+ * @brief CRC32 implementation
+ */
+
+#include <pjlib-util/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJLIB_UTIL_CRC32 CRC32 (Cyclic Redundancy Check)
+ * @ingroup PJLIB_UTIL_ENCRYPTION
+ * @{
+ * This implements CRC32 algorithm. See ITU-T V.42 for the formal
+ * specification.
+ */
+
+/** CRC32 context. */
+typedef struct pj_crc32_context
+{
+ pj_uint32_t crc_state; /**< Current state. */
+} pj_crc32_context;
+
+
+/**
+ * Initialize CRC32 context.
+ *
+ * @param ctx CRC32 context.
+ */
+PJ_DECL(void) pj_crc32_init(pj_crc32_context *ctx);
+
+/**
+ * Feed data incrementally to the CRC32 algorithm.
+ *
+ * @param ctx CRC32 context.
+ * @param data Input data.
+ * @param nbytes Length of the input data.
+ *
+ * @return The current CRC32 value.
+ */
+PJ_DECL(pj_uint32_t) pj_crc32_update(pj_crc32_context *ctx,
+ const pj_uint8_t *data,
+ pj_size_t nbytes);
+
+/**
+ * Finalize CRC32 calculation and retrieve the CRC32 value.
+ *
+ * @param ctx CRC32 context.
+ *
+ * @return The current CRC value.
+ */
+PJ_DECL(pj_uint32_t) pj_crc32_final(pj_crc32_context *ctx);
+
+/**
+ * Perform one-off CRC32 calculation to the specified data.
+ *
+ * @param data Input data.
+ * @param nbytes Length of input data.
+ *
+ * @return CRC value of the data.
+ */
+PJ_DECL(pj_uint32_t) pj_crc32_calc(const pj_uint8_t *data,
+ pj_size_t nbytes);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_CRC32_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns.h
new file mode 100644
index 0000000..94f081d
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns.h
@@ -0,0 +1,445 @@
+/* $Id: dns.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_DNS_H__
+#define __PJLIB_UTIL_DNS_H__
+
+
+/**
+ * @file dns.h
+ * @brief Low level DNS message parsing and packetization.
+ */
+#include <pjlib-util/types.h>
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_DNS DNS and Asynchronous DNS Resolver
+ * @ingroup PJ_PROTOCOLS
+ */
+
+/**
+ * @defgroup PJ_DNS_PARSING Low-level DNS Message Parsing and Packetization
+ * @ingroup PJ_DNS
+ * @{
+ *
+ * This module provides low-level services to parse and packetize DNS queries
+ * and responses. The functions support building a DNS query packet and parse
+ * the data in the DNS response. This implementation conforms to the
+ * following specifications:
+ * - RFC 1035: DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION
+ * - RFC 1886: DNS Extensions to support IP version 6
+ *
+ * To create a DNS query packet, application should call #pj_dns_make_query()
+ * function, specifying the desired DNS query type, the name to be resolved,
+ * and the buffer where the DNS packet will be built into.
+ *
+ * When incoming DNS query or response packet arrives, application can use
+ * #pj_dns_parse_packet() to parse the TCP/UDP payload into parsed DNS packet
+ * structure.
+ *
+ * This module does not provide any networking functionalities to send or
+ * receive DNS packets. This functionality should be provided by higher layer
+ * modules such as @ref PJ_DNS_RESOLVER.
+ */
+
+enum
+{
+ PJ_DNS_CLASS_IN = 1 /**< DNS class IN. */
+};
+
+/**
+ * This enumeration describes standard DNS record types as described by
+ * RFC 1035, RFC 2782, and others.
+ */
+typedef enum pj_dns_type
+{
+ PJ_DNS_TYPE_A = 1, /**< Host address (A) record. */
+ PJ_DNS_TYPE_NS = 2, /**< Authoritative name server (NS) */
+ PJ_DNS_TYPE_MD = 3, /**< Mail destination (MD) record. */
+ PJ_DNS_TYPE_MF = 4, /**< Mail forwarder (MF) record. */
+ PJ_DNS_TYPE_CNAME = 5, /**< Canonical name (CNAME) record. */
+ PJ_DNS_TYPE_SOA = 6, /**< Marks start of zone authority. */
+ PJ_DNS_TYPE_MB = 7, /**< Mailbox domain name (MB). */
+ PJ_DNS_TYPE_MG = 8, /**< Mail group member (MG). */
+ PJ_DNS_TYPE_MR = 9, /**< Mail rename domain name. */
+ PJ_DNS_TYPE_NULL = 10, /**< NULL RR. */
+ PJ_DNS_TYPE_WKS = 11, /**< Well known service description */
+ PJ_DNS_TYPE_PTR = 12, /**< Domain name pointer. */
+ PJ_DNS_TYPE_HINFO = 13, /**< Host information. */
+ PJ_DNS_TYPE_MINFO = 14, /**< Mailbox or mail list information. */
+ PJ_DNS_TYPE_MX = 15, /**< Mail exchange record. */
+ PJ_DNS_TYPE_TXT = 16, /**< Text string. */
+ PJ_DNS_TYPE_RP = 17, /**< Responsible person. */
+ PJ_DNS_TYPE_AFSB = 18, /**< AFS cell database. */
+ PJ_DNS_TYPE_X25 = 19, /**< X.25 calling address. */
+ PJ_DNS_TYPE_ISDN = 20, /**< ISDN calling address. */
+ PJ_DNS_TYPE_RT = 21, /**< Router. */
+ PJ_DNS_TYPE_NSAP = 22, /**< NSAP address. */
+ PJ_DNS_TYPE_NSAP_PTR= 23, /**< NSAP reverse address. */
+ PJ_DNS_TYPE_SIG = 24, /**< Signature. */
+ PJ_DNS_TYPE_KEY = 25, /**< Key. */
+ PJ_DNS_TYPE_PX = 26, /**< X.400 mail mapping. */
+ PJ_DNS_TYPE_GPOS = 27, /**< Geographical position (withdrawn) */
+ PJ_DNS_TYPE_AAAA = 28, /**< IPv6 address. */
+ PJ_DNS_TYPE_LOC = 29, /**< Location. */
+ PJ_DNS_TYPE_NXT = 30, /**< Next valid name in the zone. */
+ PJ_DNS_TYPE_EID = 31, /**< Endpoint idenfitier. */
+ PJ_DNS_TYPE_NIMLOC = 32, /**< Nimrod locator. */
+ PJ_DNS_TYPE_SRV = 33, /**< Server selection (SRV) record. */
+ PJ_DNS_TYPE_ATMA = 34, /**< DNS ATM address record. */
+ PJ_DNS_TYPE_NAPTR = 35, /**< DNS Naming authority pointer record. */
+ PJ_DNS_TYPE_KX = 36, /**< DNS key exchange record. */
+ PJ_DNS_TYPE_CERT = 37, /**< DNS certificate record. */
+ PJ_DNS_TYPE_A6 = 38, /**< DNS IPv6 address (experimental) */
+ PJ_DNS_TYPE_DNAME = 39, /**< DNS non-terminal name redirection rec. */
+
+ PJ_DNS_TYPE_OPT = 41, /**< DNS options - contains EDNS metadata. */
+ PJ_DNS_TYPE_APL = 42, /**< DNS Address Prefix List (APL) record. */
+ PJ_DNS_TYPE_DS = 43, /**< DNS Delegation Signer (DS) */
+ PJ_DNS_TYPE_SSHFP = 44, /**< DNS SSH Key Fingerprint */
+ PJ_DNS_TYPE_IPSECKEY= 45, /**< DNS IPSEC Key. */
+ PJ_DNS_TYPE_RRSIG = 46, /**< DNS Resource Record signature. */
+ PJ_DNS_TYPE_NSEC = 47, /**< DNS Next Secure Name. */
+ PJ_DNS_TYPE_DNSKEY = 48 /**< DNSSEC Key. */
+} pj_dns_type;
+
+
+
+/**
+ * Standard DNS header, according to RFC 1035, which will be present in
+ * both DNS query and DNS response.
+ *
+ * Note that all values seen by application would be in
+ * host by order. The library would convert them to network
+ * byte order as necessary.
+ */
+typedef struct pj_dns_hdr
+{
+ pj_uint16_t id; /**< Transaction ID. */
+ pj_uint16_t flags; /**< Flags. */
+ pj_uint16_t qdcount; /**< Nb. of queries. */
+ pj_uint16_t anscount; /**< Nb. of res records */
+ pj_uint16_t nscount; /**< Nb. of NS records. */
+ pj_uint16_t arcount; /**< Nb. of additional records */
+} pj_dns_hdr;
+
+/** Create RCODE flag */
+#define PJ_DNS_SET_RCODE(c) ((pj_uint16_t)((c) & 0x0F))
+
+/** Create RA (Recursion Available) bit */
+#define PJ_DNS_SET_RA(on) ((pj_uint16_t)((on) << 7))
+
+/** Create RD (Recursion Desired) bit */
+#define PJ_DNS_SET_RD(on) ((pj_uint16_t)((on) << 8))
+
+/** Create TC (Truncated) bit */
+#define PJ_DNS_SET_TC(on) ((pj_uint16_t)((on) << 9))
+
+/** Create AA (Authoritative Answer) bit */
+#define PJ_DNS_SET_AA(on) ((pj_uint16_t)((on) << 10))
+
+/** Create four bits opcode */
+#define PJ_DNS_SET_OPCODE(o) ((pj_uint16_t)((o) << 11))
+
+/** Create query/response bit */
+#define PJ_DNS_SET_QR(on) ((pj_uint16_t)((on) << 15))
+
+
+/** Get RCODE value */
+#define PJ_DNS_GET_RCODE(val) (((val) & PJ_DNS_SET_RCODE(0x0F)) >> 0)
+
+/** Get RA bit */
+#define PJ_DNS_GET_RA(val) (((val) & PJ_DNS_SET_RA(1)) >> 7)
+
+/** Get RD bit */
+#define PJ_DNS_GET_RD(val) (((val) & PJ_DNS_SET_RD(1)) >> 8)
+
+/** Get TC bit */
+#define PJ_DNS_GET_TC(val) (((val) & PJ_DNS_SET_TC(1)) >> 9)
+
+/** Get AA bit */
+#define PJ_DNS_GET_AA(val) (((val) & PJ_DNS_SET_AA(1)) >> 10)
+
+/** Get OPCODE value */
+#define PJ_DNS_GET_OPCODE(val) (((val) & PJ_DNS_SET_OPCODE(0x0F)) >> 11)
+
+/** Get QR bit */
+#define PJ_DNS_GET_QR(val) (((val) & PJ_DNS_SET_QR(1)) >> 15)
+
+
+/**
+ * These constants describe DNS RCODEs. Application can fold these constants
+ * into PJLIB pj_status_t namespace by calling #PJ_STATUS_FROM_DNS_RCODE()
+ * macro.
+ */
+typedef enum pj_dns_rcode
+{
+ PJ_DNS_RCODE_FORMERR = 1, /**< Format error. */
+ PJ_DNS_RCODE_SERVFAIL = 2, /**< Server failure. */
+ PJ_DNS_RCODE_NXDOMAIN = 3, /**< Name Error. */
+ PJ_DNS_RCODE_NOTIMPL = 4, /**< Not Implemented. */
+ PJ_DNS_RCODE_REFUSED = 5, /**< Refused. */
+ PJ_DNS_RCODE_YXDOMAIN = 6, /**< The name exists. */
+ PJ_DNS_RCODE_YXRRSET = 7, /**< The RRset (name, type) exists. */
+ PJ_DNS_RCODE_NXRRSET = 8, /**< The RRset (name, type) doesn't exist*/
+ PJ_DNS_RCODE_NOTAUTH = 9, /**< Not authorized. */
+ PJ_DNS_RCODE_NOTZONE = 10 /**< The zone specified is not a zone. */
+
+} pj_dns_rcode;
+
+
+/**
+ * This structure describes a DNS query record.
+ */
+typedef struct pj_dns_parsed_query
+{
+ pj_str_t name; /**< The domain in the query. */
+ pj_uint16_t type; /**< Type of the query (pj_dns_type) */
+ pj_uint16_t dnsclass; /**< Network class (PJ_DNS_CLASS_IN=1) */
+} pj_dns_parsed_query;
+
+
+/**
+ * This structure describes a Resource Record parsed from the DNS packet.
+ * All integral values are in host byte order.
+ */
+typedef struct pj_dns_parsed_rr
+{
+ pj_str_t name; /**< The domain name which this rec pertains. */
+ pj_uint16_t type; /**< RR type code. */
+ pj_uint16_t dnsclass; /**< Class of data (PJ_DNS_CLASS_IN=1). */
+ pj_uint32_t ttl; /**< Time to live. */
+ pj_uint16_t rdlength; /**< Resource data length. */
+ void *data; /**< Pointer to the raw resource data, only
+ when the type is not known. If it is known,
+ the data will be put in rdata below. */
+
+ /** For resource types that are recognized/supported by this library,
+ * the parsed resource data will be placed in this rdata union.
+ */
+ union rdata
+ {
+ /** SRV Resource Data (PJ_DNS_TYPE_SRV, 33) */
+ struct srv {
+ pj_uint16_t prio; /**< Target priority (lower is higher). */
+ pj_uint16_t weight; /**< Weight/proportion */
+ pj_uint16_t port; /**< Port number of the service */
+ pj_str_t target; /**< Target name. */
+ } srv;
+
+ /** CNAME Resource Data (PJ_DNS_TYPE_CNAME, 5) */
+ struct cname {
+ pj_str_t name; /**< Primary canonical name for an alias. */
+ } cname;
+
+ /** NS Resource Data (PJ_DNS_TYPE_NS, 2) */
+ struct ns {
+ pj_str_t name; /**< Primary name server. */
+ } ns;
+
+ /** PTR Resource Data (PJ_DNS_TYPE_PTR, 12) */
+ struct ptr {
+ pj_str_t name; /**< PTR name. */
+ } ptr;
+
+ /** A Resource Data (PJ_DNS_TYPE_A, 1) */
+ struct a {
+ pj_in_addr ip_addr;/**< IPv4 address in network byte order. */
+ } a;
+
+ /** AAAA Resource Data (PJ_DNS_TYPE_AAAA, 28) */
+ struct aaaa {
+ pj_in6_addr ip_addr;/**< IPv6 address in network byte order. */
+ } aaaa;
+
+ } rdata;
+
+} pj_dns_parsed_rr;
+
+
+/**
+ * This structure describes the parsed repersentation of the raw DNS packet.
+ * Note that all integral values in the parsed packet are represented in
+ * host byte order.
+ */
+typedef struct pj_dns_parsed_packet
+{
+ pj_dns_hdr hdr; /**< Pointer to DNS hdr, in host byte order */
+ pj_dns_parsed_query *q; /**< Array of DNS queries. */
+ pj_dns_parsed_rr *ans; /**< Array of DNS RR answer. */
+ pj_dns_parsed_rr *ns; /**< Array of NS record in the answer. */
+ pj_dns_parsed_rr *arr; /**< Array of additional RR answer. */
+} pj_dns_parsed_packet;
+
+
+/**
+ * Option flags to be specified when calling #pj_dns_packet_dup() function.
+ * These flags can be combined with bitwise OR operation.
+ */
+enum pj_dns_dup_options
+{
+ PJ_DNS_NO_QD = 1, /**< Do not duplicate the query section. */
+ PJ_DNS_NO_ANS = 2, /**< Do not duplicate the answer section. */
+ PJ_DNS_NO_NS = 4, /**< Do not duplicate the NS section. */
+ PJ_DNS_NO_AR = 8 /**< Do not duplicate the additional rec section */
+};
+
+
+/**
+ * Create DNS query packet to resolve the specified names. This function
+ * can be used to build any types of DNS query, such as A record or DNS SRV
+ * record.
+ *
+ * Application specifies the type of record and the name to be queried,
+ * and the function will build the DNS query packet into the buffer
+ * specified. Once the packet is successfully built, application can send
+ * the packet via TCP or UDP connection.
+ *
+ * @param packet The buffer to put the DNS query packet.
+ * @param size On input, it specifies the size of the buffer.
+ * On output, it will be filled with the actual size of
+ * the DNS query packet.
+ * @param id DNS query ID to associate DNS response with the
+ * query.
+ * @param qtype DNS type of record to be queried (see #pj_dns_type).
+ * @param name Name to be queried from the DNS server.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_dns_make_query(void *packet,
+ unsigned *size,
+ pj_uint16_t id,
+ int qtype,
+ const pj_str_t *name);
+
+/**
+ * Parse raw DNS packet into parsed DNS packet structure. This function is
+ * able to parse few DNS resource records such as A record, PTR record,
+ * CNAME record, NS record, and SRV record.
+ *
+ * @param pool Pool to allocate memory for the parsed packet.
+ * @param packet Pointer to the DNS packet (the TCP/UDP payload of
+ * the raw packet).
+ * @param size The size of the DNS packet.
+ * @param p_res Pointer to store the resulting parsed packet.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_dns_parse_packet(pj_pool_t *pool,
+ const void *packet,
+ unsigned size,
+ pj_dns_parsed_packet **p_res);
+
+/**
+ * Duplicate DNS packet.
+ *
+ * @param pool The pool to allocate memory for the duplicated packet.
+ * @param p The DNS packet to be cloned.
+ * @param options Option flags, from pj_dns_dup_options.
+ * @param p_dst Pointer to store the cloned DNS packet.
+ */
+PJ_DECL(void) pj_dns_packet_dup(pj_pool_t *pool,
+ const pj_dns_parsed_packet*p,
+ unsigned options,
+ pj_dns_parsed_packet **p_dst);
+
+
+/**
+ * Utility function to get the type name string of the specified DNS type.
+ *
+ * @param type DNS type (see #pj_dns_type).
+ *
+ * @return String name of the type (e.g. "A", "SRV", etc.).
+ */
+PJ_DECL(const char *) pj_dns_get_type_name(int type);
+
+
+/**
+ * Initialize DNS record as DNS SRV record.
+ *
+ * @param rec The DNS resource record to be initialized as DNS
+ * SRV record.
+ * @param res_name Resource name.
+ * @param dnsclass DNS class.
+ * @param ttl Resource TTL value.
+ * @param prio DNS SRV priority.
+ * @param weight DNS SRV weight.
+ * @param port Target port.
+ * @param target Target name.
+ */
+PJ_DECL(void) pj_dns_init_srv_rr(pj_dns_parsed_rr *rec,
+ const pj_str_t *res_name,
+ unsigned dnsclass,
+ unsigned ttl,
+ unsigned prio,
+ unsigned weight,
+ unsigned port,
+ const pj_str_t *target);
+
+/**
+ * Initialize DNS record as DNS CNAME record.
+ *
+ * @param rec The DNS resource record to be initialized as DNS
+ * CNAME record.
+ * @param res_name Resource name.
+ * @param dnsclass DNS class.
+ * @param ttl Resource TTL value.
+ * @param name Host name.
+ */
+PJ_DECL(void) pj_dns_init_cname_rr(pj_dns_parsed_rr *rec,
+ const pj_str_t *res_name,
+ unsigned dnsclass,
+ unsigned ttl,
+ const pj_str_t *name);
+
+/**
+ * Initialize DNS record as DNS A record.
+ *
+ * @param rec The DNS resource record to be initialized as DNS
+ * A record.
+ * @param res_name Resource name.
+ * @param dnsclass DNS class.
+ * @param ttl Resource TTL value.
+ * @param ip_addr Host address.
+ */
+PJ_DECL(void) pj_dns_init_a_rr(pj_dns_parsed_rr *rec,
+ const pj_str_t *res_name,
+ unsigned dnsclass,
+ unsigned ttl,
+ const pj_in_addr *ip_addr);
+
+/**
+ * Dump DNS packet to standard log.
+ *
+ * @param res The DNS packet.
+ */
+PJ_DECL(void) pj_dns_dump_packet(const pj_dns_parsed_packet *res);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_DNS_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns_server.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns_server.h
new file mode 100644
index 0000000..b30a8a1
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns_server.h
@@ -0,0 +1,117 @@
+/* $Id: dns_server.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_DNS_SERVER_H__
+#define __PJLIB_UTIL_DNS_SERVER_H__
+
+/**
+ * @file dns_server.h
+ * @brief Simple DNS server
+ */
+#include <pjlib-util/types.h>
+#include <pjlib-util/dns.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_DNS_SERVER Simple DNS Server
+ * @ingroup PJ_DNS
+ * @{
+ * This contains a simple but fully working DNS server implementation,
+ * mostly for testing purposes. It supports serving various DNS resource
+ * records such as SRV, CNAME, A, and AAAA.
+ */
+
+/**
+ * Opaque structure to hold DNS server instance.
+ */
+typedef struct pj_dns_server pj_dns_server;
+
+/**
+ * Create the DNS server instance. The instance will run immediately.
+ *
+ * @param pf The pool factory to create memory pools.
+ * @param ioqueue Ioqueue instance where the server socket will be
+ * registered to.
+ * @param af Address family of the server socket (valid values
+ * are pj_AF_INET() for IPv4 and pj_AF_INET6() for IPv6).
+ * @param port The UDP port to listen.
+ * @param flags Flags, currently must be zero.
+ * @param p_srv Pointer to receive the DNS server instance.
+ *
+ * @return PJ_SUCCESS if server has been created successfully,
+ * otherwise the function will return the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pj_dns_server_create(pj_pool_factory *pf,
+ pj_ioqueue_t *ioqueue,
+ int af,
+ unsigned port,
+ unsigned flags,
+ pj_dns_server **p_srv);
+
+/**
+ * Destroy DNS server instance.
+ *
+ * @param srv The DNS server instance.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_dns_server_destroy(pj_dns_server *srv);
+
+
+/**
+ * Add generic resource record entries to the server.
+ *
+ * @param srv The DNS server instance.
+ * @param count Number of records to be added.
+ * @param rr Array of records to be added.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_dns_server_add_rec(pj_dns_server *srv,
+ unsigned count,
+ const pj_dns_parsed_rr rr[]);
+
+/**
+ * Remove the specified record from the server.
+ *
+ * @param srv The DNS server instance.
+ * @param dns_class The resource's DNS class. Valid value is PJ_DNS_CLASS_IN.
+ * @param type The resource type.
+ * @param name The resource name to be removed.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_dns_server_del_rec(pj_dns_server *srv,
+ int dns_class,
+ pj_dns_type type,
+ const pj_str_t *name);
+
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_DNS_SERVER_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/errno.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/errno.h
new file mode 100644
index 0000000..eab118a
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/errno.h
@@ -0,0 +1,367 @@
+/* $Id: errno.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_ERRNO_H__
+#define __PJLIB_UTIL_ERRNO_H__
+
+
+#include <pj/errno.h>
+
+/**
+ * @defgroup PJLIB_UTIL_ERROR Error Codes
+ * @ingroup PJLIB_UTIL_BASE
+ * @{
+ */
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ * This value is 320000.
+ */
+#define PJLIB_UTIL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3)
+
+
+/************************************************************
+ * STUN ERROR
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Unable to resolve STUN server
+ */
+#define PJLIB_UTIL_ESTUNRESOLVE (PJLIB_UTIL_ERRNO_START+1) /* 320001 */
+/**
+ * @hideinitializer
+ * Unknown STUN message type.
+ */
+#define PJLIB_UTIL_ESTUNINMSGTYPE (PJLIB_UTIL_ERRNO_START+2) /* 320002 */
+/**
+ * @hideinitializer
+ * Invalid STUN message length
+ */
+#define PJLIB_UTIL_ESTUNINMSGLEN (PJLIB_UTIL_ERRNO_START+3) /* 320003 */
+/**
+ * @hideinitializer
+ * Invalid STUN attribute length
+ */
+#define PJLIB_UTIL_ESTUNINATTRLEN (PJLIB_UTIL_ERRNO_START+4) /* 320004 */
+/**
+ * @hideinitializer
+ * Invalid STUN attribute type
+ */
+#define PJLIB_UTIL_ESTUNINATTRTYPE (PJLIB_UTIL_ERRNO_START+5) /* 320005 */
+/**
+ * @hideinitializer
+ * Invalid STUN server/socket index
+ */
+#define PJLIB_UTIL_ESTUNININDEX (PJLIB_UTIL_ERRNO_START+6) /* 320006 */
+/**
+ * @hideinitializer
+ * No STUN binding response in the message
+ */
+#define PJLIB_UTIL_ESTUNNOBINDRES (PJLIB_UTIL_ERRNO_START+7) /* 320007 */
+/**
+ * @hideinitializer
+ * Received STUN error attribute
+ */
+#define PJLIB_UTIL_ESTUNRECVERRATTR (PJLIB_UTIL_ERRNO_START+8) /* 320008 */
+/**
+ * @hideinitializer
+ * No STUN mapped address attribute
+ */
+#define PJLIB_UTIL_ESTUNNOMAP (PJLIB_UTIL_ERRNO_START+9) /* 320009 */
+/**
+ * @hideinitializer
+ * Received no response from STUN server
+ */
+#define PJLIB_UTIL_ESTUNNOTRESPOND (PJLIB_UTIL_ERRNO_START+10) /* 320010 */
+/**
+ * @hideinitializer
+ * Symetric NAT detected by STUN
+ */
+#define PJLIB_UTIL_ESTUNSYMMETRIC (PJLIB_UTIL_ERRNO_START+11) /* 320011 */
+/**
+ * @hideinitializer
+ * Invalid STUN magic value
+ */
+#define PJLIB_UTIL_ESTUNNOTMAGIC (PJLIB_UTIL_ERRNO_START+12) /* 320012 */
+/**
+ * @hideinitializer
+ * Invalid STUN fingerprint value
+ */
+#define PJLIB_UTIL_ESTUNFINGERPRINT (PJLIB_UTIL_ERRNO_START+13) /* 320013 */
+
+
+
+/************************************************************
+ * XML ERROR
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General invalid XML message.
+ */
+#define PJLIB_UTIL_EINXML (PJLIB_UTIL_ERRNO_START+20) /* 320020 */
+
+
+
+/************************************************************
+ * DNS ERROR
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * DNS query packet buffer is too small.
+ * This error occurs when the user supplied buffer for creating DNS
+ * query (#pj_dns_make_query() function) is too small.
+ */
+#define PJLIB_UTIL_EDNSQRYTOOSMALL (PJLIB_UTIL_ERRNO_START+40) /* 320040 */
+/**
+ * @hideinitializer
+ * Invalid DNS packet length.
+ * This error occurs when the received DNS response packet does not
+ * match all the fields length.
+ */
+#define PJLIB_UTIL_EDNSINSIZE (PJLIB_UTIL_ERRNO_START+41) /* 320041 */
+/**
+ * @hideinitializer
+ * Invalid DNS class.
+ * This error occurs when the received DNS response contains network
+ * class other than IN (Internet).
+ */
+#define PJLIB_UTIL_EDNSINCLASS (PJLIB_UTIL_ERRNO_START+42) /* 320042 */
+/**
+ * @hideinitializer
+ * Invalid DNS name pointer.
+ * This error occurs when parsing the compressed names inside DNS
+ * response packet, when the name pointer points to an invalid address
+ * or the parsing has triggerred too much recursion.
+ */
+#define PJLIB_UTIL_EDNSINNAMEPTR (PJLIB_UTIL_ERRNO_START+43) /* 320043 */
+/**
+ * @hideinitializer
+ * Invalid DNS nameserver address. If hostname was specified for nameserver
+ * address, this error means that the function was unable to resolve
+ * the nameserver hostname.
+ */
+#define PJLIB_UTIL_EDNSINNSADDR (PJLIB_UTIL_ERRNO_START+44) /* 320044 */
+/**
+ * @hideinitializer
+ * No nameserver is in DNS resolver. No nameserver is configured in the
+ * resolver.
+ */
+#define PJLIB_UTIL_EDNSNONS (PJLIB_UTIL_ERRNO_START+45) /* 320045 */
+/**
+ * @hideinitializer
+ * No working DNS nameserver. All nameservers have been queried,
+ * but none was able to serve any DNS requests. These "bad" nameservers
+ * will be re-tested again for "goodness" after some period.
+ */
+#define PJLIB_UTIL_EDNSNOWORKINGNS (PJLIB_UTIL_ERRNO_START+46) /* 320046 */
+/**
+ * @hideinitializer
+ * No answer record in the DNS response.
+ */
+#define PJLIB_UTIL_EDNSNOANSWERREC (PJLIB_UTIL_ERRNO_START+47) /* 320047 */
+/**
+ * @hideinitializer
+ * Invalid DNS answer. This error is raised for example when the DNS
+ * answer does not have a query section, or the type of RR in the answer
+ * doesn't match the query.
+ */
+#define PJLIB_UTIL_EDNSINANSWER (PJLIB_UTIL_ERRNO_START+48) /* 320048 */
+
+
+/* DNS ERRORS MAPPED FROM RCODE: */
+
+/**
+ * Start of error code mapped from DNS RCODE
+ */
+#define PJLIB_UTIL_DNS_RCODE_START (PJLIB_UTIL_ERRNO_START+50) /* 320050 */
+
+/**
+ * Map DNS RCODE status into pj_status_t.
+ */
+#define PJ_STATUS_FROM_DNS_RCODE(rcode) (rcode==0 ? PJ_SUCCESS : \
+ PJLIB_UTIL_DNS_RCODE_START+rcode)
+/**
+ * @hideinitializer
+ * Format error - The name server was unable to interpret the query.
+ * This corresponds to DNS RCODE 1.
+ */
+#define PJLIB_UTIL_EDNS_FORMERR PJ_STATUS_FROM_DNS_RCODE(1) /* 320051 */
+/**
+ * @hideinitializer
+ * Server failure - The name server was unable to process this query due to a
+ * problem with the name server.
+ * This corresponds to DNS RCODE 2.
+ */
+#define PJLIB_UTIL_EDNS_SERVFAIL PJ_STATUS_FROM_DNS_RCODE(2) /* 320052 */
+/**
+ * @hideinitializer
+ * Name Error - Meaningful only for responses from an authoritative name
+ * server, this code signifies that the domain name referenced in the query
+ * does not exist.
+ * This corresponds to DNS RCODE 3.
+ */
+#define PJLIB_UTIL_EDNS_NXDOMAIN PJ_STATUS_FROM_DNS_RCODE(3) /* 320053 */
+/**
+ * @hideinitializer
+ * Not Implemented - The name server does not support the requested kind of
+ * query.
+ * This corresponds to DNS RCODE 4.
+ */
+#define PJLIB_UTIL_EDNS_NOTIMPL PJ_STATUS_FROM_DNS_RCODE(4) /* 320054 */
+/**
+ * @hideinitializer
+ * Refused - The name server refuses to perform the specified operation for
+ * policy reasons.
+ * This corresponds to DNS RCODE 5.
+ */
+#define PJLIB_UTIL_EDNS_REFUSED PJ_STATUS_FROM_DNS_RCODE(5) /* 320055 */
+/**
+ * @hideinitializer
+ * The name exists.
+ * This corresponds to DNS RCODE 6.
+ */
+#define PJLIB_UTIL_EDNS_YXDOMAIN PJ_STATUS_FROM_DNS_RCODE(6) /* 320056 */
+/**
+ * @hideinitializer
+ * The RRset (name, type) exists.
+ * This corresponds to DNS RCODE 7.
+ */
+#define PJLIB_UTIL_EDNS_YXRRSET PJ_STATUS_FROM_DNS_RCODE(7) /* 320057 */
+/**
+ * @hideinitializer
+ * The RRset (name, type) does not exist.
+ * This corresponds to DNS RCODE 8.
+ */
+#define PJLIB_UTIL_EDNS_NXRRSET PJ_STATUS_FROM_DNS_RCODE(8) /* 320058 */
+/**
+ * @hideinitializer
+ * The requestor is not authorized to perform this operation.
+ * This corresponds to DNS RCODE 9.
+ */
+#define PJLIB_UTIL_EDNS_NOTAUTH PJ_STATUS_FROM_DNS_RCODE(9) /* 320059 */
+/**
+ * @hideinitializer
+ * The zone specified is not a zone.
+ * This corresponds to DNS RCODE 10.
+ */
+#define PJLIB_UTIL_EDNS_NOTZONE PJ_STATUS_FROM_DNS_RCODE(10)/* 320060 */
+
+
+/************************************************************
+ * NEW STUN ERROR
+ ***********************************************************/
+/* Messaging errors */
+/**
+ * @hideinitializer
+ * Too many STUN attributes.
+ */
+#define PJLIB_UTIL_ESTUNTOOMANYATTR (PJLIB_UTIL_ERRNO_START+110)/* 320110 */
+/**
+ * @hideinitializer
+ * Unknown STUN attribute. This error happens when the decoder encounters
+ * mandatory attribute type which it doesn't understand.
+ */
+#define PJLIB_UTIL_ESTUNUNKNOWNATTR (PJLIB_UTIL_ERRNO_START+111)/* 320111 */
+/**
+ * @hideinitializer
+ * Invalid STUN socket address length.
+ */
+#define PJLIB_UTIL_ESTUNINADDRLEN (PJLIB_UTIL_ERRNO_START+112)/* 320112 */
+/**
+ * @hideinitializer
+ * STUN IPv6 attribute not supported
+ */
+#define PJLIB_UTIL_ESTUNIPV6NOTSUPP (PJLIB_UTIL_ERRNO_START+113)/* 320113 */
+/**
+ * @hideinitializer
+ * Expecting STUN response message.
+ */
+#define PJLIB_UTIL_ESTUNNOTRESPONSE (PJLIB_UTIL_ERRNO_START+114)/* 320114 */
+/**
+ * @hideinitializer
+ * STUN transaction ID mismatch.
+ */
+#define PJLIB_UTIL_ESTUNINVALIDID (PJLIB_UTIL_ERRNO_START+115)/* 320115 */
+/**
+ * @hideinitializer
+ * Unable to find handler for the request.
+ */
+#define PJLIB_UTIL_ESTUNNOHANDLER (PJLIB_UTIL_ERRNO_START+116)/* 320116 */
+/**
+ * @hideinitializer
+ * Found non-FINGERPRINT attribute after MESSAGE-INTEGRITY. This is not
+ * valid since MESSAGE-INTEGRITY MUST be the last attribute or the
+ * attribute right before FINGERPRINT before the message.
+ */
+#define PJLIB_UTIL_ESTUNMSGINTPOS (PJLIB_UTIL_ERRNO_START+118)/* 320118 */
+/**
+ * @hideinitializer
+ * Found attribute after FINGERPRINT. This is not valid since FINGERPRINT
+ * MUST be the last attribute in the message.
+ */
+#define PJLIB_UTIL_ESTUNFINGERPOS (PJLIB_UTIL_ERRNO_START+119)/* 320119 */
+/**
+ * @hideinitializer
+ * Missing STUN USERNAME attribute.
+ * When credential is included in the STUN message (MESSAGE-INTEGRITY is
+ * present), the USERNAME attribute must be present in the message.
+ */
+#define PJLIB_UTIL_ESTUNNOUSERNAME (PJLIB_UTIL_ERRNO_START+120)/* 320120 */
+/**
+ * @hideinitializer
+ * Unknown STUN username/credential.
+ */
+#define PJLIB_UTIL_ESTUNUSERNAME (PJLIB_UTIL_ERRNO_START+121)/* 320121 */
+/**
+ * @hideinitializer
+ * Missing/invalidSTUN MESSAGE-INTEGRITY attribute.
+ */
+#define PJLIB_UTIL_ESTUNMSGINT (PJLIB_UTIL_ERRNO_START+122)/* 320122 */
+/**
+ * @hideinitializer
+ * Found duplicate STUN attribute.
+ */
+#define PJLIB_UTIL_ESTUNDUPATTR (PJLIB_UTIL_ERRNO_START+123)/* 320123 */
+/**
+ * @hideinitializer
+ * Missing STUN REALM attribute.
+ */
+#define PJLIB_UTIL_ESTUNNOREALM (PJLIB_UTIL_ERRNO_START+124)/* 320124 */
+/**
+ * @hideinitializer
+ * Missing/stale STUN NONCE attribute value.
+ */
+#define PJLIB_UTIL_ESTUNNONCE (PJLIB_UTIL_ERRNO_START+125)/* 320125 */
+/**
+ * @hideinitializer
+ * STUN transaction terminates with failure.
+ */
+#define PJLIB_UTIL_ESTUNTSXFAILED (PJLIB_UTIL_ERRNO_START+126)/* 320126 */
+
+
+//#define PJ_STATUS_FROM_STUN_CODE(code) (PJLIB_UTIL_ERRNO_START+code)
+
+
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJLIB_UTIL_ERRNO_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/getopt.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/getopt.h
new file mode 100644
index 0000000..acf30f0
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/getopt.h
@@ -0,0 +1,146 @@
+/* $Id: getopt.h 2037 2008-06-20 21:39:02Z bennylp $ */
+/* This file has now become GPL. */
+/* Declarations for pj_getopt.
+ Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef __PJ_GETOPT_H__
+#define __PJ_GETOPT_H__ 1
+
+/**
+ * @file getopt.h
+ * @brief Compile time settings
+ */
+
+/**
+ * @defgroup PJLIB_UTIL_GETOPT Getopt
+ * @ingroup PJLIB_TEXT
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `pj_getopt' to the caller.
+ When `pj_getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *pj_optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `pj_getopt'.
+
+ On entry to `pj_getopt', zero means this is the first call; initialize.
+
+ When `pj_getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `pj_optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int pj_optind;
+
+/* Set to an option character which was unrecognized. */
+
+extern int pj_optopt;
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to pj_getopt_long or pj_getopt_long_only is a vector
+ of `struct pj_getopt_option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `pj_optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `pj_getopt'
+ returns the contents of the `val' field. */
+
+struct pj_getopt_option
+{
+ const char *name;
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct pj_getopt_option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `pj_optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `pj_optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `pj_getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `pj_getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `pj_getopt'. */
+
+int pj_getopt (int argc, char *const *argv, const char *shortopts);
+
+int pj_getopt_long (int argc, char *const *argv, const char *options,
+ const struct pj_getopt_option *longopts, int *longind);
+int pj_getopt_long_only (int argc, char *const *argv,
+ const char *shortopts,
+ const struct pj_getopt_option *longopts, int *longind);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* pj_getopt.h */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_md5.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_md5.h
new file mode 100644
index 0000000..564ac6a
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_md5.h
@@ -0,0 +1,109 @@
+/* $Id: hmac_md5.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_HMAC_MD5_H__
+#define __PJLIB_UTIL_HMAC_MD5_H__
+
+/**
+ * @file hmac_md5.h
+ * @brief HMAC MD5 Message Authentication
+ */
+
+/**
+ * @defgroup PJLIB_UTIL_ENCRYPTION Encryption Algorithms
+ */
+
+#include <pj/types.h>
+#include <pjlib-util/md5.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJLIB_UTIL_HMAC_MD5 HMAC MD5 Message Authentication
+ * @ingroup PJLIB_UTIL_ENCRYPTION
+ * @{
+ *
+ * This module contains the implementation of HMAC: Keyed-Hashing
+ * for Message Authentication, as described in RFC 2104
+ */
+
+/**
+ * The HMAC-MD5 context used in the incremental HMAC calculation.
+ */
+typedef struct pj_hmac_md5_context
+{
+ pj_md5_context context; /**< MD5 context */
+ pj_uint8_t k_opad[64]; /**< opad xor-ed with key */
+} pj_hmac_md5_context;
+
+
+/**
+ * Calculate HMAC MD5 digest for the specified input and key.
+ *
+ * @param input Pointer to the input stream.
+ * @param input_len Length of input stream in bytes.
+ * @param key Pointer to the authentication key.
+ * @param key_len Length of the authentication key.
+ * @param digest Buffer to be filled with HMAC MD5 digest.
+ */
+PJ_DECL(void) pj_hmac_md5(const pj_uint8_t *input, unsigned input_len,
+ const pj_uint8_t *key, unsigned key_len,
+ pj_uint8_t digest[16]);
+
+
+/**
+ * Initiate HMAC-MD5 context for incremental hashing.
+ *
+ * @param hctx HMAC-MD5 context.
+ * @param key Pointer to the authentication key.
+ * @param key_len Length of the authentication key.
+ */
+PJ_DECL(void) pj_hmac_md5_init(pj_hmac_md5_context *hctx,
+ const pj_uint8_t *key, unsigned key_len);
+
+/**
+ * Append string to the message.
+ *
+ * @param hctx HMAC-MD5 context.
+ * @param input Pointer to the input stream.
+ * @param input_len Length of input stream in bytes.
+ */
+PJ_DECL(void) pj_hmac_md5_update(pj_hmac_md5_context *hctx,
+ const pj_uint8_t *input,
+ unsigned input_len);
+
+/**
+ * Finish the message and return the digest.
+ *
+ * @param hctx HMAC-MD5 context.
+ * @param digest Buffer to be filled with HMAC MD5 digest.
+ */
+PJ_DECL(void) pj_hmac_md5_final(pj_hmac_md5_context *hctx,
+ pj_uint8_t digest[16]);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_HMAC_MD5_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_sha1.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_sha1.h
new file mode 100644
index 0000000..5785684
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_sha1.h
@@ -0,0 +1,107 @@
+/* $Id: hmac_sha1.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_HMAC_SHA1_H__
+#define __PJLIB_UTIL_HMAC_SHA1_H__
+
+/**
+ * @file hmac_sha1.h
+ * @brief HMAC SHA1 Message Authentication
+ */
+
+#include <pj/types.h>
+#include <pjlib-util/sha1.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJLIB_UTIL_HMAC_SHA1 HMAC SHA1 Message Authentication
+ * @ingroup PJLIB_UTIL_ENCRYPTION
+ * @{
+ *
+ * This module contains the implementation of HMAC: Keyed-Hashing
+ * for Message Authentication, as described in RFC 2104.
+ */
+
+/**
+ * The HMAC-SHA1 context used in the incremental HMAC calculation.
+ */
+typedef struct pj_hmac_sha1_context
+{
+ pj_sha1_context context; /**< SHA1 context */
+ pj_uint8_t k_opad[64]; /**< opad xor-ed with key */
+} pj_hmac_sha1_context;
+
+
+/**
+ * Calculate HMAC-SHA1 digest for the specified input and key with this
+ * single function call.
+ *
+ * @param input Pointer to the input stream.
+ * @param input_len Length of input stream in bytes.
+ * @param key Pointer to the authentication key.
+ * @param key_len Length of the authentication key.
+ * @param digest Buffer to be filled with HMAC SHA1 digest.
+ */
+PJ_DECL(void) pj_hmac_sha1(const pj_uint8_t *input, unsigned input_len,
+ const pj_uint8_t *key, unsigned key_len,
+ pj_uint8_t digest[20]);
+
+
+/**
+ * Initiate HMAC-SHA1 context for incremental hashing.
+ *
+ * @param hctx HMAC-SHA1 context.
+ * @param key Pointer to the authentication key.
+ * @param key_len Length of the authentication key.
+ */
+PJ_DECL(void) pj_hmac_sha1_init(pj_hmac_sha1_context *hctx,
+ const pj_uint8_t *key, unsigned key_len);
+
+/**
+ * Append string to the message.
+ *
+ * @param hctx HMAC-SHA1 context.
+ * @param input Pointer to the input stream.
+ * @param input_len Length of input stream in bytes.
+ */
+PJ_DECL(void) pj_hmac_sha1_update(pj_hmac_sha1_context *hctx,
+ const pj_uint8_t *input,
+ unsigned input_len);
+
+/**
+ * Finish the message and return the digest.
+ *
+ * @param hctx HMAC-SHA1 context.
+ * @param digest Buffer to be filled with HMAC SHA1 digest.
+ */
+PJ_DECL(void) pj_hmac_sha1_final(pj_hmac_sha1_context *hctx,
+ pj_uint8_t digest[20]);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_HMAC_SHA1_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/md5.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/md5.h
new file mode 100644
index 0000000..ecfddc1
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/md5.h
@@ -0,0 +1,74 @@
+/* $Id: md5.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_MD5_H__
+#define __PJLIB_UTIL_MD5_H__
+
+/**
+ * @file md5.h
+ * @brief MD5 Functions
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJLIB_UTIL_MD5 MD5
+ * @ingroup PJLIB_UTIL_ENCRYPTION
+ * @{
+ */
+
+
+/** MD5 context. */
+typedef struct pj_md5_context
+{
+ pj_uint32_t buf[4]; /**< buf */
+ pj_uint32_t bits[2]; /**< bits */
+ pj_uint8_t in[64]; /**< in */
+} pj_md5_context;
+
+/** Initialize the algorithm.
+ * @param pms MD5 context.
+ */
+PJ_DECL(void) pj_md5_init(pj_md5_context *pms);
+
+/** Append a string to the message.
+ * @param pms MD5 context.
+ * @param data Data.
+ * @param nbytes Length of data.
+ */
+PJ_DECL(void) pj_md5_update( pj_md5_context *pms,
+ const pj_uint8_t *data, unsigned nbytes);
+
+/** Finish the message and return the digest.
+ * @param pms MD5 context.
+ * @param digest 16 byte digest.
+ */
+PJ_DECL(void) pj_md5_final(pj_md5_context *pms, pj_uint8_t digest[16]);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_MD5_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/pcap.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/pcap.h
new file mode 100644
index 0000000..7ae68b5
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/pcap.h
@@ -0,0 +1,196 @@
+/* $Id: pcap.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_PCAP_H__
+#define __PJLIB_UTIL_PCAP_H__
+
+/**
+ * @file pcap.h
+ * @brief Simple PCAP file reader
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_PCAP Simple PCAP file reader
+ * @ingroup PJ_FILE_FMT
+ * @{
+ * This module describes simple utility to read PCAP file. It is not intended
+ * to support all PCAP features (that's what libpcap is for!), but it can
+ * be useful for example to playback or stream PCAP contents.
+ */
+
+/**
+ * Enumeration to describe supported data link types.
+ */
+typedef enum pj_pcap_link_type
+{
+ /** Ethernet data link */
+ PJ_PCAP_LINK_TYPE_ETH = 1
+
+} pj_pcap_link_type;
+
+
+/**
+ * Enumeration to describe supported protocol types.
+ */
+typedef enum pj_pcap_proto_type
+{
+ /** UDP protocol */
+ PJ_PCAP_PROTO_TYPE_UDP = 17
+
+} pj_pcap_proto_type;
+
+
+/**
+ * This describes UDP header, which may optionally be returned in
+ * #pj_pcap_read_udp() function. All fields are in network byte order.
+ */
+typedef struct pj_pcap_udp_hdr
+{
+ pj_uint16_t src_port; /**< Source port. */
+ pj_uint16_t dst_port; /**< Destination port */
+ pj_uint16_t len; /**< Length. */
+ pj_uint16_t csum; /**< Checksum. */
+} pj_pcap_udp_hdr;
+
+
+/**
+ * This structure describes the filter to be used when reading packets from
+ * a PCAP file. When a filter is configured, only packets matching all the
+ * filter specifications will be read from PCAP file.
+ */
+typedef struct pj_pcap_filter
+{
+ /**
+ * Select data link type, or zero to include any supported data links.
+ */
+ pj_pcap_link_type link;
+
+ /**
+ * Select protocol, or zero to include all supported protocols.
+ */
+ pj_pcap_proto_type proto;
+
+ /**
+ * Specify source IP address of the packets, or zero to include packets
+ * from any IP addresses. Note that IP address here must be in
+ * network byte order.
+ */
+ pj_uint32_t ip_src;
+
+ /**
+ * Specify destination IP address of the packets, or zero to include packets
+ * destined to any IP addresses. Note that IP address here must be in
+ * network byte order.
+ */
+ pj_uint32_t ip_dst;
+
+ /**
+ * Specify source port of the packets, or zero to include packets with
+ * any source port number. Note that the port number must be in network
+ * byte order.
+ */
+ pj_uint16_t src_port;
+
+ /**
+ * Specify destination port of the packets, or zero to include packets with
+ * any destination port number. Note that the port number must be in network
+ * byte order.
+ */
+ pj_uint16_t dst_port;
+
+} pj_pcap_filter;
+
+
+/** Opaque declaration for PCAP file */
+typedef struct pj_pcap_file pj_pcap_file;
+
+
+/**
+ * Initialize filter with default values. The default value is to allow
+ * any packets.
+ *
+ * @param filter Filter to be initialized.
+ */
+PJ_DECL(void) pj_pcap_filter_default(pj_pcap_filter *filter);
+
+/**
+ * Open PCAP file.
+ *
+ * @param pool Pool to allocate memory.
+ * @param path File/path name.
+ * @param p_file Pointer to receive PCAP file handle.
+ *
+ * @return PJ_SUCCESS if file can be opened successfully.
+ */
+PJ_DECL(pj_status_t) pj_pcap_open(pj_pool_t *pool,
+ const char *path,
+ pj_pcap_file **p_file);
+
+/**
+ * Close PCAP file.
+ *
+ * @param file PCAP file handle.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_pcap_close(pj_pcap_file *file);
+
+/**
+ * Configure filter for reading the file. When filter is configured,
+ * only packets matching all the filter settings will be returned.
+ *
+ * @param file PCAP file handle.
+ * @param filter The filter.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_pcap_set_filter(pj_pcap_file *file,
+ const pj_pcap_filter *filter);
+
+/**
+ * Read UDP payload from the next packet in the PCAP file. Optionally it
+ * can return the UDP header, if caller supplies it.
+ *
+ * @param file PCAP file handle.
+ * @param udp_hdr Optional buffer to receive UDP header.
+ * @param udp_payload Buffer to receive the UDP payload.
+ * @param udp_payload_size On input, specify the size of the buffer.
+ * On output, it will be filled with the actual size
+ * of the payload as read from the packet.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_pcap_read_udp(pj_pcap_file *file,
+ pj_pcap_udp_hdr *udp_hdr,
+ pj_uint8_t *udp_payload,
+ pj_size_t *udp_payload_size);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJLIB_UTIL_PCAP_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/resolver.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/resolver.h
new file mode 100644
index 0000000..5d124b3
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/resolver.h
@@ -0,0 +1,460 @@
+/* $Id: resolver.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_RESOLVER_H__
+#define __PJLIB_UTIL_RESOLVER_H__
+
+/**
+ * @file resolver.h
+ * @brief Asynchronous DNS resolver
+ */
+#include <pjlib-util/dns.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_DNS_RESOLVER DNS Asynchronous/Caching Resolution Engine
+ * @ingroup PJ_DNS
+ * @{
+ *
+ * This module manages the host/server resolution by performing asynchronous
+ * DNS queries and caching the results in the cache. It uses PJLIB-UTIL
+ * low-level DNS parsing functions (see @ref PJ_DNS) and currently supports
+ * several types of DNS resource records such as A record (typical query with
+ * gethostbyname()) and SRV record.
+ *
+ * \section PJ_DNS_RESOLVER_FEATURES Features
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_ASYNC Asynchronous Query and Query Aggregation
+ *
+ * The DNS queries are performed asychronously, with timeout setting
+ * configured on per resolver instance basis. Application can issue multiple
+ * asynchronous queries simultaneously. Subsequent queries to the same resource
+ * (name and DNS resource type) while existing query is still pending will be
+ * merged into one query, so that only one DNS request packet is issued.
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_RETRANSMISSION Query Retransmission
+ *
+ * Asynchronous query will be retransmitted if no response is received
+ * within the preconfigured time. Once maximum retransmission count is
+ * exceeded and no response is received, the query will time out and the
+ * callback will be called when error status.
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_CACHING Response Caching with TTL
+ *
+ * The resolver instance caches the results returned by nameservers, to
+ * enhance the performance by minimizing the message round-trip to the server.
+ * The TTL of the cached resposne is calculated from minimum TTL value found
+ * across all resource record (RR) TTL in the response and further more it can
+ * be limited to some preconfigured maximum TTL in the resolver.
+ *
+ * Response caching can be disabled by setting the maximum TTL value of the
+ * resolver to zero.
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_PARALLEL Parallel and Backup Name Servers
+ *
+ * When the resolver is configured with multiple nameservers, initially the
+ * queries will be issued to multiple name servers simultaneously to probe
+ * which servers are not active. Once the probing stage is done, subsequent
+ * queries will be directed to only one ACTIVE server which provides the best
+ * response time.
+ *
+ * Name servers are probed periodically to see which nameservers are active
+ * and which are down. This probing is done when a query is sent, thus no
+ * timer is needed to maintain this. Also probing will be done in parallel
+ * so that there would be no additional delay for the query.
+ *
+ *
+ * \subsection PJ_DNS_RESOLVER_FEATURES_REC Supported Resource Records
+ *
+ * The low-level DNS parsing utility (see @ref PJ_DNS) supports parsing of
+ * the following DNS resource records (RR):
+ * - DNS A record
+ * - DNS SRV record
+ * - DNS PTR record
+ * - DNS NS record
+ * - DNS CNAME record
+ *
+ * For other types of record, application can parse the raw resource
+ * record data (rdata) from the parsed DNS packet (#pj_dns_parsed_packet).
+ *
+ *
+ * \section PJ_DNS_RESOLVER_USING Using the Resolver
+ *
+ * To use the resolver, application first creates the resolver instance by
+ * calling #pj_dns_resolver_create(). If application already has its own
+ * timer and ioqueue instances, it can instruct the resolver to use these
+ * instances so that application does not need to poll the resolver
+ * periodically to process events. If application does not specify the
+ * timer and ioqueue instance for the resolver, an internal timer and
+ * ioqueue will be created by the resolver. And since the resolver does not
+ * create it's own thread, application MUST poll the resolver periodically
+ * by calling #pj_dns_resolver_handle_events() to allow events (network and
+ * timer) to be processed.
+ *
+ * Next, application MUST configure the nameservers to be used by the
+ * resolver, by calling #pj_dns_resolver_set_ns().
+ *
+ * Application performs asynchronous query by submitting the query with
+ * #pj_dns_resolver_start_query(). Once the query completes (either
+ * successfully or times out), the callback will be called.
+ *
+ * Application can cancel a pending query by calling #pj_dns_resolver_cancel_query().
+ *
+ * Resolver must be destroyed by calling #pj_dns_resolver_destroy() to
+ * release all resources back to the system.
+ *
+ *
+ * \section PJ_DNS_RESOLVER_LIMITATIONS Resolver Limitations
+ *
+ * Current implementation mainly suffers from a growing memory problem,
+ * which mainly is caused by the response caching. Although there is only
+ * one cache entry per {query, name} combination, these cache entry will
+ * never get deleted since there is no timer is created to invalidate these
+ * entries. So the more unique names being queried by application, there more
+ * enties will be created in the response cache.
+ *
+ * Note that a single response entry will occupy about 600-700 bytes of
+ * pool memory (the PJ_DNS_RESOLVER_RES_BUF_SIZE value plus internal
+ * structure).
+ *
+ * Application can work around this problem by doing one of these:
+ * - disable caching by setting PJ_DNS_RESOLVER_MAX_TTL and
+ * PJ_DNS_RESOLVER_INVALID_TTL to zero.
+ * - periodically query #pj_dns_resolver_get_cached_count() and destroy-
+ * recreate the resolver to recycle the memory used by the resolver.
+ *
+ * Note that future improvement may solve this problem by introducing
+ * expiration timer to the cached entries.
+ *
+ *
+ * \section PJ_DNS_RESOLVER_REFERENCE Reference
+ *
+ * The PJLIB-UTIL resolver was built from the information in the following
+ * standards:
+ * - <A HREF="http://www.faqs.org/rfcs/rfc1035.html">
+ * RFC 1035: "Domain names - implementation and specification"</A>
+ * - <A HREF="http://www.faqs.org/rfcs/rfc2782.html">
+ * RFC 2782: "A DNS RR for specifying the location of services (DNS SRV)"
+ * </A>
+ */
+
+
+
+/**
+ * Opaque data type for DNS resolver object.
+ */
+typedef struct pj_dns_resolver pj_dns_resolver;
+
+/**
+ * Opaque data type for asynchronous DNS query object.
+ */
+typedef struct pj_dns_async_query pj_dns_async_query;
+
+/**
+ * Type of asynchronous callback which will be called when the asynchronous
+ * query completes.
+ *
+ * @param user_data The user data set by application when creating the
+ * asynchronous query.
+ * @param status Status of the DNS resolution.
+ * @param response The response packet received from the server. This
+ * argument may be NULL when status is not PJ_SUCCESS.
+ */
+typedef void pj_dns_callback(void *user_data,
+ pj_status_t status,
+ pj_dns_parsed_packet *response);
+
+
+/**
+ * This structure describes resolver settings.
+ */
+typedef struct pj_dns_settings
+{
+ unsigned options; /**< Options flags. */
+ unsigned qretr_delay; /**< Query retransmit delay in msec. */
+ unsigned qretr_count; /**< Query maximum retransmission count. */
+ unsigned cache_max_ttl; /**< Maximum TTL for cached responses. If the
+ value is zero, caching is disabled. */
+ unsigned good_ns_ttl; /**< See #PJ_DNS_RESOLVER_GOOD_NS_TTL */
+ unsigned bad_ns_ttl; /**< See #PJ_DNS_RESOLVER_BAD_NS_TTL */
+} pj_dns_settings;
+
+
+/**
+ * This structure represents DNS A record, as the result of parsing
+ * DNS response packet using #pj_dns_parse_a_response().
+ */
+typedef struct pj_dns_a_record
+{
+ /** The target name being queried. */
+ pj_str_t name;
+
+ /** If target name corresponds to a CNAME entry, the alias contains
+ * the value of the CNAME entry, otherwise it will be empty.
+ */
+ pj_str_t alias;
+
+ /** Number of IP addresses. */
+ unsigned addr_count;
+
+ /** IP addresses of the host found in the response */
+ pj_in_addr addr[PJ_DNS_MAX_IP_IN_A_REC];
+
+ /** Internal buffer for hostname and alias. */
+ char buf_[128];
+
+} pj_dns_a_record;
+
+
+/**
+ * Set default values to the DNS settings.
+ *
+ * @param s The DNS settings to be initialized.
+ */
+PJ_DECL(void) pj_dns_settings_default(pj_dns_settings *s);
+
+
+/**
+ * Create DNS resolver instance. After the resolver is created, application
+ * MUST configure the nameservers with #pj_dns_resolver_set_ns().
+ *
+ * When creating the resolver, application may specify both timer heap
+ * and ioqueue instance, so that it doesn't need to poll the resolver
+ * periodically.
+ *
+ * @param pf Pool factory where the memory pool will be created from.
+ * @param name Optional resolver name to identify the instance in
+ * the log.
+ * @param options Optional options, must be zero for now.
+ * @param timer Optional timer heap instance to be used by the resolver.
+ * If timer heap is not specified, an internal timer will be
+ * created, and application would need to poll the resolver
+ * periodically.
+ * @param ioqueue Optional I/O Queue instance to be used by the resolver.
+ * If ioqueue is not specified, an internal one will be
+ * created, and application would need to poll the resolver
+ * periodically.
+ * @param p_resolver Pointer to receive the resolver instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_create(pj_pool_factory *pf,
+ const char *name,
+ unsigned options,
+ pj_timer_heap_t *timer,
+ pj_ioqueue_t *ioqueue,
+ pj_dns_resolver **p_resolver);
+
+
+/**
+ * Update the name servers for the DNS resolver. The name servers MUST be
+ * configured before any resolution can be done. The order of nameservers
+ * specifies their priority; the first name server will be tried first
+ * before the next in the list.
+ *
+ * @param resolver The resolver instance.
+ * @param count Number of name servers in the array.
+ * @param servers Array of name server IP addresses or hostnames. If
+ * hostname is specified, the hostname must be resolvable
+ * with pj_gethostbyname().
+ * @param ports Optional array of ports. If this argument is NULL,
+ * the nameserver will use default port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_set_ns(pj_dns_resolver *resolver,
+ unsigned count,
+ const pj_str_t servers[],
+ const pj_uint16_t ports[]);
+
+
+/**
+ * Get the resolver current settings.
+ *
+ * @param resolver The resolver instance.
+ * @param st Buffer to be filled up with resolver settings.
+ *
+ * @return The query timeout setting, in seconds.
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_get_settings(pj_dns_resolver *resolver,
+ pj_dns_settings *st);
+
+
+/**
+ * Modify the resolver settings. Application should initialize the settings
+ * by retrieving current settings first before applying new settings, to
+ * ensure that all fields are initialized properly.
+ *
+ * @param resolver The resolver instance.
+ * @param st The resolver settings.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_set_settings(pj_dns_resolver *resolver,
+ const pj_dns_settings *st);
+
+
+/**
+ * Poll for events from the resolver. This function MUST be called
+ * periodically when the resolver is using it's own timer or ioqueue
+ * (in other words, when NULL is specified as either \a timer or
+ * \a ioqueue argument in #pj_dns_resolver_create()).
+ *
+ * @param resolver The resolver instance.
+ * @param timeout Maximum time to wait for event occurence. If this
+ * argument is NULL, this function will wait forever
+ * until events occur.
+ */
+PJ_DECL(void) pj_dns_resolver_handle_events(pj_dns_resolver *resolver,
+ const pj_time_val *timeout);
+
+
+/**
+ * Destroy DNS resolver instance.
+ *
+ * @param resolver The resolver object to be destryed
+ * @param notify If non-zero, all pending asynchronous queries will be
+ * cancelled and its callback will be called. If FALSE,
+ * then no callback will be called.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_destroy(pj_dns_resolver *resolver,
+ pj_bool_t notify);
+
+
+/**
+ * Create and start asynchronous DNS query for a single resource. Depending
+ * on whether response cache is available, this function will either start
+ * an asynchronous DNS query or call the callback immediately.
+ *
+ * If response is not available in the cache, an asynchronous query will be
+ * started, and callback will be called at some time later when the query
+ * completes. If \a p_query argument is not NULL, it will be filled with
+ * the asynchronous query object.
+ *
+ * If response is available in the cache, the callback will be called
+ * immediately before this function returns. In this case, if \a p_query
+ * argument is not NULL, the value will be set to NULL since no new query
+ * is started.
+ *
+ * @param resolver The resolver object.
+ * @param name The name to be resolved.
+ * @param type The type of resource (see #pj_dns_type constants).
+ * @param options Optional options, must be zero for now.
+ * @param cb Callback to be called when the query completes,
+ * either successfully or with failure.
+ * @param user_data Arbitrary user data to be associated with the query,
+ * and which will be given back in the callback.
+ * @param p_query Optional pointer to receive the query object, if one
+ * was started. If this pointer is specified, a NULL may
+ * be returned if response cache is available immediately.
+ *
+ * @return PJ_SUCCESS if either an asynchronous query has been
+ * started successfully or response cache is available and
+ * the user callback has been called.
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_start_query(pj_dns_resolver *resolver,
+ const pj_str_t *name,
+ int type,
+ unsigned options,
+ pj_dns_callback *cb,
+ void *user_data,
+ pj_dns_async_query **p_query);
+
+/**
+ * Cancel a pending query.
+ *
+ * @param query The pending asynchronous query to be cancelled.
+ * @param notify If non-zero, the callback will be called with failure
+ * status to notify that the query has been cancelled.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_cancel_query(pj_dns_async_query *query,
+ pj_bool_t notify);
+
+/**
+ * A utility function to parse a DNS response containing A records into
+ * DNS A record.
+ *
+ * @param pkt The DNS response packet.
+ * @param rec The structure to be initialized with the parsed
+ * DNS A record from the packet.
+ *
+ * @return PJ_SUCCESS if response can be parsed successfully.
+ */
+PJ_DECL(pj_status_t) pj_dns_parse_a_response(const pj_dns_parsed_packet *pkt,
+ pj_dns_a_record *rec);
+
+
+/**
+ * Put the specified DNS packet into DNS cache. This function is mainly used
+ * for testing the resolver, however it can also be used to inject entries
+ * into the resolver.
+ *
+ * The packet MUST contain either answer section or query section so that
+ * it can be indexed.
+ *
+ * @param resolver The resolver instance.
+ * @param pkt DNS packet to be added to the DNS cache. If the packet
+ * matches existing entry, it will update the entry.
+ * @param set_ttl If the value is PJ_FALSE, the entry will not expire
+ * (so use with care). Otherwise cache expiration will be
+ * calculated based on the TTL of the answeres.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_dns_resolver_add_entry(pj_dns_resolver *resolver,
+ const pj_dns_parsed_packet *pkt,
+ pj_bool_t set_ttl);
+
+/**
+ * Get the total number of response in the response cache.
+ *
+ * @param resolver The resolver instance.
+ *
+ * @return Current number of entries being stored in the response
+ * cache.
+ */
+PJ_DECL(unsigned) pj_dns_resolver_get_cached_count(pj_dns_resolver *resolver);
+
+
+/**
+ * Dump resolver state to the log.
+ *
+ * @param resolver The resolver instance.
+ * @param detail Will print detailed entries.
+ */
+PJ_DECL(void) pj_dns_resolver_dump(pj_dns_resolver *resolver,
+ pj_bool_t detail);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_RESOLVER_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner.h
new file mode 100644
index 0000000..cf7c0a0
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner.h
@@ -0,0 +1,555 @@
+/* $Id: scanner.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_SCANNER_H__
+#define __PJ_SCANNER_H__
+
+/**
+ * @file scanner.h
+ * @brief Text Scanning.
+ */
+
+#include <pjlib-util/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_SCAN Fast Text Scanning
+ * @ingroup PJLIB_TEXT
+ * @brief Text scanning utility.
+ *
+ * This module describes a fast text scanning functions.
+ *
+ * @{
+ */
+#if defined(PJ_SCANNER_USE_BITWISE) && PJ_SCANNER_USE_BITWISE != 0
+# include <pjlib-util/scanner_cis_bitwise.h>
+#else
+# include <pjlib-util/scanner_cis_uint.h>
+#endif
+
+/**
+ * Initialize scanner input specification buffer.
+ *
+ * @param cs_buf The scanner character specification.
+ */
+PJ_DECL(void) pj_cis_buf_init(pj_cis_buf_t *cs_buf);
+
+/**
+ * Create a new input specification.
+ *
+ * @param cs_buf Specification buffer.
+ * @param cis Character input specification to be initialized.
+ *
+ * @return PJ_SUCCESS if new specification has been successfully
+ * created, or PJ_ETOOMANY if there are already too many
+ * specifications in the buffer.
+ */
+PJ_DECL(pj_status_t) pj_cis_init(pj_cis_buf_t *cs_buf, pj_cis_t *cis);
+
+/**
+ * Create a new input specification based on an existing specification.
+ *
+ * @param new_cis The new specification to be initialized.
+ * @param existing The existing specification, from which the input
+ * bitmask will be copied to the new specification.
+ *
+ * @return PJ_SUCCESS if new specification has been successfully
+ * created, or PJ_ETOOMANY if there are already too many
+ * specifications in the buffer.
+ */
+PJ_DECL(pj_status_t) pj_cis_dup(pj_cis_t *new_cis, pj_cis_t *existing);
+
+/**
+ * Add the characters in the specified range '[cstart, cend)' to the
+ * specification (the last character itself ('cend') is not added).
+ *
+ * @param cis The scanner character specification.
+ * @param cstart The first character in the range.
+ * @param cend The next character after the last character in the range.
+ */
+PJ_DECL(void) pj_cis_add_range( pj_cis_t *cis, int cstart, int cend);
+
+/**
+ * Add alphabetic characters to the specification.
+ *
+ * @param cis The scanner character specification.
+ */
+PJ_DECL(void) pj_cis_add_alpha( pj_cis_t *cis);
+
+/**
+ * Add numeric characters to the specification.
+ *
+ * @param cis The scanner character specification.
+ */
+PJ_DECL(void) pj_cis_add_num( pj_cis_t *cis);
+
+/**
+ * Add the characters in the string to the specification.
+ *
+ * @param cis The scanner character specification.
+ * @param str The string.
+ */
+PJ_DECL(void) pj_cis_add_str( pj_cis_t *cis, const char *str);
+
+/**
+ * Add specification from another specification.
+ *
+ * @param cis The specification is to be set.
+ * @param rhs The specification to be copied.
+ */
+PJ_DECL(void) pj_cis_add_cis( pj_cis_t *cis, const pj_cis_t *rhs);
+
+/**
+ * Delete characters in the specified range from the specification.
+ *
+ * @param cis The scanner character specification.
+ * @param cstart The first character in the range.
+ * @param cend The next character after the last character in the range.
+ */
+PJ_DECL(void) pj_cis_del_range( pj_cis_t *cis, int cstart, int cend);
+
+/**
+ * Delete characters in the specified string from the specification.
+ *
+ * @param cis The scanner character specification.
+ * @param str The string.
+ */
+PJ_DECL(void) pj_cis_del_str( pj_cis_t *cis, const char *str);
+
+/**
+ * Invert specification.
+ *
+ * @param cis The scanner character specification.
+ */
+PJ_DECL(void) pj_cis_invert( pj_cis_t *cis );
+
+/**
+ * Check whether the specified character belongs to the specification.
+ *
+ * @param cis The scanner character specification.
+ * @param c The character to check for matching.
+ *
+ * @return Non-zero if match (not necessarily one).
+ */
+PJ_INLINE(int) pj_cis_match( const pj_cis_t *cis, pj_uint8_t c )
+{
+ return PJ_CIS_ISSET(cis, c);
+}
+
+
+/**
+ * Flags for scanner.
+ */
+enum
+{
+ /** This flags specifies that the scanner should automatically skip
+ whitespaces
+ */
+ PJ_SCAN_AUTOSKIP_WS = 1,
+
+ /** This flags specifies that the scanner should automatically skip
+ SIP header continuation. This flag implies PJ_SCAN_AUTOSKIP_WS.
+ */
+ PJ_SCAN_AUTOSKIP_WS_HEADER = 3,
+
+ /** Auto-skip new lines.
+ */
+ PJ_SCAN_AUTOSKIP_NEWLINE = 4
+};
+
+
+/* Forward decl. */
+struct pj_scanner;
+
+
+/**
+ * The callback function type to be called by the scanner when it encounters
+ * syntax error.
+ *
+ * @param scanner The scanner instance that calls the callback .
+ */
+typedef void (*pj_syn_err_func_ptr)(struct pj_scanner *scanner);
+
+
+/**
+ * The text scanner structure.
+ */
+typedef struct pj_scanner
+{
+ char *begin; /**< Start of input buffer. */
+ char *end; /**< End of input buffer. */
+ char *curptr; /**< Current pointer. */
+ int line; /**< Current line. */
+ char *start_line; /**< Where current line starts. */
+ int skip_ws; /**< Skip whitespace flag. */
+ pj_syn_err_func_ptr callback; /**< Syntax error callback. */
+} pj_scanner;
+
+
+/**
+ * This structure can be used by application to store the state of the parser,
+ * so that the scanner state can be rollback to this state when necessary.
+ */
+typedef struct pj_scan_state
+{
+ char *curptr; /**< Current scanner's pointer. */
+ int line; /**< Current line. */
+ char *start_line; /**< Start of current line. */
+} pj_scan_state;
+
+
+/**
+ * Initialize the scanner. Note that the input string buffer must have
+ * length at least buflen+1 because the scanner will NULL terminate the
+ * string during initialization.
+ *
+ * @param scanner The scanner to be initialized.
+ * @param bufstart The input buffer to scan. Note that buffer[buflen] will be
+ * filled with NULL char until scanner is destroyed, so
+ * the actual buffer length must be at least buflen+1.
+ * @param buflen The length of the input buffer, which normally is
+ * strlen(bufstart).
+ * @param options Zero, or combination of PJ_SCAN_AUTOSKIP_WS or
+ * PJ_SCAN_AUTOSKIP_WS_HEADER
+ * @param callback Callback to be called when the scanner encounters syntax
+ * error condition.
+ */
+PJ_DECL(void) pj_scan_init( pj_scanner *scanner, char *bufstart, int buflen,
+ unsigned options,
+ pj_syn_err_func_ptr callback );
+
+
+/**
+ * Call this function when application has finished using the scanner.
+ *
+ * @param scanner The scanner.
+ */
+PJ_DECL(void) pj_scan_fini( pj_scanner *scanner );
+
+
+/**
+ * Determine whether the EOF condition for the scanner has been met.
+ *
+ * @param scanner The scanner.
+ *
+ * @return Non-zero if scanner is EOF.
+ */
+PJ_INLINE(int) pj_scan_is_eof( const pj_scanner *scanner)
+{
+ return scanner->curptr >= scanner->end;
+}
+
+
+/**
+ * Peek strings in current position according to parameter spec, and return
+ * the strings in parameter out. The current scanner position will not be
+ * moved. If the scanner is already in EOF state, syntax error callback will
+ * be called thrown.
+ *
+ * @param scanner The scanner.
+ * @param spec The spec to match input string.
+ * @param out String to store the result.
+ *
+ * @return the character right after the peek-ed position or zero if there's
+ * no more characters.
+ */
+PJ_DECL(int) pj_scan_peek( pj_scanner *scanner,
+ const pj_cis_t *spec, pj_str_t *out);
+
+
+/**
+ * Peek len characters in current position, and return them in out parameter.
+ * Note that whitespaces or newlines will be returned as it is, regardless
+ * of PJ_SCAN_AUTOSKIP_WS settings. If the character left is less than len,
+ * syntax error callback will be called.
+ *
+ * @param scanner The scanner.
+ * @param len Length to peek.
+ * @param out String to store the result.
+ *
+ * @return the character right after the peek-ed position or zero if there's
+ * no more characters.
+ */
+PJ_DECL(int) pj_scan_peek_n( pj_scanner *scanner,
+ pj_size_t len, pj_str_t *out);
+
+
+/**
+ * Peek strings in current position until spec is matched, and return
+ * the strings in parameter out. The current scanner position will not be
+ * moved. If the scanner is already in EOF state, syntax error callback will
+ * be called.
+ *
+ * @param scanner The scanner.
+ * @param spec The peeking will stop when the input match this spec.
+ * @param out String to store the result.
+ *
+ * @return the character right after the peek-ed position.
+ */
+PJ_DECL(int) pj_scan_peek_until( pj_scanner *scanner,
+ const pj_cis_t *spec,
+ pj_str_t *out);
+
+
+/**
+ * Get characters from the buffer according to the spec, and return them
+ * in out parameter. The scanner will attempt to get as many characters as
+ * possible as long as the spec matches. If the first character doesn't
+ * match the spec, or scanner is already in EOF when this function is called,
+ * an exception will be thrown.
+ *
+ * @param scanner The scanner.
+ * @param spec The spec to match input string.
+ * @param out String to store the result.
+ */
+PJ_DECL(void) pj_scan_get( pj_scanner *scanner,
+ const pj_cis_t *spec, pj_str_t *out);
+
+
+/**
+ * Just like #pj_scan_get(), but additionally performs unescaping when
+ * escaped ('%') character is found. The input spec MUST NOT contain the
+ * specification for '%' characted.
+ *
+ * @param scanner The scanner.
+ * @param spec The spec to match input string.
+ * @param out String to store the result.
+ */
+PJ_DECL(void) pj_scan_get_unescape( pj_scanner *scanner,
+ const pj_cis_t *spec, pj_str_t *out);
+
+
+/**
+ * Get characters between quotes. If current input doesn't match begin_quote,
+ * syntax error will be thrown. Note that the resulting string will contain
+ * the enclosing quote.
+ *
+ * @param scanner The scanner.
+ * @param begin_quote The character to begin the quote.
+ * @param end_quote The character to end the quote.
+ * @param out String to store the result.
+ */
+PJ_DECL(void) pj_scan_get_quote( pj_scanner *scanner,
+ int begin_quote, int end_quote,
+ pj_str_t *out);
+
+/**
+ * Get characters between quotes. If current input doesn't match begin_quote,
+ * syntax error will be thrown. Note that the resulting string will contain
+ * the enclosing quote.
+ *
+ * @param scanner The scanner.
+ * @param begin_quotes The character array to begin the quotes. For example,
+ * the two characters " and '.
+ * @param end_quotes The character array to end the quotes. The position
+ * found in the begin_quotes array will be used to match
+ * the end quotes. So if the begin_quotes was the array
+ * of "'< the end_quotes should be "'>. If begin_array
+ * matched the ' then the end_quotes will look for ' to
+ * match at the end.
+ * @param qsize The size of the begin_quotes and end_quotes arrays.
+ * @param out String to store the result.
+ */
+PJ_DECL(void) pj_scan_get_quotes(pj_scanner *scanner,
+ const char *begin_quotes,
+ const char *end_quotes, int qsize,
+ pj_str_t *out);
+
+
+/**
+ * Get N characters from the scanner.
+ *
+ * @param scanner The scanner.
+ * @param N Number of characters to get.
+ * @param out String to store the result.
+ */
+PJ_DECL(void) pj_scan_get_n( pj_scanner *scanner,
+ unsigned N, pj_str_t *out);
+
+
+/**
+ * Get one character from the scanner.
+ *
+ * @param scanner The scanner.
+ *
+ * @return The character.
+ */
+PJ_DECL(int) pj_scan_get_char( pj_scanner *scanner );
+
+
+/**
+ * Get characters from the scanner and move the scanner position until the
+ * current character matches the spec.
+ *
+ * @param scanner The scanner.
+ * @param spec Get until the input match this spec.
+ * @param out String to store the result.
+ */
+PJ_DECL(void) pj_scan_get_until( pj_scanner *scanner,
+ const pj_cis_t *spec, pj_str_t *out);
+
+
+/**
+ * Get characters from the scanner and move the scanner position until the
+ * current character matches until_char.
+ *
+ * @param scanner The scanner.
+ * @param until_char Get until the input match this character.
+ * @param out String to store the result.
+ */
+PJ_DECL(void) pj_scan_get_until_ch( pj_scanner *scanner,
+ int until_char, pj_str_t *out);
+
+
+/**
+ * Get characters from the scanner and move the scanner position until the
+ * current character matches until_char.
+ *
+ * @param scanner The scanner.
+ * @param until_spec Get until the input match any of these characters.
+ * @param out String to store the result.
+ */
+PJ_DECL(void) pj_scan_get_until_chr( pj_scanner *scanner,
+ const char *until_spec, pj_str_t *out);
+
+/**
+ * Advance the scanner N characters, and skip whitespace
+ * if necessary.
+ *
+ * @param scanner The scanner.
+ * @param N Number of characters to skip.
+ * @param skip Flag to specify whether whitespace should be skipped
+ * after skipping the characters.
+ */
+PJ_DECL(void) pj_scan_advance_n( pj_scanner *scanner,
+ unsigned N, pj_bool_t skip);
+
+
+/**
+ * Compare string in current position with the specified string.
+ *
+ * @param scanner The scanner.
+ * @param s The string to compare with.
+ * @param len Length of the string to compare.
+ *
+ * @return zero, <0, or >0 (just like strcmp()).
+ */
+PJ_DECL(int) pj_scan_strcmp( pj_scanner *scanner, const char *s, int len);
+
+
+/**
+ * Case-less string comparison of current position with the specified
+ * string.
+ *
+ * @param scanner The scanner.
+ * @param s The string to compare with.
+ * @param len Length of the string to compare with.
+ *
+ * @return zero, <0, or >0 (just like strcmp()).
+ */
+PJ_DECL(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len);
+
+/**
+ * Perform case insensitive string comparison of string in current position,
+ * knowing that the string to compare only consists of alphanumeric
+ * characters.
+ *
+ * Note that unlike #pj_scan_stricmp, this function can only return zero or
+ * -1.
+ *
+ * @param scanner The scanner.
+ * @param s The string to compare with.
+ * @param len Length of the string to compare with.
+ *
+ * @return zero if equal or -1.
+ *
+ * @see strnicmp_alnum, pj_stricmp_alnum
+ */
+PJ_DECL(int) pj_scan_stricmp_alnum( pj_scanner *scanner, const char *s,
+ int len);
+
+
+/**
+ * Get a newline from the scanner. A newline is defined as '\\n', or '\\r', or
+ * "\\r\\n". If current input is not newline, syntax error will be thrown.
+ *
+ * @param scanner The scanner.
+ */
+PJ_DECL(void) pj_scan_get_newline( pj_scanner *scanner );
+
+
+/**
+ * Manually skip whitespaces according to flag that was specified when
+ * the scanner was initialized.
+ *
+ * @param scanner The scanner.
+ */
+PJ_DECL(void) pj_scan_skip_whitespace( pj_scanner *scanner );
+
+
+/**
+ * Skip current line.
+ *
+ * @param scanner The scanner.
+ */
+PJ_DECL(void) pj_scan_skip_line( pj_scanner *scanner );
+
+/**
+ * Save the full scanner state.
+ *
+ * @param scanner The scanner.
+ * @param state Variable to store scanner's state.
+ */
+PJ_DECL(void) pj_scan_save_state( const pj_scanner *scanner,
+ pj_scan_state *state);
+
+
+/**
+ * Restore the full scanner state.
+ * Note that this would not restore the string if application has modified
+ * it. This will only restore the scanner scanning position.
+ *
+ * @param scanner The scanner.
+ * @param state State of the scanner.
+ */
+PJ_DECL(void) pj_scan_restore_state( pj_scanner *scanner,
+ pj_scan_state *state);
+
+/**
+ * Get current column position.
+ *
+ * @param scanner The scanner.
+ *
+ * @return The column position.
+ */
+PJ_INLINE(int) pj_scan_get_col( const pj_scanner *scanner )
+{
+ return (int)(scanner->curptr - scanner->start_line);
+}
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+#endif
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h
new file mode 100644
index 0000000..25307ca
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h
@@ -0,0 +1,97 @@
+/* $Id: scanner_cis_bitwise.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_SCANNER_CIS_BIT_H__
+#define __PJLIB_UTIL_SCANNER_CIS_BIT_H__
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * This describes the type of individual character specification in
+ * #pj_cis_buf_t. Basicly the number of bits here
+ */
+#ifndef PJ_CIS_ELEM_TYPE
+# define PJ_CIS_ELEM_TYPE pj_uint32_t
+#endif
+
+/**
+ * This describes the type of individual character specification in
+ * #pj_cis_buf_t.
+ */
+typedef PJ_CIS_ELEM_TYPE pj_cis_elem_t;
+
+/**
+ * Maximum number of input specification in a buffer.
+ * Effectively this means the number of bits in pj_cis_elem_t.
+ */
+#define PJ_CIS_MAX_INDEX (sizeof(pj_cis_elem_t) << 3)
+
+/**
+ * The scanner input specification buffer.
+ */
+typedef struct pj_cis_buf_t
+{
+ pj_cis_elem_t cis_buf[256]; /**< Must be 256 (not 128)! */
+ pj_cis_elem_t use_mask; /**< To keep used indexes. */
+} pj_cis_buf_t;
+
+/**
+ * Character input specification.
+ */
+typedef struct pj_cis_t
+{
+ pj_cis_elem_t *cis_buf; /**< Pointer to buffer. */
+ int cis_id; /**< Id. */
+} pj_cis_t;
+
+
+/**
+ * Set the membership of the specified character.
+ * Note that this is a macro, and arguments may be evaluated more than once.
+ *
+ * @param cis Pointer to character input specification.
+ * @param c The character.
+ */
+#define PJ_CIS_SET(cis,c) ((cis)->cis_buf[(int)(c)] |= (1 << (cis)->cis_id))
+
+/**
+ * Remove the membership of the specified character.
+ * Note that this is a macro, and arguments may be evaluated more than once.
+ *
+ * @param cis Pointer to character input specification.
+ * @param c The character to be removed from the membership.
+ */
+#define PJ_CIS_CLR(cis,c) ((cis)->cis_buf[(int)c] &= ~(1 << (cis)->cis_id))
+
+/**
+ * Check the membership of the specified character.
+ * Note that this is a macro, and arguments may be evaluated more than once.
+ *
+ * @param cis Pointer to character input specification.
+ * @param c The character.
+ */
+#define PJ_CIS_ISSET(cis,c) ((cis)->cis_buf[(int)c] & (1 << (cis)->cis_id))
+
+
+
+PJ_END_DECL
+
+#endif /* __PJLIB_UTIL_SCANNER_CIS_BIT_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_uint.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_uint.h
new file mode 100644
index 0000000..6b50405
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_uint.h
@@ -0,0 +1,84 @@
+/* $Id: scanner_cis_uint.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_SCANNER_CIS_BIT_H__
+#define __PJLIB_UTIL_SCANNER_CIS_BIT_H__
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * This describes the type of individual character specification in
+ * #pj_cis_buf_t. Basicly the number of bits here
+ */
+#ifndef PJ_CIS_ELEM_TYPE
+# define PJ_CIS_ELEM_TYPE int
+#endif
+
+/**
+ * This describes the type of individual character specification in
+ * #pj_cis_buf_t.
+ */
+typedef PJ_CIS_ELEM_TYPE pj_cis_elem_t;
+
+/** pj_cis_buf_t is not used when uint back-end is used. */
+typedef int pj_cis_buf_t;
+
+/**
+ * Character input specification.
+ */
+typedef struct pj_cis_t
+{
+ PJ_CIS_ELEM_TYPE cis_buf[256]; /**< Internal buffer. */
+} pj_cis_t;
+
+
+/**
+ * Set the membership of the specified character.
+ * Note that this is a macro, and arguments may be evaluated more than once.
+ *
+ * @param cis Pointer to character input specification.
+ * @param c The character.
+ */
+#define PJ_CIS_SET(cis,c) ((cis)->cis_buf[(int)(c)] = 1)
+
+/**
+ * Remove the membership of the specified character.
+ * Note that this is a macro, and arguments may be evaluated more than once.
+ *
+ * @param cis Pointer to character input specification.
+ * @param c The character to be removed from the membership.
+ */
+#define PJ_CIS_CLR(cis,c) ((cis)->cis_buf[(int)c] = 0)
+
+/**
+ * Check the membership of the specified character.
+ * Note that this is a macro, and arguments may be evaluated more than once.
+ *
+ * @param cis Pointer to character input specification.
+ * @param c The character.
+ */
+#define PJ_CIS_ISSET(cis,c) ((cis)->cis_buf[(int)c])
+
+
+
+PJ_END_DECL
+
+#endif /* __PJLIB_UTIL_SCANNER_CIS_BIT_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/sha1.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/sha1.h
new file mode 100644
index 0000000..cebc6e1
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/sha1.h
@@ -0,0 +1,80 @@
+/* $Id: sha1.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_SHA1_H__
+#define __PJLIB_UTIL_SHA1_H__
+
+/**
+ * @file sha1.h
+ * @brief SHA1 encryption implementation
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJLIB_UTIL_SHA1 SHA1
+ * @ingroup PJLIB_UTIL_ENCRYPTION
+ * @{
+ */
+
+/** SHA1 context */
+typedef struct pj_sha1_context
+{
+ pj_uint32_t state[5]; /**< State */
+ pj_uint32_t count[2]; /**< Count */
+ pj_uint8_t buffer[64]; /**< Buffer */
+} pj_sha1_context;
+
+/** SHA1 digest size is 20 bytes */
+#define PJ_SHA1_DIGEST_SIZE 20
+
+
+/** Initialize the algorithm.
+ * @param ctx SHA1 context.
+ */
+PJ_DECL(void) pj_sha1_init(pj_sha1_context *ctx);
+
+/** Append a stream to the message.
+ * @param ctx SHA1 context.
+ * @param data Data.
+ * @param nbytes Length of data.
+ */
+PJ_DECL(void) pj_sha1_update(pj_sha1_context *ctx,
+ const pj_uint8_t *data,
+ const pj_size_t nbytes);
+
+/** Finish the message and return the digest.
+ * @param ctx SHA1 context.
+ * @param digest 16 byte digest.
+ */
+PJ_DECL(void) pj_sha1_final(pj_sha1_context *ctx,
+ pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE]);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_SHA1_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/srv_resolver.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/srv_resolver.h
new file mode 100644
index 0000000..8880dcf
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/srv_resolver.h
@@ -0,0 +1,215 @@
+/* $Id: srv_resolver.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_SRV_RESOLVER_H__
+#define __PJLIB_UTIL_SRV_RESOLVER_H__
+
+/**
+ * @file srv_resolver.h
+ * @brief DNS SRV resolver
+ */
+#include <pjlib-util/resolver.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_DNS_SRV_RESOLVER DNS SRV Resolution Helper
+ * @ingroup PJ_DNS
+ * @{
+ *
+ * \section PJ_DNS_SRV_RESOLVER_INTRO DNS SRV Resolution Helper
+ *
+ * This module provides an even higher layer of abstraction for the DNS
+ * resolution framework, to resolve DNS SRV names.
+ *
+ * The #pj_dns_srv_resolve() function will asynchronously resolve the server
+ * name into IP address(es) with a single function call. If the SRV name
+ * contains multiple names, then each will be resolved with individual
+ * DNS A resolution to get the IP addresses. Upon successful completion,
+ * application callback will be called with each IP address of the
+ * target selected based on the load-balancing and fail-over criteria
+ * below.
+ *
+ * When the resolver fails to resolve the name using DNS SRV resolution
+ * (for example when the DNS SRV record is not present in the DNS server),
+ * the resolver will fallback to using DNS A record resolution to resolve
+ * the name.
+ *
+ * \subsection PJ_DNS_SRV_RESOLVER_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over
+ *
+ * When multiple targets are returned in the DNS SRV response, server entries
+ * are selected based on the following rule (which is described in RFC 2782):
+ * - targets will be sorted based on the priority first.
+ * - for targets with the same priority, #pj_dns_srv_resolve() will select
+ * only one target according to its weight. To select this one target,
+ * the function associates running-sum for all targets, and generates
+ * a random number between zero and the total running-sum (inclusive).
+ * The target selected is the first target with running-sum greater than
+ * or equal to this random number.
+ *
+ * The above procedure will select one target for each priority, allowing
+ * application to fail-over to the next target when the previous target fails.
+ * These targets are returned in the #pj_dns_srv_record structure
+ * argument of the callback.
+ *
+ * \section PJ_DNS_SRV_RESOLVER_REFERENCE Reference
+ *
+ * Reference:
+ * - <A HREF="http://www.ietf.org/rfc/rfc2782.txt">RFC 2782</A>:
+ * A DNS RR for specifying the location of services (DNS SRV)
+ */
+
+/**
+ * Flags to be specified when starting the DNS SRV query.
+ */
+typedef enum pj_dns_srv_option
+{
+ /**
+ * Specify if the resolver should fallback with DNS A
+ * resolution when the SRV resolution fails. This option may
+ * be specified together with PJ_DNS_SRV_FALLBACK_AAAA to
+ * make the resolver fallback to AAAA if SRV resolution fails,
+ * and then to DNS A resolution if the AAAA resolution fails.
+ */
+ PJ_DNS_SRV_FALLBACK_A = 1,
+
+ /**
+ * Specify if the resolver should fallback with DNS AAAA
+ * resolution when the SRV resolution fails. This option may
+ * be specified together with PJ_DNS_SRV_FALLBACK_A to
+ * make the resolver fallback to AAAA if SRV resolution fails,
+ * and then to DNS A resolution if the AAAA resolution fails.
+ */
+ PJ_DNS_SRV_FALLBACK_AAAA = 2,
+
+ /**
+ * Specify if the resolver should try to resolve with DNS AAAA
+ * resolution first of each targets in the DNS SRV record. If
+ * this option is not specified, the SRV resolver will query
+ * the DNS A record for the target instead.
+ */
+ PJ_DNS_SRV_RESOLVE_AAAA = 4
+
+} pj_dns_srv_option;
+
+
+/**
+ * This structure represents DNS SRV records as the result of DNS SRV
+ * resolution using #pj_dns_srv_resolve().
+ */
+typedef struct pj_dns_srv_record
+{
+ /** Number of address records. */
+ unsigned count;
+
+ /** Address records. */
+ struct
+ {
+ /** Server priority (the lower the higher the priority). */
+ unsigned priority;
+
+ /** Server weight (the higher the more load it can handle). */
+ unsigned weight;
+
+ /** Port number. */
+ pj_uint16_t port;
+
+ /** The host address. */
+ pj_dns_a_record server;
+
+ } entry[PJ_DNS_SRV_MAX_ADDR];
+
+} pj_dns_srv_record;
+
+
+/** Opaque declaration for DNS SRV query */
+typedef struct pj_dns_srv_async_query pj_dns_srv_async_query;
+
+/**
+ * Type of callback function to receive notification from the resolver
+ * when the resolution process completes.
+ */
+typedef void pj_dns_srv_resolver_cb(void *user_data,
+ pj_status_t status,
+ const pj_dns_srv_record *rec);
+
+
+/**
+ * Start DNS SRV resolution for the specified name. The full name of the
+ * entry will be concatenated from \a res_name and \a domain_name fragments.
+ *
+ * @param domain_name The domain name part of the name.
+ * @param res_name The full service name, including the transport name
+ * and with all the leading underscore characters and
+ * ending dot (e.g. "_sip._udp.", "_stun._udp.").
+ * @param def_port The port number to be assigned to the resolved address
+ * when the DNS SRV resolution fails and the name is
+ * resolved with DNS A resolution.
+ * @param pool Memory pool used to allocate memory for the query.
+ * @param resolver The resolver instance.
+ * @param option Option flags, which can be constructed from
+ * #pj_dns_srv_option bitmask. Note that this argument
+ * was called "fallback_a" in pjsip version 0.8.0 and
+ * older, but the new option should be backward
+ * compatible with existing applications. If application
+ * specifies PJ_TRUE as "fallback_a" value, it will
+ * correspond to PJ_DNS_SRV_FALLBACK_A option.
+ * @param token Arbitrary data to be associated with this query when
+ * the calback is called.
+ * @param cb Pointer to callback function to receive the
+ * notification when the resolution process completes.
+ * @param p_query Optional pointer to receive the query object, if one
+ * was started. If this pointer is specified, a NULL may
+ * be returned if response cache is available immediately.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_dns_srv_resolve(const pj_str_t *domain_name,
+ const pj_str_t *res_name,
+ unsigned def_port,
+ pj_pool_t *pool,
+ pj_dns_resolver *resolver,
+ unsigned option,
+ void *token,
+ pj_dns_srv_resolver_cb *cb,
+ pj_dns_srv_async_query **p_query);
+
+
+/**
+ * Cancel an outstanding DNS SRV query.
+ *
+ * @param query The pending asynchronous query to be cancelled.
+ * @param notify If non-zero, the callback will be called with failure
+ * status to notify that the query has been cancelled.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_srv_cancel_query(pj_dns_srv_async_query *query,
+ pj_bool_t notify);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_SRV_RESOLVER_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/string.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/string.h
new file mode 100644
index 0000000..b1b0413
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/string.h
@@ -0,0 +1,102 @@
+/* $Id: string.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_STRING_H__
+#define __PJLIB_UTIL_STRING_H__
+
+/**
+ * @file string.h
+ * @brief More string functions.
+ */
+
+#include <pj/types.h>
+#include <pjlib-util/scanner.h>
+
+/**
+ * @defgroup PJLIB_UTIL_STRING String Escaping Utilities
+ * @ingroup PJLIB_TEXT
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Unescape string. If source string does not contain any escaped
+ * characters, the function would simply return the original string.
+ * Otherwise a new string will be allocated.
+ *
+ * @param pool Pool to allocate the string.
+ * @param src Source string to unescape.
+ *
+ * @return String with no escaped characters.
+ */
+PJ_DECL(pj_str_t) pj_str_unescape( pj_pool_t *pool, const pj_str_t *src);
+
+/**
+ * Unescape string to destination.
+ *
+ * @param dst Target string.
+ * @param src Source string.
+ *
+ * @return Target string.
+ */
+PJ_DECL(pj_str_t*) pj_strcpy_unescape(pj_str_t *dst, const pj_str_t *src);
+
+/**
+ * Copy string to destination while escaping reserved characters, up to
+ * the specified maximum length.
+ *
+ * @param dst Target string.
+ * @param src Source string.
+ * @param max Maximum length to copy to target string.
+ * @param unres Unreserved characters, which are allowed to appear
+ * unescaped.
+ *
+ * @return The target string if all characters have been copied
+ * successfully, or NULL if there's not enough buffer to
+ * escape the strings.
+ */
+PJ_DECL(pj_str_t*) pj_strncpy_escape(pj_str_t *dst, const pj_str_t *src,
+ pj_ssize_t max, const pj_cis_t *unres);
+
+
+/**
+ * Copy string to destination while escaping reserved characters, up to
+ * the specified maximum length.
+ *
+ * @param dst Target string.
+ * @param src Source string.
+ * @param max Maximum length to copy to target string.
+ * @param unres Unreserved characters, which are allowed to appear
+ * unescaped.
+ *
+ * @return The length of the destination, or -1 if there's not
+ * enough buffer.
+ */
+PJ_DECL(pj_ssize_t) pj_strncpy2_escape(char *dst, const pj_str_t *src,
+ pj_ssize_t max, const pj_cis_t *unres);
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJLIB_UTIL_STRING_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/stun_simple.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/stun_simple.h
new file mode 100644
index 0000000..4dad266
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/stun_simple.h
@@ -0,0 +1,208 @@
+/* $Id: stun_simple.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSTUN_H__
+#define __PJSTUN_H__
+
+/**
+ * @file stun.h
+ * @brief STUN client.
+ */
+
+#include <pjlib-util/types.h>
+#include <pj/sock.h>
+
+
+PJ_BEGIN_DECL
+
+/*
+ * This enumeration describes STUN message types.
+ */
+typedef enum pjstun_msg_type
+{
+ PJSTUN_BINDING_REQUEST = 0x0001,
+ PJSTUN_BINDING_RESPONSE = 0x0101,
+ PJSTUN_BINDING_ERROR_RESPONSE = 0x0111,
+ PJSTUN_SHARED_SECRET_REQUEST = 0x0002,
+ PJSTUN_SHARED_SECRET_RESPONSE = 0x0102,
+ PJSTUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112
+} pjstun_msg_type;
+
+
+/*
+ * This enumeration describes STUN attribute types.
+ */
+typedef enum pjstun_attr_type
+{
+ PJSTUN_ATTR_MAPPED_ADDR = 1,
+ PJSTUN_ATTR_RESPONSE_ADDR,
+ PJSTUN_ATTR_CHANGE_REQUEST,
+ PJSTUN_ATTR_SOURCE_ADDR,
+ PJSTUN_ATTR_CHANGED_ADDR,
+ PJSTUN_ATTR_USERNAME,
+ PJSTUN_ATTR_PASSWORD,
+ PJSTUN_ATTR_MESSAGE_INTEGRITY,
+ PJSTUN_ATTR_ERROR_CODE,
+ PJSTUN_ATTR_UNKNOWN_ATTRIBUTES,
+ PJSTUN_ATTR_REFLECTED_FORM
+} pjstun_attr_type;
+
+
+/*
+ * This structre describes STUN message header.
+ */
+typedef struct pjstun_msg_hdr
+{
+ pj_uint16_t type;
+ pj_uint16_t length;
+ pj_uint32_t tsx[4];
+} pjstun_msg_hdr;
+
+
+/*
+ * This structre describes STUN attribute header.
+ */
+typedef struct pjstun_attr_hdr
+{
+ pj_uint16_t type;
+ pj_uint16_t length;
+} pjstun_attr_hdr;
+
+
+/*
+ * This structre describes STUN MAPPED-ADDR attribute.
+ */
+typedef struct pjstun_mapped_addr_attr
+{
+ pjstun_attr_hdr hdr;
+ pj_uint8_t ignored;
+ pj_uint8_t family;
+ pj_uint16_t port;
+ pj_uint32_t addr;
+} pjstun_mapped_addr_attr;
+
+typedef pjstun_mapped_addr_attr pjstun_response_addr_attr;
+typedef pjstun_mapped_addr_attr pjstun_changed_addr_attr;
+typedef pjstun_mapped_addr_attr pjstun_src_addr_attr;
+typedef pjstun_mapped_addr_attr pjstun_reflected_form_attr;
+
+typedef struct pjstun_change_request_attr
+{
+ pjstun_attr_hdr hdr;
+ pj_uint32_t value;
+} pjstun_change_request_attr;
+
+typedef struct pjstun_username_attr
+{
+ pjstun_attr_hdr hdr;
+ pj_uint32_t value[1];
+} pjstun_username_attr;
+
+typedef pjstun_username_attr pjstun_password_attr;
+
+typedef struct pjstun_error_code_attr
+{
+ pjstun_attr_hdr hdr;
+ pj_uint16_t ignored;
+ pj_uint8_t err_class;
+ pj_uint8_t number;
+ char reason[4];
+} pjstun_error_code_attr;
+
+typedef struct pjstun_msg
+{
+ pjstun_msg_hdr *hdr;
+ int attr_count;
+ pjstun_attr_hdr *attr[PJSTUN_MAX_ATTR];
+} pjstun_msg;
+
+/* STUN message API (stun.c). */
+
+PJ_DECL(pj_status_t) pjstun_create_bind_req( pj_pool_t *pool,
+ void **msg, pj_size_t *len,
+ pj_uint32_t id_hi,
+ pj_uint32_t id_lo);
+PJ_DECL(pj_status_t) pjstun_parse_msg( void *buf, pj_size_t len,
+ pjstun_msg *msg);
+PJ_DECL(void*) pjstun_msg_find_attr( pjstun_msg *msg, pjstun_attr_type t);
+
+
+/**
+ * @defgroup PJLIB_UTIL_STUN_CLIENT Simple STUN Helper
+ * @ingroup PJ_PROTOCOLS
+ * @brief A simple and small footprint STUN resolution helper
+ * @{
+ *
+ * This is the older implementation of STUN client, with only one function
+ * provided (pjstun_get_mapped_addr()) to retrieve the public IP address
+ * of multiple sockets.
+ */
+
+/**
+ * This is the main function to request the mapped address of local sockets
+ * to multiple STUN servers. This function is able to find the mapped
+ * addresses of multiple sockets simultaneously, and for each socket, two
+ * requests will be sent to two different STUN servers to see if both servers
+ * get the same public address for the same socket. (Note that application can
+ * specify the same address for the two servers, but still two requests will
+ * be sent for each server).
+ *
+ * This function will perform necessary retransmissions of the requests if
+ * response is not received within a predetermined period. When all responses
+ * have been received, the function will compare the mapped addresses returned
+ * by the servers, and when both are equal, the address will be returned in
+ * \a mapped_addr argument.
+ *
+ * @param pf The pool factory where memory will be allocated from.
+ * @param sock_cnt Number of sockets in the socket array.
+ * @param sock Array of local UDP sockets which public addresses are
+ * to be queried from the STUN servers.
+ * @param srv1 Host name or IP address string of the first STUN
+ * server.
+ * @param port1 The port number of the first STUN server.
+ * @param srv2 Host name or IP address string of the second STUN
+ * server.
+ * @param port2 The port number of the second STUN server.
+ * @param mapped_addr Array to receive the mapped public address of the local
+ * UDP sockets, when the function returns PJ_SUCCESS.
+ *
+ * @return This functions returns PJ_SUCCESS if responses are
+ * received from all servers AND all servers returned the
+ * same mapped public address. Otherwise this function may
+ * return one of the following error codes:
+ * - PJLIB_UTIL_ESTUNNOTRESPOND: no respons from servers.
+ * - PJLIB_UTIL_ESTUNSYMMETRIC: different mapped addresses
+ * are returned by servers.
+ * - etc.
+ *
+ */
+PJ_DECL(pj_status_t) pjstun_get_mapped_addr( pj_pool_factory *pf,
+ int sock_cnt, pj_sock_t sock[],
+ const pj_str_t *srv1, int port1,
+ const pj_str_t *srv2, int port2,
+ pj_sockaddr_in mapped_addr[]);
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSTUN_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/types.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/types.h
new file mode 100644
index 0000000..0888e72
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/types.h
@@ -0,0 +1,95 @@
+/* $Id: types.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_TYPES_H__
+#define __PJLIB_UTIL_TYPES_H__
+
+/**
+ * @file types.h
+ * @brief PJLIB-UTIL types.
+ */
+
+#include <pj/types.h>
+#include <pjlib-util/config.h>
+
+/**
+ * @defgroup PJLIB_UTIL_BASE Base
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Initialize PJLIB UTIL (defined in errno.c)
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjlib_util_init(void);
+
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJLIB_TEXT Text and String Manipulation
+ */
+
+/**
+ * @defgroup PJ_PROTOCOLS Protocols
+ */
+
+/**
+ * @defgroup PJ_FILE_FMT File Formats
+ */
+
+/**
+ * @mainpage PJLIB-UTIL
+ *
+ * \n
+ * \n
+ * \n
+ * This is the documentation of PJLIB-UTIL, an auxiliary library providing
+ * adjunct functions to PJLIB.
+ *
+ * Please go to the <A HREF="modules.htm"><B>Table of Contents</B></A> page
+ * for list of modules.
+ *
+ *
+ * \n
+ * \n
+ * \n
+ * \n
+ * \n
+ * \n
+ * \n
+ * \n
+ * \n
+ * \n
+ * \n
+ * \n
+ * \n
+ */
+
+#endif /* __PJLIB_UTIL_TYPES_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/xml.h b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/xml.h
new file mode 100644
index 0000000..554534b
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/xml.h
@@ -0,0 +1,246 @@
+/* $Id: xml.h 2727 2009-06-01 09:28:28Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_XML_H__
+#define __PJ_XML_H__
+
+/**
+ * @file xml.h
+ * @brief PJLIB XML Parser/Helper.
+ */
+
+#include <pj/types.h>
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_TINY_XML Mini/Tiny XML Parser/Helper
+ * @ingroup PJ_FILE_FMT
+ * @{
+ */
+
+/** Typedef for XML attribute. */
+typedef struct pj_xml_attr pj_xml_attr;
+
+/** Typedef for XML nodes. */
+typedef struct pj_xml_node pj_xml_node;
+
+/** This structure declares XML attribute. */
+struct pj_xml_attr
+{
+ PJ_DECL_LIST_MEMBER(pj_xml_attr); /**< Standard list elements. */
+ pj_str_t name; /**< Attribute name. */
+ pj_str_t value; /**< Attribute value. */
+};
+
+/** This structure describes XML node head inside XML node structure.
+ */
+typedef struct pj_xml_node_head
+{
+ PJ_DECL_LIST_MEMBER(pj_xml_node); /**< Standard list elements. */
+} pj_xml_node_head;
+
+/** This structure describes XML node. */
+struct pj_xml_node
+{
+ PJ_DECL_LIST_MEMBER(pj_xml_node); /**< List @a prev and @a next member */
+ pj_str_t name; /**< Node name. */
+ pj_xml_attr attr_head; /**< Attribute list. */
+ pj_xml_node_head node_head; /**< Node list. */
+ pj_str_t content; /**< Node content. */
+};
+
+/**
+ * Parse XML message into XML document with a single root node. The parser
+ * is capable of parsing XML processing instruction construct ("<?") and
+ * XML comments ("<!--"), however such constructs will be ignored and will not
+ * be included in the resulted XML node tree.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param msg The XML message to parse.
+ * @param len The length of the message.
+ *
+ * @return XML root node, or NULL if the XML document can not be parsed.
+ */
+PJ_DECL(pj_xml_node*) pj_xml_parse( pj_pool_t *pool, char *msg, pj_size_t len);
+
+
+/**
+ * Print XML into XML message. Note that the function WILL NOT NULL terminate
+ * the output.
+ *
+ * @param node The XML node to print.
+ * @param buf Buffer to hold the output message.
+ * @param len The length of the buffer.
+ * @param prolog If set to nonzero, will print XML prolog ("<?xml..")
+ *
+ * @return The size of the printed message, or -1 if there is not
+ * sufficient space in the buffer to print the message.
+ */
+PJ_DECL(int) pj_xml_print( const pj_xml_node *node, char *buf, pj_size_t len,
+ pj_bool_t prolog);
+
+/**
+ * Clone XML node and all subnodes.
+ *
+ * @param pool Pool to allocate memory for new nodes.
+ * @param rhs The node to clone.
+ *
+ * @return Cloned XML node, or NULL on fail.
+ */
+PJ_DECL(pj_xml_node*) pj_xml_clone( pj_pool_t *pool, const pj_xml_node *rhs);
+
+
+/**
+ * Create an empty node.
+ *
+ * @param pool Pool.
+ * @param name Node name.
+ *
+ * @return The new node.
+ */
+PJ_DECL(pj_xml_node*) pj_xml_node_new(pj_pool_t *pool, const pj_str_t *name);
+
+
+/**
+ * Create new XML attribute.
+ *
+ * @param pool Pool.
+ * @param name Attribute name.
+ * @param value Attribute value.
+ *
+ * @return The new XML attribute.
+ */
+PJ_DECL(pj_xml_attr*) pj_xml_attr_new(pj_pool_t *pool, const pj_str_t *name,
+ const pj_str_t *value);
+
+/**
+ * Add node to another node.
+ *
+ * @param parent Parent node.
+ * @param node Node to be added to parent.
+ */
+PJ_DECL(void) pj_xml_add_node( pj_xml_node *parent, pj_xml_node *node );
+
+
+/**
+ * Add attribute to a node.
+ *
+ * @param node Node.
+ * @param attr Attribute to add to node.
+ */
+PJ_DECL(void) pj_xml_add_attr( pj_xml_node *node, pj_xml_attr *attr );
+
+/**
+ * Find first direct child node with the specified name.
+ *
+ * @param parent Parent node.
+ * @param name Node name to find.
+ *
+ * @return XML node found or NULL.
+ */
+PJ_DECL(pj_xml_node*) pj_xml_find_node(const pj_xml_node *parent,
+ const pj_str_t *name);
+
+/**
+ * Find next direct child node with the specified name.
+ *
+ * @param parent Parent node.
+ * @param node node->next is the starting point.
+ * @param name Node name to find.
+ *
+ * @return XML node found or NULL.
+ */
+PJ_DECL(pj_xml_node*) pj_xml_find_next_node(const pj_xml_node *parent,
+ const pj_xml_node *node,
+ const pj_str_t *name);
+
+/**
+ * Recursively find the first node with the specified name in the child nodes
+ * and their children.
+ *
+ * @param parent Parent node.
+ * @param name Node name to find.
+ *
+ * @return XML node found or NULL.
+ */
+PJ_DECL(pj_xml_node*) pj_xml_find_node_rec(const pj_xml_node *parent,
+ const pj_str_t *name);
+
+
+/**
+ * Find first attribute within a node with the specified name and optional
+ * value.
+ *
+ * @param node XML Node.
+ * @param name Attribute name to find.
+ * @param value Optional value to match.
+ *
+ * @return XML attribute found, or NULL.
+ */
+PJ_DECL(pj_xml_attr*) pj_xml_find_attr(const pj_xml_node *node,
+ const pj_str_t *name,
+ const pj_str_t *value);
+
+
+/**
+ * Find a direct child node with the specified name and match the function.
+ *
+ * @param parent Parent node.
+ * @param name Optional name. If this is NULL, the name will not be
+ * matched.
+ * @param data Data to be passed to matching function.
+ * @param match Optional matching function.
+ *
+ * @return The first matched node, or NULL.
+ */
+PJ_DECL(pj_xml_node*) pj_xml_find( const pj_xml_node *parent,
+ const pj_str_t *name,
+ const void *data,
+ pj_bool_t (*match)(const pj_xml_node *,
+ const void*));
+
+
+/**
+ * Recursively find a child node with the specified name and match the
+ * function.
+ *
+ * @param parent Parent node.
+ * @param name Optional name. If this is NULL, the name will not be
+ * matched.
+ * @param data Data to be passed to matching function.
+ * @param match Optional matching function.
+ *
+ * @return The first matched node, or NULL.
+ */
+PJ_DECL(pj_xml_node*) pj_xml_find_rec(const pj_xml_node *parent,
+ const pj_str_t *name,
+ const void *data,
+ pj_bool_t (*match)(const pj_xml_node*,
+ const void*));
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJ_XML_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/file.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/file.hpp
new file mode 100644
index 0000000..80c8a62
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/file.hpp
@@ -0,0 +1,188 @@
+/* $Id: file.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_FILE_HPP__
+#define __PJPP_FILE_HPP__
+
+#include <pj/file_io.h>
+#include <pj/file_access.h>
+#include <pj++/types.hpp>
+#include <pj++/pool.hpp>
+
+//
+// File API.
+//
+class Pj_File_API
+{
+public:
+ //
+ // Check file existance.
+ //
+ static bool file_exists(const char *filename)
+ {
+ return pj_file_exists(filename) != 0;
+ }
+
+ //
+ // Get file size.
+ //
+ static pj_off_t file_size(const char *filename)
+ {
+ return pj_file_size(filename);
+ }
+
+ //
+ // Delete file.
+ //
+ static pj_status_t file_delete(const char *filename)
+ {
+ return pj_file_delete(filename);
+ }
+
+ //
+ // Move/rename file.
+ //
+ static pj_status_t file_move(const char *oldname, const char *newname)
+ {
+ return pj_file_move(oldname, newname);
+ }
+
+ //
+ // Get stat.
+ //
+ static pj_status_t file_stat(const char *filename, pj_file_stat *buf)
+ {
+ return pj_file_getstat(filename, buf);
+ }
+};
+
+
+//
+// File.
+//
+class Pj_File : public Pj_Object
+{
+public:
+ //
+ // Offset type to be used in setpos.
+ //
+ enum Offset_Type
+ {
+ PJ_SEEK_SET = PJ_SEEK_SET,
+ PJ_SEEK_CUR = PJ_SEEK_CUR,
+ PJ_SEEK_END = PJ_SEEK_END,
+ };
+
+ //
+ // Default constructor.
+ //
+ Pj_File()
+ : hnd_(0)
+ {
+ }
+
+ //
+ // Construct and open a file.
+ //
+ Pj_File(Pj_Pool *pool, const char *filename,
+ unsigned access = PJ_O_RDONLY)
+ : hnd_(NULL)
+ {
+ open(pool, filename, access);
+ }
+
+ //
+ // Destructor closes the file.
+ //
+ ~Pj_File()
+ {
+ close();
+ }
+
+ //
+ // Open a file.
+ //
+ pj_status_t open(Pj_Pool *pool, const char *filename,
+ unsigned access = PJ_O_RDONLY )
+ {
+ close();
+ return pj_file_open(pool->pool_(), filename, access, &hnd_);
+ }
+
+ //
+ // Close a file.
+ //
+ void close()
+ {
+ if (hnd_ != 0) {
+ pj_file_close(hnd_);
+ hnd_ = 0;
+ }
+ }
+
+ //
+ // Write data.
+ //
+ pj_ssize_t write(const void *buff, pj_size_t size)
+ {
+ pj_ssize_t bytes = size;
+ if (pj_file_write(hnd_, buff, &bytes) != PJ_SUCCESS)
+ return -1;
+ return bytes;
+ }
+
+ //
+ // Read data.
+ //
+ pj_ssize_t read(void *buf, pj_size_t size)
+ {
+ pj_ssize_t bytes = size;
+ if (pj_file_read(hnd_, buf, &bytes) != PJ_SUCCESS)
+ return -1;
+ return bytes;
+ }
+
+ //
+ // Set file position.
+ //
+ pj_status_t setpos(pj_off_t offset, Offset_Type whence)
+ {
+ return pj_file_setpos(hnd_, offset,
+ (enum pj_file_seek_type)whence);
+ }
+
+ //
+ // Get file position.
+ //
+ pj_off_t getpos()
+ {
+ pj_off_t pos;
+ if (pj_file_getpos(hnd_, &pos) != PJ_SUCCESS)
+ return -1;
+ return pos;
+ }
+
+private:
+ pj_oshandle_t hnd_;
+};
+
+
+
+#endif /* __PJPP_FILE_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/hash.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/hash.hpp
new file mode 100644
index 0000000..ba1f029
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/hash.hpp
@@ -0,0 +1,156 @@
+/* $Id: hash.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_HASH_HPP__
+#define __PJPP_HASH_HPP__
+
+#include <pj++/types.hpp>
+#include <pj++/pool.hpp>
+#include <pj/hash.h>
+
+//
+// Hash table.
+//
+class Pj_Hash_Table : public Pj_Object
+{
+public:
+ //
+ // Hash table iterator.
+ //
+ class iterator
+ {
+ public:
+ iterator()
+ {
+ }
+ explicit iterator(pj_hash_table_t *h, pj_hash_iterator_t *i)
+ : ht_(h), it_(i)
+ {
+ }
+ iterator(const iterator &rhs)
+ : ht_(rhs.ht_), it_(rhs.it_)
+ {
+ }
+ void operator++()
+ {
+ it_ = pj_hash_next(ht_, it_);
+ }
+ bool operator==(const iterator &rhs)
+ {
+ return ht_ == rhs.ht_ && it_ == rhs.it_;
+ }
+ iterator & operator=(const iterator &rhs)
+ {
+ ht_=rhs.ht_; it_=rhs.it_;
+ return *this;
+ }
+ private:
+ pj_hash_table_t *ht_;
+ pj_hash_iterator_t it_val_;
+ pj_hash_iterator_t *it_;
+
+ friend class Pj_Hash_Table;
+ };
+
+ //
+ // Construct hash table.
+ //
+ Pj_Hash_Table(Pj_Pool *pool, unsigned size)
+ {
+ table_ = pj_hash_create(pool->pool_(), size);
+ }
+
+ //
+ // Destroy hash table.
+ //
+ ~Pj_Hash_Table()
+ {
+ }
+
+ //
+ // Calculate hash value.
+ //
+ static pj_uint32_t calc( pj_uint32_t initial_hval,
+ const void *key,
+ unsigned keylen = PJ_HASH_KEY_STRING)
+ {
+ return pj_hash_calc(initial_hval, key, keylen);
+ }
+
+ //
+ // Return pjlib compatible hash table object.
+ //
+ pj_hash_table_t *pj_hash_table_t_()
+ {
+ return table_;
+ }
+
+ //
+ // Get the value associated with the specified key.
+ //
+ void *get(const void *key, unsigned keylen = PJ_HASH_KEY_STRING)
+ {
+ return pj_hash_get(table_, key, keylen);
+ }
+
+ //
+ // Associate a value with a key.
+ // Set the value to NULL to delete the key from the hash table.
+ //
+ void set(Pj_Pool *pool,
+ const void *key,
+ void *value,
+ unsigned keylen = PJ_HASH_KEY_STRING)
+ {
+ pj_hash_set(pool->pool_(), table_, key, keylen, value);
+ }
+
+ //
+ // Get number of items in the hash table.
+ //
+ unsigned count()
+ {
+ return pj_hash_count(table_);
+ }
+
+ //
+ // Iterate hash table.
+ //
+ iterator begin()
+ {
+ iterator it(table_, NULL);
+ it.it_ = pj_hash_first(table_, &it.it_val_);
+ return it;
+ }
+
+ //
+ // End of items.
+ //
+ iterator end()
+ {
+ return iterator(table_, NULL);
+ }
+
+private:
+ pj_hash_table_t *table_;
+};
+
+
+#endif /* __PJPP_HASH_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/list.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/list.hpp
new file mode 100644
index 0000000..1ed8530
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/list.hpp
@@ -0,0 +1,352 @@
+/* $Id: list.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_LIST_HPP__
+#define __PJPP_LIST_HPP__
+
+#include <pj/list.h>
+#include <pj++/pool.hpp>
+
+
+//
+// Linked-list.
+//
+// Note:
+// List_Node must have public member next and prev. Normally
+// it will be declared like:
+//
+// struct my_node
+// {
+// PJ_DECL_LIST_MEMBER(struct my_node);
+// ..
+// };
+//
+//
+template <class List_Node>
+class Pj_List : public Pj_Object
+{
+public:
+ //
+ // List const_iterator.
+ //
+ class const_iterator
+ {
+ public:
+ const_iterator()
+ : node_(NULL)
+ {}
+ const_iterator(const List_Node *nd)
+ : node_((List_Node*)nd)
+ {}
+ const List_Node * operator *()
+ {
+ return node_;
+ }
+ const List_Node * operator -> ()
+ {
+ return node_;
+ }
+ const_iterator operator++()
+ {
+ return const_iterator((const List_Node *)node_->next);
+ }
+ bool operator==(const const_iterator &rhs)
+ {
+ return node_ == rhs.node_;
+ }
+ bool operator!=(const const_iterator &rhs)
+ {
+ return node_ != rhs.node_;
+ }
+
+ protected:
+ List_Node *node_;
+ };
+
+ //
+ // List iterator.
+ //
+ class iterator : public const_iterator
+ {
+ public:
+ iterator()
+ {}
+ iterator(List_Node *nd)
+ : const_iterator(nd)
+ {}
+ List_Node * operator *()
+ {
+ return node_;
+ }
+ List_Node * operator -> ()
+ {
+ return node_;
+ }
+ iterator operator++()
+ {
+ return iterator((List_Node*)node_->next);
+ }
+ bool operator==(const iterator &rhs)
+ {
+ return node_ == rhs.node_;
+ }
+ bool operator!=(const iterator &rhs)
+ {
+ return node_ != rhs.node_;
+ }
+ };
+
+ //
+ // Default constructor.
+ //
+ Pj_List()
+ {
+ pj_list_init(&root_);
+ if (0) compiletest();
+ }
+
+ //
+ // You can cast Pj_List to pj_list
+ //
+ operator pj_list&()
+ {
+ return (pj_list&)root_;
+ }
+ operator const pj_list&()
+ {
+ return (const pj_list&)root_;
+ }
+
+ //
+ // You can cast Pj_List to pj_list* too
+ //
+ operator pj_list*()
+ {
+ return (pj_list*)&root_;
+ }
+ operator const pj_list*()
+ {
+ return (const pj_list*)&root_;
+ }
+
+ //
+ // Check if list is empty.
+ //
+ bool empty() const
+ {
+ return pj_list_empty(&root_);
+ }
+
+ //
+ // Get first element.
+ //
+ iterator begin()
+ {
+ return iterator(root_.next);
+ }
+
+ //
+ // Get first element.
+ //
+ const_iterator begin() const
+ {
+ return const_iterator(root_.next);
+ }
+
+ //
+ // Get end-of-element
+ //
+ const_iterator end() const
+ {
+ return const_iterator((List_Node*)&root_);
+ }
+
+ //
+ // Get end-of-element
+ //
+ iterator end()
+ {
+ return iterator((List_Node*)&root_);
+ }
+
+ //
+ // Insert node.
+ //
+ void insert_before (iterator &pos, List_Node *node)
+ {
+ pj_list_insert_before( *pos, node );
+ }
+
+ //
+ // Insert node.
+ //
+ void insert_after(iterator &pos, List_Node *node)
+ {
+ pj_list_insert_after(*pos, node);
+ }
+
+ //
+ // Merge list.
+ //
+ void merge_first(List_Node *list2)
+ {
+ pj_list_merge_first(&root_, list2);
+ }
+
+ //
+ // Merge list.
+ //
+ void merge_last(Pj_List *list)
+ {
+ pj_list_merge_last(&root_, &list->root_);
+ }
+
+ //
+ // Insert list.
+ //
+ void insert_nodes_before(iterator &pos, Pj_List *list2)
+ {
+ pj_list_insert_nodes_before(*pos, &list2->root_);
+ }
+
+ //
+ // Insert list.
+ //
+ void insert_nodes_after(iterator &pos, Pj_List *list2)
+ {
+ pj_list_insert_nodes_after(*pos, &list2->root_);
+ }
+
+ //
+ // Erase an element.
+ //
+ void erase(iterator &it)
+ {
+ pj_list_erase(*it);
+ }
+
+ //
+ // Get first element.
+ //
+ List_Node *front()
+ {
+ return root_.next;
+ }
+
+ //
+ // Get first element.
+ //
+ const List_Node *front() const
+ {
+ return root_.next;
+ }
+
+ //
+ // Remove first element.
+ //
+ void pop_front()
+ {
+ pj_list_erase(root_.next);
+ }
+
+ //
+ // Get last element.
+ //
+ List_Node *back()
+ {
+ return root_.prev;
+ }
+
+ //
+ // Get last element.
+ //
+ const List_Node *back() const
+ {
+ return root_.prev;
+ }
+
+ //
+ // Remove last element.
+ //
+ void pop_back()
+ {
+ pj_list_erase(root_.prev);
+ }
+
+ //
+ // Find a node.
+ //
+ iterator find(List_Node *node)
+ {
+ List_Node *n = pj_list_find_node(&root_, node);
+ return n ? iterator(n) : end();
+ }
+
+ //
+ // Find a node.
+ //
+ const_iterator find(List_Node *node) const
+ {
+ List_Node *n = pj_list_find_node(&root_, node);
+ return n ? const_iterator(n) : end();
+ }
+
+ //
+ // Insert a node in the back.
+ //
+ void push_back(List_Node *node)
+ {
+ pj_list_insert_after(root_.prev, node);
+ }
+
+ //
+ // Insert a node in the front.
+ //
+ void push_front(List_Node *node)
+ {
+ pj_list_insert_before(root_.next, node);
+ }
+
+ //
+ // Remove all elements.
+ //
+ void clear()
+ {
+ root_.next = &root_;
+ root_.prev = &root_;
+ }
+
+private:
+ struct RootNode
+ {
+ PJ_DECL_LIST_MEMBER(List_Node);
+ } root_;
+
+ void compiletest()
+ {
+ // If you see error in this line,
+ // it's because List_Node is not derived from Pj_List_Node.
+ List_Node *n = (List_Node*)0;
+ n = (List_Node *)n->next; n = (List_Node *)n->prev;
+ }
+};
+
+
+#endif /* __PJPP_LIST_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/lock.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/lock.hpp
new file mode 100644
index 0000000..7e8ba33
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/lock.hpp
@@ -0,0 +1,149 @@
+/* $Id: lock.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_LOCK_HPP__
+#define __PJPP_LOCK_HPP__
+
+#include <pj++/types.hpp>
+#include <pj/lock.h>
+#include <pj++/pool.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// Lock object.
+//
+class Pj_Lock : public Pj_Object
+{
+public:
+ //
+ // Constructor.
+ //
+ explicit Pj_Lock(pj_lock_t *lock)
+ : lock_(lock)
+ {
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Lock()
+ {
+ if (lock_)
+ pj_lock_destroy(lock_);
+ }
+
+ //
+ // Get pjlib compatible lock object.
+ //
+ pj_lock_t *pj_lock_t_()
+ {
+ return lock_;
+ }
+
+ //
+ // acquire lock.
+ //
+ pj_status_t acquire()
+ {
+ return pj_lock_acquire(lock_);
+ }
+
+ //
+ // release lock,.
+ //
+ pj_status_t release()
+ {
+ return pj_lock_release(lock_);
+ }
+
+protected:
+ pj_lock_t *lock_;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Null lock object.
+//
+class Pj_Null_Lock : public Pj_Lock
+{
+public:
+ //
+ // Default constructor.
+ //
+ explicit Pj_Null_Lock(Pj_Pool *pool, const char *name = NULL)
+ : Pj_Lock(NULL)
+ {
+ pj_lock_create_null_mutex(pool->pool_(), name, &lock_);
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Simple mutex lock object.
+//
+class Pj_Simple_Mutex_Lock : public Pj_Lock
+{
+public:
+ //
+ // Default constructor.
+ //
+ explicit Pj_Simple_Mutex_Lock(Pj_Pool *pool, const char *name = NULL)
+ : Pj_Lock(NULL)
+ {
+ pj_lock_create_simple_mutex(pool->pool_(), name, &lock_);
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Recursive mutex lock object.
+//
+class Pj_Recursive_Mutex_Lock : public Pj_Lock
+{
+public:
+ //
+ // Default constructor.
+ //
+ explicit Pj_Recursive_Mutex_Lock(Pj_Pool *pool, const char *name = NULL)
+ : Pj_Lock(NULL)
+ {
+ pj_lock_create_recursive_mutex(pool->pool_(), name, &lock_);
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Semaphore lock object.
+//
+class Pj_Semaphore_Lock : public Pj_Lock
+{
+public:
+ //
+ // Default constructor.
+ //
+ explicit Pj_Semaphore_Lock(Pj_Pool *pool,
+ unsigned max=PJ_MAXINT32,
+ unsigned initial=0,
+ const char *name=NULL)
+ : Pj_Lock(NULL)
+ {
+ pj_lock_create_semaphore(pool->pool_(), name, initial, max, &lock_);
+ }
+};
+
+
+
+#endif /* __PJPP_LOCK_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/os.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/os.hpp
new file mode 100644
index 0000000..c7c45ca
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/os.hpp
@@ -0,0 +1,870 @@
+/* $Id: os.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_OS_HPP__
+#define __PJPP_OS_HPP__
+
+#include <pj/os.h>
+#include <pj/string.h>
+#include <pj++/types.hpp>
+#include <pj++/pool.hpp>
+
+class Pj_Thread;
+
+//
+// Thread API.
+//
+class Pj_Thread_API
+{
+public:
+ //
+ // Create a thread.
+ //
+ static pj_status_t create( Pj_Pool *pool, pj_thread_t **thread,
+ pj_thread_proc *proc, void *arg,
+ unsigned flags = 0,
+ const char *name = NULL,
+ pj_size_t stack_size = 0 )
+ {
+ return pj_thread_create(pool->pool_(), name, proc, arg, stack_size,
+ flags, thread);
+ }
+
+ //
+ // Register a thread.
+ //
+ static pj_status_t register_this_thread( pj_thread_desc desc,
+ pj_thread_t **thread,
+ const char *name = NULL )
+ {
+ return pj_thread_register( name, desc, thread );
+ }
+
+ //
+ // Get current thread.
+ // Will return pj_thread_t (sorry folks, not Pj_Thread).
+ //
+ static pj_thread_t *this_thread()
+ {
+ return pj_thread_this();
+ }
+
+ //
+ // Get thread name.
+ //
+ static const char *get_name(pj_thread_t *thread)
+ {
+ return pj_thread_get_name(thread);
+ }
+
+ //
+ // Resume thread.
+ //
+ static pj_status_t resume(pj_thread_t *thread)
+ {
+ return pj_thread_resume(thread);
+ }
+
+ //
+ // Sleep.
+ //
+ static pj_status_t sleep(unsigned msec)
+ {
+ return pj_thread_sleep(msec);
+ }
+
+ //
+ // Join the specified thread.
+ //
+ static pj_status_t join(pj_thread_t *thread)
+ {
+ return pj_thread_join(thread);
+ }
+
+ //
+ // Destroy thread
+ //
+ static pj_status_t destroy(pj_thread_t *thread)
+ {
+ return pj_thread_destroy(thread);
+ }
+};
+
+
+
+//
+// Thread object.
+//
+// How to use:
+// Derive a class from this class, then override main().
+//
+class Pj_Thread : public Pj_Object
+{
+public:
+ enum Flags
+ {
+ FLAG_SUSPENDED = PJ_THREAD_SUSPENDED
+ };
+
+ //
+ // Default constructor.
+ //
+ Pj_Thread()
+ : thread_(NULL)
+ {
+ }
+
+ //
+ // Destroy thread.
+ //
+ ~Pj_Thread()
+ {
+ destroy();
+ }
+
+ //
+ // This is the main thread function.
+ //
+ virtual int main() = 0;
+
+ //
+ // Start a thread.
+ //
+ pj_status_t create( Pj_Pool *pool,
+ unsigned flags = 0,
+ const char *thread_name = NULL,
+ pj_size_t stack_size = PJ_THREAD_DEFAULT_STACK_SIZE)
+ {
+ destroy();
+ return Pj_Thread_API::create( pool, &thread_, &thread_proc, this,
+ flags, thread_name, stack_size);
+ }
+
+ //
+ // Get pjlib compatible thread object.
+ //
+ pj_thread_t *pj_thread_t_()
+ {
+ return thread_;
+ }
+
+ //
+ // Get thread name.
+ //
+ const char *get_name()
+ {
+ return Pj_Thread_API::get_name(thread_);
+ }
+
+ //
+ // Resume a suspended thread.
+ //
+ pj_status_t resume()
+ {
+ return Pj_Thread_API::resume(thread_);
+ }
+
+ //
+ // Join this thread.
+ //
+ pj_status_t join()
+ {
+ return Pj_Thread_API::join(thread_);
+ }
+
+ //
+ // Destroy thread.
+ //
+ pj_status_t destroy()
+ {
+ if (thread_) {
+ Pj_Thread_API::destroy(thread_);
+ thread_ = NULL;
+ }
+ }
+
+protected:
+ pj_thread_t *thread_;
+
+ static int PJ_THREAD_FUNC thread_proc(void *obj)
+ {
+ Pj_Thread *thread_class = (Pj_Thread*)obj;
+ return thread_class->main();
+ }
+};
+
+
+//
+// External Thread
+// (threads that were started by external means, i.e. not
+// with Pj_Thread::create).
+//
+// This class will normally be defined as local variable in
+// external thread's stack, normally inside thread's main proc.
+// But be aware that the handle will be destroyed on destructor!
+//
+class Pj_External_Thread : public Pj_Thread
+{
+public:
+ Pj_External_Thread()
+ {
+ }
+
+ //
+ // Register external thread so that pjlib functions can work
+ // in that thread.
+ //
+ pj_status_t register_this_thread( const char *name=NULL )
+ {
+ return Pj_Thread_API::register_this_thread(desc_, &thread_,name);
+ }
+
+private:
+ pj_thread_desc desc_;
+};
+
+
+//
+// Thread specific data/thread local storage/TLS.
+//
+class Pj_Thread_Local_API
+{
+public:
+ //
+ // Allocate thread local storage (TLS) index.
+ //
+ static pj_status_t alloc(long *index)
+ {
+ return pj_thread_local_alloc(index);
+ }
+
+ //
+ // Free TLS index.
+ //
+ static void free(long index)
+ {
+ pj_thread_local_free(index);
+ }
+
+ //
+ // Set thread specific data.
+ //
+ static pj_status_t set(long index, void *value)
+ {
+ return pj_thread_local_set(index, value);
+ }
+
+ //
+ // Get thread specific data.
+ //
+ static void *get(long index)
+ {
+ return pj_thread_local_get(index);
+ }
+
+};
+
+//
+// Atomic variable
+//
+// How to use:
+// Pj_Atomic_Var var(pool, 0);
+// var.set(..);
+//
+class Pj_Atomic_Var : public Pj_Object
+{
+public:
+ //
+ // Default constructor, initialize variable with NULL.
+ //
+ Pj_Atomic_Var()
+ : var_(NULL)
+ {
+ }
+
+ //
+ // Construct atomic variable.
+ //
+ Pj_Atomic_Var(Pj_Pool *pool, pj_atomic_value_t value)
+ : var_(NULL)
+ {
+ create(pool, value);
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Atomic_Var()
+ {
+ destroy();
+ }
+
+ //
+ // Create atomic variable.
+ //
+ pj_status_t create( Pj_Pool *pool, pj_atomic_value_t value)
+ {
+ destroy();
+ return pj_atomic_create(pool->pool_(), value, &var_);
+ }
+
+ //
+ // Destroy.
+ //
+ void destroy()
+ {
+ if (var_) {
+ pj_atomic_destroy(var_);
+ var_ = NULL;
+ }
+ }
+
+ //
+ // Get pjlib compatible atomic variable.
+ //
+ pj_atomic_t *pj_atomic_t_()
+ {
+ return var_;
+ }
+
+ //
+ // Set the value.
+ //
+ void set(pj_atomic_value_t val)
+ {
+ pj_atomic_set(var_, val);
+ }
+
+ //
+ // Get the value.
+ //
+ pj_atomic_value_t get()
+ {
+ return pj_atomic_get(var_);
+ }
+
+ //
+ // Increment.
+ //
+ void inc()
+ {
+ pj_atomic_inc(var_);
+ }
+
+ //
+ // Increment and get the result.
+ //
+ pj_atomic_value_t inc_and_get()
+ {
+ return pj_atomic_inc_and_get(var_);
+ }
+
+ //
+ // Decrement.
+ //
+ void dec()
+ {
+ pj_atomic_dec(var_);
+ }
+
+ //
+ // Decrement and get the result.
+ //
+ pj_atomic_value_t dec_and_get()
+ {
+ return pj_atomic_dec_and_get(var_);
+ }
+
+ //
+ // Add the variable.
+ //
+ void add(pj_atomic_value_t value)
+ {
+ pj_atomic_add(var_, value);
+ }
+
+ //
+ // Add the variable and get the value.
+ //
+ pj_atomic_value_t add_and_get(pj_atomic_value_t value)
+ {
+ return pj_atomic_add_and_get(var_, value );
+ }
+
+private:
+ pj_atomic_t *var_;
+};
+
+
+//
+// Mutex
+//
+class Pj_Mutex : public Pj_Object
+{
+public:
+ //
+ // Mutex type.
+ //
+ enum Type
+ {
+ DEFAULT = PJ_MUTEX_DEFAULT,
+ SIMPLE = PJ_MUTEX_SIMPLE,
+ RECURSE = PJ_MUTEX_RECURSE,
+ };
+
+ //
+ // Default constructor will create default mutex.
+ //
+ explicit Pj_Mutex(Pj_Pool *pool, Type type = DEFAULT,
+ const char *name = NULL)
+ : mutex_(NULL)
+ {
+ create(pool, type, name);
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Mutex()
+ {
+ destroy();
+ }
+
+ //
+ // Create mutex.
+ //
+ pj_status_t create( Pj_Pool *pool, Type type, const char *name = NULL)
+ {
+ destroy();
+ return pj_mutex_create( pool->pool_(), name, type,
+ &mutex_ );
+ }
+
+ //
+ // Create simple mutex.
+ //
+ pj_status_t create_simple( Pj_Pool *pool,const char *name = NULL)
+ {
+ return create(pool, SIMPLE, name);
+ }
+
+ //
+ // Create recursive mutex.
+ //
+ pj_status_t create_recursive( Pj_Pool *pool, const char *name = NULL )
+ {
+ return create(pool, RECURSE, name);
+ }
+
+ //
+ // Get pjlib compatible mutex object.
+ //
+ pj_mutex_t *pj_mutex_t_()
+ {
+ return mutex_;
+ }
+
+ //
+ // Destroy mutex.
+ //
+ void destroy()
+ {
+ if (mutex_) {
+ pj_mutex_destroy(mutex_);
+ mutex_ = NULL;
+ }
+ }
+
+ //
+ // Lock mutex.
+ //
+ pj_status_t acquire()
+ {
+ return pj_mutex_lock(mutex_);
+ }
+
+ //
+ // Unlock mutex.
+ //
+ pj_status_t release()
+ {
+ return pj_mutex_unlock(mutex_);
+ }
+
+ //
+ // Try locking the mutex.
+ //
+ pj_status_t tryacquire()
+ {
+ return pj_mutex_trylock(mutex_);
+ }
+
+private:
+ pj_mutex_t *mutex_;
+};
+
+
+//
+// Semaphore
+//
+class Pj_Semaphore : public Pj_Object
+{
+public:
+ //
+ // Construct semaphore
+ //
+ Pj_Semaphore(Pj_Pool *pool, unsigned max,
+ unsigned initial = 0, const char *name = NULL)
+ : sem_(NULL)
+ {
+ create(pool, max, initial, name);
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Semaphore()
+ {
+ destroy();
+ }
+
+ //
+ // Create semaphore
+ //
+ pj_status_t create( Pj_Pool *pool, unsigned max,
+ unsigned initial = 0, const char *name = NULL )
+ {
+ destroy();
+ return pj_sem_create( pool->pool_(), name, initial, max, &sem_);
+ }
+
+ //
+ // Destroy semaphore.
+ //
+ void destroy()
+ {
+ if (sem_) {
+ pj_sem_destroy(sem_);
+ sem_ = NULL;
+ }
+ }
+
+ //
+ // Get pjlib compatible semaphore object.
+ //
+ pj_sem_t *pj_sem_t_()
+ {
+ return (pj_sem_t*)this;
+ }
+
+ //
+ // Wait semaphore.
+ //
+ pj_status_t wait()
+ {
+ return pj_sem_wait(this->pj_sem_t_());
+ }
+
+ //
+ // Wait semaphore.
+ //
+ pj_status_t acquire()
+ {
+ return wait();
+ }
+
+ //
+ // Try wait semaphore.
+ //
+ pj_status_t trywait()
+ {
+ return pj_sem_trywait(this->pj_sem_t_());
+ }
+
+ //
+ // Try wait semaphore.
+ //
+ pj_status_t tryacquire()
+ {
+ return trywait();
+ }
+
+ //
+ // Post semaphore.
+ //
+ pj_status_t post()
+ {
+ return pj_sem_post(this->pj_sem_t_());
+ }
+
+ //
+ // Post semaphore.
+ //
+ pj_status_t release()
+ {
+ return post();
+ }
+
+private:
+ pj_sem_t *sem_;
+};
+
+
+//
+// Event object.
+//
+class Pj_Event
+{
+public:
+ //
+ // Construct event object.
+ //
+ Pj_Event( Pj_Pool *pool, bool manual_reset = false,
+ bool initial = false, const char *name = NULL )
+ : event_(NULL)
+ {
+ create(pool, manual_reset, initial, name);
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Event()
+ {
+ destroy();
+ }
+
+ //
+ // Create event object.
+ //
+ pj_status_t create( Pj_Pool *pool, bool manual_reset = false,
+ bool initial = false, const char *name = NULL)
+ {
+ destroy();
+ return pj_event_create(pool->pool_(), name, manual_reset, initial,
+ &event_);
+ }
+
+ //
+ // Get pjlib compatible event object.
+ //
+ pj_event_t *pj_event_t_()
+ {
+ return event_;
+ }
+
+ //
+ // Destroy event object.
+ //
+ void destroy()
+ {
+ if (event_) {
+ pj_event_destroy(event_);
+ event_ = NULL;
+ }
+ }
+
+ //
+ // Wait.
+ //
+ pj_status_t wait()
+ {
+ return pj_event_wait(event_);
+ }
+
+ //
+ // Try wait.
+ //
+ pj_status_t trywait()
+ {
+ return pj_event_trywait(event_);
+ }
+
+ //
+ // Set event state to signalled.
+ //
+ pj_status_t set()
+ {
+ return pj_event_set(this->pj_event_t_());
+ }
+
+ //
+ // Release one waiting thread.
+ //
+ pj_status_t pulse()
+ {
+ return pj_event_pulse(this->pj_event_t_());
+ }
+
+ //
+ // Set a non-signalled.
+ //
+ pj_status_t reset()
+ {
+ return pj_event_reset(this->pj_event_t_());
+ }
+
+private:
+ pj_event_t *event_;
+};
+
+//
+// Timestamp
+//
+class Pj_Timestamp
+{
+public:
+ pj_status_t get_timestamp()
+ {
+ return pj_get_timestamp(&ts_);
+ }
+
+ Pj_Timestamp& operator += (const Pj_Timestamp &rhs)
+ {
+ pj_add_timestamp(&ts_, &rhs.ts_);
+ return *this;
+ }
+
+ Pj_Timestamp& operator -= (const Pj_Timestamp &rhs)
+ {
+ pj_sub_timestamp(&ts_, &rhs.ts_);
+ return *this;
+ }
+
+ Pj_Time_Val to_time() const
+ {
+ Pj_Timestamp zero;
+ pj_memset(&zero, 0, sizeof(zero));
+ return Pj_Time_Val(pj_elapsed_time(&zero.ts_, &ts_));
+ }
+
+ pj_uint32_t to_msec() const
+ {
+ Pj_Timestamp zero;
+ pj_memset(&zero, 0, sizeof(zero));
+ return pj_elapsed_msec(&zero.ts_, &ts_);
+ }
+
+ pj_uint32_t to_usec() const
+ {
+ Pj_Timestamp zero;
+ pj_memset(&zero, 0, sizeof(zero));
+ return pj_elapsed_usec(&zero.ts_, &ts_);
+ }
+
+ pj_uint32_t to_nanosec() const
+ {
+ Pj_Timestamp zero;
+ pj_memset(&zero, 0, sizeof(zero));
+ return pj_elapsed_nanosec(&zero.ts_, &ts_);
+ }
+
+ pj_uint32_t to_cycle() const
+ {
+ Pj_Timestamp zero;
+ pj_memset(&zero, 0, sizeof(zero));
+ return pj_elapsed_cycle(&zero.ts_, &ts_);
+ }
+
+private:
+ pj_timestamp ts_;
+};
+
+
+//
+// OS abstraction.
+//
+class Pj_OS_API
+{
+public:
+ //
+ // Get current time.
+ //
+ static pj_status_t gettimeofday( Pj_Time_Val *tv )
+ {
+ return pj_gettimeofday(tv);
+ }
+
+ //
+ // Parse to time of day.
+ //
+ static pj_status_t time_decode( const Pj_Time_Val *tv,
+ pj_parsed_time *pt )
+ {
+ return pj_time_decode(tv, pt);
+ }
+
+ //
+ // Parse from time of day.
+ //
+ static pj_status_t time_encode( const pj_parsed_time *pt,
+ Pj_Time_Val *tv)
+ {
+ return pj_time_encode(pt, tv);
+ }
+
+ //
+ // Convert to GMT.
+ //
+ static pj_status_t time_local_to_gmt( Pj_Time_Val *tv )
+ {
+ return pj_time_local_to_gmt( tv );
+ }
+
+ //
+ // Convert time to local.
+ //
+ static pj_status_t time_gmt_to_local( Pj_Time_Val *tv)
+ {
+ return pj_time_gmt_to_local( tv );
+ }
+};
+
+//
+// Timeval inlines.
+//
+inline pj_status_t Pj_Time_Val::gettimeofday()
+{
+ return Pj_OS_API::gettimeofday(this);
+}
+
+inline pj_parsed_time Pj_Time_Val::decode()
+{
+ pj_parsed_time pt;
+ Pj_OS_API::time_decode(this, &pt);
+ return pt;
+}
+
+inline pj_status_t Pj_Time_Val::encode(const pj_parsed_time *pt)
+{
+ return Pj_OS_API::time_encode(pt, this);
+}
+
+inline pj_status_t Pj_Time_Val::to_gmt()
+{
+ return Pj_OS_API::time_local_to_gmt(this);
+}
+
+inline pj_status_t Pj_Time_Val::to_local()
+{
+ return Pj_OS_API::time_gmt_to_local(this);
+}
+
+#endif /* __PJPP_OS_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/pool.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/pool.hpp
new file mode 100644
index 0000000..04d0cbc
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/pool.hpp
@@ -0,0 +1,279 @@
+/* $Id: pool.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_POOL_HPP__
+#define __PJPP_POOL_HPP__
+
+#include <pj/pool.h>
+
+class Pj_Pool;
+class Pj_Caching_Pool;
+
+//
+// Base class for all Pjlib objects
+//
+class Pj_Object
+{
+public:
+ void *operator new(unsigned int class_size, Pj_Pool *pool);
+ void *operator new(unsigned int class_size, Pj_Pool &pool);
+
+ void operator delete(void*)
+ {
+ }
+
+ void operator delete(void*, Pj_Pool*)
+ {
+ }
+
+ void operator delete(void*, Pj_Pool&)
+ {
+ }
+
+ //
+ // Inline implementations at the end of this file.
+ //
+
+private:
+ // Can not use normal new operator; must use pool.
+ // e.g.:
+ // obj = new(pool) Pj_The_Object(pool, ...);
+ //
+ void *operator new(unsigned int)
+ {}
+};
+
+
+//
+// Pool.
+//
+class Pj_Pool : public Pj_Object
+{
+public:
+ //
+ // Default constructor, initializes internal pool to NULL.
+ // Application must call attach() some time later.
+ //
+ Pj_Pool()
+ : p_(NULL)
+ {
+ }
+
+ //
+ // Create pool.
+ //
+ Pj_Pool(Pj_Caching_Pool &caching_pool,
+ pj_size_t initial_size,
+ pj_size_t increment_size,
+ const char *name = NULL,
+ pj_pool_callback *callback = NULL);
+
+ //
+ // Construct from existing pool.
+ //
+ explicit Pj_Pool(pj_pool_t *pool)
+ : p_(pool)
+ {
+ }
+
+ //
+ // Attach existing pool.
+ //
+ void attach(pj_pool_t *pool)
+ {
+ p_ = pool;
+ }
+
+ //
+ // Destructor.
+ //
+ // Release pool back to factory. Remember: if you delete pool, then
+ // make sure that all objects that have been allocated from this pool
+ // have been properly destroyed.
+ //
+ // This is where C++ is trickier than plain C!!
+ //
+ ~Pj_Pool()
+ {
+ if (p_)
+ pj_pool_release(p_);
+ }
+
+ //
+ // Get name.
+ //
+ const char *getobjname() const
+ {
+ return pj_pool_getobjname(p_);
+ }
+
+ //
+ // You can cast Pj_Pool to pj_pool_t*
+ //
+ operator pj_pool_t*()
+ {
+ return p_;
+ }
+
+ //
+ // Get pjlib compatible pool object.
+ //
+ pj_pool_t *pool_()
+ {
+ return p_;
+ }
+
+ //
+ // Get pjlib compatible pool object.
+ //
+ const pj_pool_t *pool_() const
+ {
+ return p_;
+ }
+
+ //
+ // Get pjlib compatible pool object.
+ //
+ pj_pool_t *pj_pool_t_()
+ {
+ return p_;
+ }
+
+ //
+ // Reset pool.
+ //
+ void reset()
+ {
+ pj_pool_reset(p_);
+ }
+
+ //
+ // Get current capacity.
+ //
+ pj_size_t get_capacity()
+ {
+ pj_pool_get_capacity(p_);
+ }
+
+ //
+ // Get current total bytes allocated from the pool.
+ //
+ pj_size_t get_used_size()
+ {
+ pj_pool_get_used_size(p_);
+ }
+
+ //
+ // Allocate.
+ //
+ void *alloc(pj_size_t size)
+ {
+ return pj_pool_alloc(p_, size);
+ }
+
+ //
+ // Allocate elements and zero fill the memory.
+ //
+ void *calloc(pj_size_t count, pj_size_t elem)
+ {
+ return pj_pool_calloc(p_, count, elem);
+ }
+
+ //
+ // Allocate and zero fill memory.
+ //
+ void *zalloc(pj_size_t size)
+ {
+ return pj_pool_zalloc(p_, size);
+ }
+
+private:
+ pj_pool_t *p_;
+};
+
+
+//
+// Caching pool.
+//
+class Pj_Caching_Pool
+{
+public:
+ //
+ // Construct caching pool.
+ //
+ Pj_Caching_Pool( pj_size_t cache_capacity = 0,
+ const pj_pool_factory_policy *pol=&pj_pool_factory_default_policy)
+ {
+ pj_caching_pool_init(&cp_, pol, cache_capacity);
+ }
+
+ //
+ // Destroy caching pool.
+ //
+ ~Pj_Caching_Pool()
+ {
+ pj_caching_pool_destroy(&cp_);
+ }
+
+ //
+ // Create pool.
+ //
+ pj_pool_t *create_pool( pj_size_t initial_size,
+ pj_size_t increment_size,
+ const char *name = NULL,
+ pj_pool_callback *callback = NULL)
+ {
+ return (pj_pool_t*)(*cp_.factory.create_pool)(&cp_.factory, name,
+ initial_size,
+ increment_size,
+ callback);
+ }
+
+private:
+ pj_caching_pool cp_;
+};
+
+//
+// Inlines for Pj_Object
+//
+inline void *Pj_Object::operator new(unsigned int class_size, Pj_Pool *pool)
+{
+ return pool->alloc(class_size);
+}
+inline void *Pj_Object::operator new(unsigned int class_size, Pj_Pool &pool)
+{
+ return pool.alloc(class_size);
+}
+
+//
+// Inlines for Pj_Pool
+//
+inline Pj_Pool::Pj_Pool( Pj_Caching_Pool &caching_pool,
+ pj_size_t initial_size,
+ pj_size_t increment_size,
+ const char *name,
+ pj_pool_callback *callback)
+{
+ p_ = caching_pool.create_pool(initial_size, increment_size, name,
+ callback);
+}
+
+
+#endif /* __PJPP_POOL_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/proactor.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/proactor.hpp
new file mode 100644
index 0000000..20f1f88
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/proactor.hpp
@@ -0,0 +1,515 @@
+/* $Id: proactor.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_PROACTOR_HPP__
+#define __PJPP_PROACTOR_HPP__
+
+#include <pj/ioqueue.h>
+#include <pj++/pool.hpp>
+#include <pj++/sock.hpp>
+#include <pj++/timer.hpp>
+#include <pj/errno.h>
+
+class Pj_Proactor;
+class Pj_Event_Handler;
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Asynchronous operation key.
+//
+// Applications may inheric this class to put their application
+// specific data.
+//
+class Pj_Async_Op : public pj_ioqueue_op_key_t
+{
+public:
+ //
+ // Construct with null handler.
+ // App must call set_handler() before use.
+ //
+ Pj_Async_Op()
+ : handler_(NULL)
+ {
+ pj_ioqueue_op_key_init(this, sizeof(*this));
+ }
+
+ //
+ // Constructor.
+ //
+ explicit Pj_Async_Op(Pj_Event_Handler *handler)
+ : handler_(handler)
+ {
+ pj_ioqueue_op_key_init(this, sizeof(*this));
+ }
+
+ //
+ // Set handler.
+ //
+ void set_handler(Pj_Event_Handler *handler)
+ {
+ handler_ = handler;
+ }
+
+ //
+ // Check whether operation is still pending for this key.
+ //
+ bool is_pending();
+
+ //
+ // Cancel the operation.
+ //
+ bool cancel(pj_ssize_t bytes_status=-PJ_ECANCELLED);
+
+protected:
+ Pj_Event_Handler *handler_;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Event handler.
+//
+// Applications should inherit this class to receive various event
+// notifications.
+//
+// Applications should implement get_socket_handle().
+//
+class Pj_Event_Handler : public Pj_Object
+{
+ friend class Pj_Proactor;
+public:
+ //
+ // Default constructor.
+ //
+ Pj_Event_Handler()
+ : key_(NULL)
+ {
+ pj_memset(&timer_, 0, sizeof(timer_));
+ timer_.user_data = this;
+ timer_.cb = &timer_callback;
+ }
+
+ //
+ // Destroy.
+ //
+ virtual ~Pj_Event_Handler()
+ {
+ unregister();
+ }
+
+ //
+ // Unregister this handler from the ioqueue.
+ //
+ void unregister()
+ {
+ if (key_) {
+ pj_ioqueue_unregister(key_);
+ key_ = NULL;
+ }
+ }
+
+ //
+ // Get socket handle associated with this.
+ //
+ virtual pj_sock_t get_socket_handle()
+ {
+ return PJ_INVALID_SOCKET;
+ }
+
+ //
+ // Start async receive.
+ //
+ pj_status_t recv( Pj_Async_Op *op_key,
+ void *buf, pj_ssize_t *len,
+ unsigned flags)
+ {
+ return pj_ioqueue_recv( key_, op_key,
+ buf, len, flags);
+ }
+
+ //
+ // Start async recvfrom()
+ //
+ pj_status_t recvfrom( Pj_Async_Op *op_key,
+ void *buf, pj_ssize_t *len, unsigned flags,
+ Pj_Inet_Addr *addr)
+ {
+ addr->addrlen_ = sizeof(Pj_Inet_Addr);
+ return pj_ioqueue_recvfrom( key_, op_key, buf, len, flags,
+ addr, &addr->addrlen_ );
+ }
+
+ //
+ // Start async send()
+ //
+ pj_status_t send( Pj_Async_Op *op_key,
+ const void *data, pj_ssize_t *len,
+ unsigned flags)
+ {
+ return pj_ioqueue_send( key_, op_key, data, len, flags);
+ }
+
+ //
+ // Start async sendto()
+ //
+ pj_status_t sendto( Pj_Async_Op *op_key,
+ const void *data, pj_ssize_t *len, unsigned flags,
+ const Pj_Inet_Addr &addr)
+ {
+ return pj_ioqueue_sendto(key_, op_key, data, len, flags,
+ &addr, sizeof(addr));
+ }
+
+#if PJ_HAS_TCP
+ //
+ // Start async connect()
+ //
+ pj_status_t connect(const Pj_Inet_Addr &addr)
+ {
+ return pj_ioqueue_connect(key_, &addr, sizeof(addr));
+ }
+
+ //
+ // Start async accept().
+ //
+ pj_status_t accept( Pj_Async_Op *op_key,
+ Pj_Socket *sock,
+ Pj_Inet_Addr *local = NULL,
+ Pj_Inet_Addr *remote = NULL)
+ {
+ int *addrlen = local ? &local->addrlen_ : NULL;
+ return pj_ioqueue_accept( key_, op_key, &sock->sock_,
+ local, remote, addrlen );
+ }
+
+#endif
+
+protected:
+ //////////////////
+ // Overridables
+ //////////////////
+
+ //
+ // Timeout callback.
+ //
+ virtual void on_timeout(int)
+ {
+ }
+
+ //
+ // On read complete callback.
+ //
+ virtual void on_read_complete( Pj_Async_Op*, pj_ssize_t)
+ {
+ }
+
+ //
+ // On write complete callback.
+ //
+ virtual void on_write_complete( Pj_Async_Op *, pj_ssize_t)
+ {
+ }
+
+#if PJ_HAS_TCP
+ //
+ // On connect complete callback.
+ //
+ virtual void on_connect_complete(pj_status_t)
+ {
+ }
+
+ //
+ // On new connection callback.
+ //
+ virtual void on_accept_complete( Pj_Async_Op*, pj_sock_t, pj_status_t)
+ {
+ }
+
+#endif
+
+
+private:
+ pj_ioqueue_key_t *key_;
+ pj_timer_entry timer_;
+
+ friend class Pj_Proactor;
+ friend class Pj_Async_Op;
+
+ //
+ // Static timer callback.
+ //
+ static void timer_callback( pj_timer_heap_t*,
+ struct pj_timer_entry *entry)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) entry->user_data;
+
+ handler->on_timeout(entry->id);
+ }
+};
+
+inline bool Pj_Async_Op::is_pending()
+{
+ return pj_ioqueue_is_pending(handler_->key_, this) != 0;
+}
+
+inline bool Pj_Async_Op::cancel(pj_ssize_t bytes_status)
+{
+ return pj_ioqueue_post_completion(handler_->key_, this,
+ bytes_status) == PJ_SUCCESS;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Proactor
+//
+class Pj_Proactor : public Pj_Object
+{
+public:
+ //
+ // Default constructor, initializes to NULL.
+ //
+ Pj_Proactor()
+ : ioq_(NULL), th_(NULL)
+ {
+ cb_.on_read_complete = &read_complete_cb;
+ cb_.on_write_complete = &write_complete_cb;
+ cb_.on_accept_complete = &accept_complete_cb;
+ cb_.on_connect_complete = &connect_complete_cb;
+ }
+
+ //
+ // Construct proactor.
+ //
+ Pj_Proactor( Pj_Pool *pool, pj_size_t max_fd,
+ pj_size_t max_timer_entries )
+ : ioq_(NULL), th_(NULL)
+ {
+ cb_.on_read_complete = &read_complete_cb;
+ cb_.on_write_complete = &write_complete_cb;
+ cb_.on_accept_complete = &accept_complete_cb;
+ cb_.on_connect_complete = &connect_complete_cb;
+
+ create(pool, max_fd, max_timer_entries);
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Proactor()
+ {
+ destroy();
+ }
+
+ //
+ // Create proactor.
+ //
+ pj_status_t create( Pj_Pool *pool, pj_size_t max_fd,
+ pj_size_t timer_entry_count)
+ {
+ pj_status_t status;
+
+ destroy();
+
+ status = pj_ioqueue_create(pool->pool_(), max_fd, &ioq_);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pj_timer_heap_create(pool->pool_(),
+ timer_entry_count, &th_);
+ if (status != PJ_SUCCESS) {
+ pj_ioqueue_destroy(ioq_);
+ ioq_ = NULL;
+ return NULL;
+ }
+
+ return status;
+ }
+
+ //
+ // Destroy proactor.
+ //
+ void destroy()
+ {
+ if (ioq_) {
+ pj_ioqueue_destroy(ioq_);
+ ioq_ = NULL;
+ }
+ if (th_) {
+ pj_timer_heap_destroy(th_);
+ th_ = NULL;
+ }
+ }
+
+ //
+ // Register handler.
+ // This will call handler->get_socket_handle()
+ //
+ pj_status_t register_socket_handler(Pj_Pool *pool,
+ Pj_Event_Handler *handler)
+ {
+ return pj_ioqueue_register_sock( pool->pool_(), ioq_,
+ handler->get_socket_handle(),
+ handler, &cb_, &handler->key_ );
+ }
+
+ //
+ // Unregister handler.
+ //
+ static void unregister_handler(Pj_Event_Handler *handler)
+ {
+ if (handler->key_) {
+ pj_ioqueue_unregister( handler->key_ );
+ handler->key_ = NULL;
+ }
+ }
+
+ //
+ // Scheduler timer.
+ //
+ bool schedule_timer( Pj_Event_Handler *handler,
+ const Pj_Time_Val &delay,
+ int id=-1)
+ {
+ return schedule_timer(th_, handler, delay, id);
+ }
+
+ //
+ // Cancel timer.
+ //
+ bool cancel_timer(Pj_Event_Handler *handler)
+ {
+ return pj_timer_heap_cancel(th_, &handler->timer_) == 1;
+ }
+
+ //
+ // Handle events.
+ //
+ int handle_events(Pj_Time_Val *max_timeout)
+ {
+ Pj_Time_Val timeout(0, 0);
+ int timer_count;
+
+ timer_count = pj_timer_heap_poll( th_, &timeout );
+
+ if (timeout.get_sec() < 0)
+ timeout.sec = PJ_MAXINT32;
+
+ /* If caller specifies maximum time to wait, then compare the value
+ * with the timeout to wait from timer, and use the minimum value.
+ */
+ if (max_timeout && timeout >= *max_timeout) {
+ timeout = *max_timeout;
+ }
+
+ /* Poll events in ioqueue. */
+ int ioqueue_count;
+
+ ioqueue_count = pj_ioqueue_poll(ioq_, &timeout);
+ if (ioqueue_count < 0)
+ return ioqueue_count;
+
+ return ioqueue_count + timer_count;
+ }
+
+ //
+ // Get the internal ioqueue object.
+ //
+ pj_ioqueue_t *get_io_queue()
+ {
+ return ioq_;
+ }
+
+ //
+ // Get the internal timer heap object.
+ //
+ pj_timer_heap_t *get_timer_heap()
+ {
+ return th_;
+ }
+
+private:
+ pj_ioqueue_t *ioq_;
+ pj_timer_heap_t *th_;
+ pj_ioqueue_callback cb_;
+
+ static bool schedule_timer( pj_timer_heap_t *timer,
+ Pj_Event_Handler *handler,
+ const Pj_Time_Val &delay,
+ int id=-1)
+ {
+ handler->timer_.id = id;
+ return pj_timer_heap_schedule(timer, &handler->timer_, &delay) == 0;
+ }
+
+
+ //
+ // Static read completion callback.
+ //
+ static void read_complete_cb( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_read)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);
+
+ handler->on_read_complete((Pj_Async_Op*)op_key, bytes_read);
+ }
+
+ //
+ // Static write completion callback.
+ //
+ static void write_complete_cb(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_sent)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);
+
+ handler->on_write_complete((Pj_Async_Op*)op_key, bytes_sent);
+ }
+
+ //
+ // Static accept completion callback.
+ //
+ static void accept_complete_cb(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_sock_t new_sock,
+ pj_status_t status)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);
+
+ handler->on_accept_complete((Pj_Async_Op*)op_key, new_sock, status);
+ }
+
+ //
+ // Static connect completion callback.
+ //
+ static void connect_complete_cb(pj_ioqueue_key_t *key,
+ pj_status_t status)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);
+
+ handler->on_connect_complete(status);
+ }
+
+};
+
+#endif /* __PJPP_PROACTOR_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/scanner.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/scanner.hpp
new file mode 100644
index 0000000..4916c70
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/scanner.hpp
@@ -0,0 +1,246 @@
+/* $Id: scanner.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_SCANNER_HPP__
+#define __PJPP_SCANNER_HPP__
+
+#include <pjlib-util/scanner.h>
+#include <pj++/string.hpp>
+
+class Pj_Cis;
+class Pj_Cis_Buffer;
+class Pj_Scanner;
+
+class Pj_Cis_Buffer
+{
+ friend class Pj_Cis;
+
+public:
+ Pj_Cis_Buffer()
+ {
+ pj_cis_buf_init(&buf_);
+ }
+
+private:
+ pj_cis_buf_t buf_;
+};
+
+
+class Pj_Cis
+{
+ friend class Pj_Scanner;
+
+public:
+ Pj_Cis(Pj_Cis_Buffer *buf)
+ {
+ pj_cis_init(&buf->buf_, &cis_);
+ }
+
+ Pj_Cis(const Pj_Cis &rhs)
+ {
+ pj_cis_dup(&cis_, (pj_cis_t*)&rhs.cis_);
+ }
+
+ void add_range(int start, int end)
+ {
+ pj_cis_add_range(&cis_, start, end);
+ }
+
+ void add_alpha()
+ {
+ pj_cis_add_alpha(&cis_);
+ }
+
+ void add_num()
+ {
+ pj_cis_add_num(&cis_);
+ }
+
+ void add_str(const char *str)
+ {
+ pj_cis_add_str(&cis_, str);
+ }
+
+ void add_cis(const Pj_Cis &rhs)
+ {
+ pj_cis_add_cis(&cis_, &rhs.cis_);
+ }
+
+ void del_range(int start, int end)
+ {
+ pj_cis_del_range(&cis_, start, end);
+ }
+
+ void del_str(const char *str)
+ {
+ pj_cis_del_str(&cis_, str);
+ }
+
+ void invert()
+ {
+ pj_cis_invert(&cis_);
+ }
+
+ bool match(int c) const
+ {
+ return pj_cis_match(&cis_, c) != 0;
+ }
+
+private:
+ pj_cis_t cis_;
+};
+
+
+
+class Pj_Scanner
+{
+public:
+ Pj_Scanner() {}
+
+ enum
+ {
+ SYNTAX_ERROR = 101
+ };
+ static void syntax_error_handler_throw_pj(pj_scanner *);
+
+ typedef pj_scan_state State;
+
+ void init(char *buf, int len, unsigned options=PJ_SCAN_AUTOSKIP_WS,
+ pj_syn_err_func_ptr callback = &syntax_error_handler_throw_pj)
+ {
+ pj_scan_init(&scanner_, buf, len, options, callback);
+ }
+
+ void fini()
+ {
+ pj_scan_fini(&scanner_);
+ }
+
+ int eof() const
+ {
+ return pj_scan_is_eof(&scanner_);
+ }
+
+ int peek_char() const
+ {
+ return *scanner_.curptr;
+ }
+
+ int peek(const Pj_Cis *cis, Pj_String *out)
+ {
+ return pj_scan_peek(&scanner_, &cis->cis_, out);
+ }
+
+ int peek_n(pj_size_t len, Pj_String *out)
+ {
+ return pj_scan_peek_n(&scanner_, len, out);
+ }
+
+ int peek_until(const Pj_Cis *cis, Pj_String *out)
+ {
+ return pj_scan_peek_until(&scanner_, &cis->cis_, out);
+ }
+
+ void get(const Pj_Cis *cis, Pj_String *out)
+ {
+ pj_scan_get(&scanner_, &cis->cis_, out);
+ }
+
+ void get_n(unsigned N, Pj_String *out)
+ {
+ pj_scan_get_n(&scanner_, N, out);
+ }
+
+ int get_char()
+ {
+ return pj_scan_get_char(&scanner_);
+ }
+
+ void get_quote(int begin_quote, int end_quote, Pj_String *out)
+ {
+ pj_scan_get_quote(&scanner_, begin_quote, end_quote, out);
+ }
+
+ void get_newline()
+ {
+ pj_scan_get_newline(&scanner_);
+ }
+
+ void get_until(const Pj_Cis *cis, Pj_String *out)
+ {
+ pj_scan_get_until(&scanner_, &cis->cis_, out);
+ }
+
+ void get_until_ch(int until_ch, Pj_String *out)
+ {
+ pj_scan_get_until_ch(&scanner_, until_ch, out);
+ }
+
+ void get_until_chr(const char *spec, Pj_String *out)
+ {
+ pj_scan_get_until_chr(&scanner_, spec, out);
+ }
+
+ void advance_n(unsigned N, bool skip_ws=true)
+ {
+ pj_scan_advance_n(&scanner_, N, skip_ws);
+ }
+
+ int strcmp(const char *s, int len)
+ {
+ return pj_scan_strcmp(&scanner_, s, len);
+ }
+
+ int stricmp(const char *s, int len)
+ {
+ return pj_scan_stricmp(&scanner_, s, len);
+ }
+
+ void skip_ws()
+ {
+ pj_scan_skip_whitespace(&scanner_);
+ }
+
+ void save_state(State *state) const
+ {
+ pj_scan_save_state(&scanner_, state);
+ }
+
+ void restore_state(State *state)
+ {
+ pj_scan_restore_state(&scanner_, state);
+ }
+
+ int get_pos_line() const
+ {
+ return scanner_.line;
+ }
+
+ int get_pos_col() const
+ {
+ return pj_scan_get_col(&scanner_);
+ }
+
+
+private:
+ pj_scanner scanner_;
+};
+
+#endif /* __PJPP_SCANNER_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/sock.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/sock.hpp
new file mode 100644
index 0000000..357344c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/sock.hpp
@@ -0,0 +1,444 @@
+/* $Id: sock.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_SOCK_HPP__
+#define __PJPP_SOCK_HPP__
+
+#include <pj/sock.h>
+#include <pj/string.h>
+
+class Pj_Event_Handler;
+
+//
+// Base class for address.
+//
+class Pj_Addr
+{
+};
+
+//
+// Internet address.
+//
+class Pj_Inet_Addr : public pj_sockaddr_in, public Pj_Addr
+{
+public:
+ //
+ // Get port number.
+ //
+ pj_uint16_t get_port_number() const
+ {
+ return pj_sockaddr_in_get_port(this);
+ }
+
+ //
+ // Set port number.
+ //
+ void set_port_number(pj_uint16_t port)
+ {
+ sin_family = PJ_AF_INET;
+ pj_sockaddr_in_set_port(this, port);
+ }
+
+ //
+ // Get IP address.
+ //
+ pj_uint32_t get_ip_address() const
+ {
+ return pj_sockaddr_in_get_addr(this).s_addr;
+ }
+
+ //
+ // Get address string.
+ //
+ const char *get_address() const
+ {
+ return pj_inet_ntoa(sin_addr);
+ }
+
+ //
+ // Set IP address.
+ //
+ void set_ip_address(pj_uint32_t addr)
+ {
+ sin_family = PJ_AF_INET;
+ pj_sockaddr_in_set_addr(this, addr);
+ }
+
+ //
+ // Set address.
+ //
+ pj_status_t set_address(const pj_str_t *addr)
+ {
+ return pj_sockaddr_in_set_str_addr(this, addr);
+ }
+
+ //
+ // Set address.
+ //
+ pj_status_t set_address(const char *addr)
+ {
+ pj_str_t s;
+ return pj_sockaddr_in_set_str_addr(this, pj_cstr(&s, addr));
+ }
+
+ //
+ // Compare for equality.
+ //
+ bool operator==(const Pj_Inet_Addr &rhs) const
+ {
+ return sin_family == rhs.sin_family &&
+ sin_addr.s_addr == rhs.sin_addr.s_addr &&
+ sin_port == rhs.sin_port;
+ }
+
+private:
+ //
+ // Dummy length used in pj_ioqueue_recvfrom() etc
+ //
+ friend class Pj_Event_Handler;
+ friend class Pj_Socket;
+ friend class Pj_Sock_Stream;
+ friend class Pj_Sock_Dgram;
+
+ int addrlen_;
+};
+
+
+//
+// Socket base class.
+//
+// Note:
+// socket will not automatically be closed on destructor.
+//
+class Pj_Socket
+{
+public:
+ //
+ // Default constructor.
+ //
+ Pj_Socket()
+ : sock_(PJ_INVALID_SOCKET)
+ {
+ }
+
+ //
+ // Initialize from a socket handle.
+ //
+ explicit Pj_Socket(pj_sock_t sock)
+ : sock_(sock)
+ {
+ }
+
+ //
+ // Copy constructor.
+ //
+ Pj_Socket(const Pj_Socket &rhs)
+ : sock_(rhs.sock_)
+ {
+ }
+
+ //
+ // Destructor will not close the socket.
+ // You must call close() explicitly.
+ //
+ ~Pj_Socket()
+ {
+ }
+
+ //
+ // Set socket handle.
+ //
+ void set_handle(pj_sock_t sock)
+ {
+ sock_ = sock;
+ }
+
+ //
+ // Get socket handle.
+ //
+ pj_sock_t get_handle() const
+ {
+ return sock_;
+ }
+
+ //
+ // Get socket handle.
+ //
+ pj_sock_t& get_handle()
+ {
+ return sock_;
+ }
+
+ //
+ // See if the socket is valid.
+ //
+ bool is_valid() const
+ {
+ return sock_ != PJ_INVALID_SOCKET;
+ }
+
+ //
+ // Create the socket.
+ //
+ pj_status_t create(int af, int type, int proto)
+ {
+ return pj_sock_socket(af, type, proto, &sock_);
+ }
+
+ //
+ // Bind socket.
+ //
+ pj_status_t bind(const Pj_Inet_Addr &addr)
+ {
+ return pj_sock_bind(sock_, &addr, sizeof(Pj_Inet_Addr));
+ }
+
+ //
+ // Close socket.
+ //
+ pj_status_t close()
+ {
+ pj_sock_close(sock_);
+ }
+
+ //
+ // Get peer socket name.
+ //
+ pj_status_t getpeername(Pj_Inet_Addr *addr)
+ {
+ return pj_sock_getpeername(sock_, addr, &addr->addrlen_);
+ }
+
+ //
+ // getsockname
+ //
+ pj_status_t getsockname(Pj_Inet_Addr *addr)
+ {
+ return pj_sock_getsockname(sock_, addr, &addr->addrlen_);
+ }
+
+ //
+ // getsockopt.
+ //
+ pj_status_t getsockopt(pj_uint16_t level, pj_uint16_t optname,
+ void *optval, int *optlen)
+ {
+ return pj_sock_getsockopt(sock_, level, optname, optval, optlen);
+ }
+
+ //
+ // setsockopt
+ //
+ pj_status_t setsockopt(pj_uint16_t level, pj_uint16_t optname,
+ const void *optval, int optlen)
+ {
+ return pj_sock_setsockopt(sock_, level, optname, optval, optlen);
+ }
+
+ //
+ // receive data.
+ //
+ pj_ssize_t recv(void *buf, pj_size_t len, int flag = 0)
+ {
+ pj_ssize_t bytes = len;
+ if (pj_sock_recv(sock_, buf, &bytes, flag) != PJ_SUCCESS)
+ return -1;
+ return bytes;
+ }
+
+ //
+ // send data.
+ //
+ pj_ssize_t send(const void *buf, pj_ssize_t len, int flag = 0)
+ {
+ pj_ssize_t bytes = len;
+ if (pj_sock_send(sock_, buf, &bytes, flag) != PJ_SUCCESS)
+ return -1;
+ return bytes;
+ }
+
+ //
+ // connect.
+ //
+ pj_status_t connect(const Pj_Inet_Addr &addr)
+ {
+ return pj_sock_connect(sock_, &addr, sizeof(Pj_Inet_Addr));
+ }
+
+ //
+ // assignment.
+ //
+ Pj_Socket &operator=(const Pj_Socket &rhs)
+ {
+ sock_ = rhs.sock_;
+ return *this;
+ }
+
+protected:
+ friend class Pj_Event_Handler;
+ pj_sock_t sock_;
+};
+
+
+#if PJ_HAS_TCP
+//
+// Stream socket.
+//
+class Pj_Sock_Stream : public Pj_Socket
+{
+public:
+ //
+ // Default constructor.
+ //
+ Pj_Sock_Stream()
+ {
+ }
+
+ //
+ // Initialize from a socket handle.
+ //
+ explicit Pj_Sock_Stream(pj_sock_t sock)
+ : Pj_Socket(sock)
+ {
+ }
+
+ //
+ // Copy constructor.
+ //
+ Pj_Sock_Stream(const Pj_Sock_Stream &rhs) : Pj_Socket(rhs)
+ {
+ }
+
+ //
+ // Assignment.
+ //
+ Pj_Sock_Stream &operator=(const Pj_Sock_Stream &rhs)
+ {
+ sock_ = rhs.sock_;
+ return *this;
+ }
+
+ //
+ // listen()
+ //
+ pj_status_t listen(int backlog = 5)
+ {
+ return pj_sock_listen(sock_, backlog);
+ }
+
+ //
+ // blocking accept()
+ //
+ Pj_Sock_Stream accept(Pj_Inet_Addr *remote_addr = NULL)
+ {
+ pj_sock_t newsock;
+ int *addrlen = remote_addr ? &remote_addr->addrlen_ : NULL;
+ pj_status_t status;
+
+ status = pj_sock_accept(sock_, &newsock, remote_addr, addrlen);
+ if (status != PJ_SUCCESS)
+ return Pj_Sock_Stream(-1);
+
+ return Pj_Sock_Stream(newsock);
+ }
+
+ //
+ // shutdown()
+ //
+ pj_status_t shutdown(int how = PJ_SHUT_RDWR)
+ {
+ return pj_sock_shutdown(sock_, how);
+ }
+
+};
+#endif
+
+//
+// Datagram socket.
+//
+class Pj_Sock_Dgram : public Pj_Socket
+{
+public:
+ //
+ // Default constructor.
+ //
+ Pj_Sock_Dgram()
+ {
+ }
+
+ //
+ // Initialize from a socket handle.
+ //
+ explicit Pj_Sock_Dgram(pj_sock_t sock)
+ : Pj_Socket(sock)
+ {
+ }
+
+ //
+ // Copy constructor.
+ //
+ Pj_Sock_Dgram(const Pj_Sock_Dgram &rhs)
+ : Pj_Socket(rhs)
+ {
+ }
+
+ //
+ // Assignment.
+ //
+ Pj_Sock_Dgram &operator=(const Pj_Sock_Dgram &rhs)
+ {
+ Pj_Socket::operator =(rhs);
+ return *this;
+ }
+
+ //
+ // recvfrom()
+ //
+ pj_ssize_t recvfrom( void *buf, pj_size_t len, int flag = 0,
+ Pj_Inet_Addr *fromaddr = NULL)
+ {
+ pj_ssize_t bytes = len;
+ int *addrlen = fromaddr ? &fromaddr->addrlen_ : NULL;
+ if (pj_sock_recvfrom( sock_, buf, &bytes, flag,
+ fromaddr, addrlen) != PJ_SUCCESS)
+ {
+ return -1;
+ }
+ return bytes;
+ }
+
+ //
+ // sendto()
+ //
+ pj_ssize_t sendto( const void *buf, pj_size_t len, int flag,
+ const Pj_Inet_Addr &addr)
+ {
+ pj_ssize_t bytes = len;
+ if (pj_sock_sendto( sock_, buf, &bytes, flag,
+ &addr, sizeof(pj_sockaddr_in)) != PJ_SUCCESS)
+ {
+ return -1;
+ }
+ return bytes;
+ }
+};
+
+
+#endif /* __PJPP_SOCK_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/string.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/string.hpp
new file mode 100644
index 0000000..3c0437f
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/string.hpp
@@ -0,0 +1,468 @@
+/* $Id: string.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_STRING_HPP__
+#define __PJPP_STRING_HPP__
+
+#include <pj/string.h>
+#include <pj++/pool.hpp>
+#include <pj/assert.h>
+
+//
+// String wrapper class for pj_str_t.
+//
+class Pj_String : public pj_str_t
+{
+public:
+ //
+ // Default constructor.
+ //
+ Pj_String()
+ {
+ pj_assert(sizeof(Pj_String) == sizeof(pj_str_t));
+ ptr=NULL;
+ slen=0;
+ }
+
+ //
+ // Construct the buffer from a char* (use with care)
+ //
+ Pj_String(char *str)
+ {
+ set(str);
+ }
+
+ //
+ // Construct from a const char*.
+ //
+ Pj_String(Pj_Pool &pool, const char *src)
+ {
+ set(pool, src);
+ }
+
+ //
+ // Construct from pj_str_t&.
+ //
+ explicit Pj_String(pj_str_t &s)
+ {
+ ptr = s.ptr;
+ slen = s.slen;
+ }
+
+ //
+ // Construct from const pj_str_t& (use with care!).
+ //
+ explicit Pj_String(const pj_str_t &s)
+ {
+ ptr = (char*)s.ptr;
+ slen = s.slen;
+ }
+
+ //
+ // Construct by copying from const pj_str_t*.
+ //
+ Pj_String(Pj_Pool &pool, const pj_str_t *s)
+ {
+ set(pool, s);
+ }
+
+ //
+ // Construct by copying from Pj_String
+ //
+ Pj_String(Pj_Pool &pool, const Pj_String &rhs)
+ {
+ set(pool, rhs);
+ }
+
+ //
+ // Construct from another Pj_String, use with care!
+ //
+ explicit Pj_String(const Pj_String &rhs)
+ {
+ ptr = rhs.ptr;
+ slen = rhs.slen;
+ }
+
+ //
+ // Construct from a char* and a length.
+ //
+ Pj_String(char *str, pj_size_t len)
+ {
+ set(str, len);
+ }
+
+ //
+ // Construct from pair of pointer.
+ //
+ Pj_String(char *begin, char *end)
+ {
+ pj_strset3(this, begin, end);
+ }
+
+ //
+ // You can cast Pj_String to pj_str_t*
+ //
+ operator pj_str_t*()
+ {
+ return this;
+ }
+
+ //
+ // You can cast const Pj_String to const pj_str_t*
+ //
+ operator const pj_str_t*() const
+ {
+ return this;
+ }
+
+ //
+ // Get the length of the string.
+ //
+ pj_size_t length() const
+ {
+ return pj_strlen(this);
+ }
+
+ //
+ // Get the length of the string.
+ //
+ pj_size_t size() const
+ {
+ return length();
+ }
+
+ //
+ // Get the string buffer.
+ //
+ const char *buf() const
+ {
+ return ptr;
+ }
+
+ //
+ // Initialize buffer from char*.
+ //
+ void set(char *str)
+ {
+ pj_strset2(this, str);
+ }
+
+ //
+ // Initialize by copying from a const char*.
+ //
+ void set(Pj_Pool &pool, const char *s)
+ {
+ pj_strdup2(pool, this, s);
+ }
+
+ //
+ // Initialize from pj_str_t*.
+ //
+ void set(pj_str_t *s)
+ {
+ pj_strassign(this, s);
+ }
+
+ //
+ // Initialize by copying from const pj_str_t*.
+ //
+ void set(Pj_Pool &pool, const pj_str_t *s)
+ {
+ pj_strdup(pool, this, s);
+ }
+
+ //
+ // Initialize from char* and length.
+ //
+ void set(char *str, pj_size_t len)
+ {
+ pj_strset(this, str, len);
+ }
+
+ //
+ // Initialize from pair of pointers.
+ //
+ void set(char *begin, char *end)
+ {
+ pj_strset3(this, begin, end);
+ }
+
+ //
+ // Initialize from other Pj_String.
+ //
+ void set(Pj_String &rhs)
+ {
+ pj_strassign(this, &rhs);
+ }
+
+ //
+ // Initialize by copying from a Pj_String*.
+ //
+ void set(Pj_Pool &pool, const Pj_String *s)
+ {
+ pj_strdup(pool, this, s);
+ }
+
+ //
+ // Initialize by copying from other Pj_String.
+ //
+ void set(Pj_Pool &pool, const Pj_String &s)
+ {
+ pj_strdup(pool, this, &s);
+ }
+
+ //
+ // Copy the contents of other string.
+ //
+ void strcpy(const pj_str_t *s)
+ {
+ pj_strcpy(this, s);
+ }
+
+ //
+ // Copy the contents of other string.
+ //
+ void strcpy(const Pj_String &rhs)
+ {
+ pj_strcpy(this, &rhs);
+ }
+
+ //
+ // Copy the contents of other string.
+ //
+ void strcpy(const char *s)
+ {
+ pj_strcpy2(this, s);
+ }
+
+ //
+ // Compare string.
+ //
+ int strcmp(const char *s) const
+ {
+ return pj_strcmp2(this, s);
+ }
+
+ //
+ // Compare string.
+ //
+ int strcmp(const pj_str_t *s) const
+ {
+ return pj_strcmp(this, s);
+ }
+
+ //
+ // Compare string.
+ //
+ int strcmp(const Pj_String &rhs) const
+ {
+ return pj_strcmp(this, &rhs);
+ }
+
+ //
+ // Compare string.
+ //
+ int strncmp(const char *s, pj_size_t len) const
+ {
+ return pj_strncmp2(this, s, len);
+ }
+
+ //
+ // Compare string.
+ //
+ int strncmp(const pj_str_t *s, pj_size_t len) const
+ {
+ return pj_strncmp(this, s, len);
+ }
+
+ //
+ // Compare string.
+ //
+ int strncmp(const Pj_String &rhs, pj_size_t len) const
+ {
+ return pj_strncmp(this, &rhs, len);
+ }
+
+ //
+ // Compare string.
+ //
+ int stricmp(const char *s) const
+ {
+ return pj_stricmp2(this, s);
+ }
+
+ //
+ // Compare string.
+ //
+ int stricmp(const pj_str_t *s) const
+ {
+ return pj_stricmp(this, s);
+ }
+
+ //
+ // Compare string.
+ //
+ int stricmp(const Pj_String &rhs) const
+ {
+ return stricmp(&rhs);
+ }
+
+ //
+ // Compare string.
+ //
+ int strnicmp(const char *s, pj_size_t len) const
+ {
+ return pj_strnicmp2(this, s, len);
+ }
+
+ //
+ // Compare string.
+ //
+ int strnicmp(const pj_str_t *s, pj_size_t len) const
+ {
+ return pj_strnicmp(this, s, len);
+ }
+
+ //
+ // Compare string.
+ //
+ int strnicmp(const Pj_String &rhs, pj_size_t len) const
+ {
+ return strnicmp(&rhs, len);
+ }
+
+ //
+ // Compare contents for equality.
+ //
+ bool operator==(const char *s) const
+ {
+ return strcmp(s) == 0;
+ }
+
+ //
+ // Compare contents for equality.
+ //
+ bool operator==(const pj_str_t *s) const
+ {
+ return strcmp(s) == 0;
+ }
+
+ //
+ // Compare contents for equality.
+ //
+ bool operator==(const Pj_String &rhs) const
+ {
+ return pj_strcmp(this, &rhs) == 0;
+ }
+
+ //
+ // Assign from char*
+ //
+ Pj_String& operator=(char *s)
+ {
+ set(s);
+ return *this;
+ }
+
+ ///
+ // Assign from another Pj_String, use with care!
+ //
+ Pj_String& operator=(const Pj_String &rhs)
+ {
+ ptr = rhs.ptr;
+ slen = rhs.slen;
+ return *this;
+ }
+
+ //
+ // Find a character in the string.
+ //
+ char *strchr(int chr)
+ {
+ return pj_strchr(this, chr);
+ }
+
+ //
+ // Find a character in the string.
+ //
+ char *find(int chr)
+ {
+ return strchr(chr);
+ }
+
+ //
+ // Concatenate string.
+ //
+ void strcat(const Pj_String &rhs)
+ {
+ pj_strcat(this, &rhs);
+ }
+
+ //
+ // Left trim.
+ //
+ void ltrim()
+ {
+ pj_strltrim(this);
+ }
+
+ //
+ // Right trim.
+ //
+ void rtrim()
+ {
+ pj_strrtrim(this);
+ }
+
+ //
+ // Left and right trim.
+ //
+ void trim()
+ {
+ pj_strtrim(this);
+ }
+
+ //
+ // Convert to unsigned long.
+ //
+ unsigned long to_ulong() const
+ {
+ return pj_strtoul(this);
+ }
+
+ //
+ // Convert from unsigned long.
+ //
+ void from_ulong(unsigned long value)
+ {
+ slen = pj_utoa(value, ptr);
+ }
+
+ //
+ // Convert from unsigned long with padding.
+ //
+ void from_ulong_with_pad(unsigned long value, int min_dig=0, int pad=' ')
+ {
+ slen = pj_utoa_pad(value, ptr, min_dig, pad);
+ }
+
+};
+
+#endif /* __PJPP_STRING_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/timer.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/timer.hpp
new file mode 100644
index 0000000..c94ace0
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/timer.hpp
@@ -0,0 +1,198 @@
+/* $Id: timer.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_TIMER_HPP__
+#define __PJPP_TIMER_HPP__
+
+#include <pj/timer.h>
+#include <pj++/types.hpp>
+#include <pj/assert.h>
+#include <pj++/lock.hpp>
+
+class Pj_Timer_Heap;
+
+//////////////////////////////////////////////////////////////////////////////
+// Timer entry.
+//
+// How to use:
+// Derive class from Pj_Timer_Entry and override on_timeout().
+// Scheduler timer in Pj_Timer_Heap.
+//
+class Pj_Timer_Entry : public Pj_Object
+{
+ friend class Pj_Timer_Heap;
+
+public:
+ //
+ // Default constructor.
+ //
+ Pj_Timer_Entry()
+ {
+ entry_.user_data = this;
+ entry_.cb = &timer_heap_callback;
+ }
+
+ //
+ // Destructor, do nothing.
+ //
+ ~Pj_Timer_Entry()
+ {
+ }
+
+ //
+ // Override this to get the timeout notification.
+ //
+ virtual void on_timeout(int id) = 0;
+
+private:
+ pj_timer_entry entry_;
+
+ static void timer_heap_callback(pj_timer_heap_t*, pj_timer_entry *e)
+ {
+ Pj_Timer_Entry *entry = (Pj_Timer_Entry*) e->user_data;
+ entry->on_timeout(e->id);
+ }
+
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Timer heap.
+//
+class Pj_Timer_Heap : public Pj_Object
+{
+public:
+ //
+ // Default constructor.
+ //
+ Pj_Timer_Heap()
+ : ht_(NULL)
+ {
+ }
+
+ //
+ // Construct timer heap.
+ //
+ Pj_Timer_Heap(Pj_Pool *pool, pj_size_t initial_count)
+ : ht_(NULL)
+ {
+ create(pool, initial_count);
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Timer_Heap()
+ {
+ destroy();
+ }
+
+ //
+ // Create
+ //
+ pj_status_t create(Pj_Pool *pool, pj_size_t initial_count)
+ {
+ destroy();
+ return pj_timer_heap_create(pool->pool_(), initial_count, &ht_);
+ }
+
+ //
+ // Destroy
+ //
+ void destroy()
+ {
+ if (ht_) {
+ pj_timer_heap_destroy(ht_);
+ ht_ = NULL;
+ }
+ }
+
+ //
+ // Get pjlib compatible timer heap object.
+ //
+ pj_timer_heap_t *get_timer_heap()
+ {
+ return ht_;
+ }
+
+ //
+ // Set the lock object.
+ //
+ void set_lock( Pj_Lock *lock, bool auto_delete )
+ {
+ pj_timer_heap_set_lock( ht_, lock->pj_lock_t_(), auto_delete);
+ }
+
+ //
+ // Set maximum number of timed out entries to be processed per poll.
+ //
+ unsigned set_max_timed_out_per_poll(unsigned count)
+ {
+ return pj_timer_heap_set_max_timed_out_per_poll(ht_, count);
+ }
+
+ //
+ // Schedule a timer.
+ //
+ bool schedule( Pj_Timer_Entry *ent, const Pj_Time_Val &delay,
+ int id)
+ {
+ ent->entry_.id = id;
+ return pj_timer_heap_schedule(ht_, &ent->entry_, &delay) == 0;
+ }
+
+ //
+ // Cancel a timer.
+ //
+ bool cancel(Pj_Timer_Entry *ent)
+ {
+ return pj_timer_heap_cancel(ht_, &ent->entry_) == 1;
+ }
+
+ //
+ // Get current number of timers
+ //
+ pj_size_t count()
+ {
+ return pj_timer_heap_count(ht_);
+ }
+
+ //
+ // Get the earliest time.
+ // Return false if no timer is found.
+ //
+ bool earliest_time(Pj_Time_Val *t)
+ {
+ return pj_timer_heap_earliest_time(ht_, t) == PJ_SUCCESS;
+ }
+
+ //
+ // Poll the timer.
+ // Return number of timed out entries has been called.
+ //
+ unsigned poll(Pj_Time_Val *next_delay = NULL)
+ {
+ return pj_timer_heap_poll(ht_, next_delay);
+ }
+
+private:
+ pj_timer_heap_t *ht_;
+};
+
+#endif /* __PJPP_TIMER_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/tree.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/tree.hpp
new file mode 100644
index 0000000..a5bc875
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/tree.hpp
@@ -0,0 +1,129 @@
+/* $Id: tree.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_TREE_HPP__
+#define __PJPP_TREE_HPP__
+
+#include <pj/rbtree.h>
+
+//
+// Tree.
+//
+class PJ_Tree
+{
+public:
+ typedef pj_rbtree_comp Comp;
+ class iterator;
+ class reverse_iterator;
+
+ class Node : private pj_rbtree_node
+ {
+ friend class PJ_Tree;
+ friend class iterator;
+ friend class reverse_iterator;
+
+ public:
+ Node() {}
+ explicit Node(void *data) { user_data = data; }
+ void set_user_data(void *data) { user_data = data; }
+ void *get_user_data() const { return user_data; }
+ };
+
+ class iterator
+ {
+ public:
+ iterator() {}
+ iterator(const iterator &rhs) : tr_(rhs.tr_), nd_(rhs.nd_) {}
+ iterator(pj_rbtree *tr, pj_rbtree_node *nd) : tr_(tr), nd_(nd) {}
+ Node *operator*() { return (Node*)nd_; }
+ bool operator==(const iterator &rhs) const { return tr_==rhs.tr_ && nd_==rhs.nd_; }
+ iterator &operator=(const iterator &rhs) { tr_=rhs.tr_; nd_=rhs.nd_; return *this; }
+ void operator++() { nd_=pj_rbtree_next(tr_, nd_); }
+ void operator--() { nd_=pj_rbtree_prev(tr_, nd_); }
+ protected:
+ pj_rbtree *tr_;
+ pj_rbtree_node *nd_;
+ };
+
+ class reverse_iterator : public iterator
+ {
+ public:
+ reverse_iterator() {}
+ reverse_iterator(const reverse_iterator &it) : iterator(it) {}
+ reverse_iterator(pj_rbtree *t, pj_rbtree_node *n) : iterator(t, n) {}
+ reverse_iterator &operator=(const reverse_iterator &rhs) { iterator::operator=(rhs); return *this; }
+ Node *operator*() { return (Node*)nd_; }
+ bool operator==(const reverse_iterator &rhs) const { return iterator::operator==(rhs); }
+ void operator++() { nd_=pj_rbtree_prev(tr_, nd_); }
+ void operator--() { nd_=pj_rbtree_next(tr_, nd_); }
+ };
+
+ explicit PJ_Tree(Comp *comp) { pj_rbtree_init(&t_, comp); }
+
+ iterator begin()
+ {
+ return iterator(&t_, pj_rbtree_first(&t_));
+ }
+
+ iterator end()
+ {
+ return iterator(&t_, NULL);
+ }
+
+ reverse_iterator rbegin()
+ {
+ return reverse_iterator(&t_, pj_rbtree_last(&t_));
+ }
+
+ reverse_iterator rend()
+ {
+ return reverse_iterator(&t_, NULL);
+ }
+
+ bool insert(Node *node)
+ {
+ return pj_rbtree_insert(&t_, node)==0 ? true : false;
+ }
+
+ Node *find(const void *key)
+ {
+ return (Node*)pj_rbtree_find(&t_, key);
+ }
+
+ Node *erase(Node *node)
+ {
+ return (Node*)pj_rbtree_erase(&t_, node);
+ }
+
+ unsigned max_height(Node *node=NULL)
+ {
+ return pj_rbtree_max_height(&t_, node);
+ }
+
+ unsigned min_height(Node *node=NULL)
+ {
+ return pj_rbtree_min_height(&t_, node);
+ }
+
+private:
+ pj_rbtree t_;
+};
+
+#endif /* __PJPP_TREE_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj++/types.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/types.hpp
new file mode 100644
index 0000000..6a0d341
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj++/types.hpp
@@ -0,0 +1,175 @@
+/* $Id: types.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJPP_TYPES_HPP__
+#define __PJPP_TYPES_HPP__
+
+#include <pj/types.h>
+
+class Pj_Pool;
+class Pj_Socket ;
+class Pj_Lock;
+
+
+//
+// PJLIB initializer.
+//
+class Pjlib
+{
+public:
+ Pjlib()
+ {
+ pj_init();
+ }
+};
+
+//
+// Class Pj_Object is declared in pool.hpp
+//
+
+//
+// Time value wrapper.
+//
+class Pj_Time_Val : public pj_time_val
+{
+public:
+ Pj_Time_Val()
+ {
+ }
+
+ Pj_Time_Val(long init_sec, long init_msec)
+ {
+ sec = init_sec;
+ msec = init_msec;
+ }
+
+ Pj_Time_Val(const Pj_Time_Val &rhs)
+ {
+ sec=rhs.sec;
+ msec=rhs.msec;
+ }
+
+ explicit Pj_Time_Val(const pj_time_val &tv)
+ {
+ sec = tv.sec;
+ msec = tv.msec;
+ }
+
+ long get_sec() const
+ {
+ return sec;
+ }
+
+ long get_msec() const
+ {
+ return msec;
+ }
+
+ void set_sec (long s)
+ {
+ sec = s;
+ }
+
+ void set_msec(long ms)
+ {
+ msec = ms;
+ normalize();
+ }
+
+ long to_msec() const
+ {
+ return PJ_TIME_VAL_MSEC((*this));
+ }
+
+ bool operator == (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_EQ((*this), rhs);
+ }
+
+ bool operator > (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_GT((*this), rhs);
+ }
+
+ bool operator >= (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_GTE((*this), rhs);
+ }
+
+ bool operator < (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_LT((*this), rhs);
+ }
+
+ bool operator <= (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_LTE((*this), rhs);
+ }
+
+ Pj_Time_Val & operator = (const Pj_Time_Val &rhs)
+ {
+ sec = rhs.sec;
+ msec = rhs.msec;
+ return *this;
+ }
+
+ Pj_Time_Val & operator += (const Pj_Time_Val &rhs)
+ {
+ PJ_TIME_VAL_ADD((*this), rhs);
+ return *this;
+ }
+
+ Pj_Time_Val & operator -= (const Pj_Time_Val &rhs)
+ {
+ PJ_TIME_VAL_SUB((*this), rhs);
+ return *this;
+ }
+
+ /* Must include os.hpp to use these, otherwise unresolved in linking */
+ inline pj_status_t gettimeofday();
+ inline pj_parsed_time decode();
+ inline pj_status_t encode(const pj_parsed_time *pt);
+ inline pj_status_t to_gmt();
+ inline pj_status_t to_local();
+
+
+private:
+ void normalize()
+ {
+ pj_time_val_normalize(this);
+ }
+
+};
+
+//
+// Macro to declare common object comparison operators.
+//
+#define PJ_DECLARE_OPERATORS(rhs_type) \
+ bool operator!=(rhs_type rhs) const { \
+ return !operator==(rhs); } \
+ bool operator<=(rhs_type rhs) const { \
+ return operator<(rhs) || operator==(rhs); } \
+ bool operator>(rhs_type rhs) const { \
+ return !operator<=(rhs); } \
+ bool operator>=(rhs_type rhs) const { \
+ return !operator<(rhs); }
+
+
+#endif /* __PJPP_TYPES_HPP__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/activesock.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/activesock.h
new file mode 100644
index 0000000..36aabd3
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/activesock.h
@@ -0,0 +1,526 @@
+/* $Id: activesock.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_ASYNCSOCK_H__
+#define __PJ_ASYNCSOCK_H__
+
+/**
+ * @file activesock.h
+ * @brief Active socket
+ */
+
+#include <pj/ioqueue.h>
+#include <pj/sock.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_ACTIVESOCK Active socket I/O
+ * @brief Active socket performs active operations on socket.
+ * @ingroup PJ_IO
+ * @{
+ *
+ * Active socket is a higher level abstraction to the ioqueue. It provides
+ * automation to socket operations which otherwise would have to be done
+ * manually by the applications. For example with socket recv(), recvfrom(),
+ * and accept() operations, application only needs to invoke these
+ * operation once, and it will be notified whenever data or incoming TCP
+ * connection (in the case of accept()) arrives.
+ */
+
+/**
+ * This opaque structure describes the active socket.
+ */
+typedef struct pj_activesock_t pj_activesock_t;
+
+/**
+ * This structure contains the callbacks to be called by the active socket.
+ */
+typedef struct pj_activesock_cb
+{
+ /**
+ * This callback is called when a data arrives as the result of
+ * pj_activesock_start_read().
+ *
+ * @param asock The active socket.
+ * @param data The buffer containing the new data, if any. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument may be NULL.
+ * @param size The length of data in the buffer.
+ * @param status The status of the read operation. This may contain
+ * non-PJ_SUCCESS for example when the TCP connection
+ * has been closed. In this case, the buffer may
+ * contain left over data from previous callback which
+ * the application may want to process.
+ * @param remainder If application wishes to leave some data in the
+ * buffer (common for TCP applications), it should
+ * move the remainder data to the front part of the
+ * buffer and set the remainder length here. The value
+ * of this parameter will be ignored for datagram
+ * sockets.
+ *
+ * @return PJ_TRUE if further read is desired, and PJ_FALSE
+ * when application no longer wants to receive data.
+ * Application may destroy the active socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_data_read)(pj_activesock_t *asock,
+ void *data,
+ pj_size_t size,
+ pj_status_t status,
+ pj_size_t *remainder);
+ /**
+ * This callback is called when a packet arrives as the result of
+ * pj_activesock_start_recvfrom().
+ *
+ * @param asock The active socket.
+ * @param data The buffer containing the packet, if any. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument will be set to NULL.
+ * @param size The length of packet in the buffer. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument will be set to zero.
+ * @param src_addr Source address of the packet.
+ * @param addr_len Length of the source address.
+ * @param status This contains
+ *
+ * @return PJ_TRUE if further read is desired, and PJ_FALSE
+ * when application no longer wants to receive data.
+ * Application may destroy the active socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_data_recvfrom)(pj_activesock_t *asock,
+ void *data,
+ pj_size_t size,
+ const pj_sockaddr_t *src_addr,
+ int addr_len,
+ pj_status_t status);
+
+ /**
+ * This callback is called when data has been sent.
+ *
+ * @param asock The active socket.
+ * @param send_key Key associated with the send operation.
+ * @param sent If value is positive non-zero it indicates the
+ * number of data sent. When the value is negative,
+ * it contains the error code which can be retrieved
+ * by negating the value (i.e. status=-sent).
+ *
+ * @return Application may destroy the active socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_data_sent)(pj_activesock_t *asock,
+ pj_ioqueue_op_key_t *send_key,
+ pj_ssize_t sent);
+
+ /**
+ * This callback is called when new connection arrives as the result
+ * of pj_activesock_start_accept().
+ *
+ * @param asock The active socket.
+ * @param newsock The new incoming socket.
+ * @param src_addr The source address of the connection.
+ * @param addr_len Length of the source address.
+ *
+ * @return PJ_TRUE if further accept() is desired, and PJ_FALSE
+ * when application no longer wants to accept incoming
+ * connection. Application may destroy the active socket
+ * in the callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_accept_complete)(pj_activesock_t *asock,
+ pj_sock_t newsock,
+ const pj_sockaddr_t *src_addr,
+ int src_addr_len);
+
+ /**
+ * This callback is called when pending connect operation has been
+ * completed.
+ *
+ * @param asock The active socket.
+ * @param status The connection result. If connection has been
+ * successfully established, the status will contain
+ * PJ_SUCCESS.
+ *
+ * @return Application may destroy the active socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_connect_complete)(pj_activesock_t *asock,
+ pj_status_t status);
+
+} pj_activesock_cb;
+
+
+/**
+ * Settings that can be given during active socket creation. Application
+ * must initialize this structure with #pj_activesock_cfg_default().
+ */
+typedef struct pj_activesock_cfg
+{
+ /**
+ * Number of concurrent asynchronous operations that is to be supported
+ * by the active socket. This value only affects socket receive and
+ * accept operations -- the active socket will issue one or more
+ * asynchronous read and accept operations based on the value of this
+ * field. Setting this field to more than one will allow more than one
+ * incoming data or incoming connections to be processed simultaneously
+ * on multiprocessor systems, when the ioqueue is polled by more than
+ * one threads.
+ *
+ * The default value is 1.
+ */
+ unsigned async_cnt;
+
+ /**
+ * The ioqueue concurrency to be forced on the socket when it is
+ * registered to the ioqueue. See #pj_ioqueue_set_concurrency() for more
+ * info about ioqueue concurrency.
+ *
+ * When this value is -1, the concurrency setting will not be forced for
+ * this socket, and the socket will inherit the concurrency setting of
+ * the ioqueue. When this value is zero, the active socket will disable
+ * concurrency for the socket. When this value is +1, the active socket
+ * will enable concurrency for the socket.
+ *
+ * The default value is -1.
+ */
+ int concurrency;
+
+ /**
+ * If this option is specified, the active socket will make sure that
+ * asynchronous send operation with stream oriented socket will only
+ * call the callback after all data has been sent. This means that the
+ * active socket will automatically resend the remaining data until
+ * all data has been sent.
+ *
+ * Please note that when this option is specified, it is possible that
+ * error is reported after partial data has been sent. Also setting
+ * this will disable the ioqueue concurrency for the socket.
+ *
+ * Default value is 1.
+ */
+ pj_bool_t whole_data;
+
+} pj_activesock_cfg;
+
+
+/**
+ * Initialize the active socket configuration with the default values.
+ *
+ * @param cfg The configuration to be initialized.
+ */
+PJ_DECL(void) pj_activesock_cfg_default(pj_activesock_cfg *cfg);
+
+
+/**
+ * Create the active socket for the specified socket. This will register
+ * the socket to the specified ioqueue.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param sock The socket handle.
+ * @param sock_type Specify socket type, either pj_SOCK_DGRAM() or
+ * pj_SOCK_STREAM(). The active socket needs this
+ * information to handle connection closure for
+ * connection oriented sockets.
+ * @param ioqueue The ioqueue to use.
+ * @param opt Optional settings. When this setting is not specifed,
+ * the default values will be used.
+ * @param cb Pointer to structure containing application
+ * callbacks.
+ * @param user_data Arbitrary user data to be associated with this
+ * active socket.
+ * @param p_asock Pointer to receive the active socket instance.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_create(pj_pool_t *pool,
+ pj_sock_t sock,
+ int sock_type,
+ const pj_activesock_cfg *opt,
+ pj_ioqueue_t *ioqueue,
+ const pj_activesock_cb *cb,
+ void *user_data,
+ pj_activesock_t **p_asock);
+
+/**
+ * Create UDP socket descriptor, bind it to the specified address, and
+ * create the active socket for the socket descriptor.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param addr Specifies the address family of the socket and the
+ * address where the socket should be bound to. If
+ * this argument is NULL, then AF_INET is assumed and
+ * the socket will be bound to any addresses and port.
+ * @param opt Optional settings. When this setting is not specifed,
+ * the default values will be used.
+ * @param cb Pointer to structure containing application
+ * callbacks.
+ * @param user_data Arbitrary user data to be associated with this
+ * active socket.
+ * @param p_asock Pointer to receive the active socket instance.
+ * @param bound_addr If this argument is specified, it will be filled with
+ * the bound address on return.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_create_udp(pj_pool_t *pool,
+ const pj_sockaddr *addr,
+ const pj_activesock_cfg *opt,
+ pj_ioqueue_t *ioqueue,
+ const pj_activesock_cb *cb,
+ void *user_data,
+ pj_activesock_t **p_asock,
+ pj_sockaddr *bound_addr);
+
+
+/**
+ * Close the active socket. This will unregister the socket from the
+ * ioqueue and ultimately close the socket.
+ *
+ * @param asock The active socket.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_close(pj_activesock_t *asock);
+
+
+/**
+ * Associate arbitrary data with the active socket. Application may
+ * inspect this data in the callbacks and associate it with higher
+ * level processing.
+ *
+ * @param asock The active socket.
+ * @param user_data The user data to be associated with the active
+ * socket.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_set_user_data(pj_activesock_t *asock,
+ void *user_data);
+
+/**
+ * Retrieve the user data previously associated with this active
+ * socket.
+ *
+ * @param asock The active socket.
+ *
+ * @return The user data.
+ */
+PJ_DECL(void*) pj_activesock_get_user_data(pj_activesock_t *asock);
+
+
+/**
+ * Starts read operation on this active socket. This function will create
+ * \a async_cnt number of buffers (the \a async_cnt parameter was given
+ * in \a pj_activesock_create() function) where each buffer is \a buff_size
+ * long. The buffers are allocated from the specified \a pool. Once the
+ * buffers are created, it then issues \a async_cnt number of asynchronous
+ * \a recv() operations to the socket and returns back to caller. Incoming
+ * data on the socket will be reported back to application via the
+ * \a on_data_read() callback.
+ *
+ * Application only needs to call this function once to initiate read
+ * operations. Further read operations will be done automatically by the
+ * active socket when \a on_data_read() callback returns non-zero.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param flags Flags to be given to pj_ioqueue_recv().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_read(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ pj_uint32_t flags);
+
+/**
+ * Same as #pj_activesock_start_read(), except that the application
+ * supplies the buffers for the read operation so that the acive socket
+ * does not have to allocate the buffers.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param readbuf Array of packet buffers, each has buff_size size.
+ * @param flags Flags to be given to pj_ioqueue_recv().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_read2(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ void *readbuf[],
+ pj_uint32_t flags);
+
+/**
+ * Same as pj_activesock_start_read(), except that this function is used
+ * only for datagram sockets, and it will trigger \a on_data_recvfrom()
+ * callback instead.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param flags Flags to be given to pj_ioqueue_recvfrom().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_recvfrom(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ pj_uint32_t flags);
+
+/**
+ * Same as #pj_activesock_start_recvfrom() except that the recvfrom()
+ * operation takes the buffer from the argument rather than creating
+ * new ones.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param readbuf Array of packet buffers, each has buff_size size.
+ * @param flags Flags to be given to pj_ioqueue_recvfrom().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_recvfrom2(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ void *readbuf[],
+ pj_uint32_t flags);
+
+/**
+ * Send data using the socket.
+ *
+ * @param asock The active socket.
+ * @param send_key The operation key to send the data, which is useful
+ * if application wants to submit multiple pending
+ * send operations and want to track which exact data
+ * has been sent in the \a on_data_sent() callback.
+ * @param data The data to be sent. This data must remain valid
+ * until the data has been sent.
+ * @param size The size of the data.
+ * @param flags Flags to be given to pj_ioqueue_send().
+ *
+ *
+ * @return PJ_SUCCESS if data has been sent immediately, or
+ * PJ_EPENDING if data cannot be sent immediately. In
+ * this case the \a on_data_sent() callback will be
+ * called when data is actually sent. Any other return
+ * value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_activesock_send(pj_activesock_t *asock,
+ pj_ioqueue_op_key_t *send_key,
+ const void *data,
+ pj_ssize_t *size,
+ unsigned flags);
+
+/**
+ * Send datagram using the socket.
+ *
+ * @param asock The active socket.
+ * @param send_key The operation key to send the data, which is useful
+ * if application wants to submit multiple pending
+ * send operations and want to track which exact data
+ * has been sent in the \a on_data_sent() callback.
+ * @param data The data to be sent. This data must remain valid
+ * until the data has been sent.
+ * @param size The size of the data.
+ * @param flags Flags to be given to pj_ioqueue_send().
+ * @param addr The destination address.
+ * @param addr_len The length of the address.
+ *
+ * @return PJ_SUCCESS if data has been sent immediately, or
+ * PJ_EPENDING if data cannot be sent immediately. In
+ * this case the \a on_data_sent() callback will be
+ * called when data is actually sent. Any other return
+ * value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_activesock_sendto(pj_activesock_t *asock,
+ pj_ioqueue_op_key_t *send_key,
+ const void *data,
+ pj_ssize_t *size,
+ unsigned flags,
+ const pj_sockaddr_t *addr,
+ int addr_len);
+
+#if PJ_HAS_TCP
+/**
+ * Starts asynchronous socket accept() operations on this active socket.
+ * Application must bind the socket before calling this function. This
+ * function will issue \a async_cnt number of asynchronous \a accept()
+ * operations to the socket and returns back to caller. Incoming
+ * connection on the socket will be reported back to application via the
+ * \a on_accept_complete() callback.
+ *
+ * Application only needs to call this function once to initiate accept()
+ * operations. Further accept() operations will be done automatically by
+ * the active socket when \a on_accept_complete() callback returns non-zero.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate some internal data for the
+ * operation.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_accept(pj_activesock_t *asock,
+ pj_pool_t *pool);
+
+/**
+ * Starts asynchronous socket connect() operation for this socket. Once
+ * the connection is done (either successfully or not), the
+ * \a on_connect_complete() callback will be called.
+ *
+ * @param asock The active socket.
+ * @param pool The pool to allocate some internal data for the
+ * operation.
+ * @param remaddr Remote address.
+ * @param addr_len Length of the remote address.
+ *
+ * @return PJ_SUCCESS if connection can be established immediately,
+ * or PJ_EPENDING if connection cannot be established
+ * immediately. In this case the \a on_connect_complete()
+ * callback will be called when connection is complete.
+ * Any other return value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_connect(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ const pj_sockaddr_t *remaddr,
+ int addr_len);
+
+#endif /* PJ_HAS_TCP */
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJ_ASYNCSOCK_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/addr_resolv.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/addr_resolv.h
new file mode 100644
index 0000000..b7f16c6
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/addr_resolv.h
@@ -0,0 +1,165 @@
+/* $Id: addr_resolv.h 2908 2009-08-22 11:18:50Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_ADDR_RESOLV_H__
+#define __PJ_ADDR_RESOLV_H__
+
+/**
+ * @file addr_resolv.h
+ * @brief IP address resolution.
+ */
+
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup pj_addr_resolve Network Address Resolution
+ * @ingroup PJ_IO
+ * @{
+ *
+ * This module provides function to resolve Internet address of the
+ * specified host name. To resolve a particular host name, application
+ * can just call #pj_gethostbyname().
+ *
+ * Example:
+ * <pre>
+ * ...
+ * pj_hostent he;
+ * pj_status_t rc;
+ * pj_str_t host = pj_str("host.example.com");
+ *
+ * rc = pj_gethostbyname( &host, &he);
+ * if (rc != PJ_SUCCESS) {
+ * char errbuf[80];
+ * pj_strerror( rc, errbuf, sizeof(errbuf));
+ * PJ_LOG(2,("sample", "Unable to resolve host, error=%s", errbuf));
+ * return rc;
+ * }
+ *
+ * // process address...
+ * addr.sin_addr.s_addr = *(pj_uint32_t*)he.h_addr;
+ * ...
+ * </pre>
+ *
+ * It's pretty simple really...
+ */
+
+/** This structure describes an Internet host address. */
+typedef struct pj_hostent
+{
+ char *h_name; /**< The official name of the host. */
+ char **h_aliases; /**< Aliases list. */
+ int h_addrtype; /**< Host address type. */
+ int h_length; /**< Length of address. */
+ char **h_addr_list; /**< List of addresses. */
+} pj_hostent;
+
+/** Shortcut to h_addr_list[0] */
+#define h_addr h_addr_list[0]
+
+/**
+ * This structure describes address information pj_getaddrinfo().
+ */
+typedef struct pj_addrinfo
+{
+ char ai_canonname[PJ_MAX_HOSTNAME]; /**< Canonical name for host*/
+ pj_sockaddr ai_addr; /**< Binary address. */
+} pj_addrinfo;
+
+
+/**
+ * This function fills the structure of type pj_hostent for a given host name.
+ * For host resolution function that also works with IPv6, please see
+ * #pj_getaddrinfo().
+ *
+ * @param name Host name to resolve. Specifying IPv4 address here
+ * may fail on some platforms (e.g. Windows)
+ * @param he The pj_hostent structure to be filled. Note that
+ * the pointers in this structure points to temporary
+ * variables which value will be reset upon subsequent
+ * invocation.
+ *
+ * @return PJ_SUCCESS, or the appropriate error codes.
+ */
+PJ_DECL(pj_status_t) pj_gethostbyname(const pj_str_t *name, pj_hostent *he);
+
+
+/**
+ * Resolve the primary IP address of local host.
+ *
+ * @param af The desired address family to query. Valid values
+ * are pj_AF_INET() or pj_AF_INET6().
+ * @param addr On successful resolution, the address family and address
+ * part of this socket address will be filled up with the host
+ * IP address, in network byte order. Other parts of the socket
+ * address are untouched.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr);
+
+
+/**
+ * Get the IP address of the default interface. Default interface is the
+ * interface of the default route.
+ *
+ * @param af The desired address family to query. Valid values
+ * are pj_AF_INET() or pj_AF_INET6().
+ * @param addr On successful resolution, the address family and address
+ * part of this socket address will be filled up with the host
+ * IP address, in network byte order. Other parts of the socket
+ * address are untouched.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_getdefaultipinterface(int af,
+ pj_sockaddr *addr);
+
+
+/**
+ * This function translates the name of a service location (for example,
+ * a host name) and returns a set of addresses and associated information
+ * to be used in creating a socket with which to address the specified
+ * service.
+ *
+ * @param af The desired address family to query. Valid values
+ * are pj_AF_INET(), pj_AF_INET6(), or pj_AF_UNSPEC().
+ * @param name Descriptive name or an address string, such as host
+ * name.
+ * @param count On input, it specifies the number of elements in
+ * \a ai array. On output, this will be set with the
+ * number of address informations found for the
+ * specified name.
+ * @param ai Array of address info to be filled with the information
+ * about the host.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *name,
+ unsigned *count, pj_addrinfo ai[]);
+
+
+
+/** @} */
+
+PJ_END_DECL
+
+#endif /* __PJ_ADDR_RESOLV_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/array.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/array.h
new file mode 100644
index 0000000..067ea93
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/array.h
@@ -0,0 +1,96 @@
+/* $Id: array.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_ARRAY_H__
+#define __PJ_ARRAY_H__
+
+/**
+ * @file array.h
+ * @brief PJLIB Array helper.
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_ARRAY Array helper.
+ * @ingroup PJ_DS
+ * @{
+ *
+ * This module provides helper to manipulate array of elements of any size.
+ * It provides most used array operations such as insert, erase, and search.
+ */
+
+/**
+ * Insert value to the array at the given position, and rearrange the
+ * remaining nodes after the position.
+ *
+ * @param array the array.
+ * @param elem_size the size of the individual element.
+ * @param count the CURRENT number of elements in the array.
+ * @param pos the position where the new element is put.
+ * @param value the value to copy to the new element.
+ */
+PJ_DECL(void) pj_array_insert( void *array,
+ unsigned elem_size,
+ unsigned count,
+ unsigned pos,
+ const void *value);
+
+/**
+ * Erase a value from the array at given position, and rearrange the remaining
+ * elements post the erased element.
+ *
+ * @param array the array.
+ * @param elem_size the size of the individual element.
+ * @param count the current number of elements in the array.
+ * @param pos the index/position to delete.
+ */
+PJ_DECL(void) pj_array_erase( void *array,
+ unsigned elem_size,
+ unsigned count,
+ unsigned pos);
+
+/**
+ * Search the first value in the array according to matching function.
+ *
+ * @param array the array.
+ * @param elem_size the individual size of the element.
+ * @param count the number of elements.
+ * @param matching the matching function, which MUST return PJ_SUCCESS if
+ * the specified element match.
+ * @param result the pointer to the value found.
+ *
+ * @return PJ_SUCCESS if value is found, otherwise the error code.
+ */
+PJ_DECL(pj_status_t) pj_array_find( const void *array,
+ unsigned elem_size,
+ unsigned count,
+ pj_status_t (*matching)(const void *value),
+ void **result);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJ_ARRAY_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/assert.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/assert.h
new file mode 100644
index 0000000..c71d2e9
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/assert.h
@@ -0,0 +1,95 @@
+/* $Id: assert.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_ASSERT_H__
+#define __PJ_ASSERT_H__
+
+/**
+ * @file assert.h
+ * @brief Assertion macro pj_assert().
+ */
+
+#include <pj/config.h>
+#include <pj/compat/assert.h>
+
+/**
+ * @defgroup pj_assert Assertion Macro
+ * @ingroup PJ_MISC
+ * @{
+ *
+ * Assertion and other helper macros for sanity checking.
+ */
+
+/**
+ * @hideinitializer
+ * Check during debug build that an expression is true. If the expression
+ * computes to false during run-time, then the program will stop at the
+ * offending statements.
+ * For release build, this macro will not do anything.
+ *
+ * @param expr The expression to be evaluated.
+ */
+#ifndef pj_assert
+# define pj_assert(expr) assert(expr)
+#endif
+
+
+/**
+ * @hideinitializer
+ * If #PJ_ENABLE_EXTRA_CHECK is declared and the value is non-zero, then
+ * #PJ_ASSERT_RETURN macro will evaluate the expression in @a expr during
+ * run-time. If the expression yields false, assertion will be triggered
+ * and the current function will return with the specified return value.
+ *
+ * If #PJ_ENABLE_EXTRA_CHECK is not declared or is zero, then no run-time
+ * checking will be performed. The macro simply evaluates to pj_assert(expr).
+ */
+#if defined(PJ_ENABLE_EXTRA_CHECK) && PJ_ENABLE_EXTRA_CHECK != 0
+# define PJ_ASSERT_RETURN(expr,retval) \
+ do { \
+ if (!(expr)) { pj_assert(expr); return retval; } \
+ } while (0)
+#else
+# define PJ_ASSERT_RETURN(expr,retval) pj_assert(expr)
+#endif
+
+/**
+ * @hideinitializer
+ * If #PJ_ENABLE_EXTRA_CHECK is declared and non-zero, then
+ * #PJ_ASSERT_ON_FAIL macro will evaluate the expression in @a expr during
+ * run-time. If the expression yields false, assertion will be triggered
+ * and @a exec_on_fail will be executed.
+ *
+ * If #PJ_ENABLE_EXTRA_CHECK is not declared or is zero, then no run-time
+ * checking will be performed. The macro simply evaluates to pj_assert(expr).
+ */
+#if defined(PJ_ENABLE_EXTRA_CHECK) && PJ_ENABLE_EXTRA_CHECK != 0
+# define PJ_ASSERT_ON_FAIL(expr,exec_on_fail) \
+ do { \
+ pj_assert(expr); \
+ if (!(expr)) exec_on_fail; \
+ } while (0)
+#else
+# define PJ_ASSERT_ON_FAIL(expr,exec_on_fail) pj_assert(expr)
+#endif
+
+/** @} */
+
+#endif /* __PJ_ASSERT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/assert.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/assert.h
new file mode 100644
index 0000000..768c041
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/assert.h
@@ -0,0 +1,44 @@
+/* $Id: assert.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_ASSERT_H__
+#define __PJ_COMPAT_ASSERT_H__
+
+/**
+ * @file assert.h
+ * @brief Provides assert() macro.
+ */
+
+#if defined(PJ_HAS_ASSERT_H) && PJ_HAS_ASSERT_H != 0
+# include <assert.h>
+
+#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0
+# define assert(expr) do { \
+ if (!(expr)) \
+ printk("!!ASSERTION FAILED: [%s:%d] \"" #expr "\"\n",\
+ __FILE__, __LINE__); \
+ } while (0)
+
+#else
+# warning "assert() is not implemented"
+# define assert(expr)
+#endif
+
+#endif /* __PJ_COMPAT_ASSERT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_armcc.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_armcc.h
new file mode 100644
index 0000000..31d268b
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_armcc.h
@@ -0,0 +1,57 @@
+/* $Id: cc_armcc.h 2407 2009-01-01 20:56:36Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_CC_ARMCC_H__
+#define __PJ_COMPAT_CC_ARMCC_H__
+
+/**
+ * @file cc_armcc.h
+ * @brief Describes ARMCC compiler specifics.
+ */
+
+#ifndef __ARMCC__
+# error "This file is only for armcc!"
+#endif
+
+#define PJ_CC_NAME "armcc"
+#define PJ_CC_VER_1 __ARMCC__
+#define PJ_CC_VER_2 __ARMCC_MINOR__
+#define PJ_CC_VER_3 __ARMCC_PATCHLEVEL__
+
+#ifdef __cplusplus
+# define PJ_INLINE_SPECIFIER inline
+#else
+# define PJ_INLINE_SPECIFIER static __inline
+#endif
+
+#define PJ_THREAD_FUNC
+#define PJ_NORETURN
+#define PJ_ATTR_NORETURN __attribute__ ((noreturn))
+
+#define PJ_HAS_INT64 1
+
+typedef long long pj_int64_t;
+typedef unsigned long long pj_uint64_t;
+
+#define PJ_INT64_FMT "L"
+
+#define PJ_UNREACHED(x)
+
+#endif /* __PJ_COMPAT_CC_ARMCC_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_codew.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_codew.h
new file mode 100644
index 0000000..a0ebd42
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_codew.h
@@ -0,0 +1,55 @@
+/* $Id: cc_codew.h 2407 2009-01-01 20:56:36Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_CC_CODEW_H__
+#define __PJ_COMPAT_CC_CODEW_H__
+
+/**
+ * @file cc_codew.h
+ * @brief Describes MetroWerks Code Warrior compiler specifics.
+ */
+
+#ifndef __MWERKS__
+# error "This file is only for Code Warrior!"
+#endif
+
+#define PJ_CC_NAME "codewarrior"
+#define PJ_CC_VER_1 ((__MWERKS__ & 0xF000) >> 12)
+#define PJ_CC_VER_2 ((__MWERKS__ & 0x0F00) >> 8)
+#define PJ_CC_VER_3 ((__MWERKS__ & 0xFF))
+
+
+#define PJ_INLINE_SPECIFIER static inline
+#define PJ_THREAD_FUNC
+#define PJ_NORETURN
+#define PJ_ATTR_NORETURN
+
+#define PJ_HAS_INT64 1
+
+typedef long long pj_int64_t;
+typedef unsigned long long pj_uint64_t;
+
+#define PJ_INT64(val) val##LL
+#define PJ_UINT64(val) val##LLU
+#define PJ_INT64_FMT "L"
+
+#define PJ_UNREACHED(x)
+
+#endif /* __PJ_COMPAT_CC_CODEW_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcc.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcc.h
new file mode 100644
index 0000000..90a551a
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcc.h
@@ -0,0 +1,75 @@
+/* $Id: cc_gcc.h 2407 2009-01-01 20:56:36Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_CC_GCC_H__
+#define __PJ_COMPAT_CC_GCC_H__
+
+/**
+ * @file cc_gcc.h
+ * @brief Describes GCC compiler specifics.
+ */
+
+#ifndef __GNUC__
+# error "This file is only for gcc!"
+#endif
+
+#define PJ_CC_NAME "gcc"
+#define PJ_CC_VER_1 __GNUC__
+#define PJ_CC_VER_2 __GNUC_MINOR__
+
+/* __GNUC_PATCHLEVEL__ doesn't exist in gcc-2.9x.x */
+#ifdef __GNUC_PATCHLEVEL__
+# define PJ_CC_VER_3 __GNUC_PATCHLEVEL__
+#else
+# define PJ_CC_VER_3 0
+#endif
+
+
+
+#define PJ_THREAD_FUNC
+#define PJ_NORETURN
+
+#define PJ_HAS_INT64 1
+
+#ifdef __STRICT_ANSI__
+ #include <inttypes.h>
+ typedef int64_t pj_int64_t;
+ typedef uint64_t pj_uint64_t;
+ #define PJ_INLINE_SPECIFIER static __inline
+ #define PJ_ATTR_NORETURN
+#else
+ typedef long long pj_int64_t;
+ typedef unsigned long long pj_uint64_t;
+ #define PJ_INLINE_SPECIFIER static inline
+ #define PJ_ATTR_NORETURN __attribute__ ((noreturn))
+#endif
+
+#define PJ_INT64(val) val##LL
+#define PJ_UINT64(val) val##LLU
+#define PJ_INT64_FMT "L"
+
+
+#ifdef __GLIBC__
+# define PJ_HAS_BZERO 1
+#endif
+
+#define PJ_UNREACHED(x)
+
+#endif /* __PJ_COMPAT_CC_GCC_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcce.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcce.h
new file mode 100644
index 0000000..06cc660
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcce.h
@@ -0,0 +1,54 @@
+/* $Id: cc_gcce.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_CC_GCCE_H__
+#define __PJ_COMPAT_CC_GCCE_H__
+
+/**
+ * @file cc_gcce.h
+ * @brief Describes GCCE compiler specifics.
+ */
+
+#ifndef __GCCE__
+# error "This file is only for gcce!"
+#endif
+
+#define PJ_CC_NAME "gcce"
+#define PJ_CC_VER_1 __GCCE__
+#define PJ_CC_VER_2 __GCCE_MINOR__
+#define PJ_CC_VER_3 __GCCE_PATCHLEVEL__
+
+
+#define PJ_INLINE_SPECIFIER static inline
+#define PJ_THREAD_FUNC
+#define PJ_NORETURN
+#define PJ_ATTR_NORETURN __attribute__ ((noreturn))
+
+#define PJ_HAS_INT64 1
+
+typedef long long pj_int64_t;
+typedef unsigned long long pj_uint64_t;
+
+#define PJ_INT64(val) val##LL
+#define PJ_UINT64(val) val##LLU
+#define PJ_INT64_FMT "L"
+
+
+#endif /* __PJ_COMPAT_CC_GCCE_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_msvc.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_msvc.h
new file mode 100644
index 0000000..0eb323d
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_msvc.h
@@ -0,0 +1,84 @@
+/* $Id: cc_msvc.h 2407 2009-01-01 20:56:36Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_CC_MSVC_H__
+#define __PJ_COMPAT_CC_MSVC_H__
+
+/**
+ * @file cc_msvc.h
+ * @brief Describes Microsoft Visual C compiler specifics.
+ */
+
+#ifndef _MSC_VER
+# error "This header file is only for Visual C compiler!"
+#endif
+
+#define PJ_CC_NAME "msvc"
+#define PJ_CC_VER_1 (_MSC_VER/100)
+#define PJ_CC_VER_2 (_MSC_VER%100)
+#define PJ_CC_VER_3 0
+
+/* Disable CRT deprecation warnings. */
+#if PJ_CC_VER_1 >= 8 && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+#if PJ_CC_VER_1 >= 8 && !defined(_CRT_SECURE_NO_WARNINGS)
+# define _CRT_SECURE_NO_WARNINGS
+ /* The above doesn't seem to work, at least on VS2005, so lets use
+ * this construct as well.
+ */
+# pragma warning(disable: 4996)
+#endif
+
+#pragma warning(disable: 4127) // conditional expression is constant
+#pragma warning(disable: 4611) // not wise to mix setjmp with C++
+#pragma warning(disable: 4514) // unref. inline function has been removed
+#ifdef NDEBUG
+# pragma warning(disable: 4702) // unreachable code
+# pragma warning(disable: 4710) // function is not inlined.
+# pragma warning(disable: 4711) // function selected for auto inline expansion
+#endif
+
+#ifdef __cplusplus
+# define PJ_INLINE_SPECIFIER inline
+#else
+# define PJ_INLINE_SPECIFIER static __inline
+#endif
+
+#define PJ_EXPORT_DECL_SPECIFIER __declspec(dllexport)
+#define PJ_EXPORT_DEF_SPECIFIER __declspec(dllexport)
+#define PJ_IMPORT_DECL_SPECIFIER __declspec(dllimport)
+
+#define PJ_THREAD_FUNC
+#define PJ_NORETURN __declspec(noreturn)
+#define PJ_ATTR_NORETURN
+
+#define PJ_HAS_INT64 1
+
+typedef __int64 pj_int64_t;
+typedef unsigned __int64 pj_uint64_t;
+
+#define PJ_INT64(val) val##i64
+#define PJ_UINT64(val) val##ui64
+#define PJ_INT64_FMT "I64"
+
+#define PJ_UNREACHED(x)
+
+#endif /* __PJ_COMPAT_CC_MSVC_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_mwcc.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_mwcc.h
new file mode 100644
index 0000000..293e770
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_mwcc.h
@@ -0,0 +1,55 @@
+/* $Id: cc_mwcc.h 2407 2009-01-01 20:56:36Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_CC_MWCC_H__
+#define __PJ_COMPAT_CC_MWCC_H__
+
+/**
+ * @file cc_mwcc.h
+ * @brief Describes MWCC compiler specifics.
+ */
+
+#ifndef __CW32__
+# error "This file is only for mwcc!"
+#endif
+
+#define PJ_CC_NAME "mwcc32sym"
+#define PJ_CC_VER_1 1
+#define PJ_CC_VER_2 0
+#define PJ_CC_VER_3 0
+
+
+#define PJ_INLINE_SPECIFIER static inline
+#define PJ_THREAD_FUNC
+#define PJ_NORETURN
+#define PJ_ATTR_NORETURN __attribute__ ((noreturn))
+
+#define PJ_HAS_INT64 1
+
+typedef long long pj_int64_t;
+typedef unsigned long long pj_uint64_t;
+
+#define PJ_INT64(val) val##LL
+#define PJ_UINT64(val) val##LLU
+#define PJ_INT64_FMT "L"
+
+#define PJ_UNREACHED(x)
+
+#endif /* __PJ_COMPAT_CC_MWCC_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/ctype.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/ctype.h
new file mode 100644
index 0000000..ca4e7ac
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/ctype.h
@@ -0,0 +1,49 @@
+/* $Id: ctype.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_CTYPE_H__
+#define __PJ_COMPAT_CTYPE_H__
+
+/**
+ * @file ctype.h
+ * @brief Provides ctype function family.
+ */
+
+#if defined(PJ_HAS_CTYPE_H) && PJ_HAS_CTYPE_H != 0
+# include <ctype.h>
+#else
+# define isalnum(c) (isalpha(c) || isdigit(c))
+# define isalpha(c) (islower(c) || isupper(c))
+# define isascii(c) (((unsigned char)(c))<=0x7f)
+# define isdigit(c) ((c)>='0' && (c)<='9')
+# define isspace(c) ((c)==' ' || (c)=='\t' ||\
+ (c)=='\n' || (c)=='\r' || (c)=='\v')
+# define islower(c) ((c)>='a' && (c)<='z')
+# define isupper(c) ((c)>='A' && (c)<='Z')
+# define isxdigit(c) (isdigit(c) || (tolower(c)>='a'&&tolower(c)<='f'))
+# define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)+('a'-'A') : (c))
+# define toupper(c) (((c) >= 'a' && (c) <= 'z') ? (c)-('a'-'A') : (c))
+#endif
+
+#ifndef isblank
+# define isblank(c) (c==' ' || c=='\t')
+#endif
+
+
+#endif /* __PJ_COMPAT_CTYPE_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/errno.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/errno.h
new file mode 100644
index 0000000..09a7583
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/errno.h
@@ -0,0 +1,44 @@
+/* $Id: errno.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_ERRNO_H__
+#define __PJ_COMPAT_ERRNO_H__
+
+#if defined(PJ_WIN32) && PJ_WIN32 != 0 || \
+ defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0
+
+ typedef unsigned long pj_os_err_type;
+# define pj_get_native_os_error() GetLastError()
+# define pj_get_native_netos_error() WSAGetLastError()
+
+#elif defined(PJ_HAS_ERRNO_VAR) && PJ_HAS_ERRNO_VAR!= 0
+
+ typedef int pj_os_err_type;
+# define pj_get_native_os_error() (errno)
+# define pj_get_native_netos_error() (errno)
+
+#else
+
+# error "Please define how to get errno for this platform here!"
+
+#endif
+
+
+#endif /* __PJ_COMPAT_ERRNO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/high_precision.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/high_precision.h
new file mode 100644
index 0000000..7889f3a
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/high_precision.h
@@ -0,0 +1,103 @@
+/* $Id: high_precision.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_HIGH_PRECISION_H__
+#define __PJ_COMPAT_HIGH_PRECISION_H__
+
+
+#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT != 0
+ /*
+ * The first choice for high precision math is to use double.
+ */
+# include <math.h>
+ typedef double pj_highprec_t;
+
+# define PJ_HIGHPREC_VALUE_IS_ZERO(a) (a==0)
+# define pj_highprec_mod(a,b) (a=fmod(a,b))
+
+#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0
+
+# include <asm/div64.h>
+
+ typedef pj_int64_t pj_highprec_t;
+
+# define pj_highprec_div(a1,a2) do_div(a1,a2)
+# define pj_highprec_mod(a1,a2) (a1=do_mod(a1, a2))
+
+ PJ_INLINE(pj_int64_t) do_mod( pj_int64_t a1, pj_int64_t a2)
+ {
+ return do_div(a1,a2);
+ }
+
+
+#elif defined(PJ_HAS_INT64) && PJ_HAS_INT64 != 0
+ /*
+ * Next choice is to use 64-bit arithmatics.
+ */
+ typedef pj_int64_t pj_highprec_t;
+
+#else
+# warning "High precision math is not available"
+
+ /*
+ * Last, fallback to 32-bit arithmetics.
+ */
+ typedef pj_int32_t pj_highprec_t;
+
+#endif
+
+/**
+ * @def pj_highprec_mul
+ * pj_highprec_mul(a1, a2) - High Precision Multiplication
+ * Multiply a1 and a2, and store the result in a1.
+ */
+#ifndef pj_highprec_mul
+# define pj_highprec_mul(a1,a2) (a1 = a1 * a2)
+#endif
+
+/**
+ * @def pj_highprec_div
+ * pj_highprec_div(a1, a2) - High Precision Division
+ * Divide a2 from a1, and store the result in a1.
+ */
+#ifndef pj_highprec_div
+# define pj_highprec_div(a1,a2) (a1 = a1 / a2)
+#endif
+
+/**
+ * @def pj_highprec_mod
+ * pj_highprec_mod(a1, a2) - High Precision Modulus
+ * Get the modulus a2 from a1, and store the result in a1.
+ */
+#ifndef pj_highprec_mod
+# define pj_highprec_mod(a1,a2) (a1 = a1 % a2)
+#endif
+
+
+/**
+ * @def PJ_HIGHPREC_VALUE_IS_ZERO(a)
+ * Test if the specified high precision value is zero.
+ */
+#ifndef PJ_HIGHPREC_VALUE_IS_ZERO
+# define PJ_HIGHPREC_VALUE_IS_ZERO(a) (a==0)
+#endif
+
+
+#endif /* __PJ_COMPAT_HIGH_PRECISION_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_alpha.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_alpha.h
new file mode 100644
index 0000000..3fe8efd
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_alpha.h
@@ -0,0 +1,36 @@
+/* $Id: m_alpha.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_M_ALPHA_H__
+#define __PJ_COMPAT_M_ALPHA_H__
+
+/**
+ * @file m_alpha.h
+ * @brief Describes Alpha processor family specifics.
+ */
+
+#define PJ_M_NAME "alpha"
+
+#define PJ_HAS_PENTIUM 0
+#define PJ_IS_LITTLE_ENDIAN 1
+#define PJ_IS_BIG_ENDIAN 0
+
+
+#endif /* __PJ_COMPAT_M_ALPHA_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_armv4.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_armv4.h
new file mode 100644
index 0000000..ed423a9
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_armv4.h
@@ -0,0 +1,39 @@
+/* $Id: m_armv4.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_M_ARMV4_H__
+#define __PJ_COMPAT_M_ARMV4_H__
+
+/**
+ * @file m_armv4.h
+ * @brief Describes ARM family processor specifics.
+ */
+
+/*
+ * This file covers PJ_M_ARMV4 etc.
+ */
+
+#define PJ_M_NAME "armv4"
+
+#define PJ_HAS_PENTIUM 0
+#define PJ_IS_LITTLE_ENDIAN 1
+#define PJ_IS_BIG_ENDIAN 0
+
+
+#endif /* __PJ_COMPAT_M_ARMV4_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_auto.h.in b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_auto.h.in
new file mode 100644
index 0000000..054e872
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_auto.h.in
@@ -0,0 +1,60 @@
+/* $Id: m_auto.h.in 2510 2009-03-13 12:15:43Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_M_AUTO_H__
+#define __PJ_COMPAT_M_AUTO_H__
+
+/**
+ * @file m_auto.h
+ * @brief Automatically generated process definition file.
+ */
+
+/* Machine name, filled in by autoconf script */
+#undef PJ_M_NAME
+
+/* Endianness. It's reported on pjsip list on 09/02/13 that autoconf
+ * endianness detection failed for universal build, so special case
+ * for it here. Thanks Ruud Klaver for the fix.
+ */
+#ifdef PJ_DARWINOS
+# ifdef __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+ /* Endianness, as detected by autoconf */
+# undef WORDS_BIGENDIAN
+#endif
+
+#ifdef WORDS_BIGENDIAN
+# define PJ_IS_LITTLE_ENDIAN 0
+# define PJ_IS_BIG_ENDIAN 1
+#else
+# define PJ_IS_LITTLE_ENDIAN 1
+# define PJ_IS_BIG_ENDIAN 0
+#endif
+
+
+/* Specify if floating point is present/desired */
+#undef PJ_HAS_FLOATING_POINT
+
+/* Deprecated */
+#define PJ_HAS_PENTIUM 0
+
+#endif /* __PJ_COMPAT_M_AUTO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_i386.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_i386.h
new file mode 100644
index 0000000..ec697ce
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_i386.h
@@ -0,0 +1,35 @@
+/* $Id: m_i386.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_M_i386_H__
+#define __PJ_COMPAT_M_i386_H__
+
+/**
+ * @file m_i386.h
+ * @brief Describes Intel i386 family processor specifics.
+ */
+
+#define PJ_M_NAME "i386"
+
+#define PJ_HAS_PENTIUM 1
+#define PJ_IS_LITTLE_ENDIAN 1
+#define PJ_IS_BIG_ENDIAN 0
+
+
+#endif /* __PJ_COMPAT_M_i386_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_m68k.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_m68k.h
new file mode 100644
index 0000000..de4ea24
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_m68k.h
@@ -0,0 +1,35 @@
+/* $Id: m_m68k.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_M_M68K_H__
+#define __PJ_COMPAT_M_M68K_H__
+
+/**
+ * @file m_m68k.h
+ * @brief Describes Motorola m68k family processor specifics.
+ */
+
+#define PJ_M_NAME "m68k"
+
+#define PJ_HAS_PENTIUM 0
+#define PJ_IS_LITTLE_ENDIAN 1
+#define PJ_IS_BIG_ENDIAN 0
+
+
+#endif /* __PJ_COMPAT_M_M68K_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_powerpc.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_powerpc.h
new file mode 100644
index 0000000..50e9db7
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_powerpc.h
@@ -0,0 +1,36 @@
+/* $Id: m_powerpc.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_M_POWERPC_H__
+#define __PJ_COMPAT_M_POWERPC_H__
+
+/**
+ * @file m_ppc.h
+ * @brief Describes PowerPC family processor specifics.
+ */
+
+#define PJ_M_NAME "powerpc"
+
+#define PJ_HAS_PENTIUM 0
+#define PJ_IS_LITTLE_ENDIAN 0
+#define PJ_IS_BIG_ENDIAN 1
+
+
+#endif /* __PJ_COMPAT_M_POWERPC_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_sparc.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_sparc.h
new file mode 100644
index 0000000..a30f3c0
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_sparc.h
@@ -0,0 +1,35 @@
+/* $Id: m_sparc.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_M_SPARC_H__
+#define __PJ_COMPAT_M_SPARC_H__
+
+/**
+ * @file m_sparc.h
+ * @brief Describes SPARC family processor specifics.
+ */
+
+#define PJ_M_NAME "sparc"
+
+#define PJ_HAS_PENTIUM 0
+#define PJ_IS_LITTLE_ENDIAN 0
+#define PJ_IS_BIG_ENDIAN 1
+
+
+#endif /* __PJ_COMPAT_M_SPARC_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_x86_64.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_x86_64.h
new file mode 100644
index 0000000..09c43d2
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_x86_64.h
@@ -0,0 +1,36 @@
+/* $Id: m_x86_64.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_M_x86_64_H__
+#define __PJ_COMPAT_M_x86_64_H__
+
+/**
+ * @file m_i386.h
+ * @brief Describes 64bit x86 Intel/AMD family processor specifics.
+ */
+
+#define PJ_M_NAME "x86_64"
+
+#define PJ_HAS_PENTIUM 1
+#define PJ_IS_LITTLE_ENDIAN 1
+#define PJ_IS_BIG_ENDIAN 0
+
+
+#endif /* __PJ_COMPAT_M_x86_64_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/malloc.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/malloc.h
new file mode 100644
index 0000000..699e6eb
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/malloc.h
@@ -0,0 +1,34 @@
+/* $Id: malloc.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_MALLOC_H__
+#define __PJ_COMPAT_MALLOC_H__
+
+/**
+ * @file malloc.h
+ * @brief Provides malloc() and free() functions.
+ */
+
+#if defined(PJ_HAS_MALLOC_H) && PJ_HAS_MALLOC_H != 0
+# include <malloc.h>
+#elif defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H != 0
+# include <stdlib.h>
+#endif
+
+#endif /* __PJ_COMPAT_MALLOC_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_auto.h.in b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_auto.h.in
new file mode 100644
index 0000000..5dbe131
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_auto.h.in
@@ -0,0 +1,191 @@
+/* $Id: os_auto.h.in 2970 2009-10-26 15:47:52Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_OS_AUTO_H__
+#define __PJ_COMPAT_OS_AUTO_H__
+
+/**
+ * @file os_auto.h
+ * @brief Describes operating system specifics (automatically detected by
+ * autoconf)
+ */
+
+/* Canonical OS name */
+#undef PJ_OS_NAME
+
+/* Legacy macros */
+#undef PJ_WIN32
+#undef PJ_WIN32_WINNT
+#undef WIN32_LEAN_AND_MEAN
+#undef PJ_DARWINOS
+#undef PJ_LINUX
+#undef PJ_RTEMS
+#undef PJ_SUNOS
+
+#if defined(PJ_WIN32_WINNT) && !defined(_WIN32_WINNT)
+# define _WIN32_WINNT PJ_WIN32_WINNT
+#endif
+
+/* Headers availability */
+#undef PJ_HAS_ARPA_INET_H
+#undef PJ_HAS_ASSERT_H
+#undef PJ_HAS_CTYPE_H
+#undef PJ_HAS_ERRNO_H
+#undef PJ_HAS_FCNTL_H
+#undef PJ_HAS_LINUX_SOCKET_H
+#undef PJ_HAS_MALLOC_H
+#undef PJ_HAS_NETDB_H
+#undef PJ_HAS_NETINET_IN_SYSTM_H
+#undef PJ_HAS_NETINET_IN_H
+#undef PJ_HAS_NETINET_IP_H
+#undef PJ_HAS_NETINET_TCP_H
+#undef PJ_HAS_NET_IF_H
+#undef PJ_HAS_IFADDRS_H
+#undef PJ_HAS_SEMAPHORE_H
+#undef PJ_HAS_SETJMP_H
+#undef PJ_HAS_STDARG_H
+#undef PJ_HAS_STDDEF_H
+#undef PJ_HAS_STDIO_H
+#undef PJ_HAS_STDINT_H
+#undef PJ_HAS_STDLIB_H
+#undef PJ_HAS_STRING_H
+#undef PJ_HAS_SYS_IOCTL_H
+#undef PJ_HAS_SYS_SELECT_H
+#undef PJ_HAS_SYS_SOCKET_H
+#undef PJ_HAS_SYS_TIME_H
+#undef PJ_HAS_SYS_TIMEB_H
+#undef PJ_HAS_SYS_TYPES_H
+#undef PJ_HAS_TIME_H
+#undef PJ_HAS_UNISTD_H
+
+#undef PJ_HAS_MSWSOCK_H
+#undef PJ_HAS_WINSOCK_H
+#undef PJ_HAS_WINSOCK2_H
+#undef PJ_HAS_WS2TCPIP_H
+
+#undef PJ_SOCK_HAS_INET_ATON
+#undef PJ_SOCK_HAS_INET_PTON
+#undef PJ_SOCK_HAS_INET_NTOP
+#undef PJ_SOCK_HAS_GETADDRINFO
+
+/* On these OSes, semaphore feature depends on semaphore.h */
+#if defined(PJ_HAS_SEMAPHORE_H) && PJ_HAS_SEMAPHORE_H!=0
+# define PJ_HAS_SEMAPHORE 1
+#elif defined(PJ_WIN32) && PJ_WIN32!=0
+# define PJ_HAS_SEMAPHORE 1
+#else
+# define PJ_HAS_SEMAPHORE 0
+#endif
+
+/* Do we have pthread_mutexattr_settype()? */
+#undef PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE
+
+/* Does pthread_mutexattr_t has "recursive" member? */
+#undef PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#undef PJ_SOCKADDR_HAS_LEN
+
+/* Does the OS have socklen_t? */
+#undef PJ_HAS_SOCKLEN_T
+
+#if !defined(socklen_t) && (!defined(PJ_HAS_SOCKLEN_T) || PJ_HAS_SOCKLEN_T==0)
+# define PJ_HAS_SOCKLEN_T 1
+ typedef int socklen_t;
+#endif
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#undef PJ_SELECT_NEEDS_NFDS
+
+/* Is errno a good way to retrieve OS errors?
+ */
+#undef PJ_HAS_ERRNO_VAR
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#undef PJ_HAS_SO_ERROR
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() can not return immediate daata.
+ */
+#undef PJ_BLOCKING_ERROR_VAL
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#undef PJ_BLOCKING_CONNECT_ERROR_VAL
+
+/* Default threading is enabled, unless it's overridden. */
+#ifndef PJ_HAS_THREADS
+# define PJ_HAS_THREADS (1)
+#endif
+
+/* Do we need high resolution timer? */
+#undef PJ_HAS_HIGH_RES_TIMER
+
+/* Is malloc() available? */
+#undef PJ_HAS_MALLOC
+
+#ifndef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+#endif
+
+/* Unicode? */
+#undef PJ_NATIVE_STRING_IS_UNICODE
+
+/* Pool alignment in bytes */
+#undef PJ_POOL_ALIGNMENT
+
+/* The type of atomic variable value: */
+#undef PJ_ATOMIC_VALUE_TYPE
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#undef PJ_EMULATE_RWMUTEX
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#undef PJ_THREAD_SET_STACK_SIZE
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#undef PJ_THREAD_ALLOCATE_STACK
+
+/* SSL socket availability. */
+#ifndef PJ_HAS_SSL_SOCK
+#undef PJ_HAS_SSL_SOCK
+#endif
+
+
+#endif /* __PJ_COMPAT_OS_AUTO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_darwinos.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_darwinos.h
new file mode 100644
index 0000000..8c2223c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_darwinos.h
@@ -0,0 +1,145 @@
+/* $Id: os_darwinos.h 2962 2009-10-24 00:00:40Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_OS_DARWINOS_H__
+#define __PJ_COMPAT_OS_DARWINOS_H__
+
+/**
+ * @file os_darwinos.h
+ * @brief Describes Darwin/MacOSX operating system specifics.
+ */
+
+#define PJ_OS_NAME "darwin"
+
+#define PJ_HAS_ARPA_INET_H 1
+#define PJ_HAS_ASSERT_H 1
+#define PJ_HAS_CTYPE_H 1
+#define PJ_HAS_ERRNO_H 1
+#define PJ_HAS_LINUX_SOCKET_H 0
+#define PJ_HAS_MALLOC_H 0
+#define PJ_HAS_NETDB_H 1
+#define PJ_HAS_NETINET_IN_H 1
+#define PJ_HAS_NETINET_TCP_H 1
+#define PJ_HAS_SETJMP_H 1
+#define PJ_HAS_STDARG_H 1
+#define PJ_HAS_STDDEF_H 1
+#define PJ_HAS_STDIO_H 1
+#define PJ_HAS_STDLIB_H 1
+#define PJ_HAS_STRING_H 1
+#define PJ_HAS_SYS_IOCTL_H 1
+#define PJ_HAS_SYS_SELECT_H 1
+#define PJ_HAS_SYS_SOCKET_H 1
+#define PJ_HAS_SYS_TIME_H 1
+#define PJ_HAS_SYS_TIMEB_H 1
+#define PJ_HAS_SYS_TYPES_H 1
+#define PJ_HAS_TIME_H 1
+#define PJ_HAS_UNISTD_H 1
+
+#define PJ_HAS_MSWSOCK_H 0
+#define PJ_HAS_WINSOCK_H 0
+#define PJ_HAS_WINSOCK2_H 0
+
+/* Is errno a good way to retrieve OS errors?
+ */
+#define PJ_HAS_ERRNO_VAR 1
+
+/* Has inet_aton() ?
+ */
+#define PJ_SOCK_HAS_INET_ATON 1
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#define PJ_HAS_SO_ERROR 1
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() can not return immediate daata.
+ */
+#define PJ_BLOCKING_ERROR_VAL EWOULDBLOCK
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS
+
+/* Default threading is enabled, unless it's overridden. */
+#ifndef PJ_HAS_THREADS
+# define PJ_HAS_THREADS (1)
+#endif
+
+#define PJ_HAS_HIGH_RES_TIMER 1
+#define PJ_HAS_MALLOC 1
+#ifndef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+#endif
+#define PJ_NATIVE_STRING_IS_UNICODE 0
+
+#define PJ_ATOMIC_VALUE_TYPE long
+
+/*
+ * Socket related
+ */
+typedef int socklen_t;
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#define PJ_SOCKADDR_HAS_LEN 1
+
+/*
+ * gcc complains that it can not use precompiled header because
+ * the value of FD_SETSIZE that we declare in pj/config.h is
+ * different than the value in /usr/include/sys/types.h.
+ *
+ * This changes the default value for Darwin.
+ */
+#define PJ_IOQUEUE_MAX_HANDLES 1024
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#define PJ_SELECT_NEEDS_NFDS 0
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#define PJ_EMULATE_RWMUTEX 0
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#define PJ_THREAD_SET_STACK_SIZE 0
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#define PJ_THREAD_ALLOCATE_STACK 0
+
+/* Oh well.. MacOS 10.2 doesn't have socklen_t, but 10.4 has! */
+#define PJ_HAS_SOCKLEN_T 0
+
+
+#endif /* __PJ_COMPAT_OS_DARWINOS_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux.h
new file mode 100644
index 0000000..d28a934
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux.h
@@ -0,0 +1,129 @@
+/* $Id: os_linux.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_OS_LINUX_H__
+#define __PJ_COMPAT_OS_LINUX_H__
+
+/**
+ * @file os_linux.h
+ * @brief Describes Linux operating system specifics.
+ */
+
+#define PJ_OS_NAME "linux"
+
+#define PJ_HAS_ARPA_INET_H 1
+#define PJ_HAS_ASSERT_H 1
+#define PJ_HAS_CTYPE_H 1
+#define PJ_HAS_ERRNO_H 1
+#define PJ_HAS_LINUX_SOCKET_H 0
+#define PJ_HAS_MALLOC_H 1
+#define PJ_HAS_NETDB_H 1
+#define PJ_HAS_NETINET_IN_H 1
+#define PJ_HAS_SETJMP_H 1
+#define PJ_HAS_STDARG_H 1
+#define PJ_HAS_STDDEF_H 1
+#define PJ_HAS_STDIO_H 1
+#define PJ_HAS_STDLIB_H 1
+#define PJ_HAS_STRING_H 1
+#define PJ_HAS_SYS_IOCTL_H 1
+#define PJ_HAS_SYS_SELECT_H 1
+#define PJ_HAS_SYS_SOCKET_H 1
+#define PJ_HAS_SYS_TIME_H 1
+#define PJ_HAS_SYS_TIMEB_H 1
+#define PJ_HAS_SYS_TYPES_H 1
+#define PJ_HAS_TIME_H 1
+#define PJ_HAS_UNISTD_H 1
+#define PJ_HAS_SEMAPHORE_H 1
+
+#define PJ_HAS_MSWSOCK_H 0
+#define PJ_HAS_WINSOCK_H 0
+#define PJ_HAS_WINSOCK2_H 0
+
+#define PJ_SOCK_HAS_INET_ATON 1
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#define PJ_SOCKADDR_HAS_LEN 0
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#define PJ_SELECT_NEEDS_NFDS 0
+
+/* Is errno a good way to retrieve OS errors?
+ */
+#define PJ_HAS_ERRNO_VAR 1
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#define PJ_HAS_SO_ERROR 1
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() can not return immediate daata.
+ */
+#define PJ_BLOCKING_ERROR_VAL EAGAIN
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS
+
+/* Default threading is enabled, unless it's overridden. */
+#ifndef PJ_HAS_THREADS
+# define PJ_HAS_THREADS (1)
+#endif
+
+#define PJ_HAS_HIGH_RES_TIMER 1
+#define PJ_HAS_MALLOC 1
+#ifndef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+#endif
+#define PJ_NATIVE_STRING_IS_UNICODE 0
+
+#define PJ_ATOMIC_VALUE_TYPE long
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#define PJ_EMULATE_RWMUTEX 0
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#define PJ_THREAD_SET_STACK_SIZE 0
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#define PJ_THREAD_ALLOCATE_STACK 0
+
+/* Linux has socklen_t */
+#define PJ_HAS_SOCKLEN_T 1
+
+
+#endif /* __PJ_COMPAT_OS_LINUX_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux_kernel.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux_kernel.h
new file mode 100644
index 0000000..ff43456
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux_kernel.h
@@ -0,0 +1,149 @@
+/* $Id: os_linux_kernel.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_OS_LINUX_KERNEL_H__
+#define __PJ_COMPAT_OS_LINUX_KERNEL_H__
+
+/**
+ * @file os_linux.h
+ * @brief Describes Linux operating system specifics.
+ */
+
+#define PJ_OS_NAME "linux-module"
+
+#define PJ_HAS_ARPA_INET_H 0
+#define PJ_HAS_ASSERT_H 0
+#define PJ_HAS_CTYPE_H 0
+#define PJ_HAS_ERRNO_H 0
+#define PJ_HAS_LINUX_SOCKET_H 1
+#define PJ_HAS_MALLOC_H 0
+#define PJ_HAS_NETDB_H 0
+#define PJ_HAS_NETINET_IN_H 0
+#define PJ_HAS_SETJMP_H 0
+#define PJ_HAS_STDARG_H 1
+#define PJ_HAS_STDDEF_H 0
+#define PJ_HAS_STDIO_H 0
+#define PJ_HAS_STDLIB_H 0
+#define PJ_HAS_STRING_H 0
+#define PJ_HAS_SYS_IOCTL_H 0
+#define PJ_HAS_SYS_SELECT_H 0
+#define PJ_HAS_SYS_SOCKET_H 0
+#define PJ_HAS_SYS_TIME_H 0
+#define PJ_HAS_SYS_TIMEB_H 0
+#define PJ_HAS_SYS_TYPES_H 0
+#define PJ_HAS_TIME_H 0
+#define PJ_HAS_UNISTD_H 0
+
+#define PJ_HAS_MSWSOCK_H 0
+#define PJ_HAS_WINSOCK_H 0
+#define PJ_HAS_WINSOCK2_H 0
+
+#define PJ_SOCK_HAS_INET_ATON 0
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#define PJ_SOCKADDR_HAS_LEN 0
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#define PJ_HAS_SO_ERROR 1
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#define PJ_SELECT_NEEDS_NFDS 0
+
+/* Is errno a good way to retrieve OS errors?
+ * (probably no for linux kernel)
+ * If you answer no here, you'll need to tell pjlib how to get OS
+ * error (a compile error will tell you exactly where)
+ */
+#define PJ_HAS_ERRNO_VAR 0
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() can not return immediate daata.
+ */
+#define PJ_BLOCKING_ERROR_VAL EAGAIN
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS
+
+#ifndef PJ_HAS_THREADS
+# define PJ_HAS_THREADS (1)
+#endif
+
+
+/*
+ * Declare __FD_SETSIZE now before including <linux*>.
+ */
+#define __FD_SETSIZE PJ_IOQUEUE_MAX_HANDLES
+
+#define NULL ((void*)0)
+
+#include <linux/module.h> /* Needed by all modules */
+#include <linux/kernel.h> /* Needed for KERN_INFO */
+
+#define __PJ_EXPORT_SYMBOL(a) EXPORT_SYMBOL(a);
+
+/*
+ * Override features.
+ */
+#define PJ_HAS_FLOATING_POINT 0
+#define PJ_HAS_MALLOC 0
+#define PJ_HAS_SEMAPHORE 0
+#define PJ_HAS_EVENT_OBJ 0
+#define PJ_HAS_HIGH_RES_TIMER 1
+#ifndef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+#endif
+#define PJ_TERM_HAS_COLOR 0
+#define PJ_NATIVE_STRING_IS_UNICODE 0
+
+#define PJ_ATOMIC_VALUE_TYPE int
+#define PJ_THREAD_DESC_SIZE 128
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#define PJ_EMULATE_RWMUTEX 0
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#define PJ_THREAD_SET_STACK_SIZE 0
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#define PJ_THREAD_ALLOCATE_STACK 0
+
+
+
+#endif /* __PJ_COMPAT_OS_LINUX_KERNEL_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_palmos.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_palmos.h
new file mode 100644
index 0000000..0d69ef1
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_palmos.h
@@ -0,0 +1,119 @@
+/* $Id: os_palmos.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_OS_PALMOS_H__
+#define __PJ_COMPAT_OS_PALMOS_H__
+
+/**
+ * @file os_palmos.h
+ * @brief Describes PalmOS operating system specifics.
+ */
+
+#define PJ_OS_NAME "palmos"
+
+#define PJ_HAS_ARPA_INET_H 0
+#define PJ_HAS_ASSERT_H 1
+#define PJ_HAS_CTYPE_H 1
+#define PJ_HAS_ERRNO_H 0
+#define PJ_HAS_MALLOC_H 1
+#define PJ_HAS_NETDB_H 0
+#define PJ_HAS_NETINET_IN_H 0
+#define PJ_HAS_SETJMP_H 1
+#define PJ_HAS_STDARG_H 1
+#define PJ_HAS_STDDEF_H 1
+#define PJ_HAS_STDIO_H 1
+#define PJ_HAS_STDLIB_H 1
+#define PJ_HAS_STRING_H 1
+#define PJ_HAS_SYS_IOCTL_H 0
+#define PJ_HAS_SYS_SELECT_H 0
+#define PJ_HAS_SYS_SOCKET_H 0
+#define PJ_HAS_SYS_TIMEB_H 0
+#define PJ_HAS_SYS_TYPES_H 1
+#define PJ_HAS_TIME_H 1
+#define PJ_HAS_UNISTD_H 0
+
+#define PJ_HAS_MSWSOCK_H 0
+#define PJ_HAS_WINSOCK_H 0
+#define PJ_HAS_WINSOCK2_H 0
+
+#define PJ_SOCK_HAS_INET_ATON 0
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#define PJ_SOCKADDR_HAS_LEN 0
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#define PJ_SELECT_NEEDS_NFDS 0
+
+/* Is errno a good way to retrieve OS errors?
+ */
+#define PJ_HAS_ERRNO_VAR 0
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#define PJ_HAS_SO_ERROR 0
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() can not return immediate daata.
+ */
+#define PJ_BLOCKING_ERROR_VAL xxx
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#define PJ_BLOCKING_CONNECT_ERROR_VAL xxx
+
+/* Default threading is enabled, unless it's overridden. */
+#ifndef PJ_HAS_THREADS
+# define PJ_HAS_THREADS (1)
+#endif
+
+#define PJ_HAS_HIGH_RES_TIMER 1
+#ifndef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+#define PJ_NATIVE_STRING_IS_UNICODE 0
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#define PJ_EMULATE_RWMUTEX 1
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#define PJ_THREAD_SET_STACK_SIZE 0
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#define PJ_THREAD_ALLOCATE_STACK 0
+
+
+#endif /* __PJ_COMPAT_OS_PALMOS_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_rtems.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_rtems.h
new file mode 100644
index 0000000..6c6c468
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_rtems.h
@@ -0,0 +1,139 @@
+/* $Id: os_rtems.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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
+ */
+
+/*
+ * Thanks Zetron, Inc and Phil Torre <ptorre@zetron.com> for donating PJLIB
+ * port to RTEMS.
+ */
+
+#ifndef __PJ_COMPAT_OS_RTEMS_H__
+#define __PJ_COMPAT_OS_RTEMS_H__
+
+/**
+ * @file os_linux.h
+ * @brief Describes Linux operating system specifics.
+ */
+
+#define PJ_OS_NAME "rtems"
+
+#define PJ_HAS_ARPA_INET_H 1
+#define PJ_HAS_ASSERT_H 1
+#define PJ_HAS_CTYPE_H 1
+#define PJ_HAS_ERRNO_H 1
+#define PJ_HAS_LINUX_SOCKET_H 0
+#define PJ_HAS_MALLOC_H 1
+#define PJ_HAS_NETDB_H 1
+#define PJ_HAS_NETINET_IN_H 1
+#define PJ_HAS_SETJMP_H 1
+#define PJ_HAS_STDARG_H 0
+#define PJ_HAS_STDDEF_H 1
+#define PJ_HAS_STDIO_H 1
+#define PJ_HAS_STDLIB_H 1
+#define PJ_HAS_STRING_H 1
+#define PJ_HAS_SYS_IOCTL_H 1
+#define PJ_HAS_SYS_SELECT_H 1
+#define PJ_HAS_SYS_SOCKET_H 1
+#define PJ_HAS_SYS_TIME_H 1
+#define PJ_HAS_SYS_TIMEB_H 1
+#define PJ_HAS_SYS_TYPES_H 1
+#define PJ_HAS_TIME_H 1
+#define PJ_HAS_UNISTD_H 1
+
+#define PJ_HAS_MSWSOCK_H 0
+#define PJ_HAS_WINSOCK_H 0
+#define PJ_HAS_WINSOCK2_H 0
+
+#define PJ_SOCK_HAS_INET_ATON 1
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#define PJ_SOCKADDR_HAS_LEN 1
+
+/* Is errno a good way to retrieve OS errors?
+ */
+#define PJ_HAS_ERRNO_VAR 1
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#define PJ_HAS_SO_ERROR 1
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#define PJ_SELECT_NEEDS_NFDS 1
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() can not return immediate daata.
+ */
+#define PJ_BLOCKING_ERROR_VAL EWOULDBLOCK
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS
+
+/* Default threading is enabled, unless it's overridden. */
+#ifndef PJ_HAS_THREADS
+# define PJ_HAS_THREADS (1)
+#endif
+
+#define PJ_HAS_HIGH_RES_TIMER 1
+#define PJ_HAS_MALLOC 1
+#ifndef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+#endif
+#define PJ_NATIVE_STRING_IS_UNICODE 0
+
+#define PJ_ATOMIC_VALUE_TYPE int
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#define PJ_EMULATE_RWMUTEX 1
+
+/* Missing socklen_t */
+typedef int socklen_t;
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#define PJ_THREAD_SET_STACK_SIZE 1
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#define PJ_THREAD_ALLOCATE_STACK 1
+
+/* RTEMS has socklen_t (does it? )*/
+#define PJ_HAS_SOCKLEN_T 1
+
+
+
+
+#endif /* __PJ_COMPAT_OS_RTEMS_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_sunos.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_sunos.h
new file mode 100644
index 0000000..550a1d0
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_sunos.h
@@ -0,0 +1,132 @@
+/* $Id: os_sunos.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_OS_SUNOS_H__
+#define __PJ_COMPAT_OS_SUNOS_H__
+
+/**
+ * @file os_sunos.h
+ * @brief Describes SunOS/Solaris operating system specifics.
+ */
+
+#define PJ_OS_NAME "sunos"
+
+#define PJ_HAS_ARPA_INET_H 1
+#define PJ_HAS_ASSERT_H 1
+#define PJ_HAS_CTYPE_H 1
+#define PJ_HAS_ERRNO_H 1
+#define PJ_HAS_LINUX_SOCKET_H 0
+#define PJ_HAS_MALLOC_H 1
+#define PJ_HAS_NETDB_H 1
+#define PJ_HAS_NETINET_IN_H 1
+#define PJ_HAS_SETJMP_H 1
+#define PJ_HAS_STDARG_H 1
+#define PJ_HAS_STDDEF_H 1
+#define PJ_HAS_STDIO_H 1
+#define PJ_HAS_STDLIB_H 1
+#define PJ_HAS_STRING_H 1
+#define PJ_HAS_SYS_IOCTL_H 1
+#define PJ_HAS_SYS_SELECT_H 1
+#define PJ_HAS_SYS_SOCKET_H 1
+#define PJ_HAS_SYS_TIME_H 0
+#define PJ_HAS_SYS_TIMEB_H 1
+#define PJ_HAS_SYS_TYPES_H 1
+#define PJ_HAS_TIME_H 1
+#define PJ_HAS_UNISTD_H 1
+
+#define PJ_HAS_MSWSOCK_H 0
+#define PJ_HAS_WINSOCK_H 0
+#define PJ_HAS_WINSOCK2_H 0
+
+#define PJ_SOCK_HAS_INET_ATON 0
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#define PJ_SOCKADDR_HAS_LEN 0
+
+/* Is errno a good way to retrieve OS errors?
+ */
+#define PJ_HAS_ERRNO_VAR 1
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#define PJ_HAS_SO_ERROR 0
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() can not return immediate daata.
+ */
+#define PJ_BLOCKING_ERROR_VAL EWOULDBLOCK
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#define PJ_SELECT_NEEDS_NFDS 0
+
+/* Default threading is enabled, unless it's overridden. */
+#ifndef PJ_HAS_THREADS
+# define PJ_HAS_THREADS (1)
+#endif
+
+#define PJ_HAS_HIGH_RES_TIMER 1
+#define PJ_HAS_MALLOC 1
+#ifndef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+#endif
+#define PJ_NATIVE_STRING_IS_UNICODE 0
+
+#define PJ_ATOMIC_VALUE_TYPE long
+
+/* Get BSD related identifers in Sun's include files */
+#define BSD_COMP
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#define PJ_EMULATE_RWMUTEX 0
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#define PJ_THREAD_SET_STACK_SIZE 0
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#define PJ_THREAD_ALLOCATE_STACK 0
+
+/* SunOS has socklen_t (does it? )*/
+#define PJ_HAS_SOCKLEN_T 1
+
+
+
+#endif /* __PJ_COMPAT_OS_SUNOS_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_symbian.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_symbian.h
new file mode 100644
index 0000000..8ab45de
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_symbian.h
@@ -0,0 +1,162 @@
+/* $Id: os_symbian.h 2962 2009-10-24 00:00:40Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_OS_SYMBIAN_H__
+#define __PJ_COMPAT_OS_SYMBIAN_H__
+
+/**
+ * @file os_symbian.h
+ * @brief Describes Symbian operating system specifics.
+ */
+
+#define PJ_OS_NAME "symbian"
+
+#define PJ_HAS_ARPA_INET_H 1
+#define PJ_HAS_ASSERT_H 1
+#define PJ_HAS_CTYPE_H 1
+#define PJ_HAS_ERRNO_H 1
+#define PJ_HAS_LINUX_SOCKET_H 0
+#define PJ_HAS_MALLOC_H 0
+#define PJ_HAS_NETDB_H 1
+#define PJ_HAS_NETINET_IN_H 1
+#define PJ_HAS_NETINET_TCP_H 0
+#define PJ_HAS_SETJMP_H 1
+#define PJ_HAS_STDARG_H 1
+#define PJ_HAS_STDDEF_H 1
+#define PJ_HAS_STDIO_H 1
+#define PJ_HAS_STDLIB_H 1
+#define PJ_HAS_STRING_H 1
+#define PJ_HAS_NO_SNPRINTF 1
+#define PJ_HAS_SYS_IOCTL_H 1
+#define PJ_HAS_SYS_SELECT_H 0
+#define PJ_HAS_SYS_SOCKET_H 1
+#define PJ_HAS_SYS_TIME_H 1
+#define PJ_HAS_SYS_TIMEB_H 0
+#define PJ_HAS_SYS_TYPES_H 1
+#define PJ_HAS_TIME_H 1
+#define PJ_HAS_UNISTD_H 1
+
+#define PJ_HAS_MSWSOCK_H 0
+#define PJ_HAS_WINSOCK_H 0
+#define PJ_HAS_WINSOCK2_H 0
+
+#define PJ_SOCK_HAS_INET_ATON 0
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#define PJ_SOCKADDR_HAS_LEN 0
+/* Is errno a good way to retrieve OS errors?
+ */
+#define PJ_HAS_ERRNO_VAR 1
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#define PJ_HAS_SO_ERROR 1
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#define PJ_SELECT_NEEDS_NFDS 0
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() can not return immediate daata.
+ */
+#define PJ_BLOCKING_ERROR_VAL EAGAIN
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS
+
+/*
+ * We don't want to use threads in Symbian
+ */
+#define PJ_HAS_THREADS 0
+
+
+/*
+ * Declare __FD_SETSIZE now before including <linux*>.
+#define __FD_SETSIZE PJ_IOQUEUE_MAX_HANDLES
+ */
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+
+/* Doesn't seem to allow more than this */
+#define PJ_IOQUEUE_MAX_HANDLES 8
+
+/*
+ * Override features.
+ */
+#define PJ_HAS_FLOATING_POINT 0
+#define PJ_HAS_MALLOC 0
+#define PJ_HAS_SEMAPHORE 1
+#define PJ_HAS_EVENT_OBJ 0
+#define PJ_HAS_HIGH_RES_TIMER 1
+#define PJ_OS_HAS_CHECK_STACK 0
+#define PJ_TERM_HAS_COLOR 0
+#define PJ_NATIVE_STRING_IS_UNICODE 0
+#define PJ_NATIVE_ERR_POSITIVE 0
+
+#define PJ_ATOMIC_VALUE_TYPE int
+#define PJ_THREAD_DESC_SIZE 128
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#define PJ_EMULATE_RWMUTEX 1
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#define PJ_THREAD_SET_STACK_SIZE 0
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#define PJ_THREAD_ALLOCATE_STACK 0
+
+/* Missing socklen_t */
+#define PJ_HAS_SOCKLEN_T 1
+typedef unsigned int socklen_t;
+
+#ifndef __GCCE__
+#include <e32def.h>
+#endif
+
+#define PJ_EXPORT_DECL_SPECIFIER IMPORT_C
+//#define PJ_EXPORT_DECL_SPECIFIER
+#define PJ_EXPORT_DEF_SPECIFIER EXPORT_C
+#define PJ_IMPORT_DECL_SPECIFIER IMPORT_C
+
+
+#endif /* __PJ_COMPAT_OS_SYMBIAN_H__ */
+
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32.h
new file mode 100644
index 0000000..f28cf23
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32.h
@@ -0,0 +1,139 @@
+/* $Id: os_win32.h 3002 2009-11-10 04:30:46Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_OS_WIN32_H__
+#define __PJ_COMPAT_OS_WIN32_H__
+
+/**
+ * @file os_win32.h
+ * @brief Describes Win32 operating system family specifics.
+ */
+
+#define PJ_OS_NAME "win32"
+
+#define WIN32_LEAN_AND_MEAN
+#define PJ_WIN32_WINNT 0x0400
+#ifndef _WIN32_WINNT
+# define _WIN32_WINNT PJ_WIN32_WINNT
+#endif
+
+#define PJ_HAS_ARPA_INET_H 0
+#define PJ_HAS_ASSERT_H 1
+#define PJ_HAS_CTYPE_H 1
+#define PJ_HAS_ERRNO_H 0 /* Must be zero, otherwise errno_test() fails. */
+#define PJ_HAS_LINUX_SOCKET_H 0
+#define PJ_HAS_MALLOC_H 1
+#define PJ_HAS_NETDB_H 0
+#define PJ_HAS_NETINET_IN_H 0
+#define PJ_HAS_NETINET_TCP_H 0
+#define PJ_HAS_SETJMP_H 1
+#define PJ_HAS_STDARG_H 1
+#define PJ_HAS_STDDEF_H 1
+#undef PJ_HAS_STDINT_H
+#define PJ_HAS_STDIO_H 1
+#define PJ_HAS_STDLIB_H 1
+#define PJ_HAS_STRING_H 1
+#define PJ_HAS_SYS_IOCTL_H 0
+#define PJ_HAS_SYS_SELECT_H 0
+#define PJ_HAS_SYS_SOCKET_H 0
+#define PJ_HAS_SYS_TIME_H 0
+#define PJ_HAS_SYS_TIMEB_H 1
+#define PJ_HAS_SYS_TYPES_H 1
+#define PJ_HAS_TIME_H 1
+#define PJ_HAS_UNISTD_H 0
+
+#define PJ_HAS_MSWSOCK_H 1
+#define PJ_HAS_WINSOCK_H 0
+#define PJ_HAS_WINSOCK2_H 1
+#define PJ_HAS_WS2TCPIP_H 1
+
+#define PJ_SOCK_HAS_INET_ATON 0
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#define PJ_SOCKADDR_HAS_LEN 0
+
+/* Is errno a good way to retrieve OS errors? (No)
+ */
+#define PJ_HAS_ERRNO_VAR 0
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#define PJ_HAS_SO_ERROR 1
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() or send() can not return immediately.
+ */
+#define PJ_BLOCKING_ERROR_VAL WSAEWOULDBLOCK
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#define PJ_BLOCKING_CONNECT_ERROR_VAL WSAEWOULDBLOCK
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#define PJ_SELECT_NEEDS_NFDS 0
+
+/* Default threading is enabled, unless it's overridden. */
+#ifndef PJ_HAS_THREADS
+# define PJ_HAS_THREADS (1)
+#endif
+
+#define PJ_HAS_HIGH_RES_TIMER 1
+#define PJ_HAS_MALLOC 1
+#ifndef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 1
+#endif
+
+#ifdef UNICODE
+# define PJ_NATIVE_STRING_IS_UNICODE 1
+#else
+# define PJ_NATIVE_STRING_IS_UNICODE 0
+#endif
+
+#define PJ_ATOMIC_VALUE_TYPE long
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#define PJ_EMULATE_RWMUTEX 1
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#define PJ_THREAD_SET_STACK_SIZE 0
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#define PJ_THREAD_ALLOCATE_STACK 0
+
+
+#endif /* __PJ_COMPAT_OS_WIN32_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32_wince.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32_wince.h
new file mode 100644
index 0000000..aeedffb
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32_wince.h
@@ -0,0 +1,140 @@
+/* $Id: os_win32_wince.h 2962 2009-10-24 00:00:40Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_OS_WIN32_WINCE_H__
+#define __PJ_COMPAT_OS_WIN32_WINCE_H__
+
+/**
+ * @file os_win32.h
+ * @brief Describes Win32 operating system family specifics.
+ */
+
+#define PJ_OS_NAME "win32-wince"
+
+#define WIN32_LEAN_AND_MEAN
+#define RPC_NO_WINDOWS_H
+//#define PJ_WIN32_WINNT 0x0400
+//#define _WIN32_WINNT PJ_WIN32_WINNT
+
+#define PJ_HAS_ARPA_INET_H 0
+#define PJ_HAS_ASSERT_H 1
+#define PJ_HAS_CTYPE_H 1
+#define PJ_HAS_ERRNO_H 0 /* Must be zero, otherwise errno_test() fails. */
+#define PJ_HAS_LINUX_SOCKET_H 0
+#define PJ_HAS_MALLOC_H 1
+#define PJ_HAS_NETDB_H 0
+#define PJ_HAS_NETINET_IN_H 0
+#define PJ_HAS_NETINET_TCP_H 0
+#define PJ_HAS_SETJMP_H 1
+#define PJ_HAS_STDARG_H 1
+#define PJ_HAS_STDDEF_H 1
+#define PJ_HAS_STDIO_H 1
+#define PJ_HAS_STDLIB_H 1
+#define PJ_HAS_STRING_H 1
+#define PJ_HAS_SYS_IOCTL_H 0
+#define PJ_HAS_SYS_SELECT_H 0
+#define PJ_HAS_SYS_SOCKET_H 0
+#define PJ_HAS_SYS_TIME_H 0
+#define PJ_HAS_SYS_TIMEB_H 0 /* Doesn't have sys/timeb.h */
+#define PJ_HAS_SYS_TYPES_H 0 /* Doesn't have sys/types.h */
+#define PJ_HAS_TIME_H 1
+#define PJ_HAS_UNISTD_H 0
+
+#define PJ_HAS_MSWSOCK_H 1
+#define PJ_HAS_WINSOCK_H 0
+#define PJ_HAS_WINSOCK2_H 1
+
+#define PJ_SOCK_HAS_INET_ATON 0
+
+/* Set 1 if native sockaddr_in has sin_len member.
+ * Default: 0
+ */
+#define PJ_SOCKADDR_HAS_LEN 0
+
+/* Is errno a good way to retrieve OS errors? (no)
+ */
+#define PJ_HAS_ERRNO_VAR 0
+
+/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
+ * the status of non-blocking connect() operation.
+ */
+#define PJ_HAS_SO_ERROR 0
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket recv() or send() can not return immediately.
+ */
+#define PJ_BLOCKING_ERROR_VAL WSAEWOULDBLOCK
+
+/* This value specifies the value set in errno by the OS when a non-blocking
+ * socket connect() can not get connected immediately.
+ */
+#define PJ_BLOCKING_CONNECT_ERROR_VAL WSAEWOULDBLOCK
+
+/**
+ * If this macro is set, it tells select I/O Queue that select() needs to
+ * be given correct value of nfds (i.e. largest fd + 1). This requires
+ * select ioqueue to re-scan the descriptors on each registration and
+ * unregistration.
+ * If this macro is not set, then ioqueue will always give FD_SETSIZE for
+ * nfds argument when calling select().
+ *
+ * Default: 0
+ */
+#define PJ_SELECT_NEEDS_NFDS 0
+
+/* Default threading is enabled, unless it's overridden. */
+#ifndef PJ_HAS_THREADS
+# define PJ_HAS_THREADS (1)
+#endif
+
+#define PJ_HAS_HIGH_RES_TIMER 1
+#define PJ_HAS_MALLOC 1
+#define PJ_OS_HAS_CHECK_STACK 1
+
+#define PJ_ATOMIC_VALUE_TYPE long
+
+/* TlsAlloc() error value. */
+#define TLS_OUT_OF_INDEXES 0xFFFFFFFF
+
+/* No console. */
+#define PJ_TERM_HAS_COLOR 0
+
+/* No rdtsc */
+#define PJ_TIMESTAMP_USE_RDTSC 0
+
+/* Native string is Unicode. */
+#define PJ_NATIVE_STRING_IS_UNICODE 1
+
+/* If 1, use Read/Write mutex emulation for platforms that don't support it */
+#define PJ_EMULATE_RWMUTEX 1
+
+/* If 1, pj_thread_create() should enforce the stack size when creating
+ * threads.
+ * Default: 0 (let OS decide the thread's stack size).
+ */
+#define PJ_THREAD_SET_STACK_SIZE 0
+
+/* If 1, pj_thread_create() should allocate stack from the pool supplied.
+ * Default: 0 (let OS allocate memory for thread's stack).
+ */
+#define PJ_THREAD_ALLOCATE_STACK 0
+
+
+#endif /* __PJ_COMPAT_OS_WIN32_WINCE_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/rand.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/rand.h
new file mode 100644
index 0000000..11f8b9b
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/rand.h
@@ -0,0 +1,70 @@
+/* $Id: rand.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_RAND_H__
+#define __PJ_COMPAT_RAND_H__
+
+/**
+ * @file rand.h
+ * @brief Provides platform_rand() and platform_srand() functions.
+ */
+
+#if defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H != 0
+ /*
+ * Use stdlib based rand() and srand().
+ */
+# include <stdlib.h>
+# define platform_srand srand
+# if defined(RAND_MAX) && RAND_MAX <= 0xFFFF
+ /*
+ * When rand() is only 16 bit strong, double the strength
+ * by calling it twice!
+ */
+ PJ_INLINE(int) platform_rand(void)
+ {
+ return ((rand() & 0xFFFF) << 16) | (rand() & 0xFFFF);
+ }
+# else
+# define platform_rand rand
+# endif
+
+#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0
+ /*
+ * Linux kernel mode random number generator.
+ */
+# include <linux/random.h>
+# define platform_srand(seed)
+
+ PJ_INLINE(int) platform_rand(void)
+ {
+ int value;
+ get_random_bytes((void*)&value, sizeof(value));
+ return value;
+ }
+
+#else
+# warning "platform_rand() is not implemented"
+# define platform_rand() 1
+# define platform_srand(seed)
+
+#endif
+
+
+#endif /* __PJ_COMPAT_RAND_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/setjmp.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/setjmp.h
new file mode 100644
index 0000000..cbf5453
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/setjmp.h
@@ -0,0 +1,98 @@
+/* $Id: setjmp.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_SETJMP_H__
+#define __PJ_COMPAT_SETJMP_H__
+
+/**
+ * @file setjmp.h
+ * @brief Provides setjmp.h functionality.
+ */
+
+#if defined(PJ_HAS_SETJMP_H) && PJ_HAS_SETJMP_H != 0
+# include <setjmp.h>
+ typedef jmp_buf pj_jmp_buf;
+# ifndef pj_setjmp
+# define pj_setjmp(buf) setjmp(buf)
+# endif
+# ifndef pj_longjmp
+# define pj_longjmp(buf,d) longjmp(buf,d)
+# endif
+
+#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0 && \
+ defined(PJ_M_I386) && PJ_M_I386 != 0
+
+ /*
+ * These are taken from uClibc.
+ * Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org>
+ */
+# if defined __USE_MISC || defined _ASM
+# define JB_BX 0
+# define JB_SI 1
+# define JB_DI 2
+# define JB_BP 3
+# define JB_SP 4
+# define JB_PC 5
+# define JB_SIZE 24
+# endif
+
+# ifndef _ASM
+ typedef int __jmp_buf[6];
+
+ /* A `sigset_t' has a bit for each signal. */
+# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
+ typedef struct __sigset_t_tag
+ {
+ unsigned long int __val[_SIGSET_NWORDS];
+ } __sigset_t;
+
+ /* Calling environment, plus possibly a saved signal mask. */
+ typedef struct __jmp_buf_tag /* C++ doesn't like tagless structs. */
+ {
+ /* NOTE: The machine-dependent definitions of `__sigsetjmp'
+ assume that a `jmp_buf' begins with a `__jmp_buf' and that
+ `__mask_was_saved' follows it. Do not move these members
+ or add others before it. */
+ __jmp_buf __jmpbuf; /* Calling environment. */
+ int __mask_was_saved; /* Saved the signal mask? */
+ // we never saved the mask.
+ __sigset_t __saved_mask; /* Saved signal mask. */
+ } jmp_buf[1];
+
+ typedef jmp_buf sigjmp_buf;
+ typedef jmp_buf pj_jmp_buf;
+
+ PJ_DECL(int) pj_setjmp(pj_jmp_buf env);
+ PJ_DECL(void) pj_longjmp(pj_jmp_buf env, int val) __attribute__((noreturn));
+
+# endif /* _ASM */
+
+#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
+ /* Symbian framework don't use setjmp/longjmp */
+
+#else
+# warning "setjmp()/longjmp() is not implemented"
+ typedef int pj_jmp_buf[1];
+# define pj_setjmp(buf) 0
+# define pj_longjmp(buf,d) 0
+#endif
+
+
+#endif /* __PJ_COMPAT_SETJMP_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/size_t.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/size_t.h
new file mode 100644
index 0000000..9de2cc7
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/size_t.h
@@ -0,0 +1,32 @@
+/* $Id: size_t.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_SIZE_T_H__
+#define __PJ_COMPAT_SIZE_T_H__
+
+/**
+ * @file size_t.h
+ * @brief Provides size_t type.
+ */
+#if PJ_HAS_STDDEF_H
+# include <stddef.h>
+#endif
+
+#endif /* __PJ_COMPAT_SIZE_T_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/socket.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/socket.h
new file mode 100644
index 0000000..6c97257
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/socket.h
@@ -0,0 +1,231 @@
+/* $Id: socket.h 2962 2009-10-24 00:00:40Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_SOCKET_H__
+#define __PJ_COMPAT_SOCKET_H__
+
+/**
+ * @file socket.h
+ * @brief Provides all socket related functions,data types, error codes, etc.
+ */
+
+#if defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H != 0
+# include <winsock2.h>
+#endif
+
+#if defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H != 0
+# include <winsock.h>
+#endif
+
+#if defined(PJ_HAS_WS2TCPIP_H) && PJ_HAS_WS2TCPIP_H != 0
+# include <ws2tcpip.h>
+#endif
+
+
+/*
+ * IPv6 for Visual Studio's
+ *
+ * = Visual Studio 6 =
+ *
+ * Visual Studio 6 does not ship with IPv6 support, so you MUST
+ * download and install IPv6 Tehnology Preview (IPv6Kit) from:
+ * http://msdn.microsoft.com/downloads/sdks/platform/tpipv6/ReadMe.asp
+ * Then put IPv6Kit\inc in your Visual Studio include path.
+ *
+ * In addition, by default IPv6Kit does not want to install on
+ * Windows 2000 SP4. Please see:
+ * http://msdn.microsoft.com/downloads/sdks/platform/tpipv6/faq.asp
+ * on how to install IPv6Kit on Win2K SP4.
+ *
+ *
+ * = Visual Studio 2003, 2005 (including Express) =
+ *
+ * These VS uses Microsoft Platform SDK for Windows Server 2003 SP1, and
+ * it has built-in IPv6 support.
+ */
+#if defined(_MSC_VER) && defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0
+# ifndef s_addr
+# define s_addr S_un.S_addr
+# endif
+
+# if !defined(IPPROTO_IPV6)
+ /* Need to download and install IPv6Kit for this platform.
+ * Please see the comments above about Visual Studio 6.
+ */
+# include <tpipv6.h>
+# endif
+
+# define PJ_SOCK_HAS_GETADDRINFO 1
+#endif /* _MSC_VER */
+
+#if defined(PJ_HAS_SYS_TYPES_H) && PJ_HAS_SYS_TYPES_H != 0
+# include <sys/types.h>
+#endif
+
+#if defined(PJ_HAS_SYS_SOCKET_H) && PJ_HAS_SYS_SOCKET_H != 0
+# include <sys/socket.h>
+#endif
+
+#if defined(PJ_HAS_LINUX_SOCKET_H) && PJ_HAS_LINUX_SOCKET_H != 0
+# include <linux/socket.h>
+#endif
+
+#if defined(PJ_HAS_SYS_SELECT_H) && PJ_HAS_SYS_SELECT_H != 0
+# include <sys/select.h>
+#endif
+
+#if defined(PJ_HAS_NETINET_IN_H) && PJ_HAS_NETINET_IN_H != 0
+# include <netinet/in.h>
+#endif
+
+#if defined(PJ_HAS_NETINET_IN_SYSTM_H) && PJ_HAS_NETINET_IN_SYSTM_H != 0
+/* Required to include netinet/ip.h in FreeBSD 7.0 */
+# include <netinet/in_systm.h>
+#endif
+
+#if defined(PJ_HAS_NETINET_IP_H) && PJ_HAS_NETINET_IP_H != 0
+/* To pull in IPTOS_* constants */
+# include <netinet/ip.h>
+#endif
+
+#if defined(PJ_HAS_NETINET_TCP_H) && PJ_HAS_NETINET_TCP_H != 0
+/* To pull in TCP_NODELAY constants */
+# include <netinet/tcp.h>
+#endif
+
+#if defined(PJ_HAS_NET_IF_H) && PJ_HAS_NET_IF_H != 0
+/* For interface enumeration in ip_helper */
+# include <net/if.h>
+#endif
+
+#if defined(PJ_HAS_IFADDRS_H) && PJ_HAS_IFADDRS_H != 0
+/* Interface enum with getifaddrs() which works with IPv6 */
+# include <ifaddrs.h>
+#endif
+
+#if defined(PJ_HAS_ARPA_INET_H) && PJ_HAS_ARPA_INET_H != 0
+# include <arpa/inet.h>
+#endif
+
+#if defined(PJ_HAS_SYS_IOCTL_H) && PJ_HAS_SYS_IOCTL_H != 0
+# include <sys/ioctl.h> /* FBIONBIO */
+#endif
+
+#if defined(PJ_HAS_ERRNO_H) && PJ_HAS_ERRNO_H != 0
+# include <errno.h>
+#endif
+
+#if defined(PJ_HAS_NETDB_H) && PJ_HAS_NETDB_H != 0
+# include <netdb.h>
+#endif
+
+#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0
+# include <unistd.h>
+#endif
+
+
+/*
+ * Define common errors.
+ */
+#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \
+ (defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0)
+# define OSERR_EWOULDBLOCK WSAEWOULDBLOCK
+# define OSERR_EINPROGRESS WSAEINPROGRESS
+# define OSERR_ECONNRESET WSAECONNRESET
+# define OSERR_ENOTCONN WSAENOTCONN
+#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
+# define OSERR_EWOULDBLOCK -1
+# define OSERR_EINPROGRESS -1
+# define OSERR_ECONNRESET -1
+# define OSERR_ENOTCONN -1
+#else
+# define OSERR_EWOULDBLOCK EWOULDBLOCK
+# define OSERR_EINPROGRESS EINPROGRESS
+# define OSERR_ECONNRESET ECONNRESET
+# define OSERR_ENOTCONN ENOTCONN
+#endif
+
+
+/*
+ * And undefine these..
+ */
+#undef s_addr
+#undef s6_addr
+
+/*
+ * Linux kernel specifics
+ */
+#if defined(PJ_LINUX_KERNEL)
+# include <linux/net.h>
+# include <asm/ioctls.h> /* FIONBIO */
+# include <linux/syscalls.h> /* sys_select() */
+# include <asm/uaccess.h> /* set/get_fs() */
+
+ typedef int socklen_t;
+# define getsockopt sys_getsockopt
+
+ /*
+ * Wrapper for select() in Linux kernel.
+ */
+ PJ_INLINE(int) select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
+ struct timeval *tvp)
+ {
+ int count;
+ mm_segment_t oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ count = sys_select(n, inp, outp, exp, tvp);
+ set_fs(oldfs);
+ return count;
+ }
+#endif /* PJ_LINUX_KERNEL */
+
+
+/*
+ * This will finally be obsoleted, since it should be declared in
+ * os_auto.h
+ */
+#if !defined(PJ_HAS_SOCKLEN_T) || PJ_HAS_SOCKLEN_T==0
+ typedef int socklen_t;
+#endif
+
+/* Regarding sin_len member of sockaddr_in:
+ * BSD systems (including MacOS X requires that the sin_len member of
+ * sockaddr_in be set to sizeof(sockaddr_in), while other systems (Windows
+ * and Linux included) do not.
+ *
+ * To maintain compatibility between systems, PJLIB will automatically
+ * set this field before invoking native OS socket API, and it will
+ * always reset the field to zero before returning pj_sockaddr_in to
+ * application (such as in pj_getsockname() and pj_recvfrom()).
+ *
+ * Application MUST always set this field to zero.
+ *
+ * This way we can avoid hard to find problem such as when the socket
+ * address is used as hash table key.
+ */
+#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
+# define PJ_SOCKADDR_SET_LEN(addr,len) (((pj_addr_hdr*)(addr))->sa_zero_len=(len))
+# define PJ_SOCKADDR_RESET_LEN(addr) (((pj_addr_hdr*)(addr))->sa_zero_len=0)
+#else
+# define PJ_SOCKADDR_SET_LEN(addr,len)
+# define PJ_SOCKADDR_RESET_LEN(addr)
+#endif
+
+#endif /* __PJ_COMPAT_SOCKET_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdarg.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdarg.h
new file mode 100644
index 0000000..facf1c0
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdarg.h
@@ -0,0 +1,32 @@
+/* $Id: stdarg.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_STDARG_H__
+#define __PJ_COMPAT_STDARG_H__
+
+/**
+ * @file stdarg.h
+ * @brief Provides stdarg functionality.
+ */
+
+#if defined(PJ_HAS_STDARG_H) && PJ_HAS_STDARG_H != 0
+# include <stdarg.h>
+#endif
+
+#endif /* __PJ_COMPAT_STDARG_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdfileio.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdfileio.h
new file mode 100644
index 0000000..c9fe9bc
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdfileio.h
@@ -0,0 +1,32 @@
+/* $Id: stdfileio.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_STDFILEIO_H__
+#define __PJ_COMPAT_STDFILEIO_H__
+
+/**
+ * @file stdfileio.h
+ * @brief Compatibility for ANSI file I/O like fputs, fflush, etc.
+ */
+
+#if defined(PJ_HAS_STDIO_H) && PJ_HAS_STDIO_H != 0
+# include <stdio.h>
+#endif
+
+#endif /* __PJ_COMPAT_STDFILEIO_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/string.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/string.h
new file mode 100644
index 0000000..7fcc623
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/string.h
@@ -0,0 +1,144 @@
+/* $Id: string.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_STRING_H__
+#define __PJ_COMPAT_STRING_H__
+
+/**
+ * @file string.h
+ * @brief Provides string manipulation functions found in ANSI string.h.
+ */
+
+
+#if defined(PJ_HAS_STRING_H) && PJ_HAS_STRING_H != 0
+# include <string.h>
+#else
+
+ PJ_DECL(int) strcasecmp(const char *s1, const char *s2);
+ PJ_DECL(int) strncasecmp(const char *s1, const char *s2, int len);
+
+#endif
+
+/* For sprintf family */
+#include <stdio.h>
+
+/* On WinCE, string stuffs are declared in stdlib.h */
+#if defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H!=0
+# include <stdlib.h>
+#endif
+
+#if defined(_MSC_VER)
+# define strcasecmp _stricmp
+# define strncasecmp _strnicmp
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
+# define snwprintf _snwprintf
+# define wcsicmp _wcsicmp
+# define wcsnicmp _wcsnicmp
+#else
+# define stricmp strcasecmp
+# define strnicmp strncasecmp
+
+# if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0
+# error "Implement Unicode string functions"
+# endif
+#endif
+
+#define pj_ansi_strcmp strcmp
+#define pj_ansi_strncmp strncmp
+#define pj_ansi_strlen strlen
+#define pj_ansi_strcpy strcpy
+#define pj_ansi_strncpy strncpy
+#define pj_ansi_strcat strcat
+#define pj_ansi_strstr strstr
+#define pj_ansi_strchr strchr
+#define pj_ansi_strcasecmp strcasecmp
+#define pj_ansi_stricmp strcasecmp
+#define pj_ansi_strncasecmp strncasecmp
+#define pj_ansi_strnicmp strncasecmp
+#define pj_ansi_sprintf sprintf
+
+#if defined(PJ_HAS_NO_SNPRINTF) && PJ_HAS_NO_SNPRINTF != 0
+# include <pj/types.h>
+# include <pj/compat/stdarg.h>
+ PJ_BEGIN_DECL
+ PJ_DECL(int) snprintf(char*s1, pj_size_t len, const char*s2, ...);
+ PJ_DECL(int) vsnprintf(char*s1, pj_size_t len, const char*s2, va_list arg);
+ PJ_END_DECL
+#endif
+
+#define pj_ansi_snprintf snprintf
+#define pj_ansi_vsprintf vsprintf
+#define pj_ansi_vsnprintf vsnprintf
+
+#define pj_unicode_strcmp wcscmp
+#define pj_unicode_strncmp wcsncmp
+#define pj_unicode_strlen wcslen
+#define pj_unicode_strcpy wcscpy
+#define pj_unicode_strncpy wcsncpy
+#define pj_unicode_strcat wcscat
+#define pj_unicode_strstr wcsstr
+#define pj_unicode_strchr wcschr
+#define pj_unicode_strcasecmp wcsicmp
+#define pj_unicode_stricmp wcsicmp
+#define pj_unicode_strncasecmp wcsnicmp
+#define pj_unicode_strnicmp wcsnicmp
+#define pj_unicode_sprintf swprintf
+#define pj_unicode_snprintf snwprintf
+#define pj_unicode_vsprintf vswprintf
+#define pj_unicode_vsnprintf vsnwprintf
+
+#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0
+# define pj_native_strcmp pj_unicode_strcmp
+# define pj_native_strncmp pj_unicode_strncmp
+# define pj_native_strlen pj_unicode_strlen
+# define pj_native_strcpy pj_unicode_strcpy
+# define pj_native_strncpy pj_unicode_strncpy
+# define pj_native_strcat pj_unicode_strcat
+# define pj_native_strstr pj_unicode_strstr
+# define pj_native_strchr pj_unicode_strchr
+# define pj_native_strcasecmp pj_unicode_strcasecmp
+# define pj_native_stricmp pj_unicode_stricmp
+# define pj_native_strncasecmp pj_unicode_strncasecmp
+# define pj_native_strnicmp pj_unicode_strnicmp
+# define pj_native_sprintf pj_unicode_sprintf
+# define pj_native_snprintf pj_unicode_snprintf
+# define pj_native_vsprintf pj_unicode_vsprintf
+# define pj_native_vsnprintf pj_unicode_vsnprintf
+#else
+# define pj_native_strcmp pj_ansi_strcmp
+# define pj_native_strncmp pj_ansi_strncmp
+# define pj_native_strlen pj_ansi_strlen
+# define pj_native_strcpy pj_ansi_strcpy
+# define pj_native_strncpy pj_ansi_strncpy
+# define pj_native_strcat pj_ansi_strcat
+# define pj_native_strstr pj_ansi_strstr
+# define pj_native_strchr pj_ansi_strchr
+# define pj_native_strcasecmp pj_ansi_strcasecmp
+# define pj_native_stricmp pj_ansi_stricmp
+# define pj_native_strncasecmp pj_ansi_strncasecmp
+# define pj_native_strnicmp pj_ansi_strnicmp
+# define pj_native_sprintf pj_ansi_sprintf
+# define pj_native_snprintf pj_ansi_snprintf
+# define pj_native_vsprintf pj_ansi_vsprintf
+# define pj_native_vsnprintf pj_ansi_vsnprintf
+#endif
+
+
+#endif /* __PJ_COMPAT_STRING_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/time.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/time.h
new file mode 100644
index 0000000..c577d98
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/time.h
@@ -0,0 +1,42 @@
+/* $Id: time.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_COMPAT_TIME_H__
+#define __PJ_COMPAT_TIME_H__
+
+/**
+ * @file time.h
+ * @brief Provides ftime() and localtime() etc functions.
+ */
+
+#if defined(PJ_HAS_TIME_H) && PJ_HAS_TIME_H != 0
+# include <time.h>
+#endif
+
+#if defined(PJ_HAS_SYS_TIME_H) && PJ_HAS_SYS_TIME_H != 0
+# include <sys/time.h>
+#endif
+
+#if defined(PJ_HAS_SYS_TIMEB_H) && PJ_HAS_SYS_TIMEB_H != 0
+# include <sys/timeb.h>
+#endif
+
+
+#endif /* __PJ_COMPAT_TIME_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/config.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/config.h
new file mode 100644
index 0000000..1dc0878
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/config.h
@@ -0,0 +1,1122 @@
+/* $Id: config.h 2970 2009-10-26 15:47:52Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_CONFIG_H__
+#define __PJ_CONFIG_H__
+
+/**
+ * @file config.h
+ * @brief PJLIB Main configuration settings.
+ */
+
+/********************************************************************
+ * Include compiler specific configuration.
+ */
+#if defined(_MSC_VER)
+# include <pj/compat/cc_msvc.h>
+#elif defined(__GNUC__)
+# include <pj/compat/cc_gcc.h>
+#elif defined(__CW32__)
+# include <pj/compat/cc_mwcc.h>
+#elif defined(__MWERKS__)
+# include <pj/compat/cc_codew.h>
+#elif defined(__GCCE__)
+# include <pj/compat/cc_gcce.h>
+#elif defined(__ARMCC__)
+# include <pj/compat/cc_armcc.h>
+#else
+# error "Unknown compiler."
+#endif
+
+
+/********************************************************************
+ * Include target OS specific configuration.
+ */
+#if defined(PJ_AUTOCONF)
+ /*
+ * Autoconf
+ */
+# include <pj/compat/os_auto.h>
+
+#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
+ /*
+ * SymbianOS
+ */
+# include <pj/compat/os_symbian.h>
+
+#elif defined(PJ_WIN32_WINCE) || defined(_WIN32_WCE) || defined(UNDER_CE)
+ /*
+ * Windows CE
+ */
+# undef PJ_WIN32_WINCE
+# define PJ_WIN32_WINCE 1
+# include <pj/compat/os_win32_wince.h>
+
+ /* Also define Win32 */
+# define PJ_WIN32 1
+
+#elif defined(PJ_WIN32) || defined(_WIN32) || defined(__WIN32__) || \
+ defined(_WIN64) || defined(WIN32) || defined(__TOS_WIN__)
+ /*
+ * Win32
+ */
+# undef PJ_WIN32
+# define PJ_WIN32 1
+# include <pj/compat/os_win32.h>
+
+#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL!=0
+ /*
+ * Linux kernel
+ */
+# include <pj/compat/os_linux_kernel.h>
+
+#elif defined(PJ_LINUX) || defined(linux) || defined(__linux)
+ /*
+ * Linux
+ */
+# undef PJ_LINUX
+# define PJ_LINUX 1
+# include <pj/compat/os_linux.h>
+
+#elif defined(PJ_PALMOS) && PJ_PALMOS!=0
+ /*
+ * Palm
+ */
+# include <pj/compat/os_palmos.h>
+
+#elif defined(PJ_SUNOS) || defined(sun) || defined(__sun)
+ /*
+ * SunOS
+ */
+# undef PJ_SUNOS
+# define PJ_SUNOS 1
+# include <pj/compat/os_sunos.h>
+
+#elif defined(PJ_DARWINOS) || defined(__MACOSX__) || \
+ defined (__APPLE__) || defined (__MACH__)
+ /*
+ * MacOS X
+ */
+# undef PJ_DARWINOS
+# define PJ_DARWINOS 1
+# include <pj/compat/os_darwinos.h>
+
+#elif defined(PJ_RTEMS) && PJ_RTEMS!=0
+ /*
+ * RTEMS
+ */
+# include <pj/compat/os_rtems.h>
+#else
+# error "Please specify target os."
+#endif
+
+
+/********************************************************************
+ * Target machine specific configuration.
+ */
+#if defined(PJ_AUTOCONF)
+ /*
+ * Autoconf configured
+ */
+#include <pj/compat/m_auto.h>
+
+#elif defined (PJ_M_I386) || defined(_i386_) || defined(i_386_) || \
+ defined(_X86_) || defined(x86) || defined(__i386__) || \
+ defined(__i386) || defined(_M_IX86) || defined(__I86__)
+ /*
+ * Generic i386 processor family, little-endian
+ */
+# undef PJ_M_I386
+# define PJ_M_I386 1
+# define PJ_M_NAME "i386"
+# define PJ_HAS_PENTIUM 1
+# define PJ_IS_LITTLE_ENDIAN 1
+# define PJ_IS_BIG_ENDIAN 0
+
+
+#elif defined (PJ_M_X86_64) || defined(__amd64__) || defined(__amd64) || \
+ defined(__x86_64__) || defined(__x86_64)
+ /*
+ * AMD 64bit processor, little endian
+ */
+# undef PJ_M_X86_64
+# define PJ_M_X86_64 1
+# define PJ_M_NAME "x86_64"
+# define PJ_HAS_PENTIUM 1
+# define PJ_IS_LITTLE_ENDIAN 1
+# define PJ_IS_BIG_ENDIAN 0
+
+#elif defined(PJ_M_IA64) || defined(__ia64__) || defined(_IA64) || \
+ defined(__IA64__) || defined( _M_IA64)
+ /*
+ * Intel IA64 processor, little endian
+ */
+# undef PJ_M_IA64
+# define PJ_M_IA64 1
+# define PJ_M_NAME "ia64"
+# define PJ_HAS_PENTIUM 1
+# define PJ_IS_LITTLE_ENDIAN 1
+# define PJ_IS_BIG_ENDIAN 0
+
+#elif defined (PJ_M_M68K) && PJ_M_M68K != 0
+
+ /*
+ * Motorola m64k processor, little endian
+ */
+# undef PJ_M_M68K
+# define PJ_M_M68K 1
+# define PJ_M_NAME "m68k"
+# define PJ_HAS_PENTIUM 0
+# define PJ_IS_LITTLE_ENDIAN 1
+# define PJ_IS_BIG_ENDIAN 0
+
+
+#elif defined (PJ_M_ALPHA) || defined (__alpha__) || defined (__alpha) || \
+ defined (_M_ALPHA)
+ /*
+ * DEC Alpha processor, little endian
+ */
+# undef PJ_M_ALPHA
+# define PJ_M_ALPHA 1
+# define PJ_M_NAME "alpha"
+# define PJ_HAS_PENTIUM 0
+# define PJ_IS_LITTLE_ENDIAN 1
+# define PJ_IS_BIG_ENDIAN 0
+
+
+#elif defined(PJ_M_MIPS) || defined(__mips__) || defined(__mips) || \
+ defined(__MIPS__) || defined(MIPS) || defined(_MIPS_)
+ /*
+ * MIPS, default to little endian
+ */
+# undef PJ_M_MIPS
+# define PJ_M_MIPS 1
+# define PJ_M_NAME "mips"
+# define PJ_HAS_PENTIUM 0
+# if !defined(PJ_IS_LITTLE_ENDIAN) && !defined(PJ_IS_BIG_ENDIAN)
+# define PJ_IS_LITTLE_ENDIAN 1
+# define PJ_IS_BIG_ENDIAN 0
+# endif
+
+
+#elif defined (PJ_M_SPARC) || defined( __sparc__) || defined(__sparc)
+ /*
+ * Sun Sparc, big endian
+ */
+# undef PJ_M_SPARC
+# define PJ_M_SPARC 1
+# define PJ_M_NAME "sparc"
+# define PJ_HAS_PENTIUM 0
+# define PJ_IS_LITTLE_ENDIAN 0
+# define PJ_IS_BIG_ENDIAN 1
+
+#elif defined (PJ_M_ARMV4) || defined(ARM) || defined(_ARM_) || \
+ defined(ARMV4) || defined(__arm__)
+ /*
+ * ARM, default to little endian
+ */
+# undef PJ_M_ARMV4
+# define PJ_M_ARMV4 1
+# define PJ_M_NAME "armv4"
+# define PJ_HAS_PENTIUM 0
+# if !defined(PJ_IS_LITTLE_ENDIAN) && !defined(PJ_IS_BIG_ENDIAN)
+# define PJ_IS_LITTLE_ENDIAN 1
+# define PJ_IS_BIG_ENDIAN 0
+# endif
+
+#elif defined (PJ_M_POWERPC) || defined(__powerpc) || defined(__powerpc__) || \
+ defined(__POWERPC__) || defined(__ppc__) || defined(_M_PPC) || \
+ defined(_ARCH_PPC)
+ /*
+ * PowerPC, big endian
+ */
+# undef PJ_M_POWERPC
+# define PJ_M_POWERPC 1
+# define PJ_M_NAME "powerpc"
+# define PJ_HAS_PENTIUM 0
+# define PJ_IS_LITTLE_ENDIAN 0
+# define PJ_IS_BIG_ENDIAN 1
+
+#elif defined (PJ_M_NIOS2) || defined(__nios2) || defined(__nios2__) || \
+ defined(__NIOS2__) || defined(__M_NIOS2) || defined(_ARCH_NIOS2)
+ /*
+ * Nios2, little endian
+ */
+# undef PJ_M_NIOS2
+# define PJ_M_NIOS2 1
+# define PJ_M_NAME "nios2"
+# define PJ_HAS_PENTIUM 0
+# define PJ_IS_LITTLE_ENDIAN 1
+# define PJ_IS_BIG_ENDIAN 0
+
+#else
+# error "Please specify target machine."
+#endif
+
+/* Include size_t definition. */
+#include <pj/compat/size_t.h>
+
+/* Include site/user specific configuration to control PJLIB features.
+ * YOU MUST CREATE THIS FILE YOURSELF!!
+ */
+#include <pj/config_site.h>
+
+/********************************************************************
+ * PJLIB Features.
+ */
+
+/* Overrides for DOXYGEN */
+#ifdef DOXYGEN
+# undef PJ_FUNCTIONS_ARE_INLINED
+# undef PJ_HAS_FLOATING_POINT
+# undef PJ_LOG_MAX_LEVEL
+# undef PJ_LOG_MAX_SIZE
+# undef PJ_LOG_USE_STACK_BUFFER
+# undef PJ_TERM_HAS_COLOR
+# undef PJ_POOL_DEBUG
+# undef PJ_HAS_TCP
+# undef PJ_MAX_HOSTNAME
+# undef PJ_IOQUEUE_MAX_HANDLES
+# undef FD_SETSIZE
+# undef PJ_HAS_SEMAPHORE
+# undef PJ_HAS_EVENT_OBJ
+# undef PJ_ENABLE_EXTRA_CHECK
+# undef PJ_EXCEPTION_USE_WIN32_SEH
+# undef PJ_HAS_ERROR_STRING
+
+# define PJ_HAS_IPV6 1
+#endif
+
+/**
+ * @defgroup pj_config Build Configuration
+ * @{
+ *
+ * This section contains macros that can set during PJLIB build process
+ * to controll various aspects of the library.
+ *
+ * <b>Note</b>: the values in this page does NOT necessarily reflect to the
+ * macro values during the build process.
+ */
+
+/**
+ * If this macro is set to 1, it will enable some debugging checking
+ * in the library.
+ *
+ * Default: equal to (NOT NDEBUG).
+ */
+#ifndef PJ_DEBUG
+# ifndef NDEBUG
+# define PJ_DEBUG 1
+# else
+# define PJ_DEBUG 0
+# endif
+#endif
+
+/**
+ * Enable this macro to activate logging to mutex/semaphore related events.
+ * This is useful to troubleshoot concurrency problems such as deadlocks.
+ * In addition, you should also add PJ_LOG_HAS_THREAD_ID flag to the
+ * log decoration to assist the troubleshooting.
+ *
+ * Default: 0
+ */
+#ifndef PJ_DEBUG_MUTEX
+# define PJ_DEBUG_MUTEX 0
+#endif
+
+/**
+ * Expand functions in *_i.h header files as inline.
+ *
+ * Default: 0.
+ */
+#ifndef PJ_FUNCTIONS_ARE_INLINED
+# define PJ_FUNCTIONS_ARE_INLINED 0
+#endif
+
+/**
+ * Use floating point computations in the library.
+ *
+ * Default: 1.
+ */
+#ifndef PJ_HAS_FLOATING_POINT
+# define PJ_HAS_FLOATING_POINT 1
+#endif
+
+/**
+ * Declare maximum logging level/verbosity. Lower number indicates higher
+ * importance, with the highest importance has level zero. The least
+ * important level is five in this implementation, but this can be extended
+ * by supplying the appropriate implementation.
+ *
+ * The level conventions:
+ * - 0: fatal error
+ * - 1: error
+ * - 2: warning
+ * - 3: info
+ * - 4: debug
+ * - 5: trace
+ * - 6: more detailed trace
+ *
+ * Default: 4
+ */
+#ifndef PJ_LOG_MAX_LEVEL
+# define PJ_LOG_MAX_LEVEL 5
+#endif
+
+/**
+ * Maximum message size that can be sent to output device for each call
+ * to PJ_LOG(). If the message size is longer than this value, it will be cut.
+ * This may affect the stack usage, depending whether PJ_LOG_USE_STACK_BUFFER
+ * flag is set.
+ *
+ * Default: 2000
+ */
+#ifndef PJ_LOG_MAX_SIZE
+# define PJ_LOG_MAX_SIZE 2000
+#endif
+
+/**
+ * Log buffer.
+ * Does the log get the buffer from the stack? (default is yes).
+ * If the value is set to NO, then the buffer will be taken from static
+ * buffer, which in this case will make the log function non-reentrant.
+ *
+ * Default: 1
+ */
+#ifndef PJ_LOG_USE_STACK_BUFFER
+# define PJ_LOG_USE_STACK_BUFFER 1
+#endif
+
+
+/**
+ * Colorfull terminal (for logging etc).
+ *
+ * Default: 1
+ */
+#ifndef PJ_TERM_HAS_COLOR
+# define PJ_TERM_HAS_COLOR 1
+#endif
+
+
+/**
+ * Set this flag to non-zero to enable various checking for pool
+ * operations. When this flag is set, assertion must be enabled
+ * in the application.
+ *
+ * This will slow down pool creation and destruction and will add
+ * few bytes of overhead, so application would normally want to
+ * disable this feature on release build.
+ *
+ * Default: 0
+ */
+#ifndef PJ_SAFE_POOL
+# define PJ_SAFE_POOL 0
+#endif
+
+
+/**
+ * If pool debugging is used, then each memory allocation from the pool
+ * will call malloc(), and pool will release all memory chunks when it
+ * is destroyed. This works better when memory verification programs
+ * such as Rational Purify is used.
+ *
+ * Default: 0
+ */
+#ifndef PJ_POOL_DEBUG
+# define PJ_POOL_DEBUG 0
+#endif
+
+
+/**
+ * Specify this as \a stack_size argument in #pj_thread_create() to specify
+ * that thread should use default stack size for the current platform.
+ *
+ * Default: 8192
+ */
+#ifndef PJ_THREAD_DEFAULT_STACK_SIZE
+# define PJ_THREAD_DEFAULT_STACK_SIZE 8192
+#endif
+
+
+/**
+ * Specify if PJ_CHECK_STACK() macro is enabled to check the sanity of
+ * the stack. The OS implementation may check that no stack overflow
+ * occurs, and it also may collect statistic about stack usage. Note
+ * that this will increase the footprint of the libraries since it
+ * tracks the filename and line number of each functions.
+ */
+#ifndef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+#endif
+
+/**
+ * Do we have alternate pool implementation?
+ *
+ * Default: 0
+ */
+#ifndef PJ_HAS_POOL_ALT_API
+# define PJ_HAS_POOL_ALT_API PJ_POOL_DEBUG
+#endif
+
+
+/**
+ * Support TCP in the library.
+ * Disabling TCP will reduce the footprint slightly (about 6KB).
+ *
+ * Default: 1
+ */
+#ifndef PJ_HAS_TCP
+# define PJ_HAS_TCP 1
+#endif
+
+/**
+ * Support IPv6 in the library. If this support is disabled, some IPv6
+ * related functions will return PJ_EIPV6NOTSUP.
+ *
+ * Default: 0 (disabled, for now)
+ */
+#ifndef PJ_HAS_IPV6
+# define PJ_HAS_IPV6 0
+#endif
+
+ /**
+ * Maximum hostname length.
+ * Libraries sometimes needs to make copy of an address to stack buffer;
+ * the value here affects the stack usage.
+ *
+ * Default: 128
+ */
+#ifndef PJ_MAX_HOSTNAME
+# define PJ_MAX_HOSTNAME (128)
+#endif
+
+/**
+ * Constants for declaring the maximum handles that can be supported by
+ * a single IOQ framework. This constant might not be relevant to the
+ * underlying I/O queue impelementation, but still, developers should be
+ * aware of this constant, to make sure that the program will not break when
+ * the underlying implementation changes.
+ */
+#ifndef PJ_IOQUEUE_MAX_HANDLES
+# define PJ_IOQUEUE_MAX_HANDLES (64)
+#endif
+
+
+/**
+ * If PJ_IOQUEUE_HAS_SAFE_UNREG macro is defined, then ioqueue will do more
+ * things to ensure thread safety of handle unregistration operation by
+ * employing reference counter to each handle.
+ *
+ * In addition, the ioqueue will preallocate memory for the handles,
+ * according to the maximum number of handles that is specified during
+ * ioqueue creation.
+ *
+ * All applications would normally want this enabled, but you may disable
+ * this if:
+ * - there is no dynamic unregistration to all ioqueues.
+ * - there is no threading, or there is no preemptive multitasking.
+ *
+ * Default: 1
+ */
+#ifndef PJ_IOQUEUE_HAS_SAFE_UNREG
+# define PJ_IOQUEUE_HAS_SAFE_UNREG 1
+#endif
+
+
+/**
+ * Default concurrency setting for sockets/handles registered to ioqueue.
+ * This controls whether the ioqueue is allowed to call the key's callback
+ * concurrently/in parallel. The default is yes, which means that if there
+ * are more than one pending operations complete simultaneously, more
+ * than one threads may call the key's callback at the same time. This
+ * generally would promote good scalability for application, at the
+ * expense of more complexity to manage the concurrent accesses.
+ *
+ * Please see the ioqueue documentation for more info.
+ */
+#ifndef PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY
+# define PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY 1
+#endif
+
+
+/* Sanity check:
+ * if ioqueue concurrency is disallowed, PJ_IOQUEUE_HAS_SAFE_UNREG
+ * must be enabled.
+ */
+#if (PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY==0) && (PJ_IOQUEUE_HAS_SAFE_UNREG==0)
+# error PJ_IOQUEUE_HAS_SAFE_UNREG must be enabled if ioqueue concurrency \
+ is disabled
+#endif
+
+
+/**
+ * When safe unregistration (PJ_IOQUEUE_HAS_SAFE_UNREG) is configured in
+ * ioqueue, the PJ_IOQUEUE_KEY_FREE_DELAY macro specifies how long the
+ * ioqueue key is kept in closing state before it can be reused.
+ *
+ * The value is in miliseconds.
+ *
+ * Default: 500 msec.
+ */
+#ifndef PJ_IOQUEUE_KEY_FREE_DELAY
+# define PJ_IOQUEUE_KEY_FREE_DELAY 500
+#endif
+
+
+/**
+ * Determine if FD_SETSIZE is changeable/set-able. If so, then we will
+ * set it to PJ_IOQUEUE_MAX_HANDLES. Currently we detect this by checking
+ * for Winsock.
+ */
+#ifndef PJ_FD_SETSIZE_SETABLE
+# if (defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H!=0) || \
+ (defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H!=0)
+# define PJ_FD_SETSIZE_SETABLE 1
+# else
+# define PJ_FD_SETSIZE_SETABLE 0
+# endif
+#endif
+
+/**
+ * Overrides FD_SETSIZE so it is consistent throughout the library.
+ * We only do this if we detected that FD_SETSIZE is changeable. If
+ * FD_SETSIZE is not set-able, then PJ_IOQUEUE_MAX_HANDLES must be
+ * set to value lower than FD_SETSIZE.
+ */
+#if PJ_FD_SETSIZE_SETABLE
+ /* Only override FD_SETSIZE if the value has not been set */
+# ifndef FD_SETSIZE
+# define FD_SETSIZE PJ_IOQUEUE_MAX_HANDLES
+# endif
+#else
+ /* When FD_SETSIZE is not changeable, check if PJ_IOQUEUE_MAX_HANDLES
+ * is lower than FD_SETSIZE value.
+ */
+# ifdef FD_SETSIZE
+# if PJ_IOQUEUE_MAX_HANDLES > FD_SETSIZE
+# error "PJ_IOQUEUE_MAX_HANDLES is greater than FD_SETSIZE"
+# endif
+# endif
+#endif
+
+
+/**
+ * Specify whether #pj_enum_ip_interface() function should exclude
+ * loopback interfaces.
+ *
+ * Default: 1
+ */
+#ifndef PJ_IP_HELPER_IGNORE_LOOPBACK_IF
+# define PJ_IP_HELPER_IGNORE_LOOPBACK_IF 1
+#endif
+
+
+/**
+ * Has semaphore functionality?
+ *
+ * Default: 1
+ */
+#ifndef PJ_HAS_SEMAPHORE
+# define PJ_HAS_SEMAPHORE 1
+#endif
+
+
+/**
+ * Event object (for synchronization, e.g. in Win32)
+ *
+ * Default: 1
+ */
+#ifndef PJ_HAS_EVENT_OBJ
+# define PJ_HAS_EVENT_OBJ 1
+#endif
+
+
+/**
+ * Maximum file name length.
+ */
+#ifndef PJ_MAXPATH
+# define PJ_MAXPATH 260
+#endif
+
+
+/**
+ * Enable library's extra check.
+ * If this macro is enabled, #PJ_ASSERT_RETURN macro will expand to
+ * run-time checking. If this macro is disabled, #PJ_ASSERT_RETURN
+ * will simply evaluate to #pj_assert().
+ *
+ * You can disable this macro to reduce size, at the risk of crashes
+ * if invalid value (e.g. NULL) is passed to the library.
+ *
+ * Default: 1
+ */
+#ifndef PJ_ENABLE_EXTRA_CHECK
+# define PJ_ENABLE_EXTRA_CHECK 1
+#endif
+
+
+/**
+ * Enable name registration for exceptions with #pj_exception_id_alloc().
+ * If this feature is enabled, then the library will keep track of
+ * names associated with each exception ID requested by application via
+ * #pj_exception_id_alloc().
+ *
+ * Disabling this macro will reduce the code and .bss size by a tad bit.
+ * See also #PJ_MAX_EXCEPTION_ID.
+ *
+ * Default: 1
+ */
+#ifndef PJ_HAS_EXCEPTION_NAMES
+# define PJ_HAS_EXCEPTION_NAMES 1
+#endif
+
+/**
+ * Maximum number of unique exception IDs that can be requested
+ * with #pj_exception_id_alloc(). For each entry, a small record will
+ * be allocated in the .bss segment.
+ *
+ * Default: 16
+ */
+#ifndef PJ_MAX_EXCEPTION_ID
+# define PJ_MAX_EXCEPTION_ID 16
+#endif
+
+/**
+ * Should we use Windows Structured Exception Handling (SEH) for the
+ * PJLIB exceptions.
+ *
+ * Default: 0
+ */
+#ifndef PJ_EXCEPTION_USE_WIN32_SEH
+# define PJ_EXCEPTION_USE_WIN32_SEH 0
+#endif
+
+/**
+ * Should we attempt to use Pentium's rdtsc for high resolution
+ * timestamp.
+ *
+ * Default: 0
+ */
+#ifndef PJ_TIMESTAMP_USE_RDTSC
+# define PJ_TIMESTAMP_USE_RDTSC 0
+#endif
+
+/**
+ * Is native platform error positive number?
+ * Default: 1 (yes)
+ */
+#ifndef PJ_NATIVE_ERR_POSITIVE
+# define PJ_NATIVE_ERR_POSITIVE 1
+#endif
+
+/**
+ * Include error message string in the library (pj_strerror()).
+ * This is very much desirable!
+ *
+ * Default: 1
+ */
+#ifndef PJ_HAS_ERROR_STRING
+# define PJ_HAS_ERROR_STRING 1
+#endif
+
+
+/**
+ * Include pj_stricmp_alnum() and pj_strnicmp_alnum(), i.e. custom
+ * functions to compare alnum strings. On some systems, they're faster
+ * then stricmp/strcasecmp, but they can be slower on other systems.
+ * When disabled, pjlib will fallback to stricmp/strnicmp.
+ *
+ * Default: 0
+ */
+#ifndef PJ_HAS_STRICMP_ALNUM
+# define PJ_HAS_STRICMP_ALNUM 0
+#endif
+
+
+/*
+ * Types of QoS backend implementation.
+ */
+
+/**
+ * Dummy QoS backend implementation, will always return error on all
+ * the APIs.
+ */
+#define PJ_QOS_DUMMY 1
+
+/** QoS backend based on setsockopt(IP_TOS) */
+#define PJ_QOS_BSD 2
+
+/** QoS backend for Windows Mobile 6 */
+#define PJ_QOS_WM 3
+
+/** QoS backend for Symbian */
+#define PJ_QOS_SYMBIAN 4
+
+/**
+ * Force the use of some QoS backend API for some platforms.
+ */
+#ifndef PJ_QOS_IMPLEMENTATION
+# if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE && _WIN32_WCE >= 0x502
+ /* Windows Mobile 6 or later */
+# define PJ_QOS_IMPLEMENTATION PJ_QOS_WM
+# endif
+#endif
+
+
+/**
+ * Enable secure socket. For most platforms, this is implemented using
+ * OpenSSL, so this will require OpenSSL to be installed. For Symbian
+ * platform, this is implemented natively using CSecureSocket.
+ *
+ * Default: 0 (for now)
+ */
+#ifndef PJ_HAS_SSL_SOCK
+# define PJ_HAS_SSL_SOCK 0
+#endif
+
+
+/** @} */
+
+/********************************************************************
+ * General macros.
+ */
+
+/**
+ * @defgroup pj_dll_target Building Dynamic Link Libraries (DLL/DSO)
+ * @ingroup pj_config
+ * @{
+ *
+ * The libraries support generation of dynamic link libraries for
+ * Symbian ABIv2 target (.dso/Dynamic Shared Object files, in Symbian
+ * terms). Similar procedures may be applied for Win32 DLL with some
+ * modification.
+ *
+ * Depending on the platforms, these steps may be necessary in order to
+ * produce the dynamic libraries:
+ * - Create the (Visual Studio) projects to produce DLL output. PJLIB
+ * does not provide ready to use project files to produce DLL, so
+ * you need to create these projects yourself. For Symbian, the MMP
+ * files have been setup to produce DSO files for targets that
+ * require them.
+ * - In the (Visual Studio) projects, some macros need to be declared
+ * so that appropriate modifiers are added to symbol declarations
+ * and definitions. Please see the macro section below for information
+ * regarding these macros. For Symbian, these have been taken care by the
+ * MMP files.
+ * - Some build systems require .DEF file to be specified when creating
+ * the DLL. For Symbian, .DEF files are included in pjlib distribution,
+ * in <tt>pjlib/build.symbian</tt> directory. These DEF files are
+ * created by running <tt>./makedef.sh all</tt> from this directory,
+ * inside Mingw.
+ *
+ * Macros related for building DLL/DSO files:
+ * - For platforms that supports dynamic link libraries generation,
+ * it must declare <tt>PJ_EXPORT_SPECIFIER</tt> macro which value contains
+ * the prefix to be added to symbol definition, to export this
+ * symbol in the DLL/DSO. For example, on Win32/Visual Studio, the
+ * value of this macro is \a __declspec(dllexport), and for ARM
+ * ABIv2/Symbian, the value is \a EXPORT_C.
+ * - For platforms that supports linking with dynamic link libraries,
+ * it must declare <tt>PJ_IMPORT_SPECIFIER</tt> macro which value contains
+ * the prefix to be added to symbol declaration, to import this
+ * symbol from a DLL/DSO. For example, on Win32/Visual Studio, the
+ * value of this macro is \a __declspec(dllimport), and for ARM
+ * ABIv2/Symbian, the value is \a IMPORT_C.
+ * - Both <tt>PJ_EXPORT_SPECIFIER</tt> and <tt>PJ_IMPORT_SPECIFIER</tt>
+ * macros above can be declared in your \a config_site.h if they are not
+ * declared by pjlib.
+ * - When PJLIB is built as DLL/DSO, both <tt>PJ_DLL</tt> and
+ * <tt>PJ_EXPORTING</tt> macros must be declared, so that
+ * <tt>PJ_EXPORT_SPECIFIER</tt> modifier will be added into function
+ * definition.
+ * - When application wants to link dynamically with PJLIB, then it
+ * must declare <tt>PJ_DLL</tt> macro when using/including PJLIB header,
+ * so that <tt>PJ_IMPORT_SPECIFIER</tt> modifier is properly added into
+ * symbol declarations.
+ *
+ * When <b>PJ_DLL</b> macro is not declared, static linking is assumed.
+ *
+ * For example, here are some settings to produce DLLs with Visual Studio
+ * on Windows/Win32:
+ * - Create Visual Studio projects to produce DLL. Add the appropriate
+ * project dependencies to avoid link errors.
+ * - In the projects, declare <tt>PJ_DLL</tt> and <tt>PJ_EXPORTING</tt>
+ * macros.
+ * - Declare these macros in your <tt>config_site.h</tt>:
+ \verbatim
+ #define PJ_EXPORT_SPECIFIER __declspec(dllexport)
+ #define PJ_IMPORT_SPECIFIER __declspec(dllimport)
+ \endverbatim
+ * - And in the application (that links with the DLL) project, add
+ * <tt>PJ_DLL</tt> in the macro declarations.
+ */
+
+/** @} */
+
+/**
+ * @defgroup pj_config Build Configuration
+ * @{
+ */
+
+/**
+ * @def PJ_INLINE(type)
+ * @param type The return type of the function.
+ * Expand the function as inline.
+ */
+#define PJ_INLINE(type) PJ_INLINE_SPECIFIER type
+
+/**
+ * This macro declares platform/compiler specific specifier prefix
+ * to be added to symbol declaration to export the symbol when PJLIB
+ * is built as dynamic library.
+ *
+ * This macro should have been added by platform specific headers,
+ * if the platform supports building dynamic library target.
+ */
+#ifndef PJ_EXPORT_DECL_SPECIFIER
+# define PJ_EXPORT_DECL_SPECIFIER
+#endif
+
+
+/**
+ * This macro declares platform/compiler specific specifier prefix
+ * to be added to symbol definition to export the symbol when PJLIB
+ * is built as dynamic library.
+ *
+ * This macro should have been added by platform specific headers,
+ * if the platform supports building dynamic library target.
+ */
+#ifndef PJ_EXPORT_DEF_SPECIFIER
+# define PJ_EXPORT_DEF_SPECIFIER
+#endif
+
+
+/**
+ * This macro declares platform/compiler specific specifier prefix
+ * to be added to symbol declaration to import the symbol.
+ *
+ * This macro should have been added by platform specific headers,
+ * if the platform supports building dynamic library target.
+ */
+#ifndef PJ_IMPORT_DECL_SPECIFIER
+# define PJ_IMPORT_DECL_SPECIFIER
+#endif
+
+
+/**
+ * This macro has been deprecated. It will evaluate to nothing.
+ */
+#ifndef PJ_EXPORT_SYMBOL
+# define PJ_EXPORT_SYMBOL(x)
+#endif
+
+
+/**
+ * @def PJ_DECL(type)
+ * @param type The return type of the function.
+ * Declare a function.
+ */
+#if defined(PJ_DLL)
+# if defined(PJ_EXPORTING)
+# define PJ_DECL(type) PJ_EXPORT_DECL_SPECIFIER type
+# else
+# define PJ_DECL(type) PJ_IMPORT_DECL_SPECIFIER type
+# endif
+#elif !defined(PJ_DECL)
+# if defined(__cplusplus)
+# define PJ_DECL(type) type
+# else
+# define PJ_DECL(type) extern type
+# endif
+#endif
+
+
+/**
+ * @def PJ_DEF(type)
+ * @param type The return type of the function.
+ * Define a function.
+ */
+#if defined(PJ_DLL) && defined(PJ_EXPORTING)
+# define PJ_DEF(type) PJ_EXPORT_DEF_SPECIFIER type
+#elif !defined(PJ_DEF)
+# define PJ_DEF(type) type
+#endif
+
+
+/**
+ * @def PJ_DECL_NO_RETURN(type)
+ * @param type The return type of the function.
+ * Declare a function that will not return.
+ */
+/**
+ * @def PJ_IDECL_NO_RETURN(type)
+ * @param type The return type of the function.
+ * Declare an inline function that will not return.
+ */
+/**
+ * @def PJ_BEGIN_DECL
+ * Mark beginning of declaration section in a header file.
+ */
+/**
+ * @def PJ_END_DECL
+ * Mark end of declaration section in a header file.
+ */
+#ifdef __cplusplus
+# define PJ_DECL_NO_RETURN(type) PJ_DECL(type) PJ_NORETURN
+# define PJ_IDECL_NO_RETURN(type) PJ_INLINE(type) PJ_NORETURN
+# define PJ_BEGIN_DECL extern "C" {
+# define PJ_END_DECL }
+#else
+# define PJ_DECL_NO_RETURN(type) PJ_NORETURN PJ_DECL(type)
+# define PJ_IDECL_NO_RETURN(type) PJ_NORETURN PJ_INLINE(type)
+# define PJ_BEGIN_DECL
+# define PJ_END_DECL
+#endif
+
+
+
+/**
+ * @def PJ_DECL_DATA(type)
+ * @param type The data type.
+ * Declare a global data.
+ */
+#if defined(PJ_DLL)
+# if defined(PJ_EXPORTING)
+# define PJ_DECL_DATA(type) PJ_EXPORT_DECL_SPECIFIER extern type
+# else
+# define PJ_DECL_DATA(type) PJ_IMPORT_DECL_SPECIFIER extern type
+# endif
+#elif !defined(PJ_DECL_DATA)
+# define PJ_DECL_DATA(type) extern type
+#endif
+
+
+/**
+ * @def PJ_DEF_DATA(type)
+ * @param type The data type.
+ * Define a global data.
+ */
+#if defined(PJ_DLL) && defined(PJ_EXPORTING)
+# define PJ_DEF_DATA(type) PJ_EXPORT_DEF_SPECIFIER type
+#elif !defined(PJ_DEF_DATA)
+# define PJ_DEF_DATA(type) type
+#endif
+
+
+/**
+ * @def PJ_IDECL(type)
+ * @param type The function's return type.
+ * Declare a function that may be expanded as inline.
+ */
+/**
+ * @def PJ_IDEF(type)
+ * @param type The function's return type.
+ * Define a function that may be expanded as inline.
+ */
+
+#if PJ_FUNCTIONS_ARE_INLINED
+# define PJ_IDECL(type) PJ_INLINE(type)
+# define PJ_IDEF(type) PJ_INLINE(type)
+#else
+# define PJ_IDECL(type) PJ_DECL(type)
+# define PJ_IDEF(type) PJ_DEF(type)
+#endif
+
+
+/**
+ * @def PJ_UNUSED_ARG(arg)
+ * @param arg The argument name.
+ * PJ_UNUSED_ARG prevents warning about unused argument in a function.
+ */
+#define PJ_UNUSED_ARG(arg) (void)arg
+
+/**
+ * @def PJ_TODO(id)
+ * @param id Any identifier that will be printed as TODO message.
+ * PJ_TODO macro will display TODO message as warning during compilation.
+ * Example: PJ_TODO(CLEAN_UP_ERROR);
+ */
+#ifndef PJ_TODO
+# define PJ_TODO(id) TODO___##id:
+#endif
+
+/**
+ * Function attributes to inform that the function may throw exception.
+ *
+ * @param x The exception list, enclosed in parenthesis.
+ */
+#define __pj_throw__(x)
+
+/** @} */
+
+/********************************************************************
+ * Sanity Checks
+ */
+#ifndef PJ_HAS_HIGH_RES_TIMER
+# error "PJ_HAS_HIGH_RES_TIMER is not defined!"
+#endif
+
+#if !defined(PJ_HAS_PENTIUM)
+# error "PJ_HAS_PENTIUM is not defined!"
+#endif
+
+#if !defined(PJ_IS_LITTLE_ENDIAN)
+# error "PJ_IS_LITTLE_ENDIAN is not defined!"
+#endif
+
+#if !defined(PJ_IS_BIG_ENDIAN)
+# error "PJ_IS_BIG_ENDIAN is not defined!"
+#endif
+
+#if !defined(PJ_EMULATE_RWMUTEX)
+# error "PJ_EMULATE_RWMUTEX should be defined in compat/os_xx.h"
+#endif
+
+#if !defined(PJ_THREAD_SET_STACK_SIZE)
+# error "PJ_THREAD_SET_STACK_SIZE should be defined in compat/os_xx.h"
+#endif
+
+#if !defined(PJ_THREAD_ALLOCATE_STACK)
+# error "PJ_THREAD_ALLOCATE_STACK should be defined in compat/os_xx.h"
+#endif
+
+PJ_BEGIN_DECL
+
+/**
+ * PJLIB version string constant. @see pj_get_version()
+ */
+PJ_DECL_DATA(const char*) PJ_VERSION;
+
+/**
+ * Get PJLIB version string.
+ *
+ * @return #PJ_VERSION constant.
+ */
+PJ_DECL(const char*) pj_get_version(void);
+
+/**
+ * Dump configuration to log with verbosity equal to info(3).
+ */
+PJ_DECL(void) pj_dump_config(void);
+
+PJ_END_DECL
+
+
+#endif /* __PJ_CONFIG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site.h
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site_sample.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site_sample.h
new file mode 100644
index 0000000..f106a4f
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site_sample.h
@@ -0,0 +1,345 @@
+/*
+ * This file contains several sample settings especially for Windows
+ * Mobile and Symbian targets. You can include this file in your
+ * <pj/config_site.h> file.
+ *
+ * The Windows Mobile and Symbian settings will be activated
+ * automatically if you include this file.
+ *
+ * In addition, you may specify one of these macros (before including
+ * this file) to activate additional settings:
+ *
+ * #define PJ_CONFIG_NOKIA_APS_DIRECT
+ * Use this macro to activate the APS-Direct feature. Please see
+ * http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct for more
+ * info.
+ *
+ * #define PJ_CONFIG_WIN32_WMME_DIRECT
+ * Configuration to activate "APS-Direct" media mode on Windows or
+ * Windows Mobile, useful for testing purposes only.
+ */
+
+
+/*
+ * Typical configuration for WinCE target.
+ */
+#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
+
+ /*
+ * PJLIB settings.
+ */
+
+ /* Disable floating point support */
+ #define PJ_HAS_FLOATING_POINT 0
+
+ /*
+ * PJMEDIA settings
+ */
+
+ /* Select codecs to disable */
+ #define PJMEDIA_HAS_L16_CODEC 0
+ #define PJMEDIA_HAS_ILBC_CODEC 0
+
+ /* We probably need more buffers on WM, so increase the limit */
+ #define PJMEDIA_SOUND_BUFFER_COUNT 32
+
+ /* Fine tune Speex's default settings for best performance/quality */
+ #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 5
+
+ /* For CPU reason, disable speex AEC and use the echo suppressor. */
+ #define PJMEDIA_HAS_SPEEX_AEC 0
+
+ /* Previously, resampling is disabled due to performance reason and
+ * this condition prevented some 'light' wideband codecs (e.g: G722.1)
+ * to work along with narrowband codecs. Lately, some tests showed
+ * that 16kHz <-> 8kHz resampling using libresample small filter was
+ * affordable on ARM9 260 MHz, so here we decided to enable resampling.
+ * Note that it is important to make sure that libresample is created
+ * using small filter. For example PJSUA_DEFAULT_CODEC_QUALITY must
+ * be set to 3 or 4 so pjsua-lib will apply small filter resampling.
+ */
+ //#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_NONE
+ #define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE
+
+ /* Use the lighter WSOLA implementation */
+ #define PJMEDIA_WSOLA_IMP PJMEDIA_WSOLA_IMP_WSOLA_LITE
+
+ /*
+ * PJSIP settings.
+ */
+
+ /* Set maximum number of dialog/transaction/calls to minimum to reduce
+ * memory usage
+ */
+ #define PJSIP_MAX_TSX_COUNT 31
+ #define PJSIP_MAX_DIALOG_COUNT 31
+ #define PJSUA_MAX_CALLS 4
+
+ /*
+ * PJSUA settings
+ */
+
+ /* Default codec quality, previously was set to 5, however it is now
+ * set to 4 to make sure pjsua instantiates resampler with small filter.
+ */
+ #define PJSUA_DEFAULT_CODEC_QUALITY 4
+
+ /* Set maximum number of objects to minimum to reduce memory usage */
+ #define PJSUA_MAX_ACC 4
+ #define PJSUA_MAX_PLAYERS 4
+ #define PJSUA_MAX_RECORDERS 4
+ #define PJSUA_MAX_CONF_PORTS (PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)
+ #define PJSUA_MAX_BUDDIES 32
+
+#endif /* PJ_WIN32_WINCE */
+
+
+/*
+ * Typical configuration for Symbian OS target
+ */
+#if defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
+
+ /*
+ * PJLIB settings.
+ */
+
+ /* Disable floating point support */
+ #define PJ_HAS_FLOATING_POINT 0
+
+ /* Misc PJLIB setting */
+ #define PJ_MAXPATH 80
+
+ /* This is important for Symbian. Symbian lacks vsnprintf(), so
+ * if the log buffer is not long enough it's possible that
+ * large incoming packet will corrupt memory when the log tries
+ * to log the packet.
+ */
+ #define PJ_LOG_MAX_SIZE (PJSIP_MAX_PKT_LEN+500)
+
+ /* Since we don't have threads, log buffer can use static buffer
+ * rather than stack
+ */
+ #define PJ_LOG_USE_STACK_BUFFER 0
+
+ /* Disable check stack since it increases footprint */
+ #define PJ_OS_HAS_CHECK_STACK 0
+
+
+ /*
+ * PJMEDIA settings
+ */
+
+ /* Disable non-Symbian audio devices */
+ #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
+ #define PJMEDIA_AUDIO_DEV_HAS_WMME 0
+
+ /* Select codecs to disable */
+ #define PJMEDIA_HAS_L16_CODEC 0
+ #define PJMEDIA_HAS_ILBC_CODEC 0
+ #define PJMEDIA_HAS_G722_CODEC 0
+
+ /* Fine tune Speex's default settings for best performance/quality */
+ #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 5
+
+ /* For CPU reason, disable speex AEC and use the echo suppressor. */
+ #define PJMEDIA_HAS_SPEEX_AEC 0
+
+ /* Previously, resampling is disabled due to performance reason and
+ * this condition prevented some 'light' wideband codecs (e.g: G722.1)
+ * to work along with narrowband codecs. Lately, some tests showed
+ * that 16kHz <-> 8kHz resampling using libresample small filter was
+ * affordable on ARM9 222 MHz, so here we decided to enable resampling.
+ * Note that it is important to make sure that libresample is created
+ * using small filter. For example PJSUA_DEFAULT_CODEC_QUALITY must
+ * be set to 3 or 4 so pjsua-lib will apply small filter resampling.
+ */
+ //#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_NONE
+ #define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE
+
+ /* Use the lighter WSOLA implementation */
+ #define PJMEDIA_WSOLA_IMP PJMEDIA_WSOLA_IMP_WSOLA_LITE
+
+ /* We probably need more buffers especially if MDA audio backend
+ * is used, so increase the limit
+ */
+ #define PJMEDIA_SOUND_BUFFER_COUNT 32
+
+ /*
+ * PJSIP settings.
+ */
+
+ /* Disable safe module access, since we don't use multithreading */
+ #define PJSIP_SAFE_MODULE 0
+
+ /* Increase allowable packet size, just in case */
+ #define PJSIP_MAX_PKT_LEN 2000
+
+ /* Symbian has problem with too many large blocks */
+ #define PJSIP_POOL_LEN_ENDPT 1000
+ #define PJSIP_POOL_INC_ENDPT 1000
+ #define PJSIP_POOL_RDATA_LEN 2000
+ #define PJSIP_POOL_RDATA_INC 2000
+ #define PJSIP_POOL_LEN_TDATA 2000
+ #define PJSIP_POOL_INC_TDATA 512
+ #define PJSIP_POOL_LEN_UA 2000
+ #define PJSIP_POOL_INC_UA 1000
+ #define PJSIP_POOL_TSX_LAYER_LEN 256
+ #define PJSIP_POOL_TSX_LAYER_INC 256
+ #define PJSIP_POOL_TSX_LEN 512
+ #define PJSIP_POOL_TSX_INC 128
+
+ /*
+ * PJSUA settings.
+ */
+
+ /* Default codec quality, previously was set to 5, however it is now
+ * set to 4 to make sure pjsua instantiates resampler with small filter.
+ */
+ #define PJSUA_DEFAULT_CODEC_QUALITY 4
+
+ /* Set maximum number of dialog/transaction/calls to minimum */
+ #define PJSIP_MAX_TSX_COUNT 31
+ #define PJSIP_MAX_DIALOG_COUNT 31
+ #define PJSUA_MAX_CALLS 4
+
+ /* Other pjsua settings */
+ #define PJSUA_MAX_ACC 4
+ #define PJSUA_MAX_PLAYERS 4
+ #define PJSUA_MAX_RECORDERS 4
+ #define PJSUA_MAX_CONF_PORTS (PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)
+ #define PJSUA_MAX_BUDDIES 32
+#endif
+
+
+/*
+ * Additional configuration to activate APS-Direct feature for
+ * Nokia S60 target
+ *
+ * Please see http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct
+ */
+#ifdef PJ_CONFIG_NOKIA_APS_DIRECT
+
+ /* MUST use switchboard rather than the conference bridge */
+ #define PJMEDIA_CONF_USE_SWITCH_BOARD 1
+
+ /* Enable APS sound device backend and disable MDA & VAS */
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA 0
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 1
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 0
+
+ /* Enable passthrough codec framework */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODECS 1
+
+ /* And selectively enable which codecs are supported by the handset */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 1
+
+#endif
+
+
+/*
+ * Additional configuration to activate VAS-Direct feature for
+ * Nokia S60 target
+ *
+ * Please see http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct
+ */
+#ifdef PJ_CONFIG_NOKIA_VAS_DIRECT
+
+ /* MUST use switchboard rather than the conference bridge */
+ #define PJMEDIA_CONF_USE_SWITCH_BOARD 1
+
+ /* Enable VAS sound device backend and disable MDA & APS */
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA 0
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 0
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 1
+
+ /* Enable passthrough codec framework */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODECS 1
+
+ /* And selectively enable which codecs are supported by the handset */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 1
+
+#endif
+
+
+/*
+ * Configuration to activate "APS-Direct" media mode on Windows,
+ * useful for testing purposes only.
+ */
+#ifdef PJ_CONFIG_WIN32_WMME_DIRECT
+
+ /* MUST use switchboard rather than the conference bridge */
+ #define PJMEDIA_CONF_USE_SWITCH_BOARD 1
+
+ /* Only WMME supports the "direct" feature */
+ #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
+ #define PJMEDIA_AUDIO_DEV_HAS_WMME 1
+
+ /* Enable passthrough codec framework */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODECS 1
+
+ /* Only PCMA and PCMU are supported by WMME-direct */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 0
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 0
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 0
+
+#endif
+
+
+/*
+ * Minimum size
+ */
+#ifdef PJ_CONFIG_MINIMAL_SIZE
+
+# undef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+# define PJ_LOG_MAX_LEVEL 0
+# define PJ_ENABLE_EXTRA_CHECK 0
+# define PJ_HAS_ERROR_STRING 0
+# undef PJ_IOQUEUE_MAX_HANDLES
+/* Putting max handles to lower than 32 will make pj_fd_set_t size smaller
+ * than native fdset_t and will trigger assertion on sock_select.c.
+ */
+# define PJ_IOQUEUE_MAX_HANDLES 32
+# define PJSIP_MAX_TSX_COUNT 15
+# define PJSIP_MAX_DIALOG_COUNT 15
+# define PJSIP_UDP_SO_SNDBUF_SIZE 4000
+# define PJSIP_UDP_SO_RCVBUF_SIZE 4000
+# define PJMEDIA_HAS_LARGE_FILTER 0
+# define PJMEDIA_HAS_SMALL_FILTER 0
+
+
+#elif defined(PJ_CONFIG_MAXIMUM_SPEED)
+# define PJ_SCANNER_USE_BITWISE 0
+# undef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+# define PJ_LOG_MAX_LEVEL 3
+# define PJ_ENABLE_EXTRA_CHECK 0
+# define PJ_IOQUEUE_MAX_HANDLES 5000
+# define PJSIP_MAX_TSX_COUNT ((640*1024)-1)
+# define PJSIP_MAX_DIALOG_COUNT ((640*1024)-1)
+# define PJSIP_UDP_SO_SNDBUF_SIZE (24*1024*1024)
+# define PJSIP_UDP_SO_RCVBUF_SIZE (24*1024*1024)
+# define PJ_DEBUG 0
+# define PJSIP_SAFE_MODULE 0
+# define PJ_HAS_STRICMP_ALNUM 0
+# define PJ_HASH_USE_OWN_TOLOWER 1
+# define PJSIP_UNESCAPE_IN_PLACE 1
+
+# ifdef PJ_WIN32
+# define PJSIP_MAX_NET_EVENTS 10
+# endif
+
+# define PJSUA_MAX_CALLS 512
+
+#endif
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/ctype.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/ctype.h
new file mode 100644
index 0000000..8b6d142
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/ctype.h
@@ -0,0 +1,175 @@
+/* $Id: ctype.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_CTYPE_H__
+#define __PJ_CTYPE_H__
+
+/**
+ * @file ctype.h
+ * @brief C type helper macros.
+ */
+
+#include <pj/types.h>
+#include <pj/compat/ctype.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup pj_ctype ctype - Character Type
+ * @ingroup PJ_MISC
+ * @{
+ *
+ * This module contains several inline functions/macros for testing or
+ * manipulating character types. It is provided in PJLIB because PJLIB
+ * must not depend to LIBC.
+ */
+
+/**
+ * Returns a non-zero value if either isalpha or isdigit is true for c.
+ * @param c The integer character to test.
+ * @return Non-zero value if either isalpha or isdigit is true for c.
+ */
+PJ_INLINE(int) pj_isalnum(unsigned char c) { return isalnum(c); }
+
+/**
+ * Returns a non-zero value if c is a particular representation of an
+ * alphabetic character.
+ * @param c The integer character to test.
+ * @return Non-zero value if c is a particular representation of an
+ * alphabetic character.
+ */
+PJ_INLINE(int) pj_isalpha(unsigned char c) { return isalpha(c); }
+
+/**
+ * Returns a non-zero value if c is a particular representation of an
+ * ASCII character.
+ * @param c The integer character to test.
+ * @return Non-zero value if c is a particular representation of
+ * an ASCII character.
+ */
+PJ_INLINE(int) pj_isascii(unsigned char c) { return c<128; }
+
+/**
+ * Returns a non-zero value if c is a particular representation of
+ * a decimal-digit character.
+ * @param c The integer character to test.
+ * @return Non-zero value if c is a particular representation of
+ * a decimal-digit character.
+ */
+PJ_INLINE(int) pj_isdigit(unsigned char c) { return isdigit(c); }
+
+/**
+ * Returns a non-zero value if c is a particular representation of
+ * a space character (0x09 - 0x0D or 0x20).
+ * @param c The integer character to test.
+ * @return Non-zero value if c is a particular representation of
+ * a space character (0x09 - 0x0D or 0x20).
+ */
+PJ_INLINE(int) pj_isspace(unsigned char c) { return isspace(c); }
+
+/**
+ * Returns a non-zero value if c is a particular representation of
+ * a lowercase character.
+ * @param c The integer character to test.
+ * @return Non-zero value if c is a particular representation of
+ * a lowercase character.
+ */
+PJ_INLINE(int) pj_islower(unsigned char c) { return islower(c); }
+
+
+/**
+ * Returns a non-zero value if c is a particular representation of
+ * a uppercase character.
+ * @param c The integer character to test.
+ * @return Non-zero value if c is a particular representation of
+ * a uppercase character.
+ */
+PJ_INLINE(int) pj_isupper(unsigned char c) { return isupper(c); }
+
+/**
+ * Returns a non-zero value if c is a either a space (' ') or horizontal
+ * tab ('\\t') character.
+ * @param c The integer character to test.
+ * @return Non-zero value if c is a either a space (' ') or horizontal
+ * tab ('\\t') character.
+ */
+PJ_INLINE(int) pj_isblank(unsigned char c) { return isblank(c); }
+
+/**
+ * Converts character to lowercase.
+ * @param c The integer character to convert.
+ * @return Lowercase character of c.
+ */
+PJ_INLINE(int) pj_tolower(unsigned char c) { return tolower(c); }
+
+/**
+ * Converts character to uppercase.
+ * @param c The integer character to convert.
+ * @return Uppercase character of c.
+ */
+PJ_INLINE(int) pj_toupper(unsigned char c) { return toupper(c); }
+
+/**
+ * Returns a non-zero value if c is a particular representation of
+ * an hexadecimal digit character.
+ * @param c The integer character to test.
+ * @return Non-zero value if c is a particular representation of
+ * an hexadecimal digit character.
+ */
+PJ_INLINE(int) pj_isxdigit(unsigned char c){ return isxdigit(c); }
+
+/**
+ * Array of hex digits, in lowerspace.
+ */
+/*extern char pj_hex_digits[];*/
+#define pj_hex_digits "0123456789abcdef"
+
+/**
+ * Convert a value to hex representation.
+ * @param value Integral value to convert.
+ * @param p Buffer to hold the hex representation, which must be
+ * at least two bytes length.
+ */
+PJ_INLINE(void) pj_val_to_hex_digit(unsigned value, char *p)
+{
+ *p++ = pj_hex_digits[ (value & 0xF0) >> 4 ];
+ *p = pj_hex_digits[ (value & 0x0F) ];
+}
+
+/**
+ * Convert hex digit c to integral value.
+ * @param c The hex digit character.
+ * @return The integral value between 0 and 15.
+ */
+PJ_INLINE(unsigned) pj_hex_digit_to_val(unsigned char c)
+{
+ if (c <= '9')
+ return (c-'0') & 0x0F;
+ else if (c <= 'F')
+ return (c-'A'+10) & 0x0F;
+ else
+ return (c-'a'+10) & 0x0F;
+}
+
+/** @} */
+
+PJ_END_DECL
+
+#endif /* __PJ_CTYPE_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/doxygen.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/doxygen.h
new file mode 100644
index 0000000..1b027b9
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/doxygen.h
@@ -0,0 +1,996 @@
+/* $Id: doxygen.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_DOXYGEN_H__
+#define __PJ_DOXYGEN_H__
+
+/**
+ * @file doxygen.h
+ * @brief Doxygen's mainpage.
+ */
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+ INTRODUCTION PAGE
+ */
+
+/**
+ * @mainpage Welcome to PJLIB!
+ *
+ * @section intro_sec What is PJLIB
+ *
+ * PJLIB is an Open Source, small footprint framework library written in C for
+ * making scalable applications. Because of its small footprint, it can be used
+ * in embedded applications (we hope so!), but yet the library is also aimed for
+ * facilitating the creation of high performance protocol stacks.
+ *
+ * PJLIB is released under GPL terms.
+ *
+ * @section download_sec Download
+ *
+ * PJLIB and all documentation can be downloaded from
+ * http://www.pjsip.org.
+ *
+ *
+ * @section how_to_use_sec About This Documentation
+ *
+ * This document is generated directly from PJLIB source file using
+ * \a doxygen (http://www.doxygen.org). Doxygen is a great (and free!)
+ * tools for generating such documentation.
+ *
+ *
+ * @subsection find_samples_subsec How to Read This Document
+ *
+ * This documentation is laid out more to be a reference guide instead
+ * of tutorial, therefore first time users may find it difficult to
+ * grasp PJLIB by reading this document alone.
+ *
+ * However, we've tried our best to make this document easy to follow.
+ * For first time users, we would suggest that you follow these steps
+ * when reading this documentation:
+ *
+ * - continue reading this introduction chapter. At the end of this
+ * chapter, you'll find section called \ref pjlib_fundamentals_sec
+ * which should guide you to understand basic things about PJLIB.
+ *
+ * - find information about specific features that you want to use
+ * in PJLIB. Use the <b>Module Index</b> to find out about all
+ * features in PJLIB (if you're browsing the HTML documentation,
+ * click on the \a Module link on top of the page, or if you're
+ * reading the PDF documentation, click on \a Module \a Documentation
+ * on the navigation pane on the left).
+ *
+ * @subsection doc_organize_sec How To's
+ *
+ * Please find below links to specific tasks that you probably
+ * want to do:
+ *
+ * - <b>How to Build PJLIB</b>
+ *\n
+ * Please refer to \ref pjlib_build_sys_pg page for more information.
+ *
+ * - <b>How to Use PJLIB in My Application</b>
+ *\n
+ * Please refer to \ref configure_app_sec for more information.
+ *
+ * - <b>How to Port PJLIB</b>
+ *\n
+ * Please refer to \ref porting_pjlib_pg page.
+ *
+ * - <b>Where to Read Samples Documentation</b>
+ *\n
+ * Most of the modules provide link to the corresponding sample file.
+ * Alternatively, to get the list of all examples, you can click on
+ * <b>Related Pages</b> on the top of HTML document or on
+ * <b>PJLIB Page Documentation</b> on navigation pane of your PDF reader.
+ *
+ * - <b>How to Submit Code to PJLIB Project</b>
+ *\n
+ * Please read \ref pjlib_coding_convention_page before submitting
+ * your code. Send your code as patch against current Subversion tree
+ * to the appropriate mailing list.
+ *
+ *
+ * @section features_sec Features
+ *
+ * @subsection open_source_feat It's Open Source!
+ *
+ * PJLIB is currently released on GPL license, but other arrangements
+ * can be made with the author.
+ *
+ * @subsection extreme_portable_feat Extreme Portability
+ *
+ * PJLIB is designed to be extremely portable. It can run on any kind
+ * of processors (16-bit, 32-bit, or 64-bit, big or little endian, single
+ * or multi-processors) and operating systems. Floating point or no
+ * floating point. Multi-threading or not.
+ * It can even run in environment where no ANSI LIBC is available.
+ *
+ * Currently PJLIB is known to run on these platforms:
+ * - Win32/x86 (Win95/98/ME, NT/2000/XP/2003, mingw).
+ * - arm, WinCE and Windows Mobile.
+ * - Linux/x86, (user mode and as <b>kernel module</b>(!)).
+ * - Linux/alpha
+ * - Solaris/ultra.
+ * - MacOS X/powerpc
+ * - RTEMS (x86 and powerpc).
+ *
+ * And efforts is under way to port PJLIB on:
+ * - Symbian OS
+ *
+ *
+ * @subsection small_size_feat Small in Size
+ *
+ * One of the primary objectives is to have library that is small in size for
+ * typical embedded applications. As a rough guidance, we aim to keep the
+ * library size below 100KB for it to be considered as small.
+ * As the result, most of the functionalities in the library can be tailored
+ * to meet the requirements; user can enable/disable specific functionalities
+ * to get the desired size/performance/functionality balance.
+ *
+ * For more info, please see @ref pj_config.
+ *
+ *
+ * @subsection big_perform_feat Big in Performance
+ *
+ * Almost everything in PJLIB is designed to achieve the highest possible
+ * performance out of the target platform.
+ *
+ *
+ * @subsection no_dyn_mem No Dynamic Memory Allocations
+ *
+ * The central idea of PJLIB is that for applications to run as fast as it can,
+ * it should not use \a malloc() at all, but instead should get the memory
+ * from a preallocated storage pool. There are few things that can be
+ * optimized with this approach:
+ *
+ * - \a alloc() is a O(1) operation.
+ * - no mutex is used inside alloc(). It is assumed that synchronization
+ * will be used in higher abstraction by application anyway.
+ * - no \a free() is required. All chunks will be deleted when the pool is
+ * destroyed.
+ *
+ * The performance gained on some systems can be as high as 30x speed up
+ * against \a malloc() and \a free() on certain configurations, but of
+ * course your mileage may vary.
+ *
+ * For more information, see \ref PJ_POOL_GROUP
+ *
+ *
+ * @subsection os_abstract_feat Operating System Abstraction
+ *
+ * PJLIB has abstractions for features that are normally not portable
+ * across operating systems:
+ * - @ref PJ_THREAD
+ *\n
+ * Portable thread manipulation.
+ * - @ref PJ_TLS
+ *\n
+ * Storing data in thread's private data.
+ * - @ref PJ_MUTEX
+ *\n
+ * Mutual exclusion protection.
+ * - @ref PJ_SEM
+ *\n
+ * Semaphores.
+ * - @ref PJ_ATOMIC
+ *\n
+ * Atomic variables and their operations.
+ * - @ref PJ_CRIT_SEC
+ *\n
+ * Fast locking of critical sections.
+ * - @ref PJ_LOCK
+ *\n
+ * High level abstraction for lock objects.
+ * - @ref PJ_EVENT
+ *\n
+ * Event object.
+ * - @ref PJ_TIME
+ *\n
+ * Portable time manipulation.
+ * - @ref PJ_TIMESTAMP
+ *\n
+ * High resolution time value.
+ * - etc.
+ *
+ *
+ * @subsection ll_network_io_sec Low-Level Network I/O
+ *
+ * PJLIB has very portable abstraction and fairly complete set of API for
+ * doing network I/O communications. At the lowest level, PJLIB provides:
+ *
+ * - @ref PJ_SOCK
+ *\n
+ * A highly portable socket abstraction, runs on all kind of
+ * network APIs such as standard BSD socket, Windows socket, Linux
+ * \b kernel socket, PalmOS networking API, etc.
+ *
+ * - @ref pj_addr_resolve
+ *\n
+ * Portable address resolution, which implements #pj_gethostbyname().
+ *
+ * - @ref PJ_SOCK_SELECT
+ *\n
+ * A portable \a select() like API (#pj_sock_select()) which can be
+ * implemented with various back-end.
+ *
+ *
+ *
+ * @subsection timer_mgmt_sec Timer Management
+ *
+ * A passive framework for managing timer, see @ref PJ_TIMER for more info.
+ * There is also function to retrieve high resolution timestamp
+ * from the system (see @ref PJ_TIMESTAMP).
+ *
+ *
+ * @subsection data_struct_sec Various Data Structures
+ *
+ * Various data structures are provided in the library:
+ *
+ * - @ref PJ_PSTR
+ * - @ref PJ_ARRAY
+ * - @ref PJ_HASH
+ * - @ref PJ_LIST
+ * - @ref PJ_RBTREE
+ *
+ *
+ * @subsection exception_sec Exception Construct
+ *
+ * A convenient TRY/CATCH like construct to propagate errors, which by
+ * default are used by the @ref PJ_POOL_GROUP "memory pool" and
+ * the lexical scanner in pjlib-util. The exception
+ * construct can be used to write programs like below:
+ *
+ * <pre>
+ * #define SYNTAX_ERROR 1
+ *
+ * PJ_TRY {
+ * msg = NULL;
+ * msg = parse_msg(buf, len);
+ * }
+ * PJ_CATCH ( SYNTAX_ERROR ) {
+ * .. handle error ..
+ * }
+ * PJ_END;
+ * </pre>
+ *
+ * Please see @ref PJ_EXCEPT for more information.
+ *
+ *
+ * @subsection logging_sec Logging Facility
+ *
+ * PJLIB @ref PJ_LOG consists of macros to write logging information to
+ * some output device. Some of the features of the logging facility:
+ *
+ * - the verbosity can be fine-tuned both at compile time (to control
+ * the library size) or run-time (to control the verbosity of the
+ * information).
+ * - output device is configurable (e.g. stdout, printk, file, etc.)
+ * - log decoration is configurable.
+ *
+ * See @ref PJ_LOG for more information.
+ *
+ *
+ * @subsection guid_gen_sec Random and GUID Generation
+ *
+ * PJLIB provides facility to create random string
+ * (#pj_create_random_string()) or globally unique identifier
+ * (see @ref PJ_GUID).
+ *
+ *
+ *
+ * @section configure_app_sec Configuring Application to use PJLIB
+ *
+ * @subsection pjlib_compil_sec Building PJLIB
+ *
+ * Follow the instructions in \ref pjlib_build_sys_pg to build
+ * PJLIB.
+ *
+ * @subsection pjlib_compil_app_sec Building Applications with PJLIB
+ *
+ * Use the following settings when building applications with PJLIB.
+ *
+ * @subsubsection compil_inc_dir_sec Include Search Path
+ *
+ * Add this to your include search path ($PJLIB is PJLIB root directory):
+ * <pre>
+ * $PJLIB/include
+ * </pre>
+ *
+ * @subsubsection compil_inc_file_sec Include PJLIB Header
+ *
+ * To include all PJLIB headers:
+ * \verbatim
+ #include <pjlib.h>
+ \endverbatim
+ *
+ * Alternatively, you can include individual PJLIB headers like this:
+ * \verbatim
+ #include <pj/log.h>
+ #include <pj/os.h>
+ \endverbatim
+ *
+ *
+ * @subsubsection compil_lib_dir_sec Library Path
+ *
+ * Add this to your library search path:
+ * <pre>
+ * $PJLIB/lib
+ * </pre>
+ *
+ * Then add the appropriate PJLIB library to your link specification. For
+ * example, you would add \c libpj-i386-linux-gcc.a when you're building
+ * applications in Linux.
+ *
+ *
+ * @subsection pjlib_fundamentals_sec Principles in Using PJLIB
+ *
+ * Few things that you \b MUST do when using PJLIB, to make sure that
+ * you create trully portable applications.
+ *
+ * @subsubsection call_pjlib_init_sec Call pj_init()
+ *
+ * Before you do anything else, call \c pj_init(). This would make sure that
+ * PJLIB system is properly set up.
+ *
+ * @subsubsection no_ansi_subsec Do NOT Use ANSI C
+ *
+ * Contrary to popular teaching, ANSI C (and LIBC) is not the most portable
+ * library in the world, nor it's the most ubiquitous. For example, LIBC
+ * is not available in Linux kernel. Also normally LIBC will be excluded
+ * from compilation of RTOSes to reduce size.
+ *
+ * So for maximum portability, do NOT use ANSI C. Do not even try to include
+ * any other header files outside <include/pj>. Stick with the functionalities
+ * provided by PJLIB.
+ *
+ *
+ * @subsubsection string_rep_subsubsec Use pj_str_t instead of C Strings
+ *
+ * PJLIB uses pj_str_t instead of normal C strings. You SHOULD follow this
+ * convention too. Remember, ANSI string-h is not always available. And
+ * PJLIB string is faster!
+ *
+ * @subsubsection mem_alloc_subsubsec Use Pool for Memory Allocations
+ *
+ * You MUST NOT use \a malloc() or any other memory allocation functions.
+ * Use PJLIB @ref PJ_POOL_GROUP instead! It's faster and most portable.
+ *
+ * @subsection logging_subsubsec Use Logging for Text Display
+ *
+ * DO NOT use <stdio.h> for text output. Use PJLIB @ref PJ_LOG instead.
+ *
+ *
+ * @section porting_pjlib_sec0 Porting PJLIB
+ *
+ * Please see \ref porting_pjlib_pg page on more information to port
+ * PJLIB to new target.
+ *
+ * @section enjoy_sec Enjoy Using PJLIB!
+ *
+ * We hope that you find PJLIB usefull for your application. If you
+ * have any questions, suggestions, critics, bug fixes, or anything
+ * else, we would be happy to hear it.
+ *
+ * Enjoy using PJLIB!
+ *
+ * Benny Prijono < bennylp at pjsip dot org >
+ */
+
+
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+ CODING CONVENTION
+ */
+
+/**
+ * @page pjlib_coding_convention_page Coding Convention
+ *
+ * Before you submit your code/patches to be included with PJLIB, you must
+ * make sure that your code is compliant with PJLIB coding convention.
+ * <b>This is very important!</b> Otherwise we would not accept your code.
+ *
+ * @section coding_conv_editor_sec Editor Settings
+ *
+ * The single most important thing in the whole coding convention is editor
+ * settings. It's more important than the correctness of your code (bugs will
+ * only crash the system, but incorrect tab size is mental!).
+ *
+ * Kindly set your editor as follows:
+ * - tab size to \b 8.
+ * - indentation to \b 4.
+ *
+ * With \c vi, you can do it with:
+ * <pre>
+ * :se ts=8
+ * :se sts=4
+ * </pre>
+ *
+ * You should replace tab with eight spaces.
+ *
+ * @section coding_conv_detail_sec Coding Style
+ *
+ * Coding style MUST strictly follow K&R style. The rest of coding style
+ * must follow current style. You SHOULD be able to observe the style
+ * currently used by PJLIB from PJLIB sources, and apply the style to your
+ * code. If you're not able to do simple thing like to observe PJLIB
+ * coding style from the sources, then logic dictates that your ability to
+ * observe more difficult area in PJLIB such as memory allocation strategy,
+ * concurrency, etc is questionable.
+ *
+ * @section coding_conv_comment_sec Commenting Your Code
+ *
+ * Public API (e.g. in header files) MUST have doxygen compliant comments.
+ *
+ */
+
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+ BUILDING AND INSTALLING PJLIB
+ */
+
+
+
+/**
+ * @page pjlib_build_sys_pg Building, and Installing PJLIB
+ *
+ * @section build_sys_install_sec Build and Installation
+ *
+ * \note
+ * <b>The most up-to-date information on building and installing PJLIB
+ * should be found in the website, under "Getting Started" document.
+ * More over, the new PJLIB build system is now based on autoconf,
+ * so some of the information here might not be relevant anymore
+ * (although most still are, since the autoconf script still use
+ * the old Makefile system as the backend).</b>
+ *
+ * @subsection build_sys_install_win32_sec Visual Studio
+ *
+ * The PJLIB Visual Studio workspace supports the building of PJLIB
+ * for Win32 target. Although currently only the Visual Studio 6 Workspace is
+ * actively maintained, developers with later version of Visual Studio
+ * can easily imports VS6 workspace into their IDE.
+ *
+ * To start building PJLIB projects with Visual Studio 6 or later, open
+ * the \a workspace file in the corresponding \b \c build directory. You have
+ * several choices on which \a dsw file to open:
+ \verbatim
+ $PJPROJECT/pjlib/build/pjlib.dsw
+ $PJPROJECT/pjsip/build/pjsip.dsw
+ ..etc
+ \endverbatim
+ *
+ * The easiest way is to open <tt>pjsip_apps.dsw</tt> file in \b \c $PJPROJECT/pjsip-apps/build
+ * directory, and build pjsua project or the samples project.
+ * However this will not build the complete projects.
+ * For example, the PJLIB test is not included in this workspace.
+ * To build the complete projects, you must
+ * open and build each \a dsw file in \c build directory in each
+ * subprojects. For example, to open the complete PJLIB workspace, open
+ * <tt>pjlib.dsw</tt> in <tt>$PJPROJECT/pjlib/build</tt> directory.
+ *
+ *
+ * @subsubsection config_site_create_vc_sec Create config_site.h
+ *
+ * The file <tt><b>$PJPROJECT/pjlib/include/pj/config_site.h</b></tt>
+ * is supposed to contain configuration that is specific to your site/target.
+ * This file is not part of PJLIB, so you must create it yourself. Normally
+ * you just need to create a blank file.
+ *
+ * The reason why it's not included in PJLIB is so that you would not accidently
+ * overwrite your site configuration.
+ *
+ * If you fail to do this, Visual C will complain with error like:
+ *
+ * <b>"fatal error C1083: Cannot open include file: 'pj/config_site.h': No such file
+ * or directory"</b>.
+ *
+ * @subsubsection build_vc_subsubsec Build the Projects
+ *
+ * Just hit the build button!
+ *
+ *
+ * @subsection build_sys_install_unix_sec Make System
+ *
+ * For other targets, PJLIB provides a rather comprehensive build system
+ * that uses GNU \a make (and only GNU \a make will work).
+ * Currently, the build system supports building * PJLIB for these targets:
+ * - i386/Win32/mingw
+ * - i386/Linux
+ * - i386/Linux (kernel)
+ * - alpha/linux
+ * - sparc/SunOS
+ * - etc..
+ *
+ *
+ * @subsubsection build_req_sec Requirements
+ *
+ * In order to use the \c make based build system, you MUST have:
+ *
+ * - <b>GNU make</b>
+ *\n
+ * The Makefiles heavily utilize GNU make commands which most likely
+ * are not available in other \c make system.
+ * - <b>bash</b> shell is recommended.
+ *\n
+ * Specificly, there is a command <tt>"echo -n"</tt> which may not work
+ * in other shells. This command is used when generating dependencies
+ * (<tt>make dep</tt>) and it's located in
+ * <tt>$PJPROJECT/build/rules.mak</tt>.
+ * - <b>ar</b>, <b>ranlib</b> from GNU binutils
+ *\n
+ * In your system has different <tt>ar</tt> or <tt>ranlib</tt> (e.g. they
+ * may have been installed as <tt>gar</tt> and <tt>granlib</tt>), then
+ * either you create the relevant symbolic links, <b>or</b> modify
+ * <tt>$PJPROJECT/build/cc-gcc.mak</tt> and rename <tt>ar</tt> and
+ * <tt>ranlib</tt> to the appropriate names.
+ * - <b>gcc</b> to generate dependency.
+ *\n
+ * Currently the build system uses <tt>"gcc -MM"</tt> to generate build
+ * dependencies. If <tt>gcc</tt> is not desired to generate dependency,
+ * then either you don't run <tt>make dep</tt>, <b>or</b> edit
+ * <tt>$PJPROJECT/build/rules.mak</tt> to calculate dependency using
+ * your prefered method. (And let me know when you do so so that I can
+ * update the file. :) )
+ *
+ * @subsubsection build_overview_sec Building the Project
+ *
+ * Generally, steps required to build the PJLIB are:
+ *
+ \verbatim
+ $ cd /home/user/pjproject
+ $ ./configure
+ $ touch pjlib/include/pj/config_site.h
+ $ make dep
+ $ make
+ \endverbatim
+ *
+ * The above process will build all static libraries and all applications.
+ *
+ * \note the <tt>configure</tt> script is not a proper autoconf script,
+ * but rather a simple shell script to detect current host. This script
+ * currently does not support cross-compilation.
+ *
+ * \note For Linux kernel target, there are additional steps required, which
+ * will be explained in section \ref linux_kern_target_subsec.
+ *
+ * @subsubsection build_mak_sec Cross Compilation
+ *
+ * For cross compilation, you will need to edit the \c build.mak file in
+ * \c $PJPROJECT root directory manually. Please see <b>README-configure</b> file
+ * in the root directory for more information.
+ *
+ * For Linux kernel target, you are also required to declare the following
+ * variables in this file:
+ * - \c KERNEL_DIR: full path of kernel source tree.
+ * - \c KERNEL_ARCH: kernel ARCH options (e.g. "ARCH=um"), or leave blank
+ * for default.
+ * - \c PJPROJECT_DIR: full path of PJPROJECT source tree.
+ *
+ * Apart from these, there are also additional steps required to build
+ * Linux kernel target, which will be explained in \ref linux_kern_target_subsec.
+ *
+ * @subsubsection build_dir_sec Files in "build" Directory
+ *
+ * The <tt>*.mak</tt> files in \c $PJPROJECT/build directory are used to specify
+ * the configuration for the specified compiler, target machine target
+ * operating system, and host options. These files will be executed
+ * (included) by \a make during building process, depending on the values
+ * specified in <b>$PJPROJECT/build.mak</b> file.
+ *
+ * Normally you don't need to edit these files, except when you're porting
+ * PJLIB to new target.
+ *
+ * Below are the description of some files in this directory:
+ *
+ * - <tt>rules.mak</tt>: contains generic rules always included during make.
+ * - <tt>cc-gcc.mak</tt>: rules when gcc is used for compiler.
+ * - <tt>cc-vc.mak</tt>: rules when MSVC compiler is used.
+ * - <tt>host-mingw.mak</tt>: rules for building in mingw host.
+ * - <tt>host-unix.mak</tt>: rules for building in Unix/Posix host.
+ * - <tt>host-win32.mak</tt>: rules for building in Win32 command console
+ * (only valid when VC is used).
+ * - <tt>m-i386.mak</tt>: rules when target machine is an i386 processor.
+ * - <tt>m-m68k.mak</tt>: rules when target machine is an m68k processor.
+ * - <tt>os-linux.mak</tt>: rules when target OS is Linux.
+ * - <tt>os-linux-kernel.mak</tt>: rules when PJLIB is to be build as
+ * part of Linux kernel.
+ * - <tt>os-win32.mak</tt>: rules when target OS is Win32.
+ *
+ *
+ * @subsubsection config_site_create_sec Create config_site.h
+ *
+ * The file <tt><b>$PJPROJECT/pjlib/include/pj/config_site.h</b></tt>
+ * is supposed to contain configuration that is specific to your site/target.
+ * This file is not part of PJLIB, so you must create it yourself.
+ *
+ * The reason why it's not included in PJLIB is so that you would not accidently
+ * overwrite your site configuration.
+ *
+ *
+ * @subsubsection invoking_make_sec Invoking make
+ *
+ * Normally, \a make is invoked in \c build directory under each project.
+ * For example, to build PJLIB, you would invoke \a make in
+ * \c $PJPROJECT/pjlib/build directory like below:
+ *
+ \verbatim
+ $ cd pjlib/build
+ $ make
+ \endverbatim
+ *
+ * Alternatively you may invoke <tt>make</tt> in <tt>$PJPROJECT</tt>
+ * directory, to build all projects under that directory (e.g.
+ * PJLIB, PJSIP, etc.).
+ *
+ *
+ * @subsubsection linux_kern_target_subsec Linux Kernel Target
+ *
+ * \note
+ * <b>BUILDING APPLICATIONS IN LINUX KERNEL MODE IS A VERY DANGEROUS BUSINESS.
+ * YOU MAY CRASH THE WHOLE OF YOUR SYSTEM, CORRUPT YOUR HARDISK, ETC. PJLIB
+ * KERNEL MODULES ARE STILL IN EXPERIMENTAL PHASE. DO NOT RUN IT IN PRODUCTION
+ * SYSTEMS OR OTHER SYSTEMS WHERE RISK OF LOSS OF DATA IS NOT ACCEPTABLE.
+ * YOU HAVE BEEN WARNED.</b>
+ *
+ * \note
+ * <b>User Mode Linux (UML)</b> provides excellent way to experiment with Linux
+ * kernel without risking the stability of the host system. See
+ * http://user-mode-linux.sourceforge.net for details.
+ *
+ * \note
+ * I only use <b>UML</b> to experiment with PJLIB kernel modules.
+ * <b>I wouldn't be so foolish to use my host Linux machine to experiment
+ * with this.</b>
+ *
+ * \note
+ * You have been warned.
+ *
+ * For building PJLIB for Linux kernel target, there are additional steps required.
+ * In general, the additional tasks are:
+ * - Declare some more variables in <b><tt>build.mak</tt></b> file (this
+ * has been explained in \ref build_mak_sec above).
+ * - Perform these two small modifications in kernel source tree.
+ *
+ * There are two small modification need to be applied to the kernel tree.
+ *
+ * <b>1. Edit <tt>Makefile</tt> in kernel root source tree.</b>
+ *
+ * Add the following lines at the end of the <tt>Makefile</tt> in your
+ * <tt>$KERNEL_SRC</tt> dir:
+ \verbatim
+script:
+ $(SCRIPT)
+ \endverbatim
+ *
+ * \note Remember to replace spaces with <b>tab</b> in the Makefile.
+ *
+ * The modification above is needed to capture kernel's \c $CFLAGS and
+ * \c $CFLAGS_MODULE which will be used for PJLIB's compilation.
+ *
+ * <b>2. Add Additional Exports.</b>
+ *
+ * We need the kernel to export some more symbols for our use. So we declare
+ * the additional symbols to be exported in <tt>extra-exports.c</tt> file, and add
+ * a this file to be compiled into the kernel:
+ *
+ * - Copy the file <tt>extra-exports.c</tt> from <tt>pjlib/src/pj</tt>
+ * directory to <tt>$KERNEL_SRC/kernel/</tt> directory.
+ * - Edit <tt>Makefile</tt> in that directory, and add this line
+ * somewhere after the declaration of that variable:
+ \verbatim
+obj-y += extra-exports.o
+ \endverbatim
+ *
+ * To illustrate what have been done in your kernel source tree, below
+ * is screenshot of my kernel source tree _after_ the modification.
+ *
+ \verbatim
+[root@vpc-linux linux-2.6.7]# pwd
+/usr/src/linux-2.6.7
+[root@vpc-linux linux-2.6.7]#
+[root@vpc-linux linux-2.6.7]#
+[root@vpc-linux linux-2.6.7]# tail Makefile
+
+endif # skip-makefile
+
+FORCE:
+
+.PHONY: script
+
+script:
+ $(SCRIPT)
+
+[root@vpc-linux linux-2.6.7]#
+[root@vpc-linux linux-2.6.7]#
+[root@vpc-linux linux-2.6.7]# head kernel/extra-exports.c
+#include <linux/module.h>
+#include <linux/syscalls.h>
+
+EXPORT_SYMBOL(sys_select);
+
+EXPORT_SYMBOL(sys_epoll_create);
+EXPORT_SYMBOL(sys_epoll_ctl);
+EXPORT_SYMBOL(sys_epoll_wait);
+
+EXPORT_SYMBOL(sys_socket);
+[root@vpc-linux linux-2.6.7]#
+[root@vpc-linux linux-2.6.7]#
+[root@vpc-linux linux-2.6.7]# head -15 kernel/Makefile
+#
+# Makefile for the linux kernel.
+#
+
+obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
+ exit.o itimer.o time.o softirq.o resource.o \
+ sysctl.o capability.o ptrace.o timer.o user.o \
+ signal.o sys.o kmod.o workqueue.o pid.o \
+ rcupdate.o intermodule.o extable.o params.o posix-timers.o \
+ kthread.o
+
+obj-y += extra-exports.o
+
+obj-$(CONFIG_FUTEX) += futex.o
+obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
+[root@vpc-linux linux-2.6.7]#
+
+ \endverbatim
+ *
+ * Then you must rebuild the kernel.
+ * If you fail to do this, you won't be able to <b>insmod</b> pjlib.
+ *
+ * \note You will see a lots of warning messages during pjlib-test compilation.
+ * The warning messages complain about unresolved symbols which are defined
+ * in pjlib module. You can safely ignore these warnings. However, you can not
+ * ignore warnings about non-pjlib unresolved symbols.
+ *
+ *
+ * @subsection makefile_explained_sec Makefile Explained
+ *
+ * The \a Makefile for each project (e.g. PJLIB, PJSIP, etc) should be
+ * very similar in the contents. The Makefile is located under \c build
+ * directory in each project subdir.
+ *
+ * @subsubsection pjlib_makefile_subsec PJLIB Makefile.
+ *
+ * Below is PJLIB's Makefile:
+ *
+ * \include build/Makefile
+ *
+ * @subsubsection pjlib_os_makefile_subsec PJLIB os-linux.mak.
+ *
+ * Below is file <tt><b>os-linux.mak</b></tt> file in
+ * <tt>$PJPROJECT/pjlib/build</tt> directory,
+ * which is OS specific configuration file for Linux target that is specific
+ * for PJLIB project. For \b global OS specific configuration, please see
+ * <tt>$PJPROJECT/build/os-*.mak</tt>.
+ *
+ * \include build/os-linux.mak
+ *
+ */
+
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+ PORTING PJLIB
+ */
+
+
+
+/**
+ * @page porting_pjlib_pg Porting PJLIB
+ *
+ * \note
+ * <b>Since version 0.5.8, PJLIB build system is now based on autoconf, so
+ * most of the time we shouldn't need to apply the tweakings below to get
+ * PJLIB working on a new platform. However, since the autoconf build system
+ * still uses the old Makefile build system, the information below may still
+ * be useful for reference.
+ * </b>
+ *
+ * @section new_arch_sec Porting to New CPU Architecture
+ *
+ * Below is step-by-step guide to add support for new CPU architecture.
+ * This sample is based on porting to Alpha architecture; however steps for
+ * porting to other CPU architectures should be pretty similar.
+ *
+ * Also note that in this example, the operating system used is <b>Linux</b>.
+ * Should you wish to add support for new operating system, then follow
+ * the next section \ref porting_os_sec.
+ *
+ * Step-by-step guide to port to new CPU architecture:
+ * - decide the name for the new architecture. In this case, we choose
+ * <tt><b>alpha</b></tt>.
+ * - edit file <tt>$PJPROJECT/build.mak</tt>, and add new section for
+ * the new target:
+ * <pre>
+ * #
+ * # Linux alpha, gcc
+ * #
+ * export MACHINE_NAME := <b>alpha</b>
+ * export OS_NAME := linux
+ * export CC_NAME := gcc
+ * export HOST_NAME := unix
+ * </pre>
+ *
+ * - create a new file <tt>$PJPROJECT/build/<b>m-alpha</b>.mak</tt>.
+ * Alternatively create a copy from other file in this directory.
+ * The contents of this file will look something like:
+ * <pre>
+ * export M_CFLAGS := $(CC_DEF)<b>PJ_M_ALPHA=1</b>
+ * export M_CXXFLAGS :=
+ * export M_LDFLAGS :=
+ * export M_SOURCES :=
+ * </pre>
+ * - create a new file <tt>$PJPROJECT/pjlib/include/pj/compat/<b>m_alpha.h</b></tt>.
+ * Alternatively create a copy from other header file in this directory.
+ * The contents of this file will look something like:
+ * <pre>
+ * #define PJ_HAS_PENTIUM 0
+ * #define PJ_IS_LITTLE_ENDIAN 1
+ * #define PJ_IS_BIG_ENDIAN 0
+ * </pre>
+ * - edit <tt>pjlib/include/pj/<b>config.h</b></tt>. Add new processor
+ * configuration in this header file, like follows:
+ * <pre>
+ * ...
+ * #elif defined (PJ_M_ALPHA) && PJ_M_ALPHA != 0
+ * # include <pj/compat/m_alpha.h>
+ * ...
+ * </pre>
+ * - done. Build PJLIB with:
+ * <pre>
+ * $ cd $PJPROJECT/pjlib/build
+ * $ make dep
+ * $ make clean
+ * $ make
+ * </pre>
+ *
+ * @section porting_os_sec Porting to New Operating System Target
+ *
+ * This section will try to give you rough guideline on how to
+ * port PJLIB to a new target. As a sample, we give the target a name tag,
+ * for example <tt><b>xos</b></tt> (for X OS).
+ *
+ * @subsection new_compat_os_h_file_sec Create New Compat Header File
+ *
+ * You'll need to create a new header file
+ * <b><tt>include/pj/compat/os_xos.h</tt></b>. You can copy as a
+ * template other header file and edit it accordingly.
+ *
+ * @subsection modify_config_h_file_sec Modify config.h
+ *
+ * Then modify file <b><tt>include/pj/config.h</tt></b> to include
+ * this file accordingly (e.g. when macro <tt><b>PJ_XOS</b></tt> is
+ * defined):
+ *
+ \verbatim
+ ...
+ #elif defined(PJ_XOS)
+ # include <pj/compat/os_xos.h>
+ #else
+ #...
+ \endverbatim
+ *
+ * @subsection new_target_mak_file_sec Create New Global Make Config File
+ *
+ * Then you'll need to create global configuration file that
+ * is specific for this OS, i.e. <tt><b>os-xos.mak</b></tt> in
+ * <tt><b>$PJPROJECT/build</b></tt> directory.
+ *
+ * At very minimum, the file will normally need to define
+ * <tt><b>PJ_XOS=1</b></tt> in the \c CFLAGS section:
+ *
+ \verbatim
+#
+# $PJPROJECT/build/os-xos.mak:
+#
+export OS_CFLAGS := $(CC_DEF)PJ_XOS=1
+export OS_CXXFLAGS :=
+export OS_LDFLAGS :=
+export OS_SOURCES :=
+ \endverbatim
+ *
+ *
+ * @subsection new_target_prj_mak_file_sec Create New Project's Make Config File
+ *
+ * Then you'll need to create xos-specific configuration file
+ * for PJLIB. This file is also named <tt><b>os-xos.mak</b></tt>,
+ * but its located in <tt><b>pjlib/build</b></tt> directory.
+ * This file will specify source files that are specific to
+ * this OS to be included in the build process.
+ *
+ * Below is a sample:
+ \verbatim
+#
+# pjlib/build/os-xos.mak:
+# XOS specific configuration for PJLIB.
+#
+export PJLIB_OBJS += os_core_xos.o \
+ os_error_unix.o \
+ os_time_ansi.o
+export TEST_OBJS += main.o
+export TARGETS = pjlib pjlib-test
+ \endverbatim
+ *
+ * @subsection new_target_src_sec Create and Edit Source Files
+ *
+ * You'll normally need to create at least these files:
+ * - <tt><b>os_core_xos.c</b></tt>: core OS specific
+ * functionality.
+ * - <tt><b>os_timestamp_xos.c</b></tt>: how to get timestamp
+ * in this OS.
+ *
+ * Depending on how things are done in your OS, you may need
+ * to create these files:
+ * - <tt><b>os_error_*.c</b></tt>: how to manipulate
+ * OS error codes. Alternatively you may use existing
+ * <tt>os_error_unix.c</tt> if the OS has \c errno and
+ * \c strerror() function.
+ * - <tt><b>ioqueue_*.c</b></tt>: if the OS has specific method
+ * to perform asynchronous I/O. Alternatively you may
+ * use existing <tt>ioqueue_select.c</tt> if the OS supports
+ * \c select() function call.
+ * - <tt><b>sock_*.c</b></tt>: if the OS has specific method
+ * to perform socket communication. Alternatively you may
+ * use existing <tt>sock_bsd.c</tt> if the OS supports
+ * BSD socket API, and edit <tt>include/pj/compat/socket.h</tt>
+ * file accordingly.
+ *
+ * You will also need to check various files in
+ * <tt><b>include/pj/compat/*.h</b></tt>, to see if they're
+ * compatible with your OS.
+ *
+ * @subsection new_target_build_file_sec Build The Project
+ *
+ * After basic building blocks have been created for the OS, then
+ * the easiest way to see which parts need to be fixed is by building
+ * the project and see the error messages.
+ *
+ * @subsection new_target_edit_vs_new_file_sec Editing Existing Files vs Creating New File
+ *
+ * When you encounter compatibility errors in PJLIB during porting,
+ * you have three options on how to fix the error:
+ * - edit the existing <tt>*.c</tt> file, and give it <tt>#ifdef</tt>
+ * switch for the new OS, or
+ * - edit <tt>include/pj/compat/*.h</tt> instead, or
+ * - create a totally new file.
+ *
+ * Basicly there is no strict rule on which approach is the best
+ * to use, however the following guidelines may be used:
+ * - if the file is expected to be completely different than
+ * any existing file, then perhaps you should create a completely
+ * new file. For example, file <tt>os_core_xxx.c</tt> will
+ * normally be different for each OS flavour.
+ * - if the difference can be localized in <tt>include/compat</tt>
+ * header file, and existing <tt>#ifdef</tt> switch is there,
+ * then preferably you should edit this <tt>include/compat</tt>
+ * header file.
+ * - if the existing <tt>*.c</tt> file has <tt>#ifdef</tt> switch,
+ * then you may add another <tt>#elif</tt> switch there. This
+ * normally is used for behaviors that are not totally
+ * different on each platform.
+ * - other than that above, use your own judgement on whether
+ * to edit the file or create new file etc.
+ */
+
+#endif /* __PJ_DOXYGEN_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/errno.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/errno.h
new file mode 100644
index 0000000..7b163d6
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/errno.h
@@ -0,0 +1,575 @@
+/* $Id: errno.h 2992 2009-11-09 04:09:13Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_ERRNO_H__
+#define __PJ_ERRNO_H__
+
+/**
+ * @file errno.h
+ * @brief PJLIB Error Subsystem
+ */
+#include <pj/types.h>
+#include <pj/compat/errno.h>
+#include <stdarg.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup pj_errno Error Subsystem
+ * @{
+ *
+ * The PJLIB Error Subsystem is a framework to unify all error codes
+ * produced by all components into a single error space, and provide
+ * uniform set of APIs to access them. With this framework, any error
+ * codes are encoded as pj_status_t value. The framework is extensible,
+ * application may register new error spaces to be recognized by
+ * the framework.
+ *
+ * @section pj_errno_retval Return Values
+ *
+ * All functions that returns @a pj_status_t returns @a PJ_SUCCESS if the
+ * operation was completed successfully, or non-zero value to indicate
+ * error. If the error came from operating system, then the native error
+ * code is translated/folded into PJLIB's error namespace by using
+ * #PJ_STATUS_FROM_OS() macro. The function will do this automatically
+ * before returning the error to caller.
+ *
+ * @section err_services Retrieving and Displaying Error Messages
+ *
+ * The framework provides the following APIs to retrieve and/or display
+ * error messages:
+ *
+ * - #pj_strerror(): this is the base API to retrieve error string
+ * description for the specified pj_status_t error code.
+ *
+ * - #PJ_PERROR() macro: use this macro similar to PJ_LOG to format
+ * an error message and display them to the log
+ *
+ * - #pj_perror(): this function is similar to PJ_PERROR() but unlike
+ * #PJ_PERROR(), this function will always be included in the
+ * link process. Due to this reason, prefer to use #PJ_PERROR()
+ * if the application is concerned about the executable size.
+ *
+ * Application MUST NOT pass native error codes (such as error code from
+ * functions like GetLastError() or errno) to PJLIB functions expecting
+ * @a pj_status_t.
+ *
+ * @section err_extending Extending the Error Space
+ *
+ * Application may register new error space to be recognized by the
+ * framework by using #pj_register_strerror(). Use the range started
+ * from PJ_ERRNO_START_USER to avoid conflict with existing error
+ * spaces.
+ *
+ */
+
+/**
+ * Guidelines on error message length.
+ */
+#define PJ_ERR_MSG_SIZE 80
+
+/**
+ * Buffer for title string of #PJ_PERROR().
+ */
+#ifndef PJ_PERROR_TITLE_BUF_SIZE
+# define PJ_PERROR_TITLE_BUF_SIZE 120
+#endif
+
+
+/**
+ * Get the last platform error/status, folded into pj_status_t.
+ * @return OS dependent error code, folded into pj_status_t.
+ * @remark This function gets errno, or calls GetLastError() function and
+ * convert the code into pj_status_t with PJ_STATUS_FROM_OS. Do
+ * not call this for socket functions!
+ * @see pj_get_netos_error()
+ */
+PJ_DECL(pj_status_t) pj_get_os_error(void);
+
+/**
+ * Set last error.
+ * @param code pj_status_t
+ */
+PJ_DECL(void) pj_set_os_error(pj_status_t code);
+
+/**
+ * Get the last error from socket operations.
+ * @return Last socket error, folded into pj_status_t.
+ */
+PJ_DECL(pj_status_t) pj_get_netos_error(void);
+
+/**
+ * Set error code.
+ * @param code pj_status_t.
+ */
+PJ_DECL(void) pj_set_netos_error(pj_status_t code);
+
+
+/**
+ * Get the error message for the specified error code. The message
+ * string will be NULL terminated.
+ *
+ * @param statcode The error code.
+ * @param buf Buffer to hold the error message string.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pj_strerror( pj_status_t statcode,
+ char *buf, pj_size_t bufsize);
+
+/**
+ * A utility macro to print error message pertaining to the specified error
+ * code to the log. This macro will construct the error message title
+ * according to the 'title_fmt' argument, and add the error string pertaining
+ * to the error code after the title string. A colon (':') will be added
+ * automatically between the title and the error string.
+ *
+ * This function is similar to pj_perror() function, but has the advantage
+ * that the function call can be omitted from the link process if the
+ * log level argument is below PJ_LOG_MAX_LEVEL threshold.
+ *
+ * Note that the title string constructed from the title_fmt will be built on
+ * a string buffer which size is PJ_PERROR_TITLE_BUF_SIZE, which normally is
+ * allocated from the stack. By default this buffer size is small (around
+ * 120 characters). Application MUST ensure that the constructed title string
+ * will not exceed this limit, since not all platforms support truncating
+ * the string.
+ *
+ * @see pj_perror()
+ *
+ * @param level The logging verbosity level, valid values are 0-6. Lower
+ * number indicates higher importance, with level zero
+ * indicates fatal error. Only numeral argument is
+ * permitted (e.g. not variable).
+ * @param arg Enclosed 'printf' like arguments, with the following
+ * arguments:
+ * - the sender (NULL terminated string),
+ * - the error code (pj_status_t)
+ * - the format string (title_fmt), and
+ * - optional variable number of arguments suitable for the
+ * format string.
+ *
+ * Sample:
+ * \verbatim
+ PJ_PERROR(2, (__FILE__, PJ_EBUSY, "Error making %s", "coffee"));
+ \endverbatim
+ * @hideinitializer
+ */
+#define PJ_PERROR(level,arg) do { \
+ pj_perror_wrapper_##level(arg); \
+ } while (0)
+
+/**
+ * A utility function to print error message pertaining to the specified error
+ * code to the log. This function will construct the error message title
+ * according to the 'title_fmt' argument, and add the error string pertaining
+ * to the error code after the title string. A colon (':') will be added
+ * automatically between the title and the error string.
+ *
+ * Unlike the PJ_PERROR() macro, this function takes the \a log_level argument
+ * as a normal argument, unlike in PJ_PERROR() where a numeral value must be
+ * given. However this function will always be linked to the executable,
+ * unlike PJ_PERROR() which can be omitted when the level is below the
+ * PJ_LOG_MAX_LEVEL.
+ *
+ * Note that the title string constructed from the title_fmt will be built on
+ * a string buffer which size is PJ_PERROR_TITLE_BUF_SIZE, which normally is
+ * allocated from the stack. By default this buffer size is small (around
+ * 120 characters). Application MUST ensure that the constructed title string
+ * will not exceed this limit, since not all platforms support truncating
+ * the string.
+ *
+ * @see PJ_PERROR()
+ */
+PJ_DECL(void) pj_perror(int log_level, const char *sender, pj_status_t status,
+ const char *title_fmt, ...);
+
+
+/**
+ * Type of callback to be specified in #pj_register_strerror()
+ *
+ * @param e The error code to lookup.
+ * @param msg Buffer to store the error message.
+ * @param max Length of the buffer.
+ *
+ * @return The error string.
+ */
+typedef pj_str_t (*pj_error_callback)(pj_status_t e, char *msg, pj_size_t max);
+
+
+/**
+ * Register strerror message handler for the specified error space.
+ * Application can register its own handler to supply the error message
+ * for the specified error code range. This handler will be called
+ * by #pj_strerror().
+ *
+ * @param start_code The starting error code where the handler should
+ * be called to retrieve the error message.
+ * @param err_space The size of error space. The error code range then
+ * will fall in start_code to start_code+err_space-1
+ * range.
+ * @param f The handler to be called when #pj_strerror() is
+ * supplied with error code that falls into this range.
+ *
+ * @return PJ_SUCCESS or the specified error code. The
+ * registration may fail when the error space has been
+ * occupied by other handler, or when there are too many
+ * handlers registered to PJLIB.
+ */
+PJ_DECL(pj_status_t) pj_register_strerror(pj_status_t start_code,
+ pj_status_t err_space,
+ pj_error_callback f);
+
+/**
+ * @hideinitializer
+ * Return platform os error code folded into pj_status_t code. This is
+ * the macro that is used throughout the library for all PJLIB's functions
+ * that returns error from operating system. Application may override
+ * this macro to reduce size (e.g. by defining it to always return
+ * #PJ_EUNKNOWN).
+ *
+ * Note:
+ * This macro MUST return non-zero value regardless whether zero is
+ * passed as the argument. The reason is to protect logic error when
+ * the operating system doesn't report error codes properly.
+ *
+ * @param os_code Platform OS error code. This value may be evaluated
+ * more than once.
+ * @return The platform os error code folded into pj_status_t.
+ */
+#ifndef PJ_RETURN_OS_ERROR
+# define PJ_RETURN_OS_ERROR(os_code) (os_code ? \
+ PJ_STATUS_FROM_OS(os_code) : -1)
+#endif
+
+
+/**
+ * @hideinitializer
+ * Fold a platform specific error into an pj_status_t code.
+ *
+ * @param e The platform os error code.
+ * @return pj_status_t
+ * @warning Macro implementation; the syserr argument may be evaluated
+ * multiple times.
+ */
+#if PJ_NATIVE_ERR_POSITIVE
+# define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : e + PJ_ERRNO_START_SYS)
+#else
+# define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : PJ_ERRNO_START_SYS - e)
+#endif
+
+/**
+ * @hideinitializer
+ * Fold an pj_status_t code back to the native platform defined error.
+ *
+ * @param e The pj_status_t folded platform os error code.
+ * @return pj_os_err_type
+ * @warning macro implementation; the statcode argument may be evaluated
+ * multiple times. If the statcode was not created by
+ * pj_get_os_error or PJ_STATUS_FROM_OS, the results are undefined.
+ */
+#if PJ_NATIVE_ERR_POSITIVE
+# define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : e - PJ_ERRNO_START_SYS)
+#else
+# define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : PJ_ERRNO_START_SYS - e)
+#endif
+
+
+/**
+ * @defgroup pj_errnum PJLIB's Own Error Codes
+ * @ingroup pj_errno
+ * @{
+ */
+
+/**
+ * Use this macro to generate error message text for your error code,
+ * so that they look uniformly as the rest of the libraries.
+ *
+ * @param code The error code
+ * @param msg The error test.
+ */
+#ifndef PJ_BUILD_ERR
+# define PJ_BUILD_ERR(code,msg) { code, msg " (" #code ")" }
+#endif
+
+
+/**
+ * @hideinitializer
+ * Unknown error has been reported.
+ */
+#define PJ_EUNKNOWN (PJ_ERRNO_START_STATUS + 1) /* 70001 */
+/**
+ * @hideinitializer
+ * The operation is pending and will be completed later.
+ */
+#define PJ_EPENDING (PJ_ERRNO_START_STATUS + 2) /* 70002 */
+/**
+ * @hideinitializer
+ * Too many connecting sockets.
+ */
+#define PJ_ETOOMANYCONN (PJ_ERRNO_START_STATUS + 3) /* 70003 */
+/**
+ * @hideinitializer
+ * Invalid argument.
+ */
+#define PJ_EINVAL (PJ_ERRNO_START_STATUS + 4) /* 70004 */
+/**
+ * @hideinitializer
+ * Name too long (eg. hostname too long).
+ */
+#define PJ_ENAMETOOLONG (PJ_ERRNO_START_STATUS + 5) /* 70005 */
+/**
+ * @hideinitializer
+ * Not found.
+ */
+#define PJ_ENOTFOUND (PJ_ERRNO_START_STATUS + 6) /* 70006 */
+/**
+ * @hideinitializer
+ * Not enough memory.
+ */
+#define PJ_ENOMEM (PJ_ERRNO_START_STATUS + 7) /* 70007 */
+/**
+ * @hideinitializer
+ * Bug detected!
+ */
+#define PJ_EBUG (PJ_ERRNO_START_STATUS + 8) /* 70008 */
+/**
+ * @hideinitializer
+ * Operation timed out.
+ */
+#define PJ_ETIMEDOUT (PJ_ERRNO_START_STATUS + 9) /* 70009 */
+/**
+ * @hideinitializer
+ * Too many objects.
+ */
+#define PJ_ETOOMANY (PJ_ERRNO_START_STATUS + 10)/* 70010 */
+/**
+ * @hideinitializer
+ * Object is busy.
+ */
+#define PJ_EBUSY (PJ_ERRNO_START_STATUS + 11)/* 70011 */
+/**
+ * @hideinitializer
+ * The specified option is not supported.
+ */
+#define PJ_ENOTSUP (PJ_ERRNO_START_STATUS + 12)/* 70012 */
+/**
+ * @hideinitializer
+ * Invalid operation.
+ */
+#define PJ_EINVALIDOP (PJ_ERRNO_START_STATUS + 13)/* 70013 */
+/**
+ * @hideinitializer
+ * Operation is cancelled.
+ */
+#define PJ_ECANCELLED (PJ_ERRNO_START_STATUS + 14)/* 70014 */
+/**
+ * @hideinitializer
+ * Object already exists.
+ */
+#define PJ_EEXISTS (PJ_ERRNO_START_STATUS + 15)/* 70015 */
+/**
+ * @hideinitializer
+ * End of file.
+ */
+#define PJ_EEOF (PJ_ERRNO_START_STATUS + 16)/* 70016 */
+/**
+ * @hideinitializer
+ * Size is too big.
+ */
+#define PJ_ETOOBIG (PJ_ERRNO_START_STATUS + 17)/* 70017 */
+/**
+ * @hideinitializer
+ * Error in gethostbyname(). This is a generic error returned when
+ * gethostbyname() has returned an error.
+ */
+#define PJ_ERESOLVE (PJ_ERRNO_START_STATUS + 18)/* 70018 */
+/**
+ * @hideinitializer
+ * Size is too small.
+ */
+#define PJ_ETOOSMALL (PJ_ERRNO_START_STATUS + 19)/* 70019 */
+/**
+ * @hideinitializer
+ * Ignored
+ */
+#define PJ_EIGNORED (PJ_ERRNO_START_STATUS + 20)/* 70020 */
+/**
+ * @hideinitializer
+ * IPv6 is not supported
+ */
+#define PJ_EIPV6NOTSUP (PJ_ERRNO_START_STATUS + 21)/* 70021 */
+/**
+ * @hideinitializer
+ * Unsupported address family
+ */
+#define PJ_EAFNOTSUP (PJ_ERRNO_START_STATUS + 22)/* 70022 */
+
+/** @} */ /* pj_errnum */
+
+/** @} */ /* pj_errno */
+
+
+/**
+ * PJ_ERRNO_START is where PJLIB specific error values start.
+ */
+#define PJ_ERRNO_START 20000
+
+/**
+ * PJ_ERRNO_SPACE_SIZE is the maximum number of errors in one of
+ * the error/status range below.
+ */
+#define PJ_ERRNO_SPACE_SIZE 50000
+
+/**
+ * PJ_ERRNO_START_STATUS is where PJLIB specific status codes start.
+ * Effectively the error in this class would be 70000 - 119000.
+ */
+#define PJ_ERRNO_START_STATUS (PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
+
+/**
+ * PJ_ERRNO_START_SYS converts platform specific error codes into
+ * pj_status_t values.
+ * Effectively the error in this class would be 120000 - 169000.
+ */
+#define PJ_ERRNO_START_SYS (PJ_ERRNO_START_STATUS + PJ_ERRNO_SPACE_SIZE)
+
+/**
+ * PJ_ERRNO_START_USER are reserved for applications that use error
+ * codes along with PJLIB codes.
+ * Effectively the error in this class would be 170000 - 219000.
+ */
+#define PJ_ERRNO_START_USER (PJ_ERRNO_START_SYS + PJ_ERRNO_SPACE_SIZE)
+
+
+/*
+ * Below are list of error spaces that have been taken so far:
+ * - PJSIP_ERRNO_START (PJ_ERRNO_START_USER)
+ * - PJMEDIA_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE)
+ * - PJSIP_SIMPLE_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*2)
+ * - PJLIB_UTIL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3)
+ * - PJNATH_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4)
+ * - PJMEDIA_AUDIODEV_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*5)
+ */
+
+/* Internal */
+void pj_errno_clear_handlers(void);
+
+
+/****** Internal for PJ_PERROR *******/
+
+/**
+ * @def pj_perror_wrapper_1(arg)
+ * Internal function to write log with verbosity 1. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 1.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 1
+ #define pj_perror_wrapper_1(arg) pj_perror_1 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_perror_1(const char *sender, pj_status_t status,
+ const char *title_fmt, ...);
+#else
+ #define pj_perror_wrapper_1(arg)
+#endif
+
+/**
+ * @def pj_perror_wrapper_2(arg)
+ * Internal function to write log with verbosity 2. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 2.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 2
+ #define pj_perror_wrapper_2(arg) pj_perror_2 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_perror_2(const char *sender, pj_status_t status,
+ const char *title_fmt, ...);
+#else
+ #define pj_perror_wrapper_2(arg)
+#endif
+
+/**
+ * @def pj_perror_wrapper_3(arg)
+ * Internal function to write log with verbosity 3. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 3.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 3
+ #define pj_perror_wrapper_3(arg) pj_perror_3 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_perror_3(const char *sender, pj_status_t status,
+ const char *title_fmt, ...);
+#else
+ #define pj_perror_wrapper_3(arg)
+#endif
+
+/**
+ * @def pj_perror_wrapper_4(arg)
+ * Internal function to write log with verbosity 4. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 4.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 4
+ #define pj_perror_wrapper_4(arg) pj_perror_4 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_perror_4(const char *sender, pj_status_t status,
+ const char *title_fmt, ...);
+#else
+ #define pj_perror_wrapper_4(arg)
+#endif
+
+/**
+ * @def pj_perror_wrapper_5(arg)
+ * Internal function to write log with verbosity 5. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 5.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 5
+ #define pj_perror_wrapper_5(arg) pj_perror_5 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_perror_5(const char *sender, pj_status_t status,
+ const char *title_fmt, ...);
+#else
+ #define pj_perror_wrapper_5(arg)
+#endif
+
+/**
+ * @def pj_perror_wrapper_6(arg)
+ * Internal function to write log with verbosity 6. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 6.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 6
+ #define pj_perror_wrapper_6(arg) pj_perror_6 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_perror_6(const char *sender, pj_status_t status,
+ const char *title_fmt, ...);
+#else
+ #define pj_perror_wrapper_6(arg)
+#endif
+
+
+
+
+PJ_END_DECL
+
+#endif /* __PJ_ERRNO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/except.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/except.h
new file mode 100644
index 0000000..7d1b054
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/except.h
@@ -0,0 +1,421 @@
+/* $Id: except.h 2878 2009-08-14 10:41:00Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_EXCEPTION_H__
+#define __PJ_EXCEPTION_H__
+
+/**
+ * @file except.h
+ * @brief Exception Handling in C.
+ */
+
+#include <pj/types.h>
+#include <pj/compat/setjmp.h>
+#include <pj/log.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_EXCEPT Exception Handling
+ * @ingroup PJ_MISC
+ * @{
+ *
+ * \section pj_except_sample_sec Quick Example
+ *
+ * For the impatient, take a look at some examples:
+ * - @ref page_pjlib_samples_except_c
+ * - @ref page_pjlib_exception_test
+ *
+ * \section pj_except_except Exception Handling
+ *
+ * This module provides exception handling syntactically similar to C++ in
+ * C language. In Win32 systems, it uses Windows Structured Exception
+ * Handling (SEH) if macro PJ_EXCEPTION_USE_WIN32_SEH is non-zero.
+ * Otherwise it will use setjmp() and longjmp().
+ *
+ * On some platforms where setjmp/longjmp is not available, setjmp/longjmp
+ * implementation is provided. See <pj/compat/setjmp.h> for compatibility.
+ *
+ * The exception handling mechanism is completely thread safe, so the exception
+ * thrown by one thread will not interfere with other thread.
+ *
+ * The exception handling constructs are similar to C++. The blocks will be
+ * constructed similar to the following sample:
+ *
+ * \verbatim
+ #define NO_MEMORY 1
+ #define SYNTAX_ERROR 2
+
+ int sample1()
+ {
+ PJ_USE_EXCEPTION; // declare local exception stack.
+
+ PJ_TRY {
+ ...// do something..
+ }
+ PJ_CATCH(NO_MEMORY) {
+ ... // handle exception 1
+ }
+ PJ_END;
+ }
+
+ int sample2()
+ {
+ PJ_USE_EXCEPTION; // declare local exception stack.
+
+ PJ_TRY {
+ ...// do something..
+ }
+ PJ_CATCH_ANY {
+ if (PJ_GET_EXCEPTION() == NO_MEMORY)
+ ...; // handle no memory situation
+ else if (PJ_GET_EXCEPTION() == SYNTAX_ERROR)
+ ...; // handle syntax error
+ }
+ PJ_END;
+ }
+ \endverbatim
+ *
+ * The above sample uses hard coded exception ID. It is @b strongly
+ * recommended that applications request a unique exception ID instead
+ * of hard coded value like above.
+ *
+ * \section pj_except_reg Exception ID Allocation
+ *
+ * To ensure that exception ID (number) are used consistently and to
+ * prevent ID collisions in an application, it is strongly suggested that
+ * applications allocate an exception ID for each possible exception
+ * type. As a bonus of this process, the application can identify
+ * the name of the exception when the particular exception is thrown.
+ *
+ * Exception ID management are performed with the following APIs:
+ * - #pj_exception_id_alloc().
+ * - #pj_exception_id_free().
+ * - #pj_exception_id_name().
+ *
+ *
+ * PJLIB itself automatically allocates one exception id, i.e.
+ * #PJ_NO_MEMORY_EXCEPTION which is declared in <pj/pool.h>. This exception
+ * ID is raised by default pool policy when it fails to allocate memory.
+ *
+ * CAVEATS:
+ * - unlike C++ exception, the scheme here won't call destructors of local
+ * objects if exception is thrown. Care must be taken when a function
+ * hold some resorce such as pool or mutex etc.
+ * - You CAN NOT make nested exception in one single function without using
+ * a nested PJ_USE_EXCEPTION. Samples:
+ \verbatim
+ void wrong_sample()
+ {
+ PJ_USE_EXCEPTION;
+
+ PJ_TRY {
+ // Do stuffs
+ ...
+ }
+ PJ_CATCH_ANY {
+ // Do other stuffs
+ ....
+ ..
+
+ // The following block is WRONG! You MUST declare
+ // PJ_USE_EXCEPTION once again in this block.
+ PJ_TRY {
+ ..
+ }
+ PJ_CATCH_ANY {
+ ..
+ }
+ PJ_END;
+ }
+ PJ_END;
+ }
+
+ \endverbatim
+
+ * - You MUST NOT exit the function inside the PJ_TRY block. The correct way
+ * is to return from the function after PJ_END block is executed.
+ * For example, the following code will yield crash not in this code,
+ * but rather in the subsequent execution of PJ_TRY block:
+ \verbatim
+ void wrong_sample()
+ {
+ PJ_USE_EXCEPTION;
+
+ PJ_TRY {
+ // do some stuffs
+ ...
+ return; <======= DO NOT DO THIS!
+ }
+ PJ_CATCH_ANY {
+ }
+ PJ_END;
+ }
+ \endverbatim
+
+ * - You can not provide more than PJ_CATCH or PJ_CATCH_ANY nor use PJ_CATCH
+ * and PJ_CATCH_ANY for a single PJ_TRY.
+ * - Exceptions will always be caught by the first handler (unlike C++ where
+ * exception is only caught if the type matches.
+
+ * \section PJ_EX_KEYWORDS Keywords
+ *
+ * \subsection PJ_THROW PJ_THROW(expression)
+ * Throw an exception. The expression thrown is an integer as the result of
+ * the \a expression. This keyword can be specified anywhere within the
+ * program.
+ *
+ * \subsection PJ_USE_EXCEPTION PJ_USE_EXCEPTION
+ * Specify this in the variable definition section of the function block
+ * (or any blocks) to specify that the block has \a PJ_TRY/PJ_CATCH exception
+ * block.
+ * Actually, this is just a macro to declare local variable which is used to
+ * push the exception state to the exception stack.
+ * Note: you must specify PJ_USE_EXCEPTION as the last statement in the
+ * local variable declarations, since it may evaluate to nothing.
+ *
+ * \subsection PJ_TRY PJ_TRY
+ * The \a PJ_TRY keyword is typically followed by a block. If an exception is
+ * thrown in this block, then the execution will resume to the \a PJ_CATCH
+ * handler.
+ *
+ * \subsection PJ_CATCH PJ_CATCH(expression)
+ * The \a PJ_CATCH is normally followed by a block. This block will be executed
+ * if the exception being thrown is equal to the expression specified in the
+ * \a PJ_CATCH.
+ *
+ * \subsection PJ_CATCH_ANY PJ_CATCH_ANY
+ * The \a PJ_CATCH is normally followed by a block. This block will be executed
+ * if any exception was raised in the TRY block.
+ *
+ * \subsection PJ_END PJ_END
+ * Specify this keyword to mark the end of \a PJ_TRY / \a PJ_CATCH blocks.
+ *
+ * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void)
+ * Get the last exception thrown. This macro is normally called inside the
+ * \a PJ_CATCH or \a PJ_CATCH_ANY block, altough it can be used anywhere where
+ * the \a PJ_USE_EXCEPTION definition is in scope.
+ *
+ *
+ * \section pj_except_examples_sec Examples
+ *
+ * For some examples on how to use the exception construct, please see:
+ * - @ref page_pjlib_samples_except_c
+ * - @ref page_pjlib_exception_test
+ */
+
+/**
+ * Allocate a unique exception id.
+ * Applications don't have to allocate a unique exception ID before using
+ * the exception construct. However, by doing so it ensures that there is
+ * no collisions of exception ID.
+ *
+ * As a bonus, when exception number is acquired through this function,
+ * the library can assign name to the exception (only if
+ * PJ_HAS_EXCEPTION_NAMES is enabled (default is yes)) and find out the
+ * exception name when it catches an exception.
+ *
+ * @param name Name to be associated with the exception ID.
+ * @param id Pointer to receive the ID.
+ *
+ * @return PJ_SUCCESS on success or PJ_ETOOMANY if the library
+ * is running out out ids.
+ */
+PJ_DECL(pj_status_t) pj_exception_id_alloc(const char *name,
+ pj_exception_id_t *id);
+
+/**
+ * Free an exception id.
+ *
+ * @param id The exception ID.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_exception_id_free(pj_exception_id_t id);
+
+/**
+ * Retrieve name associated with the exception id.
+ *
+ * @param id The exception ID.
+ *
+ * @return The name associated with the specified ID.
+ */
+PJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id);
+
+
+/** @} */
+
+#if defined(PJ_EXCEPTION_USE_WIN32_SEH) && PJ_EXCEPTION_USE_WIN32_SEH != 0
+/*****************************************************************************
+ **
+ ** IMPLEMENTATION OF EXCEPTION USING WINDOWS SEH
+ **
+ ****************************************************************************/
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+PJ_IDECL_NO_RETURN(void)
+pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN
+{
+ RaiseException(id,1,0,NULL);
+}
+
+#define PJ_USE_EXCEPTION
+#define PJ_TRY __try
+#define PJ_CATCH(id) __except(GetExceptionCode()==id ? \
+ EXCEPTION_EXECUTE_HANDLER : \
+ EXCEPTION_CONTINUE_SEARCH)
+#define PJ_CATCH_ANY __except(EXCEPTION_EXECUTE_HANDLER)
+#define PJ_END
+#define PJ_THROW(id) pj_throw_exception_(id)
+#define PJ_GET_EXCEPTION() GetExceptionCode()
+
+
+#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
+/*****************************************************************************
+ **
+ ** IMPLEMENTATION OF EXCEPTION USING SYMBIAN LEAVE/TRAP FRAMEWORK
+ **
+ ****************************************************************************/
+
+/* To include this file, the source file must be compiled as
+ * C++ code!
+ */
+#ifdef __cplusplus
+
+class TPjException
+{
+public:
+ int code_;
+};
+
+#define PJ_USE_EXCEPTION
+#define PJ_TRY try
+//#define PJ_CATCH(id)
+#define PJ_CATCH_ANY catch (const TPjException & pj_excp_)
+#define PJ_END
+#define PJ_THROW(x_id) do { TPjException e; e.code_=x_id; throw e;} \
+ while (0)
+#define PJ_GET_EXCEPTION() pj_excp_.code_
+
+#else
+
+#define PJ_USE_EXCEPTION
+#define PJ_TRY
+#define PJ_CATCH_ANY if (0)
+#define PJ_END
+#define PJ_THROW(x_id) do { PJ_LOG(1,("PJ_THROW"," error code = %d",x_id)); } while (0)
+#define PJ_GET_EXCEPTION() 0
+
+#endif /* __cplusplus */
+
+#else
+/*****************************************************************************
+ **
+ ** IMPLEMENTATION OF EXCEPTION USING GENERIC SETJMP/LONGJMP
+ **
+ ****************************************************************************/
+
+/**
+ * This structure (which should be invisible to user) manages the TRY handler
+ * stack.
+ */
+struct pj_exception_state_t
+{
+ struct pj_exception_state_t *prev; /**< Previous state in the list. */
+ pj_jmp_buf state; /**< jmp_buf. */
+};
+
+/**
+ * Throw exception.
+ * @param id Exception Id.
+ */
+PJ_DECL_NO_RETURN(void)
+pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN;
+
+/**
+ * Push exception handler.
+ */
+PJ_DECL(void) pj_push_exception_handler_(struct pj_exception_state_t *rec);
+
+/**
+ * Pop exception handler.
+ */
+PJ_DECL(void) pj_pop_exception_handler_(struct pj_exception_state_t *rec);
+
+/**
+ * Declare that the function will use exception.
+ * @hideinitializer
+ */
+#define PJ_USE_EXCEPTION struct pj_exception_state_t pj_x_except__; int pj_x_code__
+
+/**
+ * Start exception specification block.
+ * @hideinitializer
+ */
+#define PJ_TRY if (1) { \
+ pj_push_exception_handler_(&pj_x_except__); \
+ pj_x_code__ = pj_setjmp(pj_x_except__.state); \
+ if (pj_x_code__ == 0)
+/**
+ * Catch the specified exception Id.
+ * @param id The exception number to catch.
+ * @hideinitializer
+ */
+#define PJ_CATCH(id) else if (pj_x_code__ == (id))
+
+/**
+ * Catch any exception number.
+ * @hideinitializer
+ */
+#define PJ_CATCH_ANY else
+
+/**
+ * End of exception specification block.
+ * @hideinitializer
+ */
+#define PJ_END pj_pop_exception_handler_(&pj_x_except__); \
+ } else {}
+
+/**
+ * Throw exception.
+ * @param exception_id The exception number.
+ * @hideinitializer
+ */
+#define PJ_THROW(exception_id) pj_throw_exception_(exception_id)
+
+/**
+ * Get current exception.
+ * @return Current exception code.
+ * @hideinitializer
+ */
+#define PJ_GET_EXCEPTION() (pj_x_code__)
+
+#endif /* PJ_EXCEPTION_USE_WIN32_SEH */
+
+
+PJ_END_DECL
+
+
+
+#endif /* __PJ_EXCEPTION_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/fifobuf.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/fifobuf.h
new file mode 100644
index 0000000..91bb8ec
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/fifobuf.h
@@ -0,0 +1,44 @@
+/* $Id: fifobuf.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_FIFOBUF_H__
+#define __PJ_FIFOBUF_H__
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+typedef struct pj_fifobuf_t pj_fifobuf_t;
+struct pj_fifobuf_t
+{
+ char *first, *last;
+ char *ubegin, *uend;
+ int full;
+};
+
+PJ_DECL(void) pj_fifobuf_init (pj_fifobuf_t *fb, void *buffer, unsigned size);
+PJ_DECL(unsigned) pj_fifobuf_max_size (pj_fifobuf_t *fb);
+PJ_DECL(void*) pj_fifobuf_alloc (pj_fifobuf_t *fb, unsigned size);
+PJ_DECL(pj_status_t) pj_fifobuf_unalloc (pj_fifobuf_t *fb, void *buf);
+PJ_DECL(pj_status_t) pj_fifobuf_free (pj_fifobuf_t *fb, void *buf);
+
+PJ_END_DECL
+
+#endif /* __PJ_FIFOBUF_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/file_access.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/file_access.h
new file mode 100644
index 0000000..d0f9237
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/file_access.h
@@ -0,0 +1,109 @@
+/* $Id: file_access.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_FILE_ACCESS_H__
+#define __PJ_FILE_ACCESS_H__
+
+/**
+ * @file file_access.h
+ * @brief File manipulation and access.
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_FILE_ACCESS File Access
+ * @ingroup PJ_IO
+ * @{
+ *
+ */
+
+/**
+ * This structure describes file information, to be obtained by
+ * calling #pj_file_getstat(). The time information in this structure
+ * is in local time.
+ */
+typedef struct pj_file_stat
+{
+ pj_off_t size; /**< Total file size. */
+ pj_time_val atime; /**< Time of last access. */
+ pj_time_val mtime; /**< Time of last modification. */
+ pj_time_val ctime; /**< Time of last creation. */
+} pj_file_stat;
+
+
+/**
+ * Returns non-zero if the specified file exists.
+ *
+ * @param filename The file name.
+ *
+ * @return Non-zero if the file exists.
+ */
+PJ_DECL(pj_bool_t) pj_file_exists(const char *filename);
+
+/**
+ * Returns the size of the file.
+ *
+ * @param filename The file name.
+ *
+ * @return The file size in bytes or -1 on error.
+ */
+PJ_DECL(pj_off_t) pj_file_size(const char *filename);
+
+/**
+ * Delete a file.
+ *
+ * @param filename The filename.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_file_delete(const char *filename);
+
+/**
+ * Move a \c oldname to \c newname. If \c newname already exists,
+ * it will be overwritten.
+ *
+ * @param oldname The file to rename.
+ * @param newname New filename to assign.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_file_move( const char *oldname,
+ const char *newname);
+
+
+/**
+ * Return information about the specified file. The time information in
+ * the \c stat structure will be in local time.
+ *
+ * @param filename The filename.
+ * @param stat Pointer to variable to receive file information.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat);
+
+
+/** @} */
+
+PJ_END_DECL
+
+
+#endif /* __PJ_FILE_ACCESS_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/file_io.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/file_io.h
new file mode 100644
index 0000000..1e84095
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/file_io.h
@@ -0,0 +1,183 @@
+/* $Id: file_io.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_FILE_IO_H__
+#define __PJ_FILE_IO_H__
+
+/**
+ * @file file_io.h
+ * @brief Simple file I/O abstraction.
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_FILE_IO File I/O
+ * @ingroup PJ_IO
+ * @{
+ *
+ * This file contains functionalities to perform file I/O. The file
+ * I/O can be implemented with various back-end, either using native
+ * file API or ANSI stream.
+ *
+ * @section pj_file_size_limit_sec Size Limits
+ *
+ * There may be limitation on the size that can be handled by the
+ * #pj_file_setpos() or #pj_file_getpos() functions. The API itself
+ * uses 64-bit integer for the file offset/position (where available);
+ * however some backends (such as ANSI) may only support signed 32-bit
+ * offset resolution.
+ *
+ * Reading and writing operation uses signed 32-bit integer to indicate
+ * the size.
+ *
+ *
+ */
+
+/**
+ * These enumerations are used when opening file. Values PJ_O_RDONLY,
+ * PJ_O_WRONLY, and PJ_O_RDWR are mutually exclusive. Value PJ_O_APPEND
+ * can only be used when the file is opened for writing.
+ */
+enum pj_file_access
+{
+ PJ_O_RDONLY = 0x1101, /**< Open file for reading. */
+ PJ_O_WRONLY = 0x1102, /**< Open file for writing. */
+ PJ_O_RDWR = 0x1103, /**< Open file for reading and writing.
+ File will be truncated. */
+ PJ_O_APPEND = 0x1108 /**< Append to existing file. */
+};
+
+/**
+ * The seek directive when setting the file position with #pj_file_setpos.
+ */
+enum pj_file_seek_type
+{
+ PJ_SEEK_SET = 0x1201, /**< Offset from beginning of the file. */
+ PJ_SEEK_CUR = 0x1202, /**< Offset from current position. */
+ PJ_SEEK_END = 0x1203 /**< Size of the file plus offset. */
+};
+
+/**
+ * Open the file as specified in \c pathname with the specified
+ * mode, and return the handle in \c fd. All files will be opened
+ * as binary.
+ *
+ * @param pool Pool to allocate memory for the new file descriptor.
+ * @param pathname The file name to open.
+ * @param flags Open flags, which is bitmask combination of
+ * #pj_file_access enum. The flag must be either
+ * PJ_O_RDONLY, PJ_O_WRONLY, or PJ_O_RDWR. When file
+ * writing is specified, existing file will be
+ * truncated unless PJ_O_APPEND is specified.
+ * @param fd The returned descriptor.
+ *
+ * @return PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_open(pj_pool_t *pool,
+ const char *pathname,
+ unsigned flags,
+ pj_oshandle_t *fd);
+
+/**
+ * Close an opened file descriptor.
+ *
+ * @param fd The file descriptor.
+ *
+ * @return PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_close(pj_oshandle_t fd);
+
+/**
+ * Write data with the specified size to an opened file.
+ *
+ * @param fd The file descriptor.
+ * @param data Data to be written to the file.
+ * @param size On input, specifies the size of data to be written.
+ * On return, it contains the number of data actually
+ * written to the file.
+ *
+ * @return PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_write(pj_oshandle_t fd,
+ const void *data,
+ pj_ssize_t *size);
+
+/**
+ * Read data from the specified file. When end-of-file condition is set,
+ * this function will return PJ_SUCCESS but the size will contain zero.
+ *
+ * @param fd The file descriptor.
+ * @param data Pointer to buffer to receive the data.
+ * @param size On input, specifies the maximum number of data to
+ * read from the file. On output, it contains the size
+ * of data actually read from the file. It will contain
+ * zero when EOF occurs.
+ *
+ * @return PJ_SUCCESS or the appropriate error code on error.
+ * When EOF occurs, the return is PJ_SUCCESS but size
+ * will report zero.
+ */
+PJ_DECL(pj_status_t) pj_file_read(pj_oshandle_t fd,
+ void *data,
+ pj_ssize_t *size);
+
+/**
+ * Set file position to new offset according to directive \c whence.
+ *
+ * @param fd The file descriptor.
+ * @param offset The new file position to set.
+ * @param whence The directive.
+ *
+ * @return PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_setpos(pj_oshandle_t fd,
+ pj_off_t offset,
+ enum pj_file_seek_type whence);
+
+/**
+ * Get current file position.
+ *
+ * @param fd The file descriptor.
+ * @param pos On return contains the file position as measured
+ * from the beginning of the file.
+ *
+ * @return PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_getpos(pj_oshandle_t fd,
+ pj_off_t *pos);
+
+/**
+ * Flush file buffers.
+ *
+ * @param fd The file descriptor.
+ *
+ * @return PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_flush(pj_oshandle_t fd);
+
+
+/** @} */
+
+
+PJ_END_DECL
+
+#endif /* __PJ_FILE_IO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/guid.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/guid.h
new file mode 100644
index 0000000..1c9ed88
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/guid.h
@@ -0,0 +1,101 @@
+/* $Id: guid.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_GUID_H__
+#define __PJ_GUID_H__
+
+
+/**
+ * @file guid.h
+ * @brief GUID Globally Unique Identifier.
+ */
+#include <pj/types.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_DS Data Structure.
+ */
+/**
+ * @defgroup PJ_GUID Globally Unique Identifier
+ * @ingroup PJ_DS
+ * @{
+ *
+ * This module provides API to create string that is globally unique.
+ * If application doesn't require that strong requirement, it can just
+ * use #pj_create_random_string() instead.
+ */
+
+
+/**
+ * PJ_GUID_STRING_LENGTH specifies length of GUID string. The value is
+ * dependent on the algorithm used internally to generate the GUID string.
+ * If real GUID generator is used, then the length will be between 32 and
+ * 36 bytes. Application should not assume which algorithm will
+ * be used by GUID generator.
+ *
+ * Regardless of the actual length of the GUID, it will not exceed
+ * PJ_GUID_MAX_LENGTH characters.
+ *
+ * @see pj_GUID_STRING_LENGTH()
+ * @see PJ_GUID_MAX_LENGTH
+ */
+PJ_DECL_DATA(const unsigned) PJ_GUID_STRING_LENGTH;
+
+/**
+ * Get #PJ_GUID_STRING_LENGTH constant.
+ */
+PJ_DECL(unsigned) pj_GUID_STRING_LENGTH(void);
+
+/**
+ * PJ_GUID_MAX_LENGTH specifies the maximum length of GUID string,
+ * regardless of which algorithm to use.
+ */
+#define PJ_GUID_MAX_LENGTH 36
+
+/**
+ * Create a globally unique string, which length is PJ_GUID_STRING_LENGTH
+ * characters. Caller is responsible for preallocating the storage used
+ * in the string.
+ *
+ * @param str The string to store the result.
+ *
+ * @return The string.
+ */
+PJ_DECL(pj_str_t*) pj_generate_unique_string(pj_str_t *str);
+
+/**
+ * Generate a unique string.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param str The string.
+ */
+PJ_DECL(void) pj_create_unique_string(pj_pool_t *pool, pj_str_t *str);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif/* __PJ_GUID_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/hash.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/hash.h
new file mode 100644
index 0000000..dbf658d
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/hash.h
@@ -0,0 +1,220 @@
+/* $Id: hash.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_HASH_H__
+#define __PJ_HASH_H__
+
+/**
+ * @file hash.h
+ * @brief Hash Table.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_HASH Hash Table
+ * @ingroup PJ_DS
+ * @{
+ * A hash table is a dictionary in which keys are mapped to array positions by
+ * hash functions. Having the keys of more than one item map to the same
+ * position is called a collision. In this library, we will chain the nodes
+ * that have the same key in a list.
+ */
+
+/**
+ * If this constant is used as keylen, then the key is interpreted as
+ * NULL terminated string.
+ */
+#define PJ_HASH_KEY_STRING ((unsigned)-1)
+
+/**
+ * This indicates the size of of each hash entry.
+ */
+#define PJ_HASH_ENTRY_BUF_SIZE (3*sizeof(void*) + 2*sizeof(pj_uint32_t))
+
+/**
+ * Type declaration for entry buffer, used by #pj_hash_set_np()
+ */
+typedef void *pj_hash_entry_buf[(PJ_HASH_ENTRY_BUF_SIZE+sizeof(void*)-1)/(sizeof(void*))];
+
+/**
+ * This is the function that is used by the hash table to calculate hash value
+ * of the specified key.
+ *
+ * @param hval the initial hash value, or zero.
+ * @param key the key to calculate.
+ * @param keylen the length of the key, or PJ_HASH_KEY_STRING to treat
+ * the key as null terminated string.
+ *
+ * @return the hash value.
+ */
+PJ_DECL(pj_uint32_t) pj_hash_calc(pj_uint32_t hval,
+ const void *key, unsigned keylen);
+
+
+/**
+ * Convert the key to lowercase and calculate the hash value. The resulting
+ * string is stored in \c result.
+ *
+ * @param hval The initial hash value, normally zero.
+ * @param result Buffer to store the result, which must be enough to hold
+ * the string.
+ * @param key The input key to be converted and calculated.
+ *
+ * @return The hash value.
+ */
+PJ_DECL(pj_uint32_t) pj_hash_calc_tolower(pj_uint32_t hval,
+ char *result,
+ const pj_str_t *key);
+
+/**
+ * Create a hash table with the specified 'bucket' size.
+ *
+ * @param pool the pool from which the hash table will be allocated from.
+ * @param size the bucket size, which will be round-up to the nearest 2^n-1
+ *
+ * @return the hash table.
+ */
+PJ_DECL(pj_hash_table_t*) pj_hash_create(pj_pool_t *pool, unsigned size);
+
+
+/**
+ * Get the value associated with the specified key.
+ *
+ * @param ht the hash table.
+ * @param key the key to look for.
+ * @param keylen the length of the key, or PJ_HASH_KEY_STRING to use the
+ * string length of the key.
+ * @param hval if this argument is not NULL and the value is not zero,
+ * the value will be used as the computed hash value. If
+ * the argument is not NULL and the value is zero, it will
+ * be filled with the computed hash upon return.
+ *
+ * @return the value associated with the key, or NULL if the key is not found.
+ */
+PJ_DECL(void *) pj_hash_get( pj_hash_table_t *ht,
+ const void *key, unsigned keylen,
+ pj_uint32_t *hval );
+
+
+/**
+ * Associate/disassociate a value with the specified key. If value is not
+ * NULL and entry already exists, the entry's value will be overwritten.
+ * If value is not NULL and entry does not exist, a new one will be created
+ * with the specified pool. Otherwise if value is NULL, entry will be
+ * deleted if it exists.
+ *
+ * @param pool the pool to allocate the new entry if a new entry has to be
+ * created.
+ * @param ht the hash table.
+ * @param key the key, which MUST point to buffer that remains valid
+ * for the duration of the entry.
+ * @param keylen the length of the key, or PJ_HASH_KEY_STRING to use the
+ * string length of the key.
+ * @param hval if the value is not zero, then the hash table will use
+ * this value to search the entry's index, otherwise it will
+ * compute the key. This value can be obtained when calling
+ * #pj_hash_get().
+ * @param value value to be associated, or NULL to delete the entry with
+ * the specified key.
+ */
+PJ_DECL(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht,
+ const void *key, unsigned keylen, pj_uint32_t hval,
+ void *value );
+
+
+/**
+ * Associate/disassociate a value with the specified key. This function works
+ * like #pj_hash_set(), except that it doesn't use pool (hence the np -- no
+ * pool suffix). If new entry needs to be allocated, it will use the entry_buf.
+ *
+ * @param ht the hash table.
+ * @param key the key.
+ * @param keylen the length of the key, or PJ_HASH_KEY_STRING to use the
+ * string length of the key.
+ * @param hval if the value is not zero, then the hash table will use
+ * this value to search the entry's index, otherwise it will
+ * compute the key. This value can be obtained when calling
+ * #pj_hash_get().
+ * @param entry_buf Buffer which will be used for the new entry, when one needs
+ * to be created.
+ * @param value value to be associated, or NULL to delete the entry with
+ * the specified key.
+ */
+PJ_DECL(void) pj_hash_set_np(pj_hash_table_t *ht,
+ const void *key, unsigned keylen,
+ pj_uint32_t hval, pj_hash_entry_buf entry_buf,
+ void *value);
+
+/**
+ * Get the total number of entries in the hash table.
+ *
+ * @param ht the hash table.
+ *
+ * @return the number of entries in the hash table.
+ */
+PJ_DECL(unsigned) pj_hash_count( pj_hash_table_t *ht );
+
+
+/**
+ * Get the iterator to the first element in the hash table.
+ *
+ * @param ht the hash table.
+ * @param it the iterator for iterating hash elements.
+ *
+ * @return the iterator to the hash element, or NULL if no element presents.
+ */
+PJ_DECL(pj_hash_iterator_t*) pj_hash_first( pj_hash_table_t *ht,
+ pj_hash_iterator_t *it );
+
+
+/**
+ * Get the next element from the iterator.
+ *
+ * @param ht the hash table.
+ * @param it the hash iterator.
+ *
+ * @return the next iterator, or NULL if there's no more element.
+ */
+PJ_DECL(pj_hash_iterator_t*) pj_hash_next( pj_hash_table_t *ht,
+ pj_hash_iterator_t *it );
+
+/**
+ * Get the value associated with a hash iterator.
+ *
+ * @param ht the hash table.
+ * @param it the hash iterator.
+ *
+ * @return the value associated with the current element in iterator.
+ */
+PJ_DECL(void*) pj_hash_this( pj_hash_table_t *ht,
+ pj_hash_iterator_t *it );
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/ioqueue.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/ioqueue.h
new file mode 100644
index 0000000..868070f
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/ioqueue.h
@@ -0,0 +1,805 @@
+/* $Id: ioqueue.h 2394 2008-12-23 17:27:53Z bennylp $
+ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_IOQUEUE_H__
+#define __PJ_IOQUEUE_H__
+
+/**
+ * @file ioqueue.h
+ * @brief I/O Dispatching Mechanism
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_IO Input/Output
+ * @brief Input/Output
+ * @ingroup PJ_OS
+ *
+ * This section contains API building blocks to perform network I/O and
+ * communications. If provides:
+ * - @ref PJ_SOCK
+ *\n
+ * A highly portable socket abstraction, runs on all kind of
+ * network APIs such as standard BSD socket, Windows socket, Linux
+ * \b kernel socket, PalmOS networking API, etc.
+ *
+ * - @ref pj_addr_resolve
+ *\n
+ * Portable address resolution, which implements #pj_gethostbyname().
+ *
+ * - @ref PJ_SOCK_SELECT
+ *\n
+ * A portable \a select() like API (#pj_sock_select()) which can be
+ * implemented with various back-ends.
+ *
+ * - @ref PJ_IOQUEUE
+ *\n
+ * Framework for dispatching network events.
+ *
+ * For more information see the modules below.
+ */
+
+/**
+ * @defgroup PJ_IOQUEUE IOQueue: I/O Event Dispatching with Proactor Pattern
+ * @ingroup PJ_IO
+ * @{
+ *
+ * I/O Queue provides API for performing asynchronous I/O operations. It
+ * conforms to proactor pattern, which allows application to submit an
+ * asynchronous operation and to be notified later when the operation has
+ * completed.
+ *
+ * The I/O Queue can work on both socket and file descriptors. For
+ * asynchronous file operations however, one must make sure that the correct
+ * file I/O back-end is used, because not all file I/O back-end can be
+ * used with the ioqueue. Please see \ref PJ_FILE_IO for more details.
+ *
+ * The framework works natively in platforms where asynchronous operation API
+ * exists, such as in Windows NT with IoCompletionPort/IOCP. In other
+ * platforms, the I/O queue abstracts the operating system's event poll API
+ * to provide semantics similar to IoCompletionPort with minimal penalties
+ * (i.e. per ioqueue and per handle mutex protection).
+ *
+ * The I/O queue provides more than just unified abstraction. It also:
+ * - makes sure that the operation uses the most effective way to utilize
+ * the underlying mechanism, to achieve the maximum theoritical
+ * throughput possible on a given platform.
+ * - choose the most efficient mechanism for event polling on a given
+ * platform.
+ *
+ * Currently, the I/O Queue is implemented using:
+ * - <tt><b>select()</b></tt>, as the common denominator, but the least
+ * efficient. Also the number of descriptor is limited to
+ * \c PJ_IOQUEUE_MAX_HANDLES (which by default is 64).
+ * - <tt><b>/dev/epoll</b></tt> on Linux (user mode and kernel mode),
+ * a much faster replacement for select() on Linux (and more importantly
+ * doesn't have limitation on number of descriptors).
+ * - <b>I/O Completion ports</b> on Windows NT/2000/XP, which is the most
+ * efficient way to dispatch events in Windows NT based OSes, and most
+ * importantly, it doesn't have the limit on how many handles to monitor.
+ * And it works with files (not only sockets) as well.
+ *
+ *
+ * \section pj_ioqueue_concurrency_sec Concurrency Rules
+ *
+ * The ioqueue has been fine tuned to allow multiple threads to poll the
+ * handles simultaneously, to maximize scalability when the application is
+ * running on multiprocessor systems. When more than one threads are polling
+ * the ioqueue and there are more than one handles are signaled, more than
+ * one threads will execute the callback simultaneously to serve the events.
+ * These parallel executions are completely safe when the events happen for
+ * two different handles.
+ *
+ * However, with multithreading, care must be taken when multiple events
+ * happen on the same handle, or when event is happening on a handle (and
+ * the callback is being executed) and application is performing
+ * unregistration to the handle at the same time.
+ *
+ * The treatments of above scenario differ according to the concurrency
+ * setting that are applied to the handle.
+ *
+ * \subsection pj_ioq_concur_set Concurrency Settings for Handles
+ *
+ * Concurrency can be set on per handle (key) basis, by using
+ * #pj_ioqueue_set_concurrency() function. The default key concurrency value
+ * for the handle is inherited from the key concurrency setting of the ioqueue,
+ * and the key concurrency setting for the ioqueue can be changed by using
+ * #pj_ioqueue_set_default_concurrency(). The default key concurrency setting
+ * for ioqueue itself is controlled by compile time setting
+ * PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY.
+ *
+ * Note that this key concurrency setting only controls whether multiple
+ * threads are allowed to operate <b>on the same key</b> at the same time.
+ * The ioqueue itself always allows multiple threads to enter the ioqeuue at
+ * the same time, and also simultaneous callback calls to <b>differrent
+ * keys</b> is always allowed regardless to the key concurrency setting.
+ *
+ * \subsection pj_ioq_parallel Parallel Callback Executions for the Same Handle
+ *
+ * Note that when key concurrency is enabled (i.e. parallel callback calls on
+ * the same key is allowed; this is the default setting), the ioqueue will only
+ * perform simultaneous callback executions on the same key when the key has
+ * invoked multiple pending operations. This could be done for example by
+ * calling #pj_ioqueue_recvfrom() more than once on the same key, each with
+ * the same key but different operation key (pj_ioqueue_op_key_t). With this
+ * scenario, when multiple packets arrive on the key at the same time, more
+ * than one threads may execute the callback simultaneously, each with the
+ * same key but different operation key.
+ *
+ * When there is only one pending operation on the key (e.g. there is only one
+ * #pj_ioqueue_recvfrom() invoked on the key), then events occuring to the
+ * same key will be queued by the ioqueue, thus no simultaneous callback calls
+ * will be performed.
+ *
+ * \subsection pj_ioq_allow_concur Concurrency is Enabled (Default Value)
+ *
+ * The default setting for the ioqueue is to allow multiple threads to
+ * execute callbacks for the same handle/key. This setting is selected to
+ * promote good performance and scalability for application.
+ *
+ * However this setting has a major drawback with regard to synchronization,
+ * and application MUST carefully follow the following guidelines to ensure
+ * that parallel access to the key does not cause problems:
+ *
+ * - Always note that callback may be called simultaneously for the same
+ * key.
+ * - <b>Care must be taken when unregistering a key</b> from the
+ * ioqueue. Application must take care that when one thread is issuing
+ * an unregistration, other thread is not simultaneously invoking the
+ * callback <b>to the same key</b>.
+ *\n
+ * This happens because the ioqueue functions are working with a pointer
+ * to the key, and there is a possible race condition where the pointer
+ * has been rendered invalid by other threads before the ioqueue has a
+ * chance to acquire mutex on it.
+ *
+ * \subsection pj_ioq_disallow_concur Concurrency is Disabled
+ *
+ * Alternatively, application may disable key concurrency to make
+ * synchronization easier. As noted above, there are three ways to control
+ * key concurrency setting:
+ * - by controlling on per handle/key basis, with #pj_ioqueue_set_concurrency().
+ * - by changing default key concurrency setting on the ioqueue, with
+ * #pj_ioqueue_set_default_concurrency().
+ * - by changing the default concurrency on compile time, by declaring
+ * PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY macro to zero in your config_site.h
+ *
+ * \section pj_ioqeuue_examples_sec Examples
+ *
+ * For some examples on how to use the I/O Queue, please see:
+ *
+ * - \ref page_pjlib_ioqueue_tcp_test
+ * - \ref page_pjlib_ioqueue_udp_test
+ * - \ref page_pjlib_ioqueue_perf_test
+ */
+
+
+/**
+ * This structure describes operation specific key to be submitted to
+ * I/O Queue when performing the asynchronous operation. This key will
+ * be returned to the application when completion callback is called.
+ *
+ * Application normally wants to attach it's specific data in the
+ * \c user_data field so that it can keep track of which operation has
+ * completed when the callback is called. Alternatively, application can
+ * also extend this struct to include its data, because the pointer that
+ * is returned in the completion callback will be exactly the same as
+ * the pointer supplied when the asynchronous function is called.
+ */
+typedef struct pj_ioqueue_op_key_t
+{
+ void *internal__[32]; /**< Internal I/O Queue data. */
+ void *activesock_data; /**< Active socket data. */
+ void *user_data; /**< Application data. */
+} pj_ioqueue_op_key_t;
+
+/**
+ * This structure describes the callbacks to be called when I/O operation
+ * completes.
+ */
+typedef struct pj_ioqueue_callback
+{
+ /**
+ * This callback is called when #pj_ioqueue_recv or #pj_ioqueue_recvfrom
+ * completes.
+ *
+ * @param key The key.
+ * @param op_key Operation key.
+ * @param bytes_read >= 0 to indicate the amount of data read,
+ * otherwise negative value containing the error
+ * code. To obtain the pj_status_t error code, use
+ * (pj_status_t code = -bytes_read).
+ */
+ void (*on_read_complete)(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_read);
+
+ /**
+ * This callback is called when #pj_ioqueue_send or #pj_ioqueue_sendto
+ * completes.
+ *
+ * @param key The key.
+ * @param op_key Operation key.
+ * @param bytes_sent >= 0 to indicate the amount of data written,
+ * otherwise negative value containing the error
+ * code. To obtain the pj_status_t error code, use
+ * (pj_status_t code = -bytes_sent).
+ */
+ void (*on_write_complete)(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_sent);
+
+ /**
+ * This callback is called when #pj_ioqueue_accept completes.
+ *
+ * @param key The key.
+ * @param op_key Operation key.
+ * @param sock Newly connected socket.
+ * @param status Zero if the operation completes successfully.
+ */
+ void (*on_accept_complete)(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_sock_t sock,
+ pj_status_t status);
+
+ /**
+ * This callback is called when #pj_ioqueue_connect completes.
+ *
+ * @param key The key.
+ * @param status PJ_SUCCESS if the operation completes successfully.
+ */
+ void (*on_connect_complete)(pj_ioqueue_key_t *key,
+ pj_status_t status);
+} pj_ioqueue_callback;
+
+
+/**
+ * Types of pending I/O Queue operation. This enumeration is only used
+ * internally within the ioqueue.
+ */
+typedef enum pj_ioqueue_operation_e
+{
+ PJ_IOQUEUE_OP_NONE = 0, /**< No operation. */
+ PJ_IOQUEUE_OP_READ = 1, /**< read() operation. */
+ PJ_IOQUEUE_OP_RECV = 2, /**< recv() operation. */
+ PJ_IOQUEUE_OP_RECV_FROM = 4, /**< recvfrom() operation. */
+ PJ_IOQUEUE_OP_WRITE = 8, /**< write() operation. */
+ PJ_IOQUEUE_OP_SEND = 16, /**< send() operation. */
+ PJ_IOQUEUE_OP_SEND_TO = 32, /**< sendto() operation. */
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0
+ PJ_IOQUEUE_OP_ACCEPT = 64, /**< accept() operation. */
+ PJ_IOQUEUE_OP_CONNECT = 128 /**< connect() operation. */
+#endif /* PJ_HAS_TCP */
+} pj_ioqueue_operation_e;
+
+
+/**
+ * This macro specifies the maximum number of events that can be
+ * processed by the ioqueue on a single poll cycle, on implementation
+ * that supports it. The value is only meaningfull when specified
+ * during PJLIB build.
+ */
+#ifndef PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL
+# define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL (16)
+#endif
+
+/**
+ * When this flag is specified in ioqueue's recv() or send() operations,
+ * the ioqueue will always mark the operation as asynchronous.
+ */
+#define PJ_IOQUEUE_ALWAYS_ASYNC ((pj_uint32_t)1 << (pj_uint32_t)31)
+
+/**
+ * Return the name of the ioqueue implementation.
+ *
+ * @return Implementation name.
+ */
+PJ_DECL(const char*) pj_ioqueue_name(void);
+
+
+/**
+ * Create a new I/O Queue framework.
+ *
+ * @param pool The pool to allocate the I/O queue structure.
+ * @param max_fd The maximum number of handles to be supported, which
+ * should not exceed PJ_IOQUEUE_MAX_HANDLES.
+ * @param ioqueue Pointer to hold the newly created I/O Queue.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_create( pj_pool_t *pool,
+ pj_size_t max_fd,
+ pj_ioqueue_t **ioqueue);
+
+/**
+ * Destroy the I/O queue.
+ *
+ * @param ioque The I/O Queue to be destroyed.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioque );
+
+/**
+ * Set the lock object to be used by the I/O Queue. This function can only
+ * be called right after the I/O queue is created, before any handle is
+ * registered to the I/O queue.
+ *
+ * Initially the I/O queue is created with non-recursive mutex protection.
+ * Applications can supply alternative lock to be used by calling this
+ * function.
+ *
+ * @param ioque The ioqueue instance.
+ * @param lock The lock to be used by the ioqueue.
+ * @param auto_delete In non-zero, the lock will be deleted by the ioqueue.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioque,
+ pj_lock_t *lock,
+ pj_bool_t auto_delete );
+
+/**
+ * Set default concurrency policy for this ioqueue. If this function is not
+ * called, the default concurrency policy for the ioqueue is controlled by
+ * compile time setting PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY.
+ *
+ * Note that changing the concurrency setting to the ioqueue will only affect
+ * subsequent key registrations. To modify the concurrency setting for
+ * individual key, use #pj_ioqueue_set_concurrency().
+ *
+ * @param ioqueue The ioqueue instance.
+ * @param allow Non-zero to allow concurrent callback calls, or
+ * PJ_FALSE to disallow it.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_set_default_concurrency(pj_ioqueue_t *ioqueue,
+ pj_bool_t allow);
+
+/**
+ * Register a socket to the I/O queue framework.
+ * When a socket is registered to the IOQueue, it may be modified to use
+ * non-blocking IO. If it is modified, there is no guarantee that this
+ * modification will be restored after the socket is unregistered.
+ *
+ * @param pool To allocate the resource for the specified handle,
+ * which must be valid until the handle/key is unregistered
+ * from I/O Queue.
+ * @param ioque The I/O Queue.
+ * @param sock The socket.
+ * @param user_data User data to be associated with the key, which can be
+ * retrieved later.
+ * @param cb Callback to be called when I/O operation completes.
+ * @param key Pointer to receive the key to be associated with this
+ * socket. Subsequent I/O queue operation will need this
+ * key.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,
+ pj_ioqueue_t *ioque,
+ pj_sock_t sock,
+ void *user_data,
+ const pj_ioqueue_callback *cb,
+ pj_ioqueue_key_t **key );
+
+/**
+ * Unregister from the I/O Queue framework. Caller must make sure that
+ * the key doesn't have any pending operations before calling this function,
+ * by calling #pj_ioqueue_is_pending() for all previously submitted
+ * operations except asynchronous connect, and if necessary call
+ * #pj_ioqueue_post_completion() to cancel the pending operations.
+ *
+ * Note that asynchronous connect operation will automatically be
+ * cancelled during the unregistration.
+ *
+ * Also note that when I/O Completion Port backend is used, application
+ * MUST close the handle immediately after unregistering the key. This is
+ * because there is no unregistering API for IOCP. The only way to
+ * unregister the handle from IOCP is to close the handle.
+ *
+ * @param key The key that was previously obtained from registration.
+ *
+ * @return PJ_SUCCESS on success or the error code.
+ *
+ * @see pj_ioqueue_is_pending
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key );
+
+
+/**
+ * Get user data associated with an ioqueue key.
+ *
+ * @param key The key that was previously obtained from registration.
+ *
+ * @return The user data associated with the descriptor, or NULL
+ * on error or if no data is associated with the key during
+ * registration.
+ */
+PJ_DECL(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key );
+
+/**
+ * Set or change the user data to be associated with the file descriptor or
+ * handle or socket descriptor.
+ *
+ * @param key The key that was previously obtained from registration.
+ * @param user_data User data to be associated with the descriptor.
+ * @param old_data Optional parameter to retrieve the old user data.
+ *
+ * @return PJ_SUCCESS on success or the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,
+ void *user_data,
+ void **old_data);
+
+/**
+ * Configure whether the ioqueue is allowed to call the key's callback
+ * concurrently/in parallel. The default concurrency setting for the key
+ * is controlled by ioqueue's default concurrency value, which can be
+ * changed by calling #pj_ioqueue_set_default_concurrency().
+ *
+ * If concurrency is allowed for the key, it means that if there are more
+ * than one pending operations complete simultaneously, more than one
+ * threads may call the key's callback at the same time. This generally
+ * would promote good scalability for application, at the expense of more
+ * complexity to manage the concurrent accesses in application's code.
+ *
+ * Alternatively application may disable the concurrent access by
+ * setting the \a allow flag to false. With concurrency disabled, only
+ * one thread can call the key's callback at one time.
+ *
+ * @param key The key that was previously obtained from registration.
+ * @param allow Set this to non-zero to allow concurrent callback calls
+ * and zero (PJ_FALSE) to disallow it.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_set_concurrency(pj_ioqueue_key_t *key,
+ pj_bool_t allow);
+
+/**
+ * Acquire the key's mutex. When the key's concurrency is disabled,
+ * application may call this function to synchronize its operation
+ * with the key's callback (i.e. this function will block until the
+ * key's callback returns).
+ *
+ * @param key The key that was previously obtained from registration.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_lock_key(pj_ioqueue_key_t *key);
+
+/**
+ * Release the lock previously acquired with pj_ioqueue_lock_key().
+ *
+ * @param key The key that was previously obtained from registration.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_unlock_key(pj_ioqueue_key_t *key);
+
+/**
+ * Initialize operation key.
+ *
+ * @param op_key The operation key to be initialied.
+ * @param size The size of the operation key.
+ */
+PJ_DECL(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,
+ pj_size_t size );
+
+/**
+ * Check if operation is pending on the specified operation key.
+ * The \c op_key must have been initialized with #pj_ioqueue_op_key_init()
+ * or submitted as pending operation before, or otherwise the result
+ * is undefined.
+ *
+ * @param key The key.
+ * @param op_key The operation key, previously submitted to any of
+ * the I/O functions and has returned PJ_EPENDING.
+ *
+ * @return Non-zero if operation is still pending.
+ */
+PJ_DECL(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key );
+
+
+/**
+ * Post completion status to the specified operation key and call the
+ * appropriate callback. When the callback is called, the number of bytes
+ * received in read/write callback or the status in accept/connect callback
+ * will be set from the \c bytes_status parameter.
+ *
+ * @param key The key.
+ * @param op_key Pending operation key.
+ * @param bytes_status Number of bytes or status to be set. A good value
+ * to put here is -PJ_ECANCELLED.
+ *
+ * @return PJ_SUCCESS if completion status has been successfully
+ * sent.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_status );
+
+
+
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0
+/**
+ * Instruct I/O Queue to accept incoming connection on the specified
+ * listening socket. This function will return immediately (i.e. non-blocking)
+ * regardless whether a connection is immediately available. If the function
+ * can't complete immediately, the caller will be notified about the incoming
+ * connection when it calls pj_ioqueue_poll(). If a new connection is
+ * immediately available, the function returns PJ_SUCCESS with the new
+ * connection; in this case, the callback WILL NOT be called.
+ *
+ * @param key The key which registered to the server socket.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called.
+ * @param new_sock Argument which contain pointer to receive the new socket
+ * for the incoming connection.
+ * @param local Optional argument which contain pointer to variable to
+ * receive local address.
+ * @param remote Optional argument which contain pointer to variable to
+ * receive the remote address.
+ * @param addrlen On input, contains the length of the buffer for the
+ * address, and on output, contains the actual length of the
+ * address. This argument is optional.
+ * @return
+ * - PJ_SUCCESS When connection is available immediately, and the
+ * parameters will be updated to contain information about
+ * the new connection. In this case, a completion callback
+ * WILL NOT be called.
+ * - PJ_EPENDING If no connection is available immediately. When a new
+ * connection arrives, the callback will be called.
+ * - non-zero which indicates the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_sock_t *new_sock,
+ pj_sockaddr_t *local,
+ pj_sockaddr_t *remote,
+ int *addrlen );
+
+/**
+ * Initiate non-blocking socket connect. If the socket can NOT be connected
+ * immediately, asynchronous connect() will be scheduled and caller will be
+ * notified via completion callback when it calls pj_ioqueue_poll(). If
+ * socket is connected immediately, the function returns PJ_SUCCESS and
+ * completion callback WILL NOT be called.
+ *
+ * @param key The key associated with TCP socket
+ * @param addr The remote address.
+ * @param addrlen The remote address length.
+ *
+ * @return
+ * - PJ_SUCCESS If socket is connected immediately. In this case, the
+ * completion callback WILL NOT be called.
+ * - PJ_EPENDING If operation is queued, or
+ * - non-zero Indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,
+ const pj_sockaddr_t *addr,
+ int addrlen );
+
+#endif /* PJ_HAS_TCP */
+
+/**
+ * Poll the I/O Queue for completed events.
+ *
+ * Note: polling the ioqueue is not necessary in Symbian. Please see
+ * @ref PJ_SYMBIAN_OS for more info.
+ *
+ * @param ioque the I/O Queue.
+ * @param timeout polling timeout, or NULL if the thread wishes to wait
+ * indefinetely for the event.
+ *
+ * @return
+ * - zero if timed out (no event).
+ * - (<0) if error occured during polling. Callback will NOT be called.
+ * - (>1) to indicate numbers of events. Callbacks have been called.
+ */
+PJ_DECL(int) pj_ioqueue_poll( pj_ioqueue_t *ioque,
+ const pj_time_val *timeout);
+
+
+/**
+ * Instruct the I/O Queue to read from the specified handle. This function
+ * returns immediately (i.e. non-blocking) regardless whether some data has
+ * been transfered. If the operation can't complete immediately, caller will
+ * be notified about the completion when it calls pj_ioqueue_poll(). If data
+ * is immediately available, the function will return PJ_SUCCESS and the
+ * callback WILL NOT be called.
+ *
+ * @param key The key that uniquely identifies the handle.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called. Caller must make sure that this key remains
+ * valid until the function completes.
+ * @param buffer The buffer to hold the read data. The caller MUST make sure
+ * that this buffer remain valid until the framework completes
+ * reading the handle.
+ * @param length On input, it specifies the size of the buffer. If data is
+ * available to be read immediately, the function returns
+ * PJ_SUCCESS and this argument will be filled with the
+ * amount of data read. If the function is pending, caller
+ * will be notified about the amount of data read in the
+ * callback. This parameter can point to local variable in
+ * caller's stack and doesn't have to remain valid for the
+ * duration of pending operation.
+ * @param flags Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then
+ * the function will never return PJ_SUCCESS.
+ *
+ * @return
+ * - PJ_SUCCESS If immediate data has been received in the buffer. In this
+ * case, the callback WILL NOT be called.
+ * - PJ_EPENDING If the operation has been queued, and the callback will be
+ * called when data has been received.
+ * - non-zero The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ void *buffer,
+ pj_ssize_t *length,
+ pj_uint32_t flags );
+
+/**
+ * This function behaves similarly as #pj_ioqueue_recv(), except that it is
+ * normally called for socket, and the remote address will also be returned
+ * along with the data. Caller MUST make sure that both buffer and addr
+ * remain valid until the framework completes reading the data.
+ *
+ * @param key The key that uniquely identifies the handle.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called.
+ * @param buffer The buffer to hold the read data. The caller MUST make sure
+ * that this buffer remain valid until the framework completes
+ * reading the handle.
+ * @param length On input, it specifies the size of the buffer. If data is
+ * available to be read immediately, the function returns
+ * PJ_SUCCESS and this argument will be filled with the
+ * amount of data read. If the function is pending, caller
+ * will be notified about the amount of data read in the
+ * callback. This parameter can point to local variable in
+ * caller's stack and doesn't have to remain valid for the
+ * duration of pending operation.
+ * @param flags Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then
+ * the function will never return PJ_SUCCESS.
+ * @param addr Optional Pointer to buffer to receive the address.
+ * @param addrlen On input, specifies the length of the address buffer.
+ * On output, it will be filled with the actual length of
+ * the address. This argument can be NULL if \c addr is not
+ * specified.
+ *
+ * @return
+ * - PJ_SUCCESS If immediate data has been received. In this case, the
+ * callback must have been called before this function
+ * returns, and no pending operation is scheduled.
+ * - PJ_EPENDING If the operation has been queued.
+ * - non-zero The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ void *buffer,
+ pj_ssize_t *length,
+ pj_uint32_t flags,
+ pj_sockaddr_t *addr,
+ int *addrlen);
+
+/**
+ * Instruct the I/O Queue to write to the handle. This function will return
+ * immediately (i.e. non-blocking) regardless whether some data has been
+ * transfered. If the function can't complete immediately, the caller will
+ * be notified about the completion when it calls pj_ioqueue_poll(). If
+ * operation completes immediately and data has been transfered, the function
+ * returns PJ_SUCCESS and the callback will NOT be called.
+ *
+ * @param key The key that identifies the handle.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called.
+ * @param data The data to send. Caller MUST make sure that this buffer
+ * remains valid until the write operation completes.
+ * @param length On input, it specifies the length of data to send. When
+ * data was sent immediately, this function returns PJ_SUCCESS
+ * and this parameter contains the length of data sent. If
+ * data can not be sent immediately, an asynchronous operation
+ * is scheduled and caller will be notified via callback the
+ * number of bytes sent. This parameter can point to local
+ * variable on caller's stack and doesn't have to remain
+ * valid until the operation has completed.
+ * @param flags Send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then
+ * the function will never return PJ_SUCCESS.
+ *
+ * @return
+ * - PJ_SUCCESS If data was immediately transfered. In this case, no
+ * pending operation has been scheduled and the callback
+ * WILL NOT be called.
+ * - PJ_EPENDING If the operation has been queued. Once data base been
+ * transfered, the callback will be called.
+ * - non-zero The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ const void *data,
+ pj_ssize_t *length,
+ pj_uint32_t flags );
+
+
+/**
+ * Instruct the I/O Queue to write to the handle. This function will return
+ * immediately (i.e. non-blocking) regardless whether some data has been
+ * transfered. If the function can't complete immediately, the caller will
+ * be notified about the completion when it calls pj_ioqueue_poll(). If
+ * operation completes immediately and data has been transfered, the function
+ * returns PJ_SUCCESS and the callback will NOT be called.
+ *
+ * @param key the key that identifies the handle.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called.
+ * @param data the data to send. Caller MUST make sure that this buffer
+ * remains valid until the write operation completes.
+ * @param length On input, it specifies the length of data to send. When
+ * data was sent immediately, this function returns PJ_SUCCESS
+ * and this parameter contains the length of data sent. If
+ * data can not be sent immediately, an asynchronous operation
+ * is scheduled and caller will be notified via callback the
+ * number of bytes sent. This parameter can point to local
+ * variable on caller's stack and doesn't have to remain
+ * valid until the operation has completed.
+ * @param flags send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then
+ * the function will never return PJ_SUCCESS.
+ * @param addr Optional remote address.
+ * @param addrlen Remote address length, \c addr is specified.
+ *
+ * @return
+ * - PJ_SUCCESS If data was immediately written.
+ * - PJ_EPENDING If the operation has been queued.
+ * - non-zero The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ const void *data,
+ pj_ssize_t *length,
+ pj_uint32_t flags,
+ const pj_sockaddr_t *addr,
+ int addrlen);
+
+
+/**
+ * !}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJ_IOQUEUE_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/ip_helper.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/ip_helper.h
new file mode 100644
index 0000000..01de7d9
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/ip_helper.h
@@ -0,0 +1,97 @@
+/* $Id: ip_helper.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_IP_ROUTE_H__
+#define __PJ_IP_ROUTE_H__
+
+/**
+ * @file ip_helper.h
+ * @brief IP helper API
+ */
+
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup pj_ip_helper IP Interface and Routing Helper
+ * @ingroup PJ_IO
+ * @{
+ *
+ * This module provides functions to query local host's IP interface and
+ * routing table.
+ */
+
+/**
+ * This structure describes IP routing entry.
+ */
+typedef union pj_ip_route_entry
+{
+ /** IP routing entry for IP version 4 routing */
+ struct
+ {
+ pj_in_addr if_addr; /**< Local interface IP address. */
+ pj_in_addr dst_addr; /**< Destination IP address. */
+ pj_in_addr mask; /**< Destination mask. */
+ } ipv4;
+} pj_ip_route_entry;
+
+
+/**
+ * Enumerate the local IP interfaces currently active in the host.
+ *
+ * @param af Family of the address to be retrieved. Application
+ * may specify pj_AF_UNSPEC() to retrieve all addresses,
+ * or pj_AF_INET() or pj_AF_INET6() to retrieve interfaces
+ * with specific address family.
+ * @param count On input, specify the number of entries. On output,
+ * it will be filled with the actual number of entries.
+ * @param ifs Array of socket addresses, which address part will
+ * be filled with the interface address. The address
+ * family part will be initialized with the address
+ * family of the IP address.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_enum_ip_interface(int af,
+ unsigned *count,
+ pj_sockaddr ifs[]);
+
+
+/**
+ * Enumerate the IP routing table for this host.
+ *
+ * @param count On input, specify the number of routes entries. On output,
+ * it will be filled with the actual number of route entries.
+ * @param routes Array of IP routing entries.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_enum_ip_route(unsigned *count,
+ pj_ip_route_entry routes[]);
+
+
+
+/** @} */
+
+PJ_END_DECL
+
+
+#endif /* __PJ_IP_ROUTE_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/list.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/list.h
new file mode 100644
index 0000000..4955ba1
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/list.h
@@ -0,0 +1,273 @@
+/* $Id: list.h 2872 2009-08-12 22:31:49Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_LIST_H__
+#define __PJ_LIST_H__
+
+/**
+ * @file list.h
+ * @brief Linked List data structure.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/*
+ * @defgroup PJ_DS Data Structure.
+ */
+
+/**
+ * @defgroup PJ_LIST Linked List
+ * @ingroup PJ_DS
+ * @{
+ *
+ * List in PJLIB is implemented as doubly-linked list, and it won't require
+ * dynamic memory allocation (just as all PJLIB data structures). The list here
+ * should be viewed more like a low level C list instead of high level C++ list
+ * (which normally are easier to use but require dynamic memory allocations),
+ * therefore all caveats with C list apply here too (such as you can NOT put
+ * a node in more than one lists).
+ *
+ * \section pj_list_example_sec Examples
+ *
+ * See below for examples on how to manipulate linked list:
+ * - @ref page_pjlib_samples_list_c
+ * - @ref page_pjlib_list_test
+ */
+
+
+/**
+ * Use this macro in the start of the structure declaration to declare that
+ * the structure can be used in the linked list operation. This macro simply
+ * declares additional member @a prev and @a next to the structure.
+ * @hideinitializer
+ */
+#define PJ_DECL_LIST_MEMBER(type) \
+ /** List @a prev. */ \
+ type *prev; \
+ /** List @a next. */ \
+ type *next
+
+
+/**
+ * This structure describes generic list node and list. The owner of this list
+ * must initialize the 'value' member to an appropriate value (typically the
+ * owner itself).
+ */
+struct pj_list
+{
+ PJ_DECL_LIST_MEMBER(void);
+};
+
+
+/**
+ * Initialize the list.
+ * Initially, the list will have no member, and function pj_list_empty() will
+ * always return nonzero (which indicates TRUE) for the newly initialized
+ * list.
+ *
+ * @param node The list head.
+ */
+PJ_INLINE(void) pj_list_init(pj_list_type * node)
+{
+ ((pj_list*)node)->next = ((pj_list*)node)->prev = node;
+}
+
+
+/**
+ * Check that the list is empty.
+ *
+ * @param node The list head.
+ *
+ * @return Non-zero if the list is empty, or zero if it is not empty.
+ *
+ */
+PJ_INLINE(int) pj_list_empty(const pj_list_type * node)
+{
+ return ((pj_list*)node)->next == node;
+}
+
+
+/**
+ * Insert the node to the list before the specified element position.
+ *
+ * @param pos The element to which the node will be inserted before.
+ * @param node The element to be inserted.
+ *
+ * @return void.
+ */
+PJ_IDECL(void) pj_list_insert_before(pj_list_type *pos, pj_list_type *node);
+
+
+/**
+ * Insert the node to the back of the list. This is just an alias for
+ * #pj_list_insert_before().
+ *
+ * @param list The list.
+ * @param node The element to be inserted.
+ */
+PJ_INLINE(void) pj_list_push_back(pj_list_type *list, pj_list_type *node)
+{
+ pj_list_insert_before(list, node);
+}
+
+
+/**
+ * Inserts all nodes in \a nodes to the target list.
+ *
+ * @param lst The target list.
+ * @param nodes Nodes list.
+ */
+PJ_IDECL(void) pj_list_insert_nodes_before(pj_list_type *lst,
+ pj_list_type *nodes);
+
+/**
+ * Insert a node to the list after the specified element position.
+ *
+ * @param pos The element in the list which will precede the inserted
+ * element.
+ * @param node The element to be inserted after the position element.
+ *
+ * @return void.
+ */
+PJ_IDECL(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node);
+
+
+/**
+ * Insert the node to the front of the list. This is just an alias for
+ * #pj_list_insert_after().
+ *
+ * @param list The list.
+ * @param node The element to be inserted.
+ */
+PJ_INLINE(void) pj_list_push_front(pj_list_type *list, pj_list_type *node)
+{
+ pj_list_insert_after(list, node);
+}
+
+
+/**
+ * Insert all nodes in \a nodes to the target list.
+ *
+ * @param lst The target list.
+ * @param nodes Nodes list.
+ */
+PJ_IDECL(void) pj_list_insert_nodes_after(pj_list_type *lst,
+ pj_list_type *nodes);
+
+
+/**
+ * Remove elements from the source list, and insert them to the destination
+ * list. The elements of the source list will occupy the
+ * front elements of the target list. Note that the node pointed by \a list2
+ * itself is not considered as a node, but rather as the list descriptor, so
+ * it will not be inserted to the \a list1. The elements to be inserted starts
+ * at \a list2->next. If \a list2 is to be included in the operation, use
+ * \a pj_list_insert_nodes_before.
+ *
+ * @param list1 The destination list.
+ * @param list2 The source list.
+ *
+ * @return void.
+ */
+PJ_IDECL(void) pj_list_merge_first(pj_list_type *list1, pj_list_type *list2);
+
+
+/**
+ * Remove elements from the second list argument, and insert them to the list
+ * in the first argument. The elements from the second list will be appended
+ * to the first list. Note that the node pointed by \a list2
+ * itself is not considered as a node, but rather as the list descriptor, so
+ * it will not be inserted to the \a list1. The elements to be inserted starts
+ * at \a list2->next. If \a list2 is to be included in the operation, use
+ * \a pj_list_insert_nodes_before.
+ *
+ * @param list1 The element in the list which will precede the inserted
+ * element.
+ * @param list2 The element in the list to be inserted.
+ *
+ * @return void.
+ */
+PJ_IDECL(void) pj_list_merge_last( pj_list_type *list1, pj_list_type *list2);
+
+
+/**
+ * Erase the node from the list it currently belongs.
+ *
+ * @param node The element to be erased.
+ */
+PJ_IDECL(void) pj_list_erase(pj_list_type *node);
+
+
+/**
+ * Find node in the list.
+ *
+ * @param list The list head.
+ * @param node The node element to be searched.
+ *
+ * @return The node itself if it is found in the list, or NULL if it is not
+ * found in the list.
+ */
+PJ_IDECL(pj_list_type*) pj_list_find_node(pj_list_type *list,
+ pj_list_type *node);
+
+
+/**
+ * Search the list for the specified value, using the specified comparison
+ * function. This function iterates on nodes in the list, started with the
+ * first node, and call the user supplied comparison function until the
+ * comparison function returns ZERO.
+ *
+ * @param list The list head.
+ * @param value The user defined value to be passed in the comparison
+ * function
+ * @param comp The comparison function, which should return ZERO to
+ * indicate that the searched value is found.
+ *
+ * @return The first node that matched, or NULL if it is not found.
+ */
+PJ_IDECL(pj_list_type*) pj_list_search(pj_list_type *list, void *value,
+ int (*comp)(void *value,
+ const pj_list_type *node)
+ );
+
+
+/**
+ * Traverse the list to get the number of elements in the list.
+ *
+ * @param list The list head.
+ *
+ * @return Number of elements.
+ */
+PJ_IDECL(pj_size_t) pj_list_size(const pj_list_type *list);
+
+
+/**
+ * @}
+ */
+
+#if PJ_FUNCTIONS_ARE_INLINED
+# include "list_i.h"
+#endif
+
+PJ_END_DECL
+
+#endif /* __PJ_LIST_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/list_i.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/list_i.h
new file mode 100644
index 0000000..d99f782
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/list_i.h
@@ -0,0 +1,121 @@
+/* $Id: list_i.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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
+ */
+
+
+/* Internal */
+PJ_INLINE(void) pj_link_node(pj_list_type *prev, pj_list_type *next)
+{
+ ((pj_list*)prev)->next = next;
+ ((pj_list*)next)->prev = prev;
+}
+
+PJ_IDEF(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node)
+{
+ ((pj_list*)node)->prev = pos;
+ ((pj_list*)node)->next = ((pj_list*)pos)->next;
+ ((pj_list*) ((pj_list*)pos)->next) ->prev = node;
+ ((pj_list*)pos)->next = node;
+}
+
+
+PJ_IDEF(void) pj_list_insert_before(pj_list_type *pos, pj_list_type *node)
+{
+ pj_list_insert_after(((pj_list*)pos)->prev, node);
+}
+
+
+PJ_IDEF(void) pj_list_insert_nodes_after(pj_list_type *pos, pj_list_type *lst)
+{
+ pj_list *lst_last = (pj_list *) ((pj_list*)lst)->prev;
+ pj_list *pos_next = (pj_list *) ((pj_list*)pos)->next;
+
+ pj_link_node(pos, lst);
+ pj_link_node(lst_last, pos_next);
+}
+
+PJ_IDEF(void) pj_list_insert_nodes_before(pj_list_type *pos, pj_list_type *lst)
+{
+ pj_list_insert_nodes_after(((pj_list*)pos)->prev, lst);
+}
+
+PJ_IDEF(void) pj_list_merge_last(pj_list_type *lst1, pj_list_type *lst2)
+{
+ if (!pj_list_empty(lst2)) {
+ pj_link_node(((pj_list*)lst1)->prev, ((pj_list*)lst2)->next);
+ pj_link_node(((pj_list*)lst2)->prev, lst1);
+ pj_list_init(lst2);
+ }
+}
+
+PJ_IDEF(void) pj_list_merge_first(pj_list_type *lst1, pj_list_type *lst2)
+{
+ if (!pj_list_empty(lst2)) {
+ pj_link_node(((pj_list*)lst2)->prev, ((pj_list*)lst1)->next);
+ pj_link_node(((pj_list*)lst1), ((pj_list*)lst2)->next);
+ pj_list_init(lst2);
+ }
+}
+
+PJ_IDEF(void) pj_list_erase(pj_list_type *node)
+{
+ pj_link_node( ((pj_list*)node)->prev, ((pj_list*)node)->next);
+
+ /* It'll be safer to init the next/prev fields to itself, to
+ * prevent multiple erase() from corrupting the list. See
+ * ticket #520 for one sample bug.
+ */
+ pj_list_init(node);
+}
+
+
+PJ_IDEF(pj_list_type*) pj_list_find_node(pj_list_type *list, pj_list_type *node)
+{
+ pj_list *p = (pj_list *) ((pj_list*)list)->next;
+ while (p != list && p != node)
+ p = (pj_list *) p->next;
+
+ return p==node ? p : NULL;
+}
+
+
+PJ_IDEF(pj_list_type*) pj_list_search(pj_list_type *list, void *value,
+ int (*comp)(void *value, const pj_list_type *node))
+{
+ pj_list *p = (pj_list *) ((pj_list*)list)->next;
+ while (p != list && (*comp)(value, p) != 0)
+ p = (pj_list *) p->next;
+
+ return p==list ? NULL : p;
+}
+
+
+PJ_IDEF(pj_size_t) pj_list_size(const pj_list_type *list)
+{
+ const pj_list *node = (const pj_list*) ((const pj_list*)list)->next;
+ pj_size_t count = 0;
+
+ while (node != list) {
+ ++count;
+ node = (pj_list*)node->next;
+ }
+
+ return count;
+}
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/lock.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/lock.h
new file mode 100644
index 0000000..6be48ef
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/lock.h
@@ -0,0 +1,154 @@
+/* $Id: lock.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_LOCK_H__
+#define __PJ_LOCK_H__
+
+/**
+ * @file lock.h
+ * @brief Higher abstraction for locking objects.
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_LOCK Lock Objects
+ * @ingroup PJ_OS
+ * @{
+ *
+ * <b>Lock Objects</b> are higher abstraction for different lock mechanisms.
+ * It offers the same API for manipulating different lock types (e.g.
+ * @ref PJ_MUTEX "mutex", @ref PJ_SEM "semaphores", or null locks).
+ * Because Lock Objects have the same API for different types of lock
+ * implementation, it can be passed around in function arguments. As the
+ * result, it can be used to control locking policy for a particular
+ * feature.
+ */
+
+
+/**
+ * Create simple, non recursive mutex lock object.
+ *
+ * @param pool Memory pool.
+ * @param name Lock object's name.
+ * @param lock Pointer to store the returned handle.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool,
+ const char *name,
+ pj_lock_t **lock );
+
+/**
+ * Create recursive mutex lock object.
+ *
+ * @param pool Memory pool.
+ * @param name Lock object's name.
+ * @param lock Pointer to store the returned handle.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool,
+ const char *name,
+ pj_lock_t **lock );
+
+
+/**
+ * Create NULL mutex. A NULL mutex doesn't actually have any synchronization
+ * object attached to it.
+ *
+ * @param pool Memory pool.
+ * @param name Lock object's name.
+ * @param lock Pointer to store the returned handle.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool,
+ const char *name,
+ pj_lock_t **lock );
+
+
+#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
+/**
+ * Create semaphore lock object.
+ *
+ * @param pool Memory pool.
+ * @param name Lock object's name.
+ * @param initial Initial value of the semaphore.
+ * @param max Maximum value of the semaphore.
+ * @param lock Pointer to store the returned handle.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_create_semaphore( pj_pool_t *pool,
+ const char *name,
+ unsigned initial,
+ unsigned max,
+ pj_lock_t **lock );
+
+#endif /* PJ_HAS_SEMAPHORE */
+
+/**
+ * Acquire lock on the specified lock object.
+ *
+ * @param lock The lock object.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_acquire( pj_lock_t *lock );
+
+
+/**
+ * Try to acquire lock on the specified lock object.
+ *
+ * @param lock The lock object.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock );
+
+
+/**
+ * Release lock on the specified lock object.
+ *
+ * @param lock The lock object.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_release( pj_lock_t *lock );
+
+
+/**
+ * Destroy the lock object.
+ *
+ * @param lock The lock object.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_destroy( pj_lock_t *lock );
+
+
+/** @} */
+
+PJ_END_DECL
+
+
+#endif /* __PJ_LOCK_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/log.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/log.h
new file mode 100644
index 0000000..621490c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/log.h
@@ -0,0 +1,402 @@
+/* $Id: log.h 2853 2009-08-05 10:58:02Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_LOG_H__
+#define __PJ_LOG_H__
+
+/**
+ * @file log.h
+ * @brief Logging Utility.
+ */
+
+#include <pj/types.h>
+#include <stdarg.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_MISC Miscelaneous
+ */
+
+/**
+ * @defgroup PJ_LOG Logging Facility
+ * @ingroup PJ_MISC
+ * @{
+ *
+ * The PJLIB logging facility is a configurable, flexible, and convenient
+ * way to write logging or trace information.
+ *
+ * To write to the log, one uses construct like below:
+ *
+ * <pre>
+ * ...
+ * PJ_LOG(3, ("main.c", "Starting hello..."));
+ * ...
+ * PJ_LOG(3, ("main.c", "Hello world from process %d", pj_getpid()));
+ * ...
+ * </pre>
+ *
+ * In the above example, the number @b 3 controls the verbosity level of
+ * the information (which means "information", by convention). The string
+ * "main.c" specifies the source or sender of the message.
+ *
+ *
+ * \section pj_log_quick_sample_sec Examples
+ *
+ * For examples, see:
+ * - @ref page_pjlib_samples_log_c.
+ *
+ */
+
+/**
+ * Log decoration flag, to be specified with #pj_log_set_decor().
+ */
+enum pj_log_decoration
+{
+ PJ_LOG_HAS_DAY_NAME = 1, /**< Include day name [default: no] */
+ PJ_LOG_HAS_YEAR = 2, /**< Include year digit [no] */
+ PJ_LOG_HAS_MONTH = 4, /**< Include month [no] */
+ PJ_LOG_HAS_DAY_OF_MON = 8, /**< Include day of month [no] */
+ PJ_LOG_HAS_TIME = 16, /**< Include time [yes] */
+ PJ_LOG_HAS_MICRO_SEC = 32, /**< Include microseconds [yes] */
+ PJ_LOG_HAS_SENDER = 64, /**< Include sender in the log [yes] */
+ PJ_LOG_HAS_NEWLINE = 128, /**< Terminate each call with newline [yes] */
+ PJ_LOG_HAS_CR = 256, /**< Include carriage return [no] */
+ PJ_LOG_HAS_SPACE = 512, /**< Include two spaces before log [yes] */
+ PJ_LOG_HAS_COLOR = 1024, /**< Colorize logs [yes on win32] */
+ PJ_LOG_HAS_LEVEL_TEXT = 2048, /**< Include level text string [no] */
+ PJ_LOG_HAS_THREAD_ID = 4096 /**< Include thread identification [no] */
+};
+
+/**
+ * Write log message.
+ * This is the main macro used to write text to the logging backend.
+ *
+ * @param level The logging verbosity level. Lower number indicates higher
+ * importance, with level zero indicates fatal error. Only
+ * numeral argument is permitted (e.g. not variable).
+ * @param arg Enclosed 'printf' like arguments, with the first
+ * argument is the sender, the second argument is format
+ * string and the following arguments are variable number of
+ * arguments suitable for the format string.
+ *
+ * Sample:
+ * \verbatim
+ PJ_LOG(2, (__FILE__, "current value is %d", value));
+ \endverbatim
+ * @hideinitializer
+ */
+#define PJ_LOG(level,arg) do { \
+ if (level <= pj_log_get_level()) \
+ pj_log_wrapper_##level(arg); \
+ } while (0)
+
+/**
+ * Signature for function to be registered to the logging subsystem to
+ * write the actual log message to some output device.
+ *
+ * @param level Log level.
+ * @param data Log message, which will be NULL terminated.
+ * @param len Message length.
+ */
+typedef void pj_log_func(int level, const char *data, int len);
+
+/**
+ * Default logging writer function used by front end logger function.
+ * This function will print the log message to stdout only.
+ * Application normally should NOT need to call this function, but
+ * rather use the PJ_LOG macro.
+ *
+ * @param level Log level.
+ * @param buffer Log message.
+ * @param len Message length.
+ */
+PJ_DECL(void) pj_log_write(int level, const char *buffer, int len);
+
+
+#if PJ_LOG_MAX_LEVEL >= 1
+
+/**
+ * Write to log.
+ *
+ * @param sender Source of the message.
+ * @param level Verbosity level.
+ * @param format Format.
+ * @param marker Marker.
+ */
+PJ_DECL(void) pj_log(const char *sender, int level,
+ const char *format, va_list marker);
+
+/**
+ * Change log output function. The front-end logging functions will call
+ * this function to write the actual message to the desired device.
+ * By default, the front-end functions use pj_log_write() to write
+ * the messages, unless it's changed by calling this function.
+ *
+ * @param func The function that will be called to write the log
+ * messages to the desired device.
+ */
+PJ_DECL(void) pj_log_set_log_func( pj_log_func *func );
+
+/**
+ * Get the current log output function that is used to write log messages.
+ *
+ * @return Current log output function.
+ */
+PJ_DECL(pj_log_func*) pj_log_get_log_func(void);
+
+/**
+ * Set maximum log level. Application can call this function to set
+ * the desired level of verbosity of the logging messages. The bigger the
+ * value, the more verbose the logging messages will be printed. However,
+ * the maximum level of verbosity can not exceed compile time value of
+ * PJ_LOG_MAX_LEVEL.
+ *
+ * @param level The maximum level of verbosity of the logging
+ * messages (6=very detailed..1=error only, 0=disabled)
+ */
+PJ_DECL(void) pj_log_set_level(int level);
+
+/**
+ * Get current maximum log verbositylevel.
+ *
+ * @return Current log maximum level.
+ */
+#if 1
+PJ_DECL(int) pj_log_get_level(void);
+#else
+PJ_DECL_DATA(int) pj_log_max_level;
+#define pj_log_get_level() pj_log_max_level
+#endif
+
+/**
+ * Set log decoration. The log decoration flag controls what are printed
+ * to output device alongside the actual message. For example, application
+ * can specify that date/time information should be displayed with each
+ * log message.
+ *
+ * @param decor Bitmask combination of #pj_log_decoration to control
+ * the layout of the log message.
+ */
+PJ_DECL(void) pj_log_set_decor(unsigned decor);
+
+/**
+ * Get current log decoration flag.
+ *
+ * @return Log decoration flag.
+ */
+PJ_DECL(unsigned) pj_log_get_decor(void);
+
+
+/**
+ * Set color of log messages.
+ *
+ * @param level Log level which color will be changed.
+ * @param color Desired color.
+ */
+PJ_DECL(void) pj_log_set_color(int level, pj_color_t color);
+
+/**
+ * Get color of log messages.
+ *
+ * @param level Log level which color will be returned.
+ * @return Log color.
+ */
+PJ_DECL(pj_color_t) pj_log_get_color(int level);
+
+/**
+ * Internal function to be called by pj_init()
+ */
+pj_status_t pj_log_init(void);
+
+#else /* #if PJ_LOG_MAX_LEVEL >= 1 */
+
+/**
+ * Change log output function. The front-end logging functions will call
+ * this function to write the actual message to the desired device.
+ * By default, the front-end functions use pj_log_write() to write
+ * the messages, unless it's changed by calling this function.
+ *
+ * @param func The function that will be called to write the log
+ * messages to the desired device.
+ */
+# define pj_log_set_log_func(func)
+
+/**
+ * Set maximum log level. Application can call this function to set
+ * the desired level of verbosity of the logging messages. The bigger the
+ * value, the more verbose the logging messages will be printed. However,
+ * the maximum level of verbosity can not exceed compile time value of
+ * PJ_LOG_MAX_LEVEL.
+ *
+ * @param level The maximum level of verbosity of the logging
+ * messages (6=very detailed..1=error only, 0=disabled)
+ */
+# define pj_log_set_level(level)
+
+/**
+ * Set log decoration. The log decoration flag controls what are printed
+ * to output device alongside the actual message. For example, application
+ * can specify that date/time information should be displayed with each
+ * log message.
+ *
+ * @param decor Bitmask combination of #pj_log_decoration to control
+ * the layout of the log message.
+ */
+# define pj_log_set_decor(decor)
+
+/**
+ * Set color of log messages.
+ *
+ * @param level Log level which color will be changed.
+ * @param color Desired color.
+ */
+# define pj_log_set_color(level, color)
+
+/**
+ * Get current maximum log verbositylevel.
+ *
+ * @return Current log maximum level.
+ */
+# define pj_log_get_level() 0
+
+/**
+ * Get current log decoration flag.
+ *
+ * @return Log decoration flag.
+ */
+# define pj_log_get_decor() 0
+
+/**
+ * Get color of log messages.
+ *
+ * @param level Log level which color will be returned.
+ * @return Log color.
+ */
+# define pj_log_get_color(level) 0
+
+
+/**
+ * Internal.
+ */
+# define pj_log_init() PJ_SUCCESS
+
+#endif /* #if PJ_LOG_MAX_LEVEL >= 1 */
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/*
+ * Log functions implementation prototypes.
+ * These functions are called by PJ_LOG macros according to verbosity
+ * level specified when calling the macro. Applications should not normally
+ * need to call these functions directly.
+ */
+
+/**
+ * @def pj_log_wrapper_1(arg)
+ * Internal function to write log with verbosity 1. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 1.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 1
+ #define pj_log_wrapper_1(arg) pj_log_1 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_log_1(const char *src, const char *format, ...);
+#else
+ #define pj_log_wrapper_1(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_2(arg)
+ * Internal function to write log with verbosity 2. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 2.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 2
+ #define pj_log_wrapper_2(arg) pj_log_2 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_log_2(const char *src, const char *format, ...);
+#else
+ #define pj_log_wrapper_2(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_3(arg)
+ * Internal function to write log with verbosity 3. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 3.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 3
+ #define pj_log_wrapper_3(arg) pj_log_3 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_log_3(const char *src, const char *format, ...);
+#else
+ #define pj_log_wrapper_3(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_4(arg)
+ * Internal function to write log with verbosity 4. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 4.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 4
+ #define pj_log_wrapper_4(arg) pj_log_4 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_log_4(const char *src, const char *format, ...);
+#else
+ #define pj_log_wrapper_4(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_5(arg)
+ * Internal function to write log with verbosity 5. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 5.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 5
+ #define pj_log_wrapper_5(arg) pj_log_5 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_log_5(const char *src, const char *format, ...);
+#else
+ #define pj_log_wrapper_5(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_6(arg)
+ * Internal function to write log with verbosity 6. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 6.
+ * @param arg Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 6
+ #define pj_log_wrapper_6(arg) pj_log_6 arg
+ /** Internal function. */
+ PJ_DECL(void) pj_log_6(const char *src, const char *format, ...);
+#else
+ #define pj_log_wrapper_6(arg)
+#endif
+
+
+PJ_END_DECL
+
+#endif /* __PJ_LOG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/math.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/math.h
new file mode 100644
index 0000000..dea6bab
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/math.h
@@ -0,0 +1,197 @@
+/* $Id: math.h 2844 2009-07-29 12:14:21Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_MATH_H__
+#define __PJ_MATH_H__
+
+/**
+ * @file math.h
+ * @brief Mathematics and Statistics.
+ */
+
+#include <pj/string.h>
+#include <pj/compat/high_precision.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup pj_math Mathematics and Statistics
+ * @ingroup PJ_MISC
+ * @{
+ *
+ * Provides common mathematics constants and operations, and also standard
+ * statistics calculation (min, max, mean, standard deviation). Statistics
+ * calculation is done in realtime (statistics state is updated on time each
+ * new sample comes).
+ */
+
+/**
+ * Mathematical constants
+ */
+#define PJ_PI 3.14159265358979323846 /* pi */
+#define PJ_1_PI 0.318309886183790671538 /* 1/pi */
+
+/**
+ * Mathematical macro
+ */
+#define PJ_ABS(x) ((x) > 0 ? (x) : -(x))
+#define PJ_MAX(x, y) ((x) > (y)? (x) : (y))
+#define PJ_MIN(x, y) ((x) < (y)? (x) : (y))
+
+/**
+ * This structure describes statistics state.
+ */
+typedef struct pj_math_stat
+{
+ int n; /* number of samples */
+ int max; /* maximum value */
+ int min; /* minimum value */
+ int last; /* last value */
+ int mean; /* mean */
+
+ /* Private members */
+#if PJ_HAS_FLOATING_POINT
+ float fmean_; /* mean(floating point) */
+#else
+ int mean_res_; /* mean residu */
+#endif
+ pj_highprec_t m2_; /* variance * n */
+} pj_math_stat;
+
+/**
+ * Calculate integer square root of an integer.
+ *
+ * @param i Integer to be calculated.
+ *
+ * @return Square root result.
+ */
+PJ_INLINE(unsigned) pj_isqrt(unsigned i)
+{
+ unsigned res = 1, prev;
+
+ /* Rough guess, calculate half bit of input */
+ prev = i >> 2;
+ while (prev) {
+ prev >>= 2;
+ res <<= 1;
+ }
+
+ /* Babilonian method */
+ do {
+ prev = res;
+ res = (prev + i/prev) >> 1;
+ } while ((prev+res)>>1 != res);
+
+ return res;
+}
+
+/**
+ * Initialize statistics state.
+ *
+ * @param stat Statistic state.
+ */
+PJ_INLINE(void) pj_math_stat_init(pj_math_stat *stat)
+{
+ pj_bzero(stat, sizeof(pj_math_stat));
+}
+
+/**
+ * Update statistics state as a new sample comes.
+ *
+ * @param stat Statistic state.
+ * @param val The new sample data.
+ */
+PJ_INLINE(void) pj_math_stat_update(pj_math_stat *stat, int val)
+{
+#if PJ_HAS_FLOATING_POINT
+ float delta;
+#else
+ int delta;
+#endif
+
+ stat->last = val;
+
+ if (stat->n++) {
+ if (stat->min > val)
+ stat->min = val;
+ if (stat->max < val)
+ stat->max = val;
+ } else {
+ stat->min = stat->max = val;
+ }
+
+#if PJ_HAS_FLOATING_POINT
+ delta = val - stat->fmean_;
+ stat->fmean_ += delta/stat->n;
+
+ /* Return mean value with 'rounding' */
+ stat->mean = (int) (stat->fmean_ + 0.5);
+
+ stat->m2_ += (int)(delta * (val-stat->fmean_));
+#else
+ delta = val - stat->mean;
+ stat->mean += delta/stat->n;
+ stat->mean_res_ += delta % stat->n;
+ if (stat->mean_res_ >= stat->n) {
+ ++stat->mean;
+ stat->mean_res_ -= stat->n;
+ } else if (stat->mean_res_ <= -stat->n) {
+ --stat->mean;
+ stat->mean_res_ += stat->n;
+ }
+
+ stat->m2_ += delta * (val-stat->mean);
+#endif
+}
+
+/**
+ * Get the standard deviation of specified statistics state.
+ *
+ * @param stat Statistic state.
+ *
+ * @return The standard deviation.
+ */
+PJ_INLINE(unsigned) pj_math_stat_get_stddev(const pj_math_stat *stat)
+{
+ if (stat->n == 0) return 0;
+ return (pj_isqrt((unsigned)(stat->m2_/stat->n)));
+}
+
+/**
+ * Set the standard deviation of statistics state. This is useful when
+ * the statistic state is operated in 'read-only' mode as a storage of
+ * statistical data.
+ *
+ * @param stat Statistic state.
+ *
+ * @param dev The standard deviation.
+ */
+PJ_INLINE(void) pj_math_stat_set_stddev(pj_math_stat *stat, unsigned dev)
+{
+ if (stat->n == 0)
+ stat->n = 1;
+ stat->m2_ = dev*dev*stat->n;
+}
+
+/** @} */
+
+PJ_END_DECL
+
+#endif /* __PJ_MATH_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/os.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/os.h
new file mode 100644
index 0000000..d74bb63
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/os.h
@@ -0,0 +1,1343 @@
+/* $Id: os.h 2843 2009-07-22 11:12:35Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_OS_H__
+#define __PJ_OS_H__
+
+/**
+ * @file os.h
+ * @brief OS dependent functions
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_OS Operating System Dependent Functionality.
+ */
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_THREAD Threads
+ * @ingroup PJ_OS
+ * @{
+ * This module provides multithreading API.
+ *
+ * \section pj_thread_examples_sec Examples
+ *
+ * For examples, please see:
+ * - \ref page_pjlib_thread_test
+ * - \ref page_pjlib_sleep_test
+ *
+ */
+
+/**
+ * Thread creation flags:
+ * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.
+ */
+typedef enum pj_thread_create_flags
+{
+ PJ_THREAD_SUSPENDED = 1
+} pj_thread_create_flags;
+
+
+/**
+ * Type of thread entry function.
+ */
+typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);
+
+/**
+ * Size of thread struct.
+ */
+#if !defined(PJ_THREAD_DESC_SIZE)
+# define PJ_THREAD_DESC_SIZE (64)
+#endif
+
+/**
+ * Thread structure, to thread's state when the thread is created by external
+ * or native API.
+ */
+typedef long pj_thread_desc[PJ_THREAD_DESC_SIZE];
+
+/**
+ * Get process ID.
+ * @return process ID.
+ */
+PJ_DECL(pj_uint32_t) pj_getpid(void);
+
+/**
+ * Create a new thread.
+ *
+ * @param pool The memory pool from which the thread record
+ * will be allocated from.
+ * @param thread_name The optional name to be assigned to the thread.
+ * @param proc Thread entry function.
+ * @param arg Argument to be passed to the thread entry function.
+ * @param stack_size The size of the stack for the new thread, or ZERO or
+ * PJ_THREAD_DEFAULT_STACK_SIZE to let the
+ * library choose the reasonable size for the stack.
+ * For some systems, the stack will be allocated from
+ * the pool, so the pool must have suitable capacity.
+ * @param flags Flags for thread creation, which is bitmask combination
+ * from enum pj_thread_create_flags.
+ * @param thread Pointer to hold the newly created thread.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_create( pj_pool_t *pool,
+ const char *thread_name,
+ pj_thread_proc *proc,
+ void *arg,
+ pj_size_t stack_size,
+ unsigned flags,
+ pj_thread_t **thread );
+
+/**
+ * Register a thread that was created by external or native API to PJLIB.
+ * This function must be called in the context of the thread being registered.
+ * When the thread is created by external function or API call,
+ * it must be 'registered' to PJLIB using pj_thread_register(), so that it can
+ * cooperate with PJLIB's framework. During registration, some data needs to
+ * be maintained, and this data must remain available during the thread's
+ * lifetime.
+ *
+ * @param thread_name The optional name to be assigned to the thread.
+ * @param desc Thread descriptor, which must be available throughout
+ * the lifetime of the thread.
+ * @param thread Pointer to hold the created thread handle.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
+ pj_thread_desc desc,
+ pj_thread_t **thread);
+
+/**
+ * Check if this thread has been registered to PJLIB.
+ *
+ * @return Non-zero if it is registered.
+ */
+PJ_DECL(pj_bool_t) pj_thread_is_registered(void);
+
+
+/**
+ * Get thread priority value for the thread.
+ *
+ * @param thread Thread handle.
+ *
+ * @return Thread priority value, or -1 on error.
+ */
+PJ_DECL(int) pj_thread_get_prio(pj_thread_t *thread);
+
+
+/**
+ * Set the thread priority. The priority value must be in the priority
+ * value range, which can be retrieved with #pj_thread_get_prio_min() and
+ * #pj_thread_get_prio_max() functions.
+ *
+ * @param thread Thread handle.
+ * @param prio New priority to be set to the thread.
+ *
+ * @return PJ_SUCCESS on success or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_set_prio(pj_thread_t *thread, int prio);
+
+/**
+ * Get the lowest priority value available for this thread.
+ *
+ * @param thread Thread handle.
+ * @return Minimum thread priority value, or -1 on error.
+ */
+PJ_DECL(int) pj_thread_get_prio_min(pj_thread_t *thread);
+
+
+/**
+ * Get the highest priority value available for this thread.
+ *
+ * @param thread Thread handle.
+ * @return Minimum thread priority value, or -1 on error.
+ */
+PJ_DECL(int) pj_thread_get_prio_max(pj_thread_t *thread);
+
+
+/**
+ * Return native handle from pj_thread_t for manipulation using native
+ * OS APIs.
+ *
+ * @param thread PJLIB thread descriptor.
+ *
+ * @return Native thread handle. For example, when the
+ * backend thread uses pthread, this function will
+ * return pointer to pthread_t, and on Windows,
+ * this function will return HANDLE.
+ */
+PJ_DECL(void*) pj_thread_get_os_handle(pj_thread_t *thread);
+
+/**
+ * Get thread name.
+ *
+ * @param thread The thread handle.
+ *
+ * @return Thread name as null terminated string.
+ */
+PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
+
+/**
+ * Resume a suspended thread.
+ *
+ * @param thread The thread handle.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
+
+/**
+ * Get the current thread.
+ *
+ * @return Thread handle of current thread.
+ */
+PJ_DECL(pj_thread_t*) pj_thread_this(void);
+
+/**
+ * Join thread, and block the caller thread until the specified thread exits.
+ * If the specified thread has already been dead, or it does not exist,
+ * the function will return immediately with successfull status.
+ *
+ * @param thread The thread handle.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
+
+
+/**
+ * Destroy thread and release resources allocated for the thread.
+ * However, the memory allocated for the pj_thread_t itself will only be released
+ * when the pool used to create the thread is destroyed.
+ *
+ * @param thread The thread handle.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
+
+
+/**
+ * Put the current thread to sleep for the specified miliseconds.
+ *
+ * @param msec Miliseconds delay.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
+
+/**
+ * @def PJ_CHECK_STACK()
+ * PJ_CHECK_STACK() macro is used to check the sanity of the stack.
+ * The OS implementation may check that no stack overflow occurs, and
+ * it also may collect statistic about stack usage.
+ */
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+
+# define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
+
+/** @internal
+ * The implementation of stack checking.
+ */
+PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
+
+/** @internal
+ * Get maximum stack usage statistic.
+ */
+PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
+
+/** @internal
+ * Dump thread stack status.
+ */
+PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
+ const char **file,
+ int *line);
+#else
+
+# define PJ_CHECK_STACK()
+/** pj_thread_get_stack_max_usage() for the thread */
+# define pj_thread_get_stack_max_usage(thread) 0
+/** pj_thread_get_stack_info() for the thread */
+# define pj_thread_get_stack_info(thread,f,l) (*(f)="",*(l)=0)
+#endif /* PJ_OS_HAS_CHECK_STACK */
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_SYMBIAN_OS Symbian OS Specific
+ * @ingroup PJ_OS
+ * @{
+ * Functionalities specific to Symbian OS.
+ *
+ * Symbian OS strongly discourages the use of polling since this wastes
+ * CPU power, and instead provides Active Object and Active Scheduler
+ * pattern to allow application (in this case, PJLIB) to register asynchronous
+ * tasks. PJLIB port for Symbian complies to this recommended behavior.
+ * As the result, few things have been changed in PJLIB for Symbian:
+ * - the timer heap (see @ref PJ_TIMER) is implemented with active
+ * object framework, and each timer entry registered to the timer
+ * heap will register an Active Object to the Active Scheduler.
+ * Because of this, polling the timer heap with pj_timer_heap_poll()
+ * is no longer necessary, and this function will just evaluate
+ * to nothing.
+ * - the ioqueue (see @ref PJ_IOQUEUE) is also implemented with
+ * active object framework, with each asynchronous operation will
+ * register an Active Object to the Active Scheduler. Because of
+ * this, polling the ioqueue with pj_ioqueue_poll() is no longer
+ * necessary, and this function will just evaluate to nothing.
+ *
+ * Since timer heap and ioqueue polling are no longer necessary, Symbian
+ * application can now poll for all events by calling
+ * \a User::WaitForAnyRequest() and \a CActiveScheduler::RunIfReady().
+ * PJLIB provides a thin wrapper which calls these two functions,
+ * called pj_symbianos_poll().
+ */
+
+/**
+ * Wait the completion of any Symbian active objects. When the timeout
+ * value is not specified (the \a ms_timeout argument is -1), this
+ * function is a thin wrapper which calls \a User::WaitForAnyRequest()
+ * and \a CActiveScheduler::RunIfReady(). If the timeout value is
+ * specified, this function will schedule a timer entry to the timer
+ * heap (which is an Active Object), to limit the wait time for event
+ * occurences. Scheduling a timer entry is an expensive operation,
+ * therefore application should only specify a timeout value when it's
+ * really necessary (for example, when it's not sure there are other
+ * Active Objects currently running in the application).
+ *
+ * @param priority The minimum priority of the Active Objects to
+ * poll, which values are from CActive::TPriority
+ * constants. If -1 is given, CActive::EPriorityStandard.
+ * priority will be used.
+ * @param ms_timeout Optional timeout to wait. Application should
+ * specify -1 to let the function wait indefinitely
+ * for any events.
+ *
+ * @return PJ_TRUE if there have been any events executed
+ * during the polling. This function will only return
+ * PJ_FALSE if \a ms_timeout argument is specified
+ * (i.e. the value is not -1) and there was no event
+ * executed when the timeout timer elapsed.
+ */
+PJ_DECL(pj_bool_t) pj_symbianos_poll(int priority, int ms_timeout);
+
+
+/**
+ * This structure declares Symbian OS specific parameters that can be
+ * specified when calling #pj_symbianos_set_params().
+ */
+typedef struct pj_symbianos_params
+{
+ /**
+ * Optional RSocketServ instance to be used by PJLIB. If this
+ * value is NULL, PJLIB will create a new RSocketServ instance
+ * when pj_init() is called.
+ */
+ void *rsocketserv;
+
+ /**
+ * Optional RConnection instance to be used by PJLIB when creating
+ * sockets. If this value is NULL, no RConnection will be
+ * specified when creating sockets.
+ */
+ void *rconnection;
+
+ /**
+ * Optional RHostResolver instance to be used by PJLIB. If this value
+ * is NULL, a new RHostResolver instance will be created when
+ * pj_init() is called.
+ */
+ void *rhostresolver;
+
+ /**
+ * Optional RHostResolver for IPv6 instance to be used by PJLIB.
+ * If this value is NULL, a new RHostResolver instance will be created
+ * when pj_init() is called.
+ */
+ void *rhostresolver6;
+
+} pj_symbianos_params;
+
+/**
+ * Specify Symbian OS parameters to be used by PJLIB. This function MUST
+ * be called before #pj_init() is called.
+ *
+ * @param prm Symbian specific parameters.
+ *
+ * @return PJ_SUCCESS if the parameters can be applied
+ * successfully.
+ */
+PJ_DECL(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm);
+
+/**
+ * Notify PJLIB that the access point connection has been down or unusable
+ * and PJLIB should not try to access the Symbian socket API (especially ones
+ * that send packets). Sending packet when RConnection is reconnected to
+ * different access point may cause the WaitForRequest() for the function to
+ * block indefinitely.
+ *
+ * @param up If set to PJ_FALSE it will cause PJLIB to not try
+ * to access socket API, and error will be returned
+ * immediately instead.
+ */
+PJ_DECL(void) pj_symbianos_set_connection_status(pj_bool_t up);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_TLS Thread Local Storage.
+ * @ingroup PJ_OS
+ * @{
+ */
+
+/**
+ * Allocate thread local storage index. The initial value of the variable at
+ * the index is zero.
+ *
+ * @param index Pointer to hold the return value.
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
+
+/**
+ * Deallocate thread local variable.
+ *
+ * @param index The variable index.
+ */
+PJ_DECL(void) pj_thread_local_free(long index);
+
+/**
+ * Set the value of thread local variable.
+ *
+ * @param index The index of the variable.
+ * @param value The value.
+ */
+PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);
+
+/**
+ * Get the value of thread local variable.
+ *
+ * @param index The index of the variable.
+ * @return The value.
+ */
+PJ_DECL(void*) pj_thread_local_get(long index);
+
+
+/**
+ * @}
+ */
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_ATOMIC Atomic Variables
+ * @ingroup PJ_OS
+ * @{
+ *
+ * This module provides API to manipulate atomic variables.
+ *
+ * \section pj_atomic_examples_sec Examples
+ *
+ * For some example codes, please see:
+ * - @ref page_pjlib_atomic_test
+ */
+
+
+/**
+ * Create atomic variable.
+ *
+ * @param pool The pool.
+ * @param initial The initial value of the atomic variable.
+ * @param atomic Pointer to hold the atomic variable upon return.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool,
+ pj_atomic_value_t initial,
+ pj_atomic_t **atomic );
+
+/**
+ * Destroy atomic variable.
+ *
+ * @param atomic_var the atomic variable.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
+
+/**
+ * Set the value of an atomic type, and return the previous value.
+ *
+ * @param atomic_var the atomic variable.
+ * @param value value to be set to the variable.
+ */
+PJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var,
+ pj_atomic_value_t value);
+
+/**
+ * Get the value of an atomic type.
+ *
+ * @param atomic_var the atomic variable.
+ *
+ * @return the value of the atomic variable.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
+
+/**
+ * Increment the value of an atomic type.
+ *
+ * @param atomic_var the atomic variable.
+ */
+PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);
+
+/**
+ * Increment the value of an atomic type and get the result.
+ *
+ * @param atomic_var the atomic variable.
+ *
+ * @return The incremented value.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);
+
+/**
+ * Decrement the value of an atomic type.
+ *
+ * @param atomic_var the atomic variable.
+ */
+PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);
+
+/**
+ * Decrement the value of an atomic type and get the result.
+ *
+ * @param atomic_var the atomic variable.
+ *
+ * @return The decremented value.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);
+
+/**
+ * Add a value to an atomic type.
+ *
+ * @param atomic_var The atomic variable.
+ * @param value Value to be added.
+ */
+PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,
+ pj_atomic_value_t value);
+
+/**
+ * Add a value to an atomic type and get the result.
+ *
+ * @param atomic_var The atomic variable.
+ * @param value Value to be added.
+ *
+ * @return The result after the addition.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
+ pj_atomic_value_t value);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_MUTEX Mutexes.
+ * @ingroup PJ_OS
+ * @{
+ *
+ * Mutex manipulation. Alternatively, application can use higher abstraction
+ * for lock objects, which provides uniform API for all kinds of lock
+ * mechanisms, including mutex. See @ref PJ_LOCK for more information.
+ */
+
+/**
+ * Mutex types:
+ * - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
+ * - PJ_MUTEX_SIMPLE: non-recursive mutex.
+ * - PJ_MUTEX_RECURSE: recursive mutex.
+ */
+typedef enum pj_mutex_type_e
+{
+ PJ_MUTEX_DEFAULT,
+ PJ_MUTEX_SIMPLE,
+ PJ_MUTEX_RECURSE
+} pj_mutex_type_e;
+
+
+/**
+ * Create mutex of the specified type.
+ *
+ * @param pool The pool.
+ * @param name Name to be associated with the mutex (for debugging).
+ * @param type The type of the mutex, of type #pj_mutex_type_e.
+ * @param mutex Pointer to hold the returned mutex instance.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool,
+ const char *name,
+ int type,
+ pj_mutex_t **mutex);
+
+/**
+ * Create simple, non-recursive mutex.
+ * This function is a simple wrapper for #pj_mutex_create to create
+ * non-recursive mutex.
+ *
+ * @param pool The pool.
+ * @param name Mutex name.
+ * @param mutex Pointer to hold the returned mutex instance.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
+ pj_mutex_t **mutex );
+
+/**
+ * Create recursive mutex.
+ * This function is a simple wrapper for #pj_mutex_create to create
+ * recursive mutex.
+ *
+ * @param pool The pool.
+ * @param name Mutex name.
+ * @param mutex Pointer to hold the returned mutex instance.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
+ const char *name,
+ pj_mutex_t **mutex );
+
+/**
+ * Acquire mutex lock.
+ *
+ * @param mutex The mutex.
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
+
+/**
+ * Release mutex lock.
+ *
+ * @param mutex The mutex.
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
+
+/**
+ * Try to acquire mutex lock.
+ *
+ * @param mutex The mutex.
+ * @return PJ_SUCCESS on success, or the error code if the
+ * lock couldn't be acquired.
+ */
+PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
+
+/**
+ * Destroy mutex.
+ *
+ * @param mutex Te mutex.
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
+
+/**
+ * Determine whether calling thread is owning the mutex (only available when
+ * PJ_DEBUG is set).
+ * @param mutex The mutex.
+ * @return Non-zero if yes.
+ */
+PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_RW_MUTEX Reader/Writer Mutex
+ * @ingroup PJ_OS
+ * @{
+ * Reader/writer mutex is a classic synchronization object where multiple
+ * readers can acquire the mutex, but only a single writer can acquire the
+ * mutex.
+ */
+
+/**
+ * Opaque declaration for reader/writer mutex.
+ * Reader/writer mutex is a classic synchronization object where multiple
+ * readers can acquire the mutex, but only a single writer can acquire the
+ * mutex.
+ */
+typedef struct pj_rwmutex_t pj_rwmutex_t;
+
+/**
+ * Create reader/writer mutex.
+ *
+ * @param pool Pool to allocate memory for the mutex.
+ * @param name Name to be assigned to the mutex.
+ * @param mutex Pointer to receive the newly created mutex.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
+ pj_rwmutex_t **mutex);
+
+/**
+ * Lock the mutex for reading.
+ *
+ * @param mutex The mutex.
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex);
+
+/**
+ * Lock the mutex for writing.
+ *
+ * @param mutex The mutex.
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex);
+
+/**
+ * Release read lock.
+ *
+ * @param mutex The mutex.
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex);
+
+/**
+ * Release write lock.
+ *
+ * @param mutex The mutex.
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex);
+
+/**
+ * Destroy reader/writer mutex.
+ *
+ * @param mutex The mutex.
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex);
+
+
+/**
+ * @}
+ */
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_CRIT_SEC Critical sections.
+ * @ingroup PJ_OS
+ * @{
+ * Critical section protection can be used to protect regions where:
+ * - mutual exclusion protection is needed.
+ * - it's rather too expensive to create a mutex.
+ * - the time spent in the region is very very brief.
+ *
+ * Critical section is a global object, and it prevents any threads from
+ * entering any regions that are protected by critical section once a thread
+ * is already in the section.
+ *
+ * Critial section is \a not recursive!
+ *
+ * Application <b>MUST NOT</b> call any functions that may cause current
+ * thread to block (such as allocating memory, performing I/O, locking mutex,
+ * etc.) while holding the critical section.
+ */
+/**
+ * Enter critical section.
+ */
+PJ_DECL(void) pj_enter_critical_section(void);
+
+/**
+ * Leave critical section.
+ */
+PJ_DECL(void) pj_leave_critical_section(void);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
+/**
+ * @defgroup PJ_SEM Semaphores.
+ * @ingroup PJ_OS
+ * @{
+ *
+ * This module provides abstraction for semaphores, where available.
+ */
+
+/**
+ * Create semaphore.
+ *
+ * @param pool The pool.
+ * @param name Name to be assigned to the semaphore (for logging purpose)
+ * @param initial The initial count of the semaphore.
+ * @param max The maximum count of the semaphore.
+ * @param sem Pointer to hold the semaphore created.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool,
+ const char *name,
+ unsigned initial,
+ unsigned max,
+ pj_sem_t **sem);
+
+/**
+ * Wait for semaphore.
+ *
+ * @param sem The semaphore.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
+
+/**
+ * Try wait for semaphore.
+ *
+ * @param sem The semaphore.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
+
+/**
+ * Release semaphore.
+ *
+ * @param sem The semaphore.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
+
+/**
+ * Destroy semaphore.
+ *
+ * @param sem The semaphore.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
+
+/**
+ * @}
+ */
+#endif /* PJ_HAS_SEMAPHORE */
+
+
+/* **************************************************************************/
+#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
+/**
+ * @defgroup PJ_EVENT Event Object.
+ * @ingroup PJ_OS
+ * @{
+ *
+ * This module provides abstraction to event object (e.g. Win32 Event) where
+ * available. Event objects can be used for synchronization among threads.
+ */
+
+/**
+ * Create event object.
+ *
+ * @param pool The pool.
+ * @param name The name of the event object (for logging purpose).
+ * @param manual_reset Specify whether the event is manual-reset
+ * @param initial Specify the initial state of the event object.
+ * @param event Pointer to hold the returned event object.
+ *
+ * @return event handle, or NULL if failed.
+ */
+PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
+ pj_bool_t manual_reset, pj_bool_t initial,
+ pj_event_t **event);
+
+/**
+ * Wait for event to be signaled.
+ *
+ * @param event The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
+
+/**
+ * Try wait for event object to be signalled.
+ *
+ * @param event The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
+
+/**
+ * Set the event object state to signaled. For auto-reset event, this
+ * will only release the first thread that are waiting on the event. For
+ * manual reset event, the state remains signaled until the event is reset.
+ * If there is no thread waiting on the event, the event object state
+ * remains signaled.
+ *
+ * @param event The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
+
+/**
+ * Set the event object to signaled state to release appropriate number of
+ * waiting threads and then reset the event object to non-signaled. For
+ * manual-reset event, this function will release all waiting threads. For
+ * auto-reset event, this function will only release one waiting thread.
+ *
+ * @param event The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
+
+/**
+ * Set the event object state to non-signaled.
+ *
+ * @param event The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
+
+/**
+ * Destroy the event object.
+ *
+ * @param event The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
+
+/**
+ * @}
+ */
+#endif /* PJ_HAS_EVENT_OBJ */
+
+/* **************************************************************************/
+/**
+ * @addtogroup PJ_TIME Time Data Type and Manipulation.
+ * @ingroup PJ_OS
+ * @{
+ * This module provides API for manipulating time.
+ *
+ * \section pj_time_examples_sec Examples
+ *
+ * For examples, please see:
+ * - \ref page_pjlib_sleep_test
+ */
+
+/**
+ * Get current time of day in local representation.
+ *
+ * @param tv Variable to store the result.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
+
+
+/**
+ * Parse time value into date/time representation.
+ *
+ * @param tv The time.
+ * @param pt Variable to store the date time result.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
+
+/**
+ * Encode date/time to time value.
+ *
+ * @param pt The date/time.
+ * @param tv Variable to store time value result.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
+
+/**
+ * Convert local time to GMT.
+ *
+ * @param tv Time to convert.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
+
+/**
+ * Convert GMT to local time.
+ *
+ * @param tv Time to convert.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
+
+/**
+ * @defgroup PJ_TERM Terminal
+ * @ingroup PJ_OS
+ * @{
+ */
+
+/**
+ * Set current terminal color.
+ *
+ * @param color The RGB color.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
+
+/**
+ * Get current terminal foreground color.
+ *
+ * @return RGB color.
+ */
+PJ_DECL(pj_color_t) pj_term_get_color(void);
+
+/**
+ * @}
+ */
+
+#endif /* PJ_TERM_HAS_COLOR */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_TIMESTAMP High Resolution Timestamp
+ * @ingroup PJ_OS
+ * @{
+ *
+ * PJLIB provides <b>High Resolution Timestamp</b> API to access highest
+ * resolution timestamp value provided by the platform. The API is usefull
+ * to measure precise elapsed time, and can be used in applications such
+ * as profiling.
+ *
+ * The timestamp value is represented in cycles, and can be related to
+ * normal time (in seconds or sub-seconds) using various functions provided.
+ *
+ * \section pj_timestamp_examples_sec Examples
+ *
+ * For examples, please see:
+ * - \ref page_pjlib_sleep_test
+ * - \ref page_pjlib_timestamp_test
+ */
+
+/*
+ * High resolution timer.
+ */
+#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
+
+/**
+ * Acquire high resolution timer value. The time value are stored
+ * in cycles.
+ *
+ * @param ts High resolution timer value.
+ * @return PJ_SUCCESS or the appropriate error code.
+ *
+ * @see pj_get_timestamp_freq().
+ */
+PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
+
+/**
+ * Get high resolution timer frequency, in cycles per second.
+ *
+ * @param freq Timer frequency, in cycles per second.
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
+
+/**
+ * Set timestamp from 32bit values.
+ * @param t The timestamp to be set.
+ * @param hi The high 32bit part.
+ * @param lo The low 32bit part.
+ */
+PJ_INLINE(void) pj_set_timestamp32(pj_timestamp *t, pj_uint32_t hi,
+ pj_uint32_t lo)
+{
+ t->u32.hi = hi;
+ t->u32.lo = lo;
+}
+
+
+/**
+ * Compare timestamp t1 and t2.
+ * @param t1 t1.
+ * @param t2 t2.
+ * @return -1 if (t1 < t2), 1 if (t1 > t2), or 0 if (t1 == t2)
+ */
+PJ_INLINE(int) pj_cmp_timestamp(const pj_timestamp *t1, const pj_timestamp *t2)
+{
+#if PJ_HAS_INT64
+ if (t1->u64 < t2->u64)
+ return -1;
+ else if (t1->u64 > t2->u64)
+ return 1;
+ else
+ return 0;
+#else
+ if (t1->u32.hi < t2->u32.hi ||
+ (t1->u32.hi == t2->u32.hi && t1->u32.lo < t2->u32.lo))
+ return -1;
+ else if (t1->u32.hi > t2->u32.hi ||
+ (t1->u32.hi == t2->u32.hi && t1->u32.lo > t2->u32.lo))
+ return 1;
+ else
+ return 0;
+#endif
+}
+
+
+/**
+ * Add timestamp t2 to t1.
+ * @param t1 t1.
+ * @param t2 t2.
+ */
+PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
+{
+#if PJ_HAS_INT64
+ t1->u64 += t2->u64;
+#else
+ pj_uint32_t old = t1->u32.lo;
+ t1->u32.hi += t2->u32.hi;
+ t1->u32.lo += t2->u32.lo;
+ if (t1->u32.lo < old)
+ ++t1->u32.hi;
+#endif
+}
+
+/**
+ * Add timestamp t2 to t1.
+ * @param t1 t1.
+ * @param t2 t2.
+ */
+PJ_INLINE(void) pj_add_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
+{
+#if PJ_HAS_INT64
+ t1->u64 += t2;
+#else
+ pj_uint32_t old = t1->u32.lo;
+ t1->u32.lo += t2;
+ if (t1->u32.lo < old)
+ ++t1->u32.hi;
+#endif
+}
+
+/**
+ * Substract timestamp t2 from t1.
+ * @param t1 t1.
+ * @param t2 t2.
+ */
+PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
+{
+#if PJ_HAS_INT64
+ t1->u64 -= t2->u64;
+#else
+ t1->u32.hi -= t2->u32.hi;
+ if (t1->u32.lo >= t2->u32.lo)
+ t1->u32.lo -= t2->u32.lo;
+ else {
+ t1->u32.lo -= t2->u32.lo;
+ --t1->u32.hi;
+ }
+#endif
+}
+
+/**
+ * Substract timestamp t2 from t1.
+ * @param t1 t1.
+ * @param t2 t2.
+ */
+PJ_INLINE(void) pj_sub_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
+{
+#if PJ_HAS_INT64
+ t1->u64 -= t2;
+#else
+ if (t1->u32.lo >= t2)
+ t1->u32.lo -= t2;
+ else {
+ t1->u32.lo -= t2;
+ --t1->u32.hi;
+ }
+#endif
+}
+
+/**
+ * Get the timestamp difference between t2 and t1 (that is t2 minus t1),
+ * and return a 32bit signed integer difference.
+ */
+PJ_INLINE(pj_int32_t) pj_timestamp_diff32(const pj_timestamp *t1,
+ const pj_timestamp *t2)
+{
+ /* Be careful with the signess (I think!) */
+#if PJ_HAS_INT64
+ pj_int64_t diff = t2->u64 - t1->u64;
+ return (pj_int32_t) diff;
+#else
+ pj_int32 diff = t2->u32.lo - t1->u32.lo;
+ return diff;
+#endif
+}
+
+
+/**
+ * Calculate the elapsed time, and store it in pj_time_val.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available.
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start The starting timestamp.
+ * @param stop The end timestamp.
+ *
+ * @return Elapsed time as #pj_time_val.
+ *
+ * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
+ const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time as 32-bit miliseconds.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available.
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start The starting timestamp.
+ * @param stop The end timestamp.
+ *
+ * @return Elapsed time in milisecond.
+ *
+ * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start,
+ const pj_timestamp *stop );
+
+/**
+ * Variant of #pj_elapsed_msec() which returns 64bit value.
+ */
+PJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start,
+ const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time in 32-bit microseconds.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available.
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start The starting timestamp.
+ * @param stop The end timestamp.
+ *
+ * @return Elapsed time in microsecond.
+ *
+ * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
+ const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time in 32-bit nanoseconds.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available.
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start The starting timestamp.
+ * @param stop The end timestamp.
+ *
+ * @return Elapsed time in nanoseconds.
+ *
+ * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
+ const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time in 32-bit cycles.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available.
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start The starting timestamp.
+ * @param stop The end timestamp.
+ *
+ * @return Elapsed time in cycles.
+ *
+ * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
+ const pj_timestamp *stop );
+
+
+#endif /* PJ_HAS_HIGH_RES_TIMER */
+
+/** @} */
+
+
+/* **************************************************************************/
+/**
+ * Internal PJLIB function to initialize the threading subsystem.
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+pj_status_t pj_thread_init(void);
+
+
+PJ_END_DECL
+
+#endif /* __PJ_OS_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool.h
new file mode 100644
index 0000000..5cf3b18
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool.h
@@ -0,0 +1,903 @@
+/* $Id: pool.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <pj/list.h>
+
+/* See if we use pool's alternate API.
+ * The alternate API is used e.g. to implement pool debugging.
+ */
+#if PJ_HAS_POOL_ALT_API
+# include <pj/pool_alt.h>
+#endif
+
+
+#ifndef __PJ_POOL_H__
+#define __PJ_POOL_H__
+
+/**
+ * @file pool.h
+ * @brief Memory Pool.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_POOL_GROUP Fast Memory Pool
+ * @brief
+ * Memory pools allow dynamic memory allocation comparable to malloc or the
+ * new in operator C++. Those implementations are not desirable for very
+ * high performance applications or real-time systems, because of the
+ * performance bottlenecks and it suffers from fragmentation issue.
+ *
+ * \section PJ_POOL_INTRO_SEC PJLIB's Memory Pool
+ * \subsection PJ_POOL_ADVANTAGE_SUBSEC Advantages
+ *
+ * PJLIB's pool has many advantages over traditional malloc/new operator and
+ * over other memory pool implementations, because:
+ * - unlike other memory pool implementation, it allows allocation of
+ * memory chunks of different sizes,
+ * - it's very very fast.
+ * \n
+ * Memory chunk allocation is not only an O(1)
+ * operation, but it's also very simple (just
+ * few pointer arithmetic operations) and it doesn't require locking
+ * any mutex,
+ * - it's memory efficient.
+ * \n
+ * Pool doesn't keep track individual memory chunks allocated by
+ * applications, so there is no additional overhead needed for each
+ * memory allocation (other than possible additional of few bytes, up to
+ * PJ_POOL_ALIGNMENT-1, for aligning the memory).
+ * But see the @ref PJ_POOL_CAVEATS_SUBSEC below.
+ * - it prevents memory leaks.
+ * \n
+ * Memory pool inherently has garbage collection functionality. In fact,
+ * there is no need to free the chunks allocated from the memory pool.
+ * All chunks previously allocated from the pool will be freed once the
+ * pool itself is destroyed. This would prevent memory leaks that haunt
+ * programmers for decades, and it provides additional performance
+ * advantage over traditional malloc/new operator.
+ *
+ * Even more, PJLIB's memory pool provides some additional usability and
+ * flexibility for applications:
+ * - memory leaks are easily traceable, since memory pool is assigned name,
+ * and application can inspect what pools currently active in the system.
+ * - by design, memory allocation from a pool is not thread safe. We assumed
+ * that a pool will be owned by a higher level object, and thread safety
+ * should be handled by that object. This enables very fast pool operations
+ * and prevents unnecessary locking operations,
+ * - by default, the memory pool API behaves more like C++ new operator,
+ * in that it will throw PJ_NO_MEMORY_EXCEPTION exception (see
+ * @ref PJ_EXCEPT) when memory chunk allocation fails. This enables failure
+ * handling to be done on more high level function (instead of checking
+ * the result of pj_pool_alloc() everytime). If application doesn't like
+ * this, the default behavior can be changed on global basis by supplying
+ * different policy to the pool factory.
+ * - any memory allocation backend allocator/deallocator may be used. By
+ * default, the policy uses malloc() and free() to manage the pool's block,
+ * but application may use different strategy, for example to allocate
+ * memory blocks from a globally static memory location.
+ *
+ *
+ * \subsection PJ_POOL_PERFORMANCE_SUBSEC Performance
+ *
+ * The result of PJLIB's memory design and careful implementation is a
+ * memory allocation strategy that can speed-up the memory allocations
+ * and deallocations by up to <b>30 times</b> compared to standard
+ * malloc()/free() (more than 150 million allocations per second on a
+ * P4/3.0GHz Linux machine).
+ *
+ * (Note: your mileage may vary, of course. You can see how much PJLIB's
+ * pool improves the performance over malloc()/free() in your target
+ * system by running pjlib-test application).
+ *
+ *
+ * \subsection PJ_POOL_CAVEATS_SUBSEC Caveats
+ *
+ * There are some caveats though!
+ *
+ * When creating pool, PJLIB requires applications to specify the initial
+ * pool size, and as soon as the pool is created, PJLIB allocates memory
+ * from the system by that size. Application designers MUST choose the
+ * initial pool size carefully, since choosing too big value will result in
+ * wasting system's memory.
+ *
+ * But the pool can grow. Application designer can specify how the
+ * pool will grow in size, by specifying the size increment when creating
+ * the pool.
+ *
+ * The pool, however, <b>cannot</b> shrink! Since there is <b>no</b>
+ * function to deallocate memory chunks, there is no way for the pool to
+ * release back unused memory to the system.
+ * Application designers must be aware that constant memory allocations
+ * from pool that has infinite life-time may cause the memory usage of
+ * the application to grow over time.
+ *
+ *
+ * \section PJ_POOL_USING_SEC Using Memory Pool
+ *
+ * This section describes how to use PJLIB's memory pool framework.
+ * As we hope the readers will witness, PJLIB's memory pool API is quite
+ * straightforward.
+ *
+ * \subsection PJ_POOL_USING_F Create Pool Factory
+ * First, application needs to initialize a pool factory (this normally
+ * only needs to be done once in one application). PJLIB provides
+ * a pool factory implementation called caching pool (see @ref
+ * PJ_CACHING_POOL), and it is initialized by calling #pj_caching_pool_init().
+ *
+ * \subsection PJ_POOL_USING_P Create The Pool
+ * Then application creates the pool object itself with #pj_pool_create(),
+ * specifying among other thing the pool factory where the pool should
+ * be created from, the pool name, initial size, and increment/expansion
+ * size.
+ *
+ * \subsection PJ_POOL_USING_M Allocate Memory as Required
+ * Then whenever application needs to allocate dynamic memory, it would
+ * call #pj_pool_alloc(), #pj_pool_calloc(), or #pj_pool_zalloc() to
+ * allocate memory chunks from the pool.
+ *
+ * \subsection PJ_POOL_USING_DP Destroy the Pool
+ * When application has finished with the pool, it should call
+ * #pj_pool_release() to release the pool object back to the factory.
+ * Depending on the types of the factory, this may release the memory back
+ * to the operating system.
+ *
+ * \subsection PJ_POOL_USING_Dc Destroy the Pool Factory
+ * And finally, before application quites, it should deinitialize the
+ * pool factory, to make sure that all memory blocks allocated by the
+ * factory are released back to the operating system. After this, of
+ * course no more memory pool allocation can be requested.
+ *
+ * \subsection PJ_POOL_USING_EX Example
+ * Below is a sample complete program that utilizes PJLIB's memory pool.
+ *
+ * \code
+
+ #include <pjlib.h>
+
+ #define THIS_FILE "pool_sample.c"
+
+ static void my_perror(const char *title, pj_status_t status)
+ {
+ char errmsg[PJ_ERR_MSG_SIZE];
+
+ pj_strerror(status, errmsg, sizeof(errmsg));
+ PJ_LOG(1,(THIS_FILE, "%s: %s [status=%d]", title, errmsg, status));
+ }
+
+ static void pool_demo_1(pj_pool_factory *pfactory)
+ {
+ unsigned i;
+ pj_pool_t *pool;
+
+ // Must create pool before we can allocate anything
+ pool = pj_pool_create(pfactory, // the factory
+ "pool1", // pool's name
+ 4000, // initial size
+ 4000, // increment size
+ NULL); // use default callback.
+ if (pool == NULL) {
+ my_perror("Error creating pool", PJ_ENOMEM);
+ return;
+ }
+
+ // Demo: allocate some memory chunks
+ for (i=0; i<1000; ++i) {
+ void *p;
+
+ p = pj_pool_alloc(pool, (pj_rand()+1) % 512);
+
+ // Do something with p
+ ...
+
+ // Look! No need to free p!!
+ }
+
+ // Done with silly demo, must free pool to release all memory.
+ pj_pool_release(pool);
+ }
+
+ int main()
+ {
+ pj_caching_pool cp;
+ pj_status_t status;
+
+ // Must init PJLIB before anything else
+ status = pj_init();
+ if (status != PJ_SUCCESS) {
+ my_perror("Error initializing PJLIB", status);
+ return 1;
+ }
+
+ // Create the pool factory, in this case, a caching pool,
+ // using default pool policy.
+ pj_caching_pool_init(&cp, NULL, 1024*1024 );
+
+ // Do a demo
+ pool_demo_1(&cp.factory);
+
+ // Done with demos, destroy caching pool before exiting app.
+ pj_caching_pool_destroy(&cp);
+
+ return 0;
+ }
+
+ \endcode
+ *
+ * More information about pool factory, the pool object, and caching pool
+ * can be found on the Module Links below.
+ */
+
+
+/**
+ * @defgroup PJ_POOL Memory Pool Object
+ * @ingroup PJ_POOL_GROUP
+ * @brief
+ * The memory pool is an opaque object created by pool factory.
+ * Application uses this object to request a memory chunk, by calling
+ * #pj_pool_alloc(), #pj_pool_calloc(), or #pj_pool_zalloc().
+ * When the application has finished using
+ * the pool, it must call #pj_pool_release() to free all the chunks previously
+ * allocated and release the pool back to the factory.
+ *
+ * A memory pool is initialized with an initial amount of memory, which is
+ * called a block. Pool can be configured to dynamically allocate more memory
+ * blocks when it runs out of memory.
+ *
+ * The pool doesn't keep track of individual memory allocations
+ * by user, and the user doesn't have to free these indidual allocations. This
+ * makes memory allocation simple and very fast. All the memory allocated from
+ * the pool will be destroyed when the pool itself is destroyed.
+ *
+ * \section PJ_POOL_THREADING_SEC More on Threading Policies
+ * - By design, memory allocation from a pool is not thread safe. We assumed
+ * that a pool will be owned by an object, and thread safety should be
+ * handled by that object. Thus these functions are not thread safe:
+ * - #pj_pool_alloc,
+ * - #pj_pool_calloc,
+ * - and other pool statistic functions.
+ * - Threading in the pool factory is decided by the policy set for the
+ * factory when it was created.
+ *
+ * \section PJ_POOL_EXAMPLES_SEC Examples
+ *
+ * For some sample codes on how to use the pool, please see:
+ * - @ref page_pjlib_pool_test
+ *
+ * @{
+ */
+
+/**
+ * The type for function to receive callback from the pool when it is unable
+ * to allocate memory. The elegant way to handle this condition is to throw
+ * exception, and this is what is expected by most of this library
+ * components.
+ */
+typedef void pj_pool_callback(pj_pool_t *pool, pj_size_t size);
+
+/**
+ * This class, which is used internally by the pool, describes a single
+ * block of memory from which user memory allocations will be allocated from.
+ */
+typedef struct pj_pool_block
+{
+ PJ_DECL_LIST_MEMBER(struct pj_pool_block); /**< List's prev and next. */
+ unsigned char *buf; /**< Start of buffer. */
+ unsigned char *cur; /**< Current alloc ptr. */
+ unsigned char *end; /**< End of buffer. */
+} pj_pool_block;
+
+
+/**
+ * This structure describes the memory pool. Only implementors of pool factory
+ * need to care about the contents of this structure.
+ */
+struct pj_pool_t
+{
+ PJ_DECL_LIST_MEMBER(struct pj_pool_t); /**< Standard list elements. */
+
+ /** Pool name */
+ char obj_name[PJ_MAX_OBJ_NAME];
+
+ /** Pool factory. */
+ pj_pool_factory *factory;
+
+ /** Data put by factory */
+ void *factory_data;
+
+ /** Current capacity allocated by the pool. */
+ pj_size_t capacity;
+
+ /** Size of memory block to be allocated when the pool runs out of memory */
+ pj_size_t increment_size;
+
+ /** List of memory blocks allcoated by the pool. */
+ pj_pool_block block_list;
+
+ /** The callback to be called when the pool is unable to allocate memory. */
+ pj_pool_callback *callback;
+
+};
+
+
+/**
+ * Guidance on how much memory required for initial pool administrative data.
+ */
+#define PJ_POOL_SIZE (sizeof(struct pj_pool_t))
+
+/**
+ * Pool memory alignment (must be power of 2).
+ */
+#ifndef PJ_POOL_ALIGNMENT
+# define PJ_POOL_ALIGNMENT 4
+#endif
+
+/**
+ * Create a new pool from the pool factory. This wrapper will call create_pool
+ * member of the pool factory.
+ *
+ * @param factory The pool factory.
+ * @param name The name to be assigned to the pool. The name should
+ * not be longer than PJ_MAX_OBJ_NAME (32 chars), or
+ * otherwise it will be truncated.
+ * @param initial_size The size of initial memory blocks taken by the pool.
+ * Note that the pool will take 68+20 bytes for
+ * administrative area from this block.
+ * @param increment_size the size of each additional blocks to be allocated
+ * when the pool is running out of memory. If user
+ * requests memory which is larger than this size, then
+ * an error occurs.
+ * Note that each time a pool allocates additional block,
+ * it needs PJ_POOL_SIZE more to store some
+ * administrative info.
+ * @param callback Callback to be called when error occurs in the pool.
+ * If this value is NULL, then the callback from pool
+ * factory policy will be used.
+ * Note that when an error occurs during pool creation,
+ * the callback itself is not called. Instead, NULL
+ * will be returned.
+ *
+ * @return The memory pool, or NULL.
+ */
+PJ_IDECL(pj_pool_t*) pj_pool_create(pj_pool_factory *factory,
+ const char *name,
+ pj_size_t initial_size,
+ pj_size_t increment_size,
+ pj_pool_callback *callback);
+
+/**
+ * Release the pool back to pool factory.
+ *
+ * @param pool Memory pool.
+ */
+PJ_IDECL(void) pj_pool_release( pj_pool_t *pool );
+
+/**
+ * Get pool object name.
+ *
+ * @param pool the pool.
+ *
+ * @return pool name as NULL terminated string.
+ */
+PJ_IDECL(const char *) pj_pool_getobjname( const pj_pool_t *pool );
+
+/**
+ * Reset the pool to its state when it was initialized.
+ * This means that if additional blocks have been allocated during runtime,
+ * then they will be freed. Only the original block allocated during
+ * initialization is retained. This function will also reset the internal
+ * counters, such as pool capacity and used size.
+ *
+ * @param pool the pool.
+ */
+PJ_DECL(void) pj_pool_reset( pj_pool_t *pool );
+
+
+/**
+ * Get the pool capacity, that is, the system storage that have been allocated
+ * by the pool, and have been used/will be used to allocate user requests.
+ * There's no guarantee that the returned value represent a single
+ * contiguous block, because the capacity may be spread in several blocks.
+ *
+ * @param pool the pool.
+ *
+ * @return the capacity.
+ */
+PJ_IDECL(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool );
+
+/**
+ * Get the total size of user allocation request.
+ *
+ * @param pool the pool.
+ *
+ * @return the total size.
+ */
+PJ_IDECL(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool );
+
+/**
+ * Allocate storage with the specified size from the pool.
+ * If there's no storage available in the pool, then the pool can allocate more
+ * blocks if the increment size is larger than the requested size.
+ *
+ * @param pool the pool.
+ * @param size the requested size.
+ *
+ * @return pointer to the allocated memory.
+ *
+ * @see PJ_POOL_ALLOC_T
+ */
+PJ_IDECL(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size);
+
+/**
+ * Allocate storage from the pool, and initialize it to zero.
+ * This function behaves like pj_pool_alloc(), except that the storage will
+ * be initialized to zero.
+ *
+ * @param pool the pool.
+ * @param count the number of elements in the array.
+ * @param elem the size of individual element.
+ *
+ * @return pointer to the allocated memory.
+ */
+PJ_IDECL(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count,
+ pj_size_t elem);
+
+
+/**
+ * Allocate storage from the pool and initialize it to zero.
+ *
+ * @param pool The pool.
+ * @param size The size to be allocated.
+ *
+ * @return Pointer to the allocated memory.
+ *
+ * @see PJ_POOL_ZALLOC_T
+ */
+PJ_INLINE(void*) pj_pool_zalloc(pj_pool_t *pool, pj_size_t size)
+{
+ return pj_pool_calloc(pool, 1, size);
+}
+
+
+/**
+ * This macro allocates memory from the pool and returns the instance of
+ * the specified type. It provides a stricker type safety than pj_pool_alloc()
+ * since the return value of this macro will be type-casted to the specified
+ * type.
+ *
+ * @param pool The pool
+ * @param type The type of object to be allocated
+ *
+ * @return Memory buffer of the specified type.
+ */
+#define PJ_POOL_ALLOC_T(pool,type) \
+ ((type*)pj_pool_alloc(pool, sizeof(type)))
+
+/**
+ * This macro allocates memory from the pool, zeroes the buffer, and
+ * returns the instance of the specified type. It provides a stricker type
+ * safety than pj_pool_zalloc() since the return value of this macro will be
+ * type-casted to the specified type.
+ *
+ * @param pool The pool
+ * @param type The type of object to be allocated
+ *
+ * @return Memory buffer of the specified type.
+ */
+#define PJ_POOL_ZALLOC_T(pool,type) \
+ ((type*)pj_pool_zalloc(pool, sizeof(type)))
+
+/*
+ * Internal functions
+ */
+PJ_IDECL(void*) pj_pool_alloc_from_block(pj_pool_block *block, pj_size_t size);
+PJ_DECL(void*) pj_pool_allocate_find(pj_pool_t *pool, unsigned size);
+
+
+
+/**
+ * @} // PJ_POOL
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJ_POOL_FACTORY Pool Factory and Policy
+ * @ingroup PJ_POOL_GROUP
+ * @brief
+ * A pool object must be created through a factory. A factory not only provides
+ * generic interface functions to create and release pool, but also provides
+ * strategy to manage the life time of pools. One sample implementation,
+ * \a pj_caching_pool, can be set to keep the pools released by application for
+ * future use as long as the total memory is below the limit.
+ *
+ * The pool factory interface declared in PJLIB is designed to be extensible.
+ * Application can define its own strategy by creating it's own pool factory
+ * implementation, and this strategy can be used even by existing library
+ * without recompilation.
+ *
+ * \section PJ_POOL_FACTORY_ITF Pool Factory Interface
+ * The pool factory defines the following interface:
+ * - \a policy: the memory pool factory policy.
+ * - \a create_pool(): create a new memory pool.
+ * - \a release_pool(): release memory pool back to factory.
+ *
+ * \section PJ_POOL_FACTORY_POL Pool Factory Policy.
+ *
+ * A pool factory only defines functions to create and release pool and how
+ * to manage pools, but the rest of the functionalities are controlled by
+ * policy. A pool policy defines:
+ * - how memory block is allocated and deallocated (the default implementation
+ * allocates and deallocate memory by calling malloc() and free()).
+ * - callback to be called when memory allocation inside a pool fails (the
+ * default implementation will throw PJ_NO_MEMORY_EXCEPTION exception).
+ * - concurrency when creating and releasing pool from/to the factory.
+ *
+ * A pool factory can be given different policy during creation to make
+ * it behave differently. For example, caching pool factory can be configured
+ * to allocate and deallocate from a static/contiguous/preallocated memory
+ * instead of using malloc()/free().
+ *
+ * What strategy/factory and what policy to use is not defined by PJLIB, but
+ * instead is left to application to make use whichever is most efficient for
+ * itself.
+ *
+ * The pool factory policy controls the behaviour of memory factories, and
+ * defines the following interface:
+ * - \a block_alloc(): allocate memory block from backend memory mgmt/system.
+ * - \a block_free(): free memory block back to backend memory mgmt/system.
+ * @{
+ */
+
+/* We unfortunately don't have support for factory policy options as now,
+ so we keep this commented at the moment.
+enum PJ_POOL_FACTORY_OPTION
+{
+ PJ_POOL_FACTORY_SERIALIZE = 1
+};
+*/
+
+/**
+ * This structure declares pool factory interface.
+ */
+typedef struct pj_pool_factory_policy
+{
+ /**
+ * Allocate memory block (for use by pool). This function is called
+ * by memory pool to allocate memory block.
+ *
+ * @param factory Pool factory.
+ * @param size The size of memory block to allocate.
+ *
+ * @return Memory block.
+ */
+ void* (*block_alloc)(pj_pool_factory *factory, pj_size_t size);
+
+ /**
+ * Free memory block.
+ *
+ * @param factory Pool factory.
+ * @param mem Memory block previously allocated by block_alloc().
+ * @param size The size of memory block.
+ */
+ void (*block_free)(pj_pool_factory *factory, void *mem, pj_size_t size);
+
+ /**
+ * Default callback to be called when memory allocation fails.
+ */
+ pj_pool_callback *callback;
+
+ /**
+ * Option flags.
+ */
+ unsigned flags;
+
+} pj_pool_factory_policy;
+
+/**
+ * \def PJ_NO_MEMORY_EXCEPTION
+ * This constant denotes the exception number that will be thrown by default
+ * memory factory policy when memory allocation fails.
+ *
+ * @see pj_NO_MEMORY_EXCEPTION()
+ */
+PJ_DECL_DATA(int) PJ_NO_MEMORY_EXCEPTION;
+
+/**
+ * Get #PJ_NO_MEMORY_EXCEPTION constant.
+ */
+PJ_DECL(int) pj_NO_MEMORY_EXCEPTION(void);
+
+/**
+ * This global variable points to default memory pool factory policy.
+ * The behaviour of the default policy is:
+ * - block allocation and deallocation use malloc() and free().
+ * - callback will raise PJ_NO_MEMORY_EXCEPTION exception.
+ * - access to pool factory is not serialized (i.e. not thread safe).
+ *
+ * @see pj_pool_factory_get_default_policy
+ */
+PJ_DECL_DATA(pj_pool_factory_policy) pj_pool_factory_default_policy;
+
+
+/**
+ * Get the default pool factory policy.
+ *
+ * @return the pool policy.
+ */
+PJ_DECL(const pj_pool_factory_policy*) pj_pool_factory_get_default_policy(void);
+
+
+/**
+ * This structure contains the declaration for pool factory interface.
+ */
+struct pj_pool_factory
+{
+ /**
+ * Memory pool policy.
+ */
+ pj_pool_factory_policy policy;
+
+ /**
+ * Create a new pool from the pool factory.
+ *
+ * @param factory The pool factory.
+ * @param name the name to be assigned to the pool. The name should
+ * not be longer than PJ_MAX_OBJ_NAME (32 chars), or
+ * otherwise it will be truncated.
+ * @param initial_size the size of initial memory blocks taken by the pool.
+ * Note that the pool will take 68+20 bytes for
+ * administrative area from this block.
+ * @param increment_size the size of each additional blocks to be allocated
+ * when the pool is running out of memory. If user
+ * requests memory which is larger than this size, then
+ * an error occurs.
+ * Note that each time a pool allocates additional block,
+ * it needs 20 bytes (equal to sizeof(pj_pool_block)) to
+ * store some administrative info.
+ * @param callback Cllback to be called when error occurs in the pool.
+ * Note that when an error occurs during pool creation,
+ * the callback itself is not called. Instead, NULL
+ * will be returned.
+ *
+ * @return the memory pool, or NULL.
+ */
+ pj_pool_t* (*create_pool)( pj_pool_factory *factory,
+ const char *name,
+ pj_size_t initial_size,
+ pj_size_t increment_size,
+ pj_pool_callback *callback);
+
+ /**
+ * Release the pool to the pool factory.
+ *
+ * @param factory The pool factory.
+ * @param pool The pool to be released.
+ */
+ void (*release_pool)( pj_pool_factory *factory, pj_pool_t *pool );
+
+ /**
+ * Dump pool status to log.
+ *
+ * @param factory The pool factory.
+ */
+ void (*dump_status)( pj_pool_factory *factory, pj_bool_t detail );
+
+ /**
+ * This is optional callback to be called by allocation policy when
+ * it allocates a new memory block. The factory may use this callback
+ * for example to keep track of the total number of memory blocks
+ * currently allocated by applications.
+ *
+ * @param factory The pool factory.
+ * @param size Size requested by application.
+ *
+ * @return MUST return PJ_TRUE, otherwise the block
+ * allocation is cancelled.
+ */
+ pj_bool_t (*on_block_alloc)(pj_pool_factory *factory, pj_size_t size);
+
+ /**
+ * This is optional callback to be called by allocation policy when
+ * it frees memory block. The factory may use this callback
+ * for example to keep track of the total number of memory blocks
+ * currently allocated by applications.
+ *
+ * @param factory The pool factory.
+ * @param size Size freed.
+ */
+ void (*on_block_free)(pj_pool_factory *factory, pj_size_t size);
+
+};
+
+/**
+ * This function is intended to be used by pool factory implementors.
+ * @param factory Pool factory.
+ * @param name Pool name.
+ * @param initial_size Initial size.
+ * @param increment_size Increment size.
+ * @param callback Callback.
+ * @return The pool object, or NULL.
+ */
+PJ_DECL(pj_pool_t*) pj_pool_create_int( pj_pool_factory *factory,
+ const char *name,
+ pj_size_t initial_size,
+ pj_size_t increment_size,
+ pj_pool_callback *callback);
+
+/**
+ * This function is intended to be used by pool factory implementors.
+ * @param pool The pool.
+ * @param name Pool name.
+ * @param increment_size Increment size.
+ * @param callback Callback function.
+ */
+PJ_DECL(void) pj_pool_init_int( pj_pool_t *pool,
+ const char *name,
+ pj_size_t increment_size,
+ pj_pool_callback *callback);
+
+/**
+ * This function is intended to be used by pool factory implementors.
+ * @param pool The memory pool.
+ */
+PJ_DECL(void) pj_pool_destroy_int( pj_pool_t *pool );
+
+
+/**
+ * Dump pool factory state.
+ * @param pf The pool factory.
+ * @param detail Detail state required.
+ */
+PJ_INLINE(void) pj_pool_factory_dump( pj_pool_factory *pf,
+ pj_bool_t detail )
+{
+ (*pf->dump_status)(pf, detail);
+}
+
+/**
+ * @} // PJ_POOL_FACTORY
+ */
+
+/* **************************************************************************/
+
+/**
+ * @defgroup PJ_CACHING_POOL Caching Pool Factory
+ * @ingroup PJ_POOL_GROUP
+ * @brief
+ * Caching pool is one sample implementation of pool factory where the
+ * factory can reuse memory to create a pool. Application defines what the
+ * maximum memory the factory can hold, and when a pool is released the
+ * factory decides whether to destroy the pool or to keep it for future use.
+ * If the total amount of memory in the internal cache is still within the
+ * limit, the factory will keep the pool in the internal cache, otherwise the
+ * pool will be destroyed, thus releasing the memory back to the system.
+ *
+ * @{
+ */
+
+/**
+ * Number of unique sizes, to be used as index to the free list.
+ * Each pool in the free list is organized by it's size.
+ */
+#define PJ_CACHING_POOL_ARRAY_SIZE 16
+
+/**
+ * Declaration for caching pool. Application doesn't normally need to
+ * care about the contents of this struct, it is only provided here because
+ * application need to define an instance of this struct (we can not allocate
+ * the struct from a pool since there is no pool factory yet!).
+ */
+struct pj_caching_pool
+{
+ /** Pool factory interface, must be declared first. */
+ pj_pool_factory factory;
+
+ /** Current factory's capacity, i.e. number of bytes that are allocated
+ * and available for application in this factory. The factory's
+ * capacity represents the size of all pools kept by this factory
+ * in it's free list, which will be returned to application when it
+ * requests to create a new pool.
+ */
+ pj_size_t capacity;
+
+ /** Maximum size that can be held by this factory. Once the capacity
+ * has exceeded @a max_capacity, further #pj_pool_release() will
+ * flush the pool. If the capacity is still below the @a max_capacity,
+ * #pj_pool_release() will save the pool to the factory's free list.
+ */
+ pj_size_t max_capacity;
+
+ /**
+ * Number of pools currently held by applications. This number gets
+ * incremented everytime #pj_pool_create() is called, and gets
+ * decremented when #pj_pool_release() is called.
+ */
+ pj_size_t used_count;
+
+ /**
+ * Total size of memory currently used by application.
+ */
+ pj_size_t used_size;
+
+ /**
+ * The maximum size of memory used by application throughout the life
+ * of the caching pool.
+ */
+ pj_size_t peak_used_size;
+
+ /**
+ * Lists of pools in the cache, indexed by pool size.
+ */
+ pj_list free_list[PJ_CACHING_POOL_ARRAY_SIZE];
+
+ /**
+ * List of pools currently allocated by applications.
+ */
+ pj_list used_list;
+
+ /**
+ * Internal pool.
+ */
+ char pool_buf[256 * (sizeof(long) / 4)];
+
+ /**
+ * Mutex.
+ */
+ pj_lock_t *lock;
+};
+
+
+
+/**
+ * Initialize caching pool.
+ *
+ * @param ch_pool The caching pool factory to be initialized.
+ * @param policy Pool factory policy.
+ * @param max_capacity The total capacity to be retained in the cache. When
+ * the pool is returned to the cache, it will be kept in
+ * recycling list if the total capacity of pools in this
+ * list plus the capacity of the pool is still below this
+ * value.
+ */
+PJ_DECL(void) pj_caching_pool_init( pj_caching_pool *ch_pool,
+ const pj_pool_factory_policy *policy,
+ pj_size_t max_capacity);
+
+
+/**
+ * Destroy caching pool, and release all the pools in the recycling list.
+ *
+ * @param ch_pool The caching pool.
+ */
+PJ_DECL(void) pj_caching_pool_destroy( pj_caching_pool *ch_pool );
+
+/**
+ * @} // PJ_CACHING_POOL
+ */
+
+# if PJ_FUNCTIONS_ARE_INLINED
+# include "pool_i.h"
+# endif
+
+PJ_END_DECL
+
+#endif /* __PJ_POOL_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_alt.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_alt.h
new file mode 100644
index 0000000..43b1807
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_alt.h
@@ -0,0 +1,198 @@
+/* $Id: pool_alt.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_POOL_ALT_H__
+#define __PJ_POOL_ALT_H__
+
+#define __PJ_POOL_H__
+
+
+/**
+ * The type for function to receive callback from the pool when it is unable
+ * to allocate memory. The elegant way to handle this condition is to throw
+ * exception, and this is what is expected by most of this library
+ * components.
+ */
+typedef void pj_pool_callback(pj_pool_t *pool, pj_size_t size);
+
+struct pj_pool_mem
+{
+ struct pj_pool_mem *next;
+
+ /* data follows immediately */
+};
+
+
+struct pj_pool_t
+{
+ struct pj_pool_mem *first_mem;
+ pj_pool_factory *factory;
+ char obj_name[32];
+ pj_size_t used_size;
+ pj_pool_callback *cb;
+};
+
+
+#define PJ_POOL_SIZE (sizeof(struct pj_pool_t))
+
+/**
+ * This constant denotes the exception number that will be thrown by default
+ * memory factory policy when memory allocation fails.
+ */
+extern int PJ_NO_MEMORY_EXCEPTION;
+
+
+
+/*
+ * Declare all pool API as macro that calls the implementation
+ * function.
+ */
+#define pj_pool_create(fc,nm,init,inc,cb) \
+ pj_pool_create_imp(__FILE__, __LINE__, fc, nm, init, inc, cb)
+
+#define pj_pool_release(pool) pj_pool_release_imp(pool)
+#define pj_pool_getobjname(pool) pj_pool_getobjname_imp(pool)
+#define pj_pool_reset(pool) pj_pool_reset_imp(pool)
+#define pj_pool_get_capacity(pool) pj_pool_get_capacity_imp(pool)
+#define pj_pool_get_used_size(pool) pj_pool_get_used_size_imp(pool)
+#define pj_pool_alloc(pool,sz) \
+ pj_pool_alloc_imp(__FILE__, __LINE__, pool, sz)
+
+#define pj_pool_calloc(pool,cnt,elem) \
+ pj_pool_calloc_imp(__FILE__, __LINE__, pool, cnt, elem)
+
+#define pj_pool_zalloc(pool,sz) \
+ pj_pool_zalloc_imp(__FILE__, __LINE__, pool, sz)
+
+
+
+/*
+ * Declare prototypes for pool implementation API.
+ */
+
+/* Create pool */
+PJ_DECL(pj_pool_t*) pj_pool_create_imp(const char *file, int line,
+ void *factory,
+ const char *name,
+ pj_size_t initial_size,
+ pj_size_t increment_size,
+ pj_pool_callback *callback);
+
+/* Release pool */
+PJ_DECL(void) pj_pool_release_imp(pj_pool_t *pool);
+
+/* Get pool name */
+PJ_DECL(const char*) pj_pool_getobjname_imp(pj_pool_t *pool);
+
+/* Reset pool */
+PJ_DECL(void) pj_pool_reset_imp(pj_pool_t *pool);
+
+/* Get capacity */
+PJ_DECL(pj_size_t) pj_pool_get_capacity_imp(pj_pool_t *pool);
+
+/* Get total used size */
+PJ_DECL(pj_size_t) pj_pool_get_used_size_imp(pj_pool_t *pool);
+
+/* Allocate memory from the pool */
+PJ_DECL(void*) pj_pool_alloc_imp(const char *file, int line,
+ pj_pool_t *pool, pj_size_t sz);
+
+/* Allocate memory from the pool and zero the memory */
+PJ_DECL(void*) pj_pool_calloc_imp(const char *file, int line,
+ pj_pool_t *pool, unsigned cnt,
+ unsigned elemsz);
+
+/* Allocate memory from the pool and zero the memory */
+PJ_DECL(void*) pj_pool_zalloc_imp(const char *file, int line,
+ pj_pool_t *pool, pj_size_t sz);
+
+
+#define PJ_POOL_ZALLOC_T(pool,type) \
+ ((type*)pj_pool_zalloc(pool, sizeof(type)))
+#define PJ_POOL_ALLOC_T(pool,type) \
+ ((type*)pj_pool_alloc(pool, sizeof(type)))
+#ifndef PJ_POOL_ALIGNMENT
+# define PJ_POOL_ALIGNMENT 4
+#endif
+
+/**
+ * This structure declares pool factory interface.
+ */
+typedef struct pj_pool_factory_policy
+{
+ /**
+ * Allocate memory block (for use by pool). This function is called
+ * by memory pool to allocate memory block.
+ *
+ * @param factory Pool factory.
+ * @param size The size of memory block to allocate.
+ *
+ * @return Memory block.
+ */
+ void* (*block_alloc)(pj_pool_factory *factory, pj_size_t size);
+
+ /**
+ * Free memory block.
+ *
+ * @param factory Pool factory.
+ * @param mem Memory block previously allocated by block_alloc().
+ * @param size The size of memory block.
+ */
+ void (*block_free)(pj_pool_factory *factory, void *mem, pj_size_t size);
+
+ /**
+ * Default callback to be called when memory allocation fails.
+ */
+ pj_pool_callback *callback;
+
+ /**
+ * Option flags.
+ */
+ unsigned flags;
+
+} pj_pool_factory_policy;
+
+struct pj_pool_factory
+{
+ pj_pool_factory_policy policy;
+ int dummy;
+};
+
+struct pj_caching_pool
+{
+ pj_pool_factory factory;
+
+ /* just to make it compilable */
+ unsigned used_count;
+ unsigned used_size;
+ unsigned peak_used_size;
+};
+
+/* just to make it compilable */
+typedef struct pj_pool_block
+{
+ int dummy;
+} pj_pool_block;
+
+#define pj_caching_pool_init( cp, pol, mac)
+#define pj_caching_pool_destroy(cp)
+#define pj_pool_factory_dump(pf, detail)
+
+#endif /* __PJ_POOL_ALT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_buf.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_buf.h
new file mode 100644
index 0000000..cfd1a03
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_buf.h
@@ -0,0 +1,105 @@
+/* $Id: pool_buf.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __POOL_STACK_H__
+#define __POOL_STACK_H__
+
+#include <pj/pool.h>
+
+/**
+ * @defgroup PJ_POOL_BUFFER Stack/Buffer Based Memory Pool Allocator
+ * @ingroup PJ_POOL_GROUP
+ * @brief Stack/buffer based pool.
+ *
+ * This section describes an implementation of memory pool which uses
+ * memory allocated from the stack. Application creates this pool
+ * by specifying a buffer (which can be allocated from static memory or
+ * stack variable), and then use normal pool API to access/use the pool.
+ *
+ * If the buffer specified during pool creation is a buffer located in the
+ * stack, the pool will be invalidated (or implicitly destroyed) when the
+ * execution leaves the enclosing block containing the buffer. Note
+ * that application must make sure that any objects allocated from this
+ * pool (such as mutexes) have been destroyed before the pool gets
+ * invalidated.
+ *
+ * Sample usage:
+ *
+ * \code
+ #include <pjlib.h>
+
+ static void test()
+ {
+ char buffer[500];
+ pj_pool_t *pool;
+ void *p;
+
+ pool = pj_pool_create_on_buf("thepool", buffer, sizeof(buffer));
+
+ // Use the pool as usual
+ p = pj_pool_alloc(pool, ...);
+ ...
+
+ // No need to release the pool
+ }
+
+ int main()
+ {
+ pj_init();
+ test();
+ return 0;
+ }
+
+ \endcode
+ *
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Create the pool using the specified buffer as the pool's memory.
+ * Subsequent allocations made from the pool will use the memory from
+ * this buffer.
+ *
+ * If the buffer specified in the parameter is a buffer located in the
+ * stack, the pool will be invalid (or implicitly destroyed) when the
+ * execution leaves the enclosing block containing the buffer. Note
+ * that application must make sure that any objects allocated from this
+ * pool (such as mutexes) have been destroyed before the pool gets
+ * invalidated.
+ *
+ * @param name Optional pool name.
+ * @param buf Buffer to be used by the pool.
+ * @param size The size of the buffer.
+ *
+ * @return The memory pool instance.
+ */
+PJ_DECL(pj_pool_t*) pj_pool_create_on_buf(const char *name,
+ void *buf,
+ pj_size_t size);
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __POOL_STACK_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_i.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_i.h
new file mode 100644
index 0000000..98de3cb
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_i.h
@@ -0,0 +1,94 @@
+/* $Id: pool_i.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include <pj/string.h>
+
+
+PJ_IDEF(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool )
+{
+ return pool->capacity;
+}
+
+PJ_IDEF(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool )
+{
+ pj_pool_block *b = pool->block_list.next;
+ pj_size_t used_size = sizeof(pj_pool_t);
+ while (b != &pool->block_list) {
+ used_size += (b->cur - b->buf) + sizeof(pj_pool_block);
+ b = b->next;
+ }
+ return used_size;
+}
+
+PJ_IDEF(void*) pj_pool_alloc_from_block( pj_pool_block *block, pj_size_t size )
+{
+ /* The operation below is valid for size==0.
+ * When size==0, the function will return the pointer to the pool
+ * memory address, but no memory will be allocated.
+ */
+ if (size & (PJ_POOL_ALIGNMENT-1)) {
+ size = (size + PJ_POOL_ALIGNMENT) & ~(PJ_POOL_ALIGNMENT-1);
+ }
+ if ((unsigned)(block->end - block->cur) >= size) {
+ void *ptr = block->cur;
+ block->cur += size;
+ return ptr;
+ }
+ return NULL;
+}
+
+PJ_IDEF(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size)
+{
+ void *ptr = pj_pool_alloc_from_block(pool->block_list.next, size);
+ if (!ptr)
+ ptr = pj_pool_allocate_find(pool, size);
+ return ptr;
+}
+
+
+PJ_IDEF(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, pj_size_t size)
+{
+ void *buf = pj_pool_alloc( pool, size*count);
+ if (buf)
+ pj_bzero(buf, size * count);
+ return buf;
+}
+
+PJ_IDEF(const char *) pj_pool_getobjname( const pj_pool_t *pool )
+{
+ return pool->obj_name;
+}
+
+PJ_IDEF(pj_pool_t*) pj_pool_create( pj_pool_factory *f,
+ const char *name,
+ pj_size_t initial_size,
+ pj_size_t increment_size,
+ pj_pool_callback *callback)
+{
+ return (*f->create_pool)(f, name, initial_size, increment_size, callback);
+}
+
+PJ_IDEF(void) pj_pool_release( pj_pool_t *pool )
+{
+ if (pool->factory->release_pool)
+ (*pool->factory->release_pool)(pool->factory, pool);
+}
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/rand.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/rand.h
new file mode 100644
index 0000000..27ccf9e
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/rand.h
@@ -0,0 +1,66 @@
+/* $Id: rand.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_RAND_H__
+#define __PJ_RAND_H__
+
+/**
+ * @file rand.h
+ * @brief Random Number Generator.
+ */
+
+#include <pj/config.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_RAND Random Number Generator
+ * @ingroup PJ_MISC
+ * @{
+ * This module contains functions for generating random numbers.
+ * This abstraction is needed not only because not all platforms have
+ * \a rand() and \a srand(), but also on some platforms \a rand()
+ * only has 16-bit randomness, which is not good enough.
+ */
+
+/**
+ * Put in seed to random number generator.
+ *
+ * @param seed Seed value.
+ */
+PJ_DECL(void) pj_srand(unsigned int seed);
+
+
+/**
+ * Generate random integer with 32bit randomness.
+ *
+ * @return a random integer.
+ */
+PJ_DECL(int) pj_rand(void);
+
+
+/** @} */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJ_RAND_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/rbtree.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/rbtree.h
new file mode 100644
index 0000000..f07e509
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/rbtree.h
@@ -0,0 +1,210 @@
+/* $Id: rbtree.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_RBTREE_H__
+#define __PJ_RBTREE_H__
+
+/**
+ * @file rbtree.h
+ * @brief Red/Black Tree
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_RBTREE Red/Black Balanced Tree
+ * @ingroup PJ_DS
+ * @brief
+ * Red/Black tree is the variant of balanced tree, where the search, insert,
+ * and delete operation is \b guaranteed to take at most \a O( lg(n) ).
+ * @{
+ */
+/**
+ * Color type for Red-Black tree.
+ */
+typedef enum pj_rbcolor_t
+{
+ PJ_RBCOLOR_BLACK,
+ PJ_RBCOLOR_RED
+} pj_rbcolor_t;
+
+/**
+ * The type of the node of the R/B Tree.
+ */
+typedef struct pj_rbtree_node
+{
+ /** Pointers to the node's parent, and left and right siblings. */
+ struct pj_rbtree_node *parent, *left, *right;
+
+ /** Key associated with the node. */
+ const void *key;
+
+ /** User data associated with the node. */
+ void *user_data;
+
+ /** The R/B Tree node color. */
+ pj_rbcolor_t color;
+
+} pj_rbtree_node;
+
+
+/**
+ * The type of function use to compare key value of tree node.
+ * @return
+ * 0 if the keys are equal
+ * <0 if key1 is lower than key2
+ * >0 if key1 is greater than key2.
+ */
+typedef int pj_rbtree_comp(const void *key1, const void *key2);
+
+
+/**
+ * Declaration of a red-black tree. All elements in the tree must have UNIQUE
+ * key.
+ * A red black tree always maintains the balance of the tree, so that the
+ * tree height will not be greater than lg(N). Insert, search, and delete
+ * operation will take lg(N) on the worst case. But for insert and delete,
+ * there is additional time needed to maintain the balance of the tree.
+ */
+typedef struct pj_rbtree
+{
+ pj_rbtree_node null_node; /**< Constant to indicate NULL node. */
+ pj_rbtree_node *null; /**< Constant to indicate NULL node. */
+ pj_rbtree_node *root; /**< Root tree node. */
+ unsigned size; /**< Number of elements in the tree. */
+ pj_rbtree_comp *comp; /**< Key comparison function. */
+} pj_rbtree;
+
+
+/**
+ * Guidance on how much memory required for each of the node.
+ */
+#define PJ_RBTREE_NODE_SIZE (sizeof(pj_rbtree_node))
+
+
+/**
+ * Guidance on memory required for the tree.
+ */
+#define PJ_RBTREE_SIZE (sizeof(pj_rbtree))
+
+
+/**
+ * Initialize the tree.
+ * @param tree the tree to be initialized.
+ * @param comp key comparison function to be used for this tree.
+ */
+PJ_DECL(void) pj_rbtree_init( pj_rbtree *tree, pj_rbtree_comp *comp);
+
+/**
+ * Get the first element in the tree.
+ * The first element always has the least value for the key, according to
+ * the comparison function.
+ * @param tree the tree.
+ * @return the tree node, or NULL if the tree has no element.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_first( pj_rbtree *tree );
+
+/**
+ * Get the last element in the tree.
+ * The last element always has the greatest key value, according to the
+ * comparison function defined for the tree.
+ * @param tree the tree.
+ * @return the tree node, or NULL if the tree has no element.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_last( pj_rbtree *tree );
+
+/**
+ * Get the successive element for the specified node.
+ * The successive element is an element with greater key value.
+ * @param tree the tree.
+ * @param node the node.
+ * @return the successive node, or NULL if the node has no successor.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_next( pj_rbtree *tree,
+ pj_rbtree_node *node );
+
+/**
+ * The the previous node for the specified node.
+ * The previous node is an element with less key value.
+ * @param tree the tree.
+ * @param node the node.
+ * @return the previous node, or NULL if the node has no previous node.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_prev( pj_rbtree *tree,
+ pj_rbtree_node *node );
+
+/**
+ * Insert a new node.
+ * The node will be inserted at sorted location. The key of the node must
+ * be UNIQUE, i.e. it hasn't existed in the tree.
+ * @param tree the tree.
+ * @param node the node to be inserted.
+ * @return zero on success, or -1 if the key already exist.
+ */
+PJ_DECL(int) pj_rbtree_insert( pj_rbtree *tree,
+ pj_rbtree_node *node );
+
+/**
+ * Find a node which has the specified key.
+ * @param tree the tree.
+ * @param key the key to search.
+ * @return the tree node with the specified key, or NULL if the key can not
+ * be found.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_find( pj_rbtree *tree,
+ const void *key );
+
+/**
+ * Erase a node from the tree.
+ * @param tree the tree.
+ * @param node the node to be erased.
+ * @return the tree node itself.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_erase( pj_rbtree *tree,
+ pj_rbtree_node *node );
+
+/**
+ * Get the maximum tree height from the specified node.
+ * @param tree the tree.
+ * @param node the node, or NULL to get the root of the tree.
+ * @return the maximum height, which should be at most lg(N)
+ */
+PJ_DECL(unsigned) pj_rbtree_max_height( pj_rbtree *tree,
+ pj_rbtree_node *node );
+
+/**
+ * Get the minumum tree height from the specified node.
+ * @param tree the tree.
+ * @param node the node, or NULL to get the root of the tree.
+ * @return the height
+ */
+PJ_DECL(unsigned) pj_rbtree_min_height( pj_rbtree *tree,
+ pj_rbtree_node *node );
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJ_RBTREE_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/sock.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/sock.h
new file mode 100644
index 0000000..2c077ca
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/sock.h
@@ -0,0 +1,1375 @@
+/* $Id: sock.h 2966 2009-10-25 09:02:07Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_SOCK_H__
+#define __PJ_SOCK_H__
+
+/**
+ * @file sock.h
+ * @brief Socket Abstraction.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_SOCK Socket Abstraction
+ * @ingroup PJ_IO
+ * @{
+ *
+ * The PJLIB socket abstraction layer is a thin and very portable abstraction
+ * for socket API. It provides API similar to BSD socket API. The abstraction
+ * is needed because BSD socket API is not always available on all platforms,
+ * therefore it wouldn't be possible to create a trully portable network
+ * programs unless we provide such abstraction.
+ *
+ * Applications can use this API directly in their application, just
+ * as they would when using traditional BSD socket API, provided they
+ * call #pj_init() first.
+ *
+ * \section pj_sock_examples_sec Examples
+ *
+ * For some examples on how to use the socket API, please see:
+ *
+ * - \ref page_pjlib_sock_test
+ * - \ref page_pjlib_select_test
+ * - \ref page_pjlib_sock_perf_test
+ */
+
+
+/**
+ * Supported address families.
+ * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL AF_*, BECAUSE
+ * THE LIBRARY WILL DO TRANSLATION TO THE NATIVE VALUE.
+ */
+
+/** Address family is unspecified. @see pj_AF_UNSPEC() */
+extern const pj_uint16_t PJ_AF_UNSPEC;
+
+/** Unix domain socket. @see pj_AF_UNIX() */
+extern const pj_uint16_t PJ_AF_UNIX;
+
+/** POSIX name for AF_UNIX */
+#define PJ_AF_LOCAL PJ_AF_UNIX;
+
+/** Internet IP protocol. @see pj_AF_INET() */
+extern const pj_uint16_t PJ_AF_INET;
+
+/** IP version 6. @see pj_AF_INET6() */
+extern const pj_uint16_t PJ_AF_INET6;
+
+/** Packet family. @see pj_AF_PACKET() */
+extern const pj_uint16_t PJ_AF_PACKET;
+
+/** IRDA sockets. @see pj_AF_IRDA() */
+extern const pj_uint16_t PJ_AF_IRDA;
+
+/*
+ * Accessor functions for various address family constants. These
+ * functions are provided because Symbian doesn't allow exporting
+ * global variables from a DLL.
+ */
+
+#if defined(PJ_DLL)
+ /** Get #PJ_AF_UNSPEC value */
+ PJ_DECL(pj_uint16_t) pj_AF_UNSPEC(void);
+ /** Get #PJ_AF_UNIX value. */
+ PJ_DECL(pj_uint16_t) pj_AF_UNIX(void);
+ /** Get #PJ_AF_INET value. */
+ PJ_DECL(pj_uint16_t) pj_AF_INET(void);
+ /** Get #PJ_AF_INET6 value. */
+ PJ_DECL(pj_uint16_t) pj_AF_INET6(void);
+ /** Get #PJ_AF_PACKET value. */
+ PJ_DECL(pj_uint16_t) pj_AF_PACKET(void);
+ /** Get #PJ_AF_IRDA value. */
+ PJ_DECL(pj_uint16_t) pj_AF_IRDA(void);
+#else
+ /* When pjlib is not built as DLL, these accessor functions are
+ * simply a macro to get their constants
+ */
+ /** Get #PJ_AF_UNSPEC value */
+# define pj_AF_UNSPEC() PJ_AF_UNSPEC
+ /** Get #PJ_AF_UNIX value. */
+# define pj_AF_UNIX() PJ_AF_UNIX
+ /** Get #PJ_AF_INET value. */
+# define pj_AF_INET() PJ_AF_INET
+ /** Get #PJ_AF_INET6 value. */
+# define pj_AF_INET6() PJ_AF_INET6
+ /** Get #PJ_AF_PACKET value. */
+# define pj_AF_PACKET() PJ_AF_PACKET
+ /** Get #PJ_AF_IRDA value. */
+# define pj_AF_IRDA() PJ_AF_IRDA
+#endif
+
+
+/**
+ * Supported types of sockets.
+ * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOCK_*, BECAUSE
+ * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE.
+ */
+
+/** Sequenced, reliable, connection-based byte streams.
+ * @see pj_SOCK_STREAM() */
+extern const pj_uint16_t PJ_SOCK_STREAM;
+
+/** Connectionless, unreliable datagrams of fixed maximum lengths.
+ * @see pj_SOCK_DGRAM() */
+extern const pj_uint16_t PJ_SOCK_DGRAM;
+
+/** Raw protocol interface. @see pj_SOCK_RAW() */
+extern const pj_uint16_t PJ_SOCK_RAW;
+
+/** Reliably-delivered messages. @see pj_SOCK_RDM() */
+extern const pj_uint16_t PJ_SOCK_RDM;
+
+
+/*
+ * Accessor functions for various constants. These functions are provided
+ * because Symbian doesn't allow exporting global variables from a DLL.
+ */
+
+#if defined(PJ_DLL)
+ /** Get #PJ_SOCK_STREAM constant */
+ PJ_DECL(int) pj_SOCK_STREAM(void);
+ /** Get #PJ_SOCK_DGRAM constant */
+ PJ_DECL(int) pj_SOCK_DGRAM(void);
+ /** Get #PJ_SOCK_RAW constant */
+ PJ_DECL(int) pj_SOCK_RAW(void);
+ /** Get #PJ_SOCK_RDM constant */
+ PJ_DECL(int) pj_SOCK_RDM(void);
+#else
+ /** Get #PJ_SOCK_STREAM constant */
+# define pj_SOCK_STREAM() PJ_SOCK_STREAM
+ /** Get #PJ_SOCK_DGRAM constant */
+# define pj_SOCK_DGRAM() PJ_SOCK_DGRAM
+ /** Get #PJ_SOCK_RAW constant */
+# define pj_SOCK_RAW() PJ_SOCK_RAW
+ /** Get #PJ_SOCK_RDM constant */
+# define pj_SOCK_RDM() PJ_SOCK_RDM
+#endif
+
+
+/**
+ * Socket level specified in #pj_sock_setsockopt() or #pj_sock_getsockopt().
+ * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOL_*, BECAUSE
+ * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE.
+ */
+/** Socket level. @see pj_SOL_SOCKET() */
+extern const pj_uint16_t PJ_SOL_SOCKET;
+/** IP level. @see pj_SOL_IP() */
+extern const pj_uint16_t PJ_SOL_IP;
+/** TCP level. @see pj_SOL_TCP() */
+extern const pj_uint16_t PJ_SOL_TCP;
+/** UDP level. @see pj_SOL_UDP() */
+extern const pj_uint16_t PJ_SOL_UDP;
+/** IP version 6. @see pj_SOL_IPV6() */
+extern const pj_uint16_t PJ_SOL_IPV6;
+
+/*
+ * Accessor functions for various constants. These functions are provided
+ * because Symbian doesn't allow exporting global variables from a DLL.
+ */
+
+#if defined(PJ_DLL)
+ /** Get #PJ_SOL_SOCKET constant */
+ PJ_DECL(pj_uint16_t) pj_SOL_SOCKET(void);
+ /** Get #PJ_SOL_IP constant */
+ PJ_DECL(pj_uint16_t) pj_SOL_IP(void);
+ /** Get #PJ_SOL_TCP constant */
+ PJ_DECL(pj_uint16_t) pj_SOL_TCP(void);
+ /** Get #PJ_SOL_UDP constant */
+ PJ_DECL(pj_uint16_t) pj_SOL_UDP(void);
+ /** Get #PJ_SOL_IPV6 constant */
+ PJ_DECL(pj_uint16_t) pj_SOL_IPV6(void);
+#else
+ /** Get #PJ_SOL_SOCKET constant */
+# define pj_SOL_SOCKET() PJ_SOL_SOCKET
+ /** Get #PJ_SOL_IP constant */
+# define pj_SOL_IP() PJ_SOL_IP
+ /** Get #PJ_SOL_TCP constant */
+# define pj_SOL_TCP() PJ_SOL_TCP
+ /** Get #PJ_SOL_UDP constant */
+# define pj_SOL_UDP() PJ_SOL_UDP
+ /** Get #PJ_SOL_IPV6 constant */
+# define pj_SOL_IPV6() PJ_SOL_IPV6
+#endif
+
+
+/* IP_TOS
+ *
+ * Note:
+ * TOS CURRENTLY DOES NOT WORK IN Windows 2000 and above!
+ * See http://support.microsoft.com/kb/248611
+ */
+/** IP_TOS optname in setsockopt(). @see pj_IP_TOS() */
+extern const pj_uint16_t PJ_IP_TOS;
+
+/*
+ * IP TOS related constats.
+ *
+ * Note:
+ * TOS CURRENTLY DOES NOT WORK IN Windows 2000 and above!
+ * See http://support.microsoft.com/kb/248611
+ */
+/** Minimize delays. @see pj_IPTOS_LOWDELAY() */
+extern const pj_uint16_t PJ_IPTOS_LOWDELAY;
+
+/** Optimize throughput. @see pj_IPTOS_THROUGHPUT() */
+extern const pj_uint16_t PJ_IPTOS_THROUGHPUT;
+
+/** Optimize for reliability. @see pj_IPTOS_RELIABILITY() */
+extern const pj_uint16_t PJ_IPTOS_RELIABILITY;
+
+/** "filler data" where slow transmission does't matter.
+ * @see pj_IPTOS_MINCOST() */
+extern const pj_uint16_t PJ_IPTOS_MINCOST;
+
+
+#if defined(PJ_DLL)
+ /** Get #PJ_IP_TOS constant */
+ PJ_DECL(int) pj_IP_TOS(void);
+
+ /** Get #PJ_IPTOS_LOWDELAY constant */
+ PJ_DECL(int) pj_IPTOS_LOWDELAY(void);
+
+ /** Get #PJ_IPTOS_THROUGHPUT constant */
+ PJ_DECL(int) pj_IPTOS_THROUGHPUT(void);
+
+ /** Get #PJ_IPTOS_RELIABILITY constant */
+ PJ_DECL(int) pj_IPTOS_RELIABILITY(void);
+
+ /** Get #PJ_IPTOS_MINCOST constant */
+ PJ_DECL(int) pj_IPTOS_MINCOST(void);
+#else
+ /** Get #PJ_IP_TOS constant */
+# define pj_IP_TOS() PJ_IP_TOS
+
+ /** Get #PJ_IPTOS_LOWDELAY constant */
+# define pj_IPTOS_LOWDELAY() PJ_IP_TOS_LOWDELAY
+
+ /** Get #PJ_IPTOS_THROUGHPUT constant */
+# define pj_IPTOS_THROUGHPUT() PJ_IP_TOS_THROUGHPUT
+
+ /** Get #PJ_IPTOS_RELIABILITY constant */
+# define pj_IPTOS_RELIABILITY() PJ_IP_TOS_RELIABILITY
+
+ /** Get #PJ_IPTOS_MINCOST constant */
+# define pj_IPTOS_MINCOST() PJ_IP_TOS_MINCOST
+#endif
+
+
+/**
+ * Values to be specified as \c optname when calling #pj_sock_setsockopt()
+ * or #pj_sock_getsockopt().
+ */
+
+/** Socket type. @see pj_SO_TYPE() */
+extern const pj_uint16_t PJ_SO_TYPE;
+
+/** Buffer size for receive. @see pj_SO_RCVBUF() */
+extern const pj_uint16_t PJ_SO_RCVBUF;
+
+/** Buffer size for send. @see pj_SO_SNDBUF() */
+extern const pj_uint16_t PJ_SO_SNDBUF;
+
+/** Disables the Nagle algorithm for send coalescing. @see pj_TCP_NODELAY */
+extern const pj_uint16_t PJ_TCP_NODELAY;
+
+/** Allows the socket to be bound to an address that is already in use.
+ * @see pj_SO_REUSEADDR */
+extern const pj_uint16_t PJ_SO_REUSEADDR;
+
+/** Set the protocol-defined priority for all packets to be sent on socket.
+ */
+extern const pj_uint16_t PJ_SO_PRIORITY;
+
+/** IP multicast interface. @see pj_IP_MULTICAST_IF() */
+extern const pj_uint16_t PJ_IP_MULTICAST_IF;
+
+/** IP multicast ttl. @see pj_IP_MULTICAST_TTL() */
+extern const pj_uint16_t PJ_IP_MULTICAST_TTL;
+
+/** IP multicast loopback. @see pj_IP_MULTICAST_LOOP() */
+extern const pj_uint16_t PJ_IP_MULTICAST_LOOP;
+
+/** Add an IP group membership. @see pj_IP_ADD_MEMBERSHIP() */
+extern const pj_uint16_t PJ_IP_ADD_MEMBERSHIP;
+
+/** Drop an IP group membership. @see pj_IP_DROP_MEMBERSHIP() */
+extern const pj_uint16_t PJ_IP_DROP_MEMBERSHIP;
+
+
+#if defined(PJ_DLL)
+ /** Get #PJ_SO_TYPE constant */
+ PJ_DECL(pj_uint16_t) pj_SO_TYPE(void);
+
+ /** Get #PJ_SO_RCVBUF constant */
+ PJ_DECL(pj_uint16_t) pj_SO_RCVBUF(void);
+
+ /** Get #PJ_SO_SNDBUF constant */
+ PJ_DECL(pj_uint16_t) pj_SO_SNDBUF(void);
+
+ /** Get #PJ_TCP_NODELAY constant */
+ PJ_DECL(pj_uint16_t) pj_TCP_NODELAY(void);
+
+ /** Get #PJ_SO_REUSEADDR constant */
+ PJ_DECL(pj_uint16_t) pj_SO_REUSEADDR(void);
+
+ /** Get #PJ_SO_PRIORITY constant */
+ PJ_DECL(pj_uint16_t) pj_SO_PRIORITY(void);
+
+ /** Get #PJ_IP_MULTICAST_IF constant */
+ PJ_DECL(pj_uint16_t) pj_IP_MULTICAST_IF(void);
+
+ /** Get #PJ_IP_MULTICAST_TTL constant */
+ PJ_DECL(pj_uint16_t) pj_IP_MULTICAST_TTL(void);
+
+ /** Get #PJ_IP_MULTICAST_LOOP constant */
+ PJ_DECL(pj_uint16_t) pj_IP_MULTICAST_LOOP(void);
+
+ /** Get #PJ_IP_ADD_MEMBERSHIP constant */
+ PJ_DECL(pj_uint16_t) pj_IP_ADD_MEMBERSHIP(void);
+
+ /** Get #PJ_IP_DROP_MEMBERSHIP constant */
+ PJ_DECL(pj_uint16_t) pj_IP_DROP_MEMBERSHIP(void);
+#else
+ /** Get #PJ_SO_TYPE constant */
+# define pj_SO_TYPE() PJ_SO_TYPE
+
+ /** Get #PJ_SO_RCVBUF constant */
+# define pj_SO_RCVBUF() PJ_SO_RCVBUF
+
+ /** Get #PJ_SO_SNDBUF constant */
+# define pj_SO_SNDBUF() PJ_SO_SNDBUF
+
+ /** Get #PJ_TCP_NODELAY constant */
+# define pj_TCP_NODELAY() PJ_TCP_NODELAY
+
+ /** Get #PJ_SO_REUSEADDR constant */
+# define pj_SO_REUSEADDR() PJ_SO_REUSEADDR
+
+ /** Get #PJ_SO_PRIORITY constant */
+# define pj_SO_PRIORITY() PJ_SO_PRIORITY
+
+ /** Get #PJ_IP_MULTICAST_IF constant */
+# define pj_IP_MULTICAST_IF() PJ_IP_MULTICAST_IF
+
+ /** Get #PJ_IP_MULTICAST_TTL constant */
+# define pj_IP_MULTICAST_TTL() PJ_IP_MULTICAST_TTL
+
+ /** Get #PJ_IP_MULTICAST_LOOP constant */
+# define pj_IP_MULTICAST_LOOP() PJ_IP_MULTICAST_LOOP
+
+ /** Get #PJ_IP_ADD_MEMBERSHIP constant */
+# define pj_IP_ADD_MEMBERSHIP() PJ_IP_ADD_MEMBERSHIP
+
+ /** Get #PJ_IP_DROP_MEMBERSHIP constant */
+# define pj_IP_DROP_MEMBERSHIP() PJ_IP_DROP_MEMBERSHIP
+#endif
+
+
+/*
+ * Flags to be specified in #pj_sock_recv, #pj_sock_send, etc.
+ */
+
+/** Out-of-band messages. @see pj_MSG_OOB() */
+extern const int PJ_MSG_OOB;
+
+/** Peek, don't remove from buffer. @see pj_MSG_PEEK() */
+extern const int PJ_MSG_PEEK;
+
+/** Don't route. @see pj_MSG_DONTROUTE() */
+extern const int PJ_MSG_DONTROUTE;
+
+
+#if defined(PJ_DLL)
+ /** Get #PJ_MSG_OOB constant */
+ PJ_DECL(int) pj_MSG_OOB(void);
+
+ /** Get #PJ_MSG_PEEK constant */
+ PJ_DECL(int) pj_MSG_PEEK(void);
+
+ /** Get #PJ_MSG_DONTROUTE constant */
+ PJ_DECL(int) pj_MSG_DONTROUTE(void);
+#else
+ /** Get #PJ_MSG_OOB constant */
+# define pj_MSG_OOB() PJ_MSG_OOB
+
+ /** Get #PJ_MSG_PEEK constant */
+# define pj_MSG_PEEK() PJ_MSG_PEEK
+
+ /** Get #PJ_MSG_DONTROUTE constant */
+# define pj_MSG_DONTROUTE() PJ_MSG_DONTROUTE
+#endif
+
+
+/**
+ * Flag to be specified in #pj_sock_shutdown().
+ */
+typedef enum pj_socket_sd_type
+{
+ PJ_SD_RECEIVE = 0, /**< No more receive. */
+ PJ_SHUT_RD = 0, /**< Alias for SD_RECEIVE. */
+ PJ_SD_SEND = 1, /**< No more sending. */
+ PJ_SHUT_WR = 1, /**< Alias for SD_SEND. */
+ PJ_SD_BOTH = 2, /**< No more send and receive. */
+ PJ_SHUT_RDWR = 2 /**< Alias for SD_BOTH. */
+} pj_socket_sd_type;
+
+
+
+/** Address to accept any incoming messages. */
+#define PJ_INADDR_ANY ((pj_uint32_t)0)
+
+/** Address indicating an error return */
+#define PJ_INADDR_NONE ((pj_uint32_t)0xffffffff)
+
+/** Address to send to all hosts. */
+#define PJ_INADDR_BROADCAST ((pj_uint32_t)0xffffffff)
+
+
+/**
+ * Maximum length specifiable by #pj_sock_listen().
+ * If the build system doesn't override this value, then the lowest
+ * denominator (five, in Win32 systems) will be used.
+ */
+#if !defined(PJ_SOMAXCONN)
+# define PJ_SOMAXCONN 5
+#endif
+
+
+/**
+ * Constant for invalid socket returned by #pj_sock_socket() and
+ * #pj_sock_accept().
+ */
+#define PJ_INVALID_SOCKET (-1)
+
+/* Must undefine s_addr because of pj_in_addr below */
+#undef s_addr
+
+/**
+ * This structure describes Internet address.
+ */
+typedef struct pj_in_addr
+{
+ pj_uint32_t s_addr; /**< The 32bit IP address. */
+} pj_in_addr;
+
+
+/**
+ * Maximum length of text representation of an IPv4 address.
+ */
+#define PJ_INET_ADDRSTRLEN 16
+
+/**
+ * Maximum length of text representation of an IPv6 address.
+ */
+#define PJ_INET6_ADDRSTRLEN 46
+
+
+/**
+ * This structure describes Internet socket address.
+ * If PJ_SOCKADDR_HAS_LEN is not zero, then sin_zero_len member is added
+ * to this struct. As far the application is concerned, the value of
+ * this member will always be zero. Internally, PJLIB may modify the value
+ * before calling OS socket API, and reset the value back to zero before
+ * returning the struct to application.
+ */
+struct pj_sockaddr_in
+{
+#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
+ pj_uint8_t sin_zero_len; /**< Just ignore this. */
+ pj_uint8_t sin_family; /**< Address family. */
+#else
+ pj_uint16_t sin_family; /**< Address family. */
+#endif
+ pj_uint16_t sin_port; /**< Transport layer port number. */
+ pj_in_addr sin_addr; /**< IP address. */
+ char sin_zero[8]; /**< Padding. */
+};
+
+
+#undef s6_addr
+
+/**
+ * This structure describes IPv6 address.
+ */
+typedef union pj_in6_addr
+{
+ /* This is the main entry */
+ pj_uint8_t s6_addr[16]; /**< 8-bit array */
+
+ /* While these are used for proper alignment */
+ pj_uint32_t u6_addr32[4];
+
+ /* Do not use this with Winsock2, as this will align pj_sockaddr_in6
+ * to 64-bit boundary and Winsock2 doesn't like it!
+ */
+#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 && \
+ (!defined(PJ_WIN32) || PJ_WIN32==0)
+ pj_int64_t u6_addr64[2];
+#endif
+
+} pj_in6_addr;
+
+
+/** Initializer value for pj_in6_addr. */
+#define PJ_IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+
+/** Initializer value for pj_in6_addr. */
+#define PJ_IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+
+/**
+ * This structure describes IPv6 socket address.
+ * If PJ_SOCKADDR_HAS_LEN is not zero, then sin_zero_len member is added
+ * to this struct. As far the application is concerned, the value of
+ * this member will always be zero. Internally, PJLIB may modify the value
+ * before calling OS socket API, and reset the value back to zero before
+ * returning the struct to application.
+ */
+typedef struct pj_sockaddr_in6
+{
+#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
+ pj_uint8_t sin6_zero_len; /**< Just ignore this. */
+ pj_uint8_t sin6_family; /**< Address family. */
+#else
+ pj_uint16_t sin6_family; /**< Address family */
+#endif
+ pj_uint16_t sin6_port; /**< Transport layer port number. */
+ pj_uint32_t sin6_flowinfo; /**< IPv6 flow information */
+ pj_in6_addr sin6_addr; /**< IPv6 address. */
+ pj_uint32_t sin6_scope_id; /**< Set of interfaces for a scope */
+} pj_sockaddr_in6;
+
+
+/**
+ * This structure describes common attributes found in transport addresses.
+ * If PJ_SOCKADDR_HAS_LEN is not zero, then sa_zero_len member is added
+ * to this struct. As far the application is concerned, the value of
+ * this member will always be zero. Internally, PJLIB may modify the value
+ * before calling OS socket API, and reset the value back to zero before
+ * returning the struct to application.
+ */
+typedef struct pj_addr_hdr
+{
+#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
+ pj_uint8_t sa_zero_len;
+ pj_uint8_t sa_family;
+#else
+ pj_uint16_t sa_family; /**< Common data: address family. */
+#endif
+} pj_addr_hdr;
+
+
+/**
+ * This union describes a generic socket address.
+ */
+typedef union pj_sockaddr
+{
+ pj_addr_hdr addr; /**< Generic transport address. */
+ pj_sockaddr_in ipv4; /**< IPv4 transport address. */
+ pj_sockaddr_in6 ipv6; /**< IPv6 transport address. */
+} pj_sockaddr;
+
+
+/**
+ * This structure provides multicast group information for IPv4 addresses.
+ */
+typedef struct pj_ip_mreq {
+ pj_in_addr imr_multiaddr; /**< IP multicast address of group. */
+ pj_in_addr imr_interface; /**< local IP address of interface. */
+} pj_ip_mreq;
+
+
+/*****************************************************************************
+ *
+ * SOCKET ADDRESS MANIPULATION.
+ *
+ *****************************************************************************
+ */
+
+/**
+ * Convert 16-bit value from network byte order to host byte order.
+ *
+ * @param netshort 16-bit network value.
+ * @return 16-bit host value.
+ */
+PJ_DECL(pj_uint16_t) pj_ntohs(pj_uint16_t netshort);
+
+/**
+ * Convert 16-bit value from host byte order to network byte order.
+ *
+ * @param hostshort 16-bit host value.
+ * @return 16-bit network value.
+ */
+PJ_DECL(pj_uint16_t) pj_htons(pj_uint16_t hostshort);
+
+/**
+ * Convert 32-bit value from network byte order to host byte order.
+ *
+ * @param netlong 32-bit network value.
+ * @return 32-bit host value.
+ */
+PJ_DECL(pj_uint32_t) pj_ntohl(pj_uint32_t netlong);
+
+/**
+ * Convert 32-bit value from host byte order to network byte order.
+ *
+ * @param hostlong 32-bit host value.
+ * @return 32-bit network value.
+ */
+PJ_DECL(pj_uint32_t) pj_htonl(pj_uint32_t hostlong);
+
+/**
+ * Convert an Internet host address given in network byte order
+ * to string in standard numbers and dots notation.
+ *
+ * @param inaddr The host address.
+ * @return The string address.
+ */
+PJ_DECL(char*) pj_inet_ntoa(pj_in_addr inaddr);
+
+/**
+ * This function converts the Internet host address cp from the standard
+ * numbers-and-dots notation into binary data and stores it in the structure
+ * that inp points to.
+ *
+ * @param cp IP address in standard numbers-and-dots notation.
+ * @param inp Structure that holds the output of the conversion.
+ *
+ * @return nonzero if the address is valid, zero if not.
+ */
+PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp);
+
+/**
+ * This function converts an address in its standard text presentation form
+ * into its numeric binary form. It supports both IPv4 and IPv6 address
+ * conversion.
+ *
+ * @param af Specify the family of the address. The PJ_AF_INET and
+ * PJ_AF_INET6 address families shall be supported.
+ * @param src Points to the string being passed in.
+ * @param dst Points to a buffer into which the function stores the
+ * numeric address; this shall be large enough to hold the
+ * numeric address (32 bits for PJ_AF_INET, 128 bits for
+ * PJ_AF_INET6).
+ *
+ * @return PJ_SUCCESS if conversion was successful.
+ */
+PJ_DECL(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst);
+
+/**
+ * This function converts a numeric address into a text string suitable
+ * for presentation. It supports both IPv4 and IPv6 address
+ * conversion.
+ * @see pj_sockaddr_print()
+ *
+ * @param af Specify the family of the address. This can be PJ_AF_INET
+ * or PJ_AF_INET6.
+ * @param src Points to a buffer holding an IPv4 address if the af argument
+ * is PJ_AF_INET, or an IPv6 address if the af argument is
+ * PJ_AF_INET6; the address must be in network byte order.
+ * @param dst Points to a buffer where the function stores the resulting
+ * text string; it shall not be NULL.
+ * @param size Specifies the size of this buffer, which shall be large
+ * enough to hold the text string (PJ_INET_ADDRSTRLEN characters
+ * for IPv4, PJ_INET6_ADDRSTRLEN characters for IPv6).
+ *
+ * @return PJ_SUCCESS if conversion was successful.
+ */
+PJ_DECL(pj_status_t) pj_inet_ntop(int af, const void *src,
+ char *dst, int size);
+
+/**
+ * Converts numeric address into its text string representation.
+ * @see pj_sockaddr_print()
+ *
+ * @param af Specify the family of the address. This can be PJ_AF_INET
+ * or PJ_AF_INET6.
+ * @param src Points to a buffer holding an IPv4 address if the af argument
+ * is PJ_AF_INET, or an IPv6 address if the af argument is
+ * PJ_AF_INET6; the address must be in network byte order.
+ * @param dst Points to a buffer where the function stores the resulting
+ * text string; it shall not be NULL.
+ * @param size Specifies the size of this buffer, which shall be large
+ * enough to hold the text string (PJ_INET_ADDRSTRLEN characters
+ * for IPv4, PJ_INET6_ADDRSTRLEN characters for IPv6).
+ *
+ * @return The address string or NULL if failed.
+ */
+PJ_DECL(char*) pj_inet_ntop2(int af, const void *src,
+ char *dst, int size);
+
+/**
+ * Print socket address.
+ *
+ * @param addr The socket address.
+ * @param buf Text buffer.
+ * @param size Size of buffer.
+ * @param flags Bitmask combination of these value:
+ * - 1: port number is included.
+ * - 2: square bracket is included for IPv6 address.
+ *
+ * @return The address string.
+ */
+PJ_DECL(char*) pj_sockaddr_print(const pj_sockaddr_t *addr,
+ char *buf, int size,
+ unsigned flags);
+
+/**
+ * Convert address string with numbers and dots to binary IP address.
+ *
+ * @param cp The IP address in numbers and dots notation.
+ * @return If success, the IP address is returned in network
+ * byte order. If failed, PJ_INADDR_NONE will be
+ * returned.
+ * @remark
+ * This is an obsolete interface to #pj_inet_aton(); it is obsolete
+ * because -1 is a valid address (255.255.255.255), and #pj_inet_aton()
+ * provides a cleaner way to indicate error return.
+ */
+PJ_DECL(pj_in_addr) pj_inet_addr(const pj_str_t *cp);
+
+/**
+ * Convert address string with numbers and dots to binary IP address.
+ *
+ * @param cp The IP address in numbers and dots notation.
+ * @return If success, the IP address is returned in network
+ * byte order. If failed, PJ_INADDR_NONE will be
+ * returned.
+ * @remark
+ * This is an obsolete interface to #pj_inet_aton(); it is obsolete
+ * because -1 is a valid address (255.255.255.255), and #pj_inet_aton()
+ * provides a cleaner way to indicate error return.
+ */
+PJ_DECL(pj_in_addr) pj_inet_addr2(const char *cp);
+
+/**
+ * Initialize IPv4 socket address based on the address and port info.
+ * The string address may be in a standard numbers and dots notation or
+ * may be a hostname. If hostname is specified, then the function will
+ * resolve the host into the IP address.
+ *
+ * @see pj_sockaddr_init()
+ *
+ * @param addr The IP socket address to be set.
+ * @param cp The address string, which can be in a standard
+ * dotted numbers or a hostname to be resolved.
+ * @param port The port number, in host byte order.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr,
+ const pj_str_t *cp,
+ pj_uint16_t port);
+
+/**
+ * Initialize IP socket address based on the address and port info.
+ * The string address may be in a standard numbers and dots notation or
+ * may be a hostname. If hostname is specified, then the function will
+ * resolve the host into the IP address.
+ *
+ * @see pj_sockaddr_in_init()
+ *
+ * @param af Internet address family.
+ * @param addr The IP socket address to be set.
+ * @param cp The address string, which can be in a standard
+ * dotted numbers or a hostname to be resolved.
+ * @param port The port number, in host byte order.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sockaddr_init(int af,
+ pj_sockaddr *addr,
+ const pj_str_t *cp,
+ pj_uint16_t port);
+
+/**
+ * Compare two socket addresses.
+ *
+ * @param addr1 First address.
+ * @param addr2 Second address.
+ *
+ * @return Zero on equal, -1 if addr1 is less than addr2,
+ * and +1 if addr1 is more than addr2.
+ */
+PJ_DECL(int) pj_sockaddr_cmp(const pj_sockaddr_t *addr1,
+ const pj_sockaddr_t *addr2);
+
+/**
+ * Get pointer to the address part of a socket address.
+ *
+ * @param addr Socket address.
+ *
+ * @return Pointer to address part (sin_addr or sin6_addr,
+ * depending on address family)
+ */
+PJ_DECL(void*) pj_sockaddr_get_addr(const pj_sockaddr_t *addr);
+
+/**
+ * Check that a socket address contains a non-zero address part.
+ *
+ * @param addr Socket address.
+ *
+ * @return Non-zero if address is set to non-zero.
+ */
+PJ_DECL(pj_bool_t) pj_sockaddr_has_addr(const pj_sockaddr_t *addr);
+
+/**
+ * Get the address part length of a socket address, based on its address
+ * family. For PJ_AF_INET, the length will be sizeof(pj_in_addr), and
+ * for PJ_AF_INET6, the length will be sizeof(pj_in6_addr).
+ *
+ * @param addr Socket address.
+ *
+ * @return Length in bytes.
+ */
+PJ_DECL(unsigned) pj_sockaddr_get_addr_len(const pj_sockaddr_t *addr);
+
+/**
+ * Get the socket address length, based on its address
+ * family. For PJ_AF_INET, the length will be sizeof(pj_sockaddr_in), and
+ * for PJ_AF_INET6, the length will be sizeof(pj_sockaddr_in6).
+ *
+ * @param addr Socket address.
+ *
+ * @return Length in bytes.
+ */
+PJ_DECL(unsigned) pj_sockaddr_get_len(const pj_sockaddr_t *addr);
+
+/**
+ * Copy only the address part (sin_addr/sin6_addr) of a socket address.
+ *
+ * @param dst Destination socket address.
+ * @param src Source socket address.
+ *
+ * @see @pj_sockaddr_cp()
+ */
+PJ_DECL(void) pj_sockaddr_copy_addr(pj_sockaddr *dst,
+ const pj_sockaddr *src);
+/**
+ * Copy socket address. This will copy the whole structure depending
+ * on the address family of the source socket address.
+ *
+ * @param dst Destination socket address.
+ * @param src Source socket address.
+ *
+ * @see @pj_sockaddr_copy_addr()
+ */
+PJ_DECL(void) pj_sockaddr_cp(pj_sockaddr_t *dst, const pj_sockaddr_t *src);
+
+/**
+ * Get the IP address of an IPv4 socket address.
+ * The address is returned as 32bit value in host byte order.
+ *
+ * @param addr The IP socket address.
+ * @return 32bit address, in host byte order.
+ */
+PJ_DECL(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr);
+
+/**
+ * Set the IP address of an IPv4 socket address.
+ *
+ * @param addr The IP socket address.
+ * @param hostaddr The host address, in host byte order.
+ */
+PJ_DECL(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr,
+ pj_uint32_t hostaddr);
+
+/**
+ * Set the IP address of an IP socket address from string address,
+ * with resolving the host if necessary. The string address may be in a
+ * standard numbers and dots notation or may be a hostname. If hostname
+ * is specified, then the function will resolve the host into the IP
+ * address.
+ *
+ * @see pj_sockaddr_set_str_addr()
+ *
+ * @param addr The IP socket address to be set.
+ * @param cp The address string, which can be in a standard
+ * dotted numbers or a hostname to be resolved.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr,
+ const pj_str_t *cp);
+
+/**
+ * Set the IP address of an IPv4 or IPv6 socket address from string address,
+ * with resolving the host if necessary. The string address may be in a
+ * standard IPv6 or IPv6 address or may be a hostname. If hostname
+ * is specified, then the function will resolve the host into the IP
+ * address according to the address family.
+ *
+ * @param af Address family.
+ * @param addr The IP socket address to be set.
+ * @param cp The address string, which can be in a standard
+ * IP numbers (IPv4 or IPv6) or a hostname to be resolved.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_sockaddr_set_str_addr(int af,
+ pj_sockaddr *addr,
+ const pj_str_t *cp);
+
+/**
+ * Get the port number of a socket address, in host byte order.
+ * This function can be used for both IPv4 and IPv6 socket address.
+ *
+ * @param addr Socket address.
+ *
+ * @return Port number, in host byte order.
+ */
+PJ_DECL(pj_uint16_t) pj_sockaddr_get_port(const pj_sockaddr_t *addr);
+
+/**
+ * Get the transport layer port number of an Internet socket address.
+ * The port is returned in host byte order.
+ *
+ * @param addr The IP socket address.
+ * @return Port number, in host byte order.
+ */
+PJ_DECL(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr);
+
+/**
+ * Set the port number of an Internet socket address.
+ *
+ * @param addr The socket address.
+ * @param hostport The port number, in host byte order.
+ */
+PJ_DECL(pj_status_t) pj_sockaddr_set_port(pj_sockaddr *addr,
+ pj_uint16_t hostport);
+
+/**
+ * Set the port number of an IPv4 socket address.
+ *
+ * @see pj_sockaddr_set_port()
+ *
+ * @param addr The IP socket address.
+ * @param hostport The port number, in host byte order.
+ */
+PJ_DECL(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr,
+ pj_uint16_t hostport);
+
+/**
+ * Parse string containing IP address and optional port into socket address,
+ * possibly also with address family detection. This function supports both
+ * IPv4 and IPv6 parsing, however IPv6 parsing may only be done if IPv6 is
+ * enabled during compilation.
+ *
+ * This function supports parsing several formats. Sample IPv4 inputs and
+ * their default results::
+ * - "10.0.0.1:80": address 10.0.0.1 and port 80.
+ * - "10.0.0.1": address 10.0.0.1 and port zero.
+ * - "10.0.0.1:": address 10.0.0.1 and port zero.
+ * - "10.0.0.1:0": address 10.0.0.1 and port zero.
+ * - ":80": address 0.0.0.0 and port 80.
+ * - ":": address 0.0.0.0 and port 0.
+ * - "localhost": address 127.0.0.1 and port 0.
+ * - "localhost:": address 127.0.0.1 and port 0.
+ * - "localhost:80": address 127.0.0.1 and port 80.
+ *
+ * Sample IPv6 inputs and their default results:
+ * - "[fec0::01]:80": address fec0::01 and port 80
+ * - "[fec0::01]": address fec0::01 and port 0
+ * - "[fec0::01]:": address fec0::01 and port 0
+ * - "[fec0::01]:0": address fec0::01 and port 0
+ * - "fec0::01": address fec0::01 and port 0
+ * - "fec0::01:80": address fec0::01:80 and port 0
+ * - "::": address zero (::) and port 0
+ * - "[::]": address zero (::) and port 0
+ * - "[::]:": address zero (::) and port 0
+ * - ":::": address zero (::) and port 0
+ * - "[::]:80": address zero (::) and port 0
+ * - ":::80": address zero (::) and port 80
+ *
+ * Note: when the IPv6 socket address contains port number, the IP
+ * part of the socket address should be enclosed with square brackets,
+ * otherwise the port number will be included as part of the IP address
+ * (see "fec0::01:80" example above).
+ *
+ * @param af Optionally specify the address family to be used. If the
+ * address family is to be deducted from the input, specify
+ * pj_AF_UNSPEC() here. Other supported values are
+ * #pj_AF_INET() and #pj_AF_INET6()
+ * @param options Additional options to assist the parsing, must be zero
+ * for now.
+ * @param str The input string to be parsed.
+ * @param addr Pointer to store the result.
+ *
+ * @return PJ_SUCCESS if the parsing is successful.
+ *
+ * @see pj_sockaddr_parse2()
+ */
+PJ_DECL(pj_status_t) pj_sockaddr_parse(int af, unsigned options,
+ const pj_str_t *str,
+ pj_sockaddr *addr);
+
+/**
+ * This function is similar to #pj_sockaddr_parse(), except that it will not
+ * convert the hostpart into IP address (thus possibly resolving the hostname
+ * into a #pj_sockaddr.
+ *
+ * Unlike #pj_sockaddr_parse(), this function has a limitation that if port
+ * number is specified in an IPv6 input string, the IP part of the IPv6 socket
+ * address MUST be enclosed in square brackets, otherwise the port number will
+ * be considered as part of the IPv6 IP address.
+ *
+ * @param af Optionally specify the address family to be used. If the
+ * address family is to be deducted from the input, specify
+ * #pj_AF_UNSPEC() here. Other supported values are
+ * #pj_AF_INET() and #pj_AF_INET6()
+ * @param options Additional options to assist the parsing, must be zero
+ * for now.
+ * @param str The input string to be parsed.
+ * @param hostpart Optional pointer to store the host part of the socket
+ * address, with any brackets removed.
+ * @param port Optional pointer to store the port number. If port number
+ * is not found, this will be set to zero upon return.
+ * @param raf Optional pointer to store the detected address family of
+ * the input address.
+ *
+ * @return PJ_SUCCESS if the parsing is successful.
+ *
+ * @see pj_sockaddr_parse()
+ */
+PJ_DECL(pj_status_t) pj_sockaddr_parse2(int af, unsigned options,
+ const pj_str_t *str,
+ pj_str_t *hostpart,
+ pj_uint16_t *port,
+ int *raf);
+
+/*****************************************************************************
+ *
+ * HOST NAME AND ADDRESS.
+ *
+ *****************************************************************************
+ */
+
+/**
+ * Get system's host name.
+ *
+ * @return The hostname, or empty string if the hostname can not
+ * be identified.
+ */
+PJ_DECL(const pj_str_t*) pj_gethostname(void);
+
+/**
+ * Get host's IP address, which the the first IP address that is resolved
+ * from the hostname.
+ *
+ * @return The host's IP address, PJ_INADDR_NONE if the host
+ * IP address can not be identified.
+ */
+PJ_DECL(pj_in_addr) pj_gethostaddr(void);
+
+
+/*****************************************************************************
+ *
+ * SOCKET API.
+ *
+ *****************************************************************************
+ */
+
+/**
+ * Create new socket/endpoint for communication.
+ *
+ * @param family Specifies a communication domain; this selects the
+ * protocol family which will be used for communication.
+ * @param type The socket has the indicated type, which specifies the
+ * communication semantics.
+ * @param protocol Specifies a particular protocol to be used with the
+ * socket. Normally only a single protocol exists to support
+ * a particular socket type within a given protocol family,
+ * in which a case protocol can be specified as 0.
+ * @param sock New socket descriptor, or PJ_INVALID_SOCKET on error.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_socket(int family,
+ int type,
+ int protocol,
+ pj_sock_t *sock);
+
+/**
+ * Close the socket descriptor.
+ *
+ * @param sockfd The socket descriptor.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_close(pj_sock_t sockfd);
+
+
+/**
+ * This function gives the socket sockfd the local address my_addr. my_addr is
+ * addrlen bytes long. Traditionally, this is called assigning a name to
+ * a socket. When a socket is created with #pj_sock_socket(), it exists in a
+ * name space (address family) but has no name assigned.
+ *
+ * @param sockfd The socket desriptor.
+ * @param my_addr The local address to bind the socket to.
+ * @param addrlen The length of the address.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_bind( pj_sock_t sockfd,
+ const pj_sockaddr_t *my_addr,
+ int addrlen);
+
+/**
+ * Bind the IP socket sockfd to the given address and port.
+ *
+ * @param sockfd The socket descriptor.
+ * @param addr Local address to bind the socket to, in host byte order.
+ * @param port The local port to bind the socket to, in host byte order.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_bind_in( pj_sock_t sockfd,
+ pj_uint32_t addr,
+ pj_uint16_t port);
+
+#if PJ_HAS_TCP
+/**
+ * Listen for incoming connection. This function only applies to connection
+ * oriented sockets (such as PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET), and it
+ * indicates the willingness to accept incoming connections.
+ *
+ * @param sockfd The socket descriptor.
+ * @param backlog Defines the maximum length the queue of pending
+ * connections may grow to.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_listen( pj_sock_t sockfd,
+ int backlog );
+
+/**
+ * Accept new connection on the specified connection oriented server socket.
+ *
+ * @param serverfd The server socket.
+ * @param newsock New socket on success, of PJ_INVALID_SOCKET if failed.
+ * @param addr A pointer to sockaddr type. If the argument is not NULL,
+ * it will be filled by the address of connecting entity.
+ * @param addrlen Initially specifies the length of the address, and upon
+ * return will be filled with the exact address length.
+ *
+ * @return Zero on success, or the error number.
+ */
+PJ_DECL(pj_status_t) pj_sock_accept( pj_sock_t serverfd,
+ pj_sock_t *newsock,
+ pj_sockaddr_t *addr,
+ int *addrlen);
+#endif
+
+/**
+ * The file descriptor sockfd must refer to a socket. If the socket is of
+ * type PJ_SOCK_DGRAM then the serv_addr address is the address to which
+ * datagrams are sent by default, and the only address from which datagrams
+ * are received. If the socket is of type PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET,
+ * this call attempts to make a connection to another socket. The
+ * other socket is specified by serv_addr, which is an address (of length
+ * addrlen) in the communications space of the socket. Each communications
+ * space interprets the serv_addr parameter in its own way.
+ *
+ * @param sockfd The socket descriptor.
+ * @param serv_addr Server address to connect to.
+ * @param addrlen The length of server address.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_connect( pj_sock_t sockfd,
+ const pj_sockaddr_t *serv_addr,
+ int addrlen);
+
+/**
+ * Return the address of peer which is connected to socket sockfd.
+ *
+ * @param sockfd The socket descriptor.
+ * @param addr Pointer to sockaddr structure to which the address
+ * will be returned.
+ * @param namelen Initially the length of the addr. Upon return the value
+ * will be set to the actual length of the address.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_getpeername(pj_sock_t sockfd,
+ pj_sockaddr_t *addr,
+ int *namelen);
+
+/**
+ * Return the current name of the specified socket.
+ *
+ * @param sockfd The socket descriptor.
+ * @param addr Pointer to sockaddr structure to which the address
+ * will be returned.
+ * @param namelen Initially the length of the addr. Upon return the value
+ * will be set to the actual length of the address.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_getsockname( pj_sock_t sockfd,
+ pj_sockaddr_t *addr,
+ int *namelen);
+
+/**
+ * Get socket option associated with a socket. Options may exist at multiple
+ * protocol levels; they are always present at the uppermost socket level.
+ *
+ * @param sockfd The socket descriptor.
+ * @param level The level which to get the option from.
+ * @param optname The option name.
+ * @param optval Identifies the buffer which the value will be
+ * returned.
+ * @param optlen Initially contains the length of the buffer, upon
+ * return will be set to the actual size of the value.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_getsockopt( pj_sock_t sockfd,
+ pj_uint16_t level,
+ pj_uint16_t optname,
+ void *optval,
+ int *optlen);
+/**
+ * Manipulate the options associated with a socket. Options may exist at
+ * multiple protocol levels; they are always present at the uppermost socket
+ * level.
+ *
+ * @param sockfd The socket descriptor.
+ * @param level The level which to get the option from.
+ * @param optname The option name.
+ * @param optval Identifies the buffer which contain the value.
+ * @param optlen The length of the value.
+ *
+ * @return PJ_SUCCESS or the status code.
+ */
+PJ_DECL(pj_status_t) pj_sock_setsockopt( pj_sock_t sockfd,
+ pj_uint16_t level,
+ pj_uint16_t optname,
+ const void *optval,
+ int optlen);
+
+
+/**
+ * Receives data stream or message coming to the specified socket.
+ *
+ * @param sockfd The socket descriptor.
+ * @param buf The buffer to receive the data or message.
+ * @param len On input, the length of the buffer. On return,
+ * contains the length of data received.
+ * @param flags Flags (such as pj_MSG_PEEK()).
+ *
+ * @return PJ_SUCCESS or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sock_recv(pj_sock_t sockfd,
+ void *buf,
+ pj_ssize_t *len,
+ unsigned flags);
+
+/**
+ * Receives data stream or message coming to the specified socket.
+ *
+ * @param sockfd The socket descriptor.
+ * @param buf The buffer to receive the data or message.
+ * @param len On input, the length of the buffer. On return,
+ * contains the length of data received.
+ * @param flags Flags (such as pj_MSG_PEEK()).
+ * @param from If not NULL, it will be filled with the source
+ * address of the connection.
+ * @param fromlen Initially contains the length of from address,
+ * and upon return will be filled with the actual
+ * length of the address.
+ *
+ * @return PJ_SUCCESS or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sock_recvfrom( pj_sock_t sockfd,
+ void *buf,
+ pj_ssize_t *len,
+ unsigned flags,
+ pj_sockaddr_t *from,
+ int *fromlen);
+
+/**
+ * Transmit data to the socket.
+ *
+ * @param sockfd Socket descriptor.
+ * @param buf Buffer containing data to be sent.
+ * @param len On input, the length of the data in the buffer.
+ * Upon return, it will be filled with the length
+ * of data sent.
+ * @param flags Flags (such as pj_MSG_DONTROUTE()).
+ *
+ * @return PJ_SUCCESS or the status code.
+ */
+PJ_DECL(pj_status_t) pj_sock_send(pj_sock_t sockfd,
+ const void *buf,
+ pj_ssize_t *len,
+ unsigned flags);
+
+/**
+ * Transmit data to the socket to the specified address.
+ *
+ * @param sockfd Socket descriptor.
+ * @param buf Buffer containing data to be sent.
+ * @param len On input, the length of the data in the buffer.
+ * Upon return, it will be filled with the length
+ * of data sent.
+ * @param flags Flags (such as pj_MSG_DONTROUTE()).
+ * @param to The address to send.
+ * @param tolen The length of the address in bytes.
+ *
+ * @return PJ_SUCCESS or the status code.
+ */
+PJ_DECL(pj_status_t) pj_sock_sendto(pj_sock_t sockfd,
+ const void *buf,
+ pj_ssize_t *len,
+ unsigned flags,
+ const pj_sockaddr_t *to,
+ int tolen);
+
+#if PJ_HAS_TCP
+/**
+ * The shutdown call causes all or part of a full-duplex connection on the
+ * socket associated with sockfd to be shut down.
+ *
+ * @param sockfd The socket descriptor.
+ * @param how If how is PJ_SHUT_RD, further receptions will be
+ * disallowed. If how is PJ_SHUT_WR, further transmissions
+ * will be disallowed. If how is PJ_SHUT_RDWR, further
+ * receptions andtransmissions will be disallowed.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_shutdown( pj_sock_t sockfd,
+ int how);
+#endif
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJ_SOCK_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_qos.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_qos.h
new file mode 100644
index 0000000..cd29dfa
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_qos.h
@@ -0,0 +1,427 @@
+/* $Id: sock_qos.h 2967 2009-10-25 10:50:17Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_SOCK_QOS_H__
+#define __PJ_SOCK_QOS_H__
+
+/**
+ * @file sock_qos.h
+ * @brief Socket QoS API
+ */
+
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup socket_qos Socket Quality of Service (QoS) API: TOS, DSCP, WMM, IEEE 802.1p
+ * @ingroup PJ_SOCK
+ * @{
+
+
+ \section intro QoS Technologies
+
+ QoS settings are available for both Layer 2 and 3 of TCP/IP protocols:
+
+ \subsection intro_ieee8021p Layer 2: IEEE 802.1p for Ethernet
+
+ IEEE 802.1p tagging will mark frames sent by a host for prioritized
+ delivery using a 3-bit Priority field in the virtual local area network
+ (VLAN) header of the Ethernet frame. The VLAN header is placed inside
+ the Ethernet header, between the Source Address field and either the
+ Length field (for an IEEE 802.3 frame) or the EtherType field (for an
+ Ethernet II frame).
+
+ \subsection intro_wmm Layer 2: WMM
+
+ At the Network Interface layer for IEEE 802.11 wireless, the Wi-Fi
+ Alliance certification for Wi-Fi Multimedia (WMM) defines four access
+ categories for prioritizing network traffic. These access categories
+ are (in order of highest to lowest priority) voice, video, best-effort,
+ and background. Host support for WMM prioritization requires that both
+ wireless network adapters and their drivers support WMM. Wireless
+ access points (APs) must have WMM enabled.
+
+ \subsection intro_dscp Layer 3: DSCP
+
+ At the Internet layer, you can use Differentiated Services/Diffserv and
+ set the value of the Differentiated Services Code Point (DSCP) in the
+ IP header. As defined in RFC 2474, the DSCP value is the high-order 6 bits
+ of the IP version 4 (IPv4) TOS field and the IP version 6 (IPv6) Traffic
+ Class field.
+
+ \subsection intro_other Layer 3: Other
+
+ Other mechanisms exist (such as RSVP, IntServ) but this will not be
+ implemented.
+
+
+ \section availability QoS Availability
+
+ \subsection linux Linux
+
+ DSCP is available via IP TOS option.
+
+ Ethernet 802.1p tagging is done by setting setsockopt(SO_PRIORITY) option
+ of the socket, then with the set_egress_map option of the vconfig utility
+ to convert this to set vlan-qos field of the packet.
+
+ WMM is not known to be available.
+
+ \subsection windows Windows and Windows Mobile
+
+ (It's a mess!)
+
+ DSCP is settable with setsockopt() on Windows 2000 or older, but Windows
+ would silently ignore this call on WinXP or later, unless administrator
+ modifies the registry. On Windows 2000, Windows XP, and Windows Server
+ 2003, GQoS (Generic QoS) API is the standard API, but this API may not be
+ supported in the future. On Vista and Windows 7, the is a new QoS2 API,
+ also known as Quality Windows Audio-Video Experience (qWAVE).
+
+ IEEE 802.1p tagging is available via Traffic Control (TC) API, available
+ on Windows XP SP2, but this needs administrator access. For Vista and
+ later, it's in qWAVE.
+
+ WMM is available for mobile platforms on Windows Mobile 6 platform and
+ Windows Embedded CE 6, via setsockopt(IP_DSCP_TRAFFIC_TYPE). qWAVE
+ supports this as well.
+
+ \subsection symbian Symbian S60 3rd Ed
+
+ Both DSCP and WMM is supported via RSocket::SetOpt() with will set both
+ Layer 2 and Layer 3 QoS settings accordingly. Internally, PJLIB sets the
+ DSCP field of the socket, and based on certain DSCP values mapping,
+ Symbian will set the WMM tag accordingly.
+
+ \section api PJLIB's QoS API Abstraction
+
+ Based on the above, the following API is implemented.
+
+ Declare the following "standard" traffic types.
+
+ \code
+ typedef enum pj_qos_type
+ {
+ PJ_QOS_TYPE_BEST_EFFORT,
+ PJ_QOS_TYPE_BACKGROUND,
+ PJ_QOS_TYPE_VIDEO,
+ PJ_QOS_TYPE_VOICE,
+ PJ_QOS_TYPE_CONTROL
+ } pj_qos_type;
+ \endcode
+
+ The traffic classes above will determine how the Layer 2 and 3 QoS
+ settings will be used. The standard mapping between the classes above
+ to the corresponding Layer 2 and 3 settings are as follows:
+
+ \code
+ =================================================================
+ PJLIB Traffic Type IP DSCP WMM 802.1p
+ -----------------------------------------------------------------
+ BEST_EFFORT 0x00 BE (Bulk Effort) 0
+ BACKGROUND 0x08 BK (Bulk) 2
+ VIDEO 0x28 VI (Video) 5
+ VOICE 0x30 VO (Voice) 6
+ CONTROL 0x38 VO (Voice) 7
+ =================================================================
+ \endcode
+
+ There are two sets of API provided to manipulate the QoS parameters.
+
+ \subsection portable_api Portable API
+
+ The first set of API is:
+
+ \code
+ // Set QoS parameters
+ PJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
+ pj_qos_type val);
+
+ // Get QoS parameters
+ PJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
+ pj_qos_type *p_val);
+ \endcode
+
+ The API will set the traffic type according to the DSCP class, for both
+ Layer 2 and Layer 3 QoS settings, where it's available. If any of the
+ layer QoS setting is not settable, the API will silently ignore it.
+ If both layers are not setable, the API will return error.
+
+ The API above is the recommended use of QoS, since it is the most
+ portable across all platforms.
+
+ \subsection detail_api Fine Grained Control API
+
+ The second set of API is intended for application that wants to fine
+ tune the QoS parameters.
+
+ The Layer 2 and 3 QoS parameters are stored in pj_qos_params structure:
+
+ \code
+ typedef enum pj_qos_flag
+ {
+ PJ_QOS_PARAM_HAS_DSCP = 1,
+ PJ_QOS_PARAM_HAS_SO_PRIO = 2,
+ PJ_QOS_PARAM_HAS_WMM = 4
+ } pj_qos_flag;
+
+ typedef enum pj_qos_wmm_prio
+ {
+ PJ_QOS_WMM_PRIO_BULK_EFFORT,
+ PJ_QOS_WMM_PRIO_BULK,
+ PJ_QOS_WMM_PRIO_VIDEO,
+ PJ_QOS_WMM_PRIO_VOICE
+ } pj_qos_wmm_prio;
+
+ typedef struct pj_qos_params
+ {
+ pj_uint8_t flags; // Determines which values to
+ // set, bitmask of pj_qos_flag
+ pj_uint8_t dscp_val; // The 6 bits DSCP value to set
+ pj_uint8_t so_prio; // SO_PRIORITY value
+ pj_qos_wmm_prio wmm_prio; // WMM priority value
+ } pj_qos_params;
+ \endcode
+
+ The second set of API with more fine-grained control over the parameters
+ are:
+
+ \code
+ // Retrieve QoS params for the specified traffic type
+ PJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type,
+ pj_qos_params *p);
+
+ // Set QoS parameters to the socket
+ PJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
+ const pj_qos_params *p);
+
+ // Get QoS parameters from the socket
+ PJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
+ pj_qos_params *p);
+ \endcode
+
+
+ Important:
+
+ The pj_sock_set/get_qos_params() APIs are not portable, and it's probably
+ only going to be implemented on Linux. Application should always try to
+ use pj_sock_set_qos_type() instead.
+ */
+
+
+/**
+ * High level traffic classification.
+ */
+typedef enum pj_qos_type
+{
+ PJ_QOS_TYPE_BEST_EFFORT, /**< Best effort traffic (default value).
+ Any QoS function calls with specifying
+ this value are effectively no-op */
+ PJ_QOS_TYPE_BACKGROUND, /**< Background traffic. */
+ PJ_QOS_TYPE_VIDEO, /**< Video traffic. */
+ PJ_QOS_TYPE_VOICE, /**< Voice traffic. */
+ PJ_QOS_TYPE_CONTROL /**< Control traffic. */
+} pj_qos_type;
+
+/**
+ * Bitmask flag to indicate which QoS layer setting is set in the
+ * \a flags field of the #pj_qos_params structure.
+ */
+typedef enum pj_qos_flag
+{
+ PJ_QOS_PARAM_HAS_DSCP = 1, /**< DSCP field is set. */
+ PJ_QOS_PARAM_HAS_SO_PRIO = 2, /**< Socket SO_PRIORITY */
+ PJ_QOS_PARAM_HAS_WMM = 4 /**< WMM field is set. */
+} pj_qos_flag;
+
+
+/**
+ * Standard WMM priorities.
+ */
+typedef enum pj_qos_wmm_prio
+{
+ PJ_QOS_WMM_PRIO_BULK_EFFORT, /**< Bulk effort priority */
+ PJ_QOS_WMM_PRIO_BULK, /**< Bulk priority. */
+ PJ_QOS_WMM_PRIO_VIDEO, /**< Video priority */
+ PJ_QOS_WMM_PRIO_VOICE /**< Voice priority */
+} pj_qos_wmm_prio;
+
+
+/**
+ * QoS parameters to be set or retrieved to/from the socket.
+ */
+typedef struct pj_qos_params
+{
+ pj_uint8_t flags; /**< Determines which values to
+ set, bitmask of pj_qos_flag */
+ pj_uint8_t dscp_val; /**< The 6 bits DSCP value to set */
+ pj_uint8_t so_prio; /**< SO_PRIORITY value */
+ pj_qos_wmm_prio wmm_prio; /**< WMM priority value */
+} pj_qos_params;
+
+
+
+/**
+ * This is the high level and portable API to enable QoS on the specified
+ * socket, by setting the traffic type to the specified parameter.
+ *
+ * @param sock The socket.
+ * @param type Traffic type to be set.
+ *
+ * @return PJ_SUCCESS if at least Layer 2 or Layer 3 setting is
+ * successfully set. If both Layer 2 and Layer 3 settings
+ * can't be set, this function will return error.
+ */
+PJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
+ pj_qos_type type);
+
+/**
+ * This is the high level and portable API to get the traffic type that has
+ * been set on the socket. On occasions where the Layer 2 or Layer 3 settings
+ * were modified by using low level API, this function may return approximation
+ * of the closest QoS type that matches the settings.
+ *
+ * @param sock The socket.
+ * @param p_type Pointer to receive the traffic type of the socket.
+ *
+ * @return PJ_SUCCESS if traffic type for the socket can be obtained
+ * or approximated..
+ */
+PJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
+ pj_qos_type *p_type);
+
+
+/**
+ * This is a convenience function to apply QoS to the socket, and print error
+ * logging if the operations failed. Both QoS traffic type and the low level
+ * QoS parameters can be applied with this function.
+ *
+ * @param sock The socket handle.
+ * @param qos_type QoS traffic type. The QoS traffic type will be applied
+ * only if the value is not PJ_QOS_TYPE_BEST_EFFORT,
+ * @param qos_params Optional low-level QoS parameters. This will be
+ * applied only if this argument is not NULL and the
+ * flags inside the structure is non-zero. Upon return,
+ * the flags will indicate which parameters have been
+ * applied successfully.
+ * @param log_level This function will print to log at this level upon
+ * encountering errors.
+ * @param log_sender Optional sender name in the log.
+ * @param sock_name Optional name to help identify the socket in the log.
+ *
+ * @return PJ_SUCCESS if at least Layer 2 or Layer 3 setting is
+ * successfully set. If both Layer 2 and Layer 3 settings
+ * can't be set, this function will return error.
+ *
+ * @see pj_sock_apply_qos2()
+ */
+PJ_DECL(pj_status_t) pj_sock_apply_qos(pj_sock_t sock,
+ pj_qos_type qos_type,
+ pj_qos_params *qos_params,
+ unsigned log_level,
+ const char *log_sender,
+ const char *sock_name);
+
+/**
+ * Variant of #pj_sock_apply_qos() where the \a qos_params parameter is
+ * const.
+ *
+ * @see pj_sock_apply_qos()
+ */
+PJ_DECL(pj_status_t) pj_sock_apply_qos2(pj_sock_t sock,
+ pj_qos_type qos_type,
+ const pj_qos_params *qos_params,
+ unsigned log_level,
+ const char *log_sender,
+ const char *sock_name);
+
+/**
+ * Retrieve the standard mapping of QoS params for the specified traffic
+ * type.
+ *
+ * @param type The traffic type from which the QoS parameters
+ * are to be retrieved.
+ * @param p_param Pointer to receive the QoS parameters.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type,
+ pj_qos_params *p_param);
+
+
+/**
+ * Retrieve the traffic type that matches the specified QoS parameters.
+ * If no exact matching is found, this function will return an
+ * approximation of the closest matching traffic type for the specified
+ * QoS parameters.
+ *
+ * @param param Structure containing QoS parameters to map into
+ * "standard" traffic types.
+ * @param p_type Pointer to receive the traffic type.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_qos_get_type(const pj_qos_params *param,
+ pj_qos_type *p_type);
+
+
+/**
+ * This is a low level API to set QoS parameters to the socket.
+ *
+ * @param sock The socket.
+ * @param param Structure containing QoS parameters to be applied
+ * to the socket. Upon return, the \a flags field
+ * of this structure will be set with bitmask value
+ * indicating which QoS settings have successfully
+ * been applied to the socket.
+ *
+ * @return PJ_SUCCESS if at least one field setting has been
+ * successfully set. If no setting can't be set,
+ * this function will return error.
+ */
+PJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
+ pj_qos_params *param);
+
+/**
+ * This is a low level API to get QoS parameters from the socket.
+ *
+ * @param sock The socket.
+ * @param p_param Pointer to receive the parameters. Upon returning
+ * successfully, the \a flags field of this structure
+ * will be initialized with the appropriate bitmask
+ * to indicate which fields have been successfully
+ * retrieved.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
+ pj_qos_params *p_param);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJ_SOCK_QOS_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_select.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_select.h
new file mode 100644
index 0000000..1dfa9d8
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_select.h
@@ -0,0 +1,152 @@
+/* $Id: sock_select.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_SELECT_H__
+#define __PJ_SELECT_H__
+
+/**
+ * @file sock_select.h
+ * @brief Socket select().
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_SOCK_SELECT Socket select() API.
+ * @ingroup PJ_IO
+ * @{
+ * This module provides portable abstraction for \a select() like API.
+ * The abstraction is needed so that it can utilize various event
+ * dispatching mechanisms that are available across platforms.
+ *
+ * The API is very similar to normal \a select() usage.
+ *
+ * \section pj_sock_select_examples_sec Examples
+ *
+ * For some examples on how to use the select API, please see:
+ *
+ * - \ref page_pjlib_select_test
+ */
+
+/**
+ * Portable structure declarations for pj_fd_set.
+ * The implementation of pj_sock_select() does not use this structure
+ * per-se, but instead it will use the native fd_set structure. However,
+ * we must make sure that the size of pj_fd_set_t can accomodate the
+ * native fd_set structure.
+ */
+typedef struct pj_fd_set_t
+{
+ pj_sock_t data[PJ_IOQUEUE_MAX_HANDLES+ 4]; /**< Opaque buffer for fd_set */
+} pj_fd_set_t;
+
+
+/**
+ * Initialize the descriptor set pointed to by fdsetp to the null set.
+ *
+ * @param fdsetp The descriptor set.
+ */
+PJ_DECL(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp);
+
+
+/**
+ * This is an internal function, application shouldn't use this.
+ *
+ * Get the number of descriptors in the set. This is defined in sock_select.c
+ * This function will only return the number of sockets set from PJ_FD_SET
+ * operation. When the set is modified by other means (such as by select()),
+ * the count will not be reflected here.
+ *
+ * @param fdsetp The descriptor set.
+ *
+ * @return Number of descriptors in the set.
+ */
+PJ_DECL(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp);
+
+
+/**
+ * Add the file descriptor fd to the set pointed to by fdsetp.
+ * If the file descriptor fd is already in this set, there shall be no effect
+ * on the set, nor will an error be returned.
+ *
+ * @param fd The socket descriptor.
+ * @param fdsetp The descriptor set.
+ */
+PJ_DECL(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp);
+
+/**
+ * Remove the file descriptor fd from the set pointed to by fdsetp.
+ * If fd is not a member of this set, there shall be no effect on the set,
+ * nor will an error be returned.
+ *
+ * @param fd The socket descriptor.
+ * @param fdsetp The descriptor set.
+ */
+PJ_DECL(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp);
+
+
+/**
+ * Evaluate to non-zero if the file descriptor fd is a member of the set
+ * pointed to by fdsetp, and shall evaluate to zero otherwise.
+ *
+ * @param fd The socket descriptor.
+ * @param fdsetp The descriptor set.
+ *
+ * @return Nonzero if fd is member of the descriptor set.
+ */
+PJ_DECL(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp);
+
+
+/**
+ * This function wait for a number of file descriptors to change status.
+ * The behaviour is the same as select() function call which appear in
+ * standard BSD socket libraries.
+ *
+ * @param n On Unices, this specifies the highest-numbered
+ * descriptor in any of the three set, plus 1. On Windows,
+ * the value is ignored.
+ * @param readfds Optional pointer to a set of sockets to be checked for
+ * readability.
+ * @param writefds Optional pointer to a set of sockets to be checked for
+ * writability.
+ * @param exceptfds Optional pointer to a set of sockets to be checked for
+ * errors.
+ * @param timeout Maximum time for select to wait, or null for blocking
+ * operations.
+ *
+ * @return The total number of socket handles that are ready, or
+ * zero if the time limit expired, or -1 if an error occurred.
+ */
+PJ_DECL(int) pj_sock_select( int n,
+ pj_fd_set_t *readfds,
+ pj_fd_set_t *writefds,
+ pj_fd_set_t *exceptfds,
+ const pj_time_val *timeout);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJ_SELECT_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/ssl_sock.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/ssl_sock.h
new file mode 100644
index 0000000..1873598
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/ssl_sock.h
@@ -0,0 +1,874 @@
+/* $Id: ssl_sock.h 2998 2009-11-09 08:51:34Z bennylp $ */
+/*
+ * Copyright (C) 2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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_SSL_SOCK_H__
+#define __PJ_SSL_SOCK_H__
+
+/**
+ * @file ssl_sock.h
+ * @brief Secure socket
+ */
+
+#include <pj/ioqueue.h>
+#include <pj/sock.h>
+#include <pj/sock_qos.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_SSL_SOCK Secure socket I/O
+ * @brief Secure socket provides security on socket operation using standard
+ * security protocols such as SSL and TLS.
+ * @ingroup PJ_IO
+ * @{
+ *
+ * Secure socket wraps normal socket and applies security features, i.e:
+ * privacy and data integrity, on the socket traffic, using standard security
+ * protocols such as SSL and TLS.
+ *
+ * Secure socket employs active socket operations, which is similar to (and
+ * described more detail) in \ref PJ_ACTIVESOCK.
+ */
+
+
+ /**
+ * This opaque structure describes the secure socket.
+ */
+typedef struct pj_ssl_sock_t pj_ssl_sock_t;
+
+
+/**
+ * Opaque declaration of endpoint certificate or credentials. This may contains
+ * certificate, private key, and trusted Certificate Authorities list.
+ */
+typedef struct pj_ssl_cert_t pj_ssl_cert_t;
+
+
+/**
+ * Describe structure of certificate info.
+ */
+typedef struct pj_ssl_cert_info {
+ pj_str_t subject; /**< Subject. */
+ pj_str_t issuer; /**< Issuer. */
+ unsigned version; /**< Certificate version. */
+ pj_time_val validity_start; /**< Validity start. */
+ pj_time_val validity_end; /**< Validity end. */
+ pj_bool_t validity_use_gmt; /**< Flag if validity date/time
+ use GMT. */
+} pj_ssl_cert_info;
+
+
+/**
+ * Create credential from files.
+ *
+ * @param CA_file The file of trusted CA list.
+ * @param cert_file The file of certificate.
+ * @param privkey_file The file of private key.
+ * @param privkey_pass The password of private key, if any.
+ * @param p_cert Pointer to credential instance to be created.
+ *
+ * @return PJ_SUCCESS when successful.
+ */
+PJ_DECL(pj_status_t) pj_ssl_cert_load_from_files(pj_pool_t *pool,
+ const pj_str_t *CA_file,
+ const pj_str_t *cert_file,
+ const pj_str_t *privkey_file,
+ const pj_str_t *privkey_pass,
+ pj_ssl_cert_t **p_cert);
+
+
+/**
+ * Cipher suites enumeration.
+ */
+typedef enum pj_ssl_cipher {
+
+ /* NULL */
+ TLS_NULL_WITH_NULL_NULL = 0x00000000,
+
+ /* TLS/SSLv3 */
+ TLS_RSA_WITH_NULL_MD5 = 0x00000001,
+ TLS_RSA_WITH_NULL_SHA = 0x00000002,
+ TLS_RSA_WITH_NULL_SHA256 = 0x0000003B,
+ TLS_RSA_WITH_RC4_128_MD5 = 0x00000004,
+ TLS_RSA_WITH_RC4_128_SHA = 0x00000005,
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x0000000A,
+ TLS_RSA_WITH_AES_128_CBC_SHA = 0x0000002F,
+ TLS_RSA_WITH_AES_256_CBC_SHA = 0x00000035,
+ TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x0000003C,
+ TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x0000003D,
+ TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x0000000D,
+ TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x00000010,
+ TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x00000013,
+ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x00000016,
+ TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x00000030,
+ TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x00000031,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x00000032,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x00000033,
+ TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x00000036,
+ TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x00000037,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x00000038,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x00000039,
+ TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x0000003E,
+ TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x0000003F,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x00000040,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x00000067,
+ TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x00000068,
+ TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x00000069,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x0000006A,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x0000006B,
+ TLS_DH_anon_WITH_RC4_128_MD5 = 0x00000018,
+ TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x0000001B,
+ TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x00000034,
+ TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x0000003A,
+ TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x0000006C,
+ TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x0000006D,
+
+ /* TLS (deprecated) */
+ TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x00000003,
+ TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x00000006,
+ TLS_RSA_WITH_IDEA_CBC_SHA = 0x00000007,
+ TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x00000008,
+ TLS_RSA_WITH_DES_CBC_SHA = 0x00000009,
+ TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0000000B,
+ TLS_DH_DSS_WITH_DES_CBC_SHA = 0x0000000C,
+ TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0000000E,
+ TLS_DH_RSA_WITH_DES_CBC_SHA = 0x0000000F,
+ TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x00000011,
+ TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x00000012,
+ TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x00000014,
+ TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x00000015,
+ TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x00000017,
+ TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x00000019,
+ TLS_DH_anon_WITH_DES_CBC_SHA = 0x0000001A,
+
+ /* SSLv3 */
+ SSL_FORTEZZA_KEA_WITH_NULL_SHA = 0x0000001C,
+ SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA= 0x0000001D,
+ SSL_FORTEZZA_KEA_WITH_RC4_128_SHA = 0x0000001E,
+
+ /* SSLv2 */
+ SSL_CK_RC4_128_WITH_MD5 = 0x00010080,
+ SSL_CK_RC4_128_EXPORT40_WITH_MD5 = 0x00020080,
+ SSL_CK_RC2_128_CBC_WITH_MD5 = 0x00030080,
+ SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 = 0x00040080,
+ SSL_CK_IDEA_128_CBC_WITH_MD5 = 0x00050080,
+ SSL_CK_DES_64_CBC_WITH_MD5 = 0x00060040,
+ SSL_CK_DES_192_EDE3_CBC_WITH_MD5 = 0x000700C0
+
+} pj_ssl_cipher;
+
+
+/**
+ * Get cipher list supported by SSL/TLS backend.
+ *
+ * @param ciphers The ciphers buffer to receive cipher list.
+ * @param cipher_num Maximum number of ciphers to be received.
+ *
+ * @return PJ_SUCCESS when successful.
+ */
+PJ_DECL(pj_status_t) pj_ssl_cipher_get_availables(pj_ssl_cipher ciphers[],
+ unsigned *cipher_num);
+
+
+/**
+ * Get cipher name string.
+ *
+ * @param cipher The cipher.
+ *
+ * @return The cipher name or NULL if cipher is not recognized.
+ */
+PJ_DECL(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher);
+
+
+/**
+ * This structure contains the callbacks to be called by the secure socket.
+ */
+typedef struct pj_ssl_sock_cb
+{
+ /**
+ * This callback is called when a data arrives as the result of
+ * pj_ssl_sock_start_read().
+ *
+ * @param ssock The secure socket.
+ * @param data The buffer containing the new data, if any. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument may be NULL.
+ * @param size The length of data in the buffer.
+ * @param status The status of the read operation. This may contain
+ * non-PJ_SUCCESS for example when the TCP connection
+ * has been closed. In this case, the buffer may
+ * contain left over data from previous callback which
+ * the application may want to process.
+ * @param remainder If application wishes to leave some data in the
+ * buffer (common for TCP applications), it should
+ * move the remainder data to the front part of the
+ * buffer and set the remainder length here. The value
+ * of this parameter will be ignored for datagram
+ * sockets.
+ *
+ * @return PJ_TRUE if further read is desired, and PJ_FALSE
+ * when application no longer wants to receive data.
+ * Application may destroy the secure socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_data_read)(pj_ssl_sock_t *ssock,
+ void *data,
+ pj_size_t size,
+ pj_status_t status,
+ pj_size_t *remainder);
+ /**
+ * This callback is called when a packet arrives as the result of
+ * pj_ssl_sock_start_recvfrom().
+ *
+ * @param ssock The secure socket.
+ * @param data The buffer containing the packet, if any. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument will be set to NULL.
+ * @param size The length of packet in the buffer. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument will be set to zero.
+ * @param src_addr Source address of the packet.
+ * @param addr_len Length of the source address.
+ * @param status This contains
+ *
+ * @return PJ_TRUE if further read is desired, and PJ_FALSE
+ * when application no longer wants to receive data.
+ * Application may destroy the secure socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_data_recvfrom)(pj_ssl_sock_t *ssock,
+ void *data,
+ pj_size_t size,
+ const pj_sockaddr_t *src_addr,
+ int addr_len,
+ pj_status_t status);
+
+ /**
+ * This callback is called when data has been sent.
+ *
+ * @param ssock The secure socket.
+ * @param send_key Key associated with the send operation.
+ * @param sent If value is positive non-zero it indicates the
+ * number of data sent. When the value is negative,
+ * it contains the error code which can be retrieved
+ * by negating the value (i.e. status=-sent).
+ *
+ * @return Application may destroy the secure socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_data_sent)(pj_ssl_sock_t *ssock,
+ pj_ioqueue_op_key_t *send_key,
+ pj_ssize_t sent);
+
+ /**
+ * This callback is called when new connection arrives as the result
+ * of pj_ssl_sock_start_accept().
+ *
+ * @param ssock The secure socket.
+ * @param newsock The new incoming secure socket.
+ * @param src_addr The source address of the connection.
+ * @param addr_len Length of the source address.
+ *
+ * @return PJ_TRUE if further accept() is desired, and PJ_FALSE
+ * when application no longer wants to accept incoming
+ * connection. Application may destroy the secure socket
+ * in the callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_accept_complete)(pj_ssl_sock_t *ssock,
+ pj_ssl_sock_t *newsock,
+ const pj_sockaddr_t *src_addr,
+ int src_addr_len);
+
+ /**
+ * This callback is called when pending connect operation has been
+ * completed.
+ *
+ * @param ssock The secure socket.
+ * @param status The connection result. If connection has been
+ * successfully established, the status will contain
+ * PJ_SUCCESS.
+ *
+ * @return Application may destroy the secure socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_connect_complete)(pj_ssl_sock_t *ssock,
+ pj_status_t status);
+
+} pj_ssl_sock_cb;
+
+
+/**
+ * Enumeration of secure socket protocol types.
+ */
+typedef enum pj_ssl_sock_proto
+{
+ PJ_SSL_SOCK_PROTO_DEFAULT, /**< Default protocol of backend. */
+ PJ_SSL_SOCK_PROTO_TLS1, /**< TLSv1.0 protocol. */
+ PJ_SSL_SOCK_PROTO_SSL3, /**< SSLv3.0 protocol. */
+ PJ_SSL_SOCK_PROTO_SSL23, /**< SSLv3.0 but can roll back to
+ SSLv2.0. */
+ PJ_SSL_SOCK_PROTO_SSL2, /**< SSLv2.0 protocol. */
+ PJ_SSL_SOCK_PROTO_DTLS1 /**< DTLSv1.0 protocol. */
+} pj_ssl_sock_proto;
+
+
+/**
+ * Definition of secure socket info structure.
+ */
+typedef struct pj_ssl_sock_info
+{
+ /**
+ * Describes whether secure socket connection is established, i.e: TLS/SSL
+ * handshaking has been done successfully.
+ */
+ pj_bool_t established;
+
+ /**
+ * Describes secure socket protocol being used.
+ */
+ pj_ssl_sock_proto proto;
+
+ /**
+ * Describes cipher suite being used, this will only be set when connection
+ * is established.
+ */
+ pj_ssl_cipher cipher;
+
+ /**
+ * Describes local address.
+ */
+ pj_sockaddr local_addr;
+
+ /**
+ * Describes remote address.
+ */
+ pj_sockaddr remote_addr;
+
+ /**
+ * Describes active local certificate info.
+ */
+ pj_ssl_cert_info local_cert_info;
+
+ /**
+ * Describes active remote certificate info.
+ */
+ pj_ssl_cert_info remote_cert_info;
+
+} pj_ssl_sock_info;
+
+
+/**
+ * Definition of secure socket creation parameters.
+ */
+typedef struct pj_ssl_sock_param
+{
+ /**
+ * Specifies socket address family, either pj_AF_INET() and pj_AF_INET6().
+ *
+ * Default is pj_AF_INET().
+ */
+ int sock_af;
+
+ /**
+ * Specify socket type, either pj_SOCK_DGRAM() or pj_SOCK_STREAM().
+ *
+ * Default is pj_SOCK_STREAM().
+ */
+ int sock_type;
+
+ /**
+ * Specify the ioqueue to use. Secure socket uses the ioqueue to perform
+ * active socket operations, see \ref PJ_ACTIVESOCK for more detail.
+ */
+ pj_ioqueue_t *ioqueue;
+
+ /**
+ * Specify the timer heap to use. Secure socket uses the timer to provide
+ * auto cancelation on asynchronous operation when it takes longer time
+ * than specified timeout period, e.g: security negotiation timeout.
+ */
+ pj_timer_heap_t *timer_heap;
+
+ /**
+ * Specify secure socket callbacks, see #pj_ssl_sock_cb.
+ */
+ pj_ssl_sock_cb cb;
+
+ /**
+ * Specify secure socket user data.
+ */
+ void *user_data;
+
+ /**
+ * Specify security protocol to use, see #pj_ssl_sock_proto.
+ *
+ * Default is PJ_SSL_SOCK_PROTO_DEFAULT.
+ */
+ pj_ssl_sock_proto proto;
+
+ /**
+ * Number of concurrent asynchronous operations that is to be supported
+ * by the secure socket. This value only affects socket receive and
+ * accept operations -- the secure socket will issue one or more
+ * asynchronous read and accept operations based on the value of this
+ * field. Setting this field to more than one will allow more than one
+ * incoming data or incoming connections to be processed simultaneously
+ * on multiprocessor systems, when the ioqueue is polled by more than
+ * one threads.
+ *
+ * The default value is 1.
+ */
+ unsigned async_cnt;
+
+ /**
+ * The ioqueue concurrency to be forced on the socket when it is
+ * registered to the ioqueue. See #pj_ioqueue_set_concurrency() for more
+ * info about ioqueue concurrency.
+ *
+ * When this value is -1, the concurrency setting will not be forced for
+ * this socket, and the socket will inherit the concurrency setting of
+ * the ioqueue. When this value is zero, the secure socket will disable
+ * concurrency for the socket. When this value is +1, the secure socket
+ * will enable concurrency for the socket.
+ *
+ * The default value is -1.
+ */
+ int concurrency;
+
+ /**
+ * If this option is specified, the secure socket will make sure that
+ * asynchronous send operation with stream oriented socket will only
+ * call the callback after all data has been sent. This means that the
+ * secure socket will automatically resend the remaining data until
+ * all data has been sent.
+ *
+ * Please note that when this option is specified, it is possible that
+ * error is reported after partial data has been sent. Also setting
+ * this will disable the ioqueue concurrency for the socket.
+ *
+ * Default value is 1.
+ */
+ pj_bool_t whole_data;
+
+ /**
+ * Specify buffer size for sending operation. Buffering sending data
+ * is used for allowing application to perform multiple outstanding
+ * send operations. Whenever application specifies this setting too
+ * small, sending operation may return PJ_ENOMEM.
+ *
+ * Default value is 8192 bytes.
+ */
+ pj_size_t send_buffer_size;
+
+ /**
+ * Specify buffer size for receiving encrypted (and perhaps compressed)
+ * data on underlying socket. This setting is unused on Symbian, since
+ * SSL/TLS Symbian backend, CSecureSocket, can use application buffer
+ * directly.
+ *
+ * Default value is 1500.
+ */
+ pj_size_t read_buffer_size;
+
+ /**
+ * Number of ciphers contained in the specified cipher preference.
+ * If this is set to zero, then default cipher list of the backend
+ * will be used.
+ */
+ unsigned ciphers_num;
+
+ /**
+ * Ciphers and order preference. If empty, then default cipher list and
+ * its default order of the backend will be used.
+ */
+ pj_ssl_cipher *ciphers;
+
+ /**
+ * Security negotiation timeout. If this is set to zero (both sec and
+ * msec), the negotiation doesn't have a timeout.
+ *
+ * Default value is zero.
+ */
+ pj_time_val timeout;
+
+ /**
+ * Specify whether endpoint should verify peer certificate.
+ *
+ * Default value is PJ_FALSE.
+ */
+ pj_bool_t verify_peer;
+
+ /**
+ * When secure socket is acting as server (handles incoming connection),
+ * it will require the client to provide certificate.
+ *
+ * Default value is PJ_FALSE.
+ */
+ pj_bool_t require_client_cert;
+
+ /**
+ * When secure socket is acting as client (perform outgoing connection)
+ * and it needs to verify server name (e.g: host or domain name) by
+ * matching it to the name specified in the server certificate. This
+ * setting is useful when the server is hosting multiple domains for
+ * the same listening socket.
+ *
+ * Default value is zero/not-set.
+ */
+ pj_str_t server_name;
+
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * By default all settings in this structure are disabled.
+ */
+ pj_qos_params qos_params;
+
+ /**
+ * Specify if the transport should ignore any errors when setting the QoS
+ * traffic type/parameters.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t qos_ignore_error;
+
+
+} pj_ssl_sock_param;
+
+
+/**
+ * Initialize the secure socket parameters for its creation with
+ * the default values.
+ *
+ * @param param The parameter to be initialized.
+ */
+PJ_DECL(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param);
+
+
+/**
+ * Create secure socket instance.
+ *
+ * @param pool The pool for allocating secure socket instance.
+ * @param param The secure socket parameter, see #pj_ssl_sock_param.
+ * @param p_ssock Pointer to secure socket instance to be created.
+ *
+ * @return PJ_SUCCESS when successful.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_create(pj_pool_t *pool,
+ const pj_ssl_sock_param *param,
+ pj_ssl_sock_t **p_ssock);
+
+
+/**
+ * Set secure socket certificate or credentials. Credentials may include
+ * certificate, private key and trusted Certification Authorities list.
+ * Normally, server socket must provide certificate (and private key).
+ * Socket client may also need to provide certificate in case requested
+ * by the server.
+ *
+ * @param ssock The secure socket instance.
+ * @param pool The pool.
+ * @param cert The endpoint certificate/credentials, see
+ * #pj_ssl_cert_t.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_set_certificate(
+ pj_ssl_sock_t *ssock,
+ pj_pool_t *pool,
+ const pj_ssl_cert_t *cert);
+
+
+/**
+ * Close and destroy the secure socket.
+ *
+ * @param ssock The secure socket.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock);
+
+
+/**
+ * Associate arbitrary data with the secure socket. Application may
+ * inspect this data in the callbacks and associate it with higher
+ * level processing.
+ *
+ * @param ssock The secure socket.
+ * @param user_data The user data to be associated with the secure
+ * socket.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_set_user_data(pj_ssl_sock_t *ssock,
+ void *user_data);
+
+/**
+ * Retrieve the user data previously associated with this secure
+ * socket.
+ *
+ * @param ssock The secure socket.
+ *
+ * @return The user data.
+ */
+PJ_DECL(void*) pj_ssl_sock_get_user_data(pj_ssl_sock_t *ssock);
+
+
+/**
+ * Retrieve the local address and port used by specified secure socket.
+ *
+ * @param ssock The secure socket.
+ * @param info The info buffer to be set, see #pj_ssl_sock_info.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_get_info(pj_ssl_sock_t *ssock,
+ pj_ssl_sock_info *info);
+
+
+/**
+ * Starts read operation on this secure socket. This function will create
+ * \a async_cnt number of buffers (the \a async_cnt parameter was given
+ * in \a pj_ssl_sock_create() function) where each buffer is \a buff_size
+ * long. The buffers are allocated from the specified \a pool. Once the
+ * buffers are created, it then issues \a async_cnt number of asynchronous
+ * \a recv() operations to the socket and returns back to caller. Incoming
+ * data on the socket will be reported back to application via the
+ * \a on_data_read() callback.
+ *
+ * Application only needs to call this function once to initiate read
+ * operations. Further read operations will be done automatically by the
+ * secure socket when \a on_data_read() callback returns non-zero.
+ *
+ * @param ssock The secure socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param flags Flags to be given to pj_ioqueue_recv().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_start_read(pj_ssl_sock_t *ssock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ pj_uint32_t flags);
+
+/**
+ * Same as #pj_ssl_sock_start_read(), except that the application
+ * supplies the buffers for the read operation so that the acive socket
+ * does not have to allocate the buffers.
+ *
+ * @param ssock The secure socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param readbuf Array of packet buffers, each has buff_size size.
+ * @param flags Flags to be given to pj_ioqueue_recv().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_start_read2(pj_ssl_sock_t *ssock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ void *readbuf[],
+ pj_uint32_t flags);
+
+/**
+ * Same as pj_ssl_sock_start_read(), except that this function is used
+ * only for datagram sockets, and it will trigger \a on_data_recvfrom()
+ * callback instead.
+ *
+ * @param ssock The secure socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param flags Flags to be given to pj_ioqueue_recvfrom().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_start_recvfrom(pj_ssl_sock_t *ssock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ pj_uint32_t flags);
+
+/**
+ * Same as #pj_ssl_sock_start_recvfrom() except that the recvfrom()
+ * operation takes the buffer from the argument rather than creating
+ * new ones.
+ *
+ * @param ssock The secure socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param readbuf Array of packet buffers, each has buff_size size.
+ * @param flags Flags to be given to pj_ioqueue_recvfrom().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_start_recvfrom2(pj_ssl_sock_t *ssock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ void *readbuf[],
+ pj_uint32_t flags);
+
+/**
+ * Send data using the socket.
+ *
+ * @param ssock The secure socket.
+ * @param send_key The operation key to send the data, which is useful
+ * if application wants to submit multiple pending
+ * send operations and want to track which exact data
+ * has been sent in the \a on_data_sent() callback.
+ * @param data The data to be sent. This data must remain valid
+ * until the data has been sent.
+ * @param size The size of the data.
+ * @param flags Flags to be given to pj_ioqueue_send().
+ *
+ * @return PJ_SUCCESS if data has been sent immediately, or
+ * PJ_EPENDING if data cannot be sent immediately or
+ * PJ_ENOMEM when sending buffer could not handle all
+ * queued data, see \a send_buffer_size. The callback
+ * \a on_data_sent() will be called when data is actually
+ * sent. Any other return value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_send(pj_ssl_sock_t *ssock,
+ pj_ioqueue_op_key_t *send_key,
+ const void *data,
+ pj_ssize_t *size,
+ unsigned flags);
+
+/**
+ * Send datagram using the socket.
+ *
+ * @param ssock The secure socket.
+ * @param send_key The operation key to send the data, which is useful
+ * if application wants to submit multiple pending
+ * send operations and want to track which exact data
+ * has been sent in the \a on_data_sent() callback.
+ * @param data The data to be sent. This data must remain valid
+ * until the data has been sent.
+ * @param size The size of the data.
+ * @param flags Flags to be given to pj_ioqueue_send().
+ * @param addr The destination address.
+ * @param addr_len Length of buffer containing destination address.
+ *
+ * @return PJ_SUCCESS if data has been sent immediately, or
+ * PJ_EPENDING if data cannot be sent immediately. In
+ * this case the \a on_data_sent() callback will be
+ * called when data is actually sent. Any other return
+ * value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_sendto(pj_ssl_sock_t *ssock,
+ pj_ioqueue_op_key_t *send_key,
+ const void *data,
+ pj_ssize_t *size,
+ unsigned flags,
+ const pj_sockaddr_t *addr,
+ int addr_len);
+
+
+/**
+ * Starts asynchronous socket accept() operations on this secure socket.
+ * This function will issue \a async_cnt number of asynchronous \a accept()
+ * operations to the socket and returns back to caller. Incoming
+ * connection on the socket will be reported back to application via the
+ * \a on_accept_complete() callback.
+ *
+ * Application only needs to call this function once to initiate accept()
+ * operations. Further accept() operations will be done automatically by
+ * the secure socket when \a on_accept_complete() callback returns non-zero.
+ *
+ * @param ssock The secure socket.
+ * @param pool Pool used to allocate some internal data for the
+ * operation.
+ * @param localaddr Local address to bind on.
+ * @param addr_len Length of buffer containing local address.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_start_accept(pj_ssl_sock_t *ssock,
+ pj_pool_t *pool,
+ const pj_sockaddr_t *local_addr,
+ int addr_len);
+
+
+/**
+ * Starts asynchronous socket connect() operation and SSL/TLS handshaking
+ * for this socket. Once the connection is done (either successfully or not),
+ * the \a on_connect_complete() callback will be called.
+ *
+ * @param ssock The secure socket.
+ * @param pool The pool to allocate some internal data for the
+ * operation.
+ * @param localaddr Local address.
+ * @param remaddr Remote address.
+ * @param addr_len Length of buffer containing above addresses.
+ *
+ * @return PJ_SUCCESS if connection can be established immediately
+ * or PJ_EPENDING if connection cannot be established
+ * immediately. In this case the \a on_connect_complete()
+ * callback will be called when connection is complete.
+ * Any other return value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_start_connect(pj_ssl_sock_t *ssock,
+ pj_pool_t *pool,
+ const pj_sockaddr_t *localaddr,
+ const pj_sockaddr_t *remaddr,
+ int addr_len);
+
+
+/**
+ * Starts SSL/TLS renegotiation over an already established SSL connection
+ * for this socket. This operation is performed transparently, no callback
+ * will be called once the renegotiation completed successfully. However,
+ * when the renegotiation fails, the connection will be closed and callback
+ * \a on_data_read() will be invoked with non-PJ_SUCCESS status code.
+ *
+ * @param ssock The secure socket.
+ *
+ * @return PJ_SUCCESS if renegotiation is completed immediately,
+ * or PJ_EPENDING if renegotiation has been started and
+ * waiting for completion, or the appropriate error code
+ * on failure.
+ */
+PJ_DECL(pj_status_t) pj_ssl_sock_renegotiate(pj_ssl_sock_t *ssock);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJ_SSL_SOCK_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/string.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/string.h
new file mode 100644
index 0000000..69c0c5c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/string.h
@@ -0,0 +1,692 @@
+/* $Id: string.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_STRING_H__
+#define __PJ_STRING_H__
+
+/**
+ * @file string.h
+ * @brief PJLIB String Operations.
+ */
+
+#include <pj/types.h>
+#include <pj/compat/string.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_PSTR String Operations
+ * @ingroup PJ_DS
+ * @{
+ * This module provides string manipulation API.
+ *
+ * \section pj_pstr_not_null_sec PJLIB String is NOT Null Terminated!
+ *
+ * That is the first information that developers need to know. Instead
+ * of using normal C string, strings in PJLIB are represented as
+ * pj_str_t structure below:
+ *
+ * <pre>
+ * typedef struct pj_str_t
+ * {
+ * char *ptr;
+ * pj_size_t slen;
+ * } pj_str_t;
+ * </pre>
+ *
+ * There are some advantages of using this approach:
+ * - the string can point to arbitrary location in memory even
+ * if the string in that location is not null terminated. This is
+ * most usefull for text parsing, where the parsed text can just
+ * point to the original text in the input. If we use C string,
+ * then we will have to copy the text portion from the input
+ * to a string variable.
+ * - because the length of the string is known, string copy operation
+ * can be made more efficient.
+ *
+ * Most of APIs in PJLIB that expect or return string will represent
+ * the string as pj_str_t instead of normal C string.
+ *
+ * \section pj_pstr_examples_sec Examples
+ *
+ * For some examples, please see:
+ * - @ref page_pjlib_string_test
+ */
+
+/**
+ * Create string initializer from a normal C string.
+ *
+ * @param str Null terminated string to be stored.
+ *
+ * @return pj_str_t.
+ */
+PJ_IDECL(pj_str_t) pj_str(char *str);
+
+/**
+ * Create constant string from normal C string.
+ *
+ * @param str The string to be initialized.
+ * @param s Null terminated string.
+ *
+ * @return pj_str_t.
+ */
+PJ_INLINE(const pj_str_t*) pj_cstr(pj_str_t *str, const char *s)
+{
+ str->ptr = (char*)s;
+ str->slen = s ? (pj_ssize_t)strlen(s) : 0;
+ return str;
+}
+
+/**
+ * Set the pointer and length to the specified value.
+ *
+ * @param str the string.
+ * @param ptr pointer to set.
+ * @param length length to set.
+ *
+ * @return the string.
+ */
+PJ_INLINE(pj_str_t*) pj_strset( pj_str_t *str, char *ptr, pj_size_t length)
+{
+ str->ptr = ptr;
+ str->slen = (pj_ssize_t)length;
+ return str;
+}
+
+/**
+ * Set the pointer and length of the string to the source string, which
+ * must be NULL terminated.
+ *
+ * @param str the string.
+ * @param src pointer to set.
+ *
+ * @return the string.
+ */
+PJ_INLINE(pj_str_t*) pj_strset2( pj_str_t *str, char *src)
+{
+ str->ptr = src;
+ str->slen = src ? (pj_ssize_t)strlen(src) : 0;
+ return str;
+}
+
+/**
+ * Set the pointer and the length of the string.
+ *
+ * @param str The target string.
+ * @param begin The start of the string.
+ * @param end The end of the string.
+ *
+ * @return the target string.
+ */
+PJ_INLINE(pj_str_t*) pj_strset3( pj_str_t *str, char *begin, char *end )
+{
+ str->ptr = begin;
+ str->slen = (pj_ssize_t)(end-begin);
+ return str;
+}
+
+/**
+ * Assign string.
+ *
+ * @param dst The target string.
+ * @param src The source string.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src );
+
+/**
+ * Copy string contents.
+ *
+ * @param dst The target string.
+ * @param src The source string.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src);
+
+/**
+ * Copy string contents.
+ *
+ * @param dst The target string.
+ * @param src The source string.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src);
+
+/**
+ * Copy source string to destination up to the specified max length.
+ *
+ * @param dst The target string.
+ * @param src The source string.
+ * @param max Maximum characters to copy.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strncpy(pj_str_t *dst, const pj_str_t *src,
+ pj_ssize_t max);
+
+/**
+ * Copy source string to destination up to the specified max length,
+ * and NULL terminate the destination. If source string length is
+ * greater than or equal to max, then max-1 will be copied.
+ *
+ * @param dst The target string.
+ * @param src The source string.
+ * @param max Maximum characters to copy.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strncpy_with_null(pj_str_t *dst, const pj_str_t *src,
+ pj_ssize_t max);
+
+/**
+ * Duplicate string.
+ *
+ * @param pool The pool.
+ * @param dst The string result.
+ * @param src The string to duplicate.
+ *
+ * @return the string result.
+ */
+PJ_IDECL(pj_str_t*) pj_strdup(pj_pool_t *pool,
+ pj_str_t *dst,
+ const pj_str_t *src);
+
+/**
+ * Duplicate string and NULL terminate the destination string.
+ *
+ * @param pool The pool.
+ * @param dst The string result.
+ * @param src The string to duplicate.
+ *
+ * @return The string result.
+ */
+PJ_IDECL(pj_str_t*) pj_strdup_with_null(pj_pool_t *pool,
+ pj_str_t *dst,
+ const pj_str_t *src);
+
+/**
+ * Duplicate string.
+ *
+ * @param pool The pool.
+ * @param dst The string result.
+ * @param src The string to duplicate.
+ *
+ * @return the string result.
+ */
+PJ_IDECL(pj_str_t*) pj_strdup2(pj_pool_t *pool,
+ pj_str_t *dst,
+ const char *src);
+
+/**
+ * Duplicate string and NULL terminate the destination string.
+ *
+ * @param pool The pool.
+ * @param dst The string result.
+ * @param src The string to duplicate.
+ *
+ * @return The string result.
+ */
+PJ_IDECL(pj_str_t*) pj_strdup2_with_null(pj_pool_t *pool,
+ pj_str_t *dst,
+ const char *src);
+
+
+/**
+ * Duplicate string.
+ *
+ * @param pool The pool.
+ * @param src The string to duplicate.
+ *
+ * @return the string result.
+ */
+PJ_IDECL(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src);
+
+/**
+ * Return the length of the string.
+ *
+ * @param str The string.
+ *
+ * @return the length of the string.
+ */
+PJ_INLINE(pj_size_t) pj_strlen( const pj_str_t *str )
+{
+ return str->slen;
+}
+
+/**
+ * Return the pointer to the string data.
+ *
+ * @param str The string.
+ *
+ * @return the pointer to the string buffer.
+ */
+PJ_INLINE(const char*) pj_strbuf( const pj_str_t *str )
+{
+ return str->ptr;
+}
+
+/**
+ * Compare strings.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ *
+ * @return
+ * - < 0 if str1 is less than str2
+ * - 0 if str1 is identical to str2
+ * - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2);
+
+/**
+ * Compare strings.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ *
+ * @return
+ * - < 0 if str1 is less than str2
+ * - 0 if str1 is identical to str2
+ * - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strcmp2( const pj_str_t *str1, const char *str2 );
+
+/**
+ * Compare strings.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ * @param len The maximum number of characters to compare.
+ *
+ * @return
+ * - < 0 if str1 is less than str2
+ * - 0 if str1 is identical to str2
+ * - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2,
+ pj_size_t len);
+
+/**
+ * Compare strings.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ * @param len The maximum number of characters to compare.
+ *
+ * @return
+ * - < 0 if str1 is less than str2
+ * - 0 if str1 is identical to str2
+ * - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strncmp2( const pj_str_t *str1, const char *str2,
+ pj_size_t len);
+
+/**
+ * Perform case-insensitive comparison to the strings.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ *
+ * @return
+ * - < 0 if str1 is less than str2
+ * - 0 if str1 is equal to str2
+ * - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_stricmp(const pj_str_t *str1, const pj_str_t *str2);
+
+/**
+ * Perform lowercase comparison to the strings which consists of only
+ * alnum characters. More over, it will only return non-zero if both
+ * strings are not equal, not the usual negative or positive value.
+ *
+ * If non-alnum inputs are given, then the function may mistakenly
+ * treat two strings as equal.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ * @param len The length to compare.
+ *
+ * @return
+ * - 0 if str1 is equal to str2
+ * - (-1) if not equal.
+ */
+#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0
+PJ_IDECL(int) strnicmp_alnum(const char *str1, const char *str2,
+ int len);
+#else
+#define strnicmp_alnum pj_ansi_strnicmp
+#endif
+
+/**
+ * Perform lowercase comparison to the strings which consists of only
+ * alnum characters. More over, it will only return non-zero if both
+ * strings are not equal, not the usual negative or positive value.
+ *
+ * If non-alnum inputs are given, then the function may mistakenly
+ * treat two strings as equal.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ *
+ * @return
+ * - 0 if str1 is equal to str2
+ * - (-1) if not equal.
+ */
+#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0
+PJ_IDECL(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2);
+#else
+#define pj_stricmp_alnum pj_stricmp
+#endif
+
+/**
+ * Perform case-insensitive comparison to the strings.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ *
+ * @return
+ * - < 0 if str1 is less than str2
+ * - 0 if str1 is identical to str2
+ * - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_stricmp2( const pj_str_t *str1, const char *str2);
+
+/**
+ * Perform case-insensitive comparison to the strings.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ * @param len The maximum number of characters to compare.
+ *
+ * @return
+ * - < 0 if str1 is less than str2
+ * - 0 if str1 is identical to str2
+ * - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2,
+ pj_size_t len);
+
+/**
+ * Perform case-insensitive comparison to the strings.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ * @param len The maximum number of characters to compare.
+ *
+ * @return
+ * - < 0 if str1 is less than str2
+ * - 0 if str1 is identical to str2
+ * - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strnicmp2( const pj_str_t *str1, const char *str2,
+ pj_size_t len);
+
+/**
+ * Concatenate strings.
+ *
+ * @param dst The destination string.
+ * @param src The source string.
+ */
+PJ_IDECL(void) pj_strcat(pj_str_t *dst, const pj_str_t *src);
+
+
+/**
+ * Concatenate strings.
+ *
+ * @param dst The destination string.
+ * @param src The source string.
+ */
+PJ_IDECL(void) pj_strcat2(pj_str_t *dst, const char *src);
+
+
+/**
+ * Finds a character in a string.
+ *
+ * @param str The string.
+ * @param chr The character to find.
+ *
+ * @return the pointer to first character found, or NULL.
+ */
+PJ_INLINE(char*) pj_strchr( const pj_str_t *str, int chr)
+{
+ return (char*) memchr((char*)str->ptr, chr, str->slen);
+}
+
+/**
+ * Find the occurence of a substring substr in string str.
+ *
+ * @param str The string to search.
+ * @param substr The string to search fo.
+ *
+ * @return the pointer to the position of substr in str, or NULL. Note
+ * that if str is not NULL terminated, the returned pointer
+ * is pointing to non-NULL terminated string.
+ */
+PJ_DECL(char*) pj_strstr(const pj_str_t *str, const pj_str_t *substr);
+
+/**
+ * Performs substring lookup like pj_strstr() but ignores the case of
+ * both strings.
+ *
+ * @param str The string to search.
+ * @param substr The string to search fo.
+ *
+ * @return the pointer to the position of substr in str, or NULL. Note
+ * that if str is not NULL terminated, the returned pointer
+ * is pointing to non-NULL terminated string.
+ */
+PJ_DECL(char*) pj_stristr(const pj_str_t *str, const pj_str_t *substr);
+
+/**
+ * Remove (trim) leading whitespaces from the string.
+ *
+ * @param str The string.
+ *
+ * @return the string.
+ */
+PJ_DECL(pj_str_t*) pj_strltrim( pj_str_t *str );
+
+/**
+ * Remove (trim) the trailing whitespaces from the string.
+ *
+ * @param str The string.
+ *
+ * @return the string.
+ */
+PJ_DECL(pj_str_t*) pj_strrtrim( pj_str_t *str );
+
+/**
+ * Remove (trim) leading and trailing whitespaces from the string.
+ *
+ * @param str The string.
+ *
+ * @return the string.
+ */
+PJ_IDECL(pj_str_t*) pj_strtrim( pj_str_t *str );
+
+/**
+ * Initialize the buffer with some random string. Note that the
+ * generated string is not NULL terminated.
+ *
+ * @param str the string to store the result.
+ * @param length the length of the random string to generate.
+ *
+ * @return the string.
+ */
+PJ_DECL(char*) pj_create_random_string(char *str, pj_size_t length);
+
+/**
+ * Convert string to unsigned integer. The conversion will stop as
+ * soon as non-digit character is found or all the characters have
+ * been processed.
+ *
+ * @param str the string.
+ *
+ * @return the unsigned integer.
+ */
+PJ_DECL(unsigned long) pj_strtoul(const pj_str_t *str);
+
+/**
+ * Convert strings to an unsigned long-integer value.
+ * This function stops reading the string input either when the number
+ * of characters has exceeded the length of the input or it has read
+ * the first character it cannot recognize as part of a number, that is
+ * a character greater than or equal to base.
+ *
+ * @param str The input string.
+ * @param endptr Optional pointer to receive the remainder/unparsed
+ * portion of the input.
+ * @param base Number base to use.
+ *
+ * @return the unsigned integer number.
+ */
+PJ_DECL(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr,
+ unsigned base);
+
+/**
+ * Utility to convert unsigned integer to string. Note that the
+ * string will be NULL terminated.
+ *
+ * @param val the unsigned integer value.
+ * @param buf the buffer
+ *
+ * @return the number of characters written
+ */
+PJ_DECL(int) pj_utoa(unsigned long val, char *buf);
+
+/**
+ * Convert unsigned integer to string with minimum digits. Note that the
+ * string will be NULL terminated.
+ *
+ * @param val The unsigned integer value.
+ * @param buf The buffer.
+ * @param min_dig Minimum digits to be printed, or zero to specify no
+ * minimum digit.
+ * @param pad The padding character to be put in front of the string
+ * when the digits is less than minimum.
+ *
+ * @return the number of characters written.
+ */
+PJ_DECL(int) pj_utoa_pad( unsigned long val, char *buf, int min_dig, int pad);
+
+
+/**
+ * Fill the memory location with zero.
+ *
+ * @param dst The destination buffer.
+ * @param size The number of bytes.
+ */
+PJ_INLINE(void) pj_bzero(void *dst, pj_size_t size)
+{
+#if defined(PJ_HAS_BZERO) && PJ_HAS_BZERO!=0
+ bzero(dst, size);
+#else
+ memset(dst, 0, size);
+#endif
+}
+
+
+/**
+ * Fill the memory location with value.
+ *
+ * @param dst The destination buffer.
+ * @param c Character to set.
+ * @param size The number of characters.
+ *
+ * @return the value of dst.
+ */
+PJ_INLINE(void*) pj_memset(void *dst, int c, pj_size_t size)
+{
+ return memset(dst, c, size);
+}
+
+/**
+ * Copy buffer.
+ *
+ * @param dst The destination buffer.
+ * @param src The source buffer.
+ * @param size The size to copy.
+ *
+ * @return the destination buffer.
+ */
+PJ_INLINE(void*) pj_memcpy(void *dst, const void *src, pj_size_t size)
+{
+ return memcpy(dst, src, size);
+}
+
+/**
+ * Move memory.
+ *
+ * @param dst The destination buffer.
+ * @param src The source buffer.
+ * @param size The size to copy.
+ *
+ * @return the destination buffer.
+ */
+PJ_INLINE(void*) pj_memmove(void *dst, const void *src, pj_size_t size)
+{
+ return memmove(dst, src, size);
+}
+
+/**
+ * Compare buffers.
+ *
+ * @param buf1 The first buffer.
+ * @param buf2 The second buffer.
+ * @param size The size to compare.
+ *
+ * @return negative, zero, or positive value.
+ */
+PJ_INLINE(int) pj_memcmp(const void *buf1, const void *buf2, pj_size_t size)
+{
+ return memcmp(buf1, buf2, size);
+}
+
+/**
+ * Find character in the buffer.
+ *
+ * @param buf The buffer.
+ * @param c The character to find.
+ * @param size The size to check.
+ *
+ * @return the pointer to location where the character is found, or NULL if
+ * not found.
+ */
+PJ_INLINE(void*) pj_memchr(const void *buf, int c, pj_size_t size)
+{
+ return (void*)memchr((void*)buf, c, size);
+}
+
+
+/**
+ * @}
+ */
+
+#if PJ_FUNCTIONS_ARE_INLINED
+# include <pj/string_i.h>
+#endif
+
+PJ_END_DECL
+
+#endif /* __PJ_STRING_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/string_i.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/string_i.h
new file mode 100644
index 0000000..925ec1e
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/string_i.h
@@ -0,0 +1,371 @@
+/* $Id: string_i.h 2749 2009-06-04 22:08:16Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <pj/pool.h>
+
+PJ_IDEF(pj_str_t) pj_str(char *str)
+{
+ pj_str_t dst;
+ dst.ptr = str;
+ dst.slen = str ? pj_ansi_strlen(str) : 0;
+ return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strdup(pj_pool_t *pool,
+ pj_str_t *dst,
+ const pj_str_t *src)
+{
+ /* Without this, destination will be corrupted */
+ if (dst == src)
+ return dst;
+
+ if (src->slen) {
+ dst->ptr = (char*)pj_pool_alloc(pool, src->slen);
+ pj_memcpy(dst->ptr, src->ptr, src->slen);
+ }
+ dst->slen = src->slen;
+ return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strdup_with_null( pj_pool_t *pool,
+ pj_str_t *dst,
+ const pj_str_t *src)
+{
+ dst->ptr = (char*)pj_pool_alloc(pool, src->slen+1);
+ if (src->slen) {
+ pj_memcpy(dst->ptr, src->ptr, src->slen);
+ }
+ dst->slen = src->slen;
+ dst->ptr[dst->slen] = '\0';
+ return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strdup2(pj_pool_t *pool,
+ pj_str_t *dst,
+ const char *src)
+{
+ dst->slen = src ? pj_ansi_strlen(src) : 0;
+ if (dst->slen) {
+ dst->ptr = (char*)pj_pool_alloc(pool, dst->slen);
+ pj_memcpy(dst->ptr, src, dst->slen);
+ } else {
+ dst->ptr = NULL;
+ }
+ return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strdup2_with_null( pj_pool_t *pool,
+ pj_str_t *dst,
+ const char *src)
+{
+ dst->slen = src ? pj_ansi_strlen(src) : 0;
+ dst->ptr = (char*)pj_pool_alloc(pool, dst->slen+1);
+ if (dst->slen) {
+ pj_memcpy(dst->ptr, src, dst->slen);
+ }
+ dst->ptr[dst->slen] = '\0';
+ return dst;
+}
+
+PJ_IDEF(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src)
+{
+ pj_str_t temp;
+ pj_strdup2(pool, &temp, src);
+ return temp;
+}
+
+PJ_IDEF(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src )
+{
+ dst->ptr = src->ptr;
+ dst->slen = src->slen;
+ return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src)
+{
+ dst->slen = src->slen;
+ if (src->slen > 0)
+ pj_memcpy(dst->ptr, src->ptr, src->slen);
+ return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src)
+{
+ dst->slen = src ? pj_ansi_strlen(src) : 0;
+ if (dst->slen > 0)
+ pj_memcpy(dst->ptr, src, dst->slen);
+ return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strncpy( pj_str_t *dst, const pj_str_t *src,
+ pj_ssize_t max)
+{
+ if (max > src->slen) max = src->slen;
+ pj_memcpy(dst->ptr, src->ptr, max);
+ dst->slen = max;
+ return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strncpy_with_null( pj_str_t *dst, const pj_str_t *src,
+ pj_ssize_t max)
+{
+ if (max <= src->slen)
+ max = max-1;
+ else
+ max = src->slen;
+
+ pj_memcpy(dst->ptr, src->ptr, max);
+ dst->ptr[max] = '\0';
+ dst->slen = max;
+ return dst;
+}
+
+
+PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2)
+{
+ if (str1->slen == 0) {
+ return str2->slen==0 ? 0 : -1;
+ } else if (str2->slen == 0) {
+ return 1;
+ } else {
+ int min = (str1->slen < str2->slen)? str1->slen : str2->slen;
+ int res = pj_memcmp(str1->ptr, str2->ptr, min);
+ if (res == 0) {
+ return (str1->slen < str2->slen) ? -1 :
+ (str1->slen == str2->slen ? 0 : 1);
+ } else {
+ return res;
+ }
+ }
+}
+
+PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2,
+ pj_size_t len)
+{
+ pj_str_t copy1, copy2;
+
+ if (len < (unsigned)str1->slen) {
+ copy1.ptr = str1->ptr;
+ copy1.slen = len;
+ str1 = &copy1;
+ }
+
+ if (len < (unsigned)str2->slen) {
+ copy2.ptr = str2->ptr;
+ copy2.slen = len;
+ str2 = &copy2;
+ }
+
+ return pj_strcmp(str1, str2);
+}
+
+PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2,
+ pj_size_t len)
+{
+ pj_str_t copy2;
+
+ if (str2) {
+ copy2.ptr = (char*)str2;
+ copy2.slen = pj_ansi_strlen(str2);
+ } else {
+ copy2.slen = 0;
+ }
+
+ return pj_strncmp(str1, &copy2, len);
+}
+
+PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )
+{
+ pj_str_t copy2;
+
+ if (str2) {
+ copy2.ptr = (char*)str2;
+ copy2.slen = pj_ansi_strlen(str2);
+ } else {
+ copy2.ptr = NULL;
+ copy2.slen = 0;
+ }
+
+ return pj_strcmp(str1, &copy2);
+}
+
+PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
+{
+ if (str1->slen == 0) {
+ return str2->slen==0 ? 0 : -1;
+ } else if (str2->slen == 0) {
+ return 1;
+ } else {
+ int min = (str1->slen < str2->slen)? str1->slen : str2->slen;
+ int res = pj_ansi_strnicmp(str1->ptr, str2->ptr, min);
+ if (res == 0) {
+ return (str1->slen < str2->slen) ? -1 :
+ (str1->slen == str2->slen ? 0 : 1);
+ } else {
+ return res;
+ }
+ }
+}
+
+#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0
+PJ_IDEF(int) strnicmp_alnum( const char *str1, const char *str2,
+ int len)
+{
+ if (len==0)
+ return 0;
+ else {
+ register const pj_uint32_t *p1 = (pj_uint32_t*)str1,
+ *p2 = (pj_uint32_t*)str2;
+ while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
+ ++p1, ++p2, len-=4;
+
+ if (len > 3)
+ return -1;
+#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
+ else if (len==3)
+ return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
+ else if (len==2)
+ return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
+ else if (len==1)
+ return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
+#else
+ else if (len==3)
+ return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
+ else if (len==2)
+ return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
+ else if (len==1)
+ return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
+#endif
+ else
+ return 0;
+ }
+}
+
+PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
+{
+ register int len = str1->slen;
+
+ if (len != str2->slen) {
+ return (len < str2->slen) ? -1 : 1;
+ } else if (len == 0) {
+ return 0;
+ } else {
+ register const pj_uint32_t *p1 = (pj_uint32_t*)str1->ptr,
+ *p2 = (pj_uint32_t*)str2->ptr;
+ while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
+ ++p1, ++p2, len-=4;
+
+ if (len > 3)
+ return -1;
+#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
+ else if (len==3)
+ return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
+ else if (len==2)
+ return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
+ else if (len==1)
+ return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
+#else
+ else if (len==3)
+ return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
+ else if (len==2)
+ return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
+ else if (len==1)
+ return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
+#endif
+ else
+ return 0;
+ }
+}
+#endif /* PJ_HAS_STRICMP_ALNUM */
+
+PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)
+{
+ pj_str_t copy2;
+
+ if (str2) {
+ copy2.ptr = (char*)str2;
+ copy2.slen = pj_ansi_strlen(str2);
+ } else {
+ copy2.ptr = NULL;
+ copy2.slen = 0;
+ }
+
+ return pj_stricmp(str1, &copy2);
+}
+
+PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2,
+ pj_size_t len)
+{
+ pj_str_t copy1, copy2;
+
+ if (len < (unsigned)str1->slen) {
+ copy1.ptr = str1->ptr;
+ copy1.slen = len;
+ str1 = &copy1;
+ }
+
+ if (len < (unsigned)str2->slen) {
+ copy2.ptr = str2->ptr;
+ copy2.slen = len;
+ str2 = &copy2;
+ }
+
+ return pj_stricmp(str1, str2);
+}
+
+PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2,
+ pj_size_t len)
+{
+ pj_str_t copy2;
+
+ if (str2) {
+ copy2.ptr = (char*)str2;
+ copy2.slen = pj_ansi_strlen(str2);
+ } else {
+ copy2.slen = 0;
+ }
+
+ return pj_strnicmp(str1, &copy2, len);
+}
+
+PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src)
+{
+ if (src->slen) {
+ pj_memcpy(dst->ptr + dst->slen, src->ptr, src->slen);
+ dst->slen += src->slen;
+ }
+}
+
+PJ_IDEF(void) pj_strcat2(pj_str_t *dst, const char *str)
+{
+ unsigned len = str? pj_ansi_strlen(str) : 0;
+ if (len) {
+ pj_memcpy(dst->ptr + dst->slen, str, len);
+ dst->slen += len;
+ }
+}
+
+PJ_IDEF(pj_str_t*) pj_strtrim( pj_str_t *str )
+{
+ pj_strltrim(str);
+ pj_strrtrim(str);
+ return str;
+}
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/timer.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/timer.h
new file mode 100644
index 0000000..8e0dd45
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/timer.h
@@ -0,0 +1,276 @@
+/* $Id: timer.h 2512 2009-03-13 15:49:06Z bennylp $ */
+/*
+ * 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_TIMER_H__
+#define __PJ_TIMER_H__
+
+/**
+ * @file timer.h
+ * @brief Timer Heap
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_TIMER Timer Heap Management.
+ * @ingroup PJ_MISC
+ * @brief
+ * The timer scheduling implementation here is based on ACE library's
+ * ACE_Timer_Heap, with only little modification to suit our library's style
+ * (I even left most of the comments in the original source).
+ *
+ * To quote the original quote in ACE_Timer_Heap_T class:
+ *
+ * This implementation uses a heap-based callout queue of
+ * absolute times. Therefore, in the average and worst case,
+ * scheduling, canceling, and expiring timers is O(log N) (where
+ * N is the total number of timers). In addition, we can also
+ * preallocate as many \a ACE_Timer_Nodes as there are slots in
+ * the heap. This allows us to completely remove the need for
+ * dynamic memory allocation, which is important for real-time
+ * systems.
+ *
+ * You can find the fine ACE library at:
+ * http://www.cs.wustl.edu/~schmidt/ACE.html
+ *
+ * ACE is Copyright (C)1993-2006 Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
+ *
+ * @{
+ *
+ * \section pj_timer_examples_sec Examples
+ *
+ * For some examples on how to use the timer heap, please see the link below.
+ *
+ * - \ref page_pjlib_timer_test
+ */
+
+
+/**
+ * The type for internal timer ID.
+ */
+#if defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
+typedef void *pj_timer_id_t;
+#else
+typedef int pj_timer_id_t;
+#endif
+
+/**
+ * Forward declaration for pj_timer_entry.
+ */
+struct pj_timer_entry;
+
+/**
+ * The type of callback function to be called by timer scheduler when a timer
+ * has expired.
+ *
+ * @param timer_heap The timer heap.
+ * @param entry Timer entry which timer's has expired.
+ */
+typedef void pj_timer_heap_callback(pj_timer_heap_t *timer_heap,
+ struct pj_timer_entry *entry);
+
+
+/**
+ * This structure represents an entry to the timer.
+ */
+struct pj_timer_entry
+{
+ /**
+ * User data to be associated with this entry.
+ * Applications normally will put the instance of object that
+ * owns the timer entry in this field.
+ */
+ void *user_data;
+
+ /**
+ * Arbitrary ID assigned by the user/owner of this entry.
+ * Applications can use this ID to distinguish multiple
+ * timer entries that share the same callback and user_data.
+ */
+ int id;
+
+ /**
+ * Callback to be called when the timer expires.
+ */
+ pj_timer_heap_callback *cb;
+
+ /**
+ * Internal unique timer ID, which is assigned by the timer heap.
+ * Application should not touch this ID.
+ */
+ pj_timer_id_t _timer_id;
+
+ /**
+ * The future time when the timer expires, which the value is updated
+ * by timer heap when the timer is scheduled.
+ */
+ pj_time_val _timer_value;
+};
+
+
+/**
+ * Calculate memory size required to create a timer heap.
+ *
+ * @param count Number of timer entries to be supported.
+ * @return Memory size requirement in bytes.
+ */
+PJ_DECL(pj_size_t) pj_timer_heap_mem_size(pj_size_t count);
+
+/**
+ * Create a timer heap.
+ *
+ * @param pool The pool where allocations in the timer heap will be
+ * allocated. The timer heap will dynamicly allocate
+ * more storate from the pool if the number of timer
+ * entries registered is more than the size originally
+ * requested when calling this function.
+ * @param count The maximum number of timer entries to be supported
+ * initially. If the application registers more entries
+ * during runtime, then the timer heap will resize.
+ * @param ht Pointer to receive the created timer heap.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_timer_heap_create( pj_pool_t *pool,
+ pj_size_t count,
+ pj_timer_heap_t **ht);
+
+/**
+ * Destroy the timer heap.
+ *
+ * @param ht The timer heap.
+ */
+PJ_DECL(void) pj_timer_heap_destroy( pj_timer_heap_t *ht );
+
+
+/**
+ * Set lock object to be used by the timer heap. By default, the timer heap
+ * uses dummy synchronization.
+ *
+ * @param ht The timer heap.
+ * @param lock The lock object to be used for synchronization.
+ * @param auto_del If nonzero, the lock object will be destroyed when
+ * the timer heap is destroyed.
+ */
+PJ_DECL(void) pj_timer_heap_set_lock( pj_timer_heap_t *ht,
+ pj_lock_t *lock,
+ pj_bool_t auto_del );
+
+/**
+ * Set maximum number of timed out entries to process in a single poll.
+ *
+ * @param ht The timer heap.
+ * @param count Number of entries.
+ *
+ * @return The old number.
+ */
+PJ_DECL(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht,
+ unsigned count );
+
+/**
+ * Initialize a timer entry. Application should call this function at least
+ * once before scheduling the entry to the timer heap, to properly initialize
+ * the timer entry.
+ *
+ * @param entry The timer entry to be initialized.
+ * @param id Arbitrary ID assigned by the user/owner of this entry.
+ * Applications can use this ID to distinguish multiple
+ * timer entries that share the same callback and user_data.
+ * @param user_data User data to be associated with this entry.
+ * Applications normally will put the instance of object that
+ * owns the timer entry in this field.
+ * @param cb Callback function to be called when the timer elapses.
+ *
+ * @return The timer entry itself.
+ */
+PJ_DECL(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,
+ int id,
+ void *user_data,
+ pj_timer_heap_callback *cb );
+
+/**
+ * Schedule a timer entry which will expire AFTER the specified delay.
+ *
+ * @param ht The timer heap.
+ * @param entry The entry to be registered.
+ * @param delay The interval to expire.
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht,
+ pj_timer_entry *entry,
+ const pj_time_val *delay);
+
+/**
+ * Cancel a previously registered timer.
+ *
+ * @param ht The timer heap.
+ * @param entry The entry to be cancelled.
+ * @return The number of timer cancelled, which should be one if the
+ * entry has really been registered, or zero if no timer was
+ * cancelled.
+ */
+PJ_DECL(int) pj_timer_heap_cancel( pj_timer_heap_t *ht,
+ pj_timer_entry *entry);
+
+/**
+ * Get the number of timer entries.
+ *
+ * @param ht The timer heap.
+ * @return The number of timer entries.
+ */
+PJ_DECL(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht );
+
+/**
+ * Get the earliest time registered in the timer heap. The timer heap
+ * MUST have at least one timer being scheduled (application should use
+ * #pj_timer_heap_count() before calling this function).
+ *
+ * @param ht The timer heap.
+ * @param timeval The time deadline of the earliest timer entry.
+ *
+ * @return PJ_SUCCESS, or PJ_ENOTFOUND if no entry is scheduled.
+ */
+PJ_DECL(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t *ht,
+ pj_time_val *timeval);
+
+/**
+ * Poll the timer heap, check for expired timers and call the callback for
+ * each of the expired timers.
+ *
+ * Note: polling the timer heap is not necessary in Symbian. Please see
+ * @ref PJ_SYMBIAN_OS for more info.
+ *
+ * @param ht The timer heap.
+ * @param next_delay If this parameter is not NULL, it will be filled up with
+ * the time delay until the next timer elapsed, or
+ * PJ_MAXINT32 in the sec part if no entry exist.
+ *
+ * @return The number of timers expired.
+ */
+PJ_DECL(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht,
+ pj_time_val *next_delay);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJ_TIMER_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/types.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/types.h
new file mode 100644
index 0000000..97c8aa9
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/types.h
@@ -0,0 +1,544 @@
+/* $Id: types.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_TYPES_H__
+#define __PJ_TYPES_H__
+
+
+/**
+ * @file types.h
+ * @brief Declaration of basic types and utility.
+ */
+/**
+ * @defgroup PJ_BASIC Basic Data Types and Library Functionality.
+ * @ingroup PJ_DS
+ * @{
+ */
+#include <pj/config.h>
+
+PJ_BEGIN_DECL
+
+/* ************************************************************************* */
+
+/** Signed 32bit integer. */
+typedef int pj_int32_t;
+
+/** Unsigned 32bit integer. */
+typedef unsigned int pj_uint32_t;
+
+/** Signed 16bit integer. */
+typedef short pj_int16_t;
+
+/** Unsigned 16bit integer. */
+typedef unsigned short pj_uint16_t;
+
+/** Signed 8bit integer. */
+typedef signed char pj_int8_t;
+
+/** Unsigned 8bit integer. */
+typedef unsigned char pj_uint8_t;
+
+/** Large unsigned integer. */
+typedef size_t pj_size_t;
+
+/** Large signed integer. */
+typedef long pj_ssize_t;
+
+/** Status code. */
+typedef int pj_status_t;
+
+/** Boolean. */
+typedef int pj_bool_t;
+
+/** Native char type, which will be equal to wchar_t for Unicode
+ * and char for ANSI. */
+#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0
+ typedef wchar_t pj_char_t;
+#else
+ typedef char pj_char_t;
+#endif
+
+/** This macro creates Unicode or ANSI literal string depending whether
+ * native platform string is Unicode or ANSI. */
+#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0
+# define PJ_T(literal_str) L##literal_str
+#else
+# define PJ_T(literal_str) literal_str
+#endif
+
+
+/** Status is OK. */
+#define PJ_SUCCESS 0
+
+/** True value. */
+#define PJ_TRUE 1
+
+/** False value. */
+#define PJ_FALSE 0
+
+/**
+ * File offset type.
+ */
+#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0
+typedef pj_int64_t pj_off_t;
+#else
+typedef pj_ssize_t pj_off_t;
+#endif
+
+/* ************************************************************************* */
+/*
+ * Data structure types.
+ */
+/**
+ * This type is used as replacement to legacy C string, and used throughout
+ * the library. By convention, the string is NOT null terminated.
+ */
+struct pj_str_t
+{
+ /** Buffer pointer, which is by convention NOT null terminated. */
+ char *ptr;
+
+ /** The length of the string. */
+ pj_ssize_t slen;
+};
+
+/**
+ * This structure represents high resolution (64bit) time value. The time
+ * values represent time in cycles, which is retrieved by calling
+ * #pj_get_timestamp().
+ */
+typedef union pj_timestamp
+{
+ struct
+ {
+#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
+ pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */
+ pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */
+#else
+ pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */
+ pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */
+#endif
+ } u32; /**< The 64-bit value as two 32-bit values. */
+
+#if PJ_HAS_INT64
+ pj_uint64_t u64; /**< The whole 64-bit value, where available. */
+#endif
+} pj_timestamp;
+
+
+
+/**
+ * The opaque data type for linked list, which is used as arguments throughout
+ * the linked list operations.
+ */
+typedef void pj_list_type;
+
+/**
+ * List.
+ */
+typedef struct pj_list pj_list;
+
+/**
+ * Opaque data type for hash tables.
+ */
+typedef struct pj_hash_table_t pj_hash_table_t;
+
+/**
+ * Opaque data type for hash entry (only used internally by hash table).
+ */
+typedef struct pj_hash_entry pj_hash_entry;
+
+/**
+ * Data type for hash search iterator.
+ * This structure should be opaque, however applications need to declare
+ * concrete variable of this type, that's why the declaration is visible here.
+ */
+typedef struct pj_hash_iterator_t
+{
+ pj_uint32_t index; /**< Internal index. */
+ pj_hash_entry *entry; /**< Internal entry. */
+} pj_hash_iterator_t;
+
+
+/**
+ * Forward declaration for memory pool factory.
+ */
+typedef struct pj_pool_factory pj_pool_factory;
+
+/**
+ * Opaque data type for memory pool.
+ */
+typedef struct pj_pool_t pj_pool_t;
+
+/**
+ * Forward declaration for caching pool, a pool factory implementation.
+ */
+typedef struct pj_caching_pool pj_caching_pool;
+
+/**
+ * This type is used as replacement to legacy C string, and used throughout
+ * the library.
+ */
+typedef struct pj_str_t pj_str_t;
+
+/**
+ * Opaque data type for I/O Queue structure.
+ */
+typedef struct pj_ioqueue_t pj_ioqueue_t;
+
+/**
+ * Opaque data type for key that identifies a handle registered to the
+ * I/O queue framework.
+ */
+typedef struct pj_ioqueue_key_t pj_ioqueue_key_t;
+
+/**
+ * Opaque data to identify timer heap.
+ */
+typedef struct pj_timer_heap_t pj_timer_heap_t;
+
+/**
+ * Forward declaration for timer entry.
+ */
+typedef struct pj_timer_entry pj_timer_entry;
+
+/**
+ * Opaque data type for atomic operations.
+ */
+typedef struct pj_atomic_t pj_atomic_t;
+
+/**
+ * Value type of an atomic variable.
+ */
+typedef PJ_ATOMIC_VALUE_TYPE pj_atomic_value_t;
+
+/* ************************************************************************* */
+
+/** Thread handle. */
+typedef struct pj_thread_t pj_thread_t;
+
+/** Lock object. */
+typedef struct pj_lock_t pj_lock_t;
+
+/** Mutex handle. */
+typedef struct pj_mutex_t pj_mutex_t;
+
+/** Semaphore handle. */
+typedef struct pj_sem_t pj_sem_t;
+
+/** Event object. */
+typedef struct pj_event_t pj_event_t;
+
+/** Unidirectional stream pipe object. */
+typedef struct pj_pipe_t pj_pipe_t;
+
+/** Operating system handle. */
+typedef void *pj_oshandle_t;
+
+/** Socket handle. */
+typedef long pj_sock_t;
+
+/** Generic socket address. */
+typedef void pj_sockaddr_t;
+
+/** Forward declaration. */
+typedef struct pj_sockaddr_in pj_sockaddr_in;
+
+/** Color type. */
+typedef unsigned int pj_color_t;
+
+/** Exception id. */
+typedef int pj_exception_id_t;
+
+/* ************************************************************************* */
+
+/** Utility macro to compute the number of elements in static array. */
+#define PJ_ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+/** Maximum value for signed 32-bit integer. */
+#define PJ_MAXINT32 0x7FFFFFFFL
+
+/**
+ * Length of object names.
+ */
+#define PJ_MAX_OBJ_NAME 32
+
+/* ************************************************************************* */
+/*
+ * General.
+ */
+/**
+ * Initialize the PJ Library.
+ * This function must be called before using the library. The purpose of this
+ * function is to initialize static library data, such as character table used
+ * in random string generation, and to initialize operating system dependent
+ * functionality (such as WSAStartup() in Windows).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_init(void);
+
+
+/**
+ * Shutdown PJLIB.
+ */
+PJ_DECL(void) pj_shutdown(void);
+
+/**
+ * Type of callback to register to pj_atexit().
+ */
+typedef void (*pj_exit_callback)(void);
+
+/**
+ * Register cleanup function to be called by PJLIB when pj_shutdown() is
+ * called.
+ *
+ * @param func The function to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_atexit(pj_exit_callback func);
+
+
+
+/**
+ * Swap the byte order of an 16bit data.
+ *
+ * @param val16 The 16bit data.
+ *
+ * @return An 16bit data with swapped byte order.
+ */
+PJ_INLINE(pj_int16_t) pj_swap16(pj_int16_t val16)
+{
+ pj_uint8_t *p = (pj_uint8_t*)&val16;
+ pj_uint8_t tmp = *p;
+ *p = *(p+1);
+ *(p+1) = tmp;
+ return val16;
+}
+
+/**
+ * Swap the byte order of an 32bit data.
+ *
+ * @param val32 The 32bit data.
+ *
+ * @return An 32bit data with swapped byte order.
+ */
+PJ_INLINE(pj_int32_t) pj_swap32(pj_int32_t val32)
+{
+ pj_uint8_t *p = (pj_uint8_t*)&val32;
+ pj_uint8_t tmp = *p;
+ *p = *(p+3);
+ *(p+3) = tmp;
+ tmp = *(p+1);
+ *(p+1) = *(p+2);
+ *(p+2) = tmp;
+ return val32;
+}
+
+
+/**
+ * @}
+ */
+/**
+ * @addtogroup PJ_TIME Time Data Type and Manipulation.
+ * @ingroup PJ_MISC
+ * @{
+ */
+
+/**
+ * Representation of time value in this library.
+ * This type can be used to represent either an interval or a specific time
+ * or date.
+ */
+typedef struct pj_time_val
+{
+ /** The seconds part of the time. */
+ long sec;
+
+ /** The miliseconds fraction of the time. */
+ long msec;
+
+} pj_time_val;
+
+/**
+ * Normalize the value in time value.
+ * @param t Time value to be normalized.
+ */
+PJ_DECL(void) pj_time_val_normalize(pj_time_val *t);
+
+/**
+ * Get the total time value in miliseconds. This is the same as
+ * multiplying the second part with 1000 and then add the miliseconds
+ * part to the result.
+ *
+ * @param t The time value.
+ * @return Total time in miliseconds.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_MSEC(t) ((t).sec * 1000 + (t).msec)
+
+/**
+ * This macro will check if \a t1 is equal to \a t2.
+ *
+ * @param t1 The first time value to compare.
+ * @param t2 The second time value to compare.
+ * @return Non-zero if both time values are equal.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_EQ(t1, t2) ((t1).sec==(t2).sec && (t1).msec==(t2).msec)
+
+/**
+ * This macro will check if \a t1 is greater than \a t2
+ *
+ * @param t1 The first time value to compare.
+ * @param t2 The second time value to compare.
+ * @return Non-zero if t1 is greater than t2.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_GT(t1, t2) ((t1).sec>(t2).sec || \
+ ((t1).sec==(t2).sec && (t1).msec>(t2).msec))
+
+/**
+ * This macro will check if \a t1 is greater than or equal to \a t2
+ *
+ * @param t1 The first time value to compare.
+ * @param t2 The second time value to compare.
+ * @return Non-zero if t1 is greater than or equal to t2.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_GTE(t1, t2) (PJ_TIME_VAL_GT(t1,t2) || \
+ PJ_TIME_VAL_EQ(t1,t2))
+
+/**
+ * This macro will check if \a t1 is less than \a t2
+ *
+ * @param t1 The first time value to compare.
+ * @param t2 The second time value to compare.
+ * @return Non-zero if t1 is less than t2.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_LT(t1, t2) (!(PJ_TIME_VAL_GTE(t1,t2)))
+
+/**
+ * This macro will check if \a t1 is less than or equal to \a t2.
+ *
+ * @param t1 The first time value to compare.
+ * @param t2 The second time value to compare.
+ * @return Non-zero if t1 is less than or equal to t2.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_LTE(t1, t2) (!PJ_TIME_VAL_GT(t1, t2))
+
+/**
+ * Add \a t2 to \a t1 and store the result in \a t1. Effectively
+ *
+ * this macro will expand as: (\a t1 += \a t2).
+ * @param t1 The time value to add.
+ * @param t2 The time value to be added to \a t1.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_ADD(t1, t2) do { \
+ (t1).sec += (t2).sec; \
+ (t1).msec += (t2).msec; \
+ pj_time_val_normalize(&(t1)); \
+ } while (0)
+
+
+/**
+ * Substract \a t2 from \a t1 and store the result in \a t1. Effectively
+ * this macro will expand as (\a t1 -= \a t2).
+ *
+ * @param t1 The time value to subsctract.
+ * @param t2 The time value to be substracted from \a t1.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_SUB(t1, t2) do { \
+ (t1).sec -= (t2).sec; \
+ (t1).msec -= (t2).msec; \
+ pj_time_val_normalize(&(t1)); \
+ } while (0)
+
+
+/**
+ * This structure represent the parsed representation of time.
+ * It is acquired by calling #pj_time_decode().
+ */
+typedef struct pj_parsed_time
+{
+ /** This represents day of week where value zero means Sunday */
+ int wday;
+
+ /* This represents day of the year, 0-365, where zero means
+ * 1st of January.
+ */
+ /*int yday; */
+
+ /** This represents day of month: 1-31 */
+ int day;
+
+ /** This represents month, with the value is 0 - 11 (zero is January) */
+ int mon;
+
+ /** This represent the actual year (unlike in ANSI libc where
+ * the value must be added by 1900).
+ */
+ int year;
+
+ /** This represents the second part, with the value is 0-59 */
+ int sec;
+
+ /** This represents the minute part, with the value is: 0-59 */
+ int min;
+
+ /** This represents the hour part, with the value is 0-23 */
+ int hour;
+
+ /** This represents the milisecond part, with the value is 0-999 */
+ int msec;
+
+} pj_parsed_time;
+
+
+/**
+ * @} // Time Management
+ */
+
+/* ************************************************************************* */
+/*
+ * Terminal.
+ */
+/**
+ * Color code combination.
+ */
+enum {
+ PJ_TERM_COLOR_R = 2, /**< Red */
+ PJ_TERM_COLOR_G = 4, /**< Green */
+ PJ_TERM_COLOR_B = 1, /**< Blue. */
+ PJ_TERM_COLOR_BRIGHT = 8 /**< Bright mask. */
+};
+
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJ_TYPES_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pj/unicode.h b/Protocols/SIP/lib/pjsip/pjlib/include/pj/unicode.h
new file mode 100644
index 0000000..84c1517
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pj/unicode.h
@@ -0,0 +1,141 @@
+/* $Id: unicode.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_UNICODE_H__
+#define __PJ_UNICODE_H__
+
+#include <pj/types.h>
+
+
+/**
+ * @defgroup PJ_UNICODE Unicode Support
+ * @ingroup PJ_MISC
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @file unicode.h
+ * @brief Provides Unicode conversion for Unicode OSes
+ */
+
+/**
+ * Convert ANSI strings to Unicode strings.
+ *
+ * @param str The ANSI string to be converted.
+ * @param len The length of the input string.
+ * @param wbuf Buffer to hold the Unicode string output.
+ * @param wbuf_count Buffer size, in number of elements (not bytes).
+ *
+ * @return The Unicode string, NULL terminated.
+ */
+PJ_DECL(wchar_t*) pj_ansi_to_unicode(const char *str, pj_size_t len,
+ wchar_t *wbuf, pj_size_t wbuf_count);
+
+
+/**
+ * Convert Unicode string to ANSI string.
+ *
+ * @param wstr The Unicode string to be converted.
+ * @param len The length of the input string.
+ * @param buf Buffer to hold the ANSI string output.
+ * @param buf_size Size of the output buffer.
+ *
+ * @return The ANSI string, NULL terminated.
+ */
+PJ_DECL(char*) pj_unicode_to_ansi(const wchar_t *wstr, pj_size_t len,
+ char *buf, pj_size_t buf_size);
+
+
+#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0
+
+/**
+ * This macro is used to declare temporary Unicode buffer for ANSI to
+ * Unicode conversion, and should be put in declaration section of a block.
+ * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this
+ * macro will expand to nothing.
+ */
+# define PJ_DECL_UNICODE_TEMP_BUF(buf,size) wchar_t buf[size];
+
+/**
+ * This macro will convert ANSI string to native, when the platform's
+ * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero).
+ */
+# define PJ_STRING_TO_NATIVE(s,buf,max) pj_ansi_to_unicode( \
+ s, strlen(s), \
+ buf, max)
+
+/**
+ * This macro is used to declare temporary ANSI buffer for Unicode to
+ * ANSI conversion, and should be put in declaration section of a block.
+ * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this
+ * macro will expand to nothing.
+ */
+# define PJ_DECL_ANSI_TEMP_BUF(buf,size) char buf[size];
+
+
+/**
+ * This macro will convert Unicode string to ANSI, when the platform's
+ * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero).
+ */
+# define PJ_NATIVE_TO_STRING(cs,buf,max) pj_unicode_to_ansi( \
+ cs, wcslen(cs), \
+ buf, max)
+
+#else
+
+/**
+ * This macro is used to declare temporary Unicode buffer for ANSI to
+ * Unicode conversion, and should be put in declaration section of a block.
+ * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this
+ * macro will expand to nothing.
+ */
+# define PJ_DECL_UNICODE_TEMP_BUF(var,size)
+/**
+ * This macro will convert ANSI string to native, when the platform's
+ * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero).
+ */
+# define PJ_STRING_TO_NATIVE(s,buf,max) ((char*)s)
+/**
+ * This macro is used to declare temporary ANSI buffer for Unicode to
+ * ANSI conversion, and should be put in declaration section of a block.
+ * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this
+ * macro will expand to nothing.
+ */
+# define PJ_DECL_ANSI_TEMP_BUF(buf,size)
+/**
+ * This macro will convert Unicode string to ANSI, when the platform's
+ * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero).
+ */
+# define PJ_NATIVE_TO_STRING(cs,buf,max) ((char*)(const char*)cs)
+
+#endif
+
+
+
+PJ_END_DECL
+
+/*
+ * @}
+ */
+
+
+#endif /* __PJ_UNICODE_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pjlib++.hpp b/Protocols/SIP/lib/pjsip/pjlib/include/pjlib++.hpp
new file mode 100644
index 0000000..ce269a6
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pjlib++.hpp
@@ -0,0 +1,35 @@
+/* $Id: pjlib++.hpp 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJLIBPP_H__
+#define __PJLIBPP_H__
+
+#include <pj++/file.hpp>
+#include <pj++/pool.hpp>
+#include <pj++/hash.hpp>
+#include <pj++/list.hpp>
+#include <pj++/os.hpp>
+#include <pj++/proactor.hpp>
+#include <pj++/scanner.hpp>
+#include <pj++/sock.hpp>
+#include <pj++/string.hpp>
+#include <pj++/timer.hpp>
+#include <pj++/tree.hpp>
+
+#endif /* __PJLIBPP_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjlib/include/pjlib.h b/Protocols/SIP/lib/pjsip/pjlib/include/pjlib.h
new file mode 100644
index 0000000..4868f84
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjlib/include/pjlib.h
@@ -0,0 +1,63 @@
+/* $Id: pjlib.h 2970 2009-10-26 15:47:52Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __PJLIB_H__
+#define __PJLIB_H__
+
+/**
+ * @file pjlib.h
+ * @brief Include all PJLIB header files.
+ */
+
+#include <pj/activesock.h>
+#include <pj/addr_resolv.h>
+#include <pj/array.h>
+#include <pj/assert.h>
+#include <pj/ctype.h>
+#include <pj/errno.h>
+#include <pj/except.h>
+#include <pj/fifobuf.h>
+#include <pj/file_access.h>
+#include <pj/file_io.h>
+#include <pj/guid.h>
+#include <pj/hash.h>
+#include <pj/ioqueue.h>
+#include <pj/ip_helper.h>
+#include <pj/list.h>
+#include <pj/lock.h>
+#include <pj/log.h>
+#include <pj/math.h>
+#include <pj/os.h>
+#include <pj/pool.h>
+#include <pj/pool_buf.h>
+#include <pj/rand.h>
+#include <pj/rbtree.h>
+#include <pj/sock.h>
+#include <pj/sock_qos.h>
+#include <pj/sock_select.h>
+#include <pj/ssl_sock.h>
+#include <pj/string.h>
+#include <pj/timer.h>
+#include <pj/unicode.h>
+
+#include <pj/compat/high_precision.h>
+
+#endif /* __PJLIB_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev.h
new file mode 100644
index 0000000..96f62fe
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev.h
@@ -0,0 +1,667 @@
+/* $Id: audiodev.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_AUDIODEV_AUDIODEV_H__
+#define __PJMEDIA_AUDIODEV_AUDIODEV_H__
+
+/**
+ * @file audiodev.h
+ * @brief Audio device API.
+ */
+#include <pjmedia-audiodev/config.h>
+#include <pjmedia-audiodev/errno.h>
+#include <pjmedia/types.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup s2_audio_device_reference Audio Device API Reference
+ * @ingroup audio_device_api
+ * @brief API Reference
+ * @{
+ */
+
+/**
+ * Type for device index.
+ */
+typedef pj_int32_t pjmedia_aud_dev_index;
+
+/**
+ * Device index constants.
+ */
+enum
+{
+ /**
+ * Constant to denote default capture device
+ */
+ PJMEDIA_AUD_DEFAULT_CAPTURE_DEV = -1,
+
+ /**
+ * Constant to denote default playback device
+ */
+ PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV = -2,
+
+ /**
+ * Constant to denote invalid device index.
+ */
+ PJMEDIA_AUD_INVALID_DEV = -3
+};
+
+
+/**
+ * This enumeration identifies various audio device capabilities. These audio
+ * capabilities indicates what features are supported by the underlying
+ * audio device implementation.
+ *
+ * Applications get these capabilities in the #pjmedia_aud_dev_info structure.
+ *
+ * Application can also set the specific features/capabilities when opening
+ * the audio stream by setting the \a flags member of #pjmedia_aud_param
+ * structure.
+ *
+ * Once audio stream is running, application can also retrieve or set some
+ * specific audio capability, by using #pjmedia_aud_stream_get_cap() and
+ * #pjmedia_aud_stream_set_cap() and specifying the desired capability. The
+ * value of the capability is specified as pointer, and application needs to
+ * supply the pointer with the correct value, according to the documentation
+ * of each of the capability.
+ */
+typedef enum pjmedia_aud_dev_cap
+{
+ /**
+ * Support for audio formats other than PCM. The value of this capability
+ * is represented by #pjmedia_format structure.
+ */
+ PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1,
+
+ /**
+ * Support for audio input latency control or query. The value of this
+ * capability is an unsigned integer containing milliseconds value of
+ * the latency.
+ */
+ PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2,
+
+ /**
+ * Support for audio output latency control or query. The value of this
+ * capability is an unsigned integer containing milliseconds value of
+ * the latency.
+ */
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4,
+
+ /**
+ * Support for setting/retrieving the audio input device volume level.
+ * The value of this capability is an unsigned integer representing
+ * the input audio volume setting in percent.
+ */
+ PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8,
+
+ /**
+ * Support for setting/retrieving the audio output device volume level.
+ * The value of this capability is an unsigned integer representing
+ * the output audio volume setting in percent.
+ */
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16,
+
+ /**
+ * Support for monitoring the current audio input signal volume.
+ * The value of this capability is an unsigned integer representing
+ * the audio volume in percent.
+ */
+ PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32,
+
+ /**
+ * Support for monitoring the current audio output signal volume.
+ * The value of this capability is an unsigned integer representing
+ * the audio volume in percent.
+ */
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64,
+
+ /**
+ * Support for audio input routing. The value of this capability is an
+ * integer containing #pjmedia_aud_dev_route enumeration.
+ */
+ PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128,
+
+ /**
+ * Support for audio output routing (e.g. loudspeaker vs earpiece). The
+ * value of this capability is an integer containing #pjmedia_aud_dev_route
+ * enumeration.
+ */
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256,
+
+ /**
+ * The audio device has echo cancellation feature. The value of this
+ * capability is a pj_bool_t containing boolean PJ_TRUE or PJ_FALSE.
+ */
+ PJMEDIA_AUD_DEV_CAP_EC = 512,
+
+ /**
+ * The audio device supports setting echo cancellation fail length. The
+ * value of this capability is an unsigned integer representing the
+ * echo tail in milliseconds.
+ */
+ PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024,
+
+ /**
+ * The audio device has voice activity detection feature. The value
+ * of this capability is a pj_bool_t containing boolean PJ_TRUE or
+ * PJ_FALSE.
+ */
+ PJMEDIA_AUD_DEV_CAP_VAD = 2048,
+
+ /**
+ * The audio device has comfort noise generation feature. The value
+ * of this capability is a pj_bool_t containing boolean PJ_TRUE or
+ * PJ_FALSE.
+ */
+ PJMEDIA_AUD_DEV_CAP_CNG = 4096,
+
+ /**
+ * The audio device has packet loss concealment feature. The value
+ * of this capability is a pj_bool_t containing boolean PJ_TRUE or
+ * PJ_FALSE.
+ */
+ PJMEDIA_AUD_DEV_CAP_PLC = 8192,
+
+ /**
+ * End of capability
+ */
+ PJMEDIA_AUD_DEV_CAP_MAX = 16384
+
+} pjmedia_aud_dev_cap;
+
+
+/**
+ * This enumeration describes audio routing setting.
+ */
+typedef enum pjmedia_aud_dev_route
+{
+ /** Default route. */
+ PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0,
+
+ /** Route to loudspeaker */
+ PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1,
+
+ /** Route to earpiece */
+ PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2
+
+} pjmedia_aud_dev_route;
+
+
+/**
+ * Device information structure returned by #pjmedia_aud_dev_get_info().
+ */
+typedef struct pjmedia_aud_dev_info
+{
+ /**
+ * The device name
+ */
+ char name[64];
+
+ /**
+ * Maximum number of input channels supported by this device. If the
+ * value is zero, the device does not support input operation (i.e.
+ * it is a playback only device).
+ */
+ unsigned input_count;
+
+ /**
+ * Maximum number of output channels supported by this device. If the
+ * value is zero, the device does not support output operation (i.e.
+ * it is an input only device).
+ */
+ unsigned output_count;
+
+ /**
+ * Default sampling rate.
+ */
+ unsigned default_samples_per_sec;
+
+ /**
+ * The underlying driver name
+ */
+ char driver[32];
+
+ /**
+ * Device capabilities, as bitmask combination of #pjmedia_aud_dev_cap.
+ */
+ unsigned caps;
+
+ /**
+ * Supported audio device routes, as bitmask combination of
+ * #pjmedia_aud_dev_route. The value may be zero if the device
+ * does not support audio routing.
+ */
+ unsigned routes;
+
+ /**
+ * Number of audio formats supported by this device. The value may be
+ * zero if the device does not support non-PCM format.
+ */
+ unsigned ext_fmt_cnt;
+
+ /**
+ * Array of supported extended audio formats
+ */
+ pjmedia_format ext_fmt[8];
+
+
+} pjmedia_aud_dev_info;
+
+
+/**
+ * This callback is called by player stream when it needs additional data
+ * to be played by the device. Application must fill in the whole of output
+ * buffer with audio samples.
+ *
+ * The frame argument contains the following values:
+ * - timestamp Playback timestamp, in samples.
+ * - buf Buffer to be filled out by application.
+ * - size The size requested in bytes, which will be equal to
+ * the size of one whole packet.
+ *
+ * @param user_data User data associated with the stream.
+ * @param frame Audio frame, which buffer is to be filled in by
+ * the application.
+ *
+ * @return Returning non-PJ_SUCCESS will cause the audio stream
+ * to stop
+ */
+typedef pj_status_t (*pjmedia_aud_play_cb)(void *user_data,
+ pjmedia_frame *frame);
+
+/**
+ * This callback is called by recorder stream when it has captured the whole
+ * packet worth of audio samples.
+ *
+ * @param user_data User data associated with the stream.
+ * @param frame Captured frame.
+ *
+ * @return Returning non-PJ_SUCCESS will cause the audio stream
+ * to stop
+ */
+typedef pj_status_t (*pjmedia_aud_rec_cb)(void *user_data,
+ pjmedia_frame *frame);
+
+/**
+ * This structure specifies the parameters to open the audio stream.
+ */
+typedef struct pjmedia_aud_param
+{
+ /**
+ * The audio direction. This setting is mandatory.
+ */
+ pjmedia_dir dir;
+
+ /**
+ * The audio recorder device ID. This setting is mandatory if the audio
+ * direction includes input/capture direction.
+ */
+ pjmedia_aud_dev_index rec_id;
+
+ /**
+ * The audio playback device ID. This setting is mandatory if the audio
+ * direction includes output/playback direction.
+ */
+ pjmedia_aud_dev_index play_id;
+
+ /**
+ * Clock rate/sampling rate. This setting is mandatory.
+ */
+ unsigned clock_rate;
+
+ /**
+ * Number of channels. This setting is mandatory.
+ */
+ unsigned channel_count;
+
+ /**
+ * Number of samples per frame. This setting is mandatory.
+ */
+ unsigned samples_per_frame;
+
+ /**
+ * Number of bits per sample. This setting is mandatory.
+ */
+ unsigned bits_per_sample;
+
+ /**
+ * This flags specifies which of the optional settings are valid in this
+ * structure. The flags is bitmask combination of pjmedia_aud_dev_cap.
+ */
+ unsigned flags;
+
+ /**
+ * Set the audio format. This setting is optional, and will only be used
+ * if PJMEDIA_AUD_DEV_CAP_EXT_FORMAT is set in the flags.
+ */
+ pjmedia_format ext_fmt;
+
+ /**
+ * Input latency, in milliseconds. This setting is optional, and will
+ * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY is set in the flags.
+ */
+ unsigned input_latency_ms;
+
+ /**
+ * Input latency, in milliseconds. This setting is optional, and will
+ * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY is set in the flags.
+ */
+ unsigned output_latency_ms;
+
+ /**
+ * Input volume setting, in percent. This setting is optional, and will
+ * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING is set in
+ * the flags.
+ */
+ unsigned input_vol;
+
+ /**
+ * Output volume setting, in percent. This setting is optional, and will
+ * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING is set in
+ * the flags.
+ */
+ unsigned output_vol;
+
+ /**
+ * Set the audio input route. This setting is optional, and will only be
+ * used if PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE is set in the flags.
+ */
+ pjmedia_aud_dev_route input_route;
+
+ /**
+ * Set the audio output route. This setting is optional, and will only be
+ * used if PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE is set in the flags.
+ */
+ pjmedia_aud_dev_route output_route;
+
+ /**
+ * Enable/disable echo canceller, if the device supports it. This setting
+ * is optional, and will only be used if PJMEDIA_AUD_DEV_CAP_EC is set in
+ * the flags.
+ */
+ pj_bool_t ec_enabled;
+
+ /**
+ * Set echo canceller tail length in milliseconds, if the device supports
+ * it. This setting is optional, and will only be used if
+ * PJMEDIA_AUD_DEV_CAP_EC_TAIL is set in the flags.
+ */
+ unsigned ec_tail_ms;
+
+ /**
+ * Enable/disable PLC. This setting is optional, and will only be used
+ * if PJMEDIA_AUD_DEV_CAP_PLC is set in the flags.
+ */
+ pj_bool_t plc_enabled;
+
+ /**
+ * Enable/disable CNG. This setting is optional, and will only be used
+ * if PJMEDIA_AUD_DEV_CAP_CNG is set in the flags.
+ */
+ pj_bool_t cng_enabled;
+
+} pjmedia_aud_param;
+
+
+/** Forward declaration for pjmedia_aud_stream */
+typedef struct pjmedia_aud_stream pjmedia_aud_stream;
+
+/** Forward declaration for audio device factory */
+typedef struct pjmedia_aud_dev_factory pjmedia_aud_dev_factory;
+
+/**
+ * Get string info for the specified capability.
+ *
+ * @param cap The capability ID.
+ * @param p_desc Optional pointer which will be filled with longer
+ * description about the capability.
+ *
+ * @return Capability name.
+ */
+PJ_DECL(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
+ const char **p_desc);
+
+
+/**
+ * Set a capability field value in #pjmedia_aud_param structure. This will
+ * also set the flags field for the specified capability in the structure.
+ *
+ * @param param The structure.
+ * @param cap The audio capability which value is to be set.
+ * @param value Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_param_set_cap(pjmedia_aud_param *param,
+ pjmedia_aud_dev_cap cap,
+ const void *pval);
+
+
+/**
+ * Get a capability field value from #pjmedia_aud_param structure. This
+ * function will return PJMEDIA_EAUD_INVCAP error if the flag for that
+ * capability is not set in the flags field in the structure.
+ *
+ * @param param The structure.
+ * @param cap The audio capability which value is to be retrieved.
+ * @param value Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_param_get_cap(const pjmedia_aud_param *param,
+ pjmedia_aud_dev_cap cap,
+ void *pval);
+
+/**
+ * Initialize the audio subsystem. This will register all supported audio
+ * device factories to the audio subsystem. This function may be called
+ * more than once, but each call to this function must have the
+ * corresponding #pjmedia_aud_subsys_shutdown() call.
+ *
+ * @param pf The pool factory.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_subsys_init(pj_pool_factory *pf);
+
+
+/**
+ * Get the pool factory registered to the audio subsystem.
+ *
+ * @return The pool factory.
+ */
+PJ_DECL(pj_pool_factory*) pjmedia_aud_subsys_get_pool_factory(void);
+
+
+/**
+ * Shutdown the audio subsystem. This will destroy all audio device factories
+ * registered in the audio subsystem. Note that currently opened audio streams
+ * may or may not be closed, depending on the implementation of the audio
+ * device factories.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_subsys_shutdown(void);
+
+
+/**
+ * Get the number of sound devices installed in the system.
+ *
+ * @return The number of sound devices installed in the system.
+ */
+PJ_DECL(unsigned) pjmedia_aud_dev_count(void);
+
+
+/**
+ * Get device information.
+ *
+ * @param id The audio device ID.
+ * @param info The device information which will be filled in by this
+ * function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,
+ pjmedia_aud_dev_info *info);
+
+
+/**
+ * Lookup device index based on the driver and device name.
+ *
+ * @param drv_name The driver name.
+ * @param dev_name The device name.
+ * @param id Pointer to store the returned device ID.
+ *
+ * @return PJ_SUCCESS if the device can be found.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_lookup(const char *drv_name,
+ const char *dev_name,
+ pjmedia_aud_dev_index *id);
+
+
+/**
+ * Initialize the audio device parameters with default values for the
+ * specified device.
+ *
+ * @param id The audio device ID.
+ * @param param The audio device parameters which will be initialized
+ * by this function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,
+ pjmedia_aud_param *param);
+
+
+/**
+ * Open audio stream object using the specified parameters.
+ *
+ * @param param Sound device parameters to be used for the stream.
+ * @param rec_cb Callback to be called on every input frame captured.
+ * @param play_cb Callback to be called everytime the sound device needs
+ * audio frames to be played back.
+ * @param user_data Arbitrary user data, which will be given back in the
+ * callbacks.
+ * @param p_strm Pointer to receive the audio stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *param,
+ pjmedia_aud_rec_cb rec_cb,
+ pjmedia_aud_play_cb play_cb,
+ void *user_data,
+ pjmedia_aud_stream **p_strm);
+
+/**
+ * Get the running parameters for the specified audio stream.
+ *
+ * @param strm The audio stream.
+ * @param param Audio stream parameters to be filled in by this
+ * function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,
+ pjmedia_aud_param *param);
+
+/**
+ * Get the value of a specific capability of the audio stream.
+ *
+ * @param strm The audio stream.
+ * @param cap The audio capability which value is to be retrieved.
+ * @param value Pointer to value to be filled in by this function
+ * once it returns successfully. Please see the type
+ * of value to be supplied in the pjmedia_aud_dev_cap
+ * documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm,
+ pjmedia_aud_dev_cap cap,
+ void *value);
+
+/**
+ * Set the value of a specific capability of the audio stream.
+ *
+ * @param strm The audio stream.
+ * @param cap The audio capability which value is to be set.
+ * @param value Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm,
+ pjmedia_aud_dev_cap cap,
+ const void *value);
+
+/**
+ * Start the stream.
+ *
+ * @param strm The audio stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm);
+
+/**
+ * Stop the stream.
+ *
+ * @param strm The audio stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm);
+
+/**
+ * Destroy the stream.
+ *
+ * @param strm The audio stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_AUDIODEV_AUDIODEV_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev_imp.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev_imp.h
new file mode 100644
index 0000000..c7d6933
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev_imp.h
@@ -0,0 +1,181 @@
+/* $Id: audiodev_imp.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __AUDIODEV_IMP_H__
+#define __AUDIODEV_IMP_H__
+
+#include <pjmedia-audiodev/audiodev.h>
+
+/**
+ * @defgroup s8_audio_device_implementors_api Audio Device Implementors API
+ * @ingroup audio_device_api
+ * @brief API for audio device implementors
+ * @{
+ */
+
+/**
+ * Sound device factory operations.
+ */
+typedef struct pjmedia_aud_dev_factory_op
+{
+ /**
+ * Initialize the audio device factory.
+ *
+ * @param f The audio device factory.
+ */
+ pj_status_t (*init)(pjmedia_aud_dev_factory *f);
+
+ /**
+ * Close this audio device factory and release all resources back to the
+ * operating system.
+ *
+ * @param f The audio device factory.
+ */
+ pj_status_t (*destroy)(pjmedia_aud_dev_factory *f);
+
+ /**
+ * Get the number of audio devices installed in the system.
+ *
+ * @param f The audio device factory.
+ */
+ unsigned (*get_dev_count)(pjmedia_aud_dev_factory *f);
+
+ /**
+ * Get the audio device information and capabilities.
+ *
+ * @param f The audio device factory.
+ * @param index Device index.
+ * @param info The audio device information structure which will be
+ * initialized by this function once it returns
+ * successfully.
+ */
+ pj_status_t (*get_dev_info)(pjmedia_aud_dev_factory *f,
+ unsigned index,
+ pjmedia_aud_dev_info *info);
+
+ /**
+ * Initialize the specified audio device parameter with the default
+ * values for the specified device.
+ *
+ * @param f The audio device factory.
+ * @param index Device index.
+ * @param param The audio device parameter.
+ */
+ pj_status_t (*default_param)(pjmedia_aud_dev_factory *f,
+ unsigned index,
+ pjmedia_aud_param *param);
+
+ /**
+ * Open the audio device and create audio stream. See
+ * #pjmedia_aud_stream_create()
+ */
+ pj_status_t (*create_stream)(pjmedia_aud_dev_factory *f,
+ const pjmedia_aud_param *param,
+ pjmedia_aud_rec_cb rec_cb,
+ pjmedia_aud_play_cb play_cb,
+ void *user_data,
+ pjmedia_aud_stream **p_aud_strm);
+
+} pjmedia_aud_dev_factory_op;
+
+
+/**
+ * This structure describes an audio device factory.
+ */
+struct pjmedia_aud_dev_factory
+{
+ /** Internal data to be initialized by audio subsystem. */
+ struct {
+ /** Driver index */
+ unsigned drv_idx;
+ } sys;
+
+ /** Operations */
+ pjmedia_aud_dev_factory_op *op;
+};
+
+
+/**
+ * Sound stream operations.
+ */
+typedef struct pjmedia_aud_stream_op
+{
+ /**
+ * See #pjmedia_aud_stream_get_param()
+ */
+ pj_status_t (*get_param)(pjmedia_aud_stream *strm,
+ pjmedia_aud_param *param);
+
+ /**
+ * See #pjmedia_aud_stream_get_cap()
+ */
+ pj_status_t (*get_cap)(pjmedia_aud_stream *strm,
+ pjmedia_aud_dev_cap cap,
+ void *value);
+
+ /**
+ * See #pjmedia_aud_stream_set_cap()
+ */
+ pj_status_t (*set_cap)(pjmedia_aud_stream *strm,
+ pjmedia_aud_dev_cap cap,
+ const void *value);
+
+ /**
+ * See #pjmedia_aud_stream_start()
+ */
+ pj_status_t (*start)(pjmedia_aud_stream *strm);
+
+ /**
+ * See #pjmedia_aud_stream_stop().
+ */
+ pj_status_t (*stop)(pjmedia_aud_stream *strm);
+
+ /**
+ * See #pjmedia_aud_stream_destroy().
+ */
+ pj_status_t (*destroy)(pjmedia_aud_stream *strm);
+
+} pjmedia_aud_stream_op;
+
+
+/**
+ * This structure describes the audio device stream.
+ */
+struct pjmedia_aud_stream
+{
+ /** Internal data to be initialized by audio subsystem */
+ struct {
+ /** Driver index */
+ unsigned drv_idx;
+ } sys;
+
+ /** Operations */
+ pjmedia_aud_stream_op *op;
+};
+
+
+
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __AUDIODEV_IMP_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiotest.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiotest.h
new file mode 100644
index 0000000..eb8c749
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiotest.h
@@ -0,0 +1,116 @@
+/* $Id: audiotest.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_AUDIODEV_AUDIOTEST_H__
+#define __PJMEDIA_AUDIODEV_AUDIOTEST_H__
+
+/**
+ * @file audiotest.h
+ * @brief Audio test utility.
+ */
+#include <pjmedia-audiodev/audiodev.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup s30_audio_test_utility Audio tests utility.
+ * @ingroup audio_device_api
+ * @brief Audio test utility.
+ * @{
+ */
+
+/**
+ * Statistic for each direction.
+ */
+typedef struct pjmedia_aud_test_stat
+{
+ /**
+ * Number of frames processed during the test.
+ */
+ unsigned frame_cnt;
+
+ /**
+ * Minimum inter-frame arrival time, in milliseconds
+ */
+ unsigned min_interval;
+
+ /**
+ * Maximum inter-frame arrival time, in milliseconds
+ */
+ unsigned max_interval;
+
+ /**
+ * Average inter-frame arrival time, in milliseconds
+ */
+ unsigned avg_interval;
+
+ /**
+ * Standard deviation of inter-frame arrival time, in milliseconds
+ */
+ unsigned dev_interval;
+
+ /**
+ * Maximum number of frame burst
+ */
+ unsigned max_burst;
+
+} pjmedia_aud_test_stat;
+
+
+/**
+ * Test results.
+ */
+typedef struct pjmedia_aud_test_results
+{
+ /**
+ * Recording statistic.
+ */
+ pjmedia_aud_test_stat rec;
+
+ /**
+ * Playback statistic.
+ */
+ pjmedia_aud_test_stat play;
+
+ /**
+ * Clock drifts per second, in samples. Positive number indicates rec
+ * device is running faster than playback device.
+ */
+ pj_int32_t rec_drift_per_sec;
+
+} pjmedia_aud_test_results;
+
+
+/**
+ * Perform audio device testing.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_test(const pjmedia_aud_param *param,
+ pjmedia_aud_test_results *result);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_AUDIODEV_AUDIOTEST_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/config.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/config.h
new file mode 100644
index 0000000..271b94c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/config.h
@@ -0,0 +1,394 @@
+/* $Id: config.h 2977 2009-10-29 09:39:17Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_AUDIODEV_CONFIG_H__
+#define __PJMEDIA_AUDIODEV_CONFIG_H__
+
+/**
+ * @file audiodev.h
+ * @brief Audio device API.
+ */
+#include <pjmedia/types.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup audio_device_api Audio Device API
+ * @brief PJMEDIA audio device abstraction API.
+ */
+
+/**
+ * @defgroup s1_audio_device_config Compile time configurations
+ * @ingroup audio_device_api
+ * @brief Compile time configurations
+ * @{
+ */
+
+/**
+ * This setting controls whether PortAudio support should be included.
+ *
+ * By default it is enabled except on Windows platforms (including
+ * Windows Mobile) and Symbian.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
+# if (defined(PJ_WIN32) && PJ_WIN32!=0) || \
+ (defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0)
+# define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
+# else
+# define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 1
+# endif
+#endif
+
+
+/**
+ * This setting controls whether WMME support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_WMME
+# define PJMEDIA_AUDIO_DEV_HAS_WMME 1
+#endif
+
+
+/**
+ * This setting controls whether Symbian APS support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_SYMB_APS
+# define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 0
+#endif
+
+
+/**
+ * This setting controls whether Symbian VAS support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS
+# define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 0
+#endif
+
+/**
+ * This setting controls Symbian VAS version to be used. Currently, valid
+ * values are only 1 (for VAS 1.0) and 2 (for VAS 2.0).
+ *
+ * Default: 1 (VAS version 1.0)
+ */
+#ifndef PJMEDIA_AUDIO_DEV_SYMB_VAS_VERSION
+# define PJMEDIA_AUDIO_DEV_SYMB_VAS_VERSION 1
+#endif
+
+
+/**
+ * This setting controls whether Symbian audio (using built-in multimedia
+ * framework) support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA
+# define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA PJ_SYMBIAN
+#endif
+
+
+/**
+ * This setting controls whether the Audio Device API should support
+ * device implementation that is based on the old sound device API
+ * (sound.h).
+ *
+ * Enable this API if:
+ * - you have implemented your own sound device using the old sound
+ * device API (sound.h), and
+ * - you wish to be able to use your sound device implementation
+ * using the new Audio Device API.
+ *
+ * Please see http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more
+ * info.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_LEGACY_DEVICE
+# define PJMEDIA_AUDIO_DEV_HAS_LEGACY_DEVICE 0
+#endif
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_AUDIODEV_CONFIG_H__ */
+
+/*
+ --------------------- DOCUMENTATION FOLLOWS ---------------------------
+ */
+
+/**
+ * @addtogroup audio_device_api Audio Device API
+ * @{
+
+PJMEDIA Audio Device API is a cross-platform audio API appropriate for use with
+VoIP applications and many other types of audio streaming applications.
+
+The API abstracts many different audio API's on various platforms, such as:
+ - PortAudio back-end for Win32, Windows Mobile, Linux, Unix, dan MacOS X.
+ - native WMME audio for Win32 and Windows Mobile devices
+ - native Symbian audio streaming/multimedia framework (MMF) implementation
+ - native Nokia Audio Proxy Server (APS) implementation
+ - null-audio implementation
+ - and more to be implemented in the future
+
+The Audio Device API/library is an evolution from PJMEDIA @ref PJMED_SND and
+contains many enhancements:
+
+ - Forward compatibility:
+\n
+ The new API has been designed to be extensible, it will support new API's as
+ well as new features that may be introduced in the future without breaking
+ compatibility with applications that use this API as well as compatibility
+ with existing device implementations.
+
+ - Device capabilities:
+\n
+ At the heart of the API is device capabilities management, where all possible
+ audio capabilities of audio devices should be able to be handled in a generic
+ manner. With this framework, new capabilities that may be discovered in the
+ future can be handled in manner without breaking existing applications.
+
+ - Built-in features:
+\n
+ The device capabilities framework enables applications to use and control
+ audio features built-in in the device, such as:
+ - echo cancellation,
+ - built-in codecs,
+ - audio routing (e.g. to earpiece or loudspeaker),
+ - volume control,
+ - etc.
+
+ - Codec support:
+\n
+ Some audio devices such as Nokia/Symbian Audio Proxy Server (APS) and Nokia
+ VoIP Audio Services (VAS) support built-in hardware audio codecs (e.g. G.729,
+ iLBC, and AMR), and application can use the sound device in encoded mode to
+ make use of these hardware codecs.
+
+ - Multiple backends:
+\n
+ The new API supports multiple audio backends (called factories or drivers in
+ the code) to be active simultaneously, and audio backends may be added or
+ removed during run-time.
+
+
+@section using Overview on using the API
+
+@subsection getting_started Getting started
+
+ -# <b>Configure the application's project settings</b>.\n
+ Add the following
+ include:
+ \code
+ #include <pjmedia_audiodev.h>\endcode\n
+ And add <b>pjmedia-audiodev</b> library to your application link
+ specifications.\n
+ -# <b>Compile time settings</b>.\n
+ Use the compile time settings to enable or
+ disable specific audio drivers. For more information, please see
+ \ref s1_audio_device_config.
+ -# <b>API initialization and cleaning up</b>.\n
+ Before anything else, application must initialize the API by calling:
+ \code
+ pjmedia_aud_subsys_init(pf);\endcode\n
+ And add this in the application cleanup sequence
+ \code
+ pjmedia_aud_subsys_shutdown();\endcode
+
+@subsection devices Working with devices
+
+ -# The following code prints the list of audio devices detected
+ in the system.
+ \code
+ int dev_count;
+ pjmedia_aud_dev_index dev_idx;
+ pj_status_t status;
+
+ dev_count = pjmedia_aud_dev_count();
+ printf("Got %d audio devices\n", dev_count);
+
+ for (dev_idx=0; dev_idx<dev_count; ++i) {
+ pjmedia_aud_dev_info info;
+
+ status = pjmedia_aud_dev_get_info(dev_idx, &info);
+ printf("%d. %s (in=%d, out=%d)\n",
+ dev_idx, info.name,
+ info.input_count, info.output_count);
+ }
+ \endcode\n
+ -# Info: The #PJMEDIA_AUD_DEFAULT_CAPTURE_DEV and #PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV
+ constants are used to denote default capture and playback devices
+ respectively.
+ -# Info: You may save the device and driver's name in your application
+ setting, for example to specify the prefered devices to be
+ used by your application. You can then retrieve the device index
+ for the device by calling:
+ \code
+ const char *drv_name = "WMME";
+ const char *dev_name = "Wave mapper";
+ pjmedia_aud_dev_index dev_idx;
+
+ status = pjmedia_aud_dev_lookup(drv_name, dev_name, &dev_idx);
+ if (status==PJ_SUCCESS)
+ printf("Device index is %d\n", dev_idx);
+ \endcode
+
+@subsection caps Device capabilities
+
+Capabilities are encoded as #pjmedia_aud_dev_cap enumeration. Please see
+#pjmedia_aud_dev_cap enumeration for more information.
+
+ -# The following snippet prints the capabilities supported by the device:
+ \code
+ pjmedia_aud_dev_info info;
+ pj_status_t status;
+
+ status = pjmedia_aud_dev_get_info(PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, &info);
+ if (status == PJ_SUCCESS) {
+ unsigned i;
+ // Enumerate capability bits
+ printf("Device capabilities: ");
+ for (i=0; i<32; ++i) {
+ if (info.caps & (1 << i))
+ printf("%s ", pjmedia_aud_dev_cap_name(1 << i, NULL));
+ }
+ }
+ \endcode\n
+ -# Info: You can set the device settings when opening audio stream by setting
+ the flags and the appropriate setting in #pjmedia_aud_param when calling
+ #pjmedia_aud_stream_create()\n
+ -# Info: Once the audio stream is running, you can retrieve or change the stream
+ setting by specifying the capability in #pjmedia_aud_stream_get_cap()
+ and #pjmedia_aud_stream_set_cap() respectively.
+
+
+@subsection creating_stream Creating audio streams
+
+The audio stream enables audio streaming to capture device, playback device,
+or both.
+
+ -# It is recommended to initialize the #pjmedia_aud_param with its default
+ values before using it:
+ \code
+ pjmedia_aud_param param;
+ pjmedia_aud_dev_index dev_idx;
+ pj_status_t status;
+
+ dev_idx = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
+ status = pjmedia_aud_dev_default_param(dev_idx, &param);
+ \endcode\n
+ -# Configure the mandatory parameters:
+ \code
+ param.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
+ param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
+ param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
+ param.clock_rate = 8000;
+ param.channel_count = 1;
+ param.samples_per_frame = 160;
+ param.bits_per_sample = 16;
+ \endcode\n
+ -# If you want the audio stream to use the device's built-in codec, specify
+ the codec in the #pjmedia_aud_param. You must make sure that the codec
+ is supported by the device, by looking at its supported format list in
+ the #pjmedia_aud_dev_info.\n
+ The snippet below sets the audio stream to use G.711 ULAW encoding:
+ \code
+ unsigned i;
+
+ // Make sure Ulaw is supported
+ if ((info.caps & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) == 0)
+ error("Device does not support extended formats");
+ for (i = 0; i < info.ext_fmt_cnt; ++i) {
+ if (info.ext_fmt[i].id == PJMEDIA_FORMAT_ULAW)
+ break;
+ }
+ if (i == info.ext_fmt_cnt)
+ error("Device does not support Ulaw format");
+
+ // Set Ulaw format
+ param.flags |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT;
+ param.ext_fmt.id = PJMEDIA_FORMAT_ULAW;
+ param.ext_fmt.bitrate = 64000;
+ param.ext_fmt.vad = PJ_FALSE;
+ \endcode\n
+ -# Note that if non-PCM format is configured on the audio stream, the
+ capture and/or playback functions (#pjmedia_aud_rec_cb and
+ #pjmedia_aud_play_cb respectively) will report the audio frame as
+ #pjmedia_frame_ext structure instead of the #pjmedia_frame.
+ -# Optionally configure other device's capabilities. The following snippet
+ shows how to enable echo cancellation on the device (note that this
+ snippet may not be necessary since the setting may have been enabled
+ when calling #pjmedia_aud_dev_default_param() above):
+ \code
+ if (info.caps & PJMEDIA_AUD_DEV_CAP_EC) {
+ param.flags |= PJMEDIA_AUD_DEV_CAP_EC;
+ param.ec_enabled = PJ_TRUE;
+ }
+ \endcode
+ -# Open the audio stream, specifying the capture and/or playback callback
+ functions:
+ \code
+ pjmedia_aud_stream *stream;
+
+ status = pjmedia_aud_stream_create(&param, &rec_cb, &play_cb,
+ user_data, &stream);
+ \endcode
+
+@subsection working_with_stream Working with audio streams
+
+ -# To start the audio stream:
+ \code
+ status = pjmedia_aud_stream_start(stream);
+ \endcode\n
+ To stop the stream:
+ \code
+ status = pjmedia_aud_stream_stop(stream);
+ \endcode\n
+ And to destroy the stream:
+ \code
+ status = pjmedia_aud_stream_destroy(stream);
+ \endcode\n
+ -# Info: The following shows how to retrieve the capability value of the
+ stream (in this case, the current output volume setting).
+ \code
+ // Volume setting is an unsigned integer showing the level in percent.
+ unsigned vol;
+ status = pjmedia_aud_stream_get_cap(stream,
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
+ &vol);
+ \endcode
+ -# Info: And following shows how to modify the capability value of the
+ stream (in this case, the current output volume setting).
+ \code
+ // Volume setting is an unsigned integer showing the level in percent.
+ unsigned vol = 50;
+ status = pjmedia_aud_stream_set_cap(stream,
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
+ &vol);
+ \endcode
+
+
+*/
+
+
+/**
+ * @}
+ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/errno.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/errno.h
new file mode 100644
index 0000000..ada9f87
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/errno.h
@@ -0,0 +1,198 @@
+/* $Id: errno.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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 __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__
+#define __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__
+
+/**
+ * @file errno.h Error Codes
+ * @brief Audiodev specific error codes.
+ */
+
+#include <pjmedia-audiodev/config.h>
+#include <pj/errno.h>
+
+/**
+ * @defgroup error_codes Error Codes
+ * @ingroup audio_device_api
+ * @brief Audio devive library specific error codes.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ * This value is 420000.
+ */
+#define PJMEDIA_AUDIODEV_ERRNO_START \
+ (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*5)
+#define PJMEDIA_AUDIODEV_ERRNO_END \
+ (PJMEDIA_AUDIODEV_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1)
+
+
+/**
+ * Mapping from PortAudio error codes to pjmedia error space.
+ */
+#define PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START \
+ (PJMEDIA_AUDIODEV_ERRNO_END-10000)
+#define PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_END \
+ (PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START + 10000 -1)
+/**
+ * Convert PortAudio error code to PJLIB error code.
+ * PortAudio error code range: 0 >= err >= -10000
+ */
+#define PJMEDIA_AUDIODEV_ERRNO_FROM_PORTAUDIO(err) \
+ ((int)PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START-err)
+
+/**
+ * Mapping from Windows multimedia WaveIn error codes.
+ */
+#define PJMEDIA_AUDIODEV_WMME_IN_ERROR_START \
+ (PJMEDIA_AUDIODEV_ERRNO_START + 30000)
+#define PJMEDIA_AUDIODEV_WMME_IN_ERROR_END \
+ (PJMEDIA_AUDIODEV_WMME_IN_ERROR_START + 1000 - 1)
+/**
+ * Convert WaveIn operation error codes to PJLIB error space.
+ */
+#define PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(err) \
+ ((int)PJMEDIA_AUDIODEV_WMME_IN_ERROR_START+err)
+
+
+/**
+ * Mapping from Windows multimedia WaveOut error codes.
+ */
+#define PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START \
+ (PJMEDIA_AUDIODEV_WMME_IN_ERROR_END + 1000)
+#define PJMEDIA_AUDIODEV_WMME_OUT_ERROR_END \
+ (PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START + 1000)
+/**
+ * Convert WaveOut operation error codes to PJLIB error space.
+ */
+#define PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(err) \
+ ((int)PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START+err)
+
+
+/************************************************************
+ * Audio Device API error codes
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General/unknown error.
+ */
+#define PJMEDIA_EAUD_ERR (PJMEDIA_AUDIODEV_ERRNO_START+1) /* 420001 */
+
+/**
+ * @hideinitializer
+ * Unknown error from audio driver
+ */
+#define PJMEDIA_EAUD_SYSERR (PJMEDIA_AUDIODEV_ERRNO_START+2) /* 420002 */
+
+/**
+ * @hideinitializer
+ * Audio subsystem not initialized
+ */
+#define PJMEDIA_EAUD_INIT (PJMEDIA_AUDIODEV_ERRNO_START+3) /* 420003 */
+
+/**
+ * @hideinitializer
+ * Invalid audio device
+ */
+#define PJMEDIA_EAUD_INVDEV (PJMEDIA_AUDIODEV_ERRNO_START+4) /* 420004 */
+
+/**
+ * @hideinitializer
+ * Found no devices
+ */
+#define PJMEDIA_EAUD_NODEV (PJMEDIA_AUDIODEV_ERRNO_START+5) /* 420005 */
+
+/**
+ * @hideinitializer
+ * Unable to find default device
+ */
+#define PJMEDIA_EAUD_NODEFDEV (PJMEDIA_AUDIODEV_ERRNO_START+6) /* 420006 */
+
+/**
+ * @hideinitializer
+ * Device not ready
+ */
+#define PJMEDIA_EAUD_NOTREADY (PJMEDIA_AUDIODEV_ERRNO_START+7) /* 420007 */
+
+/**
+ * @hideinitializer
+ * The audio capability is invalid or not supported
+ */
+#define PJMEDIA_EAUD_INVCAP (PJMEDIA_AUDIODEV_ERRNO_START+8) /* 420008 */
+
+/**
+ * @hideinitializer
+ * The operation is invalid or not supported
+ */
+#define PJMEDIA_EAUD_INVOP (PJMEDIA_AUDIODEV_ERRNO_START+9) /* 420009 */
+
+/**
+ * @hideinitializer
+ * Bad or invalid audio device format
+ */
+#define PJMEDIA_EAUD_BADFORMAT (PJMEDIA_AUDIODEV_ERRNO_START+10) /* 4200010 */
+
+/**
+ * @hideinitializer
+ * Invalid audio device sample format
+ */
+#define PJMEDIA_EAUD_SAMPFORMAT (PJMEDIA_AUDIODEV_ERRNO_START+11) /* 4200011 */
+
+/**
+ * @hideinitializer
+ * Bad latency setting
+ */
+#define PJMEDIA_EAUD_BADLATENCY (PJMEDIA_AUDIODEV_ERRNO_START+12) /* 4200012 */
+
+
+
+
+
+/**
+ * Get error message for the specified error code. Note that this
+ * function is only able to decode PJMEDIA Audiodev specific error code.
+ * Application should use pj_strerror(), which should be able to
+ * decode all error codes belonging to all subsystems (e.g. pjlib,
+ * pjmedia, pjsip, etc).
+ *
+ * @param status The error code.
+ * @param buffer The buffer where to put the error message.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pjmedia_audiodev_strerror(pj_status_t status, char *buffer,
+ pj_size_t bufsize);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec.h
new file mode 100644
index 0000000..9bc852b
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec.h
@@ -0,0 +1,39 @@
+/* $Id: pjmedia-codec.h 2563 2009-04-01 12:05:34Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_PJMEDIA_CODEC_H__
+#define __PJMEDIA_CODEC_PJMEDIA_CODEC_H__
+
+/**
+ * @file pjmedia-codec.h
+ * @brief Include all codecs API in PJMEDIA-CODEC
+ */
+
+#include <pjmedia-codec/l16.h>
+#include <pjmedia-codec/gsm.h>
+#include <pjmedia-codec/speex.h>
+#include <pjmedia-codec/ilbc.h>
+#include <pjmedia-codec/g722.h>
+#include <pjmedia-codec/g7221.h>
+#include <pjmedia-codec/ipp_codecs.h>
+#include <pjmedia-codec/passthrough.h>
+
+
+#endif /* __PJMEDIA_CODEC_PJMEDIA_CODEC_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/amr_helper.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/amr_helper.h
new file mode 100644
index 0000000..bbb5aea
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/amr_helper.h
@@ -0,0 +1,1222 @@
+/* $Id: amr_helper.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODECS_AMR_HELPER_H__
+#define __PJMEDIA_CODECS_AMR_HELPER_H__
+
+/**
+ * @file pjmedia-codec/amr_helper.h
+ * @brief Common tables and helper functions for AMR codec (NB & WB).
+ */
+
+
+#ifdef _MSC_VER
+# pragma warning(disable:4214) // bit field types other than int
+#endif
+
+/**
+ * @defgroup PJMED_AMR_CODEC_HELPER AMR Codec Helper
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief AMR common tables and helper functions.
+ * @{
+ *
+ * This sections describes common AMR constants tables (e.g: bits sensitivity
+ * order map, frame lengths, bitrates) and helper functions (e.g: pack AMR
+ * payload in octet-aligned mode or bandwidth-efficient mode, payload parser,
+ * reorder AMR bitstream).
+ */
+
+PJ_BEGIN_DECL
+
+
+/* AMR bits sensitivity order maps */
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap122[244] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 23, 15, 16, 17, 18,
+ 19, 20, 21, 22, 24, 25, 26, 27, 28, 38,
+ 141, 39, 142, 40, 143, 41, 144, 42, 145, 43,
+ 146, 44, 147, 45, 148, 46, 149, 47, 97, 150,
+ 200, 48, 98, 151, 201, 49, 99, 152, 202, 86,
+ 136, 189, 239, 87, 137, 190, 240, 88, 138, 191,
+ 241, 91, 194, 92, 195, 93, 196, 94, 197, 95,
+ 198, 29, 30, 31, 32, 33, 34, 35, 50, 100,
+ 153, 203, 89, 139, 192, 242, 51, 101, 154, 204,
+ 55, 105, 158, 208, 90, 140, 193, 243, 59, 109,
+ 162, 212, 63, 113, 166, 216, 67, 117, 170, 220,
+ 36, 37, 54, 53, 52, 58, 57, 56, 62, 61,
+ 60, 66, 65, 64, 70, 69, 68, 104, 103, 102,
+ 108, 107, 106, 112, 111, 110, 116, 115, 114, 120,
+ 119, 118, 157, 156, 155, 161, 160, 159, 165, 164,
+ 163, 169, 168, 167, 173, 172, 171, 207, 206, 205,
+ 211, 210, 209, 215, 214, 213, 219, 218, 217, 223,
+ 222, 221, 73, 72, 71, 76, 75, 74, 79, 78,
+ 77, 82, 81, 80, 85, 84, 83, 123, 122, 121,
+ 126, 125, 124, 129, 128, 127, 132, 131, 130, 135,
+ 134, 133, 176, 175, 174, 179, 178, 177, 182, 181,
+ 180, 185, 184, 183, 188, 187, 186, 226, 225, 224,
+ 229, 228, 227, 232, 231, 230, 235, 234, 233, 238,
+ 237, 236, 96, 199
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap102[204] =
+{
+ 7, 6, 5, 4, 3, 2, 1, 0, 16, 15,
+ 14, 13, 12, 11, 10, 9, 8, 26, 27, 28,
+ 29, 30, 31, 115, 116, 117, 118, 119, 120, 72,
+ 73, 161, 162, 65, 68, 69, 108, 111, 112, 154,
+ 157, 158, 197, 200, 201, 32, 33, 121, 122, 74,
+ 75, 163, 164, 66, 109, 155, 198, 19, 23, 21,
+ 22, 18, 17, 20, 24, 25, 37, 36, 35, 34,
+ 80, 79, 78, 77, 126, 125, 124, 123, 169, 168,
+ 167, 166, 70, 67, 71, 113, 110, 114, 159, 156,
+ 160, 202, 199, 203, 76, 165, 81, 82, 92, 91,
+ 93, 83, 95, 85, 84, 94, 101, 102, 96, 104,
+ 86, 103, 87, 97, 127, 128, 138, 137, 139, 129,
+ 141, 131, 130, 140, 147, 148, 142, 150, 132, 149,
+ 133, 143, 170, 171, 181, 180, 182, 172, 184, 174,
+ 173, 183, 190, 191, 185, 193, 175, 192, 176, 186,
+ 38, 39, 49, 48, 50, 40, 52, 42, 41, 51,
+ 58, 59, 53, 61, 43, 60, 44, 54, 194, 179,
+ 189, 196, 177, 195, 178, 187, 188, 151, 136, 146,
+ 153, 134, 152, 135, 144, 145, 105, 90, 100, 107,
+ 88, 106, 89, 98, 99, 62, 47, 57, 64, 45,
+ 63, 46, 55, 56
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap795[159] =
+{
+ 8, 7, 6, 5, 4, 3, 2, 14, 16, 9,
+ 10, 12, 13, 15, 11, 17, 20, 22, 24, 23,
+ 19, 18, 21, 56, 88, 122, 154, 57, 89, 123,
+ 155, 58, 90, 124, 156, 52, 84, 118, 150, 53,
+ 85, 119, 151, 27, 93, 28, 94, 29, 95, 30,
+ 96, 31, 97, 61, 127, 62, 128, 63, 129, 59,
+ 91, 125, 157, 32, 98, 64, 130, 1, 0, 25,
+ 26, 33, 99, 34, 100, 65, 131, 66, 132, 54,
+ 86, 120, 152, 60, 92, 126, 158, 55, 87, 121,
+ 153, 117, 116, 115, 46, 78, 112, 144, 43, 75,
+ 109, 141, 40, 72, 106, 138, 36, 68, 102, 134,
+ 114, 149, 148, 147, 146, 83, 82, 81, 80, 51,
+ 50, 49, 48, 47, 45, 44, 42, 39, 35, 79,
+ 77, 76, 74, 71, 67, 113, 111, 110, 108, 105,
+ 101, 145, 143, 142, 140, 137, 133, 41, 73, 107,
+ 139, 37, 69, 103, 135, 38, 70, 104, 136
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap74[148] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 26, 87, 27,
+ 88, 28, 89, 29, 90, 30, 91, 51, 80, 112,
+ 141, 52, 81, 113, 142, 54, 83, 115, 144, 55,
+ 84, 116, 145, 58, 119, 59, 120, 21, 22, 23,
+ 17, 18, 19, 31, 60, 92, 121, 56, 85, 117,
+ 146, 20, 24, 25, 50, 79, 111, 140, 57, 86,
+ 118, 147, 49, 78, 110, 139, 48, 77, 53, 82,
+ 114, 143, 109, 138, 47, 76, 108, 137, 32, 33,
+ 61, 62, 93, 94, 122, 123, 41, 42, 43, 44,
+ 45, 46, 70, 71, 72, 73, 74, 75, 102, 103,
+ 104, 105, 106, 107, 131, 132, 133, 134, 135, 136,
+ 34, 63, 95, 124, 35, 64, 96, 125, 36, 65,
+ 97, 126, 37, 66, 98, 127, 38, 67, 99, 128,
+ 39, 68, 100, 129, 40, 69, 101, 130
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap67[134] =
+{
+ 0, 1, 4, 3, 5, 6, 13, 7, 2, 8,
+ 9, 11, 15, 12, 14, 10, 28, 82, 29, 83,
+ 27, 81, 26, 80, 30, 84, 16, 55, 109, 56,
+ 110, 31, 85, 57, 111, 48, 73, 102, 127, 32,
+ 86, 51, 76, 105, 130, 52, 77, 106, 131, 58,
+ 112, 33, 87, 19, 23, 53, 78, 107, 132, 21,
+ 22, 18, 17, 20, 24, 25, 50, 75, 104, 129,
+ 47, 72, 101, 126, 54, 79, 108, 133, 46, 71,
+ 100, 125, 128, 103, 74, 49, 45, 70, 99, 124,
+ 42, 67, 96, 121, 39, 64, 93, 118, 38, 63,
+ 92, 117, 35, 60, 89, 114, 34, 59, 88, 113,
+ 44, 69, 98, 123, 43, 68, 97, 122, 41, 66,
+ 95, 120, 40, 65, 94, 119, 37, 62, 91, 116,
+ 36, 61, 90, 115
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap59[118] =
+{
+ 0, 1, 4, 5, 3, 6, 7, 2, 13, 15,
+ 8, 9, 11, 12, 14, 10, 16, 28, 74, 29,
+ 75, 27, 73, 26, 72, 30, 76, 51, 97, 50,
+ 71, 96, 117, 31, 77, 52, 98, 49, 70, 95,
+ 116, 53, 99, 32, 78, 33, 79, 48, 69, 94,
+ 115, 47, 68, 93, 114, 46, 67, 92, 113, 19,
+ 21, 23, 22, 18, 17, 20, 24, 111, 43, 89,
+ 110, 64, 65, 44, 90, 25, 45, 66, 91, 112,
+ 54, 100, 40, 61, 86, 107, 39, 60, 85, 106,
+ 36, 57, 82, 103, 35, 56, 81, 102, 34, 55,
+ 80, 101, 42, 63, 88, 109, 41, 62, 87, 108,
+ 38, 59, 84, 105, 37, 58, 83, 104
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap515[103] =
+{
+ 7, 6, 5, 4, 3, 2, 1, 0, 15, 14,
+ 13, 12, 11, 10, 9, 8, 23, 24, 25, 26,
+ 27, 46, 65, 84, 45, 44, 43, 64, 63, 62,
+ 83, 82, 81, 102, 101, 100, 42, 61, 80, 99,
+ 28, 47, 66, 85, 18, 41, 60, 79, 98, 29,
+ 48, 67, 17, 20, 22, 40, 59, 78, 97, 21,
+ 30, 49, 68, 86, 19, 16, 87, 39, 38, 58,
+ 57, 77, 35, 54, 73, 92, 76, 96, 95, 36,
+ 55, 74, 93, 32, 51, 33, 52, 70, 71, 89,
+ 90, 31, 50, 69, 88, 37, 56, 75, 94, 34,
+ 53, 72, 91
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap475[95] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 23, 24, 25, 26,
+ 27, 28, 48, 49, 61, 62, 82, 83, 47, 46,
+ 45, 44, 81, 80, 79, 78, 17, 18, 20, 22,
+ 77, 76, 75, 74, 29, 30, 43, 42, 41, 40,
+ 38, 39, 16, 19, 21, 50, 51, 59, 60, 63,
+ 64, 72, 73, 84, 85, 93, 94, 32, 33, 35,
+ 36, 53, 54, 56, 57, 66, 67, 69, 70, 87,
+ 88, 90, 91, 34, 55, 68, 89, 37, 58, 71,
+ 92, 31, 52, 65, 86
+};
+
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_660[] =
+{
+ 0, 5, 6, 7, 61, 84, 107, 130, 62, 85,
+ 8, 4, 37, 38, 39, 40, 58, 81, 104, 127,
+ 60, 83, 106, 129, 108, 131, 128, 41, 42, 80,
+ 126, 1, 3, 57, 103, 82, 105, 59, 2, 63,
+ 109, 110, 86, 19, 22, 23, 64, 87, 18, 20,
+ 21, 17, 13, 88, 43, 89, 65, 111, 14, 24,
+ 25, 26, 27, 28, 15, 16, 44, 90, 66, 112,
+ 9, 11, 10, 12, 67, 113, 29, 30, 31, 32,
+ 34, 33, 35, 36, 45, 51, 68, 74, 91, 97,
+ 114, 120, 46, 69, 92, 115, 52, 75, 98, 121,
+ 47, 70, 93, 116, 53, 76, 99, 122, 48, 71,
+ 94, 117, 54, 77, 100, 123, 49, 72, 95, 118,
+ 55, 78, 101, 124, 50, 73, 96, 119, 56, 79,
+ 102, 125
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_885[] =
+{
+ 0, 4, 6, 7, 5, 3, 47, 48, 49, 112,
+ 113, 114, 75, 106, 140, 171, 80, 111, 145, 176,
+ 77, 108, 142, 173, 78, 109, 143, 174, 79, 110,
+ 144, 175, 76, 107, 141, 172, 50, 115, 51, 2,
+ 1, 81, 116, 146, 19, 21, 12, 17, 18, 20,
+ 16, 25, 13, 10, 14, 24, 23, 22, 26, 8,
+ 15, 52, 117, 31, 82, 147, 9, 33, 11, 83,
+ 148, 53, 118, 28, 27, 84, 149, 34, 35, 29,
+ 46, 32, 30, 54, 119, 37, 36, 39, 38, 40,
+ 85, 150, 41, 42, 43, 44, 45, 55, 60, 65,
+ 70, 86, 91, 96, 101, 120, 125, 130, 135, 151,
+ 156, 161, 166, 56, 87, 121, 152, 61, 92, 126,
+ 157, 66, 97, 131, 162, 71, 102, 136, 167, 57,
+ 88, 122, 153, 62, 93, 127, 158, 67, 98, 132,
+ 163, 72, 103, 137, 168, 58, 89, 123, 154, 63,
+ 94, 128, 159, 68, 99, 133, 164, 73, 104, 138,
+ 169, 59, 90, 124, 155, 64, 95, 129, 160, 69,
+ 100, 134, 165, 74, 105, 139, 170
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1265[] =
+{
+ 0, 4, 6, 93, 143, 196, 246, 7, 5, 3,
+ 47, 48, 49, 50, 51, 150, 151, 152, 153, 154,
+ 94, 144, 197, 247, 99, 149, 202, 252, 96, 146,
+ 199, 249, 97, 147, 200, 250, 100, 203, 98, 148,
+ 201, 251, 95, 145, 198, 248, 52, 2, 1, 101,
+ 204, 155, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 156, 31, 102, 205, 9, 33, 11, 103, 206, 54,
+ 157, 28, 27, 104, 207, 34, 35, 29, 46, 32,
+ 30, 55, 158, 37, 36, 39, 38, 40, 105, 208,
+ 41, 42, 43, 44, 45, 56, 106, 159, 209, 57,
+ 66, 75, 84, 107, 116, 125, 134, 160, 169, 178,
+ 187, 210, 219, 228, 237, 58, 108, 161, 211, 62,
+ 112, 165, 215, 67, 117, 170, 220, 71, 121, 174,
+ 224, 76, 126, 179, 229, 80, 130, 183, 233, 85,
+ 135, 188, 238, 89, 139, 192, 242, 59, 109, 162,
+ 212, 63, 113, 166, 216, 68, 118, 171, 221, 72,
+ 122, 175, 225, 77, 127, 180, 230, 81, 131, 184,
+ 234, 86, 136, 189, 239, 90, 140, 193, 243, 60,
+ 110, 163, 213, 64, 114, 167, 217, 69, 119, 172,
+ 222, 73, 123, 176, 226, 78, 128, 181, 231, 82,
+ 132, 185, 235, 87, 137, 190, 240, 91, 141, 194,
+ 244, 61, 111, 164, 214, 65, 115, 168, 218, 70,
+ 120, 173, 223, 74, 124, 177, 227, 79, 129, 182,
+ 232, 83, 133, 186, 236, 88, 138, 191, 241, 92,
+ 142, 195, 245
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1425[] =
+{
+ 0, 4, 6, 101, 159, 220, 278, 7, 5, 3,
+ 47, 48, 49, 50, 51, 166, 167, 168, 169, 170,
+ 102, 160, 221, 279, 107, 165, 226, 284, 104, 162,
+ 223, 281, 105, 163, 224, 282, 108, 227, 106, 164,
+ 225, 283, 103, 161, 222, 280, 52, 2, 1, 109,
+ 228, 171, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 172, 31, 110, 229, 9, 33, 11, 111, 230, 54,
+ 173, 28, 27, 112, 231, 34, 35, 29, 46, 32,
+ 30, 55, 174, 37, 36, 39, 38, 40, 113, 232,
+ 41, 42, 43, 44, 45, 56, 114, 175, 233, 62,
+ 120, 181, 239, 75, 133, 194, 252, 57, 115, 176,
+ 234, 63, 121, 182, 240, 70, 128, 189, 247, 76,
+ 134, 195, 253, 83, 141, 202, 260, 92, 150, 211,
+ 269, 84, 142, 203, 261, 93, 151, 212, 270, 85,
+ 143, 204, 262, 94, 152, 213, 271, 86, 144, 205,
+ 263, 95, 153, 214, 272, 64, 122, 183, 241, 77,
+ 135, 196, 254, 65, 123, 184, 242, 78, 136, 197,
+ 255, 87, 145, 206, 264, 96, 154, 215, 273, 58,
+ 116, 177, 235, 66, 124, 185, 243, 71, 129, 190,
+ 248, 79, 137, 198, 256, 88, 146, 207, 265, 97,
+ 155, 216, 274, 59, 117, 178, 236, 67, 125, 186,
+ 244, 72, 130, 191, 249, 80, 138, 199, 257, 89,
+ 147, 208, 266, 98, 156, 217, 275, 60, 118, 179,
+ 237, 68, 126, 187, 245, 73, 131, 192, 250, 81,
+ 139, 200, 258, 90, 148, 209, 267, 99, 157, 218,
+ 276, 61, 119, 180, 238, 69, 127, 188, 246, 74,
+ 132, 193, 251, 82, 140, 201, 259, 91, 149, 210,
+ 268, 100, 158, 219, 277
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1585[] =
+{
+ 0, 4, 6, 109, 175, 244, 310, 7, 5, 3,
+ 47, 48, 49, 50, 51, 182, 183, 184, 185, 186,
+ 110, 176, 245, 311, 115, 181, 250, 316, 112, 178,
+ 247, 313, 113, 179, 248, 314, 116, 251, 114, 180,
+ 249, 315, 111, 177, 246, 312, 52, 2, 1, 117,
+ 252, 187, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 188, 31, 118, 253, 9, 33, 11, 119, 254, 54,
+ 189, 28, 27, 120, 255, 34, 35, 29, 46, 32,
+ 30, 55, 190, 37, 36, 39, 38, 40, 121, 256,
+ 41, 42, 43, 44, 45, 56, 122, 191, 257, 63,
+ 129, 198, 264, 76, 142, 211, 277, 89, 155, 224,
+ 290, 102, 168, 237, 303, 57, 123, 192, 258, 70,
+ 136, 205, 271, 83, 149, 218, 284, 96, 162, 231,
+ 297, 62, 128, 197, 263, 75, 141, 210, 276, 88,
+ 154, 223, 289, 101, 167, 236, 302, 58, 124, 193,
+ 259, 71, 137, 206, 272, 84, 150, 219, 285, 97,
+ 163, 232, 298, 59, 125, 194, 260, 64, 130, 199,
+ 265, 67, 133, 202, 268, 72, 138, 207, 273, 77,
+ 143, 212, 278, 80, 146, 215, 281, 85, 151, 220,
+ 286, 90, 156, 225, 291, 93, 159, 228, 294, 98,
+ 164, 233, 299, 103, 169, 238, 304, 106, 172, 241,
+ 307, 60, 126, 195, 261, 65, 131, 200, 266, 68,
+ 134, 203, 269, 73, 139, 208, 274, 78, 144, 213,
+ 279, 81, 147, 216, 282, 86, 152, 221, 287, 91,
+ 157, 226, 292, 94, 160, 229, 295, 99, 165, 234,
+ 300, 104, 170, 239, 305, 107, 173, 242, 308, 61,
+ 127, 196, 262, 66, 132, 201, 267, 69, 135, 204,
+ 270, 74, 140, 209, 275, 79, 145, 214, 280, 82,
+ 148, 217, 283, 87, 153, 222, 288, 92, 158, 227,
+ 293, 95, 161, 230, 296, 100, 166, 235, 301, 105,
+ 171, 240, 306, 108, 174, 243, 309
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1825[] =
+{
+ 0, 4, 6, 121, 199, 280, 358, 7, 5, 3,
+ 47, 48, 49, 50, 51, 206, 207, 208, 209, 210,
+ 122, 200, 281, 359, 127, 205, 286, 364, 124, 202,
+ 283, 361, 125, 203, 284, 362, 128, 287, 126, 204,
+ 285, 363, 123, 201, 282, 360, 52, 2, 1, 129,
+ 288, 211, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 212, 31, 130, 289, 9, 33, 11, 131, 290, 54,
+ 213, 28, 27, 132, 291, 34, 35, 29, 46, 32,
+ 30, 55, 214, 37, 36, 39, 38, 40, 133, 292,
+ 41, 42, 43, 44, 45, 56, 134, 215, 293, 198,
+ 299, 136, 120, 138, 60, 279, 58, 62, 357, 139,
+ 140, 295, 156, 57, 219, 297, 63, 217, 137, 170,
+ 300, 222, 64, 106, 61, 78, 294, 92, 142, 141,
+ 135, 221, 296, 301, 343, 59, 298, 184, 329, 315,
+ 220, 216, 265, 251, 218, 237, 352, 223, 157, 86,
+ 171, 87, 164, 351, 111, 302, 65, 178, 115, 323,
+ 72, 192, 101, 179, 93, 73, 193, 151, 337, 309,
+ 143, 274, 69, 324, 165, 150, 97, 338, 110, 310,
+ 330, 273, 68, 107, 175, 245, 114, 79, 113, 189,
+ 246, 259, 174, 71, 185, 96, 344, 100, 322, 83,
+ 334, 316, 333, 252, 161, 348, 147, 82, 269, 232,
+ 260, 308, 353, 347, 163, 231, 306, 320, 188, 270,
+ 146, 177, 266, 350, 256, 85, 149, 116, 191, 160,
+ 238, 258, 336, 305, 255, 88, 224, 99, 339, 230,
+ 228, 227, 272, 242, 241, 319, 233, 311, 102, 74,
+ 180, 275, 66, 194, 152, 325, 172, 247, 244, 261,
+ 117, 158, 166, 354, 75, 144, 108, 312, 94, 186,
+ 303, 80, 234, 89, 195, 112, 340, 181, 345, 317,
+ 326, 276, 239, 167, 118, 313, 70, 355, 327, 253,
+ 190, 176, 271, 104, 98, 153, 103, 90, 76, 267,
+ 277, 248, 225, 262, 182, 84, 154, 235, 335, 168,
+ 331, 196, 341, 249, 162, 307, 148, 349, 263, 321,
+ 257, 243, 229, 356, 159, 119, 67, 187, 173, 145,
+ 240, 77, 304, 332, 314, 342, 109, 254, 81, 278,
+ 105, 91, 346, 318, 183, 250, 197, 328, 95, 155,
+ 169, 268, 226, 236, 264
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1985[] =
+{
+ 0, 4, 6, 129, 215, 304, 390, 7, 5, 3,
+ 47, 48, 49, 50, 51, 222, 223, 224, 225, 226,
+ 130, 216, 305, 391, 135, 221, 310, 396, 132, 218,
+ 307, 393, 133, 219, 308, 394, 136, 311, 134, 220,
+ 309, 395, 131, 217, 306, 392, 52, 2, 1, 137,
+ 312, 227, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 228, 31, 138, 313, 9, 33, 11, 139, 314, 54,
+ 229, 28, 27, 140, 315, 34, 35, 29, 46, 32,
+ 30, 55, 230, 37, 36, 39, 38, 40, 141, 316,
+ 41, 42, 43, 44, 45, 56, 142, 231, 317, 63,
+ 73, 92, 340, 82, 324, 149, 353, 159, 334, 165,
+ 338, 178, 163, 254, 77, 168, 257, 153, 343, 57,
+ 248, 238, 79, 252, 166, 67, 80, 201, 101, 267,
+ 143, 164, 341, 255, 339, 187, 376, 318, 78, 328,
+ 362, 115, 232, 242, 253, 290, 276, 62, 58, 158,
+ 68, 93, 179, 319, 148, 169, 154, 72, 385, 329,
+ 333, 344, 102, 83, 144, 233, 323, 124, 243, 192,
+ 354, 237, 64, 247, 202, 209, 150, 116, 335, 268,
+ 239, 299, 188, 196, 298, 94, 195, 258, 123, 363,
+ 384, 109, 325, 371, 170, 370, 84, 110, 295, 180,
+ 74, 210, 191, 106, 291, 205, 367, 381, 377, 206,
+ 355, 122, 119, 120, 383, 160, 105, 108, 277, 380,
+ 294, 284, 285, 345, 208, 269, 249, 366, 386, 300,
+ 297, 259, 125, 369, 197, 97, 194, 286, 211, 281,
+ 280, 183, 372, 87, 155, 283, 59, 348, 327, 184,
+ 76, 111, 330, 203, 349, 69, 98, 152, 145, 189,
+ 66, 320, 337, 173, 358, 251, 198, 174, 263, 262,
+ 126, 241, 193, 88, 388, 117, 95, 387, 112, 359,
+ 287, 244, 103, 272, 301, 171, 162, 234, 273, 127,
+ 373, 181, 292, 85, 378, 302, 121, 107, 364, 346,
+ 356, 212, 278, 213, 65, 382, 288, 207, 113, 175,
+ 99, 296, 374, 368, 199, 260, 185, 336, 331, 161,
+ 270, 264, 250, 240, 75, 350, 151, 60, 89, 321,
+ 156, 274, 360, 326, 70, 282, 167, 146, 352, 81,
+ 91, 389, 266, 245, 177, 235, 190, 256, 204, 342,
+ 128, 118, 303, 104, 379, 182, 114, 375, 200, 96,
+ 293, 172, 214, 365, 279, 86, 289, 351, 347, 357,
+ 261, 186, 176, 271, 90, 100, 147, 322, 275, 361,
+ 71, 332, 61, 265, 157, 246, 236
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_2305[] =
+{
+ 0, 4, 6, 145, 247, 352, 454, 7, 5, 3,
+ 47, 48, 49, 50, 51, 254, 255, 256, 257, 258,
+ 146, 248, 353, 455, 151, 253, 358, 460, 148, 250,
+ 355, 457, 149, 251, 356, 458, 152, 359, 150, 252,
+ 357, 459, 147, 249, 354, 456, 52, 2, 1, 153,
+ 360, 259, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 260, 31, 154, 361, 9, 33, 11, 155, 362, 54,
+ 261, 28, 27, 156, 363, 34, 35, 29, 46, 32,
+ 30, 55, 262, 37, 36, 39, 38, 40, 157, 364,
+ 41, 42, 43, 44, 45, 56, 158, 263, 365, 181,
+ 192, 170, 79, 57, 399, 90, 159, 297, 377, 366,
+ 275, 68, 183, 388, 286, 194, 299, 92, 70, 182,
+ 401, 172, 59, 91, 58, 400, 368, 161, 81, 160,
+ 264, 171, 80, 389, 390, 378, 379, 193, 298, 69,
+ 266, 265, 367, 277, 288, 276, 287, 184, 60, 195,
+ 82, 93, 71, 369, 402, 173, 162, 444, 300, 391,
+ 98, 76, 278, 61, 267, 374, 135, 411, 167, 102,
+ 380, 200, 87, 178, 65, 94, 204, 124, 72, 342,
+ 189, 305, 381, 396, 433, 301, 226, 407, 289, 237,
+ 113, 215, 185, 128, 309, 403, 116, 320, 196, 331,
+ 370, 422, 174, 64, 392, 83, 425, 219, 134, 188,
+ 432, 112, 427, 139, 279, 163, 436, 208, 447, 218,
+ 236, 229, 97, 294, 385, 230, 166, 268, 177, 443,
+ 225, 426, 101, 272, 138, 127, 290, 117, 347, 199,
+ 414, 95, 140, 240, 410, 395, 209, 129, 283, 346,
+ 105, 241, 437, 86, 308, 448, 203, 345, 186, 107,
+ 220, 415, 334, 319, 106, 313, 118, 123, 73, 207,
+ 421, 214, 384, 373, 438, 62, 371, 341, 75, 449,
+ 168, 323, 164, 242, 416, 324, 304, 197, 335, 404,
+ 271, 63, 191, 325, 96, 169, 231, 280, 312, 187,
+ 406, 84, 201, 100, 67, 382, 175, 336, 202, 330,
+ 269, 393, 376, 383, 293, 307, 409, 179, 285, 314,
+ 302, 372, 398, 190, 180, 89, 99, 103, 232, 78,
+ 88, 77, 136, 387, 165, 198, 394, 125, 176, 428,
+ 74, 375, 238, 227, 66, 273, 282, 141, 306, 412,
+ 114, 85, 130, 348, 119, 291, 296, 386, 233, 397,
+ 303, 405, 284, 445, 423, 221, 210, 205, 450, 108,
+ 274, 434, 216, 343, 337, 142, 243, 321, 408, 451,
+ 310, 292, 120, 109, 281, 439, 270, 429, 332, 295,
+ 418, 211, 315, 222, 326, 131, 430, 244, 327, 349,
+ 417, 316, 143, 338, 440, 234, 110, 212, 452, 245,
+ 121, 419, 350, 223, 132, 441, 328, 413, 317, 339,
+ 126, 104, 137, 446, 344, 239, 435, 115, 333, 206,
+ 322, 217, 228, 424, 453, 311, 351, 111, 442, 224,
+ 213, 122, 431, 340, 235, 246, 133, 144, 420, 329,
+ 318
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_2385[] =
+{
+ 0, 4, 6, 145, 251, 360, 466, 7, 5, 3,
+ 47, 48, 49, 50, 51, 262, 263, 264, 265, 266,
+ 146, 252, 361, 467, 151, 257, 366, 472, 148, 254,
+ 363, 469, 149, 255, 364, 470, 156, 371, 150, 256,
+ 365, 471, 147, 253, 362, 468, 52, 2, 1, 157,
+ 372, 267, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 268, 31, 152, 153, 154, 155, 258, 259, 260, 261,
+ 367, 368, 369, 370, 473, 474, 475, 476, 158, 373,
+ 9, 33, 11, 159, 374, 54, 269, 28, 27, 160,
+ 375, 34, 35, 29, 46, 32, 30, 55, 270, 37,
+ 36, 39, 38, 40, 161, 376, 41, 42, 43, 44,
+ 45, 56, 162, 271, 377, 185, 196, 174, 79, 57,
+ 411, 90, 163, 305, 389, 378, 283, 68, 187, 400,
+ 294, 198, 307, 92, 70, 186, 413, 176, 59, 91,
+ 58, 412, 380, 165, 81, 164, 272, 175, 80, 401,
+ 402, 390, 391, 197, 306, 69, 274, 273, 379, 285,
+ 296, 284, 295, 188, 60, 199, 82, 93, 71, 381,
+ 414, 177, 166, 456, 308, 403, 98, 76, 286, 61,
+ 275, 386, 135, 423, 171, 102, 392, 204, 87, 182,
+ 65, 94, 208, 124, 72, 350, 193, 313, 393, 408,
+ 445, 309, 230, 419, 297, 241, 113, 219, 189, 128,
+ 317, 415, 116, 328, 200, 339, 382, 434, 178, 64,
+ 404, 83, 437, 223, 134, 192, 444, 112, 439, 139,
+ 287, 167, 448, 212, 459, 222, 240, 233, 97, 302,
+ 397, 234, 170, 276, 181, 455, 229, 438, 101, 280,
+ 138, 127, 298, 117, 355, 203, 426, 95, 140, 244,
+ 422, 407, 213, 129, 291, 354, 105, 245, 449, 86,
+ 316, 460, 207, 353, 190, 107, 224, 427, 342, 327,
+ 106, 321, 118, 123, 73, 211, 433, 218, 396, 385,
+ 450, 62, 383, 349, 75, 461, 172, 331, 168, 246,
+ 428, 332, 312, 201, 343, 416, 279, 63, 195, 333,
+ 96, 173, 235, 288, 320, 191, 418, 84, 205, 100,
+ 67, 394, 179, 344, 206, 338, 277, 405, 388, 395,
+ 301, 315, 421, 183, 293, 322, 310, 384, 410, 194,
+ 184, 89, 99, 103, 236, 78, 88, 77, 136, 399,
+ 169, 202, 406, 125, 180, 440, 74, 387, 242, 231,
+ 66, 281, 290, 141, 314, 424, 114, 85, 130, 356,
+ 119, 299, 304, 398, 237, 409, 311, 417, 292, 457,
+ 435, 225, 214, 209, 462, 108, 282, 446, 220, 351,
+ 345, 142, 247, 329, 420, 463, 318, 300, 120, 109,
+ 289, 451, 278, 441, 340, 303, 430, 215, 323, 226,
+ 334, 131, 442, 248, 335, 357, 429, 324, 143, 346,
+ 452, 238, 110, 216, 464, 249, 121, 431, 358, 227,
+ 132, 453, 336, 425, 325, 347, 126, 104, 137, 458,
+ 352, 243, 447, 115, 341, 210, 330, 221, 232, 436,
+ 465, 319, 359, 111, 454, 228, 217, 122, 443, 348,
+ 239, 250, 133, 144, 432, 337, 326
+};
+
+/**
+ * AMR-NB bitstream sensitivity order maps.
+ */
+const pj_int16_t* const pjmedia_codec_amrnb_ordermaps[8] =
+{
+ pjmedia_codec_amrnb_ordermap475,
+ pjmedia_codec_amrnb_ordermap515,
+ pjmedia_codec_amrnb_ordermap59,
+ pjmedia_codec_amrnb_ordermap67,
+ pjmedia_codec_amrnb_ordermap74,
+ pjmedia_codec_amrnb_ordermap795,
+ pjmedia_codec_amrnb_ordermap102,
+ pjmedia_codec_amrnb_ordermap122
+};
+
+/**
+ * AMR-WB bitstream sensitivity order maps.
+ */
+const pj_int16_t* const pjmedia_codec_amrwb_ordermaps[9] =
+{
+ pjmedia_codec_amrwb_ordermap_660,
+ pjmedia_codec_amrwb_ordermap_885,
+ pjmedia_codec_amrwb_ordermap_1265,
+ pjmedia_codec_amrwb_ordermap_1425,
+ pjmedia_codec_amrwb_ordermap_1585,
+ pjmedia_codec_amrwb_ordermap_1825,
+ pjmedia_codec_amrwb_ordermap_1985,
+ pjmedia_codec_amrwb_ordermap_2305,
+ pjmedia_codec_amrwb_ordermap_2385
+};
+
+/**
+ * Constant of AMR-NB frame lengths in bytes.
+ */
+const pj_uint8_t pjmedia_codec_amrnb_framelen[16] =
+ {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 5};
+/**
+ * Constant of AMR-NB frame lengths in bits.
+ */
+const pj_uint16_t pjmedia_codec_amrnb_framelenbits[9] =
+ {95, 103, 118, 134, 148, 159, 204, 244, 39};
+/**
+ * Constant of AMR-NB bitrates.
+ */
+const pj_uint16_t pjmedia_codec_amrnb_bitrates[8] =
+ {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200};
+
+/**
+ * Constant of AMR-WB frame lengths in bytes.
+ */
+const pj_uint8_t pjmedia_codec_amrwb_framelen[16] =
+ {17, 23, 32, 37, 40, 46, 50, 58, 60, 5, 0, 0, 0, 0, 0, 5};
+/**
+ * Constant of AMR-WB frame lengths in bits.
+ */
+const pj_uint16_t pjmedia_codec_amrwb_framelenbits[10] =
+ {132, 177, 253, 285, 317, 365, 397, 461, 477, 40};
+/**
+ * Constant of AMR-WB bitrates.
+ */
+const pj_uint16_t pjmedia_codec_amrwb_bitrates[9] =
+ {6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850};
+
+
+/**
+ * This structure describes AMR frame info, to be fitted into @pjmedia_frame
+ * bit info.
+ */
+#pragma pack(1)
+typedef struct pjmedia_codec_amr_bit_info {
+ pj_uint8_t frame_type; /**< AMR frame type. */
+ pj_int8_t mode; /**< AMR mode. */
+ pj_uint8_t start_bit; /**< Frame start bit. */
+ pj_uint8_t good_quality:1; /**< Flag if frame is good/degraded. */
+} pjmedia_codec_amr_bit_info;
+#pragma pack()
+
+
+/**
+ * This structure describes AMR settings.
+ */
+typedef struct pjmedia_codec_amr_pack_setting {
+ pj_uint8_t amr_nb:1; /**< Set 1 for AMR-NB, 0 for AMR-WB. */
+ pj_uint8_t reorder:1; /**< Reorder bitstream into descending
+ sensitivity order or vice versa. */
+ pj_uint8_t octet_aligned:1; /**< TRUE if payload is in octet-aligned mode,
+ FALSE if payload is in bandwidth
+ efficient mode. */
+ pj_uint8_t cmr:4; /**< Change Mode Request for remote
+ encoder. */
+} pjmedia_codec_amr_pack_setting;
+
+
+/**
+ * Get AMR mode based on bitrate.
+ *
+ * @param bitrate AMR bitrate.
+ *
+ * @return AMR mode.
+ */
+PJ_INLINE(pj_int8_t) pjmedia_codec_amr_get_mode(unsigned bitrate)
+{
+ pj_int8_t mode = -1;
+
+ if(bitrate==4750){
+ mode = 0;
+ } else if(bitrate==5150){
+ mode = 1;
+ } else if(bitrate==5900){
+ mode = 2;
+ } else if(bitrate==6700){
+ mode = 3;
+ } else if(bitrate==7400){
+ mode = 4;
+ } else if(bitrate==7950){
+ mode = 5;
+ } else if(bitrate==10200){
+ mode = 6;
+ } else if(bitrate==12200){
+ mode = 7;
+
+ /* AMRWB */
+ } else if(bitrate==6600){
+ mode = 0;
+ } else if(bitrate==8850){
+ mode = 1;
+ } else if(bitrate==12650){
+ mode = 2;
+ } else if(bitrate==14250){
+ mode = 3;
+ } else if(bitrate==15850){
+ mode = 4;
+ } else if(bitrate==18250){
+ mode = 5;
+ } else if(bitrate==19850){
+ mode = 6;
+ } else if(bitrate==23050){
+ mode = 7;
+ } else if(bitrate==23850){
+ mode = 8;
+ }
+ return mode;
+}
+
+/**
+ * Get AMR mode based on frame length.
+ *
+ * @param amrnb Set to PJ_TRUE for AMR-NB domain or PJ_FALSE for AMR-WB.
+ * @param frame_len The frame length.
+ *
+ * @return AMR mode.
+ */
+
+PJ_INLINE(pj_int8_t) pjmedia_codec_amr_get_mode2(pj_bool_t amrnb,
+ unsigned frame_len)
+{
+ int i;
+
+ if (amrnb) {
+ for (i = 0; i < 9; ++i)
+ if (frame_len == pjmedia_codec_amrnb_framelen[i])
+ return (pj_int8_t)i;
+ } else {
+ for (i = 0; i < 10; ++i) {
+ if (frame_len == pjmedia_codec_amrwb_framelen[i])
+ return (pj_int8_t)i;
+ }
+ }
+
+ pj_assert(!"Invalid AMR frame length");
+ return -1;
+}
+
+/**
+ * Prepare a frame before pass it to decoder. This function will do:
+ * - reorder AMR bitstream from descending sensitivity order into
+ * encoder bits order. This can be enabled/disabled via param
+ * 'setting' by setting/resetting field 'reorder'.
+ * - align left the start bit (make the start_bit to be 0).
+ *
+ * @param amr_nb Set PJ_TRUE for AMR-NB and PJ_FALSE for AMR-WB.
+ * @param in Input frame.
+ * @param setting Settings, see @pjmedia_codec_amr_pack_setting.
+ * @param out Output frame.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_amr_predecode(
+ const pjmedia_frame *in,
+ const pjmedia_codec_amr_pack_setting *setting,
+ pjmedia_frame *out)
+{
+ pj_int8_t amr_bits[477 + 7] = {0};
+ pj_int8_t *p_amr_bits = &amr_bits[0];
+
+ pj_uint8_t *r = (pj_uint8_t*) in->buf; /* read cursor */
+ pj_uint8_t *w = (pj_uint8_t*) out->buf; /* write cursor */
+
+ /* env vars for AMR or AMRWB */
+ pj_uint8_t SID_FT;
+ const pj_uint8_t *framelen_tbl;
+ const pj_uint16_t *framelenbit_tbl;
+ const pj_uint16_t *bitrate_tbl;
+ const pj_int16_t* const *order_maps;
+
+ pjmedia_codec_amr_bit_info *in_info =
+ (pjmedia_codec_amr_bit_info*) &in->bit_info;
+ pjmedia_codec_amr_bit_info *out_info =
+ (pjmedia_codec_amr_bit_info*) &out->bit_info;
+
+ unsigned i;
+
+ *out_info = *in_info;
+
+ if (setting->amr_nb) {
+ SID_FT = 8;
+ framelen_tbl = pjmedia_codec_amrnb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrnb_framelenbits;
+ bitrate_tbl = pjmedia_codec_amrnb_bitrates;
+ order_maps = pjmedia_codec_amrnb_ordermaps;
+ } else {
+ SID_FT = 9;
+ framelen_tbl = pjmedia_codec_amrwb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrwb_framelenbits;
+ bitrate_tbl = pjmedia_codec_amrwb_bitrates;
+ order_maps = pjmedia_codec_amrwb_ordermaps;
+ }
+
+ /* unpack AMR bitstream if there is any data */
+ if (in_info->frame_type <= SID_FT) {
+ i = 0;
+ if (in_info->start_bit) {
+ for (; i < (unsigned)(8-in_info->start_bit); ++i)
+ *p_amr_bits++ = (pj_uint8_t)
+ ((*r >> (7-in_info->start_bit-i)) & 1);
+ ++r;
+ }
+ for(; i < framelenbit_tbl[in_info->frame_type]; i += 8, ++r) {
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 7) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 6) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 5) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 4) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 3) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 2) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 1) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r ) & 1);
+ }
+ }
+
+ if (in_info->frame_type < SID_FT) {
+
+ /* Speech */
+ out_info->mode = in_info->frame_type;
+ out->size = framelen_tbl[out_info->mode];
+
+ pj_bzero(out->buf, out->size);
+
+ if (setting->reorder) {
+ const pj_int16_t *order_map;
+
+ order_map = order_maps[out_info->mode];
+ for(i = 0; i < framelenbit_tbl[out_info->mode]; ++i) {
+ if (amr_bits[i]) {
+ pj_uint16_t bitpos;
+ bitpos = order_map[i];
+ w[bitpos>>3] |= 1 << (7 - (bitpos % 8));
+ }
+ }
+ } else {
+ for(i = 0; i < framelenbit_tbl[out_info->mode]; ++i) {
+ if (amr_bits[i])
+ w[i >> 3] |= 1 << (7 - (i % 8));
+ }
+ }
+
+ } else if (in_info->frame_type == SID_FT) {
+
+ /* SID */
+ pj_uint8_t w_bitptr = 0;
+ pj_uint8_t FT_;
+
+ if (setting->amr_nb)
+ FT_ = (pj_uint8_t)((amr_bits[36] << 2) | (amr_bits[37] << 1) |
+ amr_bits[38]);
+ else
+ FT_ = (pj_uint8_t)((amr_bits[36] << 3) | (amr_bits[37] << 2) |
+ (amr_bits[38] << 1) | amr_bits[39]);
+
+ out_info->mode = FT_;
+ out->size = 5;
+
+ pj_bzero(out->buf, out->size);
+ for(i = 0; i < framelenbit_tbl[SID_FT]; ++i) {
+ if (amr_bits[i])
+ *w |= (1 << (7-w_bitptr));
+
+ if (++w_bitptr == 8) {
+ ++w;
+ w_bitptr = 0;
+ }
+ }
+
+ } else {
+
+ /* NO DATA */
+ out->size = 0;
+ out_info->mode = -1;
+ }
+
+ out_info->start_bit = 0;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Pack encoded AMR frame(s) into an RTP payload.
+ *
+ * @param frames AMR frames to be packed.
+ * @param nframes Number of frames to be packed.
+ * @param setting Settings, see @pjmedia_codec_amr_pack_setting.
+ * @param pkt Payload.
+ * @param pkt_size Payload size, as input this specifies payload maximum size,
+ * as output this specifies payload packed size.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE (pj_status_t) pjmedia_codec_amr_pack(
+ const pjmedia_frame frames[],
+ unsigned nframes,
+ const pjmedia_codec_amr_pack_setting *setting,
+ void *pkt,
+ pj_size_t *pkt_size)
+{
+ /* Write cursor */
+ pj_uint8_t *w = (pj_uint8_t*)pkt;
+ pj_uint8_t w_bitptr = 0;
+
+ /* Read cursor */
+ pj_uint8_t *r;
+
+ /* env vars for AMR or AMRWB */
+ pj_uint8_t SID_FT;
+ const pj_uint8_t *framelen_tbl;
+ const pj_uint16_t *framelenbit_tbl;
+ const pj_uint16_t *bitrate_tbl;
+ const pj_int16_t* const *order_maps;
+
+ /* frame info */
+ pjmedia_codec_amr_bit_info *info;
+
+ unsigned i, max_pkt_size;
+
+ max_pkt_size = *pkt_size;
+
+ if (setting->amr_nb) {
+ SID_FT = 8;
+ framelen_tbl = pjmedia_codec_amrnb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrnb_framelenbits;
+ bitrate_tbl = pjmedia_codec_amrnb_bitrates;
+ order_maps = pjmedia_codec_amrnb_ordermaps;
+ } else {
+ SID_FT = 9;
+ framelen_tbl = pjmedia_codec_amrwb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrwb_framelenbits;
+ bitrate_tbl = pjmedia_codec_amrwb_bitrates;
+ order_maps = pjmedia_codec_amrwb_ordermaps;
+ }
+
+ /* Code Mode Request, 4 bits */
+ *w = (pj_uint8_t)(setting->cmr << 4);
+ w_bitptr = 4;
+ if (setting->octet_aligned) {
+ ++w;
+ w_bitptr = 0;
+ }
+
+ /* Table Of Contents, 6 bits each */
+ for (i = 0; i < nframes; ++i) {
+ pj_uint8_t TOC, FT, Q;
+ pj_bool_t F;
+
+ info = (pjmedia_codec_amr_bit_info*)&frames[i].bit_info;
+
+ F = (i != nframes-1);
+ FT = info->frame_type;
+ Q = (pj_uint8_t)(info->good_quality == 1);
+ pj_assert(FT <= SID_FT || FT == 14 || FT == 15);
+
+ /* Check buffer availability */
+ *pkt_size = w - (pj_uint8_t*)pkt + 1;
+ PJ_ASSERT_RETURN(*pkt_size <= max_pkt_size, PJ_ETOOSMALL);
+
+ TOC = (pj_uint8_t)((F<<5) | (FT<<1) | Q);
+ if (w_bitptr == 0) {
+ *w = (pj_uint8_t)(TOC<<2);
+ w_bitptr = 6;
+ } else if (w_bitptr == 2) {
+ *w++ |= TOC;
+ w_bitptr = 0;
+ } else if (w_bitptr == 4) {
+ *w++ |= TOC>>2;
+ *w = (pj_uint8_t)(TOC<<6);
+ w_bitptr = 2;
+ } else if (w_bitptr == 6) {
+ *w++ |= TOC>>4;
+ *w = (pj_uint8_t)(TOC<<4);
+ w_bitptr = 4;
+ }
+ if (setting->octet_aligned) {
+ ++w;
+ w_bitptr = 0;
+ }
+ }
+
+ /* Encoded data */
+ for (i = 0; i < nframes; ++i) {
+ pj_int8_t amr_bits[477 + 7] = {0};
+ pj_int8_t *p_amr_bits = &amr_bits[0];
+ unsigned j;
+
+ info = (pjmedia_codec_amr_bit_info*)&frames[i].bit_info;
+
+ /* Check buffer availability */
+ *pkt_size = w - (pj_uint8_t*)pkt;
+ if (info->frame_type <= SID_FT)
+ *pkt_size += framelen_tbl[info->frame_type] + 1;
+ PJ_ASSERT_RETURN(*pkt_size <= max_pkt_size, PJ_ETOOSMALL);
+
+ /* Skip if there is no data */
+ if (info->frame_type > SID_FT)
+ continue;
+
+ /* Unpack bits */
+ r = (pj_uint8_t*) frames[i].buf;
+ j = 0;
+ if (info->start_bit) {
+ for (; j < (unsigned)(8-info->start_bit); ++j)
+ *p_amr_bits++ = (pj_uint8_t)
+ ((*r >> (7-info->start_bit-j)) & 1);
+ ++r;
+ }
+ for(; j < framelenbit_tbl[info->frame_type]; j+=8, ++r) {
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 7) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 6) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 5) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 4) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 3) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 2) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 1) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r ) & 1);
+ }
+
+ if (info->frame_type < SID_FT) {
+
+ /* Speech */
+ if (w_bitptr == 0) *w = 0;
+
+ if (setting->reorder) {
+ const pj_int16_t *order_map;
+
+ /* Put bits in the packet, sensitivity descending ordered */
+ order_map = order_maps[info->frame_type];
+ for(j = 0; j < framelenbit_tbl[info->frame_type]; ++j) {
+ if (amr_bits[order_map[j]])
+ *w |= (1 << (7-w_bitptr));
+
+ if (++w_bitptr == 8) {
+ w_bitptr = 0;
+ ++w;
+ *w = 0;
+ }
+ }
+ } else {
+ for(j = 0; j < framelenbit_tbl[info->frame_type]; ++j) {
+ if (amr_bits[j])
+ *w |= (1 << (7-w_bitptr));
+
+ if (++w_bitptr == 8) {
+ w_bitptr = 0;
+ ++w;
+ *w = 0;
+ }
+ }
+ }
+
+ } else if (info->frame_type == SID_FT) {
+
+ /* SID */
+ pj_uint8_t STI = 0;
+
+ amr_bits[35] = (pj_uint8_t)(STI & 1);
+
+ if (setting->amr_nb) {
+ amr_bits[36] = (pj_uint8_t)((info->mode >> 2) & 1);
+ amr_bits[37] = (pj_uint8_t)((info->mode >> 1) & 1);
+ amr_bits[38] = (pj_uint8_t)((info->mode) & 1);
+ } else {
+ amr_bits[36] = (pj_uint8_t)((info->mode >> 3) & 1);
+ amr_bits[37] = (pj_uint8_t)((info->mode >> 2) & 1);
+ amr_bits[38] = (pj_uint8_t)((info->mode >> 1) & 1);
+ amr_bits[39] = (pj_uint8_t)((info->mode) & 1);
+ }
+
+ if (w_bitptr == 0) *w = 0;
+ for(j = 0; j < framelenbit_tbl[info->frame_type]; ++j) {
+ if (amr_bits[j])
+ *w |= (1 << (7-w_bitptr));
+
+ if (++w_bitptr == 8) {
+ w_bitptr = 0;
+ ++w;
+ *w = 0;
+ }
+ }
+ }
+
+ if (setting->octet_aligned) {
+ ++w;
+ w_bitptr = 0;
+ }
+ }
+
+ *pkt_size = w - (pj_uint8_t*)pkt;
+ if (w_bitptr)
+ *pkt_size += 1;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Parse AMR payload into frames.
+ *
+ * @param pkt Payload.
+ * @param pkt_size Payload size.
+ * @param ts Base timestamp.
+ * @param setting Settings, see @pjmedia_codec_amr_pack_setting.
+ * @param frames Frames parsed.
+ * @param nframes Number of frames parsed.
+ * @param cmr Change Mode Request message for local encoder.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_amr_parse(
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_timestamp *ts,
+ const pjmedia_codec_amr_pack_setting* setting,
+ pjmedia_frame frames[],
+ unsigned *nframes,
+ pj_uint8_t *cmr)
+{
+ unsigned cnt = 0;
+ pj_timestamp ts_ = *ts;
+
+ /* Read cursor */
+ pj_uint8_t r_bitptr = 0;
+ pj_uint8_t *r = (pj_uint8_t*)pkt;
+
+ /* env vars for AMR or AMRWB */
+ pj_uint8_t SID_FT;
+ const pj_uint8_t *framelen_tbl;
+ const pj_uint16_t *framelenbit_tbl;
+ const pj_int16_t* const *order_maps;
+
+ /* frame info */
+ pjmedia_codec_amr_bit_info *info;
+
+ if (setting->amr_nb) {
+ SID_FT = 8;
+ framelen_tbl = pjmedia_codec_amrnb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrnb_framelenbits;
+ order_maps = pjmedia_codec_amrnb_ordermaps;
+ } else {
+ SID_FT = 9;
+ framelen_tbl = pjmedia_codec_amrwb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrwb_framelenbits;
+ order_maps = pjmedia_codec_amrwb_ordermaps;
+ }
+
+ PJ_UNUSED_ARG(pkt_size);
+
+ /* Code Mode Request, 4 bits */
+ *cmr = (pj_uint8_t)((*r >> 4) & 0x0F);
+ r_bitptr = 4;
+ if (setting->octet_aligned) {
+ ++r;
+ r_bitptr = 0;
+ }
+
+ /* Table Of Contents, 6 bits each */
+ for (;;) {
+ pj_uint8_t TOC = 0;
+ pj_uint8_t F, FT, Q;
+
+ if (r_bitptr == 0) {
+ TOC = (pj_uint8_t)(*r >> 2);
+ r_bitptr = 6;
+ } else if (r_bitptr == 2) {
+ TOC = (pj_uint8_t)(*r++ & 0x3F);
+ r_bitptr = 0;
+ } else if (r_bitptr == 4) {
+ TOC = (pj_uint8_t)((*r++ & 0x0f) << 2);
+ TOC |= *r >> 6;
+ r_bitptr = 2;
+ } else if (r_bitptr == 6) {
+ TOC = (pj_uint8_t)((*r++ & 0x03) << 4);
+ TOC |= *r >> 4;
+ r_bitptr = 4;
+ }
+
+ F = (pj_uint8_t)(TOC >> 5);
+ FT = (pj_uint8_t)((TOC >> 1) & 0x0F);
+ Q = (pj_uint8_t)(TOC & 1);
+
+ if (FT > SID_FT && FT < 14) {
+ pj_assert(!"Invalid AMR frametype, stream may be corrupted!");
+ break;
+ }
+
+ if (setting->octet_aligned) {
+ ++r;
+ r_bitptr = 0;
+ }
+
+ /* Set frame attributes */
+ info = (pjmedia_codec_amr_bit_info*) &frames[cnt].bit_info;
+ info->frame_type = FT;
+ info->mode = (pj_int8_t)((FT < SID_FT)? FT : -1);
+ info->good_quality = (pj_uint8_t)(Q == 1);
+ info->start_bit = 0;
+ frames[cnt].timestamp = ts_;
+ frames[cnt].type = PJMEDIA_FRAME_TYPE_AUDIO;
+
+ /* AMR frame length is 20ms */
+ ts_.u64 += setting->amr_nb? 160 : 320;
+
+ if (++cnt == *nframes || !F)
+ break;
+ }
+ *nframes = cnt;
+
+ cnt = 0;
+
+ /* Speech frames */
+ while (cnt < *nframes) {
+ pj_uint8_t FT;
+
+ info = (pjmedia_codec_amr_bit_info*) &frames[cnt].bit_info;
+ FT = info->frame_type;
+
+ frames[cnt].buf = r;
+ info->start_bit = r_bitptr;
+
+ if (setting->octet_aligned) {
+ r += framelen_tbl[FT];
+ frames[cnt].size = framelen_tbl[FT];
+ } else {
+ if (FT == 14 || FT == 15) {
+ /* NO DATA */
+ frames[cnt].size = 0;
+ } else {
+ unsigned adv_bit;
+
+ adv_bit = framelenbit_tbl[FT] + r_bitptr;
+ r += adv_bit >> 3;
+ r_bitptr = (pj_uint8_t)(adv_bit % 8);
+
+ frames[cnt].size = adv_bit >> 3;
+ if (r_bitptr)
+ ++frames[cnt].size;
+ }
+ }
+ ++cnt;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_AMR_HELPER_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config.h
new file mode 100644
index 0000000..5a22a7d
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config.h
@@ -0,0 +1,316 @@
+/* $Id: config.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_CONFIG_H__
+#define __PJMEDIA_CODEC_CONFIG_H__
+
+/**
+ * @file config.h
+ * @brief PJMEDIA-CODEC compile time settings
+ */
+
+/**
+ * @defgroup pjmedia_codec_config PJMEDIA-CODEC Compile Time Settings
+ * @ingroup PJMEDIA_CODEC
+ * @brief Various compile time settings such as to enable/disable codecs
+ * @{
+ */
+
+#include <pjmedia/types.h>
+
+
+/*
+ * Include config_auto.h if autoconf is used (PJ_AUTOCONF is set)
+ */
+#if defined(PJ_AUTOCONF)
+# include <pjmedia-codec/config_auto.h>
+#endif
+
+/**
+ * Unless specified otherwise, L16 codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_L16_CODEC
+# define PJMEDIA_HAS_L16_CODEC 1
+#endif
+
+
+/**
+ * Unless specified otherwise, GSM codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_GSM_CODEC
+# define PJMEDIA_HAS_GSM_CODEC 1
+#endif
+
+
+/**
+ * Unless specified otherwise, Speex codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_SPEEX_CODEC
+# define PJMEDIA_HAS_SPEEX_CODEC 1
+#endif
+
+/**
+ * Speex codec default complexity setting.
+ */
+#ifndef PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY
+# define PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY 2
+#endif
+
+/**
+ * Speex codec default quality setting. Please note that pjsua-lib may override
+ * this setting via its codec quality setting (i.e PJSUA_DEFAULT_CODEC_QUALITY).
+ */
+#ifndef PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY
+# define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 8
+#endif
+
+
+/**
+ * Unless specified otherwise, iLBC codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_ILBC_CODEC
+# define PJMEDIA_HAS_ILBC_CODEC 1
+#endif
+
+
+/**
+ * Unless specified otherwise, G.722 codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_G722_CODEC
+# define PJMEDIA_HAS_G722_CODEC 1
+#endif
+
+
+/**
+ * Enable the features provided by Intel IPP libraries, for example
+ * codecs such as G.729, G.723.1, G.726, G.728, G.722.1, and AMR.
+ *
+ * By default this is disabled. Please follow the instructions in
+ * http://trac.pjsip.org/repos/wiki/Intel_IPP_Codecs on how to setup
+ * Intel IPP with PJMEDIA.
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP
+# define PJMEDIA_HAS_INTEL_IPP 0
+#endif
+
+
+/**
+ * Visual Studio only: when this option is set, the Intel IPP libraries
+ * will be automatically linked to application using pragma(comment)
+ * constructs. This is convenient, however it will only link with
+ * the stub libraries and the Intel IPP DLL's will be required when
+ * distributing the application.
+ *
+ * If application wants to link with the different types of the Intel IPP
+ * libraries (for example, the static libraries), it must set this option
+ * to zero and specify the Intel IPP libraries in the application's input
+ * library specification manually.
+ *
+ * Default 1.
+ */
+#ifndef PJMEDIA_AUTO_LINK_IPP_LIBS
+# define PJMEDIA_AUTO_LINK_IPP_LIBS 1
+#endif
+
+
+/**
+ * Enable Intel IPP AMR codec. This also needs to be enabled when AMR WB
+ * codec is enabled. This option is only used when PJMEDIA_HAS_INTEL_IPP
+ * is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_AMR 1
+#endif
+
+
+/**
+ * Enable Intel IPP AMR wideband codec. The PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
+ * option must also be enabled to use this codec. This option is only used
+ * when PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.729 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G729
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G729 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.723.1 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.726 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G726
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G726 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.728 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G728
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G728 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.722.1 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 1
+#endif
+
+/**
+ * Enable Passthrough codecs.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODECS
+# define PJMEDIA_HAS_PASSTHROUGH_CODECS 0
+#endif
+
+/**
+ * Enable AMR passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 1
+#endif
+
+/**
+ * Enable G.729 passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_G729
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 1
+#endif
+
+/**
+ * Enable iLBC passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 1
+#endif
+
+/**
+ * Enable PCMU passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1
+#endif
+
+/**
+ * Enable PCMA passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1
+#endif
+
+/* If passthrough and PCMU/PCMA are enabled, disable the software
+ * G.711 codec
+ */
+#if PJMEDIA_HAS_PASSTHROUGH_CODECS && \
+ (PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU || PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA)
+# undef PJMEDIA_HAS_G711_CODEC
+# define PJMEDIA_HAS_G711_CODEC 0
+#endif
+
+
+/**
+ * G.722.1 codec is disabled by default.
+ */
+#ifndef PJMEDIA_HAS_G7221_CODEC
+# define PJMEDIA_HAS_G7221_CODEC 0
+#endif
+
+/**
+ * Default G.722.1 codec encoder and decoder level adjustment.
+ * If the value is non-zero, then PCM input samples to the encoder will
+ * be shifted right by this value, and similarly PCM output samples from
+ * the decoder will be shifted left by this value.
+ *
+ * This can be changed at run-time after initialization by calling
+ * #pjmedia_codec_g7221_set_pcm_shift().
+ */
+#ifndef PJMEDIA_G7221_DEFAULT_PCM_SHIFT
+# define PJMEDIA_G7221_DEFAULT_PCM_SHIFT 1
+#endif
+
+
+/**
+ * Enabling both G.722.1 codec implementations, internal PJMEDIA and IPP,
+ * may cause problem in SDP, i.e: payload types duplications. So, let's
+ * just trap such case here at compile time.
+ *
+ * Application can control which implementation to be used by manipulating
+ * PJMEDIA_HAS_G7221_CODEC and PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 in
+ * config_site.h.
+ */
+#if (PJMEDIA_HAS_G7221_CODEC != 0) && (PJMEDIA_HAS_INTEL_IPP != 0) && \
+ (PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 != 0)
+# error Only one G.722.1 implementation can be enabled at the same time. \
+ Please use PJMEDIA_HAS_G7221_CODEC and \
+ PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 in your config_site.h \
+ to control which implementation to be used.
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_CONFIG_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config_auto.h.in b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config_auto.h.in
new file mode 100644
index 0000000..db6cb80
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config_auto.h.in
@@ -0,0 +1,71 @@
+/* $Id: config_auto.h.in 2601 2009-04-15 14:45:41Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_CONFIG_AUTO_H_
+#define __PJMEDIA_CODEC_CONFIG_AUTO_H_
+
+/**
+ * @file config_auto.h
+ * @brief PJMEDIA-CODEC configuration as set by autoconf script
+ */
+
+/*
+ * Note:
+ * The configuration in config_site.h overrides any other settings,
+ * including the setting as detected by autoconf.
+ */
+
+/* L16 codec */
+#ifndef PJMEDIA_HAS_L16_CODEC
+#undef PJMEDIA_HAS_L16_CODEC
+#endif
+
+
+/* GSM codec */
+#ifndef PJMEDIA_HAS_GSM_CODEC
+#undef PJMEDIA_HAS_GSM_CODEC
+#endif
+
+
+/* Speex codec */
+#ifndef PJMEDIA_HAS_SPEEX_CODEC
+#undef PJMEDIA_HAS_SPEEX_CODEC
+#endif
+
+
+/* iLBC codec */
+#ifndef PJMEDIA_HAS_ILBC_CODEC
+#undef PJMEDIA_HAS_ILBC_CODEC
+#endif
+
+
+/* G722 codec */
+#ifndef PJMEDIA_HAS_G722_CODEC
+#undef PJMEDIA_HAS_G722_CODEC
+#endif
+
+/* G7221 codec */
+#ifndef PJMEDIA_HAS_G7221_CODEC
+#undef PJMEDIA_HAS_G7221_CODEC
+#endif
+
+
+#endif /* __PJMEDIA_CODEC_CONFIG_AUTO_H_ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g722.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g722.h
new file mode 100644
index 0000000..42f0311
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g722.h
@@ -0,0 +1,74 @@
+/* $Id: g722.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_G722_H__
+#define __PJMEDIA_CODEC_G722_H__
+
+/**
+ * @file pjmedia-codec/g722.h
+ * @brief G.722 codec.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_G722 G.722 Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of G.722 Codec
+ * @{
+ *
+ * This section describes functions to register and register G.722 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * The G.722 codec implementation is provided as part of pjmedia-codec
+ * library, and does not depend on external G.722 codec implementation.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register G.722 codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g722_init(pjmedia_endpt *endpt);
+
+
+/**
+ * Unregister G.722 codec factory from pjmedia endpoint and cleanup
+ * resources allocated by the factory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g722_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_G722_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g7221.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g7221.h
new file mode 100644
index 0000000..0384563
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g7221.h
@@ -0,0 +1,128 @@
+/* $Id: g7221.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODECS_G7221_H__
+#define __PJMEDIA_CODECS_G7221_H__
+
+/**
+ * @file pjmedia-codec/g7221.h
+ * @brief G722.1 codec.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_G7221_CODEC G722.1 Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of G722.1 codec
+ * @{
+ *
+ * <b>G722.1 licensed from Polycom®</b>
+ * <b>G722.1 Annex C licensed from Polycom®</b>
+ *
+ * This section describes functions to register and register G722.1 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * PJMEDIA G722.1 codec implementation is based on ITU-T Recommendation
+ * G.722.1 (05/2005) C fixed point implementation including its Annex C.
+ *
+ * G722.1 is a low complexity codec that supports for 7kHz and 14kHz bandwidth
+ * audio signals working at bitrates ranging from 16kbps to 48kbps. It may be
+ * used with speech or music inputs.
+ *
+ * The codec implementation supports for standard and non-standard bitrates.
+ * By default, the standard bitrates are enabled upon initialization, i.e.:
+ * - 24kbps and 32kbps for audio bandwidth 7 kHz (16kHz sampling rate),
+ * - 24kbps, 32kbps, and 48kbps for audio bandwidth 14 kHz (32kHz sampling
+ * rate).
+ * The usage of non-standard bitrates must follow this requirements:
+ * - for sampling rate 16kHz: 16000 to 32000 bps, it must be a multiple of 400
+ * - for sampling rate 32kHz: 24000 to 48000 bps, it must be a multiple of 400
+ * Note that currently it is only up to two non-standard modes can be enabled
+ * at one time.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Initialize and register G722.1 codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g7221_init( pjmedia_endpt *endpt );
+
+
+/**
+ * Enable and disable G722.1 mode. By default, the standard modes are
+ * enabled upon initialization, i.e.:
+ * - sampling rate 16kHz, bitrate 24kbps and 32kbps.
+ * - sampling rate 32kHz, bitrate 24kbps, 32kbps, and 48kbps.
+ * This function can also be used for enabling non-standard modes.
+ * Note that currently it is only up to two non-standard modes can be
+ * enabled at one time.
+ *
+ * @param sample_rate PCM sampling rate, in Hz, valid values are only
+ * 16000 and 32000.
+ * @param bitrate G722.1 bitrate, in bps, the valid values are
+ * standard and non-standard bitrates as described
+ * above.
+ * @param enabled PJ_TRUE for enabling specified mode.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate,
+ unsigned bitrate,
+ pj_bool_t enabled);
+
+/**
+ * Set the G.722.1 codec encoder and decoder level adjustment.
+ * If the value is non-zero, then PCM input samples to the encoder will
+ * be shifted right by this value, and similarly PCM output samples from
+ * the decoder will be shifted left by this value.
+ *
+ * Default value is PJMEDIA_G7221_DEFAULT_PCM_SHIFT.
+ *
+ * @param val The value
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g7221_set_pcm_shift(int val);
+
+
+
+/**
+ * Unregister G722.1 codecs factory from pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g7221_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_G7221_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/gsm.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/gsm.h
new file mode 100644
index 0000000..7555fd5
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/gsm.h
@@ -0,0 +1,72 @@
+/* $Id: gsm.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_GSM_H__
+#define __PJMEDIA_CODEC_GSM_H__
+
+/**
+ * @file pjmedia-codec/gsm.h
+ * @brief GSM 06.10 codec.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_GSM GSM 06.10 Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of GSM FR based on GSM 06.10 library
+ * @{
+ *
+ * This section describes functions to register and register GSM codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register GSM codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_gsm_init( pjmedia_endpt *endpt );
+
+
+
+/**
+ * Unregister GSM codec factory from pjmedia endpoint and deinitialize
+ * the GSM codec library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_gsm_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_GSM_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ilbc.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ilbc.h
new file mode 100644
index 0000000..b9ad150
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ilbc.h
@@ -0,0 +1,76 @@
+/* $Id: ilbc.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_ILBC_H__
+#define __PJMEDIA_CODEC_ILBC_H__
+
+/**
+ * @file pjmedia-codec/ilbc.h
+ * @brief iLBC codec.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_ILBC iLBC Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of iLBC Codec
+ * @{
+ *
+ * This section describes functions to register and register iLBC codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register iLBC codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ * @param mode Default decoder mode to be used. Valid values are
+ * 20 and 30 ms. Note that encoder mode follows the
+ * setting advertised in the remote's SDP.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ilbc_init( pjmedia_endpt *endpt,
+ int mode );
+
+
+
+/**
+ * Unregister iLBC codec factory from pjmedia endpoint and deinitialize
+ * the iLBC codec library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ilbc_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_ILBC_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ipp_codecs.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ipp_codecs.h
new file mode 100644
index 0000000..1936c88
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ipp_codecs.h
@@ -0,0 +1,73 @@
+/* $Id: ipp_codecs.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODECS_IPP_H__
+#define __PJMEDIA_CODECS_IPP_H__
+
+/**
+ * @file pjmedia-codec/ipp_codecs.h
+ * @brief IPP codecs wrapper.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_IPP_CODEC IPP Codecs
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of IPP codecs
+ * @{
+ *
+ * This section describes functions to register and register IPP codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ * This codec factory contains various codecs, e.g: G.729, G.723.1, G.726,
+ * G.728, G.722.1, AMR.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Initialize and register IPP codecs factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ipp_init( pjmedia_endpt *endpt );
+
+
+
+/**
+ * Unregister IPP codecs factory from pjmedia endpoint and deinitialize
+ * the IPP codecs library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ipp_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_IPP_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/l16.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/l16.h
new file mode 100644
index 0000000..ce49270
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/l16.h
@@ -0,0 +1,69 @@
+/* $Id: l16.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_L16_H__
+#define __PJMEDIA_CODEC_L16_H__
+
+#include <pjmedia-codec/types.h>
+
+
+/**
+ * @defgroup PJMED_L16 L16 Codec Family
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief PCM/16bit/linear codecs
+ * @{
+ *
+ * This section describes functions to register and register L16 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * Note that the L16 codec factory registers several (about fourteen!)
+ * L16 codec types to codec manager (different combinations of clock
+ * rate and number of channels).
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register L16 codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ * @param options Must be zero for now.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_l16_init( pjmedia_endpt *endpt,
+ unsigned options);
+
+
+
+/**
+ * Unregister L16 codec factory from pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_l16_deinit(void);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_CODEC_L16_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/passthrough.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/passthrough.h
new file mode 100644
index 0000000..ea8c046
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/passthrough.h
@@ -0,0 +1,106 @@
+/* $Id: passthrough.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODECS_PASSTHROUGH_H__
+#define __PJMEDIA_CODECS_PASSTHROUGH_H__
+
+/**
+ * @file pjmedia-codec/passthrough.h
+ * @brief Passthrough codecs.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_PASSTHROUGH_CODEC Passthrough Codecs
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of passthrough codecs
+ * @{
+ *
+ * This section describes functions to register and register passthrough
+ * codecs factory to the codec manager. After the codec factory has been
+ * registered, application can use @ref PJMEDIA_CODEC API to manipulate
+ * the codec. This codec factory contains various codecs, e.g: G.729, iLBC,
+ * AMR, and G.711.
+ *
+ * Passthrough codecs are codecs wrapper that does not perform encoding
+ * or decoding, it just pack and parse encoded audio data from/into RTP
+ * payload. This will accomodate pjmedia ports which work with encoded
+ * audio data, e.g: encoded audio files, sound device with capability
+ * of playing/recording encoded audio data.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Codec passthrough configuration settings.
+ */
+typedef struct pjmedia_codec_passthrough_setting
+{
+ unsigned fmt_cnt; /**< Number of encoding formats
+ to be enabled. */
+ pjmedia_format *fmts; /**< Encoding formats to be
+ enabled. */
+ unsigned ilbc_mode; /**< iLBC default mode. */
+} pjmedia_codec_passthrough_setting;
+
+
+/**
+ * Initialize and register passthrough codecs factory to pjmedia endpoint,
+ * all supported encoding formats will be enabled.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_passthrough_init( pjmedia_endpt *endpt );
+
+
+/**
+ * Initialize and register passthrough codecs factory to pjmedia endpoint
+ * with only specified encoding formats enabled.
+ *
+ * @param endpt The pjmedia endpoint.
+ * @param setting The settings, see @pjmedia_codec_passthrough_setting.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_passthrough_init2(
+ pjmedia_endpt *endpt,
+ const pjmedia_codec_passthrough_setting *setting);
+
+
+/**
+ * Unregister passthrough codecs factory from pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_passthrough_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_PASSTHROUGH_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/speex.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/speex.h
new file mode 100644
index 0000000..a08b8c1
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/speex.h
@@ -0,0 +1,121 @@
+/* $Id: speex.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_SPEEX_H__
+#define __PJMEDIA_CODEC_SPEEX_H__
+
+/**
+ * @file speex.h
+ * @brief Speex codec header.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_SPEEX Speex Codec Family
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of Speex codecs (narrow/wide/ultrawide-band).
+ * @{
+ *
+ * This section describes functions to register and register speex codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * By default, the speex codec factory registers three Speex codecs:
+ * "speex/8000" narrowband codec, "speex/16000" wideband codec, and
+ * "speex/32000" ultra-wideband codec. This behavior can be changed by
+ * specifying #pjmedia_speex_options flags during initialization.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Bitmask options to be passed during Speex codec factory initialization.
+ */
+enum pjmedia_speex_options
+{
+ PJMEDIA_SPEEX_NO_NB = 1, /**< Disable narrowband mode. */
+ PJMEDIA_SPEEX_NO_WB = 2, /**< Disable wideband mode. */
+ PJMEDIA_SPEEX_NO_UWB = 4, /**< Disable ultra-wideband mode. */
+};
+
+
+/**
+ * Initialize and register Speex codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ * @param options Bitmask of pjmedia_speex_options (default=0).
+ * @param quality Specify encoding quality, or use -1 for default
+ * (@see PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY).
+ * @param complexity Specify encoding complexity , or use -1 for default
+ * (@see PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_speex_init( pjmedia_endpt *endpt,
+ unsigned options,
+ int quality,
+ int complexity );
+
+
+/**
+ * Initialize Speex codec factory using default settings and register to
+ * pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_speex_init_default(pjmedia_endpt *endpt);
+
+
+/**
+ * Change the settings of Speex codec.
+ *
+ * @param clock_rate Clock rate of Speex mode to be set.
+ * @param quality Specify encoding quality, or use -1 for default
+ * (@see PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY).
+ * @param complexity Specify encoding complexity , or use -1 for default
+ * (@see PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_speex_set_param(unsigned clock_rate,
+ int quality,
+ int complexity);
+
+
+/**
+ * Unregister Speex codec factory from pjmedia endpoint and deinitialize
+ * the Speex codec library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_speex_deinit(void);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_SPEEX_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/types.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/types.h
new file mode 100644
index 0000000..04079ac
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/types.h
@@ -0,0 +1,93 @@
+/* $Id: types.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_TYPES_H__
+#define __PJMEDIA_CODEC_TYPES_H__
+
+/**
+ * @file types.h
+ * @brief PJMEDIA-CODEC types and constants
+ */
+
+#include <pjmedia-codec/config.h>
+
+/**
+ * @defgroup pjmedia_codec_types PJMEDIA-CODEC Types and Constants
+ * @ingroup PJMEDIA_CODEC
+ * @brief Constants used by PJMEDIA-CODEC
+ * @{
+ */
+
+
+
+/**
+ * These are the dynamic payload types that are used by codecs in
+ * this library. Also see the header file <pjmedia/codec.h> for list
+ * of static payload types.
+ */
+enum
+{
+ /* PJMEDIA_RTP_PT_TELEPHONE_EVENTS is declared in
+ * <pjmedia/config.h>
+ */
+#if PJMEDIA_RTP_PT_TELEPHONE_EVENTS
+ PJMEDIA_RTP_PT_START = PJMEDIA_RTP_PT_TELEPHONE_EVENTS,
+#else
+ PJMEDIA_RTP_PT_START = 102,
+#endif
+
+ PJMEDIA_RTP_PT_SPEEX_NB, /**< Speex narrowband/8KHz */
+ PJMEDIA_RTP_PT_SPEEX_WB, /**< Speex wideband/16KHz */
+ PJMEDIA_RTP_PT_SPEEX_UWB, /**< Speex 32KHz */
+ PJMEDIA_RTP_PT_L16_8KHZ_MONO, /**< L16 @ 8KHz, mono */
+ PJMEDIA_RTP_PT_L16_8KHZ_STEREO, /**< L16 @ 8KHz, stereo */
+ //PJMEDIA_RTP_PT_L16_11KHZ_MONO, /**< L16 @ 11KHz, mono */
+ //PJMEDIA_RTP_PT_L16_11KHZ_STEREO, /**< L16 @ 11KHz, stereo */
+ PJMEDIA_RTP_PT_L16_16KHZ_MONO, /**< L16 @ 16KHz, mono */
+ PJMEDIA_RTP_PT_L16_16KHZ_STEREO, /**< L16 @ 16KHz, stereo */
+ //PJMEDIA_RTP_PT_L16_22KHZ_MONO, /**< L16 @ 22KHz, mono */
+ //PJMEDIA_RTP_PT_L16_22KHZ_STEREO, /**< L16 @ 22KHz, stereo */
+ PJMEDIA_RTP_PT_L16_32KHZ_MONO, /**< L16 @ 32KHz, mono */
+ PJMEDIA_RTP_PT_L16_32KHZ_STEREO, /**< L16 @ 32KHz, stereo */
+ PJMEDIA_RTP_PT_L16_48KHZ_MONO, /**< L16 @ 48KHz, mono */
+ PJMEDIA_RTP_PT_L16_48KHZ_STEREO, /**< L16 @ 48KHz, stereo */
+ PJMEDIA_RTP_PT_ILBC, /**< iLBC (13.3/15.2Kbps) */
+ PJMEDIA_RTP_PT_AMR, /**< AMR (4.75 - 12.2Kbps) */
+ PJMEDIA_RTP_PT_AMRWB, /**< AMRWB (6.6 - 23.85Kbps)*/
+ PJMEDIA_RTP_PT_AMRWBE, /**< AMRWBE */
+ PJMEDIA_RTP_PT_G726_16, /**< G726 @ 16Kbps */
+ PJMEDIA_RTP_PT_G726_24, /**< G726 @ 24Kbps */
+ /* PJMEDIA_RTP_PT_G726_32,*/ /**< G726 @ 32Kbps, static? */
+ PJMEDIA_RTP_PT_G726_40, /**< G726 @ 40Kbps */
+ PJMEDIA_RTP_PT_G722_1_16, /**< G722.1 (16Kbps) */
+ PJMEDIA_RTP_PT_G722_1_24, /**< G722.1 (24Kbps) */
+ PJMEDIA_RTP_PT_G722_1_32, /**< G722.1 (32Kbps) */
+ PJMEDIA_RTP_PT_G7221C_24, /**< G722.1 Annex C (24Kbps)*/
+ PJMEDIA_RTP_PT_G7221C_32, /**< G722.1 Annex C (32Kbps)*/
+ PJMEDIA_RTP_PT_G7221C_48, /**< G722.1 Annex C (48Kbps)*/
+ PJMEDIA_RTP_PT_G7221_RSV1, /**< G722.1 reserve */
+ PJMEDIA_RTP_PT_G7221_RSV2, /**< G722.1 reserve */
+};
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CODEC_TYPES_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia.h
new file mode 100644
index 0000000..09f2a46
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia.h
@@ -0,0 +1,73 @@
+/* $Id: pjmedia.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_H__
+#define __PJMEDIA_H__
+
+/**
+ * @file pjmedia.h
+ * @brief PJMEDIA main header file.
+ */
+
+#include <pjmedia/types.h>
+#include <pjmedia/alaw_ulaw.h>
+#include <pjmedia/bidirectional.h>
+#include <pjmedia/circbuf.h>
+#include <pjmedia/clock.h>
+#include <pjmedia/codec.h>
+#include <pjmedia/conference.h>
+#include <pjmedia/delaybuf.h>
+#include <pjmedia/echo.h>
+#include <pjmedia/echo_port.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/endpoint.h>
+#include <pjmedia/g711.h>
+#include <pjmedia/jbuf.h>
+#include <pjmedia/master_port.h>
+#include <pjmedia/mem_port.h>
+#include <pjmedia/null_port.h>
+#include <pjmedia/plc.h>
+#include <pjmedia/port.h>
+#include <pjmedia/resample.h>
+#include <pjmedia/rtcp.h>
+#include <pjmedia/rtcp_xr.h>
+#include <pjmedia/rtp.h>
+#include <pjmedia/sdp.h>
+#include <pjmedia/sdp_neg.h>
+#include <pjmedia/session.h>
+#include <pjmedia/silencedet.h>
+#include <pjmedia/sound.h>
+#include <pjmedia/sound_port.h>
+#include <pjmedia/splitcomb.h>
+#include <pjmedia/stereo.h>
+#include <pjmedia/stream.h>
+#include <pjmedia/tonegen.h>
+#include <pjmedia/transport.h>
+#include <pjmedia/transport_adapter_sample.h>
+#include <pjmedia/transport_ice.h>
+#include <pjmedia/transport_loop.h>
+#include <pjmedia/transport_srtp.h>
+#include <pjmedia/transport_udp.h>
+#include <pjmedia/wav_playlist.h>
+#include <pjmedia/wav_port.h>
+#include <pjmedia/wave.h>
+#include <pjmedia/wsola.h>
+
+#endif /* __PJMEDIA_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/alaw_ulaw.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/alaw_ulaw.h
new file mode 100644
index 0000000..015722e
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/alaw_ulaw.h
@@ -0,0 +1,213 @@
+/* $Id: alaw_ulaw.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_ALAW_ULAW_H__
+#define __PJMEDIA_ALAW_ULAW_H__
+
+#include <pjmedia/types.h>
+
+PJ_BEGIN_DECL
+
+#if defined(PJMEDIA_HAS_ALAW_ULAW_TABLE) && PJMEDIA_HAS_ALAW_ULAW_TABLE!=0
+
+extern const pj_uint8_t pjmedia_linear2ulaw_tab[16384];
+extern const pj_uint8_t pjmedia_linear2alaw_tab[16384];
+extern const pj_int16_t pjmedia_ulaw2linear_tab[256];
+extern const pj_int16_t pjmedia_alaw2linear_tab[256];
+
+
+/**
+ * Convert 16-bit linear PCM value to 8-bit A-Law.
+ *
+ * @param pcm_val 16-bit linear PCM value.
+ * @return 8-bit A-Law value.
+ */
+#define pjmedia_linear2alaw(pcm_val) \
+ pjmedia_linear2alaw_tab[(((pj_int16_t)pcm_val) >> 2) & 0x3fff]
+
+/**
+ * Convert 8-bit A-Law value to 16-bit linear PCM value.
+ *
+ * @param chara_val 8-bit A-Law value.
+ * @return 16-bit linear PCM value.
+ */
+#define pjmedia_alaw2linear(chara_val) \
+ pjmedia_alaw2linear_tab[chara_val]
+
+/**
+ * Convert 16-bit linear PCM value to 8-bit U-Law.
+ *
+ * @param pcm_val 16-bit linear PCM value.
+ * @return U-bit A-Law value.
+ */
+#define pjmedia_linear2ulaw(pcm_val) \
+ pjmedia_linear2ulaw_tab[(((pj_int16_t)pcm_val) >> 2) & 0x3fff]
+
+/**
+ * Convert 8-bit U-Law value to 16-bit linear PCM value.
+ *
+ * @param u_val 8-bit U-Law value.
+ * @return 16-bit linear PCM value.
+ */
+#define pjmedia_ulaw2linear(u_val) \
+ pjmedia_ulaw2linear_tab[u_val]
+
+/**
+ * Convert 8-bit A-Law value to 8-bit U-Law value.
+ *
+ * @param aval 8-bit A-Law value.
+ * @return 8-bit U-Law value.
+ */
+#define pjmedia_alaw2ulaw(aval) \
+ pjmedia_linear2ulaw(pjmedia_alaw2linear(aval))
+
+/**
+ * Convert 8-bit U-Law value to 8-bit A-Law value.
+ *
+ * @param uval 8-bit U-Law value.
+ * @return 8-bit A-Law value.
+ */
+#define pjmedia_ulaw2alaw(uval) \
+ pjmedia_linear2alaw(pjmedia_ulaw2linear(uval))
+
+
+#else
+
+/**
+ * Convert 16-bit linear PCM value to 8-bit A-Law.
+ *
+ * @param pcm_val 16-bit linear PCM value.
+ * @return 8-bit A-Law value.
+ */
+PJ_DECL(pj_uint8_t) pjmedia_linear2alaw(int pcm_val);
+
+/**
+ * Convert 8-bit A-Law value to 16-bit linear PCM value.
+ *
+ * @param chara_val 8-bit A-Law value.
+ * @return 16-bit linear PCM value.
+ */
+PJ_DECL(int) pjmedia_alaw2linear(unsigned chara_val);
+
+/**
+ * Convert 16-bit linear PCM value to 8-bit U-Law.
+ *
+ * @param pcm_val 16-bit linear PCM value.
+ * @return U-bit A-Law value.
+ */
+PJ_DECL(unsigned char) pjmedia_linear2ulaw(int pcm_val);
+
+/**
+ * Convert 8-bit U-Law value to 16-bit linear PCM value.
+ *
+ * @param u_val 8-bit U-Law value.
+ * @return 16-bit linear PCM value.
+ */
+PJ_DECL(int) pjmedia_ulaw2linear(unsigned char u_val);
+
+/**
+ * Convert 8-bit A-Law value to 8-bit U-Law value.
+ *
+ * @param aval 8-bit A-Law value.
+ * @return 8-bit U-Law value.
+ */
+PJ_DECL(unsigned char) pjmedia_alaw2ulaw(unsigned char aval);
+
+/**
+ * Convert 8-bit U-Law value to 8-bit A-Law value.
+ *
+ * @param uval 8-bit U-Law value.
+ * @return 8-bit A-Law value.
+ */
+PJ_DECL(unsigned char) pjmedia_ulaw2alaw(unsigned char uval);
+
+#endif
+
+/**
+ * Encode 16-bit linear PCM data to 8-bit U-Law data.
+ *
+ * @param dst Destination buffer for 8-bit U-Law data.
+ * @param src Source, 16-bit linear PCM data.
+ * @param count Number of samples.
+ */
+PJ_INLINE(void) pjmedia_ulaw_encode(pj_uint8_t *dst, const pj_int16_t *src,
+ pj_size_t count)
+{
+ const pj_int16_t *end = src + count;
+
+ while (src < end) {
+ *dst++ = pjmedia_linear2ulaw(*src++);
+ }
+}
+
+/**
+ * Encode 16-bit linear PCM data to 8-bit A-Law data.
+ *
+ * @param dst Destination buffer for 8-bit A-Law data.
+ * @param src Source, 16-bit linear PCM data.
+ * @param count Number of samples.
+ */
+PJ_INLINE(void) pjmedia_alaw_encode(pj_uint8_t *dst, const pj_int16_t *src,
+ pj_size_t count)
+{
+ const pj_int16_t *end = src + count;
+
+ while (src < end) {
+ *dst++ = pjmedia_linear2alaw(*src++);
+ }
+}
+
+/**
+ * Decode 8-bit U-Law data to 16-bit linear PCM data.
+ *
+ * @param dst Destination buffer for 16-bit PCM data.
+ * @param src Source, 8-bit U-Law data.
+ * @param len Encoded frame/source length in bytes.
+ */
+PJ_INLINE(void) pjmedia_ulaw_decode(pj_int16_t *dst, const pj_uint8_t *src,
+ pj_size_t len)
+{
+ const pj_uint8_t *end = src + len;
+
+ while (src < end) {
+ *dst++ = pjmedia_ulaw2linear(*src++);
+ }
+}
+
+/**
+ * Decode 8-bit A-Law data to 16-bit linear PCM data.
+ *
+ * @param dst Destination buffer for 16-bit PCM data.
+ * @param src Source, 8-bit A-Law data.
+ * @param len Encoded frame/source length in bytes.
+ */
+PJ_INLINE(void) pjmedia_alaw_decode(pj_int16_t *dst, const pj_uint8_t *src,
+ pj_size_t len)
+{
+ const pj_uint8_t *end = src + len;
+
+ while (src < end) {
+ *dst++ = pjmedia_alaw2linear(*src++);
+ }
+}
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_ALAW_ULAW_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/bidirectional.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/bidirectional.h
new file mode 100644
index 0000000..a374540
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/bidirectional.h
@@ -0,0 +1,67 @@
+/* $Id: bidirectional.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_BIDIRECTIONAL_H__
+#define __PJMEDIA_BIDIRECTIONAL_H__
+
+/**
+ * @file bidirectional.h
+ * @brief Bidirectional media port.
+ */
+#include <pjmedia/port.h>
+
+
+/**
+ * @defgroup PJMEDIA_BIDIRECTIONAL_PORT Bidirectional Port
+ * @ingroup PJMEDIA_PORT
+ * @brief A bidirectional port combines two unidirectional ports into one
+ * bidirectional port
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create bidirectional port from two unidirectional ports
+ *
+ * @param pool Pool to allocate memory.
+ * @param get_port Port where get_frame() will be directed to.
+ * @param put_port Port where put_frame() will be directed to.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_bidirectional_port_create(pj_pool_t *pool,
+ pjmedia_port *get_port,
+ pjmedia_port *put_port,
+ pjmedia_port **p_port );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_BIDIRECTIONAL_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/circbuf.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/circbuf.h
new file mode 100644
index 0000000..b036280
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/circbuf.h
@@ -0,0 +1,435 @@
+/* $Id: circbuf.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CIRC_BUF_H__
+#define __PJMEDIA_CIRC_BUF_H__
+
+/**
+ * @file circbuf.h
+ * @brief Circular Buffer.
+ */
+
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/pool.h>
+
+/**
+ * @defgroup PJMED_CIRCBUF Circular Buffer
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Circular buffer manages read and write contiguous audio samples in a
+ * non-contiguous buffer as if the buffer were contiguous. This should give
+ * better performance than keeping contiguous samples in a contiguous buffer,
+ * since read/write operations will only update the pointers, instead of
+ * shifting audio samples.
+ *
+ * @{
+ *
+ * This section describes PJMEDIA's implementation of circular buffer.
+ */
+
+/* Algorithm checkings, for development purpose only */
+#if 0
+# define PJMEDIA_CIRC_BUF_CHECK(x) pj_assert(x)
+#else
+# define PJMEDIA_CIRC_BUF_CHECK(x)
+#endif
+
+PJ_BEGIN_DECL
+
+/**
+ * Circular buffer structure
+ */
+typedef struct pjmedia_circ_buf {
+ pj_int16_t *buf; /**< The buffer */
+ unsigned capacity; /**< Buffer capacity, in samples */
+
+ pj_int16_t *start; /**< Pointer to the first sample */
+ unsigned len; /**< Audio samples length,
+ in samples */
+} pjmedia_circ_buf;
+
+
+/**
+ * Create the circular buffer.
+ *
+ * @param pool Pool where the circular buffer will be allocated
+ * from.
+ * @param capacity Capacity of the buffer, in samples.
+ * @param p_cb Pointer to receive the circular buffer instance.
+ *
+ * @return PJ_SUCCESS if the circular buffer has been
+ * created successfully, otherwise the appropriate
+ * error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_create(pj_pool_t *pool,
+ unsigned capacity,
+ pjmedia_circ_buf **p_cb)
+{
+ pjmedia_circ_buf *cbuf;
+
+ cbuf = PJ_POOL_ZALLOC_T(pool, pjmedia_circ_buf);
+ cbuf->buf = (pj_int16_t*) pj_pool_calloc(pool, capacity,
+ sizeof(pj_int16_t));
+ cbuf->capacity = capacity;
+ cbuf->start = cbuf->buf;
+ cbuf->len = 0;
+
+ *p_cb = cbuf;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Reset the circular buffer.
+ *
+ * @param circbuf The circular buffer.
+ *
+ * @return PJ_SUCCESS when successful.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_reset(pjmedia_circ_buf *circbuf)
+{
+ circbuf->start = circbuf->buf;
+ circbuf->len = 0;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Get the circular buffer length, it is number of samples buffered in the
+ * circular buffer.
+ *
+ * @param circbuf The circular buffer.
+ *
+ * @return The buffer length.
+ */
+PJ_INLINE(unsigned) pjmedia_circ_buf_get_len(pjmedia_circ_buf *circbuf)
+{
+ return circbuf->len;
+}
+
+
+/**
+ * Set circular buffer length. This is useful when audio buffer is manually
+ * manipulated by the user, e.g: shrinked, expanded.
+ *
+ * @param circbuf The circular buffer.
+ * @param len The new buffer length.
+ */
+PJ_INLINE(void) pjmedia_circ_buf_set_len(pjmedia_circ_buf *circbuf,
+ unsigned len)
+{
+ PJMEDIA_CIRC_BUF_CHECK(len <= circbuf->capacity);
+ circbuf->len = len;
+}
+
+
+/**
+ * Advance the read pointer of circular buffer. This function will discard
+ * the skipped samples while advancing the read pointer, thus reducing
+ * the buffer length.
+ *
+ * @param circbuf The circular buffer.
+ * @param count Distance from current read pointer, can only be
+ * possitive number, in samples.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_adv_read_ptr(pjmedia_circ_buf *circbuf,
+ unsigned count)
+{
+ if (count >= circbuf->len)
+ return pjmedia_circ_buf_reset(circbuf);
+
+ PJMEDIA_CIRC_BUF_CHECK(count <= circbuf->len);
+
+ circbuf->start += count;
+ if (circbuf->start >= circbuf->buf + circbuf->capacity)
+ circbuf->start -= circbuf->capacity;
+ circbuf->len -= count;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Advance the write pointer of circular buffer. Since write pointer is always
+ * pointing to a sample after the end of sample, so this function also means
+ * increasing the buffer length.
+ *
+ * @param circbuf The circular buffer.
+ * @param count Distance from current write pointer, can only be
+ * possitive number, in samples.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_adv_write_ptr(pjmedia_circ_buf *circbuf,
+ unsigned count)
+{
+ if (count + circbuf->len > circbuf->capacity)
+ return PJ_ETOOBIG;
+
+ circbuf->len += count;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Get the real buffer addresses containing the audio samples.
+ *
+ * @param circbuf The circular buffer.
+ * @param reg1 Pointer to store the first buffer address.
+ * @param reg1_len Pointer to store the length of the first buffer,
+ * in samples.
+ * @param reg2 Pointer to store the second buffer address.
+ * @param reg2_len Pointer to store the length of the second buffer,
+ * in samples.
+ */
+PJ_INLINE(void) pjmedia_circ_buf_get_read_regions(pjmedia_circ_buf *circbuf,
+ pj_int16_t **reg1,
+ unsigned *reg1_len,
+ pj_int16_t **reg2,
+ unsigned *reg2_len)
+{
+ *reg1 = circbuf->start;
+ *reg1_len = circbuf->len;
+ if (*reg1 + *reg1_len > circbuf->buf + circbuf->capacity) {
+ *reg1_len = circbuf->buf + circbuf->capacity - circbuf->start;
+ *reg2 = circbuf->buf;
+ *reg2_len = circbuf->len - *reg1_len;
+ } else {
+ *reg2 = NULL;
+ *reg2_len = 0;
+ }
+
+ PJMEDIA_CIRC_BUF_CHECK(*reg1_len != 0 || (*reg1_len == 0 &&
+ circbuf->len == 0));
+ PJMEDIA_CIRC_BUF_CHECK(*reg1_len + *reg2_len == circbuf->len);
+}
+
+
+/**
+ * Get the real buffer addresses that is empty or writeable.
+ *
+ * @param circbuf The circular buffer.
+ * @param reg1 Pointer to store the first buffer address.
+ * @param reg1_len Pointer to store the length of the first buffer,
+ * in samples.
+ * @param reg2 Pointer to store the second buffer address.
+ * @param reg2_len Pointer to store the length of the second buffer,
+ * in samples.
+ */
+PJ_INLINE(void) pjmedia_circ_buf_get_write_regions(pjmedia_circ_buf *circbuf,
+ pj_int16_t **reg1,
+ unsigned *reg1_len,
+ pj_int16_t **reg2,
+ unsigned *reg2_len)
+{
+ *reg1 = circbuf->start + circbuf->len;
+ if (*reg1 >= circbuf->buf + circbuf->capacity)
+ *reg1 -= circbuf->capacity;
+ *reg1_len = circbuf->capacity - circbuf->len;
+ if (*reg1 + *reg1_len > circbuf->buf + circbuf->capacity) {
+ *reg1_len = circbuf->buf + circbuf->capacity - *reg1;
+ *reg2 = circbuf->buf;
+ *reg2_len = circbuf->start - circbuf->buf;
+ } else {
+ *reg2 = NULL;
+ *reg2_len = 0;
+ }
+
+ PJMEDIA_CIRC_BUF_CHECK(*reg1_len != 0 || (*reg1_len == 0 &&
+ circbuf->len == 0));
+ PJMEDIA_CIRC_BUF_CHECK(*reg1_len + *reg2_len == circbuf->capacity -
+ circbuf->len);
+}
+
+
+/**
+ * Read audio samples from the circular buffer.
+ *
+ * @param circbuf The circular buffer.
+ * @param data Buffer to store the read audio samples.
+ * @param count Number of samples being read.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_read(pjmedia_circ_buf *circbuf,
+ pj_int16_t *data,
+ unsigned count)
+{
+ pj_int16_t *reg1, *reg2;
+ unsigned reg1cnt, reg2cnt;
+
+ /* Data in the buffer is less than requested */
+ if (count > circbuf->len)
+ return PJ_ETOOBIG;
+
+ pjmedia_circ_buf_get_read_regions(circbuf, &reg1, &reg1cnt,
+ &reg2, &reg2cnt);
+ if (reg1cnt >= count) {
+ pjmedia_copy_samples(data, reg1, count);
+ } else {
+ pjmedia_copy_samples(data, reg1, reg1cnt);
+ pjmedia_copy_samples(data + reg1cnt, reg2, count - reg1cnt);
+ }
+
+ return pjmedia_circ_buf_adv_read_ptr(circbuf, count);
+}
+
+
+/**
+ * Write audio samples to the circular buffer.
+ *
+ * @param circbuf The circular buffer.
+ * @param data Audio samples to be written.
+ * @param count Number of samples being written.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_write(pjmedia_circ_buf *circbuf,
+ pj_int16_t *data,
+ unsigned count)
+{
+ pj_int16_t *reg1, *reg2;
+ unsigned reg1cnt, reg2cnt;
+
+ /* Data to write is larger than buffer can store */
+ if (count > circbuf->capacity - circbuf->len)
+ return PJ_ETOOBIG;
+
+ pjmedia_circ_buf_get_write_regions(circbuf, &reg1, &reg1cnt,
+ &reg2, &reg2cnt);
+ if (reg1cnt >= count) {
+ pjmedia_copy_samples(reg1, data, count);
+ } else {
+ pjmedia_copy_samples(reg1, data, reg1cnt);
+ pjmedia_copy_samples(reg2, data + reg1cnt, count - reg1cnt);
+ }
+
+ return pjmedia_circ_buf_adv_write_ptr(circbuf, count);
+}
+
+
+/**
+ * Copy audio samples from the circular buffer without changing its state.
+ *
+ * @param circbuf The circular buffer.
+ * @param start_idx Starting sample index to be copied.
+ * @param data Buffer to store the read audio samples.
+ * @param count Number of samples being read.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_copy(pjmedia_circ_buf *circbuf,
+ unsigned start_idx,
+ pj_int16_t *data,
+ unsigned count)
+{
+ pj_int16_t *reg1, *reg2;
+ unsigned reg1cnt, reg2cnt;
+
+ /* Data in the buffer is less than requested */
+ if (count + start_idx > circbuf->len)
+ return PJ_ETOOBIG;
+
+ pjmedia_circ_buf_get_read_regions(circbuf, &reg1, &reg1cnt,
+ &reg2, &reg2cnt);
+ if (reg1cnt > start_idx) {
+ unsigned tmp_len;
+ tmp_len = reg1cnt - start_idx;
+ if (tmp_len > count)
+ tmp_len = count;
+ pjmedia_copy_samples(data, reg1 + start_idx, tmp_len);
+ if (tmp_len < count)
+ pjmedia_copy_samples(data + tmp_len, reg2, count - tmp_len);
+ } else {
+ pjmedia_copy_samples(data, reg2 + start_idx - reg1cnt, count);
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Pack the buffer so the first sample will be in the beginning of the buffer.
+ * This will also make the buffer contiguous.
+ *
+ * @param circbuf The circular buffer.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_pack_buffer(pjmedia_circ_buf *circbuf)
+{
+ pj_int16_t *reg1, *reg2;
+ unsigned reg1cnt, reg2cnt;
+ unsigned gap;
+
+ pjmedia_circ_buf_get_read_regions(circbuf, &reg1, &reg1cnt,
+ &reg2, &reg2cnt);
+
+ /* Check if not contigue */
+ if (reg2cnt != 0) {
+ /* Check if no space left to roll the buffer
+ * (or should this function provide temporary buffer?)
+ */
+ gap = circbuf->capacity - pjmedia_circ_buf_get_len(circbuf);
+ if (gap == 0)
+ return PJ_ETOOBIG;
+
+ /* Roll buffer left using the gap until reg2cnt == 0 */
+ do {
+ if (gap > reg2cnt)
+ gap = reg2cnt;
+ pjmedia_move_samples(reg1 - gap, reg1, reg1cnt);
+ pjmedia_copy_samples(reg1 + reg1cnt - gap, reg2, gap);
+ if (gap < reg2cnt)
+ pjmedia_move_samples(reg2, reg2 + gap, reg2cnt - gap);
+ reg1 -= gap;
+ reg1cnt += gap;
+ reg2cnt -= gap;
+ } while (reg2cnt > 0);
+ }
+
+ /* Finally, Shift samples to the left edge */
+ if (reg1 != circbuf->buf)
+ pjmedia_move_samples(circbuf->buf, reg1,
+ pjmedia_circ_buf_get_len(circbuf));
+ circbuf->start = circbuf->buf;
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/clock.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/clock.h
new file mode 100644
index 0000000..0972d44
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/clock.h
@@ -0,0 +1,208 @@
+/* $Id: clock.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CLOCK_H__
+#define __PJMEDIA_CLOCK_H__
+
+/**
+ * @file clock.h
+ * @brief Media clock.
+ */
+#include <pjmedia/types.h>
+
+
+/**
+ * @defgroup PJMEDIA_PORT_CLOCK Clock/Timing
+ * @ingroup PJMEDIA_PORT
+ * @brief Various types of classes that provide timing.
+ * @{
+
+ The media clock/timing extends the media port concept that is explained
+ in @ref PJMEDIA_PORT. When clock is present in the ports
+ interconnection, media will flow automatically (and with correct timing too!)
+ from one media port to another.
+
+ There are few objects in PJMEDIA that are able to provide clock/timing
+ to media ports interconnection:
+
+ - @ref PJMED_SND_PORT\n
+ The sound device makes a good candidate as the clock source, and
+ PJMEDIA @ref PJMED_SND is designed so that it is able to invoke
+ operations according to timing driven by the sound hardware clock
+ (this may sound complicated, but actually it just means that
+ the sound device abstraction provides callbacks to be called when
+ it has/wants media frames).\n
+ See @ref PJMED_SND_PORT for more details.
+
+ - @ref PJMEDIA_MASTER_PORT\n
+ The master port uses @ref PJMEDIA_CLOCK as the clock source. By using
+ @ref PJMEDIA_MASTER_PORT, it is possible to interconnect passive
+ media ports and let the frames flow automatically in timely manner.\n
+ Please see @ref PJMEDIA_MASTER_PORT for more details.
+
+ @}
+ */
+
+
+/**
+ * @addtogroup PJMEDIA_CLOCK Clock Generator
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Interface for generating clock.
+ * @{
+ *
+ * The clock generator provides the application with media timing,
+ * and it is used by the @ref PJMEDIA_MASTER_PORT for its sound clock.
+ *
+ * The clock generator may be configured to run <b>asynchronously</b>
+ * (the default behavior) or <b>synchronously</b>. When it is run
+ * asynchronously, it will call the application's callback every time
+ * the clock <b>tick</b> expires. When it is run synchronously,
+ * application must continuously polls the clock generator to synchronize
+ * the timing.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for media clock.
+ */
+typedef struct pjmedia_clock pjmedia_clock;
+
+
+/**
+ * Options when creating the clock.
+ */
+enum pjmedia_clock_options
+{
+ /**
+ * Prevents the clock from running asynchronously. In this case,
+ * application must poll the clock continuously by calling
+ * #pjmedia_clock_wait() in order to synchronize timing.
+ */
+ PJMEDIA_CLOCK_NO_ASYNC = 1,
+
+ /**
+ * Prevent the clock from setting it's thread to highest priority.
+ */
+ PJMEDIA_CLOCK_NO_HIGHEST_PRIO = 2
+};
+
+
+/**
+ * Type of media clock callback.
+ *
+ * @param ts Current timestamp, in samples.
+ * @param user_data Application data that is passed when
+ * the clock was created.
+ */
+typedef void pjmedia_clock_callback(const pj_timestamp *ts,
+ void *user_data);
+
+
+
+/**
+ * Create media clock.
+ *
+ * @param pool Pool to allocate memory.
+ * @param clock_rate Number of samples per second.
+ * @param channel_count Number of channel.
+ * @param samples_per_frame Number of samples per frame. This argument
+ * along with clock_rate and channel_count, specifies
+ * the interval of each clock run (or clock ticks).
+ * @param options Bitmask of pjmedia_clock_options.
+ * @param cb Callback to be called for each clock tick.
+ * @param user_data User data, which will be passed to the callback.
+ * @param p_clock Pointer to receive the clock instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned options,
+ pjmedia_clock_callback *cb,
+ void *user_data,
+ pjmedia_clock **p_clock);
+
+/**
+ * Start the clock. For clock created with asynchronous flag set to TRUE,
+ * this may start a worker thread for the clock (depending on the
+ * backend clock implementation being used).
+ *
+ * @param clock The media clock.
+ *
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_start(pjmedia_clock *clock);
+
+
+/**
+ * Stop the clock.
+ *
+ * @param clock The media clock.
+ *
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock);
+
+
+
+/**
+ * Poll the media clock, and execute the callback when the clock tick has
+ * elapsed. This operation is only valid if the clock is created with async
+ * flag set to FALSE.
+ *
+ * @param clock The media clock.
+ * @param wait If non-zero, then the function will block until
+ * a clock tick elapsed and callback has been called.
+ * @param ts Optional argument to receive the current
+ * timestamp.
+ *
+ * @return Non-zero if clock tick has elapsed, or FALSE if
+ * the function returns before a clock tick has
+ * elapsed.
+ */
+PJ_DECL(pj_bool_t) pjmedia_clock_wait(pjmedia_clock *clock,
+ pj_bool_t wait,
+ pj_timestamp *ts);
+
+
+/**
+ * Destroy the clock.
+ *
+ * @param clock The media clock.
+ *
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock);
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CLOCK_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/codec.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/codec.h
new file mode 100644
index 0000000..1bb8038
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/codec.h
@@ -0,0 +1,879 @@
+/* $Id: codec.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CODEC_H__
+#define __PJMEDIA_CODEC_H__
+
+
+/**
+ * @file codec.h
+ * @brief Codec framework.
+ */
+
+#include <pjmedia/port.h>
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_CODEC Codec Framework
+ * @brief Media codec framework and management
+ * @{
+ *
+ * @section codec_mgmt_sec Codec Management
+ * @subsection codec_fact_sec Codec Manager
+ *
+ * The codec manager is used to manage all codec capabilities in the endpoint.
+ * When used with media endpoint (pjmedia_endpt), application can retrieve
+ * the codec manager instance by calling #pjmedia_endpt_get_codec_mgr().
+ *
+ * @subsection reg_new_codec Registering New Codec
+ *
+ * New codec types can be registered to PJMEDIA (or to be precise, to the
+ * codec manager) during run-time.
+ * To do this, application needs to initialize an instance of
+ * codec factory (#pjmedia_codec_factory) and registers this codec factory
+ * by calling #pjmedia_codec_mgr_register_factory().
+ *
+ * For codecs implemented/supported by PJMEDIA, this process is normally
+ * concealed in an easy to use function such as #pjmedia_codec_g711_init().
+ *
+ * @subsection codec_factory Codec Factory
+ *
+ * A codec factory (#pjmedia_codec_factory) is registered to codec manager,
+ * and it is used to create and release codec instance.
+ *
+ * The most important member of the codec factory is the "virtual" function
+ * table #pjmedia_codec_factory_op, where it contains, among other thing,
+ * pointer to functions to allocate and deallocate codec instance.
+ *
+ * @subsection codec_inst Codec Instance
+ *
+ * Application allocates codec instance by calling #pjmedia_codec_mgr_alloc_codec().
+ * One codec instance (#pjmedia_codec) can be used for simultaneous encoding
+ * and decoding.
+ *
+ * The most important member of the codec instance is the "virtual" function
+ * table #pjmedia_codec_op, where it holds pointer to functions to
+ * encode/decode media frames.
+ *
+ * @subsection codec_ident Codec Identification
+ *
+ * A particular codec type in PJMEDIA can be uniquely identified by two
+ * keys: by #pjmedia_codec_info, or by #pjmedia_codec_id string. A fully
+ * qualified codec ID string consists of codec name, sampling rate, and
+ * number of channels. However, application may use only first parts of
+ * the tokens as long as it will make to codec ID unique. For example, "gsm"
+ * is a fully qualified codec name, since it will always have 8000 clock
+ * rate and 1 channel. Other examples of fully qualified codec ID strings
+ * are "pcma", "speex/8000", "speex/16000", and "L16/16000/1". A codec
+ * id "speex" (without clock rate) is not fully qualified, since it will
+ * match the narrowband, wideband, and ultrawideband Speex codec.
+ *
+ * The two keys can be converted to one another, with
+ * #pjmedia_codec_info_to_id() and #pjmedia_codec_mgr_find_codecs_by_id()
+ * functions.
+ *
+ * Codec ID string is not case sensitive.
+ *
+ *
+ * @section using_codec Using the Codec Framework
+ * @subsection init_alloc_codec Allocating Codec
+ *
+ * Application needs to allocate one codec instance for encoding and decoding
+ * media frames. One codec instance can be used to perform both encoding
+ * and decoding.
+ *
+ * Application allocates codec by calling #pjmedia_codec_mgr_alloc_codec().
+ * This function takes #pjmedia_codec_info argument, which is used to locate
+ * the particular codec factory to be used to allocate the codec.
+ *
+ * Application can build #pjmedia_codec_info structure manually for
+ * the specific codec, or alternatively it may get the #pjmedia_codec_info
+ * from the codec ID string, by using #pjmedia_codec_mgr_find_codecs_by_id()
+ * function.
+ *
+ * The following snippet shows an example to allocate a codec:
+ *
+ \code
+ pj_str_t codec_id;
+ pjmedia_codec_info *codec_info;
+ unsigned count = 1;
+ pjmedia_codec *codec;
+
+ codec_id = pj_str("pcma");
+
+ // Find codec info for the specified coded ID (i.e. "pcma").
+ status = pjmedia_codec_mgr_find_codecs_by_id( codec_mgr, &codec_id,
+ &count, &codec_info, NULL);
+
+ // Allocate the codec.
+ status = pjmedia_codec_mgr_alloc_codec( codec_mgr, codec_info, &codec );
+
+ \endcode
+ *
+ *
+ * @subsection opening_codec Initializing Codec
+ *
+ * Once codec is allocated, application needs to initialize the codec
+ * by calling <b><tt>open</tt></b> member of the codec. This function
+ * takes #pjmedia_codec_param as the argument, which contains the
+ * settings for the codec.
+ *
+ * Application shoud use #pjmedia_codec_mgr_get_default_param() function
+ * to initiaize #pjmedia_codec_param. The <tt>setting</tt> part of
+ * #pjmedia_codec_param then can be tuned to suit the application's
+ * requirements.
+ *
+ * The following snippet shows an example to initialize codec:
+ *
+ \code
+ pjmedia_codec_param param;
+
+ // Retrieve default codec param for the specified codec.
+ pjmedia_codec_mgr_get_default_param(codec_mgr, codec_info
+ &param);
+
+ // Application may change the "settings" part of codec param,
+ // for example, to disable VAD
+ param.setting.vad = 0;
+
+ // Open the codec using the specified settings.
+ codec->op->open( codec, &param );
+
+ \endcode
+ *
+ *
+ * @subsection enc_dec_codec Encoding and Decoding Media Frames
+ *
+ * Application encodes and decodes media frames by calling
+ * <tt>encode</tt> and <tt>decode</tt> member of the codec's "virtual"
+ * function table (#pjmedia_codec_op).
+ *
+ * @subsection plc_codec Concealing Lost Frames
+ *
+ * All codecs has Packet Lost Concealment (PLC) feature, and application
+ * can activate the PLC to conceal lost frames by calling <tt>recover</tt>
+ * member of the codec's "virtual" function table (#pjmedia_codec_op).
+ *
+ * If the codec's algorithm supports PLC, the <tt>recover</tt> function
+ * will use the codec's PLC. Otherwise for codecs that don't have
+ * intrinsic PLC, PJMEDIA will suply the PLC implementation from the
+ * @ref PJMED_PLC implementation.
+ *
+ * @subsection close_codec Closing and Releasing the Codec
+ *
+ * The codec must be closed by calling <tt>close</tt> member of the codec's
+ * operation. Then it must be released by calling
+ * #pjmedia_codec_mgr_dealloc_codec().
+ */
+
+
+/**
+ * Standard RTP static payload types, as defined by RFC 3551.
+ * The header file <pjmedia-codec/types.h> also declares dynamic payload
+ * type numbers that are used by PJMEDIA when advertising the capability
+ * for example in SDP message.
+ */
+enum pjmedia_rtp_pt
+{
+ PJMEDIA_RTP_PT_PCMU = 0, /**< audio PCMU */
+ PJMEDIA_RTP_PT_G726_32 = 2, /**< audio G726-32 */
+ PJMEDIA_RTP_PT_GSM = 3, /**< audio GSM */
+ PJMEDIA_RTP_PT_G723 = 4, /**< audio G723 */
+ PJMEDIA_RTP_PT_DVI4_8K = 5, /**< audio DVI4 8KHz */
+ PJMEDIA_RTP_PT_DVI4_16K = 6, /**< audio DVI4 16Khz */
+ PJMEDIA_RTP_PT_LPC = 7, /**< audio LPC */
+ PJMEDIA_RTP_PT_PCMA = 8, /**< audio PCMA */
+ PJMEDIA_RTP_PT_G722 = 9, /**< audio G722 */
+ PJMEDIA_RTP_PT_L16_2 = 10, /**< audio 16bit linear 44.1KHz stereo */
+ PJMEDIA_RTP_PT_L16_1 = 11, /**< audio 16bit linear 44.1KHz mono */
+ PJMEDIA_RTP_PT_QCELP = 12, /**< audio QCELP */
+ PJMEDIA_RTP_PT_CN = 13, /**< audio Comfort Noise */
+ PJMEDIA_RTP_PT_MPA = 14, /**< audio MPEG1/MPEG2 elemetr. streams */
+ PJMEDIA_RTP_PT_G728 = 15, /**< audio G728 */
+ PJMEDIA_RTP_PT_DVI4_11K = 16, /**< audio DVI4 11.025KHz mono */
+ PJMEDIA_RTP_PT_DVI4_22K = 17, /**< audio DVI4 22.050KHz mono */
+ PJMEDIA_RTP_PT_G729 = 18, /**< audio G729 */
+
+ PJMEDIA_RTP_PT_CELB = 25, /**< video/comb Cell-B by Sun (RFC2029) */
+ PJMEDIA_RTP_PT_JPEG = 26, /**< video JPEG */
+ PJMEDIA_RTP_PT_NV = 28, /**< video NV by nv program by Xerox */
+ PJMEDIA_RTP_PT_H261 = 31, /**< video H261 */
+ PJMEDIA_RTP_PT_MPV = 32, /**< video MPEG1 or MPEG2 elementary */
+ PJMEDIA_RTP_PT_MP2T = 33, /**< video MPEG2 transport */
+ PJMEDIA_RTP_PT_H263 = 34, /**< video H263 */
+
+ PJMEDIA_RTP_PT_DYNAMIC = 96 /**< start of dynamic RTP payload */
+
+};
+
+
+/**
+ * Identification used to search for codec factory that supports specific
+ * codec specification.
+ */
+typedef struct pjmedia_codec_info
+{
+ pjmedia_type type; /**< Media type. */
+ unsigned pt; /**< Payload type (can be dynamic). */
+ pj_str_t encoding_name; /**< Encoding name. */
+ unsigned clock_rate; /**< Sampling rate. */
+ unsigned channel_cnt; /**< Channel count. */
+} pjmedia_codec_info;
+
+#define PJMEDIA_CODEC_MAX_FMTP_CNT 8
+
+/**
+ * Structure of codec specific parameters which contains name=value pairs.
+ * The codec specific parameters are to be used with SDP according to
+ * the standards (e.g: RFC 3555).
+ */
+typedef struct pjmedia_codec_fmtp
+{
+ pj_uint8_t cnt;
+ struct param {
+ pj_str_t name;
+ pj_str_t val;
+ } param [PJMEDIA_CODEC_MAX_FMTP_CNT];
+} pjmedia_codec_fmtp;
+
+/**
+ * Detailed codec attributes used both to configure a codec and to query
+ * the capability of codec factories.
+ */
+typedef struct pjmedia_codec_param
+{
+ /**
+ * The "info" part of codec param describes the capability of the codec,
+ * and the value should NOT be changed by application.
+ */
+ struct {
+ unsigned clock_rate; /**< Sampling rate in Hz */
+ unsigned channel_cnt; /**< Channel count. */
+ pj_uint32_t avg_bps; /**< Average bandwidth in bits/sec */
+ pj_uint32_t max_bps; /**< Maximum bandwidth in bits/sec */
+ pj_uint16_t frm_ptime; /**< Decoder frame ptime in msec. */
+ pj_uint16_t enc_ptime; /**< Encoder ptime, or zero if it's
+ equal to decoder ptime. */
+ pj_uint8_t pcm_bits_per_sample; /**< Bits/sample in the PCM side */
+ pj_uint8_t pt; /**< Payload type. */
+ pjmedia_format_id fmt_id; /**< Source format, it's format of
+ encoder input and decoder
+ output. */
+ } info;
+
+ /**
+ * The "setting" part of codec param describes various settings to be
+ * applied to the codec. When the codec param is retrieved from the codec
+ * or codec factory, the values of these will be filled by the capability
+ * of the codec. Any features that are supported by the codec (e.g. vad
+ * or plc) will be turned on, so that application can query which
+ * capabilities are supported by the codec. Application may change the
+ * settings here before instantiating the codec/stream.
+ */
+ struct {
+ pj_uint8_t frm_per_pkt; /**< Number of frames per packet. */
+ unsigned vad:1; /**< Voice Activity Detector. */
+ unsigned cng:1; /**< Comfort Noise Generator. */
+ unsigned penh:1; /**< Perceptual Enhancement */
+ unsigned plc:1; /**< Packet loss concealment */
+ unsigned reserved:1; /**< Reserved, must be zero. */
+ pjmedia_codec_fmtp enc_fmtp;/**< Encoder's fmtp params. */
+ pjmedia_codec_fmtp dec_fmtp;/**< Decoder's fmtp params. */
+ } setting;
+} pjmedia_codec_param;
+
+
+
+/*
+ * Forward declaration for pjmedia_codec.
+ */
+typedef struct pjmedia_codec pjmedia_codec;
+
+
+/**
+ * This structure describes codec operations. Each codec MUST implement
+ * all of these functions.
+ */
+typedef struct pjmedia_codec_op
+{
+ /**
+ * Initialize codec using the specified attribute.
+ *
+ * @param codec The codec instance.
+ * @param pool Pool to use when the codec needs to allocate
+ * some memory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*init)(pjmedia_codec *codec,
+ pj_pool_t *pool );
+
+ /**
+ * Open the codec and initialize with the specified parameter.
+ * Upon successful initialization, the codec may modify the parameter
+ * and fills in the unspecified values (such as enc_ptime, when
+ * encoder ptime is different than decoder ptime).
+ *
+ * @param codec The codec instance.
+ * @param param Codec initialization parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*open)(pjmedia_codec *codec,
+ pjmedia_codec_param *param );
+
+ /**
+ * Close and shutdown codec, releasing all resources allocated by
+ * this codec, if any.
+ *
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*close)(pjmedia_codec *codec);
+
+ /**
+ * Modify the codec parameter after the codec is open.
+ * Note that not all codec parameters can be modified during run-time.
+ * When the parameter cannot be changed, this function will return
+ * non-PJ_SUCCESS, and the original parameters will not be changed.
+ *
+ * Application can expect changing trivial codec settings such as
+ * changing VAD setting to succeed.
+ *
+ * @param codec The codec instance.
+ * @param param The new codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*modify)(pjmedia_codec *codec,
+ const pjmedia_codec_param *param );
+
+ /**
+ * Instruct the codec to inspect the specified payload/packet and
+ * split the packet into individual base frames. Each output frames will
+ * have ptime that is equal to basic frame ptime (i.e. the value of
+ * info.frm_ptime in #pjmedia_codec_param).
+ *
+ * @param codec The codec instance
+ * @param pkt The input packet.
+ * @param pkt_size Size of the packet.
+ * @param timestamp The timestamp of the first sample in the packet.
+ * @param frame_cnt On input, specifies the maximum number of frames
+ * in the array. On output, the codec must fill
+ * with number of frames detected in the packet.
+ * @param frames On output, specifies the frames that have been
+ * detected in the packet.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*parse)( pjmedia_codec *codec,
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_timestamp *timestamp,
+ unsigned *frame_cnt,
+ pjmedia_frame frames[]);
+
+ /**
+ * Instruct the codec to encode the specified input frame. The input
+ * PCM samples MUST have ptime that is multiplication of base frame
+ * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+ pj_status_t (*encode)(pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned out_size,
+ struct pjmedia_frame *output);
+
+ /**
+ * Instruct the codec to decode the specified input frame. The input
+ * frame MUST have ptime that is exactly equal to base frame
+ * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).
+ * Application can achieve this by parsing the packet into base
+ * frames before decoding each frame.
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+ pj_status_t (*decode)(pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned out_size,
+ struct pjmedia_frame *output);
+
+ /**
+ * Instruct the codec to recover a missing frame.
+ *
+ * @param codec The codec instance.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame where generated signal
+ * will be placed.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+ pj_status_t (*recover)(pjmedia_codec *codec,
+ unsigned out_size,
+ struct pjmedia_frame *output);
+} pjmedia_codec_op;
+
+
+
+/*
+ * Forward declaration for pjmedia_codec_factory.
+ */
+typedef struct pjmedia_codec_factory pjmedia_codec_factory;
+
+
+/**
+ * This structure describes a codec instance.
+ */
+struct pjmedia_codec
+{
+ /** Entries to put this codec instance in codec factory's list. */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_codec);
+
+ /** Codec's private data. */
+ void *codec_data;
+
+ /** Codec factory where this codec was allocated. */
+ pjmedia_codec_factory *factory;
+
+ /** Operations to codec. */
+ pjmedia_codec_op *op;
+};
+
+
+
+/**
+ * This structure describes operations that must be supported by codec
+ * factories.
+ */
+typedef struct pjmedia_codec_factory_op
+{
+ /**
+ * Check whether the factory can create codec with the specified
+ * codec info.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ *
+ * @return PJ_SUCCESS if this factory is able to create an
+ * instance of codec with the specified info.
+ */
+ pj_status_t (*test_alloc)(pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *info );
+
+ /**
+ * Create default attributes for the specified codec ID. This function
+ * can be called by application to get the capability of the codec.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ * @param attr The attribute to be initialized.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+ pj_status_t (*default_attr)(pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *info,
+ pjmedia_codec_param *attr );
+
+ /**
+ * Enumerate supported codecs that can be created using this factory.
+ *
+ * @param factory The codec factory.
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the value will be set to
+ * the number of elements that have been initialized
+ * by this function.
+ * @param info The codec info array, which contents will be
+ * initialized upon return.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*enum_info)(pjmedia_codec_factory *factory,
+ unsigned *count,
+ pjmedia_codec_info codecs[]);
+
+ /**
+ * Create one instance of the codec with the specified codec info.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ * @param p_codec Pointer to receive the codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*alloc_codec)(pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *info,
+ pjmedia_codec **p_codec);
+
+ /**
+ * This function is called by codec manager to return a particular
+ * instance of codec back to the codec factory.
+ *
+ * @param factory The codec factory.
+ * @param codec The codec instance to be returned.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*dealloc_codec)(pjmedia_codec_factory *factory,
+ pjmedia_codec *codec );
+
+} pjmedia_codec_factory_op;
+
+
+
+/**
+ * Codec factory describes a module that is able to create codec with specific
+ * capabilities. These capabilities can be queried by codec manager to create
+ * instances of codec.
+ */
+struct pjmedia_codec_factory
+{
+ /** Entries to put this structure in the codec manager list. */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_codec_factory);
+
+ /** The factory's private data. */
+ void *factory_data;
+
+ /** Operations to the factory. */
+ pjmedia_codec_factory_op *op;
+
+};
+
+
+/**
+ * Declare maximum codecs
+ */
+#define PJMEDIA_CODEC_MGR_MAX_CODECS 32
+
+
+/**
+ * Specify these values to set the codec priority, by calling
+ * #pjmedia_codec_mgr_set_codec_priority().
+ */
+typedef enum pjmedia_codec_priority
+{
+ /**
+ * This priority makes the codec the highest in the order.
+ * The last codec specified with this priority will get the
+ * highest place in the order, and will change the priority
+ * of previously highest priority codec to NEXT_HIGHER.
+ */
+ PJMEDIA_CODEC_PRIO_HIGHEST = 255,
+
+ /**
+ * This priority will put the codec as the next codec after
+ * codecs with this same priority.
+ */
+ PJMEDIA_CODEC_PRIO_NEXT_HIGHER = 254,
+
+ /**
+ * This is the initial codec priority when it is registered to
+ * codec manager by codec factory.
+ */
+ PJMEDIA_CODEC_PRIO_NORMAL = 128,
+
+ /**
+ * This priority makes the codec the lowest in the order.
+ * The last codec specified with this priority will be put
+ * in the last place in the order.
+ */
+ PJMEDIA_CODEC_PRIO_LOWEST = 1,
+
+ /**
+ * This priority will prevent the codec from being listed in the
+ * SDP created by media endpoint, thus should prevent the codec
+ * from being used in the sessions. However, the codec will still
+ * be listed by #pjmedia_codec_mgr_enum_codecs() and other codec
+ * query functions.
+ */
+ PJMEDIA_CODEC_PRIO_DISABLED = 0
+
+} pjmedia_codec_priority;
+
+
+/**
+ * Codec identification (e.g. "pcmu/8000/1").
+ * See @ref codec_ident for more info.
+ */
+typedef char pjmedia_codec_id[32];
+
+
+/**
+ * Codec manager maintains array of these structs for each supported
+ * codec.
+ */
+struct pjmedia_codec_desc
+{
+ pjmedia_codec_info info; /**< Codec info. */
+ pjmedia_codec_id id; /**< Fully qualified name */
+ pjmedia_codec_priority prio; /**< Priority. */
+ pjmedia_codec_factory *factory; /**< The factory. */
+};
+
+
+/**
+ * The declaration for codec manager. Application doesn't normally need
+ * to see this declaration, but nevertheless this declaration is needed
+ * by media endpoint to instantiate the codec manager.
+ */
+typedef struct pjmedia_codec_mgr
+{
+ /** List of codec factories registered to codec manager. */
+ pjmedia_codec_factory factory_list;
+
+ /** Number of supported codesc. */
+ unsigned codec_cnt;
+
+ /** Array of codec descriptor. */
+ struct pjmedia_codec_desc codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS];
+
+} pjmedia_codec_mgr;
+
+
+
+/**
+ * Initialize codec manager. Normally this function is called by pjmedia
+ * endpoint's initialization code.
+ *
+ * @param mgr Codec manager instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_mgr_init(pjmedia_codec_mgr *mgr);
+
+
+/**
+ * Register codec factory to codec manager. This will also register
+ * all supported codecs in the factory to the codec manager.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param factory The codec factory to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_register_factory( pjmedia_codec_mgr *mgr,
+ pjmedia_codec_factory *factory);
+
+/**
+ * Unregister codec factory from the codec manager. This will also
+ * remove all the codecs registered by the codec factory from the
+ * codec manager's list of supported codecs.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param factory The codec factory to be unregistered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_unregister_factory( pjmedia_codec_mgr *mgr,
+ pjmedia_codec_factory *factory);
+
+/**
+ * Enumerate all supported codecs that have been registered to the
+ * codec manager by codec factories.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the value will be set to
+ * the number of elements that have been initialized
+ * by this function.
+ * @param info The codec info array, which contents will be
+ * initialized upon return.
+ * @param prio Optional pointer to receive array of codec priorities.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_mgr_enum_codecs( pjmedia_codec_mgr *mgr,
+ unsigned *count,
+ pjmedia_codec_info info[],
+ unsigned *prio);
+
+/**
+ * Get codec info for the specified static payload type. Note that
+ * this can only find codec with static payload types. This function can
+ * be used to find codec info for a payload type inside SDP which doesn't
+ * have the corresponding rtpmap attribute.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param pt Static payload type/number.
+ * @param inf Pointer to receive codec info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_get_codec_info( pjmedia_codec_mgr *mgr,
+ unsigned pt,
+ const pjmedia_codec_info **inf);
+
+/**
+ * Convert codec info struct into a unique codec identifier.
+ * A codec identifier looks something like "L16/44100/2".
+ *
+ * @param info The codec info
+ * @param id Buffer to put the codec info string.
+ * @param max_len The length of the buffer.
+ *
+ * @return The null terminated codec info string, or NULL if
+ * the buffer is not long enough.
+ */
+PJ_DECL(char*) pjmedia_codec_info_to_id(const pjmedia_codec_info *info,
+ char *id, unsigned max_len );
+
+
+/**
+ * Find codecs by the unique codec identifier. This function will find
+ * all codecs that match the codec identifier prefix. For example, if
+ * "L16" is specified, then it will find "L16/8000/1", "L16/16000/1",
+ * and so on, up to the maximum count specified in the argument.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param codec_id The full codec ID or codec ID prefix. If an empty
+ * string is given, it will match all codecs.
+ * @param count Maximum number of codecs to find. On return, it
+ * contains the actual number of codecs found.
+ * @param p_info Array of pointer to codec info to be filled. This
+ * argument may be NULL, which in this case, only
+ * codec count will be returned.
+ * @param prio Optional array of codec priorities.
+ *
+ * @return PJ_SUCCESS if at least one codec info is found.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_find_codecs_by_id( pjmedia_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ unsigned *count,
+ const pjmedia_codec_info *p_info[],
+ unsigned prio[]);
+
+
+/**
+ * Set codec priority. The codec priority determines the order of
+ * the codec in the SDP created by the endpoint. If more than one codecs
+ * are found with the same codec_id prefix, then the function sets the
+ * priorities of all those codecs.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param codec_id The full codec ID or codec ID prefix. If an empty
+ * string is given, it will match all codecs.
+ * @param prio Priority to be set. The priority can have any value
+ * between 1 to 255. When the priority is set to zero,
+ * the codec will be disabled.
+ *
+ * @return PJ_SUCCESS if at least one codec info is found.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_set_codec_priority(pjmedia_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ pj_uint8_t prio);
+
+
+/**
+ * Get default codec param for the specified codec info.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param info The codec info, which default parameter's is being
+ * queried.
+ * @param param On return, will be filled with the default codec
+ * parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_get_default_param( pjmedia_codec_mgr *mgr,
+ const pjmedia_codec_info *info,
+ pjmedia_codec_param *param );
+
+/**
+ * Request the codec manager to allocate one instance of codec with the
+ * specified codec info. The codec will enumerate all codec factories
+ * until it finds factory that is able to create the specified codec.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param info The information about the codec to be created.
+ * @param p_codec Pointer to receive the codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_alloc_codec( pjmedia_codec_mgr *mgr,
+ const pjmedia_codec_info *info,
+ pjmedia_codec **p_codec);
+
+/**
+ * Deallocate the specified codec instance. The codec manager will return
+ * the instance of the codec back to its factory.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_mgr_dealloc_codec(pjmedia_codec_mgr *mgr,
+ pjmedia_codec *codec);
+
+
+
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJMEDIA_CODEC_CODECS Supported codecs
+ * @ingroup PJMEDIA_CODEC
+ * @brief Documentation about individual codec supported by PJMEDIA
+ * @{
+ * Please see the APIs provided by the individual codecs below.
+ */
+/**
+ * @}
+ */
+
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_CODEC_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/conference.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/conference.h
new file mode 100644
index 0000000..5b13590
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/conference.h
@@ -0,0 +1,511 @@
+/* $Id: conference.h 2728 2009-06-01 13:56:09Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CONF_H__
+#define __PJMEDIA_CONF_H__
+
+
+/**
+ * @file conference.h
+ * @brief Conference bridge.
+ */
+#include <pjmedia/port.h>
+
+/**
+ * @defgroup PJMEDIA_CONF Conference Bridge
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio conference bridge implementation
+ * @{
+ *
+ * This describes the conference bridge implementation in PJMEDIA. The
+ * conference bridge provides powerful and very efficient mechanism to
+ * route the audio flow and mix the audio signal when required.
+ *
+ * Some more information about the media flow when conference bridge is
+ * used is described in http://www.pjsip.org/trac/wiki/media-flow .
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * The conference bridge signature in pjmedia_port_info.
+ */
+#define PJMEDIA_CONF_BRIDGE_SIGNATURE \
+ PJMEDIA_PORT_SIGNATURE('C', 'O', 'N', 'F')
+
+/**
+ * The audio switchboard signature in pjmedia_port_info.
+ */
+#define PJMEDIA_CONF_SWITCH_SIGNATURE \
+ PJMEDIA_PORT_SIGNATURE('A', 'S', 'W', 'I')
+
+
+/**
+ * Opaque type for conference bridge.
+ */
+typedef struct pjmedia_conf pjmedia_conf;
+
+/**
+ * Conference port info.
+ */
+typedef struct pjmedia_conf_port_info
+{
+ unsigned slot; /**< Slot number. */
+ pj_str_t name; /**< Port name. */
+ pjmedia_format format; /**< Format. */
+ pjmedia_port_op tx_setting; /**< Transmit settings. */
+ pjmedia_port_op rx_setting; /**< Receive settings. */
+ unsigned listener_cnt; /**< Number of listeners. */
+ unsigned *listener_slots; /**< Array of listeners. */
+ unsigned transmitter_cnt; /**< Number of transmitter. */
+ unsigned clock_rate; /**< Clock rate of the port. */
+ unsigned channel_count; /**< Number of channels. */
+ unsigned samples_per_frame; /**< Samples per frame */
+ unsigned bits_per_sample; /**< Bits per sample. */
+ int tx_adj_level; /**< Tx level adjustment. */
+ int rx_adj_level; /**< Rx level adjustment. */
+} pjmedia_conf_port_info;
+
+
+/**
+ * Conference port options. The values here can be combined in bitmask to
+ * be specified when the conference bridge is created.
+ */
+enum pjmedia_conf_option
+{
+ PJMEDIA_CONF_NO_MIC = 1, /**< Disable audio streams from the
+ microphone device. */
+ PJMEDIA_CONF_NO_DEVICE = 2, /**< Do not create sound device. */
+ PJMEDIA_CONF_SMALL_FILTER=4,/**< Use small filter table when resampling */
+ PJMEDIA_CONF_USE_LINEAR=8 /**< Use linear resampling instead of filter
+ based. */
+};
+
+
+/**
+ * Create conference bridge with the specified parameters. The sampling rate,
+ * samples per frame, and bits per sample will be used for the internal
+ * operation of the bridge (e.g. when mixing audio frames). However, ports
+ * with different configuration may be connected to the bridge. In this case,
+ * the bridge is able to perform sampling rate conversion, and buffering in
+ * case the samples per frame is different.
+ *
+ * For this version of PJMEDIA, only 16bits per sample is supported.
+ *
+ * For this version of PJMEDIA, the channel count of the ports MUST match
+ * the channel count of the bridge.
+ *
+ * Under normal operation (i.e. when PJMEDIA_CONF_NO_DEVICE option is NOT
+ * specified), the bridge internally create an instance of sound device
+ * and connect the sound device to port zero of the bridge.
+ *
+ * If PJMEDIA_CONF_NO_DEVICE options is specified, no sound device will
+ * be created in the conference bridge. Application MUST acquire the port
+ * interface of the bridge by calling #pjmedia_conf_get_master_port(), and
+ * connect this port interface to a sound device port by calling
+ * #pjmedia_snd_port_connect(), or to a master port (pjmedia_master_port)
+ * if application doesn't want to instantiate any sound devices.
+ *
+ * The sound device or master port are crucial for the bridge's operation,
+ * because it provides the bridge with necessary clock to process the audio
+ * frames periodically. Internally, the bridge runs when get_frame() to
+ * port zero is called.
+ *
+ * @param pool Pool to use to allocate the bridge and
+ * additional buffers for the sound device.
+ * @param max_slots Maximum number of slots/ports to be created in
+ * the bridge. Note that the bridge internally uses
+ * one port for the sound device, so the actual
+ * maximum number of ports will be less one than
+ * this value.
+ * @param sampling_rate Set the sampling rate of the bridge. This value
+ * is also used to set the sampling rate of the
+ * sound device.
+ * @param channel_count Number of channels in the PCM stream. Normally
+ * the value will be 1 for mono, but application may
+ * specify a value of 2 for stereo. Note that all
+ * ports that will be connected to the bridge MUST
+ * have the same number of channels as the bridge.
+ * @param samples_per_frame Set the number of samples per frame. This value
+ * is also used to set the sound device.
+ * @param bits_per_sample Set the number of bits per sample. This value
+ * is also used to set the sound device. Currently
+ * only 16bit per sample is supported.
+ * @param options Bitmask options to be set for the bridge. The
+ * options are constructed from #pjmedia_conf_option
+ * enumeration.
+ * @param p_conf Pointer to receive the conference bridge instance.
+ *
+ * @return PJ_SUCCESS if conference bridge can be created.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_create( pj_pool_t *pool,
+ unsigned max_slots,
+ unsigned sampling_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_conf **p_conf );
+
+
+/**
+ * Destroy conference bridge.
+ *
+ * @param conf The conference bridge.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_destroy( pjmedia_conf *conf );
+
+
+/**
+ * Get the master port interface of the conference bridge. The master port
+ * corresponds to the port zero of the bridge. This is only usefull when
+ * application wants to manage the sound device by itself, instead of
+ * allowing the bridge to automatically create a sound device implicitly.
+ *
+ * This function will only return a port interface if PJMEDIA_CONF_NO_DEVICE
+ * option was specified when the bridge was created.
+ *
+ * Application can connect the port returned by this function to a
+ * sound device by calling #pjmedia_snd_port_connect().
+ *
+ * @param conf The conference bridge.
+ *
+ * @return The port interface of port zero of the bridge,
+ * only when PJMEDIA_CONF_NO_DEVICE options was
+ * specified when the bridge was created.
+ */
+PJ_DECL(pjmedia_port*) pjmedia_conf_get_master_port(pjmedia_conf *conf);
+
+
+/**
+ * Set master port name.
+ *
+ * @param conf The conference bridge.
+ * @param name Name to be assigned.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_set_port0_name(pjmedia_conf *conf,
+ const pj_str_t *name);
+
+
+/**
+ * Add media port to the conference bridge.
+ *
+ * By default, the new conference port will have both TX and RX enabled,
+ * but it is not connected to any other ports. Application SHOULD call
+ * #pjmedia_conf_connect_port() to enable audio transmission and receipt
+ * to/from this port.
+ *
+ * Once the media port is connected to other port(s) in the bridge,
+ * the bridge will continuosly call get_frame() and put_frame() to the
+ * port, allowing media to flow to/from the port.
+ *
+ * @param conf The conference bridge.
+ * @param pool Pool to allocate buffers for this port.
+ * @param strm_port Stream port interface.
+ * @param name Optional name for the port. If this value is NULL,
+ * the name will be taken from the name in the port
+ * info.
+ * @param p_slot Pointer to receive the slot index of the port in
+ * the conference bridge.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_add_port( pjmedia_conf *conf,
+ pj_pool_t *pool,
+ pjmedia_port *strm_port,
+ const pj_str_t *name,
+ unsigned *p_slot );
+
+
+/**
+ * <i><b>Warning:</b> This API has been deprecated since 1.3 and will be
+ * removed in the future release, use #PJMEDIA_SPLITCOMB instead.</i>
+ *
+ * Create and add a passive media port to the conference bridge. Unlike
+ * "normal" media port that is added with #pjmedia_conf_add_port(), media
+ * port created with this function will not have its get_frame() and
+ * put_frame() called by the bridge; instead, application MUST continuosly
+ * call these functions to the port, to allow media to flow from/to the
+ * port.
+ *
+ * Upon return of this function, application will be given two objects:
+ * the slot number of the port in the bridge, and pointer to the media
+ * port where application MUST start calling get_frame() and put_frame()
+ * to the port.
+ *
+ * @param conf The conference bridge.
+ * @param pool Pool to allocate buffers etc for this port.
+ * @param name Name to be assigned to the port.
+ * @param clock_rate Clock rate/sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample.
+ * @param options Options (should be zero at the moment).
+ * @param p_slot Pointer to receive the slot index of the port in
+ * the conference bridge.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_add_passive_port( pjmedia_conf *conf,
+ pj_pool_t *pool,
+ const pj_str_t *name,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ unsigned *p_slot,
+ pjmedia_port **p_port );
+
+
+/**
+ * Change TX and RX settings for the port.
+ *
+ * @param conf The conference bridge.
+ * @param slot Port number/slot in the conference bridge.
+ * @param tx Settings for the transmission TO this port.
+ * @param rx Settings for the receipt FROM this port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_configure_port( pjmedia_conf *conf,
+ unsigned slot,
+ pjmedia_port_op tx,
+ pjmedia_port_op rx);
+
+
+/**
+ * Enable unidirectional audio from the specified source slot to the
+ * specified sink slot.
+ *
+ * @param conf The conference bridge.
+ * @param src_slot Source slot.
+ * @param sink_slot Sink slot.
+ * @param level This argument is reserved for future improvements
+ * where it is possible to adjust the level of signal
+ * transmitted in a specific connection. For now,
+ * this argument MUST be zero.
+ *
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf,
+ unsigned src_slot,
+ unsigned sink_slot,
+ int level );
+
+
+/**
+ * Disconnect unidirectional audio from the specified source to the specified
+ * sink slot.
+ *
+ * @param conf The conference bridge.
+ * @param src_slot Source slot.
+ * @param sink_slot Sink slot.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
+ unsigned src_slot,
+ unsigned sink_slot );
+
+
+/**
+ * Get number of ports currently registered to the conference bridge.
+ *
+ * @param conf The conference bridge.
+ *
+ * @return Number of ports currently registered to the conference
+ * bridge.
+ */
+PJ_DECL(unsigned) pjmedia_conf_get_port_count(pjmedia_conf *conf);
+
+
+/**
+ * Get total number of ports connections currently set up in the bridge.
+ *
+ * @param conf The conference bridge.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(unsigned) pjmedia_conf_get_connect_count(pjmedia_conf *conf);
+
+
+/**
+ * Remove the specified port from the conference bridge.
+ *
+ * @param conf The conference bridge.
+ * @param slot The port index to be removed.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,
+ unsigned slot );
+
+
+
+/**
+ * Enumerate occupied ports in the bridge.
+ *
+ * @param conf The conference bridge.
+ * @param ports Array of port numbers to be filled in.
+ * @param count On input, specifies the maximum number of ports
+ * in the array. On return, it will be filled with
+ * the actual number of ports.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,
+ unsigned ports[],
+ unsigned *count );
+
+
+/**
+ * Get port info.
+ *
+ * @param conf The conference bridge.
+ * @param slot Port index.
+ * @param info Pointer to receive the info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,
+ unsigned slot,
+ pjmedia_conf_port_info *info);
+
+
+/**
+ * Get occupied ports info.
+ *
+ * @param conf The conference bridge.
+ * @param size On input, contains maximum number of infos
+ * to be retrieved. On output, contains the actual
+ * number of infos that have been copied.
+ * @param info Array of info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_get_ports_info(pjmedia_conf *conf,
+ unsigned *size,
+ pjmedia_conf_port_info info[]
+ );
+
+
+/**
+ * Get last signal level transmitted to or received from the specified port.
+ * This will retrieve the "real-time" signal level of the audio as they are
+ * transmitted or received by the specified port. Application may call this
+ * function periodically to display the signal level to a VU meter.
+ *
+ * The signal level is an integer value in zero to 255, with zero indicates
+ * no signal, and 255 indicates the loudest signal level.
+ *
+ * @param conf The conference bridge.
+ * @param slot Slot number.
+ * @param tx_level Optional argument to receive the level of signal
+ * transmitted to the specified port (i.e. the direction
+ * is from the bridge to the port).
+ * @param rx_level Optional argument to receive the level of signal
+ * received from the port (i.e. the direction is from the
+ * port to the bridge).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_get_signal_level(pjmedia_conf *conf,
+ unsigned slot,
+ unsigned *tx_level,
+ unsigned *rx_level);
+
+
+/**
+ * Adjust the level of signal received from the specified port.
+ * Application may adjust the level to make signal received from the port
+ * either louder or more quiet. The level adjustment is calculated with this
+ * formula: <b><tt>output = input * (adj_level+128) / 128</tt></b>. Using
+ * this, zero indicates no adjustment, the value -128 will mute the signal,
+ * and the value of +128 will make the signal 100% louder, +256 will make it
+ * 200% louder, etc.
+ *
+ * The level adjustment value will stay with the port until the port is
+ * removed from the bridge or new adjustment value is set. The current
+ * level adjustment value is reported in the media port info when
+ * the #pjmedia_conf_get_port_info() function is called.
+ *
+ * @param conf The conference bridge.
+ * @param slot Slot number of the port.
+ * @param adj_level Adjustment level, which must be greater than or equal
+ * to -128. A value of zero means there is no level
+ * adjustment to be made, the value -128 will mute the
+ * signal, and the value of +128 will make the signal
+ * 100% louder, +256 will make it 200% louder, etc.
+ * See the function description for the formula.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_adjust_rx_level( pjmedia_conf *conf,
+ unsigned slot,
+ int adj_level );
+
+
+/**
+ * Adjust the level of signal to be transmitted to the specified port.
+ * Application may adjust the level to make signal transmitted to the port
+ * either louder or more quiet. The level adjustment is calculated with this
+ * formula: <b><tt>output = input * (adj_level+128) / 128</tt></b>. Using
+ * this, zero indicates no adjustment, the value -128 will mute the signal,
+ * and the value of +128 will make the signal 100% louder, +256 will make it
+ * 200% louder, etc.
+ *
+ * The level adjustment value will stay with the port until the port is
+ * removed from the bridge or new adjustment value is set. The current
+ * level adjustment value is reported in the media port info when
+ * the #pjmedia_conf_get_port_info() function is called.
+ *
+ * @param conf The conference bridge.
+ * @param slot Slot number of the port.
+ * @param adj_level Adjustment level, which must be greater than or equal
+ * to -128. A value of zero means there is no level
+ * adjustment to be made, the value -128 will mute the
+ * signal, and the value of +128 will make the signal
+ * 100% louder, +256 will make it 200% louder, etc.
+ * See the function description for the formula.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf,
+ unsigned slot,
+ int adj_level );
+
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CONF_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config.h
new file mode 100644
index 0000000..abcfc30
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config.h
@@ -0,0 +1,833 @@
+/* $Id: config.h 2977 2009-10-29 09:39:17Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CONFIG_H__
+#define __PJMEDIA_CONFIG_H__
+
+/**
+ * @file pjmedia/config.h Compile time config
+ * @brief Contains some compile time constants.
+ */
+#include <pj/config.h>
+
+/**
+ * @defgroup PJMEDIA_BASE Base Types and Configurations
+ */
+
+/**
+ * @defgroup PJMEDIA_CONFIG Compile time configuration
+ * @ingroup PJMEDIA_BASE
+ * @brief Some compile time configuration settings.
+ * @{
+ */
+
+/*
+ * Include config_auto.h if autoconf is used (PJ_AUTOCONF is set)
+ */
+#if defined(PJ_AUTOCONF)
+# include <pjmedia/config_auto.h>
+#endif
+
+/**
+ * Specify whether we prefer to use audio switch board rather than
+ * conference bridge.
+ *
+ * Audio switch board is a kind of simplified version of conference
+ * bridge, but not really the subset of conference bridge. It has
+ * stricter rules on audio routing among the pjmedia ports and has
+ * no audio mixing capability. The power of it is it could work with
+ * encoded audio frames where conference brigde couldn't.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_CONF_USE_SWITCH_BOARD
+# define PJMEDIA_CONF_USE_SWITCH_BOARD 0
+#endif
+
+/*
+ * Types of sound stream backends.
+ */
+
+/**
+ * This macro has been deprecated in releasee 1.1. Please see
+ * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more information.
+ */
+#if defined(PJMEDIA_SOUND_IMPLEMENTATION)
+# error PJMEDIA_SOUND_IMPLEMENTATION has been deprecated
+#endif
+
+/**
+ * This macro has been deprecated in releasee 1.1. Please see
+ * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more information.
+ */
+#if defined(PJMEDIA_PREFER_DIRECT_SOUND)
+# error PJMEDIA_PREFER_DIRECT_SOUND has been deprecated
+#endif
+
+/**
+ * This macro controls whether the legacy sound device API is to be
+ * implemented, for applications that still use the old sound device
+ * API (sound.h). If this macro is set to non-zero, the sound_legacy.c
+ * will be included in the compilation. The sound_legacy.c is an
+ * implementation of old sound device (sound.h) using the new Audio
+ * Device API.
+ *
+ * Please see http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more
+ * info.
+ */
+#ifndef PJMEDIA_HAS_LEGACY_SOUND_API
+# define PJMEDIA_HAS_LEGACY_SOUND_API 1
+#endif
+
+/**
+ * Specify default sound device latency, in milisecond.
+ */
+#ifndef PJMEDIA_SND_DEFAULT_REC_LATENCY
+# define PJMEDIA_SND_DEFAULT_REC_LATENCY 100
+#endif
+
+/**
+ * Specify default sound device latency, in milisecond.
+ *
+ * Default is 160ms for Windows Mobile and 140ms for other platforms.
+ */
+#ifndef PJMEDIA_SND_DEFAULT_PLAY_LATENCY
+# if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
+# define PJMEDIA_SND_DEFAULT_PLAY_LATENCY 160
+# else
+# define PJMEDIA_SND_DEFAULT_PLAY_LATENCY 140
+# endif
+#endif
+
+
+/*
+ * Types of WSOLA backend algorithm.
+ */
+
+/**
+ * This denotes implementation of WSOLA using null algorithm. Expansion
+ * will generate zero frames, and compression will just discard some
+ * samples from the input.
+ *
+ * This type of implementation may be used as it requires the least
+ * processing power.
+ */
+#define PJMEDIA_WSOLA_IMP_NULL 0
+
+/**
+ * This denotes implementation of WSOLA using fixed or floating point WSOLA
+ * algorithm. This implementation provides the best quality of the result,
+ * at the expense of one frame delay and intensive processing power
+ * requirement.
+ */
+#define PJMEDIA_WSOLA_IMP_WSOLA 1
+
+/**
+ * This denotes implementation of WSOLA algorithm with faster waveform
+ * similarity calculation. This implementation provides fair quality of
+ * the result with the main advantage of low processing power requirement.
+ */
+#define PJMEDIA_WSOLA_IMP_WSOLA_LITE 2
+
+/**
+ * Specify type of Waveform based Similarity Overlap and Add (WSOLA) backend
+ * implementation to be used. WSOLA is an algorithm to expand and/or compress
+ * audio frames without changing the pitch, and used by the delaybuf and as PLC
+ * backend algorithm.
+ *
+ * Default is PJMEDIA_WSOLA_IMP_WSOLA
+ */
+#ifndef PJMEDIA_WSOLA_IMP
+# define PJMEDIA_WSOLA_IMP PJMEDIA_WSOLA_IMP_WSOLA
+#endif
+
+
+/**
+ * Specify the default maximum duration of synthetic audio that is generated
+ * by WSOLA. This value should be long enough to cover burst of packet losses.
+ * but not too long, because as the duration increases the quality would
+ * degrade considerably.
+ *
+ * Note that this limit is only applied when fading is enabled in the WSOLA
+ * session.
+ *
+ * Default: 80
+ */
+#ifndef PJMEDIA_WSOLA_MAX_EXPAND_MSEC
+# define PJMEDIA_WSOLA_MAX_EXPAND_MSEC 80
+#endif
+
+
+/**
+ * Specify WSOLA template length, in milliseconds. The longer the template,
+ * the smoother signal to be generated at the expense of more computation
+ * needed, since the algorithm will have to compare more samples to find
+ * the most similar pitch.
+ *
+ * Default: 5
+ */
+#ifndef PJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC
+# define PJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC 5
+#endif
+
+
+/**
+ * Specify WSOLA algorithm delay, in milliseconds. The algorithm delay is
+ * used to merge synthetic samples with real samples in the transition
+ * between real to synthetic and vice versa. The longer the delay, the
+ * smoother signal to be generated, at the expense of longer latency and
+ * a slighty more computation.
+ *
+ * Default: 5
+ */
+#ifndef PJMEDIA_WSOLA_DELAY_MSEC
+# define PJMEDIA_WSOLA_DELAY_MSEC 5
+#endif
+
+
+/**
+ * Set this to non-zero to disable fade-out/in effect in the PLC when it
+ * instructs WSOLA to generate synthetic frames. The use of fading may
+ * or may not improve the quality of audio, depending on the nature of
+ * packet loss and the type of audio input (e.g. speech vs music).
+ * Disabling fading also implicitly remove the maximum limit of synthetic
+ * audio samples generated by WSOLA (see PJMEDIA_WSOLA_MAX_EXPAND_MSEC).
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_WSOLA_PLC_NO_FADING
+# define PJMEDIA_WSOLA_PLC_NO_FADING 0
+#endif
+
+
+/**
+ * Specify number of sound buffers. Larger number is better for sound
+ * stability and to accommodate sound devices that are unable to send frames
+ * in timely manner, however it would probably cause more audio delay (and
+ * definitely will take more memory). One individual buffer is normally 10ms
+ * or 20 ms long, depending on ptime settings (samples_per_frame value).
+ *
+ * The setting here currently is used by the conference bridge, the splitter
+ * combiner port, and dsound.c.
+ *
+ * Default: (PJMEDIA_SND_DEFAULT_PLAY_LATENCY+20)/20
+ */
+#ifndef PJMEDIA_SOUND_BUFFER_COUNT
+# define PJMEDIA_SOUND_BUFFER_COUNT ((PJMEDIA_SND_DEFAULT_PLAY_LATENCY+20)/20)
+#endif
+
+
+/**
+ * Specify which A-law/U-law conversion algorithm to use.
+ * By default the conversion algorithm uses A-law/U-law table which gives
+ * the best performance, at the expense of 33 KBytes of static data.
+ * If this option is disabled, a smaller but slower algorithm will be used.
+ */
+#ifndef PJMEDIA_HAS_ALAW_ULAW_TABLE
+# define PJMEDIA_HAS_ALAW_ULAW_TABLE 1
+#endif
+
+
+/**
+ * Unless specified otherwise, G711 codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_G711_CODEC
+# define PJMEDIA_HAS_G711_CODEC 1
+#endif
+
+
+/*
+ * Warn about obsolete macros.
+ *
+ * PJMEDIA_HAS_SMALL_FILTER has been deprecated in 0.7.
+ */
+#if defined(PJMEDIA_HAS_SMALL_FILTER)
+# ifdef _MSC_VER
+# pragma message("Warning: PJMEDIA_HAS_SMALL_FILTER macro is deprecated"\
+ " and has no effect")
+# else
+# warning "PJMEDIA_HAS_SMALL_FILTER macro is deprecated and has no effect"
+# endif
+#endif
+
+
+/*
+ * Warn about obsolete macros.
+ *
+ * PJMEDIA_HAS_LARGE_FILTER has been deprecated in 0.7.
+ */
+#if defined(PJMEDIA_HAS_LARGE_FILTER)
+# ifdef _MSC_VER
+# pragma message("Warning: PJMEDIA_HAS_LARGE_FILTER macro is deprecated"\
+ " and has no effect")
+# else
+# warning "PJMEDIA_HAS_LARGE_FILTER macro is deprecated"
+# endif
+#endif
+
+
+/*
+ * These macros are obsolete in 0.7.1 so it will trigger compilation error.
+ * Please use PJMEDIA_RESAMPLE_IMP to select the resample implementation
+ * to use.
+ */
+#ifdef PJMEDIA_HAS_LIBRESAMPLE
+# error "PJMEDIA_HAS_LIBRESAMPLE macro is deprecated. Use '#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE'"
+#endif
+
+#ifdef PJMEDIA_HAS_SPEEX_RESAMPLE
+# error "PJMEDIA_HAS_SPEEX_RESAMPLE macro is deprecated. Use '#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_SPEEX'"
+#endif
+
+
+/*
+ * Sample rate conversion backends.
+ * Select one of these backends in PJMEDIA_RESAMPLE_IMP.
+ */
+#define PJMEDIA_RESAMPLE_NONE 1 /**< No resampling. */
+#define PJMEDIA_RESAMPLE_LIBRESAMPLE 2 /**< Sample rate conversion
+ using libresample. */
+#define PJMEDIA_RESAMPLE_SPEEX 3 /**< Sample rate conversion
+ using Speex. */
+#define PJMEDIA_RESAMPLE_LIBSAMPLERATE 4 /**< Sample rate conversion
+ using libsamplerate
+ (a.k.a Secret Rabbit Code)
+ */
+
+/**
+ * Select which resample implementation to use. Currently pjmedia supports:
+ * - #PJMEDIA_RESAMPLE_LIBRESAMPLE, to use libresample-1.7, this is the default
+ * implementation to be used.
+ * - #PJMEDIA_RESAMPLE_LIBSAMPLERATE, to use libsamplerate implementation
+ * (a.k.a. Secret Rabbit Code).
+ * - #PJMEDIA_RESAMPLE_SPEEX, to use experimental sample rate conversion in
+ * Speex library.
+ * - #PJMEDIA_RESAMPLE_NONE, to disable sample rate conversion. Any calls to
+ * resample function will return error.
+ *
+ * Default is PJMEDIA_RESAMPLE_LIBRESAMPLE
+ */
+#ifndef PJMEDIA_RESAMPLE_IMP
+# define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE
+#endif
+
+
+/**
+ * Specify whether libsamplerate, when used, should be linked statically
+ * into the application. This option is only useful for Visual Studio
+ * projects, and when this static linking is enabled
+ */
+
+
+/**
+ * Default file player/writer buffer size.
+ */
+#ifndef PJMEDIA_FILE_PORT_BUFSIZE
+# define PJMEDIA_FILE_PORT_BUFSIZE 4000
+#endif
+
+
+/**
+ * Maximum frame duration (in msec) to be supported.
+ * This (among other thing) will affect the size of buffers to be allocated
+ * for outgoing packets.
+ */
+#ifndef PJMEDIA_MAX_FRAME_DURATION_MS
+# define PJMEDIA_MAX_FRAME_DURATION_MS 200
+#endif
+
+
+/**
+ * Max packet size to support.
+ */
+#ifndef PJMEDIA_MAX_MTU
+# define PJMEDIA_MAX_MTU 1500
+#endif
+
+
+/**
+ * DTMF/telephone-event duration, in timestamp.
+ */
+#ifndef PJMEDIA_DTMF_DURATION
+# define PJMEDIA_DTMF_DURATION 1600 /* in timestamp */
+#endif
+
+
+/**
+ * Number of packets received from different source IP address from the
+ * remote address required to make the stream switch transmission
+ * to the source address.
+ */
+#ifndef PJMEDIA_RTP_NAT_PROBATION_CNT
+# define PJMEDIA_RTP_NAT_PROBATION_CNT 10
+#endif
+
+
+/**
+ * Specify whether RTCP should be advertised in SDP. This setting would
+ * affect whether RTCP candidate will be added in SDP when ICE is used.
+ * Application might want to disable RTCP advertisement in SDP to
+ * reduce the message size.
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJMEDIA_ADVERTISE_RTCP
+# define PJMEDIA_ADVERTISE_RTCP 1
+#endif
+
+
+/**
+ * Interval to send RTCP packets, in msec
+ */
+#ifndef PJMEDIA_RTCP_INTERVAL
+# define PJMEDIA_RTCP_INTERVAL 5000 /* msec*/
+#endif
+
+
+/**
+ * Tell RTCP to ignore the first N packets when calculating the
+ * jitter statistics. From experimentation, the first few packets
+ * (25 or so) have relatively big jitter, possibly because during
+ * this time, the program is also busy setting up the signaling,
+ * so they make the average jitter big.
+ *
+ * Default: 25.
+ */
+#ifndef PJMEDIA_RTCP_IGNORE_FIRST_PACKETS
+# define PJMEDIA_RTCP_IGNORE_FIRST_PACKETS 25
+#endif
+
+/**
+ * Specify whether RTCP XR support should be built into PJMEDIA. Disabling
+ * this feature will reduce footprint slightly. Note that even when this
+ * setting is enabled, RTCP XR processing will only be performed in stream
+ * if it is enabled on run-time on per stream basis. See
+ * PJMEDIA_STREAM_ENABLE_XR setting for more info.
+ *
+ * Default: 1 (yes).
+ */
+#ifndef PJMEDIA_HAS_RTCP_XR
+# define PJMEDIA_HAS_RTCP_XR 0
+#endif
+
+
+/**
+ * The RTCP XR feature is activated and used by stream if \a enable_rtcp_xr
+ * field of \a pjmedia_stream_info structure is non-zero. This setting
+ * controls the default value of this field.
+ *
+ * Default: 0 (disabled)
+ */
+#ifndef PJMEDIA_STREAM_ENABLE_XR
+# define PJMEDIA_STREAM_ENABLE_XR 0
+#endif
+
+/**
+ * Specify how long (in miliseconds) the stream should suspend the
+ * silence detector/voice activity detector (VAD) during the initial
+ * period of the session. This feature is useful to open bindings in
+ * all NAT routers between local and remote endpoint since most NATs
+ * do not allow incoming packet to get in before local endpoint sends
+ * outgoing packets.
+ *
+ * Specify zero to disable this feature.
+ *
+ * Default: 600 msec (which gives good probability that some RTP
+ * packets will reach the destination, but without
+ * filling up the jitter buffer on the remote end).
+ */
+#ifndef PJMEDIA_STREAM_VAD_SUSPEND_MSEC
+# define PJMEDIA_STREAM_VAD_SUSPEND_MSEC 600
+#endif
+
+
+/**
+ * Specify the maximum duration of silence period in the codec, in msec.
+ * This is useful for example to keep NAT binding open in the firewall
+ * and to prevent server from disconnecting the call because no
+ * RTP packet is received.
+ *
+ * This only applies to codecs that use PJMEDIA's VAD (pretty much
+ * everything including iLBC, except Speex, which has its own DTX
+ * mechanism).
+ *
+ * Use (-1) to disable this feature.
+ *
+ * Default: 5000 ms
+ *
+ */
+#ifndef PJMEDIA_CODEC_MAX_SILENCE_PERIOD
+# define PJMEDIA_CODEC_MAX_SILENCE_PERIOD 5000
+#endif
+
+
+/**
+ * Suggested or default threshold to be set for fixed silence detection
+ * or as starting threshold for adaptive silence detection. The threshold
+ * has the range from zero to 0xFFFF.
+ */
+#ifndef PJMEDIA_SILENCE_DET_THRESHOLD
+# define PJMEDIA_SILENCE_DET_THRESHOLD 4
+#endif
+
+
+/**
+ * Maximum silence threshold in the silence detector. The silence detector
+ * will not cut the audio transmission if the audio level is above this
+ * level.
+ *
+ * Use 0x10000 (or greater) to disable this feature.
+ *
+ * Default: 0x10000 (disabled)
+ */
+#ifndef PJMEDIA_SILENCE_DET_MAX_THRESHOLD
+# define PJMEDIA_SILENCE_DET_MAX_THRESHOLD 0x10000
+#endif
+
+
+/**
+ * Speex Accoustic Echo Cancellation (AEC).
+ * By default is enabled.
+ */
+#ifndef PJMEDIA_HAS_SPEEX_AEC
+# define PJMEDIA_HAS_SPEEX_AEC 1
+#endif
+
+
+/**
+ * This specifies the behavior of the SDP negotiator when responding to an
+ * offer, whether it should rather use the codec preference as set by
+ * remote, or should it rather use the codec preference as specified by
+ * local endpoint.
+ *
+ * For example, suppose incoming call has codec order "8 0 3", while
+ * local codec order is "3 0 8". If remote codec order is preferable,
+ * the selected codec will be 8, while if local codec order is preferable,
+ * the selected codec will be 3.
+ *
+ * If set to non-zero, the negotiator will use the codec order as specified
+ * by remote in the offer.
+ *
+ * Note that this behavior can be changed during run-time by calling
+ * pjmedia_sdp_neg_set_prefer_remote_codec_order().
+ *
+ * Default is 1 (to maintain backward compatibility)
+ */
+#ifndef PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER
+# define PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER 1
+#endif
+
+
+/**
+ * Support for sending and decoding RTCP port in SDP (RFC 3605).
+ * Default is equal to PJMEDIA_ADVERTISE_RTCP setting.
+ */
+#ifndef PJMEDIA_HAS_RTCP_IN_SDP
+# define PJMEDIA_HAS_RTCP_IN_SDP (PJMEDIA_ADVERTISE_RTCP)
+#endif
+
+
+/**
+ * This macro controls whether pjmedia should include SDP rtpmap
+ * attribute for static payload types. SDP rtpmap for static
+ * payload types are optional, although they are normally included
+ * for interoperability reason.
+ *
+ * Note that there is also a run-time variable to turn this setting
+ * on or off, defined in endpoint.c. To access this variable, use
+ * the following construct
+ *
+ \verbatim
+ extern pj_bool_t pjmedia_add_rtpmap_for_static_pt;
+
+ // Do not include rtpmap for static payload types (<96)
+ pjmedia_add_rtpmap_for_static_pt = PJ_FALSE;
+ \endverbatim
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJMEDIA_ADD_RTPMAP_FOR_STATIC_PT
+# define PJMEDIA_ADD_RTPMAP_FOR_STATIC_PT 1
+#endif
+
+
+/**
+ * This macro declares the payload type for telephone-event
+ * that is advertised by PJMEDIA for outgoing SDP. If this macro
+ * is set to zero, telephone events would not be advertised nor
+ * supported.
+ *
+ * If this value is changed to other number, please update the
+ * PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR too.
+ */
+#ifndef PJMEDIA_RTP_PT_TELEPHONE_EVENTS
+# define PJMEDIA_RTP_PT_TELEPHONE_EVENTS 101
+#endif
+
+
+/**
+ * Macro to get the string representation of the telephone-event
+ * payload type.
+ */
+#ifndef PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR
+# define PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR "101"
+#endif
+
+
+/**
+ * Maximum tones/digits that can be enqueued in the tone generator.
+ */
+#ifndef PJMEDIA_TONEGEN_MAX_DIGITS
+# define PJMEDIA_TONEGEN_MAX_DIGITS 32
+#endif
+
+
+/*
+ * Below specifies the various tone generator backend algorithm.
+ */
+
+/**
+ * The math's sine(), floating point. This has very good precision
+ * but it's the slowest and requires floating point support and
+ * linking with the math library.
+ */
+#define PJMEDIA_TONEGEN_SINE 1
+
+/**
+ * Floating point approximation of sine(). This has relatively good
+ * precision and much faster than plain sine(), but it requires floating-
+ * point support and linking with the math library.
+ */
+#define PJMEDIA_TONEGEN_FLOATING_POINT 2
+
+/**
+ * Fixed point using sine signal generated by Cordic algorithm. This
+ * algorithm can be tuned to provide balance between precision and
+ * performance by tuning the PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP
+ * setting, and may be suitable for platforms that lack floating-point
+ * support.
+ */
+#define PJMEDIA_TONEGEN_FIXED_POINT_CORDIC 3
+
+/**
+ * Fast fixed point using some approximation to generate sine waves.
+ * The tone generated by this algorithm is not very precise, however
+ * the algorithm is very fast.
+ */
+#define PJMEDIA_TONEGEN_FAST_FIXED_POINT 4
+
+
+/**
+ * Specify the tone generator algorithm to be used. Please see
+ * http://trac.pjsip.org/repos/wiki/Tone_Generator for the performance
+ * analysis results of the various tone generator algorithms.
+ *
+ * Default value:
+ * - PJMEDIA_TONEGEN_FLOATING_POINT when PJ_HAS_FLOATING_POINT is set
+ * - PJMEDIA_TONEGEN_FIXED_POINT_CORDIC when PJ_HAS_FLOATING_POINT is not set
+ */
+#ifndef PJMEDIA_TONEGEN_ALG
+# if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT
+# define PJMEDIA_TONEGEN_ALG PJMEDIA_TONEGEN_FLOATING_POINT
+# else
+# define PJMEDIA_TONEGEN_ALG PJMEDIA_TONEGEN_FIXED_POINT_CORDIC
+# endif
+#endif
+
+
+/**
+ * Specify the number of calculation loops to generate the tone, when
+ * PJMEDIA_TONEGEN_FIXED_POINT_CORDIC algorithm is used. With more calculation
+ * loops, the tone signal gets more precise, but this will add more
+ * processing.
+ *
+ * Valid values are 1 to 28.
+ *
+ * Default value: 10
+ */
+#ifndef PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP
+# define PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP 10
+#endif
+
+
+/**
+ * Enable high quality of tone generation, the better quality will cost
+ * more CPU load. This is only applied to floating point enabled machines.
+ *
+ * By default it is enabled when PJ_HAS_FLOATING_POINT is set.
+ *
+ * This macro has been deprecated in version 1.0-rc3.
+ */
+#ifdef PJMEDIA_USE_HIGH_QUALITY_TONEGEN
+# error "The PJMEDIA_USE_HIGH_QUALITY_TONEGEN macro is obsolete"
+#endif
+
+
+/**
+ * Fade-in duration for the tone, in milliseconds. Set to zero to disable
+ * this feature.
+ *
+ * Default: 1 (msec)
+ */
+#ifndef PJMEDIA_TONEGEN_FADE_IN_TIME
+# define PJMEDIA_TONEGEN_FADE_IN_TIME 1
+#endif
+
+
+/**
+ * Fade-out duration for the tone, in milliseconds. Set to zero to disable
+ * this feature.
+ *
+ * Default: 2 (msec)
+ */
+#ifndef PJMEDIA_TONEGEN_FADE_OUT_TIME
+# define PJMEDIA_TONEGEN_FADE_OUT_TIME 2
+#endif
+
+
+/**
+ * The default tone generator amplitude (1-32767).
+ *
+ * Default value: 12288
+ */
+#ifndef PJMEDIA_TONEGEN_VOLUME
+# define PJMEDIA_TONEGEN_VOLUME 12288
+#endif
+
+
+/**
+ * Enable support for SRTP media transport. This will require linking
+ * with libsrtp from the third_party directory.
+ *
+ * By default it is enabled.
+ */
+#ifndef PJMEDIA_HAS_SRTP
+# define PJMEDIA_HAS_SRTP 1
+#endif
+
+
+/**
+ * Enable support to handle codecs with inconsistent clock rate
+ * between clock rate in SDP/RTP & the clock rate that is actually used.
+ * This happens for example with G.722 and MPEG audio codecs.
+ * See:
+ * - G.722 : RFC 3551 4.5.2
+ * - MPEG audio : RFC 3551 4.5.13 & RFC 3119
+ *
+ * Also when this feature is enabled, some handling will be performed
+ * to deal with clock rate incompatibilities of some phones.
+ *
+ * By default it is enabled.
+ */
+#ifndef PJMEDIA_HANDLE_G722_MPEG_BUG
+# define PJMEDIA_HANDLE_G722_MPEG_BUG 1
+#endif
+
+
+/**
+ * Transport info (pjmedia_transport_info) contains a socket info and list
+ * of transport specific info, since transports can be chained together
+ * (for example, SRTP transport uses UDP transport as the underlying
+ * transport). This constant specifies maximum number of transport specific
+ * infos that can be held in a transport info.
+ */
+#ifndef PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT
+# define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT 4
+#endif
+
+
+/**
+ * Maximum size in bytes of storage buffer of a transport specific info.
+ */
+#ifndef PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE
+# define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE (16*sizeof(long))
+#endif
+
+
+/**
+ * Value to be specified in PJMEDIA_STREAM_ENABLE_KA setting.
+ * This indicates that an empty RTP packet should be used as
+ * the keep-alive packet.
+ */
+#define PJMEDIA_STREAM_KA_EMPTY_RTP 1
+
+/**
+ * Value to be specified in PJMEDIA_STREAM_ENABLE_KA setting.
+ * This indicates that a user defined packet should be used
+ * as the keep-alive packet. The content of the user-defined
+ * packet is specified by PJMEDIA_STREAM_KA_USER_PKT. Default
+ * content is a CR-LF packet.
+ */
+#define PJMEDIA_STREAM_KA_USER 2
+
+/**
+ * The content of the user defined keep-alive packet. The format
+ * of the packet is initializer to pj_str_t structure. Note that
+ * the content may contain NULL character.
+ */
+#ifndef PJMEDIA_STREAM_KA_USER_PKT
+# define PJMEDIA_STREAM_KA_USER_PKT { "\r\n", 2 }
+#endif
+
+/**
+ * Specify another type of keep-alive and NAT hole punching
+ * mechanism (the other type is PJMEDIA_STREAM_VAD_SUSPEND_MSEC
+ * and PJMEDIA_CODEC_MAX_SILENCE_PERIOD) to be used by stream.
+ * When this feature is enabled, the stream will initially
+ * transmit one packet to punch a hole in NAT, and periodically
+ * transmit keep-alive packets.
+ *
+ * When this alternative keep-alive mechanism is used, application
+ * may disable the other keep-alive mechanisms, i.e: by setting
+ * PJMEDIA_STREAM_VAD_SUSPEND_MSEC to zero and
+ * PJMEDIA_CODEC_MAX_SILENCE_PERIOD to -1.
+ *
+ * The value of this macro specifies the type of packet used
+ * for the keep-alive mechanism. Valid values are
+ * PJMEDIA_STREAM_KA_EMPTY_RTP and PJMEDIA_STREAM_KA_USER.
+ *
+ * The duration of the keep-alive interval further can be set
+ * with PJMEDIA_STREAM_KA_INTERVAL setting.
+ *
+ * Default: 0 (disabled)
+ */
+#ifndef PJMEDIA_STREAM_ENABLE_KA
+# define PJMEDIA_STREAM_ENABLE_KA 0
+#endif
+
+
+/**
+ * Specify the keep-alive interval of PJMEDIA_STREAM_ENABLE_KA
+ * mechanism, in seconds.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJMEDIA_STREAM_KA_INTERVAL
+# define PJMEDIA_STREAM_KA_INTERVAL 5
+#endif
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CONFIG_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config_auto.h.in b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config_auto.h.in
new file mode 100644
index 0000000..3ec8773
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config_auto.h.in
@@ -0,0 +1,43 @@
+/* $Id: config_auto.h.in 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_CONFIG_AUTO_H_
+#define __PJMEDIA_CONFIG_AUTO_H_
+
+/**
+ * @file config_auto.h
+ * @brief PJMEDIA configuration as set by autoconf script
+ */
+
+/*
+ * Note:
+ * The configuration in config_site.h overrides any other settings,
+ * including the setting as detected by autoconf.
+ */
+
+/* G711 codec */
+#ifndef PJMEDIA_HAS_G711_CODEC
+#undef PJMEDIA_HAS_G711_CODEC
+#endif
+
+
+#endif /* __PJMEDIA_CONFIG_AUTO_H_ */
+
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/delaybuf.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/delaybuf.h
new file mode 100644
index 0000000..fc6a3e6
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/delaybuf.h
@@ -0,0 +1,158 @@
+/* $Id: delaybuf.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_DELAYBUF_H__
+#define __PJMEDIA_DELAYBUF_H__
+
+
+/**
+ * @file delaybuf.h
+ * @brief Delay Buffer.
+ */
+
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMED_DELAYBUF Adaptive Delay Buffer
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Adaptive delay buffer with high-quality time-scale
+ * modification
+ * @{
+ *
+ * This section describes PJMEDIA's implementation of delay buffer.
+ * Delay buffer works quite similarly like a fixed jitter buffer, that
+ * is it will delay the frame retrieval by some interval so that caller
+ * will get continuous frame from the buffer. This can be useful when
+ * the put() and get() operations are not evenly interleaved, for example
+ * when caller performs burst of put() operations and then followed by
+ * burst of get() operations. With using this delay buffer, the buffer
+ * will put the burst frames into a buffer so that get() operations
+ * will always get a frame from the buffer (assuming that the number of
+ * get() and put() are matched).
+ *
+ * The buffer is adaptive, that is it continuously learns the optimal delay
+ * to be applied to the audio flow at run-time. Once the optimal delay has
+ * been learned, the delay buffer will apply this delay to the audio flow,
+ * expanding or shrinking the audio samples as necessary when the actual
+ * audio samples in the buffer are too low or too high. It does this without
+ * distorting the audio quality of the audio, by using \a PJMED_WSOLA.
+ *
+ * The delay buffer is used in \ref PJMED_SND_PORT, \ref PJMEDIA_SPLITCOMB,
+ * and \ref PJMEDIA_CONF.
+ */
+
+PJ_BEGIN_DECL
+
+/** Opaque declaration for delay buffer. */
+typedef struct pjmedia_delay_buf pjmedia_delay_buf;
+
+/**
+ * Create the delay buffer. Once the delay buffer is created, it will
+ * enter learning state unless the delay argument is specified, which
+ * in this case it will directly enter the running state.
+ *
+ * @param pool Pool where the delay buffer will be allocated
+ * from.
+ * @param name Optional name for the buffer for log
+ * identification.
+ * @param clock_rate Number of samples processed per second.
+ * @param samples_per_frame Number of samples per frame.
+ * @param channel_count Number of channel per frame.
+ * @param max_delay Maximum number of delay to be accommodated,
+ * in ms, if this value is negative or less than
+ * one frame time, default maximum delay used is
+ * 400 ms.
+ * @param option Option flags, must be zero for now.
+ * @param p_b Pointer to receive the delay buffer instance.
+ *
+ * @return PJ_SUCCESS if the delay buffer has been
+ * created successfully, otherwise the appropriate
+ * error will be returned.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_create(pj_pool_t *pool,
+ const char *name,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ unsigned channel_count,
+ unsigned max_delay,
+ unsigned options,
+ pjmedia_delay_buf **p_b);
+
+/**
+ * Put one frame into the buffer.
+ *
+ * @param b The delay buffer.
+ * @param frame Frame to be put into the buffer. This frame
+ * must have samples_per_frame length.
+ *
+ * @return PJ_SUCCESS if frames can be put successfully.
+ * PJ_EPENDING if the buffer is still at learning
+ * state. PJ_ETOOMANY if the number of frames
+ * will exceed maximum delay level, which in this
+ * case the new frame will overwrite the oldest
+ * frame in the buffer.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,
+ pj_int16_t frame[]);
+
+/**
+ * Get one frame from the buffer.
+ *
+ * @param b The delay buffer.
+ * @param frame Buffer to receive the frame from the delay
+ * buffer.
+ *
+ * @return PJ_SUCCESS if frame has been copied successfully.
+ * PJ_EPENDING if no frame is available, either
+ * because the buffer is still at learning state or
+ * no buffer is available during running state.
+ * On non-successful return, the frame will be
+ * filled with zeroes.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_get(pjmedia_delay_buf *b,
+ pj_int16_t frame[]);
+
+/**
+ * Reset delay buffer. This will clear the buffer's content. But keep
+ * the learning result.
+ *
+ * @param b The delay buffer.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_reset(pjmedia_delay_buf *b);
+
+/**
+ * Destroy delay buffer.
+ *
+ * @param b Delay buffer session.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_destroy(pjmedia_delay_buf *b);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_DELAYBUF_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/doxygen.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/doxygen.h
new file mode 100644
index 0000000..945b6c5
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/doxygen.h
@@ -0,0 +1,174 @@
+/* $Id: doxygen.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_DOXYGEN_H__
+#define __PJMEDIA_DOXYGEN_H__
+
+/**
+ * @file doxygen.h
+ * @brief Doxygen's mainpage.
+ */
+
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+ INTRODUCTION PAGE
+ */
+
+/**
+ * @mainpage PJMEDIA and PJMEDIA-CODEC
+ *
+ * \n
+ * @section intro_sec PJMEDIA
+ *
+ * PJMEDIA is a rather complete media stack, distributed under Open Source/GPL
+ * terms, and featuring small footprint and good extensibility and portability.
+ *
+ * Please click the <A HREF="modules.htm"><b>Table of Contents</b></A> link on top
+ * of this page to get the complete features currently present in PJMEDIA.
+ *
+ * Also please read the documentation about @ref PJMEDIA_PORT
+ * which is a major concept that is used for implementing many objects in
+ * the library.
+ *
+ * \n
+ * @section pjmedia_codec_sec PJMEDIA-CODEC
+ *
+ * PJMEDIA-CODEC is a static library containing various codec implementations,
+ * wrapped into PJMEDIA codec framework. The static library is designed as
+ * such so that only codecs that are explicitly initialized are linked with
+ * the application, therefore keeping the application size in control.
+ *
+ * Please see @ref pjmedia_codec_page on how to use the codec in
+ * PJMEDIA-CODEC.
+ *
+ * \n
+ * @section main_page_get_start_sec Getting Started
+ *
+ * For those who likes to just get start coding, the @ref getting_started_pjmedia
+ * may be a good place to start.
+ *
+ * The @ref page_pjmedia_samples page describes some examples that are available
+ * in the source tree.
+ *
+ *
+ * \n
+ * @section pjmedia_lic Copying and Acknowledgements
+ *
+ * PJMEDIA and PJMEDIA-CODEC contains various parts obtained from other
+ * places, and each of these would have their own licensing terms.
+ * Please see @ref lic_stuffs page for details.
+ *
+ */
+
+
+/**
+ @page page_pjmedia_samples PJMEDIA and PJMEDIA-CODEC Examples
+
+ @section pjmedia_samples_sec PJMEDIA and PJMEDIA-CODEC Examples
+
+ Please find below some PJMEDIA related examples that may help in giving
+ some more info:
+
+ - @ref page_pjmedia_samples_level_c\n
+ This is a good place to start learning about @ref PJMEDIA_PORT,
+ as it shows that @ref PJMEDIA_PORT are only "passive" objects
+ with <tt>get_frame()</tt> and <tt>put_frame()</tt> interface, and
+ someone has to call these to retrieve/store media frames.
+
+ - @ref page_pjmedia_samples_playfile_c\n
+ This example shows that when application connects a media port (in this
+ case a @ref PJMEDIA_FILE_PLAY) to @ref PJMED_SND_PORT, media will flow
+ automatically since the @ref PJMED_SND_PORT provides @ref PJMEDIA_PORT_CLOCK.
+
+ - @ref page_pjmedia_samples_recfile_c\n
+ Demonstrates how to capture audio from microphone to WAV file.
+
+ - @ref page_pjmedia_samples_playsine_c\n
+ Demonstrates how to create a custom @ref PJMEDIA_PORT (in this
+ case a sine wave generator) and integrate it to PJMEDIA.
+
+ - @ref page_pjmedia_samples_confsample_c\n
+ This demonstrates how to use the @ref PJMEDIA_CONF. The sample program can
+ open multiple WAV files, and instruct the conference bridge to mix the
+ signal before playing it to the sound device.
+
+ - @ref page_pjmedia_samples_confbench_c\n
+ I use this to benchmark/optimize the conference bridge algorithm, but
+ readers may find the source useful.
+
+ - @ref page_pjmedia_samples_resampleplay_c\n
+ Demonstrates how to use @ref PJMEDIA_RESAMPLE_PORT to change the
+ sampling rate of a media port (in this case, a @ref PJMEDIA_FILE_PLAY).
+
+ - @ref page_pjmedia_samples_sndtest_c\n
+ This program performs some tests to the sound device to get some
+ quality parameters (such as sound jitter and clock drifts).\n
+ Screenshots on WinXP: \image html sndtest.jpg "sndtest screenshot on WinXP"
+
+ - @ref page_pjmedia_samples_streamutil_c\n
+ This example mainly demonstrates how to stream media (in this case a
+ @ref PJMEDIA_FILE_PLAY) to remote peer using RTP.
+
+ - @ref page_pjmedia_samples_siprtp_c\n
+ This is a useful program (integrated with PJSIP) to actively measure
+ the network quality/impairment parameters by making one or more SIP
+ calls (or receiving one or more SIP calls) and display the network
+ impairment of each stream direction at the end of the call.
+ The program is able to measure network quality parameters such as
+ jitter, packet lost/reorder/duplicate, round trip time, etc.\n
+ Note that the remote peer MUST support RTCP so that network quality
+ of each direction can be calculated. Using siprtp for both endpoints
+ is recommended.\n
+ Screenshots on WinXP: \image html siprtp.jpg "siprtp screenshot on WinXP"
+
+ - @ref page_pjmedia_samples_tonegen_c\n
+ This is a simple program to generate a tone and write the samples to
+ a raw PCM file. The main purpose of this file is to analyze the
+ quality of the tones/sine wave generated by PJMEDIA tone/sine wave
+ generator.
+
+ - @ref page_pjmedia_samples_aectest_c\n
+ Play a file to speaker, run AEC, and record the microphone input
+ to see if echo is coming.
+ */
+
+/**
+ * \page page_pjmedia_samples_siprtp_c Samples: Using SIP and Custom RTP/RTCP to Monitor Quality
+ *
+ * This source is an example to demonstrate using SIP and RTP/RTCP framework
+ * to measure the network quality/impairment from the SIP call. This
+ * program can be used to make calls or to receive calls from other
+ * SIP endpoint (or other siprtp program), and to display the media
+ * quality statistics at the end of the call.
+ *
+ * Note that the remote peer must support RTCP.
+ *
+ * The layout of the program has been designed so that custom reporting
+ * can be generated instead of plain human readable text.
+ *
+ * The source code of the file is pjsip-apps/src/samples/siprtp.c
+ *
+ * Screenshots on WinXP: \image html siprtp.jpg
+ *
+ * \includelineno siprtp.c
+ */
+
+#endif /* __PJMEDIA_DOXYGEN_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo.h
new file mode 100644
index 0000000..d8a4ec1
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo.h
@@ -0,0 +1,247 @@
+/* $Id: echo.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_ECHO_H__
+#define __PJMEDIA_ECHO_H__
+
+
+/**
+ * @file echo.h
+ * @brief Echo Cancellation API.
+ */
+#include <pjmedia/types.h>
+
+
+
+/**
+ * @defgroup PJMEDIA_Echo_Cancel Accoustic Echo Cancellation API
+ * @ingroup PJMEDIA_PORT
+ * @brief Echo Cancellation API.
+ * @{
+ *
+ * This section describes API to perform echo cancellation to audio signal.
+ * There may be multiple echo canceller implementation in PJMEDIA, ranging
+ * from simple echo suppressor to a full Accoustic Echo Canceller/AEC. By
+ * using this API, application should be able to use which EC backend to
+ * use base on the requirement and capability of the platform.
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque type for PJMEDIA Echo Canceller state.
+ */
+typedef struct pjmedia_echo_state pjmedia_echo_state;
+
+
+/**
+ * Echo cancellation options.
+ */
+typedef enum pjmedia_echo_flag
+{
+ /**
+ * Use any available backend echo canceller algorithm. This is
+ * the default settings. This setting is mutually exclusive with
+ * PJMEDIA_ECHO_SIMPLE and PJMEDIA_ECHO_SPEEX.
+ */
+ PJMEDIA_ECHO_DEFAULT= 0,
+
+ /**
+ * Force to use Speex AEC as the backend echo canceller algorithm.
+ * This setting is mutually exclusive with PJMEDIA_ECHO_SIMPLE.
+ */
+ PJMEDIA_ECHO_SPEEX = 1,
+
+ /**
+ * If PJMEDIA_ECHO_SIMPLE flag is specified during echo canceller
+ * creation, then a simple echo suppressor will be used instead of
+ * an accoustic echo cancellation. This setting is mutually exclusive
+ * with PJMEDIA_ECHO_SPEEX.
+ */
+ PJMEDIA_ECHO_SIMPLE = 2,
+
+ /**
+ * For internal use.
+ */
+ PJMEDIA_ECHO_ALGO_MASK = 15,
+
+ /**
+ * If PJMEDIA_ECHO_NO_LOCK flag is specified, no mutex will be created
+ * for the echo canceller, but application will guarantee that echo
+ * canceller will not be called by different threads at the same time.
+ */
+ PJMEDIA_ECHO_NO_LOCK = 16
+
+} pjmedia_echo_flag;
+
+
+
+
+/**
+ * Create the echo canceller.
+ *
+ * @param pool Pool to allocate memory.
+ * @param clock_rate Media clock rate/sampling rate.
+ * @param samples_per_frame Number of samples per frame.
+ * @param tail_ms Tail length, miliseconds.
+ * @param latency_ms Total lacency introduced by playback and
+ * recording device. Set to zero if the latency
+ * is not known.
+ * @param options Options. If PJMEDIA_ECHO_SIMPLE is specified,
+ * then a simple echo suppressor implementation
+ * will be used instead of an accoustic echo
+ * cancellation.
+ * See #pjmedia_echo_flag for other options.
+ * @param p_echo Pointer to receive the Echo Canceller state.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate status.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_create(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ unsigned tail_ms,
+ unsigned latency_ms,
+ unsigned options,
+ pjmedia_echo_state **p_echo );
+
+/**
+ * Create multi-channel the echo canceller.
+ *
+ * @param pool Pool to allocate memory.
+ * @param clock_rate Media clock rate/sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param tail_ms Tail length, miliseconds.
+ * @param latency_ms Total lacency introduced by playback and
+ * recording device. Set to zero if the latency
+ * is not known.
+ * @param options Options. If PJMEDIA_ECHO_SIMPLE is specified,
+ * then a simple echo suppressor implementation
+ * will be used instead of an accoustic echo
+ * cancellation.
+ * See #pjmedia_echo_flag for other options.
+ * @param p_echo Pointer to receive the Echo Canceller state.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate status.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_create2(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned tail_ms,
+ unsigned latency_ms,
+ unsigned options,
+ pjmedia_echo_state **p_echo );
+
+/**
+ * Destroy the Echo Canceller.
+ *
+ * @param echo The Echo Canceller.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_destroy(pjmedia_echo_state *echo );
+
+
+/**
+ * Reset the echo canceller.
+ *
+ * @param echo The Echo Canceller.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_reset(pjmedia_echo_state *echo );
+
+
+/**
+ * Let the Echo Canceller know that a frame has been played to the speaker.
+ * The Echo Canceller will keep the frame in its internal buffer, to be used
+ * when cancelling the echo with #pjmedia_echo_capture().
+ *
+ * @param echo The Echo Canceller.
+ * @param play_frm Sample buffer containing frame to be played
+ * (or has been played) to the playback device.
+ * The frame must contain exactly samples_per_frame
+ * number of samples.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_playback(pjmedia_echo_state *echo,
+ pj_int16_t *play_frm );
+
+
+/**
+ * Let the Echo Canceller know that a frame has been captured from the
+ * microphone. The Echo Canceller will cancel the echo from the captured
+ * signal, using the internal buffer (supplied by #pjmedia_echo_playback())
+ * as the FES (Far End Speech) reference.
+ *
+ * @param echo The Echo Canceller.
+ * @param rec_frm On input, it contains the input signal (captured
+ * from microphone) which echo is to be removed.
+ * Upon returning this function, this buffer contain
+ * the processed signal with the echo removed.
+ * The frame must contain exactly samples_per_frame
+ * number of samples.
+ * @param options Echo cancellation options, reserved for future use.
+ * Put zero for now.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_capture(pjmedia_echo_state *echo,
+ pj_int16_t *rec_frm,
+ unsigned options );
+
+
+/**
+ * Perform echo cancellation.
+ *
+ * @param echo The Echo Canceller.
+ * @param rec_frm On input, it contains the input signal (captured
+ * from microphone) which echo is to be removed.
+ * Upon returning this function, this buffer contain
+ * the processed signal with the echo removed.
+ * @param play_frm Sample buffer containing frame to be played
+ * (or has been played) to the playback device.
+ * The frame must contain exactly samples_per_frame
+ * number of samples.
+ * @param options Echo cancellation options, reserved for future use.
+ * Put zero for now.
+ * @param reserved Reserved for future use, put NULL for now.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_cancel( pjmedia_echo_state *echo,
+ pj_int16_t *rec_frm,
+ const pj_int16_t *play_frm,
+ unsigned options,
+ void *reserved );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_ECHO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo_port.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo_port.h
new file mode 100644
index 0000000..e0e1737
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo_port.h
@@ -0,0 +1,74 @@
+/* $Id: echo_port.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_AEC_PORT_H__
+#define __PJMEDIA_AEC_PORT_H__
+
+/**
+ * @file echo_port.h
+ * @brief AEC (Accoustic Echo Cancellation) media port.
+ */
+#include <pjmedia/port.h>
+
+
+
+/**
+ * @defgroup PJMEDIA_ECHO_PORT Echo Cancellation Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Echo Cancellation
+ * @{
+ *
+ * Wrapper to \ref PJMEDIA_Echo_Cancel into media port interface.
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create echo canceller port.
+ *
+ * @param pool Pool to allocate memory.
+ * @param dn_port Downstream port.
+ * @param tail_ms Tail length in miliseconds.
+ * @param latency_ms Total lacency introduced by playback and
+ * recording device. Set to zero if the latency
+ * is not known.
+ * @param options Options, as in #pjmedia_echo_create().
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_port_create(pj_pool_t *pool,
+ pjmedia_port *dn_port,
+ unsigned tail_ms,
+ unsigned latency_ms,
+ unsigned options,
+ pjmedia_port **p_port );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_AEC_PORT_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/endpoint.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/endpoint.h
new file mode 100644
index 0000000..f52275e
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/endpoint.h
@@ -0,0 +1,177 @@
+/* $Id: endpoint.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_MEDIAMGR_H__
+#define __PJMEDIA_MEDIAMGR_H__
+
+
+/**
+ * @file endpoint.h
+ * @brief Media endpoint.
+ */
+/**
+ * @defgroup PJMED_ENDPT The Endpoint
+ * @{
+ *
+ * The media endpoint acts as placeholder for endpoint capabilities. Each
+ * media endpoint will have a codec manager to manage list of codecs installed
+ * in the endpoint and a sound device factory.
+ *
+ * A reference to media endpoint instance is required when application wants
+ * to create a media session (#pjmedia_session_create()).
+ */
+
+#include <pjmedia/codec.h>
+#include <pjmedia/sdp.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create an instance of media endpoint.
+ *
+ * @param pf Pool factory, which will be used by the media endpoint
+ * throughout its lifetime.
+ * @param ioqueue Optional ioqueue instance to be registered to the
+ * endpoint. The ioqueue instance is used to poll all RTP
+ * and RTCP sockets. If this argument is NULL, the
+ * endpoint will create an internal ioqueue instance.
+ * @param worker_cnt Specify the number of worker threads to be created
+ * to poll the ioqueue.
+ * @param p_endpt Pointer to receive the endpoint instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create( pj_pool_factory *pf,
+ pj_ioqueue_t *ioqueue,
+ unsigned worker_cnt,
+ pjmedia_endpt **p_endpt);
+
+/**
+ * Destroy media endpoint instance.
+ *
+ * @param endpt Media endpoint instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_destroy(pjmedia_endpt *endpt);
+
+
+
+/**
+ * Get the ioqueue instance of the media endpoint.
+ *
+ * @param endpt The media endpoint instance.
+ *
+ * @return The ioqueue instance of the media endpoint.
+ */
+PJ_DECL(pj_ioqueue_t*) pjmedia_endpt_get_ioqueue(pjmedia_endpt *endpt);
+
+
+/**
+ * Get the number of worker threads on the media endpoint
+ *
+ * @param endpt The media endpoint instance.
+ * @return The number of worker threads on the media endpoint
+ */
+PJ_DECL(unsigned) pjmedia_endpt_get_thread_count(pjmedia_endpt *endpt);
+
+/**
+ * Get a reference to one of the worker threads of the media endpoint
+ *
+ * @param endpt The media endpoint instance.
+ * @param index The index of the thread: 0<= index < thread_cnt
+ *
+ * @return pj_thread_t or NULL
+ */
+PJ_DECL(pj_thread_t*) pjmedia_endpt_get_thread(pjmedia_endpt *endpt,
+ unsigned index);
+
+
+/**
+ * Request the media endpoint to create pool.
+ *
+ * @param endpt The media endpoint instance.
+ * @param name Name to be assigned to the pool.
+ * @param initial Initial pool size, in bytes.
+ * @param increment Increment size, in bytes.
+ *
+ * @return Memory pool.
+ */
+PJ_DECL(pj_pool_t*) pjmedia_endpt_create_pool( pjmedia_endpt *endpt,
+ const char *name,
+ pj_size_t initial,
+ pj_size_t increment);
+
+/**
+ * Get the codec manager instance of the media endpoint.
+ *
+ * @param endpt The media endpoint instance.
+ *
+ * @return The instance of codec manager belonging to
+ * this media endpoint.
+ */
+PJ_DECL(pjmedia_codec_mgr*) pjmedia_endpt_get_codec_mgr(pjmedia_endpt *endpt);
+
+
+/**
+ * Create a SDP session description that describes the endpoint
+ * capability.
+ *
+ * @param endpt The media endpoint.
+ * @param pool Pool to use to create the SDP descriptor.
+ * @param stream_cnt Number of elements in the sock_info array. This
+ * also denotes the maximum number of streams (i.e.
+ * the "m=" lines) that will be created in the SDP.
+ * @param sock_info Array of socket transport information. One
+ * transport is needed for each media stream, and
+ * each transport consists of an RTP and RTCP socket
+ * pair.
+ * @param p_sdp Pointer to receive SDP session descriptor.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ unsigned stream_cnt,
+ const pjmedia_sock_info sock_info[],
+ pjmedia_sdp_session **p_sdp );
+
+
+/**
+ * Dump media endpoint capabilities.
+ *
+ * @param endpt The media endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_dump(pjmedia_endpt *endpt);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __PJMEDIA_MEDIAMGR_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/errno.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/errno.h
new file mode 100644
index 0000000..9dcecbf
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/errno.h
@@ -0,0 +1,631 @@
+/* $Id: errno.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_ERRNO_H__
+#define __PJMEDIA_ERRNO_H__
+
+/**
+ * @file errno.h Error Codes
+ * @brief PJMEDIA specific error codes.
+ */
+
+#include <pjmedia/types.h>
+#include <pj/errno.h>
+
+/**
+ * @defgroup PJMEDIA_ERRNO Error Codes
+ * @ingroup PJMEDIA_BASE
+ * @brief PJMEDIA specific error codes.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ */
+#define PJMEDIA_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE)
+#define PJMEDIA_ERRNO_END (PJMEDIA_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1)
+
+
+/**
+ * Mapping from PortAudio error codes to pjmedia error space.
+ */
+#define PJMEDIA_PORTAUDIO_ERRNO_START (PJMEDIA_ERRNO_END-10000)
+#define PJMEDIA_PORTAUDIO_ERRNO_END (PJMEDIA_PORTAUDIO_ERRNO_START + 10000 -1)
+/**
+ * Convert PortAudio error code to PJMEDIA error code.
+ * PortAudio error code range: 0 >= err >= -10000
+ */
+#define PJMEDIA_ERRNO_FROM_PORTAUDIO(err) ((int)PJMEDIA_PORTAUDIO_ERRNO_START-err)
+
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+
+ /**
+ * Mapping from LibSRTP error codes to pjmedia error space.
+ */
+#define PJMEDIA_LIBSRTP_ERRNO_START (PJMEDIA_ERRNO_END-10200)
+#define PJMEDIA_LIBSRTP_ERRNO_END (PJMEDIA_LIBSRTP_ERRNO_START + 200 - 1)
+/**
+ * Convert LibSRTP error code to PJMEDIA error code.
+ * LibSRTP error code range: 0 <= err < 200
+ */
+#define PJMEDIA_ERRNO_FROM_LIBSRTP(err) (PJMEDIA_LIBSRTP_ERRNO_START+err)
+
+#endif
+
+/************************************************************
+ * GENERIC/GENERAL PJMEDIA ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General/unknown PJMEDIA error.
+ */
+#define PJMEDIA_ERROR (PJMEDIA_ERRNO_START+1) /* 220001 */
+
+
+/************************************************************
+ * SDP ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Generic invalid SDP descriptor.
+ */
+#define PJMEDIA_SDP_EINSDP (PJMEDIA_ERRNO_START+20) /* 220020 */
+/**
+ * @hideinitializer
+ * Invalid SDP version.
+ */
+#define PJMEDIA_SDP_EINVER (PJMEDIA_ERRNO_START+21) /* 220021 */
+/**
+ * @hideinitializer
+ * Invalid SDP origin (o=) line.
+ */
+#define PJMEDIA_SDP_EINORIGIN (PJMEDIA_ERRNO_START+22) /* 220022 */
+/**
+ * @hideinitializer
+ * Invalid SDP time (t=) line.
+ */
+#define PJMEDIA_SDP_EINTIME (PJMEDIA_ERRNO_START+23) /* 220023 */
+/**
+ * @hideinitializer
+ * Empty SDP subject/name (s=) line.
+ */
+#define PJMEDIA_SDP_EINNAME (PJMEDIA_ERRNO_START+24) /* 220024 */
+/**
+ * @hideinitializer
+ * Invalid SDP connection info (c=) line.
+ */
+#define PJMEDIA_SDP_EINCONN (PJMEDIA_ERRNO_START+25) /* 220025 */
+/**
+ * @hideinitializer
+ * Missing SDP connection info line.
+ */
+#define PJMEDIA_SDP_EMISSINGCONN (PJMEDIA_ERRNO_START+26) /* 220026 */
+/**
+ * @hideinitializer
+ * Invalid attribute (a=) line.
+ */
+#define PJMEDIA_SDP_EINATTR (PJMEDIA_ERRNO_START+27) /* 220027 */
+/**
+ * @hideinitializer
+ * Invalid rtpmap attribute.
+ */
+#define PJMEDIA_SDP_EINRTPMAP (PJMEDIA_ERRNO_START+28) /* 220028 */
+/**
+ * @hideinitializer
+ * rtpmap attribute is too long.
+ */
+#define PJMEDIA_SDP_ERTPMAPTOOLONG (PJMEDIA_ERRNO_START+29) /* 220029 */
+/**
+ * @hideinitializer
+ * rtpmap is missing for dynamic payload type.
+ */
+#define PJMEDIA_SDP_EMISSINGRTPMAP (PJMEDIA_ERRNO_START+30) /* 220030 */
+/**
+ * @hideinitializer
+ * Invalid SDP media (m=) line.
+ */
+#define PJMEDIA_SDP_EINMEDIA (PJMEDIA_ERRNO_START+31) /* 220031 */
+/**
+ * @hideinitializer
+ * No payload format in the media stream.
+ */
+#define PJMEDIA_SDP_ENOFMT (PJMEDIA_ERRNO_START+32) /* 220032 */
+/**
+ * @hideinitializer
+ * Invalid payload type in media.
+ */
+#define PJMEDIA_SDP_EINPT (PJMEDIA_ERRNO_START+33) /* 220033 */
+/**
+ * @hideinitializer
+ * Invalid SDP "fmtp" attribute.
+ */
+#define PJMEDIA_SDP_EINFMTP (PJMEDIA_ERRNO_START+34) /* 220034 */
+/**
+ * @hideinitializer
+ * Invalid SDP "rtcp" attribute.
+ */
+#define PJMEDIA_SDP_EINRTCP (PJMEDIA_ERRNO_START+35) /* 220035 */
+/**
+ * @hideinitializer
+ * Invalid SDP media transport protocol.
+ */
+#define PJMEDIA_SDP_EINPROTO (PJMEDIA_ERRNO_START+36) /* 220036 */
+
+
+/************************************************************
+ * SDP NEGOTIATOR ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Invalid state to perform the specified operation.
+ */
+#define PJMEDIA_SDPNEG_EINSTATE (PJMEDIA_ERRNO_START+40) /* 220040 */
+/**
+ * @hideinitializer
+ * No initial local SDP.
+ */
+#define PJMEDIA_SDPNEG_ENOINITIAL (PJMEDIA_ERRNO_START+41) /* 220041 */
+/**
+ * @hideinitializer
+ * No currently active SDP.
+ */
+#define PJMEDIA_SDPNEG_ENOACTIVE (PJMEDIA_ERRNO_START+42) /* 220042 */
+/**
+ * @hideinitializer
+ * No current offer or answer.
+ */
+#define PJMEDIA_SDPNEG_ENONEG (PJMEDIA_ERRNO_START+43) /* 220043 */
+/**
+ * @hideinitializer
+ * Media count mismatch in offer and answer.
+ */
+#define PJMEDIA_SDPNEG_EMISMEDIA (PJMEDIA_ERRNO_START+44) /* 220044 */
+/**
+ * @hideinitializer
+ * Media type is different in the remote answer.
+ */
+#define PJMEDIA_SDPNEG_EINVANSMEDIA (PJMEDIA_ERRNO_START+45) /* 220045 */
+/**
+ * @hideinitializer
+ * Transport type is different in the remote answer.
+ */
+#define PJMEDIA_SDPNEG_EINVANSTP (PJMEDIA_ERRNO_START+46) /* 220046 */
+/**
+ * @hideinitializer
+ * No common media payload is provided in the answer.
+ */
+#define PJMEDIA_SDPNEG_EANSNOMEDIA (PJMEDIA_ERRNO_START+47) /* 220047 */
+/**
+ * @hideinitializer
+ * No media is active after negotiation.
+ */
+#define PJMEDIA_SDPNEG_ENOMEDIA (PJMEDIA_ERRNO_START+48) /* 220048 */
+/**
+ * @hideinitializer
+ * No suitable codec for remote offer.
+ */
+#define PJMEDIA_SDPNEG_NOANSCODEC (PJMEDIA_ERRNO_START+49) /* 220049 */
+/**
+ * @hideinitializer
+ * No suitable telephone-event for remote offer.
+ */
+#define PJMEDIA_SDPNEG_NOANSTELEVENT (PJMEDIA_ERRNO_START+50) /* 220050 */
+/**
+ * @hideinitializer
+ * No suitable answer for unknown remote offer.
+ */
+#define PJMEDIA_SDPNEG_NOANSUNKNOWN (PJMEDIA_ERRNO_START+51) /* 220051 */
+
+
+/************************************************************
+ * SDP COMPARISON STATUS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * SDP media stream not equal.
+ */
+#define PJMEDIA_SDP_EMEDIANOTEQUAL (PJMEDIA_ERRNO_START+60) /* 220060 */
+/**
+ * @hideinitializer
+ * Port number in SDP media descriptor not equal.
+ */
+#define PJMEDIA_SDP_EPORTNOTEQUAL (PJMEDIA_ERRNO_START+61) /* 220061 */
+/**
+ * @hideinitializer
+ * Transport in SDP media descriptor not equal.
+ */
+#define PJMEDIA_SDP_ETPORTNOTEQUAL (PJMEDIA_ERRNO_START+62) /* 220062 */
+/**
+ * @hideinitializer
+ * Media format in SDP media descriptor not equal.
+ */
+#define PJMEDIA_SDP_EFORMATNOTEQUAL (PJMEDIA_ERRNO_START+63) /* 220063 */
+/**
+ * @hideinitializer
+ * SDP connection description not equal.
+ */
+#define PJMEDIA_SDP_ECONNNOTEQUAL (PJMEDIA_ERRNO_START+64) /* 220064 */
+/**
+ * @hideinitializer
+ * SDP attributes not equal.
+ */
+#define PJMEDIA_SDP_EATTRNOTEQUAL (PJMEDIA_ERRNO_START+65) /* 220065 */
+/**
+ * @hideinitializer
+ * SDP media direction not equal.
+ */
+#define PJMEDIA_SDP_EDIRNOTEQUAL (PJMEDIA_ERRNO_START+66) /* 220066 */
+/**
+ * @hideinitializer
+ * SDP fmtp attribute not equal.
+ */
+#define PJMEDIA_SDP_EFMTPNOTEQUAL (PJMEDIA_ERRNO_START+67) /* 220067 */
+/**
+ * @hideinitializer
+ * SDP ftpmap attribute not equal.
+ */
+#define PJMEDIA_SDP_ERTPMAPNOTEQUAL (PJMEDIA_ERRNO_START+68) /* 220068 */
+/**
+ * @hideinitializer
+ * SDP session descriptor not equal.
+ */
+#define PJMEDIA_SDP_ESESSNOTEQUAL (PJMEDIA_ERRNO_START+69) /* 220069 */
+/**
+ * @hideinitializer
+ * SDP origin not equal.
+ */
+#define PJMEDIA_SDP_EORIGINNOTEQUAL (PJMEDIA_ERRNO_START+70) /* 220070 */
+/**
+ * @hideinitializer
+ * SDP name/subject not equal.
+ */
+#define PJMEDIA_SDP_ENAMENOTEQUAL (PJMEDIA_ERRNO_START+71) /* 220071 */
+/**
+ * @hideinitializer
+ * SDP time not equal.
+ */
+#define PJMEDIA_SDP_ETIMENOTEQUAL (PJMEDIA_ERRNO_START+72) /* 220072 */
+
+
+/************************************************************
+ * CODEC
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Unsupported codec.
+ */
+#define PJMEDIA_CODEC_EUNSUP (PJMEDIA_ERRNO_START+80) /* 220080 */
+/**
+ * @hideinitializer
+ * Codec internal creation error.
+ */
+#define PJMEDIA_CODEC_EFAILED (PJMEDIA_ERRNO_START+81) /* 220081 */
+/**
+ * @hideinitializer
+ * Codec frame is too short.
+ */
+#define PJMEDIA_CODEC_EFRMTOOSHORT (PJMEDIA_ERRNO_START+82) /* 220082 */
+/**
+ * @hideinitializer
+ * PCM buffer is too short.
+ */
+#define PJMEDIA_CODEC_EPCMTOOSHORT (PJMEDIA_ERRNO_START+83) /* 220083 */
+/**
+ * @hideinitializer
+ * Invalid codec frame length.
+ */
+#define PJMEDIA_CODEC_EFRMINLEN (PJMEDIA_ERRNO_START+84) /* 220084 */
+/**
+ * @hideinitializer
+ * Invalid PCM frame length.
+ */
+#define PJMEDIA_CODEC_EPCMFRMINLEN (PJMEDIA_ERRNO_START+85) /* 220085 */
+/**
+ * @hideinitializer
+ * Invalid mode.
+ */
+#define PJMEDIA_CODEC_EINMODE (PJMEDIA_ERRNO_START+86) /* 220086 */
+
+
+/************************************************************
+ * MEDIA
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Invalid remote IP address (in SDP).
+ */
+#define PJMEDIA_EINVALIDIP (PJMEDIA_ERRNO_START+100) /* 220100 */
+/**
+ * @hideinitializer
+ * Asymetric codec is not supported.
+ */
+#define PJMEDIA_EASYMCODEC (PJMEDIA_ERRNO_START+101) /* 220101 */
+/**
+ * @hideinitializer
+ * Invalid payload type.
+ */
+#define PJMEDIA_EINVALIDPT (PJMEDIA_ERRNO_START+102) /* 220102 */
+/**
+ * @hideinitializer
+ * Missing rtpmap.
+ */
+#define PJMEDIA_EMISSINGRTPMAP (PJMEDIA_ERRNO_START+103) /* 220103 */
+/**
+ * @hideinitializer
+ * Invalid media type.
+ */
+#define PJMEDIA_EINVALIMEDIATYPE (PJMEDIA_ERRNO_START+104) /* 220104 */
+/**
+ * @hideinitializer
+ * Remote does not support DTMF.
+ */
+#define PJMEDIA_EREMOTENODTMF (PJMEDIA_ERRNO_START+105) /* 220105 */
+/**
+ * @hideinitializer
+ * Invalid DTMF digit.
+ */
+#define PJMEDIA_RTP_EINDTMF (PJMEDIA_ERRNO_START+106) /* 220106 */
+/**
+ * @hideinitializer
+ * Remote does not support RFC 2833
+ */
+#define PJMEDIA_RTP_EREMNORFC2833 (PJMEDIA_ERRNO_START+107) /* 220107 */
+
+
+
+/************************************************************
+ * RTP SESSION ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General invalid RTP packet error.
+ */
+#define PJMEDIA_RTP_EINPKT (PJMEDIA_ERRNO_START+120) /* 220120 */
+/**
+ * @hideinitializer
+ * Invalid RTP packet packing.
+ */
+#define PJMEDIA_RTP_EINPACK (PJMEDIA_ERRNO_START+121) /* 220121 */
+/**
+ * @hideinitializer
+ * Invalid RTP packet version.
+ */
+#define PJMEDIA_RTP_EINVER (PJMEDIA_ERRNO_START+122) /* 220122 */
+/**
+ * @hideinitializer
+ * RTP SSRC id mismatch.
+ */
+#define PJMEDIA_RTP_EINSSRC (PJMEDIA_ERRNO_START+123) /* 220123 */
+/**
+ * @hideinitializer
+ * RTP payload type mismatch.
+ */
+#define PJMEDIA_RTP_EINPT (PJMEDIA_ERRNO_START+124) /* 220124 */
+/**
+ * @hideinitializer
+ * Invalid RTP packet length.
+ */
+#define PJMEDIA_RTP_EINLEN (PJMEDIA_ERRNO_START+125) /* 220125 */
+/**
+ * @hideinitializer
+ * RTP session restarted.
+ */
+#define PJMEDIA_RTP_ESESSRESTART (PJMEDIA_ERRNO_START+130) /* 220130 */
+/**
+ * @hideinitializer
+ * RTP session in probation
+ */
+#define PJMEDIA_RTP_ESESSPROBATION (PJMEDIA_ERRNO_START+131) /* 220131 */
+/**
+ * @hideinitializer
+ * Bad RTP sequence number
+ */
+#define PJMEDIA_RTP_EBADSEQ (PJMEDIA_ERRNO_START+132) /* 220132 */
+/**
+ * @hideinitializer
+ * RTP media port destination is not configured
+ */
+#define PJMEDIA_RTP_EBADDEST (PJMEDIA_ERRNO_START+133) /* 220133 */
+/**
+ * @hideinitializer
+ * RTP is not configured.
+ */
+#define PJMEDIA_RTP_ENOCONFIG (PJMEDIA_ERRNO_START+134) /* 220134 */
+
+
+/************************************************************
+ * PORT ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Generic incompatible port error.
+ */
+#define PJMEDIA_ENOTCOMPATIBLE (PJMEDIA_ERRNO_START+160) /* 220160 */
+/**
+ * @hideinitializer
+ * Incompatible clock rate
+ */
+#define PJMEDIA_ENCCLOCKRATE (PJMEDIA_ERRNO_START+161) /* 220161 */
+/**
+ * @hideinitializer
+ * Incompatible samples per frame
+ */
+#define PJMEDIA_ENCSAMPLESPFRAME (PJMEDIA_ERRNO_START+162) /* 220162 */
+/**
+ * @hideinitializer
+ * Incompatible media type
+ */
+#define PJMEDIA_ENCTYPE (PJMEDIA_ERRNO_START+163) /* 220163 */
+/**
+ * @hideinitializer
+ * Incompatible bits per sample
+ */
+#define PJMEDIA_ENCBITS (PJMEDIA_ERRNO_START+164) /* 220164 */
+/**
+ * @hideinitializer
+ * Incompatible bytes per frame
+ */
+#define PJMEDIA_ENCBYTES (PJMEDIA_ERRNO_START+165) /* 220165 */
+/**
+ * @hideinitializer
+ * Incompatible number of channels
+ */
+#define PJMEDIA_ENCCHANNEL (PJMEDIA_ERRNO_START+166) /* 220166 */
+
+
+/************************************************************
+ * FILE ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Not a valid WAVE file.
+ */
+#define PJMEDIA_ENOTVALIDWAVE (PJMEDIA_ERRNO_START+180) /* 220180 */
+/**
+ * @hideinitializer
+ * Unsupported WAVE file.
+ */
+#define PJMEDIA_EWAVEUNSUPP (PJMEDIA_ERRNO_START+181) /* 220181 */
+/**
+ * @hideinitializer
+ * Wave file too short.
+ */
+#define PJMEDIA_EWAVETOOSHORT (PJMEDIA_ERRNO_START+182) /* 220182 */
+/**
+ * @hideinitializer
+ * Sound frame is too large for file buffer.
+ */
+#define PJMEDIA_EFRMFILETOOBIG (PJMEDIA_ERRNO_START+183) /* 220183 */
+
+
+/************************************************************
+ * SOUND DEVICE ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * No suitable audio capture device.
+ */
+#define PJMEDIA_ENOSNDREC (PJMEDIA_ERRNO_START+200) /* 220200 */
+/**
+ * @hideinitializer
+ * No suitable audio playback device.
+ */
+#define PJMEDIA_ENOSNDPLAY (PJMEDIA_ERRNO_START+201) /* 220201 */
+/**
+ * @hideinitializer
+ * Invalid sound device ID.
+ */
+#define PJMEDIA_ESNDINDEVID (PJMEDIA_ERRNO_START+202) /* 220202 */
+/**
+ * @hideinitializer
+ * Invalid sample format for sound device.
+ */
+#define PJMEDIA_ESNDINSAMPLEFMT (PJMEDIA_ERRNO_START+203) /* 220203 */
+
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+/************************************************************
+ * SRTP TRANSPORT ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * SRTP crypto-suite name not match the offerer tag.
+ */
+#define PJMEDIA_SRTP_ECRYPTONOTMATCH (PJMEDIA_ERRNO_START+220) /* 220220 */
+/**
+ * @hideinitializer
+ * Invalid SRTP key length for specific crypto.
+ */
+#define PJMEDIA_SRTP_EINKEYLEN (PJMEDIA_ERRNO_START+221) /* 220221 */
+/**
+ * @hideinitializer
+ * Unsupported SRTP crypto-suite.
+ */
+#define PJMEDIA_SRTP_ENOTSUPCRYPTO (PJMEDIA_ERRNO_START+222) /* 220222 */
+/**
+ * @hideinitializer
+ * SRTP SDP contains ambigue answer.
+ */
+#define PJMEDIA_SRTP_ESDPAMBIGUEANS (PJMEDIA_ERRNO_START+223) /* 220223 */
+/**
+ * @hideinitializer
+ * Duplicated crypto tag.
+ */
+#define PJMEDIA_SRTP_ESDPDUPCRYPTOTAG (PJMEDIA_ERRNO_START+224) /* 220224 */
+/**
+ * @hideinitializer
+ * Invalid crypto attribute.
+ */
+#define PJMEDIA_SRTP_ESDPINCRYPTO (PJMEDIA_ERRNO_START+225) /* 220225 */
+/**
+ * @hideinitializer
+ * Invalid crypto tag.
+ */
+#define PJMEDIA_SRTP_ESDPINCRYPTOTAG (PJMEDIA_ERRNO_START+226) /* 220226 */
+/**
+ * @hideinitializer
+ * Invalid SDP media transport for SRTP.
+ */
+#define PJMEDIA_SRTP_ESDPINTRANSPORT (PJMEDIA_ERRNO_START+227) /* 220227 */
+/**
+ * @hideinitializer
+ * SRTP crypto attribute required in SDP.
+ */
+#define PJMEDIA_SRTP_ESDPREQCRYPTO (PJMEDIA_ERRNO_START+228) /* 220228 */
+/**
+ * @hideinitializer
+ * Secure transport required in SDP media descriptor.
+ */
+#define PJMEDIA_SRTP_ESDPREQSECTP (PJMEDIA_ERRNO_START+229) /* 220229 */
+
+#endif /* PJMEDIA_HAS_SRTP */
+
+
+/**
+ * Get error message for the specified error code. Note that this
+ * function is only able to decode PJMEDIA specific error code.
+ * Application should use pj_strerror(), which should be able to
+ * decode all error codes belonging to all subsystems (e.g. pjlib,
+ * pjmedia, pjsip, etc).
+ *
+ * @param status The error code.
+ * @param buffer The buffer where to put the error message.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pjmedia_strerror( pj_status_t status, char *buffer,
+ pj_size_t bufsize);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_ERRNO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/g711.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/g711.h
new file mode 100644
index 0000000..8f79604
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/g711.h
@@ -0,0 +1,70 @@
+/* $Id: g711.h 2875 2009-08-13 15:57:26Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_G711_H__
+#define __PJMEDIA_G711_H__
+
+/**
+ * @file g711.h
+ * @brief G711 Codec
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_G711 G711 G.711 Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Standard G.711/PCMA and PCMU codec.
+ * @{
+ * This section describes functions to register and register G.711 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register G711 codec factory to pjmedia endpoint.
+ * This will register PCMU and PCMA codec, in that order.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g711_init(pjmedia_endpt *endpt);
+
+
+
+/**
+ * Unregister G711 codec factory from pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g711_deinit(void);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_G711_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/jbuf.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/jbuf.h
new file mode 100644
index 0000000..e80ea02
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/jbuf.h
@@ -0,0 +1,314 @@
+/* $Id: jbuf.h 2844 2009-07-29 12:14:21Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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
+ */
+/*
+ * Based on implementation kindly contributed by Switchlab, Ltd.
+ */
+#ifndef __PJMEDIA_JBUF_H__
+#define __PJMEDIA_JBUF_H__
+
+
+/**
+ * @file jbuf.h
+ * @brief Adaptive jitter buffer implementation.
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMED_JBUF Adaptive jitter buffer
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Adaptive de-jitter buffering implementation
+ * @{
+ *
+ * This section describes PJMEDIA's implementation of de-jitter buffer.
+ * The de-jitter buffer may be set to operate in adaptive mode or fixed
+ * delay mode.
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Types of frame returned by the jitter buffer.
+ */
+enum pjmedia_jb_frame_type
+{
+ PJMEDIA_JB_MISSING_FRAME = 0, /**< No frame because it's missing */
+ PJMEDIA_JB_NORMAL_FRAME = 1, /**< Normal frame is being returned */
+ PJMEDIA_JB_ZERO_PREFETCH_FRAME = 2, /**< Zero frame is being returned
+ because JB is bufferring. */
+ PJMEDIA_JB_ZERO_EMPTY_FRAME = 3 /**< Zero frame is being returned
+ because JB is empty. */
+};
+
+
+/**
+ * @see pjmedia_jb_frame_type.
+ */
+typedef enum pjmedia_jb_frame_type pjmedia_jb_frame_type;
+
+
+/**
+ * This structure describes jitter buffer state.
+ */
+struct pjmedia_jb_state
+{
+ /* Setting */
+ unsigned frame_size; /**< Individual frame size, in bytes. */
+ unsigned min_prefetch; /**< Minimum allowed prefetch, in frms. */
+ unsigned max_prefetch; /**< Maximum allowed prefetch, in frms. */
+
+ /* Status */
+ unsigned prefetch; /**< Current prefetch value, in frames */
+ unsigned size; /**< Current buffer size, in frames. */
+
+ /* Statistic */
+ unsigned avg_delay; /**< Average delay, in ms. */
+ unsigned min_delay; /**< Minimum delay, in ms. */
+ unsigned max_delay; /**< Maximum delay, in ms. */
+ unsigned dev_delay; /**< Standard deviation of delay, in ms.*/
+ unsigned avg_burst; /**< Average burst, in frames. */
+ unsigned lost; /**< Number of lost frames. */
+ unsigned discard; /**< Number of discarded frames. */
+ unsigned empty; /**< Number of empty on GET events. */
+};
+
+
+/**
+ * @see pjmedia_jb_state
+ */
+typedef struct pjmedia_jb_state pjmedia_jb_state;
+
+
+/**
+ * The constant PJMEDIA_JB_DEFAULT_INIT_DELAY specifies default jitter
+ * buffer prefetch count during jitter buffer creation.
+ */
+#define PJMEDIA_JB_DEFAULT_INIT_DELAY 15
+
+/**
+ * Opaque declaration for jitter buffer.
+ */
+typedef struct pjmedia_jbuf pjmedia_jbuf;
+
+
+/**
+ * Create an adaptive jitter buffer according to the specification. If
+ * application wants to have a fixed jitter buffer, it may call
+ * #pjmedia_jbuf_set_fixed() after the jitter buffer is created.
+ *
+ * This function may allocate large chunk of memory to keep the frames in
+ * the buffer.
+ *
+ * @param pool The pool to allocate memory.
+ * @param name Name to identify the jitter buffer for logging
+ * purpose.
+ * @param frame_size The size of each frame that will be kept in the
+ * jitter buffer, in bytes. This should correspond
+ * to the minimum frame size supported by the codec.
+ * For example, a 10ms frame (80 bytes) would be
+ * recommended for G.711 codec.
+ * @param max_count Maximum number of frames that can be kept in the
+ * jitter buffer. This effectively means the maximum
+ * delay that may be introduced by this jitter
+ * buffer.
+ * @param ptime Indication of frame duration, used to calculate
+ * the interval between jitter recalculation.
+ * @param p_jb Pointer to receive jitter buffer instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool,
+ const pj_str_t *name,
+ unsigned frame_size,
+ unsigned ptime,
+ unsigned max_count,
+ pjmedia_jbuf **p_jb);
+
+/**
+ * Set the jitter buffer to fixed delay mode. The default behavior
+ * is to adapt the delay with actual packet delay.
+ *
+ * @param jb The jitter buffer
+ * @param prefetch The fixed delay value, in number of frames.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_set_fixed( pjmedia_jbuf *jb,
+ unsigned prefetch);
+
+
+/**
+ * Set the jitter buffer to adaptive mode.
+ *
+ * @param jb The jitter buffer.
+ * @param prefetch The initial prefetch value to be applied to the
+ * jitter buffer. Setting this to other than 0 will
+ * activate prefetch buffering, a jitter buffer feature
+ * that each time it gets empty, it won't return a
+ * normal frame until its size reaches the number
+ * specified here.
+ * @param min_prefetch The minimum delay that must be applied to each
+ * incoming packets, in number of frames.
+ * @param max_prefetch The maximum allowable value for prefetch delay,
+ * in number of frames.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_set_adaptive( pjmedia_jbuf *jb,
+ unsigned prefetch,
+ unsigned min_prefetch,
+ unsigned max_prefetch);
+
+
+/**
+ * Destroy jitter buffer instance.
+ *
+ * @param jb The jitter buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb);
+
+
+/**
+ * Restart jitter. This function flushes all packets in the buffer and
+ * reset the internal sequence number.
+ *
+ * @param jb The jitter buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb);
+
+/**
+ * Put a frame to the jitter buffer. If the frame can be accepted (based
+ * on the sequence number), the jitter buffer will copy the frame and put
+ * it in the appropriate position in the buffer.
+ *
+ * Application MUST manage it's own synchronization when multiple threads
+ * are accessing the jitter buffer at the same time.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Pointer to frame buffer to be stored in the jitter
+ * buffer.
+ * @param size The frame size.
+ * @param frame_seq The frame sequence number.
+ */
+PJ_DECL(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb,
+ const void *frame,
+ pj_size_t size,
+ int frame_seq);
+
+/**
+ * Put a frame to the jitter buffer. If the frame can be accepted (based
+ * on the sequence number), the jitter buffer will copy the frame and put
+ * it in the appropriate position in the buffer.
+ *
+ * Application MUST manage it's own synchronization when multiple threads
+ * are accessing the jitter buffer at the same time.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Pointer to frame buffer to be stored in the jitter
+ * buffer.
+ * @param size The frame size.
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ * @param frame_seq The frame sequence number.
+ * @param discarded Flag whether the frame is discarded by jitter buffer.
+ */
+PJ_DECL(void) pjmedia_jbuf_put_frame2( pjmedia_jbuf *jb,
+ const void *frame,
+ pj_size_t size,
+ pj_uint32_t bit_info,
+ int frame_seq,
+ pj_bool_t *discarded);
+
+/**
+ * Get a frame from the jitter buffer. The jitter buffer will return the
+ * oldest frame from it's buffer, when it is available.
+ *
+ * Application MUST manage it's own synchronization when multiple threads
+ * are accessing the jitter buffer at the same time.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Buffer to receive the payload from the jitter buffer.
+ * Application MUST make sure that the buffer has
+ * appropriate size (i.e. not less than the frame size,
+ * as specified when the jitter buffer was created).
+ * The jitter buffer only copied a frame to this
+ * buffer when the frame type returned by this function
+ * is PJMEDIA_JB_NORMAL_FRAME.
+ * @param p_frm_type Pointer to receive frame type. If jitter buffer is
+ * currently empty or bufferring, the frame type will
+ * be set to PJMEDIA_JB_ZERO_FRAME, and no frame will
+ * be copied. If the jitter buffer detects that frame is
+ * missing with current sequence number, the frame type
+ * will be set to PJMEDIA_JB_MISSING_FRAME, and no
+ * frame will be copied. If there is a frame, the jitter
+ * buffer will copy the frame to the buffer, and frame
+ * type will be set to PJMEDIA_JB_NORMAL_FRAME.
+ */
+PJ_DECL(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,
+ void *frame,
+ char *p_frm_type);
+
+/**
+ * Get a frame from the jitter buffer. The jitter buffer will return the
+ * oldest frame from it's buffer, when it is available.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Buffer to receive the payload from the jitter buffer.
+ * @see pjmedia_jbuf_get_frame().
+ * @param size Pointer to receive frame size.
+ * @param p_frm_type Pointer to receive frame type.
+ * @see pjmedia_jbuf_get_frame().
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ */
+PJ_DECL(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
+ void *frame,
+ pj_size_t *size,
+ char *p_frm_type,
+ pj_uint32_t *bit_info);
+
+
+/**
+ * Get jitter buffer current state/settings.
+ *
+ * @param jb The jitter buffer.
+ * @param state Buffer to receive jitter buffer state.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,
+ pjmedia_jb_state *state );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_JBUF_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/master_port.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/master_port.h
new file mode 100644
index 0000000..0e10547
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/master_port.h
@@ -0,0 +1,179 @@
+/* $Id: master_port.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_MASTER_PORT_H__
+#define __PJMEDIA_MASTER_PORT_H__
+
+
+/**
+ * @file master_port.h
+ * @brief Master port.
+ */
+#include <pjmedia/port.h>
+
+/**
+ * @defgroup PJMEDIA_MASTER_PORT Master Port
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Thread based media clock provider
+ * @{
+ *
+ * A master port has two media ports connected to it, and by convention
+ * thay are called downstream and upstream ports. The media stream flowing to
+ * the downstream port is called encoding or send direction, and media stream
+ * flowing to the upstream port is called decoding or receive direction
+ * (imagine the downstream as stream to remote endpoint, and upstream as
+ * local media port; media flowing to remote endpoint (downstream) will need
+ * to be encoded before it is transmitted to remote endpoint).
+ *
+ * A master port internally has an instance of @ref PJMEDIA_CLOCK, which
+ * provides the essensial timing for the master port. The @ref PJMEDIA_CLOCK
+ * runs asynchronously, and whenever a clock <b>tick</b> expires, a callback
+ * will be called, and the master port performs the following tasks:
+ * - it calls <b><tt>get_frame()</tt></b> from the downstream port,
+ * when give the frame to the upstream port by calling <b><tt>put_frame
+ * </tt></b> to the upstream port, and
+ * - performs the same task, but on the reverse direction (i.e. get the stream
+ * from upstream port and give it to the downstream port).
+ *
+ * Because master port enables media stream to flow automatically, it is
+ * said that the master port supplies @ref PJMEDIA_PORT_CLOCK to the
+ * media ports interconnection.
+ *
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for master port.
+ */
+typedef struct pjmedia_master_port pjmedia_master_port;
+
+
+/**
+ * Create a master port.
+ *
+ * @param pool Pool to allocate master port from.
+ * @param u_port Upstream port.
+ * @param d_port Downstream port.
+ * @param options Options flags, from bitmask combinations from
+ * pjmedia_clock_options.
+ * @param p_m Pointer to receive the master port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_create(pj_pool_t *pool,
+ pjmedia_port *u_port,
+ pjmedia_port *d_port,
+ unsigned options,
+ pjmedia_master_port **p_m);
+
+
+/**
+ * Start the media flow.
+ *
+ * @param m The master port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_start(pjmedia_master_port *m);
+
+
+/**
+ * Stop the media flow.
+ *
+ * @param m The master port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_stop(pjmedia_master_port *m);
+
+
+/**
+ * Change the upstream port. Note that application is responsible to destroy
+ * current upstream port (the one that is going to be replaced with the
+ * new port).
+ *
+ * @param m The master port.
+ * @param port Port to be used for upstream port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_set_uport(pjmedia_master_port *m,
+ pjmedia_port *port);
+
+
+/**
+ * Get the upstream port.
+ *
+ * @param m The master port.
+ *
+ * @return The upstream port.
+ */
+PJ_DECL(pjmedia_port*) pjmedia_master_port_get_uport(pjmedia_master_port*m);
+
+
+/**
+ * Change the downstream port. Note that application is responsible to destroy
+ * current downstream port (the one that is going to be replaced with the
+ * new port).
+ *
+ * @param m The master port.
+ * @param port Port to be used for downstream port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_set_dport(pjmedia_master_port *m,
+ pjmedia_port *port);
+
+
+/**
+ * Get the downstream port.
+ *
+ * @param m The master port.
+ *
+ * @return The downstream port.
+ */
+PJ_DECL(pjmedia_port*) pjmedia_master_port_get_dport(pjmedia_master_port*m);
+
+
+/**
+ * Destroy the master port, and optionally destroy the upstream and
+ * downstream ports.
+ *
+ * @param m The master port.
+ * @param destroy_ports If non-zero, the function will destroy both
+ * upstream and downstream ports too.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_destroy(pjmedia_master_port *m,
+ pj_bool_t destroy_ports);
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_MASTER_PORT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/mem_port.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/mem_port.h
new file mode 100644
index 0000000..5de8523
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/mem_port.h
@@ -0,0 +1,195 @@
+/* $Id: mem_port.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_MEM_PORT_H__
+#define __PJMEDIA_MEM_PORT_H__
+
+/**
+ * @file mem_port.h
+ * @brief Memory based media playback/capture port
+ */
+#include <pjmedia/port.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_MEM_PLAYER Memory/Buffer-based Playback Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Media playback from a fixed size memory buffer
+ * @{
+ *
+ * A memory/buffer based playback port is used to play media from a fixed
+ * size buffer. This is useful over @ref PJMEDIA_FILE_PLAY for
+ * situation where filesystems are not available in the target system.
+ */
+
+
+/**
+ * Memory player options.
+ */
+enum pjmedia_mem_player_option
+{
+ /**
+ * Tell the memory player to return NULL frame when the whole
+ * buffer has been played instead of rewinding the buffer back
+ * to start position.
+ */
+ PJMEDIA_MEM_NO_LOOP = 1
+};
+
+
+/**
+ * Create the buffer based playback to play the media from the specified
+ * buffer.
+ *
+ * @param pool Pool to allocate memory for the port structure.
+ * @param buffer The buffer to play the media from, which should
+ * be available throughout the life time of the port.
+ * The player plays the media directly from this
+ * buffer (i.e. no copying is done).
+ * @param size The size of the buffer, in bytes.
+ * @param clock_rate Sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample.
+ * @param options Option flags, see #pjmedia_mem_player_option
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_mem_player_create(pj_pool_t *pool,
+ const void *buffer,
+ pj_size_t size,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_port );
+
+
+/**
+ * Register a callback to be called when the buffer reading has reached the
+ * end of buffer. If the player is set to play repeatedly, then the callback
+ * will be called multiple times. Note that only one callback can be
+ * registered for each player port.
+ *
+ * @param port The memory player port.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the playback will stop. Note that if
+ * application destroys the player port in the callback,
+ * it must return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_mem_player_set_eof_cb( pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJMEDIA_MEM_CAPTURE Memory/Buffer-based Capture Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Media capture to fixed size memory buffer
+ * @{
+ *
+ * A memory based capture is used to save media streams to a fixed size
+ * buffer. This is useful over @ref PJMEDIA_FILE_REC for
+ * situation where filesystems are not available in the target system.
+ */
+
+/**
+ * Create media port to capture/record media into a fixed size buffer.
+ *
+ * @param pool Pool to allocate memory for the port structure.
+ * @param buffer The buffer to record the media to, which should
+ * be available throughout the life time of the port.
+ * @param size The maximum size of the buffer, in bytes.
+ * @param clock_rate Sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample.
+ * @param options Option flags.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_mem_capture_create(pj_pool_t *pool,
+ void *buffer,
+ pj_size_t size,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_port);
+
+
+/**
+ * Register a callback to be called when no space left in the buffer.
+ * Note that when a callback is registered, this callback will also be
+ * called when application destroys the port and the callback has not
+ * been called before.
+ *
+ * @param port The memory recorder port.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the recording will stop. In other cases
+ * recording will be restarted and the rest of the frame
+ * will be stored starting from the beginning of the
+ * buffer. Note that if application destroys the capture
+ * port in the callback, it must return non-PJ_SUCCESS
+ * here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_mem_capture_set_eof_cb(pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+/**
+ * Return the current size of the recorded data in the buffer.
+ *
+ * @param port The memory recorder port.
+ * @return The size of buffer data..
+ */
+PJ_DECL(pj_size_t)
+pjmedia_mem_capture_get_size(pjmedia_port *port);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_MEM_PORT_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/null_port.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/null_port.h
new file mode 100644
index 0000000..e4e7659
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/null_port.h
@@ -0,0 +1,70 @@
+/* $Id: null_port.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_NULL_PORT_H__
+#define __PJMEDIA_NULL_PORT_H__
+
+/**
+ * @file null_port.h
+ * @brief Null media port.
+ */
+#include <pjmedia/port.h>
+
+
+
+/**
+ * @defgroup PJMEDIA_NULL_PORT Null Port
+ * @ingroup PJMEDIA_PORT
+ * @brief The simplest type of media port which does nothing.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create Null port.
+ *
+ * @param pool Pool to allocate memory.
+ * @param sampling_rate Sampling rate of the port.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_null_port_create( pj_pool_t *pool,
+ unsigned sampling_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pjmedia_port **p_port );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_NULL_PORT_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/plc.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/plc.h
new file mode 100644
index 0000000..5ab4a10
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/plc.h
@@ -0,0 +1,115 @@
+/* $Id: plc.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_PLC_H__
+#define __PJMEDIA_PLC_H__
+
+
+/**
+ * @file plc.h
+ * @brief Packet Lost Concealment (PLC) API.
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMED_PLC Packet Lost Concealment (PLC)
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Packet lost compensation algorithm
+ * @{
+ *
+ * This section describes PJMEDIA's implementation of Packet Lost
+ * Concealment algorithm. This algorithm is used to implement PLC for
+ * codecs that do not have built-in support for one (e.g. G.711 or GSM
+ * codecs).
+ *
+ * The PLC algorithm (either built-in or external) is embedded in
+ * PJMEDIA codec instance, and application can conceal lost frames
+ * by calling <b><tt>recover()</tt></b> member of the codec's member
+ * operation (#pjmedia_codec_op).
+ *
+ * See also @ref plc_codec for more info.
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for PLC.
+ */
+typedef struct pjmedia_plc pjmedia_plc;
+
+
+
+/**
+ * Create PLC session. This function will select the PLC algorithm to
+ * use based on the arguments.
+ *
+ * @param pool Pool to allocate memory for the PLC.
+ * @param clock_rate Media sampling rate.
+ * @param samples_per_frame Number of samples per frame.
+ * @param options Must be zero for now.
+ * @param p_plc Pointer to receive the PLC instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_plc_create( pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ unsigned options,
+ pjmedia_plc **p_plc);
+
+
+/**
+ * Save a good frame to PLC.
+ *
+ * @param plc The PLC session.
+ * @param frame The good frame to be stored to PLC. This frame
+ * must have the same length as the configured
+ * samples per frame.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_plc_save( pjmedia_plc *plc,
+ pj_int16_t *frame );
+
+
+/**
+ * Generate a replacement for lost frame.
+ *
+ * @param plc The PLC session.
+ * @param frame Buffer to receive the generated frame. This buffer
+ * must be able to store the frame.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_plc_generate( pjmedia_plc *plc,
+ pj_int16_t *frame );
+
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_PLC_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/port.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/port.h
new file mode 100644
index 0000000..20f5b55
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/port.h
@@ -0,0 +1,326 @@
+/* $Id: port.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_PORT_H__
+#define __PJMEDIA_PORT_H__
+
+/**
+ * @file port.h
+ * @brief Port interface declaration
+ */
+#include <pjmedia/types.h>
+#include <pj/assert.h>
+#include <pj/os.h>
+
+
+/**
+ @addtogroup PJMEDIA_PORT Media Ports Framework
+ @{
+
+ @section media_port_intro Media Port Concepts
+
+ @subsection The Media Port
+ A media port (represented with pjmedia_port "class") provides a generic
+ and extensible framework for implementing media terminations. A media
+ port interface basically has the following properties:
+ - media port information (pjmedia_port_info) to describe the
+ media port properties (sampling rate, number of channels, etc.),
+ - pointer to function to acquire frames from the port (<tt>get_frame()
+ </tt> interface), which will be called by #pjmedia_port_get_frame()
+ public API, and
+ - pointer to function to store frames to the port (<tt>put_frame()</tt>
+ interface) which will be called by #pjmedia_port_put_frame() public
+ API.
+
+ Media ports are passive "objects". Applications (or other PJMEDIA
+ components) must actively calls #pjmedia_port_get_frame() or
+ #pjmedia_port_put_frame() from/to the media port in order to retrieve/
+ store media frames.
+
+ Some media ports (such as @ref PJMEDIA_CONF and @ref PJMEDIA_RESAMPLE_PORT)
+ may be interconnected with each other, while some
+ others represent the ultimate source/sink termination for the media.
+
+
+ @subsection port_clock_ex1 Example: Manual Resampling
+
+ For example, suppose application wants to convert the sampling rate
+ of one WAV file to another. In this case, application would create and
+ arrange media ports connection as follows:
+
+ \image html sample-manual-resampling.jpg
+
+ Application would setup the media ports using the following pseudo-
+ code:
+
+ \code
+
+ pjmedia_port *player, *resample, *writer;
+ pj_status_t status;
+
+ // Create the file player port.
+ status = pjmedia_wav_player_port_create(pool,
+ "Input.WAV", // file name
+ 20, // ptime.
+ PJMEDIA_FILE_NO_LOOP, // flags
+ 0, // buffer size
+ NULL, // user data.
+ &player );
+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);
+
+ // Create the resample port with specifying the target sampling rate,
+ // and with the file port as the source. This will effectively
+ // connect the resample port with the player port.
+ status = pjmedia_resample_port_create( pool, player, 8000,
+ 0, &resample);
+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);
+
+ // Create the file writer, specifying the resample port's configuration
+ // as the WAV parameters.
+ status pjmedia_wav_writer_port_create(pool,
+ "Output.WAV", // file name.
+ resample->info.clock_rate,
+ resample->info.channel_count,
+ resample->info.samples_per_frame,
+ resample->info.bits_per_sample,
+ 0, // flags
+ 0, // buffer size
+ NULL, // user data.
+ &writer);
+
+ \endcode
+
+
+ After the ports have been set up, application can perform the conversion
+ process by running this loop:
+
+ \code
+
+ pj_int16_t samplebuf[MAX_FRAME];
+
+ while (1) {
+ pjmedia_frame frame;
+ pj_status_t status;
+
+ frame.buf = samplebuf;
+ frame.size = sizeof(samplebuf);
+
+ // Get the frame from resample port.
+ status = pjmedia_port_get_frame(resample, &frame);
+ if (status != PJ_SUCCESS || frame.type == PJMEDIA_FRAME_TYPE_NONE) {
+ // End-of-file, end the conversion.
+ break;
+ }
+
+ // Put the frame to write port.
+ status = pjmedia_port_put_frame(writer, &frame);
+ if (status != PJ_SUCCESS) {
+ // Error in writing the file.
+ break;
+ }
+ }
+
+ \endcode
+
+ For the sake of completeness, after the resampling process is done,
+ application would need to destroy the ports:
+
+ \code
+ // Note: by default, destroying resample port will destroy the
+ // the downstream port too.
+ pjmedia_port_destroy(resample);
+ pjmedia_port_destroy(writer);
+ \endcode
+
+
+ The above steps are okay for our simple purpose of changing file's sampling
+ rate. But for other purposes, the process of reading and writing frames
+ need to be done in timely manner (for example, sending RTP packets to
+ remote stream). And more over, as the application's scope goes bigger,
+ the same pattern of manually reading/writing frames comes up more and more often,
+ thus perhaps it would be better if PJMEDIA provides mechanism to
+ automate this process.
+
+ And indeed PJMEDIA does provide such mechanism, which is described in
+ @ref PJMEDIA_PORT_CLOCK section.
+
+
+ @subsection media_port_autom Automating Media Flow
+
+ PJMEDIA provides few mechanisms to make media flows automatically
+ among media ports. This concept is described in @ref PJMEDIA_PORT_CLOCK
+ section.
+*/
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Port operation setting.
+ */
+typedef enum pjmedia_port_op
+{
+ /**
+ * No change to the port TX or RX settings.
+ */
+ PJMEDIA_PORT_NO_CHANGE,
+
+ /**
+ * TX or RX is disabled from the port. It means get_frame() or
+ * put_frame() WILL NOT be called for this port.
+ */
+ PJMEDIA_PORT_DISABLE,
+
+ /**
+ * TX or RX is muted, which means that get_frame() or put_frame()
+ * will still be called, but the audio frame is discarded.
+ */
+ PJMEDIA_PORT_MUTE,
+
+ /**
+ * Enable TX and RX to/from this port.
+ */
+ PJMEDIA_PORT_ENABLE
+
+} pjmedia_port_op;
+
+
+/**
+ * Port info.
+ */
+typedef struct pjmedia_port_info
+{
+ pj_str_t name; /**< Port name. */
+ pj_uint32_t signature; /**< Port signature. */
+ pjmedia_type type; /**< Media type. */
+ pj_bool_t has_info; /**< Has info? */
+ pj_bool_t need_info; /**< Need info on connect? */
+ unsigned pt; /**< Payload type (can be dynamic). */
+ pjmedia_format format; /**< Format. */
+ pj_str_t encoding_name; /**< Encoding name. */
+ unsigned clock_rate; /**< Sampling rate. */
+ unsigned channel_count; /**< Number of channels. */
+ unsigned bits_per_sample; /**< Bits/sample */
+ unsigned samples_per_frame; /**< No of samples per frame. */
+ unsigned bytes_per_frame; /**< No of samples per frame. */
+} pjmedia_port_info;
+
+
+/**
+ * Port interface.
+ */
+typedef struct pjmedia_port
+{
+ pjmedia_port_info info; /**< Port information. */
+
+ /** Port data can be used by the port creator to attach arbitrary
+ * value to be associated with the port.
+ */
+ struct port_data {
+ void *pdata; /**< Pointer data. */
+ long ldata; /**< Long data. */
+ } port_data;
+
+ /**
+ * Sink interface.
+ * This should only be called by #pjmedia_port_put_frame().
+ */
+ pj_status_t (*put_frame)(struct pjmedia_port *this_port,
+ const pjmedia_frame *frame);
+
+ /**
+ * Source interface.
+ * This should only be called by #pjmedia_port_get_frame().
+ */
+ pj_status_t (*get_frame)(struct pjmedia_port *this_port,
+ pjmedia_frame *frame);
+
+ /**
+ * Called to destroy this port.
+ */
+ pj_status_t (*on_destroy)(struct pjmedia_port *this_port);
+
+} pjmedia_port;
+
+
+/**
+ * This is an auxiliary function to initialize port info for
+ * ports which deal with PCM audio.
+ *
+ * @param info The port info to be initialized.
+ * @param name Port name.
+ * @param signature Port signature.
+ * @param clock_rate Port's clock rate.
+ * @param channel_count Number of channels.
+ * @param bits_per_sample Bits per sample.
+ * @param samples_per_frame Number of samples per frame.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_port_info_init( pjmedia_port_info *info,
+ const pj_str_t *name,
+ unsigned signature,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned bits_per_sample,
+ unsigned samples_per_frame);
+
+
+/**
+ * Get a frame from the port (and subsequent downstream ports).
+ *
+ * @param port The media port.
+ * @param frame Frame to store samples.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port,
+ pjmedia_frame *frame );
+
+/**
+ * Put a frame to the port (and subsequent downstream ports).
+ *
+ * @param port The media port.
+ * @param frame Frame to the put to the port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_port_put_frame( pjmedia_port *port,
+ const pjmedia_frame *frame );
+
+
+/**
+ * Destroy port (and subsequent downstream ports)
+ *
+ * @param port The media port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_port_destroy( pjmedia_port *port );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_PORT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/resample.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/resample.h
new file mode 100644
index 0000000..ada2e77
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/resample.h
@@ -0,0 +1,200 @@
+/* $Id: resample.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_RESAMPLE_H__
+#define __PJMEDIA_RESAMPLE_H__
+
+
+
+/**
+ * @file resample.h
+ * @brief Sample rate converter.
+ */
+#include <pjmedia/types.h>
+#include <pjmedia/port.h>
+
+/**
+ * @defgroup PJMEDIA_RESAMPLE Resampling Algorithm
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Sample rate conversion algorithm
+ * @{
+ *
+ * This section describes the base resampling functions. In addition to this,
+ * application can use the @ref PJMEDIA_RESAMPLE_PORT which provides
+ * media port abstraction for the base resampling algorithm.
+ */
+
+PJ_BEGIN_DECL
+
+/*
+ * This file declares two types of API:
+ *
+ * Application can use #pjmedia_resample_create() and #pjmedia_resample_run()
+ * to convert a frame from source rate to destination rate. The inpuit frame
+ * must have a constant length.
+ *
+ * Alternatively, application can create a resampling port with
+ * #pjmedia_resample_port_create() and connect the port to other ports to
+ * change the sampling rate of the samples.
+ */
+
+
+/**
+ * Opaque resample session.
+ */
+typedef struct pjmedia_resample pjmedia_resample;
+
+/**
+ * Create a frame based resample session.
+ *
+ * @param pool Pool to allocate the structure and buffers.
+ * @param high_quality If true, then high quality conversion will be
+ * used, at the expense of more CPU and memory,
+ * because temporary buffer needs to be created.
+ * @param large_filter If true, large filter size will be used.
+ * @param channel_count Number of channels.
+ * @param rate_in Clock rate of the input samples.
+ * @param rate_out Clock rate of the output samples.
+ * @param samples_per_frame Number of samples per frame in the input.
+ * @param p_resample Pointer to receive the resample session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_resample_create(pj_pool_t *pool,
+ pj_bool_t high_quality,
+ pj_bool_t large_filter,
+ unsigned channel_count,
+ unsigned rate_in,
+ unsigned rate_out,
+ unsigned samples_per_frame,
+ pjmedia_resample **p_resample);
+
+
+/**
+ * Use the resample session to resample a frame. The frame must have the
+ * same size and settings as the resample session, or otherwise the
+ * behavior is undefined.
+ *
+ * @param resample The resample session.
+ * @param input Buffer containing the input samples.
+ * @param output Buffer to store the output samples.
+ */
+PJ_DECL(void) pjmedia_resample_run( pjmedia_resample *resample,
+ const pj_int16_t *input,
+ pj_int16_t *output );
+
+
+/**
+ * Get the input frame size of a resample session.
+ *
+ * @param resample The resample session.
+ *
+ * @return The frame size, in number of samples.
+ */
+PJ_DECL(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample);
+
+
+/**
+ * Destroy the resample.
+ *
+ * @param resample The resample session.
+ */
+PJ_DECL(void) pjmedia_resample_destroy(pjmedia_resample *resample);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJMEDIA_RESAMPLE_PORT Resample Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio sample rate conversion
+ * @{
+ *
+ * This section describes media port abstraction for @ref PJMEDIA_RESAMPLE.
+ */
+
+
+/**
+ * Option flags that can be specified when creating resample port.
+ */
+enum pjmedia_resample_port_options
+{
+ /**
+ * Do not use high quality resampling algorithm, but use linear
+ * algorithm instead.
+ */
+ PJMEDIA_RESAMPLE_USE_LINEAR = 1,
+
+ /**
+ * Use small filter workspace when high quality resampling is
+ * used.
+ */
+ PJMEDIA_RESAMPLE_USE_SMALL_FILTER = 2,
+
+ /**
+ * Do not destroy downstream port when resample port is destroyed.
+ */
+ PJMEDIA_RESAMPLE_DONT_DESTROY_DN = 4
+};
+
+
+
+/**
+ * Create a resample port. This creates a bidirectional resample session,
+ * which will resample frames when the port's get_frame() and put_frame()
+ * is called.
+ *
+ * When the resample port's get_frame() is called, this port will get
+ * a frame from the downstream port and resample the frame to the target
+ * clock rate before returning it to the caller.
+ *
+ * When the resample port's put_frame() is called, this port will resample
+ * the frame to the downstream port's clock rate before giving the frame
+ * to the downstream port.
+ *
+ * @param pool Pool to allocate the structure and buffers.
+ * @param dn_port The downstream port, which clock rate is to
+ * be converted to the target clock rate.
+ * @param clock_rate Target clock rate.
+ * @param options Flags from #pjmedia_resample_port_options.
+ * When this flag is zero, the default behavior
+ * is to use high quality resampling with
+ * large filter, and to destroy downstream port
+ * when resample port is destroyed.
+ * @param p_port Pointer to receive the resample port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,
+ pjmedia_port *dn_port,
+ unsigned clock_rate,
+ unsigned options,
+ pjmedia_port **p_port );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_RESAMPLE_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp.h
new file mode 100644
index 0000000..6814d35
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp.h
@@ -0,0 +1,408 @@
+/* $Id: rtcp.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_RTCP_H__
+#define __PJMEDIA_RTCP_H__
+
+/**
+ * @file rtcp.h
+ * @brief RTCP implementation.
+ */
+
+#include <pjmedia/types.h>
+#include <pjmedia/rtcp_xr.h>
+#include <pjmedia/rtp.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_RTCP RTCP Session and Encapsulation (RFC 3550)
+ * @ingroup PJMEDIA_SESSION
+ * @brief RTCP format and session management
+ * @{
+ *
+ * PJMEDIA implements subsets of RTCP specification (RFC 3550) to monitor
+ * the quality of the real-time media (audio/video) transmission. In
+ * addition to the standard quality monitoring and reporting with RTCP
+ * SR and RR types, PJMEDIA's RTCP implementation is able to report
+ * extended statistics for incoming streams, such as packet duplications,
+ * reorder, discarded, and loss period (to distinguish between random
+ * and burst loss).
+ *
+ * The bidirectional media quality statistic is represented with
+ * #pjmedia_rtcp_stat structure.
+ *
+ * When application uses the stream interface (see @ref PJMED_STRM),
+ * application may retrieve the RTCP statistic by calling
+ * #pjmedia_stream_get_stat() function.
+ */
+
+#pragma pack(1)
+
+/**
+ * RTCP sender report.
+ */
+struct pjmedia_rtcp_sr
+{
+ pj_uint32_t ntp_sec; /**< NTP time, seconds part. */
+ pj_uint32_t ntp_frac; /**< NTP time, fractions part. */
+ pj_uint32_t rtp_ts; /**< RTP timestamp. */
+ pj_uint32_t sender_pcount; /**< Sender packet cound. */
+ pj_uint32_t sender_bcount; /**< Sender octet/bytes count. */
+};
+
+/**
+ * @see pjmedia_rtcp_sr
+ */
+typedef struct pjmedia_rtcp_sr pjmedia_rtcp_sr;
+
+/**
+ * RTCP receiver report.
+ */
+struct pjmedia_rtcp_rr
+{
+ pj_uint32_t ssrc; /**< SSRC identification. */
+#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
+ pj_uint32_t fract_lost:8; /**< Fraction lost. */
+ pj_uint32_t total_lost_2:8; /**< Total lost, bit 16-23. */
+ pj_uint32_t total_lost_1:8; /**< Total lost, bit 8-15. */
+ pj_uint32_t total_lost_0:8; /**< Total lost, bit 0-7. */
+#else
+ pj_uint32_t fract_lost:8; /**< Fraction lost. */
+ pj_uint32_t total_lost_2:8; /**< Total lost, bit 0-7. */
+ pj_uint32_t total_lost_1:8; /**< Total lost, bit 8-15. */
+ pj_uint32_t total_lost_0:8; /**< Total lost, bit 16-23. */
+#endif
+ pj_uint32_t last_seq; /**< Last sequence number. */
+ pj_uint32_t jitter; /**< Jitter. */
+ pj_uint32_t lsr; /**< Last SR. */
+ pj_uint32_t dlsr; /**< Delay since last SR. */
+};
+
+/**
+ * @see pjmedia_rtcp_rr
+ */
+typedef struct pjmedia_rtcp_rr pjmedia_rtcp_rr;
+
+
+/**
+ * RTCP common header.
+ */
+struct pjmedia_rtcp_common
+{
+#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
+ unsigned version:2; /**< packet type */
+ unsigned p:1; /**< padding flag */
+ unsigned count:5; /**< varies by payload type */
+ unsigned pt:8; /**< payload type */
+#else
+ unsigned count:5; /**< varies by payload type */
+ unsigned p:1; /**< padding flag */
+ unsigned version:2; /**< packet type */
+ unsigned pt:8; /**< payload type */
+#endif
+ unsigned length:16; /**< packet length */
+ pj_uint32_t ssrc; /**< SSRC identification */
+};
+
+/**
+ * @see pjmedia_rtcp_common
+ */
+typedef struct pjmedia_rtcp_common pjmedia_rtcp_common;
+
+/**
+ * This structure declares default RTCP packet (SR) that is sent by pjmedia.
+ * Incoming RTCP packet may have different format, and must be parsed
+ * manually by application.
+ */
+typedef struct pjmedia_rtcp_sr_pkt
+{
+ pjmedia_rtcp_common common; /**< Common header. */
+ pjmedia_rtcp_sr sr; /**< Sender report. */
+ pjmedia_rtcp_rr rr; /**< variable-length list */
+} pjmedia_rtcp_sr_pkt;
+
+/**
+ * This structure declares RTCP RR (Receiver Report) packet.
+ */
+typedef struct pjmedia_rtcp_rr_pkt
+{
+ pjmedia_rtcp_common common; /**< Common header. */
+ pjmedia_rtcp_rr rr; /**< variable-length list */
+} pjmedia_rtcp_rr_pkt;
+
+
+#pragma pack()
+
+
+/**
+ * NTP time representation.
+ */
+struct pjmedia_rtcp_ntp_rec
+{
+ pj_uint32_t hi; /**< High order 32-bit part. */
+ pj_uint32_t lo; /**< Lo order 32-bit part. */
+};
+
+/**
+ * @see pjmedia_rtcp_ntp_rec
+ */
+typedef struct pjmedia_rtcp_ntp_rec pjmedia_rtcp_ntp_rec;
+
+
+
+/**
+ * Unidirectional RTP stream statistics.
+ */
+struct pjmedia_rtcp_stream_stat
+{
+ pj_time_val update; /**< Time of last update. */
+ unsigned update_cnt; /**< Number of updates (to calculate avg) */
+ pj_uint32_t pkt; /**< Total number of packets */
+ pj_uint32_t bytes; /**< Total number of payload/bytes */
+ unsigned discard; /**< Total number of discarded packets. */
+ unsigned loss; /**< Total number of packets lost */
+ unsigned reorder; /**< Total number of out of order packets */
+ unsigned dup; /**< Total number of duplicates packets */
+
+ pj_math_stat loss_period;/**< Loss period statistics (in usec) */
+
+ struct {
+ unsigned burst:1; /**< Burst/sequential packet lost detected */
+ unsigned random:1; /**< Random packet lost detected. */
+ } loss_type; /**< Types of loss detected. */
+
+ pj_math_stat jitter; /**< Jitter statistics (in usec) */
+};
+
+
+/**
+ * @see pjmedia_rtcp_stream_stat
+ */
+typedef struct pjmedia_rtcp_stream_stat pjmedia_rtcp_stream_stat;
+
+
+
+/**
+ * Bidirectional RTP stream statistics.
+ */
+struct pjmedia_rtcp_stat
+{
+ pj_time_val start; /**< Time when session was created */
+
+ pjmedia_rtcp_stream_stat tx; /**< Encoder stream statistics. */
+ pjmedia_rtcp_stream_stat rx; /**< Decoder stream statistics. */
+
+ pj_math_stat rtt; /**< Round trip delay statistic(in usec)*/
+
+ pj_uint32_t rtp_tx_last_ts; /**< Last TX RTP timestamp. */
+ pj_uint16_t rtp_tx_last_seq;/**< Last TX RTP sequence. */
+};
+
+
+/**
+ * @see pjmedia_rtcp_stat
+ */
+typedef struct pjmedia_rtcp_stat pjmedia_rtcp_stat;
+
+
+/**
+ * RTCP session is used to monitor the RTP session of one endpoint. There
+ * should only be one RTCP session for a bidirectional RTP streams.
+ */
+struct pjmedia_rtcp_session
+{
+ char *name; /**< Name identification. */
+ pjmedia_rtcp_sr_pkt rtcp_sr_pkt;/**< Cached RTCP SR packet. */
+ pjmedia_rtcp_rr_pkt rtcp_rr_pkt;/**< Cached RTCP RR packet. */
+
+ pjmedia_rtp_seq_session seq_ctrl; /**< RTCP sequence number control. */
+ unsigned rtp_last_ts;/**< Last timestamp in RX RTP pkt. */
+
+ unsigned clock_rate; /**< Clock rate of the stream */
+ unsigned pkt_size; /**< Avg pkt size, in samples. */
+ pj_uint32_t received; /**< # pkt received */
+ pj_uint32_t exp_prior; /**< # pkt expected at last interval*/
+ pj_uint32_t rx_prior; /**< # pkt received at last interval*/
+ pj_int32_t transit; /**< Rel transit time for prev pkt */
+ pj_uint32_t jitter; /**< Scaled jitter */
+ pj_time_val tv_base; /**< Base time, in seconds. */
+ pj_timestamp ts_base; /**< Base system timestamp. */
+ pj_timestamp ts_freq; /**< System timestamp frequency. */
+
+ pj_uint32_t rx_lsr; /**< NTP ts in last SR received */
+ pj_timestamp rx_lsr_time;/**< Time when last SR is received */
+ pj_uint32_t peer_ssrc; /**< Peer SSRC */
+
+ pjmedia_rtcp_stat stat; /**< Bidirectional stream stat. */
+
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+ /**
+ * Specify whether RTCP XR processing is enabled on this session.
+ */
+ pj_bool_t xr_enabled;
+
+ /**
+ * RTCP XR session, only valid if RTCP XR processing is enabled
+ * on this session.
+ */
+ pjmedia_rtcp_xr_session xr_session;
+#endif
+};
+
+/**
+ * @see pjmedia_rtcp_session
+ */
+typedef struct pjmedia_rtcp_session pjmedia_rtcp_session;
+
+
+/**
+ * Initialize RTCP session.
+ *
+ * @param session The session
+ * @param name Optional name to identify the session (for
+ * logging purpose).
+ * @param clock_rate Codec clock rate in samples per second.
+ * @param samples_per_frame Average number of samples per frame.
+ * @param ssrc The SSRC used in to identify the session.
+ */
+PJ_DECL(void) pjmedia_rtcp_init( pjmedia_rtcp_session *session,
+ char *name,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ pj_uint32_t ssrc );
+
+
+/**
+ * Utility function to retrieve current NTP timestamp.
+ *
+ * @param sess RTCP session.
+ * @param ntp NTP record.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtcp_get_ntp_time(const pjmedia_rtcp_session *sess,
+ pjmedia_rtcp_ntp_rec *ntp);
+
+
+/**
+ * Deinitialize RTCP session.
+ *
+ * @param session The session.
+ */
+PJ_DECL(void) pjmedia_rtcp_fini( pjmedia_rtcp_session *session);
+
+
+/**
+ * Call this function everytime an RTP packet is received to let the RTCP
+ * session do its internal calculations.
+ *
+ * @param session The session.
+ * @param seq The RTP packet sequence number, in host byte order.
+ * @param ts The RTP packet timestamp, in host byte order.
+ * @param payload Size of the payload.
+ */
+PJ_DECL(void) pjmedia_rtcp_rx_rtp( pjmedia_rtcp_session *session,
+ unsigned seq,
+ unsigned ts,
+ unsigned payload);
+
+
+/**
+ * Call this function everytime an RTP packet is received to let the RTCP
+ * session do its internal calculations.
+ *
+ * @param session The session.
+ * @param seq The RTP packet sequence number, in host byte order.
+ * @param ts The RTP packet timestamp, in host byte order.
+ * @param payload Size of the payload.
+ * @param discarded Flag to specify whether the packet is discarded.
+ */
+PJ_DECL(void) pjmedia_rtcp_rx_rtp2(pjmedia_rtcp_session *session,
+ unsigned seq,
+ unsigned ts,
+ unsigned payload,
+ pj_bool_t discarded);
+
+
+/**
+ * Call this function everytime an RTP packet is sent to let the RTCP session
+ * do its internal calculations.
+ *
+ * @param session The session.
+ * @param ptsize The payload size of the RTP packet (ie packet minus
+ * RTP header) in bytes.
+ */
+PJ_DECL(void) pjmedia_rtcp_tx_rtp( pjmedia_rtcp_session *session,
+ unsigned ptsize );
+
+
+/**
+ * Call this function when an RTCP packet is received from remote peer.
+ * This RTCP packet received from remote is used to calculate the end-to-
+ * end delay of the network.
+ *
+ * @param session RTCP session.
+ * @param rtcp_pkt The received RTCP packet.
+ * @param size Size of the incoming packet.
+ */
+PJ_DECL(void) pjmedia_rtcp_rx_rtcp( pjmedia_rtcp_session *session,
+ const void *rtcp_pkt,
+ pj_size_t size);
+
+
+/**
+ * Build a RTCP packet to be transmitted to remote RTP peer. This will
+ * create RTCP Sender Report (SR) or Receiver Report (RR) depending on
+ * whether the endpoint has been transmitting RTP since the last interval.
+ * Note that this function will reset the interval counters (such as
+ * the ones to calculate fraction lost) in the session.
+ *
+ * @param session The RTCP session.
+ * @param rtcp_pkt Upon return, it will contain pointer to the
+ * RTCP packet, which can be RTCP SR or RR.
+ * @param len Upon return, it will indicate the size of
+ * the RTCP packet.
+ */
+PJ_DECL(void) pjmedia_rtcp_build_rtcp( pjmedia_rtcp_session *session,
+ void **rtcp_pkt, int *len);
+
+
+/**
+ * Call this function if RTCP XR needs to be enabled/disabled in the
+ * RTCP session.
+ *
+ * @param session The RTCP session.
+ * @param enable Enable/disable RTCP XR.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtcp_enable_xr( pjmedia_rtcp_session *session,
+ pj_bool_t enable);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_RTCP_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp_xr.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp_xr.h
new file mode 100644
index 0000000..37ecc75
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp_xr.h
@@ -0,0 +1,467 @@
+/* $Id: rtcp_xr.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_RTCP_XR_H__
+#define __PJMEDIA_RTCP_XR_H__
+
+/**
+ * @file rtcp_xr.h
+ * @brief RTCP XR implementation.
+ */
+
+#include <pjmedia/types.h>
+#include <pj/math.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_RTCP_XR RTCP Extended Report (XR) - RFC 3611
+ * @ingroup PJMEDIA_SESSION
+ * @brief RTCP XR extension to RTCP session
+ * @{
+ *
+ * PJMEDIA implements subsets of RTCP XR specification (RFC 3611) to monitor
+ * the quality of the real-time media (audio/video) transmission.
+ */
+
+/**
+ * Enumeration of report types of RTCP XR. Useful for user to enable varying
+ * combinations of RTCP XR report blocks.
+ */
+typedef enum {
+ PJMEDIA_RTCP_XR_LOSS_RLE = (1 << 0),
+ PJMEDIA_RTCP_XR_DUP_RLE = (1 << 1),
+ PJMEDIA_RTCP_XR_RCPT_TIMES = (1 << 2),
+ PJMEDIA_RTCP_XR_RR_TIME = (1 << 3),
+ PJMEDIA_RTCP_XR_DLRR = (1 << 4),
+ PJMEDIA_RTCP_XR_STATS = (1 << 5),
+ PJMEDIA_RTCP_XR_VOIP_METRICS = (1 << 6)
+} pjmedia_rtcp_xr_type;
+
+/**
+ * Enumeration of info need to be updated manually to RTCP XR. Most info
+ * could be updated automatically each time RTP received.
+ */
+typedef enum {
+ PJMEDIA_RTCP_XR_INFO_SIGNAL_LVL = 1,
+ PJMEDIA_RTCP_XR_INFO_NOISE_LVL = 2,
+ PJMEDIA_RTCP_XR_INFO_RERL = 3,
+ PJMEDIA_RTCP_XR_INFO_R_FACTOR = 4,
+ PJMEDIA_RTCP_XR_INFO_MOS_LQ = 5,
+ PJMEDIA_RTCP_XR_INFO_MOS_CQ = 6,
+ PJMEDIA_RTCP_XR_INFO_CONF_PLC = 7,
+ PJMEDIA_RTCP_XR_INFO_CONF_JBA = 8,
+ PJMEDIA_RTCP_XR_INFO_CONF_JBR = 9,
+ PJMEDIA_RTCP_XR_INFO_JB_NOM = 10,
+ PJMEDIA_RTCP_XR_INFO_JB_MAX = 11,
+ PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX = 12
+} pjmedia_rtcp_xr_info;
+
+/**
+ * Enumeration of PLC types definitions for RTCP XR report.
+ */
+typedef enum {
+ PJMEDIA_RTCP_XR_PLC_UNK = 0,
+ PJMEDIA_RTCP_XR_PLC_DIS = 1,
+ PJMEDIA_RTCP_XR_PLC_ENH = 2,
+ PJMEDIA_RTCP_XR_PLC_STD = 3
+} pjmedia_rtcp_xr_plc_type;
+
+/**
+ * Enumeration of jitter buffer types definitions for RTCP XR report.
+ */
+typedef enum {
+ PJMEDIA_RTCP_XR_JB_UNKNOWN = 0,
+ PJMEDIA_RTCP_XR_JB_FIXED = 2,
+ PJMEDIA_RTCP_XR_JB_ADAPTIVE = 3
+} pjmedia_rtcp_xr_jb_type;
+
+
+#pragma pack(1)
+
+/**
+ * This type declares RTCP XR Report Header.
+ */
+typedef struct pjmedia_rtcp_xr_rb_header
+{
+ pj_uint8_t bt; /**< Block type. */
+ pj_uint8_t specific; /**< Block specific data. */
+ pj_uint16_t length; /**< Block length. */
+} pjmedia_rtcp_xr_rb_header;
+
+/**
+ * This type declares RTCP XR Receiver Reference Time Report Block.
+ */
+typedef struct pjmedia_rtcp_xr_rb_rr_time
+{
+ pjmedia_rtcp_xr_rb_header header; /**< Block header. */
+ pj_uint32_t ntp_sec; /**< NTP time, seconds part. */
+ pj_uint32_t ntp_frac; /**< NTP time, fractions part. */
+} pjmedia_rtcp_xr_rb_rr_time;
+
+
+/**
+ * This type declares RTCP XR DLRR Report Sub-block
+ */
+typedef struct pjmedia_rtcp_xr_rb_dlrr_item
+{
+ pj_uint32_t ssrc; /**< receiver SSRC */
+ pj_uint32_t lrr; /**< last receiver report */
+ pj_uint32_t dlrr; /**< delay since last receiver
+ report */
+} pjmedia_rtcp_xr_rb_dlrr_item;
+
+/**
+ * This type declares RTCP XR DLRR Report Block
+ */
+typedef struct pjmedia_rtcp_xr_rb_dlrr
+{
+ pjmedia_rtcp_xr_rb_header header; /**< Block header. */
+ pjmedia_rtcp_xr_rb_dlrr_item item; /**< Block contents,
+ variable length list */
+} pjmedia_rtcp_xr_rb_dlrr;
+
+/**
+ * This type declares RTCP XR Statistics Summary Report Block
+ */
+typedef struct pjmedia_rtcp_xr_rb_stats
+{
+ pjmedia_rtcp_xr_rb_header header; /**< Block header. */
+ pj_uint32_t ssrc; /**< Receiver SSRC */
+ pj_uint16_t begin_seq; /**< Begin RTP sequence reported */
+ pj_uint16_t end_seq; /**< End RTP sequence reported */
+ pj_uint32_t lost; /**< Number of packet lost in this
+ interval */
+ pj_uint32_t dup; /**< Number of duplicated packet in
+ this interval */
+ pj_uint32_t jitter_min; /**< Minimum jitter in this interval */
+ pj_uint32_t jitter_max; /**< Maximum jitter in this interval */
+ pj_uint32_t jitter_mean; /**< Average jitter in this interval */
+ pj_uint32_t jitter_dev; /**< Jitter deviation in this
+ interval */
+ pj_uint32_t toh_min:8; /**< Minimum ToH in this interval */
+ pj_uint32_t toh_max:8; /**< Maximum ToH in this interval */
+ pj_uint32_t toh_mean:8; /**< Average ToH in this interval */
+ pj_uint32_t toh_dev:8; /**< ToH deviation in this interval */
+} pjmedia_rtcp_xr_rb_stats;
+
+/**
+ * This type declares RTCP XR VoIP Metrics Report Block
+ */
+typedef struct pjmedia_rtcp_xr_rb_voip_mtc
+{
+ pjmedia_rtcp_xr_rb_header header; /**< Block header. */
+ pj_uint32_t ssrc; /**< Receiver SSRC */
+ pj_uint8_t loss_rate; /**< Packet loss rate */
+ pj_uint8_t discard_rate; /**< Packet discarded rate */
+ pj_uint8_t burst_den; /**< Burst density */
+ pj_uint8_t gap_den; /**< Gap density */
+ pj_uint16_t burst_dur; /**< Burst duration */
+ pj_uint16_t gap_dur; /**< Gap duration */
+ pj_uint16_t rnd_trip_delay;/**< Round trip delay */
+ pj_uint16_t end_sys_delay; /**< End system delay */
+ pj_uint8_t signal_lvl; /**< Signal level */
+ pj_uint8_t noise_lvl; /**< Noise level */
+ pj_uint8_t rerl; /**< Residual Echo Return Loss */
+ pj_uint8_t gmin; /**< The gap threshold */
+ pj_uint8_t r_factor; /**< Voice quality metric carried
+ over this RTP session */
+ pj_uint8_t ext_r_factor; /**< Voice quality metric carried
+ outside of this RTP session*/
+ pj_uint8_t mos_lq; /**< Mean Opinion Score for
+ Listening Quality */
+ pj_uint8_t mos_cq; /**< Mean Opinion Score for
+ Conversation Quality */
+ pj_uint8_t rx_config; /**< Receiver configuration */
+ pj_uint8_t reserved2; /**< Not used */
+ pj_uint16_t jb_nom; /**< Current delay by jitter
+ buffer */
+ pj_uint16_t jb_max; /**< Maximum delay by jitter
+ buffer */
+ pj_uint16_t jb_abs_max; /**< Maximum possible delay by
+ jitter buffer */
+} pjmedia_rtcp_xr_rb_voip_mtc;
+
+/**
+ * This structure declares RTCP XR (Extended Report) packet.
+ */
+typedef struct pjmedia_rtcp_xr_pkt
+{
+ struct {
+#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
+ unsigned version:2; /**< packet type */
+ unsigned p:1; /**< padding flag */
+ unsigned count:5; /**< varies by payload type */
+ unsigned pt:8; /**< payload type */
+#else
+ unsigned count:5; /**< varies by payload type */
+ unsigned p:1; /**< padding flag */
+ unsigned version:2; /**< packet type */
+ unsigned pt:8; /**< payload type */
+#endif
+ unsigned length:16; /**< packet length */
+ pj_uint32_t ssrc; /**< SSRC identification */
+ } common;
+
+ pj_int8_t buf[PJMEDIA_MAX_MTU];/**< Content buffer */
+} pjmedia_rtcp_xr_pkt;
+
+#pragma pack()
+
+
+/**
+ * This structure describes RTCP XR statitic.
+ */
+typedef struct pjmedia_rtcp_xr_stream_stat
+{
+ struct {
+ pj_time_val update; /**< Time of last update. */
+
+ pj_uint32_t begin_seq; /**< Begin # seq of this interval. */
+ pj_uint32_t end_seq; /**< End # seq of this interval. */
+ unsigned count; /**< Number of packets. */
+
+ /**
+ * Flags represent whether the such report is valid/updated
+ */
+ unsigned l:1; /**< Lost flag */
+ unsigned d:1; /**< Duplicated flag */
+ unsigned j:1; /**< Jitter flag */
+ unsigned t:2; /**< TTL or Hop Limit,
+ 0=none, 1=TTL, 2=HL */
+
+ unsigned lost; /**< Number of packets lost */
+ unsigned dup; /**< Number of duplicated packets */
+ pj_math_stat jitter; /**< Jitter statistics (in usec) */
+ pj_math_stat toh; /**< TTL of hop limit statistics. */
+ } stat_sum;
+
+ struct {
+ pj_time_val update; /**< Time of last update. */
+
+ pj_uint8_t loss_rate; /**< Packet loss rate */
+ pj_uint8_t discard_rate; /**< Packet discarded rate */
+ pj_uint8_t burst_den; /**< Burst density */
+ pj_uint8_t gap_den; /**< Gap density */
+ pj_uint16_t burst_dur; /**< Burst duration */
+ pj_uint16_t gap_dur; /**< Gap duration */
+ pj_uint16_t rnd_trip_delay; /**< Round trip delay */
+ pj_uint16_t end_sys_delay; /**< End system delay */
+ pj_int8_t signal_lvl; /**< Signal level */
+ pj_int8_t noise_lvl; /**< Noise level */
+ pj_uint8_t rerl; /**< Residual Echo Return Loss */
+ pj_uint8_t gmin; /**< The gap threshold */
+ pj_uint8_t r_factor; /**< Voice quality metric carried
+ over this RTP session */
+ pj_uint8_t ext_r_factor; /**< Voice quality metric carried
+ outside of this RTP session*/
+ pj_uint8_t mos_lq; /**< Mean Opinion Score for
+ Listening Quality */
+ pj_uint8_t mos_cq; /**< Mean Opinion Score for
+ Conversation Quality */
+ pj_uint8_t rx_config; /**< Receiver configuration */
+ pj_uint16_t jb_nom; /**< Current delay by jitter
+ buffer */
+ pj_uint16_t jb_max; /**< Maximum delay by jitter
+ buffer */
+ pj_uint16_t jb_abs_max; /**< Maximum possible delay by
+ jitter buffer */
+ } voip_mtc;
+
+} pjmedia_rtcp_xr_stream_stat;
+
+typedef struct pjmedia_rtcp_xr_stat
+{
+ pjmedia_rtcp_xr_stream_stat rx; /**< Decoding direction statistics. */
+ pjmedia_rtcp_xr_stream_stat tx; /**< Encoding direction statistics. */
+ pj_math_stat rtt; /**< Round-trip delay stat (in usec)
+ the value is calculated from
+ receiver side. */
+} pjmedia_rtcp_xr_stat;
+
+/**
+ * Forward declaration of RTCP session
+ */
+struct pjmedia_rtcp_session;
+
+/**
+ * RTCP session is used to monitor the RTP session of one endpoint. There
+ * should only be one RTCP session for a bidirectional RTP streams.
+ */
+struct pjmedia_rtcp_xr_session
+{
+ char *name; /**< Name identification. */
+ pjmedia_rtcp_xr_pkt pkt; /**< Cached RTCP XR packet. */
+
+ pj_uint32_t rx_lrr; /**< NTP ts in last RR received. */
+ pj_timestamp rx_lrr_time;/**< Time when last RR is received. */
+ pj_uint32_t rx_last_rr; /**< # pkt received since last
+ sending RR time. */
+
+ pjmedia_rtcp_xr_stat stat; /**< RTCP XR statistics. */
+
+ /* The reference sequence number is an extended sequence number
+ * that serves as the basis for determining whether a new 16 bit
+ * sequence number comes earlier or later in the 32 bit sequence
+ * space.
+ */
+ pj_uint32_t src_ref_seq;
+ pj_bool_t uninitialized_src_ref_seq;
+
+ /* This structure contains variables needed for calculating
+ * burst metrics.
+ */
+ struct {
+ pj_uint32_t pkt;
+ pj_uint32_t lost;
+ pj_uint32_t loss_count;
+ pj_uint32_t discard_count;
+ pj_uint32_t c11;
+ pj_uint32_t c13;
+ pj_uint32_t c14;
+ pj_uint32_t c22;
+ pj_uint32_t c23;
+ pj_uint32_t c33;
+ } voip_mtc_stat;
+
+ unsigned ptime; /**< Packet time. */
+ unsigned frames_per_packet; /**< # frames per packet. */
+
+ struct pjmedia_rtcp_session *rtcp_session;
+ /**< Parent/RTCP session. */
+};
+
+typedef struct pjmedia_rtcp_xr_session pjmedia_rtcp_xr_session;
+
+/**
+ * Build an RTCP XR packet which contains one or more RTCP XR report blocks.
+ * There are seven report types as defined in RFC 3611.
+ *
+ * @param session The RTCP XR session.
+ * @param rpt_types Report types to be included in the packet, report types
+ * are defined in pjmedia_rtcp_xr_type, set this to zero
+ * will make this function build all reports appropriately.
+ * @param rtcp_pkt Upon return, it will contain pointer to the RTCP XR packet.
+ * @param len Upon return, it will indicate the size of the generated
+ * RTCP XR packet.
+ */
+PJ_DECL(void) pjmedia_rtcp_build_rtcp_xr( pjmedia_rtcp_xr_session *session,
+ unsigned rpt_types,
+ void **rtcp_pkt, int *len);
+
+/**
+ * Call this function to manually update some info needed by RTCP XR to
+ * generate report which could not be populated directly when receiving
+ * RTP.
+ *
+ * @param session The RTCP XR session.
+ * @param info Info type to be updated, @see pjmedia_rtcp_xr_info.
+ * @param val Value.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtcp_xr_update_info(
+ pjmedia_rtcp_xr_session *session,
+ unsigned info,
+ pj_int32_t val);
+
+/*
+ * Private APIs:
+ */
+
+/**
+ * This function is called internally by RTCP session when RTCP XR is enabled
+ * to initialize the RTCP XR session.
+ *
+ * @param session RTCP XR session.
+ * @param r_session RTCP session.
+ * @param gmin Gmin value (defined in RFC 3611), set to 0 for default (16).
+ * @param ptime Packet time.
+ * @param frames_per_packet
+ Number of frames per packet.
+ */
+void pjmedia_rtcp_xr_init( pjmedia_rtcp_xr_session *session,
+ struct pjmedia_rtcp_session *r_session,
+ pj_uint8_t gmin,
+ unsigned frames_per_packet);
+
+/**
+ * This function is called internally by RTCP session to destroy
+ * the RTCP XR session.
+ *
+ * @param session RTCP XR session.
+ */
+void pjmedia_rtcp_xr_fini( pjmedia_rtcp_xr_session *session );
+
+/**
+ * This function is called internally by RTCP session when it receives
+ * incoming RTCP XR packets.
+ *
+ * @param session RTCP XR session.
+ * @param rtcp_pkt The received RTCP XR packet.
+ * @param size Size of the incoming packet.
+ */
+void pjmedia_rtcp_xr_rx_rtcp_xr( pjmedia_rtcp_xr_session *session,
+ const void *rtcp_xr_pkt,
+ pj_size_t size);
+
+/**
+ * This function is called internally by RTCP session whenever an RTP packet
+ * is received or lost to let the RTCP XR session update its statistics.
+ * Data passed to this function is a result of analyzation by RTCP and the
+ * jitter buffer. Whenever some info is available, the value should be zero
+ * or more (no negative info), otherwise if info is not available the info
+ * should be -1 so no update will be done for this info in the RTCP XR session.
+ *
+ * @param session RTCP XR session.
+ * @param seq Sequence number of RTP packet.
+ * @param lost Info if this packet is lost.
+ * @param dup Info if this packet is a duplication.
+ * @param discarded Info if this packet is discarded
+ * (not because of duplication).
+ * @param jitter Info jitter of this packet.
+ * @param toh Info Time To Live or Hops Limit of this packet.
+ * @param toh_ipv4 Set PJ_TRUE if packet is transported over IPv4.
+ */
+void pjmedia_rtcp_xr_rx_rtp( pjmedia_rtcp_xr_session *session,
+ unsigned seq,
+ int lost,
+ int dup,
+ int discarded,
+ int jitter,
+ int toh, pj_bool_t toh_ipv4);
+
+/**
+ * This function is called internally by RTCP session whenever an RTP
+ * packet is sent to let the RTCP XR session do its internal calculations.
+ *
+ * @param session RTCP XR session.
+ * @param ptsize Size of RTP payload being sent.
+ */
+void pjmedia_rtcp_xr_tx_rtp( pjmedia_rtcp_xr_session *session,
+ unsigned ptsize );
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_RTCP_XR_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtp.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtp.h
new file mode 100644
index 0000000..86cda9c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtp.h
@@ -0,0 +1,394 @@
+/* $Id: rtp.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_RTP_H__
+#define __PJMEDIA_RTP_H__
+
+
+/**
+ * @file rtp.h
+ * @brief RTP packet and RTP session declarations.
+ */
+#include <pjmedia/types.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_RTP RTP Session and Encapsulation (RFC 3550)
+ * @ingroup PJMEDIA_SESSION
+ * @brief RTP format and session management
+ * @{
+ *
+ * The RTP module is designed to be dependent only to PJLIB, it does not depend
+ * on any other parts of PJMEDIA library. The RTP module does not even depend
+ * on any transports (sockets), to promote even more use, such as in DSP
+ * development (where transport may be handled by different processor).
+ *
+ * An RTCP implementation is available, in separate module. Please see
+ * @ref PJMED_RTCP.
+ *
+ * The functions that are provided by this module:
+ * - creating RTP header for each outgoing packet.
+ * - decoding RTP packet into RTP header and payload.
+ * - provide simple RTP session management (sequence number, etc.)
+ *
+ * The RTP module does not use any dynamic memory at all.
+ *
+ * \section P1 How to Use the RTP Module
+ *
+ * First application must call #pjmedia_rtp_session_init() to initialize the RTP
+ * session.
+ *
+ * When application wants to send RTP packet, it needs to call
+ * #pjmedia_rtp_encode_rtp() to build the RTP header. Note that this WILL NOT build
+ * the complete RTP packet, but instead only the header. Application can
+ * then either concatenate the header with the payload, or send the two
+ * fragments (the header and the payload) using scatter-gather transport API
+ * (e.g. \a sendv()).
+ *
+ * When application receives an RTP packet, first it should call
+ * #pjmedia_rtp_decode_rtp to decode RTP header and payload, then it should call
+ * #pjmedia_rtp_session_update to check whether we can process the RTP payload,
+ * and to let the RTP session updates its internal status. The decode function
+ * is guaranteed to point the payload to the correct position regardless of
+ * any options present in the RTP packet.
+ *
+ */
+
+#ifdef _MSC_VER
+# pragma warning(disable:4214) // bit field types other than int
+#endif
+
+
+/**
+ * RTP packet header. Note that all RTP functions here will work with this
+ * header in network byte order.
+ */
+#pragma pack(1)
+struct pjmedia_rtp_hdr
+{
+#if defined(PJ_IS_BIG_ENDIAN) && (PJ_IS_BIG_ENDIAN!=0)
+ pj_uint16_t v:2; /**< packet type/version */
+ pj_uint16_t p:1; /**< padding flag */
+ pj_uint16_t x:1; /**< extension flag */
+ pj_uint16_t cc:4; /**< CSRC count */
+ pj_uint16_t m:1; /**< marker bit */
+ pj_uint16_t pt:7; /**< payload type */
+#else
+ pj_uint16_t cc:4; /**< CSRC count */
+ pj_uint16_t x:1; /**< header extension flag */
+ pj_uint16_t p:1; /**< padding flag */
+ pj_uint16_t v:2; /**< packet type/version */
+ pj_uint16_t pt:7; /**< payload type */
+ pj_uint16_t m:1; /**< marker bit */
+#endif
+ pj_uint16_t seq; /**< sequence number */
+ pj_uint32_t ts; /**< timestamp */
+ pj_uint32_t ssrc; /**< synchronization source */
+};
+#pragma pack()
+
+/**
+ * @see pjmedia_rtp_hdr
+ */
+typedef struct pjmedia_rtp_hdr pjmedia_rtp_hdr;
+
+
+/**
+ * RTP extendsion header.
+ */
+struct pjmedia_rtp_ext_hdr
+{
+ pj_uint16_t profile_data; /**< Profile data. */
+ pj_uint16_t length; /**< Length. */
+};
+
+/**
+ * @see pjmedia_rtp_ext_hdr
+ */
+typedef struct pjmedia_rtp_ext_hdr pjmedia_rtp_ext_hdr;
+
+
+#pragma pack(1)
+
+/**
+ * Declaration for DTMF telephony-events (RFC2833).
+ */
+struct pjmedia_rtp_dtmf_event
+{
+ pj_uint8_t event; /**< Event type ID. */
+ pj_uint8_t e_vol; /**< Event volume. */
+ pj_uint16_t duration; /**< Event duration. */
+};
+
+/**
+ * @see pjmedia_rtp_dtmf_event
+ */
+typedef struct pjmedia_rtp_dtmf_event pjmedia_rtp_dtmf_event;
+
+#pragma pack()
+
+
+/**
+ * A generic sequence number management, used by both RTP and RTCP.
+ */
+struct pjmedia_rtp_seq_session
+{
+ pj_uint16_t max_seq; /**< Highest sequence number heard */
+ pj_uint32_t cycles; /**< Shifted count of seq number cycles */
+ pj_uint32_t base_seq; /**< Base seq number */
+ pj_uint32_t bad_seq; /**< Last 'bad' seq number + 1 */
+ pj_uint32_t probation; /**< Sequ. packets till source is valid */
+};
+
+/**
+ * @see pjmedia_rtp_seq_session
+ */
+typedef struct pjmedia_rtp_seq_session pjmedia_rtp_seq_session;
+
+
+/**
+ * RTP session descriptor.
+ */
+struct pjmedia_rtp_session
+{
+ pjmedia_rtp_hdr out_hdr; /**< Saved hdr for outgoing pkts. */
+ pjmedia_rtp_seq_session seq_ctrl; /**< Sequence number management. */
+ pj_uint16_t out_pt; /**< Default outgoing payload type. */
+ pj_uint32_t out_extseq; /**< Outgoing extended seq #. */
+ pj_uint32_t peer_ssrc; /**< Peer SSRC. */
+ pj_uint32_t received; /**< Number of received packets. */
+};
+
+/**
+ * @see pjmedia_rtp_session
+ */
+typedef struct pjmedia_rtp_session pjmedia_rtp_session;
+
+
+/**
+ * This structure is used to receive additional information about the
+ * state of incoming RTP packet.
+ */
+struct pjmedia_rtp_status
+{
+ union {
+ struct flag {
+ int bad:1; /**< General flag to indicate that sequence is
+ bad, and application should not process
+ this packet. More information will be given
+ in other flags. */
+ int badpt:1; /**< Bad payload type. */
+ int badssrc:1; /**< Bad SSRC */
+ int dup:1; /**< Indicates duplicate packet */
+ int outorder:1; /**< Indicates out of order packet */
+ int probation:1;/**< Indicates that session is in probation
+ until more packets are received. */
+ int restart:1; /**< Indicates that sequence number has made
+ a large jump, and internal base sequence
+ number has been adjusted. */
+ } flag; /**< Status flags. */
+
+ pj_uint16_t value; /**< Status value, to conveniently address all
+ flags. */
+
+ } status; /**< Status information union. */
+
+ pj_uint16_t diff; /**< Sequence number difference from previous
+ packet. Normally the value should be 1.
+ Value greater than one may indicate packet
+ loss. If packet with lower sequence is
+ received, the value will be set to zero.
+ If base sequence has been restarted, the
+ value will be one. */
+};
+
+
+/**
+ * RTP session settings.
+ */
+typedef struct pjmedia_rtp_session_setting
+{
+ pj_uint8_t flags; /**< Bitmask flags to specify whether such
+ field is set. Bitmask contents are:
+ (bit #0 is LSB)
+ bit #0: default payload type
+ bit #1: sender SSRC
+ bit #2: sequence
+ bit #3: timestamp */
+ int default_pt; /**< Default payload type. */
+ pj_uint32_t sender_ssrc; /**< Sender SSRC. */
+ pj_uint16_t seq; /**< Sequence. */
+ pj_uint32_t ts; /**< Timestamp. */
+} pjmedia_rtp_session_setting;
+
+
+/**
+ * @see pjmedia_rtp_status
+ */
+typedef struct pjmedia_rtp_status pjmedia_rtp_status;
+
+
+/**
+ * This function will initialize the RTP session according to given parameters.
+ *
+ * @param ses The session.
+ * @param default_pt Default payload type.
+ * @param sender_ssrc SSRC used for outgoing packets, in host byte order.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses,
+ int default_pt,
+ pj_uint32_t sender_ssrc );
+
+/**
+ * This function will initialize the RTP session according to given parameters
+ * defined in RTP session settings.
+ *
+ * @param ses The session.
+ * @param settings RTP session settings.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_session_init2(
+ pjmedia_rtp_session *ses,
+ pjmedia_rtp_session_setting settings);
+
+
+/**
+ * Create the RTP header based on arguments and current state of the RTP
+ * session.
+ *
+ * @param ses The session.
+ * @param pt Payload type.
+ * @param m Marker flag.
+ * @param payload_len Payload length in bytes.
+ * @param ts_len Timestamp length.
+ * @param rtphdr Upon return will point to RTP packet header.
+ * @param hdrlen Upon return will indicate the size of RTP packet header
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_encode_rtp( pjmedia_rtp_session *ses,
+ int pt, int m,
+ int payload_len, int ts_len,
+ const void **rtphdr,
+ int *hdrlen );
+
+/**
+ * This function decodes incoming packet into RTP header and payload.
+ * The decode function is guaranteed to point the payload to the correct
+ * position regardless of any options present in the RTP packet.
+ *
+ * Note that this function does not modify the returned RTP header to
+ * host byte order.
+ *
+ * @param ses The session.
+ * @param pkt The received RTP packet.
+ * @param pkt_len The length of the packet.
+ * @param hdr Upon return will point to the location of the RTP
+ * header inside the packet. Note that the RTP header
+ * will be given back as is, meaning that the fields
+ * will be in network byte order.
+ * @param payload Upon return will point to the location of the
+ * payload inside the packet.
+ * @param payloadlen Upon return will indicate the size of the payload.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_decode_rtp( pjmedia_rtp_session *ses,
+ const void *pkt, int pkt_len,
+ const pjmedia_rtp_hdr **hdr,
+ const void **payload,
+ unsigned *payloadlen);
+
+/**
+ * Call this function everytime an RTP packet is received to check whether
+ * the packet can be received and to let the RTP session performs its internal
+ * calculations.
+ *
+ * @param ses The session.
+ * @param hdr The RTP header of the incoming packet. The header must
+ * be given with fields in network byte order.
+ * @param seq_st Optional structure to receive the status of the RTP packet
+ * processing.
+ */
+PJ_DECL(void) pjmedia_rtp_session_update( pjmedia_rtp_session *ses,
+ const pjmedia_rtp_hdr *hdr,
+ pjmedia_rtp_status *seq_st);
+
+
+/**
+ * Call this function everytime an RTP packet is received to check whether
+ * the packet can be received and to let the RTP session performs its internal
+ * calculations.
+ *
+ * @param ses The session.
+ * @param hdr The RTP header of the incoming packet. The header must
+ * be given with fields in network byte order.
+ * @param seq_st Optional structure to receive the status of the RTP packet
+ * processing.
+ * @param check_pt Flag to indicate whether payload type needs to be validate.
+ *
+ * @see pjmedia_rtp_session_update()
+ */
+PJ_DECL(void) pjmedia_rtp_session_update2(pjmedia_rtp_session *ses,
+ const pjmedia_rtp_hdr *hdr,
+ pjmedia_rtp_status *seq_st,
+ pj_bool_t check_pt);
+
+
+/*
+ * INTERNAL:
+ */
+
+/**
+ * Internal function for creating sequence number control, shared by RTCP
+ * implementation.
+ *
+ * @param seq_ctrl The sequence control instance.
+ * @param seq Sequence number to initialize.
+ */
+void pjmedia_rtp_seq_init(pjmedia_rtp_seq_session *seq_ctrl,
+ pj_uint16_t seq);
+
+
+/**
+ * Internal function update sequence control, shared by RTCP implementation.
+ *
+ * @param seq_ctrl The sequence control instance.
+ * @param seq Sequence number to update.
+ * @param seq_status Optional structure to receive additional information
+ * about the packet.
+ */
+void pjmedia_rtp_seq_update( pjmedia_rtp_seq_session *seq_ctrl,
+ pj_uint16_t seq,
+ pjmedia_rtp_status *seq_status);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_RTP_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp.h
new file mode 100644
index 0000000..e49fc36
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp.h
@@ -0,0 +1,674 @@
+/* $Id: sdp.h 2995 2009-11-09 05:18:12Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_SDP_H__
+#define __PJMEDIA_SDP_H__
+
+/**
+ * @file sdp.h
+ * @brief SDP header file.
+ */
+#include <pjmedia/types.h>
+
+
+/**
+ * @defgroup PJMEDIA_SDP SDP Parsing and Data Structure
+ * @ingroup PJMEDIA_SESSION
+ * @brief SDP data structure representation and parsing
+ * @{
+ *
+ * The basic SDP session descriptor and elements are described in header
+ * file <b><pjmedia/sdp.h></b>. This file contains declaration for
+ * SDP session descriptor and SDP media descriptor, along with their
+ * attributes. This file also declares functions to parse SDP message.
+ */
+
+
+PJ_BEGIN_DECL
+
+/**
+ * The PJMEDIA_MAX_SDP_FMT macro defines maximum format in a media line.
+ */
+#ifndef PJMEDIA_MAX_SDP_FMT
+# define PJMEDIA_MAX_SDP_FMT 32
+#endif
+
+/**
+ * The PJMEDIA_MAX_SDP_ATTR macro defines maximum SDP attributes in media and
+ * session descriptor.
+ */
+#ifndef PJMEDIA_MAX_SDP_ATTR
+# define PJMEDIA_MAX_SDP_ATTR (PJMEDIA_MAX_SDP_FMT*2 + 4)
+#endif
+
+/**
+ * The PJMEDIA_MAX_SDP_MEDIA macro defines maximum SDP media lines in a
+ * SDP session descriptor.
+ */
+#ifndef PJMEDIA_MAX_SDP_MEDIA
+# define PJMEDIA_MAX_SDP_MEDIA 16
+#endif
+
+
+/* **************************************************************************
+ * SDP ATTRIBUTES
+ ***************************************************************************
+ */
+
+/**
+ * Generic representation of attribute.
+ */
+struct pjmedia_sdp_attr
+{
+ pj_str_t name; /**< Attribute name. */
+ pj_str_t value; /**< Attribute value. */
+};
+
+/**
+ * @see pjmedia_sdp_attr
+ */
+typedef struct pjmedia_sdp_attr pjmedia_sdp_attr;
+
+
+/**
+ * Create SDP attribute.
+ *
+ * @param pool Pool to create the attribute.
+ * @param name Attribute name.
+ * @param value Optional attribute value.
+ *
+ * @return The new SDP attribute.
+ */
+PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_create(pj_pool_t *pool,
+ const char *name,
+ const pj_str_t *value);
+
+/**
+ * Clone attribute
+ *
+ * @param pool Pool to be used.
+ * @param attr The attribute to clone.
+ *
+ * @return New attribute as cloned from the attribute.
+ */
+PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_clone(pj_pool_t *pool,
+ const pjmedia_sdp_attr*attr);
+
+/**
+ * Find the first attribute with the specified type.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param name Attribute name to find.
+ * @param fmt Optional string to indicate which payload format
+ * to find for \a rtpmap and \a fmt attributes. For other
+ * types of attributes, the value should be NULL.
+ *
+ * @return The specified attribute, or NULL if it can't be found.
+ *
+ * @see pjmedia_sdp_attr_find2, pjmedia_sdp_media_find_attr,
+ * pjmedia_sdp_media_find_attr2
+ */
+PJ_DECL(pjmedia_sdp_attr*)
+pjmedia_sdp_attr_find(unsigned count,
+ pjmedia_sdp_attr *const attr_array[],
+ const pj_str_t *name, const pj_str_t *fmt);
+
+/**
+ * Find the first attribute with the specified type.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param name Attribute name to find.
+ * @param fmt Optional string to indicate which payload format
+ * to find for \a rtpmap and \a fmt attributes. For other
+ * types of attributes, the value should be NULL.
+ *
+ * @return The specified attribute, or NULL if it can't be found.
+ *
+ * @see pjmedia_sdp_attr_find, pjmedia_sdp_media_find_attr,
+ * pjmedia_sdp_media_find_attr2
+ */
+PJ_DECL(pjmedia_sdp_attr*)
+pjmedia_sdp_attr_find2(unsigned count,
+ pjmedia_sdp_attr *const attr_array[],
+ const char *name, const pj_str_t *fmt);
+
+/**
+ * Add a new attribute to array of attributes.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param attr The attribute to add.
+ *
+ * @return PJ_SUCCESS or the error code.
+ *
+ * @see pjmedia_sdp_media_add_attr
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_add(unsigned *count,
+ pjmedia_sdp_attr *attr_array[],
+ pjmedia_sdp_attr *attr);
+
+/**
+ * Remove all attributes with the specified name in array of attributes.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param name Attribute name to find.
+ *
+ * @return Number of attributes removed.
+ *
+ * @see pjmedia_sdp_media_remove_all_attr
+ */
+PJ_DECL(unsigned) pjmedia_sdp_attr_remove_all(unsigned *count,
+ pjmedia_sdp_attr *attr_array[],
+ const char *name);
+
+
+/**
+ * Remove the specified attribute from the attribute array.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param attr The attribute instance to remove.
+ *
+ * @return PJ_SUCCESS when attribute has been removed, or
+ * PJ_ENOTFOUND when the attribute can not be found.
+ *
+ * @see pjmedia_sdp_media_remove_attr
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_remove(unsigned *count,
+ pjmedia_sdp_attr *attr_array[],
+ pjmedia_sdp_attr *attr);
+
+
+/**
+ * This structure declares SDP \a rtpmap attribute.
+ */
+struct pjmedia_sdp_rtpmap
+{
+ pj_str_t pt; /**< Payload type. */
+ pj_str_t enc_name; /**< Encoding name. */
+ unsigned clock_rate; /**< Clock rate. */
+ pj_str_t param; /**< Parameter. */
+};
+
+/**
+ * @see pjmedia_sdp_rtpmap
+ */
+typedef struct pjmedia_sdp_rtpmap pjmedia_sdp_rtpmap;
+
+
+/**
+ * Convert generic attribute to SDP \a rtpmap. This function allocates
+ * a new attribute and call #pjmedia_sdp_attr_get_rtpmap().
+ *
+ * @param pool Pool used to create the rtpmap attribute.
+ * @param attr Generic attribute to be converted to rtpmap, which
+ * name must be "rtpmap".
+ * @param p_rtpmap Pointer to receive SDP rtpmap attribute.
+ *
+ * @return PJ_SUCCESS if the attribute can be successfully
+ * converted to \a rtpmap type.
+ *
+ * @see pjmedia_sdp_attr_get_rtpmap
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_to_rtpmap(pj_pool_t *pool,
+ const pjmedia_sdp_attr *attr,
+ pjmedia_sdp_rtpmap **p_rtpmap);
+
+
+/**
+ * Get the rtpmap representation of the same SDP attribute.
+ *
+ * @param attr Generic attribute to be converted to rtpmap, which
+ * name must be "rtpmap".
+ * @param rtpmap SDP \a rtpmap attribute to be initialized.
+ *
+ * @return PJ_SUCCESS if the attribute can be successfully
+ * converted to \a rtpmap attribute.
+ *
+ * @see pjmedia_sdp_attr_to_rtpmap
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_rtpmap(const pjmedia_sdp_attr *attr,
+ pjmedia_sdp_rtpmap *rtpmap);
+
+
+/**
+ * Convert \a rtpmap attribute to generic attribute.
+ *
+ * @param pool Pool to be used.
+ * @param rtpmap The \a rtpmap attribute.
+ * @param p_attr Pointer to receive the generic SDP attribute.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_rtpmap_to_attr( pj_pool_t *pool,
+ const pjmedia_sdp_rtpmap *rtpmap,
+ pjmedia_sdp_attr **p_attr);
+
+
+/**
+ * This structure describes SDP \a fmtp attribute.
+ */
+struct pjmedia_sdp_fmtp
+{
+ pj_str_t fmt; /**< Format type. */
+ pj_str_t fmt_param; /**< Format specific parameter. */
+};
+
+
+/**
+ * @see pjmedia_sdp_fmtp
+ */
+typedef struct pjmedia_sdp_fmtp pjmedia_sdp_fmtp;
+
+
+
+/**
+ * Get the fmtp representation of the same SDP attribute.
+ *
+ * @param attr Generic attribute to be converted to fmtp, which
+ * name must be "fmtp".
+ * @param fmtp SDP fmtp attribute to be initialized.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_fmtp(const pjmedia_sdp_attr *attr,
+ pjmedia_sdp_fmtp *fmtp);
+
+
+/**
+ * This structure describes SDP \a rtcp attribute.
+ */
+typedef struct pjmedia_sdp_rtcp_attr
+{
+ unsigned port; /**< RTCP port number. */
+ pj_str_t net_type; /**< Optional network type. */
+ pj_str_t addr_type; /**< Optional address type. */
+ pj_str_t addr; /**< Optional address. */
+} pjmedia_sdp_rtcp_attr;
+
+
+/**
+ * Parse a generic SDP attribute to get SDP rtcp attribute values.
+ *
+ * @param attr Generic attribute to be converted to rtcp, which
+ * name must be "rtcp".
+ * @param rtcp SDP rtcp attribute to be initialized.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_rtcp(const pjmedia_sdp_attr *attr,
+ pjmedia_sdp_rtcp_attr *rtcp);
+
+
+/**
+ * Create a=rtcp attribute.
+ *
+ * @param pool Pool to create the attribute.
+ * @param a Socket address.
+ *
+ * @return SDP RTCP attribute.
+ */
+PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_create_rtcp(pj_pool_t *pool,
+ const pj_sockaddr *a);
+
+
+/* **************************************************************************
+ * SDP CONNECTION INFO
+ ****************************************************************************
+ */
+
+/**
+ * This structure describes SDP connection info ("c=" line).
+ */
+struct pjmedia_sdp_conn
+{
+ pj_str_t net_type; /**< Network type ("IN"). */
+ pj_str_t addr_type; /**< Address type ("IP4", "IP6"). */
+ pj_str_t addr; /**< The address. */
+};
+
+
+/**
+ * @see pjmedia_sdp_conn
+ */
+typedef struct pjmedia_sdp_conn pjmedia_sdp_conn;
+
+
+/**
+ * Clone connection info.
+ *
+ * @param pool Pool to allocate memory for the new connection info.
+ * @param rhs The connection into to clone.
+ *
+ * @return The new connection info.
+ */
+PJ_DECL(pjmedia_sdp_conn*) pjmedia_sdp_conn_clone(pj_pool_t *pool,
+ const pjmedia_sdp_conn *rhs);
+
+
+
+/* **************************************************************************
+ * SDP MEDIA INFO/LINE
+ ****************************************************************************
+ */
+
+/**
+ * This structure describes SDP media descriptor. A SDP media descriptor
+ * starts with "m=" line and contains the media attributes and optional
+ * connection line.
+ */
+struct pjmedia_sdp_media
+{
+ /** Media descriptor line ("m=" line) */
+ struct
+ {
+ pj_str_t media; /**< Media type ("audio", "video") */
+ pj_uint16_t port; /**< Port number. */
+ unsigned port_count; /**< Port count, used only when >2 */
+ pj_str_t transport; /**< Transport ("RTP/AVP") */
+ unsigned fmt_count; /**< Number of formats. */
+ pj_str_t fmt[PJMEDIA_MAX_SDP_FMT]; /**< Media formats. */
+ } desc;
+
+ pjmedia_sdp_conn *conn; /**< Optional connection info. */
+ unsigned attr_count; /**< Number of attributes. */
+ pjmedia_sdp_attr*attr[PJMEDIA_MAX_SDP_ATTR]; /**< Attributes. */
+
+};
+
+
+/**
+ * @see pjmedia_sdp_media
+ */
+typedef struct pjmedia_sdp_media pjmedia_sdp_media;
+
+
+/**
+ * Clone SDP media description.
+ *
+ * @param pool Pool to allocate memory for the new media description.
+ * @param rhs The media descriptin to clone.
+ *
+ * @return New media description.
+ */
+PJ_DECL(pjmedia_sdp_media*)
+pjmedia_sdp_media_clone( pj_pool_t *pool,
+ const pjmedia_sdp_media *rhs);
+
+/**
+ * Find the first occurence of the specified attribute name in the media
+ * descriptor. Optionally the format may be specified.
+ *
+ * @param m The SDP media description.
+ * @param name Attribute name to find.
+ * @param fmt Optional payload type to match in the
+ * attribute list, when the attribute is \a rtpmap
+ * or \a fmtp. For other types of SDP attributes, this
+ * value should be NULL.
+ *
+ * @return The first instance of the specified attribute or NULL.
+ */
+PJ_DECL(pjmedia_sdp_attr*)
+pjmedia_sdp_media_find_attr(const pjmedia_sdp_media *m,
+ const pj_str_t *name, const pj_str_t *fmt);
+
+
+/**
+ * Find the first occurence of the specified attribute name in the SDP media
+ * descriptor. Optionally the format may be specified.
+ *
+ * @param m The SDP media description.
+ * @param name Attribute name to find.
+ * @param fmt Optional payload type to match in the
+ * attribute list, when the attribute is \a rtpmap
+ * or \a fmtp. For other types of SDP attributes, this
+ * value should be NULL.
+ *
+ * @return The first instance of the specified attribute or NULL.
+ */
+PJ_DECL(pjmedia_sdp_attr*)
+pjmedia_sdp_media_find_attr2(const pjmedia_sdp_media *m,
+ const char *name, const pj_str_t *fmt);
+
+/**
+ * Add new attribute to the media descriptor.
+ *
+ * @param m The SDP media description.
+ * @param attr Attribute to add.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_media_add_attr(pjmedia_sdp_media *m,
+ pjmedia_sdp_attr *attr);
+
+/**
+ * Remove all attributes with the specified name from the SDP media
+ * descriptor.
+ *
+ * @param m The SDP media description.
+ * @param name Attribute name to remove.
+ *
+ * @return The number of attributes removed.
+ */
+PJ_DECL(unsigned)
+pjmedia_sdp_media_remove_all_attr(pjmedia_sdp_media *m,
+ const char *name);
+
+
+/**
+ * Remove the occurence of the specified attribute from the SDP media
+ * descriptor.
+ *
+ * @param m The SDP media descriptor.
+ * @param attr The attribute to find and remove.
+ *
+ * @return PJ_SUCCESS if the attribute can be found and has
+ * been removed from the array.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_media_remove_attr(pjmedia_sdp_media *m,
+ pjmedia_sdp_attr *attr);
+
+
+/**
+ * Compare two SDP media for equality.
+ *
+ * @param sd1 The first SDP media to compare.
+ * @param sd2 The second SDP media to compare.
+ * @param option Comparison option, which should be zero for now.
+ *
+ * @return PJ_SUCCESS when both SDP medias are equal, or the
+ * appropriate status code describing which part of
+ * the descriptors that are not equal.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_media_cmp(const pjmedia_sdp_media *sd1,
+ const pjmedia_sdp_media *sd2,
+ unsigned option);
+
+
+/**
+ * Compare two media transports for compatibility.
+ *
+ * @param t1 The first media transport to compare.
+ * @param t2 The second media transport to compare.
+ *
+ * @return PJ_SUCCESS when both media transports are compatible,
+ * otherwise returns PJMEDIA_SDP_ETPORTNOTEQUAL.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_transport_cmp(const pj_str_t *t1,
+ const pj_str_t *t2);
+
+
+/**
+ * Deactivate SDP media.
+ *
+ * @param m The SDP media to deactivate.
+ *
+ * @return PJ_SUCCESS when SDP media successfully deactivated,
+ * otherwise appropriate status code returned.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_media_deactivate(pj_pool_t *pool,
+ pjmedia_sdp_media *m);
+
+
+/* **************************************************************************
+ * SDP SESSION DESCRIPTION
+ ****************************************************************************
+ */
+
+
+/**
+ * This structure describes SDP session description. A SDP session descriptor
+ * contains complete information about a session, and normally is exchanged
+ * with remote media peer using signaling protocol such as SIP.
+ */
+struct pjmedia_sdp_session
+{
+ /** Session origin (o= line) */
+ struct
+ {
+ pj_str_t user; /**< User */
+ pj_uint32_t id; /**< Session ID */
+ pj_uint32_t version; /**< Session version */
+ pj_str_t net_type; /**< Network type ("IN") */
+ pj_str_t addr_type; /**< Address type ("IP4", "IP6") */
+ pj_str_t addr; /**< The address. */
+ } origin;
+
+ pj_str_t name; /**< Subject line (s=) */
+ pjmedia_sdp_conn *conn; /**< Connection line (c=) */
+
+ /** Session time (t= line) */
+ struct
+ {
+ pj_uint32_t start; /**< Start time. */
+ pj_uint32_t stop; /**< Stop time. */
+ } time;
+
+ unsigned attr_count; /**< Number of attributes. */
+ pjmedia_sdp_attr *attr[PJMEDIA_MAX_SDP_ATTR]; /**< Attributes array. */
+
+ unsigned media_count; /**< Number of media. */
+ pjmedia_sdp_media *media[PJMEDIA_MAX_SDP_MEDIA]; /**< Media array. */
+
+};
+
+/**
+ * @see pjmedia_sdp_session
+ */
+typedef struct pjmedia_sdp_session pjmedia_sdp_session;
+
+
+
+/**
+ * Parse SDP message.
+ *
+ * @param pool The pool to allocate SDP session description.
+ * @param buf The message buffer.
+ * @param len The length of the message.
+ * @param p_sdp Pointer to receive the SDP session descriptor.
+ *
+ * @return PJ_SUCCESS if message was successfully parsed into
+ * SDP session descriptor.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool,
+ char *buf, pj_size_t len,
+ pjmedia_sdp_session **p_sdp );
+
+/**
+ * Print SDP description to a buffer.
+ *
+ * @param sdp The SDP session description.
+ * @param buf The buffer.
+ * @param size The buffer length.
+ *
+ * @return the length printed, or -1 if the buffer is too
+ * short.
+ */
+PJ_DECL(int) pjmedia_sdp_print( const pjmedia_sdp_session *sdp,
+ char *buf, pj_size_t size);
+
+
+/**
+ * Perform semantic validation for the specified SDP session descriptor.
+ * This function perform validation beyond just syntactic verification,
+ * such as to verify the value of network type and address type, check
+ * the connection line, and verify that \a rtpmap attribute is present
+ * when dynamic payload type is used.
+ *
+ * @param sdp The SDP session descriptor to validate.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_validate(const pjmedia_sdp_session *sdp);
+
+
+/**
+ * Clone SDP session descriptor.
+ *
+ * @param pool The pool used to clone the session.
+ * @param sdp The SDP session to clone.
+ *
+ * @return New SDP session.
+ */
+PJ_DECL(pjmedia_sdp_session*)
+pjmedia_sdp_session_clone( pj_pool_t *pool,
+ const pjmedia_sdp_session *sdp);
+
+
+/**
+ * Compare two SDP session for equality.
+ *
+ * @param sd1 The first SDP session to compare.
+ * @param sd2 The second SDP session to compare.
+ * @param option Must be zero for now.
+ *
+ * @return PJ_SUCCESS when both SDPs are equal, or otherwise
+ * the status code indicates which part of the session
+ * descriptors are not equal.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_session_cmp(const pjmedia_sdp_session *sd1,
+ const pjmedia_sdp_session *sd2,
+ unsigned option);
+
+
+/**
+ * Add new attribute to the session descriptor.
+ *
+ * @param s The SDP session description.
+ * @param attr Attribute to add.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_session_add_attr(pjmedia_sdp_session *m,
+ pjmedia_sdp_attr *attr);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_SDP_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp_neg.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp_neg.h
new file mode 100644
index 0000000..caa4906
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp_neg.h
@@ -0,0 +1,674 @@
+/* $Id: sdp_neg.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_SDP_NEG_H__
+#define __PJMEDIA_SDP_NEG_H__
+
+
+/**
+ * @file sdp_neg.h
+ * @brief SDP negotiator header file.
+ */
+/**
+ * @defgroup PJMEDIA_SDP_NEG SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)
+ * @ingroup PJMEDIA_SESSION
+ * @brief SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)
+ * @{
+ *
+ * The header file <b><pjmedia/sdp_neg.h></b> contains the declaration
+ * of SDP offer and answer negotiator. SDP offer and answer model is described
+ * in RFC 3264 <b>"An Offer/Answer Model with Session Description Protocol
+ * (SDP)"</b>.
+ *
+ * The SDP negotiator is represented with opaque type \a pjmedia_sdp_neg.
+ * This structure contains negotiation state and several SDP session
+ * descriptors currently being used in the negotiation.
+ *
+ *
+ * \section sdpneg_state_dia SDP Negotiator State Diagram
+ *
+ * The following diagram describes the state transition diagram of the
+ * SDP negotiator.
+ *
+ * <pre>
+ *
+ * modify_local_offer()
+ * create_w_local_offer() +-------------+ send_local_offer()
+ * ----------------------->| LOCAL_OFFER |<-----------------------
+ * | +-------------+______ |
+ * | | \______ cancel() |
+ * | set_remote_answer() | \______ |
+ * | V \ |
+ * +--+---+ +-----------+ negotiate() +-~----+
+ * | NULL | | WAIT_NEGO |-------------------->| DONE |
+ * +------+ +-----------+ +------+
+ * | A |
+ * | set_local_answer() | |
+ * | | |
+ * | +--------------+ set_remote_offer() |
+ * ----------------------->| REMOTE_OFFER |<----------------------
+ * create_w_remote_offer() +--------------+
+ *
+ * </pre>
+ *
+ *
+ *
+ * \section sdpneg_offer_answer SDP Offer/Answer Model with Negotiator
+ *
+ * \subsection sdpneg_create_offer Creating Initial Offer
+ *
+ * Application creates an offer by manualy building the SDP session descriptor
+ * (pjmedia_sdp_session), or request PJMEDIA endpoint (pjmedia_endpt) to
+ * create SDP session descriptor based on capabilities that present in the
+ * endpoint by calling #pjmedia_endpt_create_sdp().
+ *
+ * Application then creates SDP negotiator instance by calling
+ * #pjmedia_sdp_neg_create_w_local_offer(), passing the SDP offer in the
+ * function arguments. The SDP negotiator keeps a copy of current local offer,
+ * and update its state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER.
+ *
+ * Application can then send the initial SDP offer that it creates to
+ * remote peer using signaling protocol such as SIP.
+ *
+ *
+ * \subsection sdpneg_subseq_offer Generating Subsequent Offer
+ *
+ * The negotiator can only create subsequent offer after it has finished
+ * the negotiation process of previous offer/answer session (i.e. the
+ * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).
+ *
+ * If any previous negotiation process was successfull (i.e. the return
+ * value of #pjmedia_sdp_neg_negotiate() was PJ_SUCCESS), the negotiator
+ * keeps both active local and active remote SDP.
+ *
+ * If application does not want send modified offer, it can just send
+ * the active local SDP as the offer. In this case, application calls
+ * #pjmedia_sdp_neg_send_local_offer() to get the active local SDP.
+ *
+ * If application wants to modify it's local offer, it MUST inform
+ * the negotiator about the modified SDP by calling
+ * #pjmedia_sdp_neg_modify_local_offer().
+ *
+ * In both cases, the negotiator will internally create a copy of the offer,
+ * and move it's state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it
+ * waits until application passes the remote answer.
+ *
+ *
+ * \subsection sdpneg_receive_offer Receiving Initial Offer
+ *
+ * Application receives an offer in the incoming request from remote to
+ * establish multimedia session, such as incoming INVITE message with SDP
+ * body.
+ *
+ * Initially, when the initial offer is received, application creates the
+ * SDP negotiator by calling #pjmedia_sdp_neg_create_w_remote_offer(),
+ * specifying the remote SDP offer in one of the argument.
+ *
+ * At this stage, application may or may not ready to create an answer.
+ * For example, a SIP B2BUA needs to make outgoing call and receive SDP
+ * from the outgoing call leg in order to create a SDP answer to the
+ * incoming call leg.
+ *
+ * If application is not ready to create an answer, it passes NULL as
+ * the local SDP when it calls #pjmedia_sdp_neg_create_w_remote_offer().
+ *
+ * The section @ref sdpneg_create_answer describes the case when
+ * application is ready to create a SDP answer.
+ *
+ *
+ * \subsection sdpneg_subseq_offer Receiving Subsequent Offer
+ *
+ * Application passes subsequent SDP offer received from remote by
+ * calling #pjmedia_sdp_neg_set_remote_offer().
+ *
+ * The negotiator can only receive subsequent offer after it has finished
+ * the negotiation process of previous offer/answer session (i.e. the
+ * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).
+ *
+ *
+ * \subsection sdpneg_recv_answer Receiving SDP Answer
+ *
+ * When application receives SDP answer from remote, it informs the
+ * negotiator by calling #pjmedia_sdp_neg_set_remote_answer(). The
+ * negotiator validates the answer (#pjmedia_sdp_validate()), and if
+ * succeeds, it moves it's state to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO.
+ *
+ * Application then instruct the negotiator to negotiate the remote
+ * answer by calling #pjmedia_sdp_neg_negotiate(). The purpose of
+ * this negotiation is to verify remote answer, and update the initial
+ * offer according to the answer. For example, the initial offer may
+ * specify that a stream is \a sendrecv, while the answer specifies
+ * that remote stream is \a inactive. In this case, the negotiator
+ * will update the stream in the local active media as \a inactive
+ * too.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will
+ * keep the updated local answer and remote answer internally. These two
+ * SDPs are called active local SDP and active remote SDP, as it describes
+ * currently active session.
+ *
+ * Application can retrieve the active local SDP by calling
+ * #pjmedia_sdp_neg_get_active_local(), and active remote SDP by calling
+ * #pjmedia_sdp_neg_get_active_remote().
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),
+ * it WILL NOT update its active local and active remote SDP.
+ *
+ * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(),
+ * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ *
+ * \subsection sdpneg_cancel_offer Cancelling an Offer
+ *
+ * In other case, after an offer is generated (negotiator state is in
+ * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER), the answer may not be received, and
+ * application wants the negotiator to reset itself to its previous state.
+ * Consider this example:
+ *
+ * - media has been established, and negotiator state is
+ * PJMEDIA_SDP_NEG_STATE_DONE.
+ * - application generates a new offer for re-INVITE, so in this case
+ * it would either call #pjmedia_sdp_neg_send_local_offer() or
+ * #pjmedia_sdp_neg_modify_local_offer()
+ * - the negotiator state moves to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER
+ * - the re-INVITE was rejected with an error
+ *
+ * Since an answer is not received, it is necessary to reset the negotiator
+ * state back to PJMEDIA_SDP_NEG_STATE_DONE so that the negotiator can
+ * create or receive new offer.
+ *
+ * This can be accomplished by calling #pjmedia_sdp_neg_cancel_offer(),
+ * to reset the negotiator state back to PJMEDIA_SDP_NEG_STATE_DONE. In
+ * this case, both active local and active remote will not be modified.
+ *
+ * \subsection sdpneg_create_answer Generating SDP Answer
+ *
+ * After remote offer has been set in the negotiator, application can
+ * request the SDP negotiator to generate appropriate answer based on local
+ * capability.
+ *
+ * To do this, first the application MUST have an SDP describing its local
+ * capabilities. This SDP can be built manually, or application can generate
+ * SDP to describe local media endpoint capability by calling
+ * #pjmedia_endpt_create_sdp(). When the application is a SIP B2BUA,
+ * application can treat the SDP received from the outgoing call leg as if
+ * it was it's local capability.
+ *
+ * The local SDP session descriptor DOES NOT have to match the SDP offer.
+ * For example, it can have more or less media lines than the offer, or
+ * their order may be different than the offer. The negotiator is capable
+ * to match and reorder local SDP according to remote offer, and create
+ * an answer that is suitable for the offer.
+ *
+ * After local SDP capability has been acquired, application can create
+ * a SDP answer.
+ *
+ * If application does not already have the negotiator instance, it creates
+ * one by calling #pjmedia_sdp_neg_create_w_remote_offer(), specifying
+ * both remote SDP offer and local SDP as the arguments. The SDP negotiator
+ * validates both remote and local SDP by calling #pjmedia_sdp_validate(),
+ * and if both SDPs are valid, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the
+ * offer and answer.
+ *
+ * If application already has the negotiator instance, it sets the local
+ * SDP in the negotiator by calling #pjmedia_sdp_neg_set_local_answer().
+ * The SDP negotiator then validates local SDP (#pjmedia_sdp_validate() ),
+ * and if it is valid, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the
+ * offer and answer.
+ *
+ * After the SDP negotiator state has moved to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,
+ * application calls #pjmedia_sdp_neg_negotiate() to instruct the SDP
+ * negotiator to negotiate both offer and answer. This function returns
+ * PJ_SUCCESS if an answer can be generated AND at least one media stream
+ * is active in the session.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will
+ * keep the remote offer and local answer internally. These two SDPs are
+ * called active local SDP and active remote SDP, as it describes currently
+ * active session.
+ *
+ * Application can retrieve the active local SDP by calling
+ * #pjmedia_sdp_neg_get_active_local(), and send this SDP to remote as the
+ * SDP answer.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),
+ * it WILL NOT update its active local and active remote SDP.
+ *
+ * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(),
+ * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ *
+ */
+
+#include <pjmedia/sdp.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * This enumeration describes SDP negotiation state.
+ */
+enum pjmedia_sdp_neg_state
+{
+ /**
+ * This is the state of SDP negoator before it is initialized.
+ */
+ PJMEDIA_SDP_NEG_STATE_NULL,
+
+ /**
+ * This state occurs when SDP negotiator has sent our offer to remote and
+ * it is waiting for answer.
+ */
+ PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+
+ /**
+ * This state occurs when SDP negotiator has received offer from remote
+ * and currently waiting for local answer.
+ */
+ PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER,
+
+ /**
+ * This state occurs when an offer (either local or remote) has been
+ * provided with answer. The SDP negotiator is ready to negotiate both
+ * session descriptors. Application can call #pjmedia_sdp_neg_negotiate()
+ * immediately to begin negotiation process.
+ */
+ PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,
+
+ /**
+ * This state occurs when SDP negotiation has completed, either
+ * successfully or not.
+ */
+ PJMEDIA_SDP_NEG_STATE_DONE
+};
+
+
+/**
+ * @see pjmedia_sdp_neg_state
+ */
+typedef enum pjmedia_sdp_neg_state pjmedia_sdp_neg_state;
+
+
+/**
+ * Opaque declaration of SDP negotiator.
+ */
+typedef struct pjmedia_sdp_neg pjmedia_sdp_neg;
+
+
+/**
+ * Get the state string description of the specified state.
+ *
+ * @param state Negotiator state.
+ *
+ * @return String description of the state.
+ */
+PJ_DECL(const char*) pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state);
+
+
+/**
+ * Create the SDP negotiator with local offer. The SDP negotiator then
+ * will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER state, where it waits
+ * until it receives answer from remote. When SDP answer from remote is
+ * received, application must call #pjmedia_sdp_neg_set_remote_answer().
+ *
+ * After calling this function, application should send the local SDP offer
+ * to remote party using signaling protocol such as SIP and wait for SDP
+ * answer.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param local The initial local capability.
+ * @param p_neg Pointer to receive the negotiator instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_create_w_local_offer( pj_pool_t *pool,
+ const pjmedia_sdp_session *local,
+ pjmedia_sdp_neg **p_neg);
+
+/**
+ * Initialize the SDP negotiator with remote offer, and optionally
+ * specify the initial local capability, if known. Application normally
+ * calls this function when it receives initial offer from remote.
+ *
+ * If local media capability is specified, this capability will be set as
+ * initial local capability of the negotiator, and after this function is
+ * called, the SDP negotiator state will move to state
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and the negotiation function can be
+ * called.
+ *
+ * If local SDP is not specified, the negotiator will not have initial local
+ * capability, and after this function is called the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER state. Application MUST supply
+ * local answer later with #pjmedia_sdp_neg_set_local_answer(), before
+ * calling the negotiation function.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param initial Optional initial local capability.
+ * @param remote The remote offer.
+ * @param p_neg Pointer to receive the negotiator instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool,
+ const pjmedia_sdp_session *initial,
+ const pjmedia_sdp_session *remote,
+ pjmedia_sdp_neg **p_neg);
+
+/**
+ * This specifies the behavior of the SDP negotiator when responding to an
+ * offer, whether it should rather use the codec preference as set by
+ * remote, or should it rather use the codec preference as specified by
+ * local endpoint.
+ *
+ * For example, suppose incoming call has codec order "8 0 3", while
+ * local codec order is "3 0 8". If remote codec order is preferable,
+ * the selected codec will be 8, while if local codec order is preferable,
+ * the selected codec will be 3.
+ *
+ * By default, the value in PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER will
+ * be used.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param prefer_remote If non-zero, the negotiator will use the codec
+ * order as specified in remote offer. If zero, it
+ * will prefer to use the local codec order.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_prefer_remote_codec_order(pjmedia_sdp_neg *neg,
+ pj_bool_t prefer_remote);
+
+
+/**
+ * Get SDP negotiator state.
+ *
+ * @param neg The SDP negotiator instance.
+ *
+ * @return The negotiator state.
+ */
+PJ_DECL(pjmedia_sdp_neg_state)
+pjmedia_sdp_neg_get_state( pjmedia_sdp_neg *neg );
+
+/**
+ * Get the currently active local SDP. Application can only call this
+ * function after negotiation has been done, or otherwise there won't be
+ * active SDPs. Calling this function will not change the state of the
+ * negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param local Pointer to receive the local active SDP.
+ *
+ * @return PJ_SUCCESS if local active SDP is present.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_active_local( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **local);
+
+/**
+ * Get the currently active remote SDP. Application can only call this
+ * function after negotiation has been done, or otherwise there won't be
+ * active SDPs. Calling this function will not change the state of the
+ * negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param remote Pointer to receive the remote active SDP.
+ *
+ * @return PJ_SUCCESS if remote active SDP is present.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_active_remote( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **remote);
+
+
+/**
+ * Determine whether remote sent answer (as opposed to offer) on the
+ * last negotiation. This function can only be called in state
+ * PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ * @param neg The SDP negotiator instance.
+ *
+ * @return Non-zero if it was remote who sent answer,
+ * otherwise zero if it was local who supplied
+ * answer.
+ */
+PJ_DECL(pj_bool_t)
+pjmedia_sdp_neg_was_answer_remote(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Get the current remote SDP offer or answer. Application can only
+ * call this function in state PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER or
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be remote
+ * SDP offer/answer. Calling this function will not change the state
+ * of the negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param remote Pointer to receive the current remote offer or
+ * answer.
+ *
+ * @return PJ_SUCCESS if the negotiator currently has
+ * remote offer or answer.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_neg_remote( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **remote);
+
+
+/**
+ * Get the current local SDP offer or answer. Application can only
+ * call this function in state PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER or
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be local
+ * SDP offer/answer. Calling this function will not change the state
+ * of the negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param local Pointer to receive the current local offer or
+ * answer.
+ *
+ * @return PJ_SUCCESS if the negotiator currently has
+ * local offer or answer.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_neg_local( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **local);
+
+/**
+ * Modify local session with a new SDP and treat this as a new offer.
+ * This function can only be called in state PJMEDIA_SDP_NEG_STATE_DONE.
+ * After calling this function, application can send the SDP as offer
+ * to remote party, using signaling protocol such as SIP.
+ * The negotiator state will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+ * where it waits for SDP answer from remote.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param local The new local SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *local);
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state.
+ * Application calls this function to retrieve currently active
+ * local SDP, and then send the SDP to remote as an offer. The negotiator
+ * state will then move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it waits
+ * for SDP answer from remote.
+ *
+ * When SDP answer has been received from remote, application must call
+ * #pjmedia_sdp_neg_set_remote_answer().
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param offer Pointer to receive active local SDP to be
+ * offered to remote.
+ *
+ * @return PJ_SUCCESS if local offer can be created.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_send_local_offer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **offer);
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER
+ * state, i.e. after application calls #pjmedia_sdp_neg_send_local_offer()
+ * function. Application calls this function when it receives SDP answer
+ * from remote. After this function is called, the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the
+ * negotiation function #pjmedia_sdp_neg_negotiate().
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param remote The remote answer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_remote_answer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *remote);
+
+
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state.
+ * Application calls this function when it receives SDP offer from remote.
+ * After this function is called, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER, and application MUST call the
+ * #pjmedia_sdp_neg_set_local_answer() to set local answer before it can
+ * call the negotiation function.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param remote The remote offer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_remote_offer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *remote);
+
+
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER
+ * state, i.e. after application calls #pjmedia_sdp_neg_set_remote_offer()
+ * function. After this function is called, the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the
+ * negotiation function #pjmedia_sdp_neg_negotiate().
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param local Optional local answer. If negotiator has initial
+ * local capability, application can specify NULL on
+ * this argument; in this case, the negotiator will
+ * create answer by by negotiating remote offer with
+ * initial local capability. If negotiator doesn't have
+ * initial local capability, application MUST specify
+ * local answer here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_local_answer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *local);
+
+
+/**
+ * Call this function when the negotiator is in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO
+ * state to see if it was local who is answering the offer (instead of
+ * remote).
+ *
+ * @param neg The negotiator.
+ *
+ * @return PJ_TRUE if it is local is answering an offer, PJ_FALSE
+ * if remote has answered local offer.
+ */
+PJ_DECL(pj_bool_t) pjmedia_sdp_neg_has_local_answer(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Cancel previously sent offer, and move negotiator state back to
+ * previous stable state (PJMEDIA_SDP_NEG_STATE_DONE). The negotiator
+ * must be in PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER state.
+ *
+ * @param neg The negotiator.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Negotiate local and remote answer. Before calling this function, the
+ * SDP negotiator must be in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO state.
+ * After calling this function, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_DONE regardless whether the negotiation has
+ * been successfull or not.
+ *
+ * If the negotiation succeeds (i.e. the return value is PJ_SUCCESS),
+ * the active local and remote SDP will be replaced with the new SDP
+ * from the negotiation process.
+ *
+ * If the negotiation fails, the active local and remote SDP will not
+ * change.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param allow_asym Should be zero.
+ *
+ * @return PJ_SUCCESS when there is at least one media
+ * is actuve common in both offer and answer, or
+ * failure code when negotiation has failed.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ pj_bool_t allow_asym);
+
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_SDP_NEG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/session.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/session.h
new file mode 100644
index 0000000..fcbb955
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/session.h
@@ -0,0 +1,404 @@
+/* $Id: session.h 2844 2009-07-29 12:14:21Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_SESSION_H__
+#define __PJMEDIA_SESSION_H__
+
+
+/**
+ * @file session.h
+ * @brief Media Session.
+ */
+
+#include <pjmedia/endpoint.h>
+#include <pjmedia/stream.h>
+#include <pjmedia/sdp.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_SESSION Media Sessions
+ * @brief Management of media sessions
+ * @{
+ *
+ * A media session represents multimedia communication between two
+ * parties. A media session represents the multimedia session that
+ * is described by SDP session descriptor. A media session consists
+ * of one or more media streams (pjmedia_stream), where each stream
+ * represents one media line (m= line) in SDP.
+ *
+ * This module provides functions to create and manage multimedia
+ * sessions.
+ *
+ * Application creates the media session by calling #pjmedia_session_create(),
+ * normally after it has completed negotiating both SDP offer and answer.
+ * The session creation function creates the media session (including
+ * media streams) based on the content of local and remote SDP.
+ */
+
+
+/**
+ * Session info, retrieved from a session by calling
+ * #pjmedia_session_get_info().
+ */
+struct pjmedia_session_info
+{
+ /** Number of streams. */
+ unsigned stream_cnt;
+
+ /** Individual stream info. */
+ pjmedia_stream_info stream_info[PJMEDIA_MAX_SDP_MEDIA];
+};
+
+
+/**
+ * Opaque declaration of media session.
+ */
+typedef struct pjmedia_session pjmedia_session;
+
+
+/**
+ * @see pjmedia_session_info.
+ */
+typedef struct pjmedia_session_info pjmedia_session_info;
+
+
+/**
+ * This function will initialize the session info based on information
+ * in both SDP session descriptors. The remaining information will be
+ * taken from default codec parameters. If socket info array is specified,
+ * the socket will be copied to the session info as well.
+ *
+ * @param pool Pool to allocate memory.
+ * @param endpt Pjmedia endpoint.
+ * @param max_streams Maximum number of stream infos to be created.
+ * @param si Session info structure to be initialized.
+ * @param local Local SDP session descriptor.
+ * @param remote Remote SDP session descriptor.
+ *
+ * @return PJ_SUCCESS if stream info is successfully initialized.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_info_from_sdp( pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ unsigned max_streams,
+ pjmedia_session_info *si,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote);
+
+
+/**
+ * This function will initialize the stream info based on information
+ * in both SDP session descriptors for the specified stream index.
+ * The remaining information will be taken from default codec parameters.
+ * If socket info array is specified, the socket will be copied to the
+ * session info as well.
+ *
+ * @param si Stream info structure to be initialized.
+ * @param pool Pool to allocate memory.
+ * @param endpt PJMEDIA endpoint instance.
+ * @param local Local SDP session descriptor.
+ * @param remote Remote SDP session descriptor.
+ * @param stream_idx Media stream index in the session descriptor.
+ *
+ * @return PJ_SUCCESS if stream info is successfully initialized.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_stream_info_from_sdp( pjmedia_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote,
+ unsigned stream_idx);
+
+/**
+ * Create media session based on the local and remote SDP. After the session
+ * has been created, application normally would want to get the media port
+ * interface of each streams, by calling #pjmedia_session_get_port(). The
+ * media port interface exports put_frame() and get_frame() function, used
+ * to transmit and receive media frames from the stream.
+ *
+ * Without application calling put_frame() and get_frame(), there will be
+ * no media frames transmitted or received by the session.
+ *
+ * @param endpt The PJMEDIA endpoint instance.
+ * @param si Session info containing stream count and array of
+ * stream info. The stream count indicates how many
+ * streams to be created in the session.
+ * @param transports Array of media stream transports, with
+ * sufficient number of elements (one for each stream).
+ * @param user_data Arbitrary user data to be kept in the session.
+ * @param p_session Pointer to receive the media session.
+ *
+ * @return PJ_SUCCESS if media session can be created
+ * successfully.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_create( pjmedia_endpt *endpt,
+ const pjmedia_session_info *si,
+ pjmedia_transport *transports[],
+ void *user_data,
+ pjmedia_session **p_session );
+
+
+/**
+ * Get media session info of the session.
+ *
+ * @param session The session which info is being queried.
+ * @param info Pointer to receive session info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_info( pjmedia_session *session,
+ pjmedia_session_info *info );
+
+/**
+ * Get user data of the session.
+ *
+ * @param session The session being queried.
+ *
+ * @return User data of the session.
+ */
+PJ_DECL(void*) pjmedia_session_get_user_data( pjmedia_session *session);
+
+
+/**
+ * Activate all streams in media session for the specified direction.
+ * Application only needs to call this function if it previously paused
+ * the session.
+ *
+ * @param session The media session.
+ * @param dir The direction to activate.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_resume(pjmedia_session *session,
+ pjmedia_dir dir);
+
+
+/**
+ * Suspend receipt and transmission of all streams in media session
+ * for the specified direction.
+ *
+ * @param session The media session.
+ * @param dir The media direction to suspend.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_pause(pjmedia_session *session,
+ pjmedia_dir dir);
+
+/**
+ * Suspend receipt and transmission of individual stream in media session
+ * for the specified direction.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param dir The media direction to pause.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_pause_stream( pjmedia_session *session,
+ unsigned index,
+ pjmedia_dir dir);
+
+/**
+ * Activate individual stream in media session for the specified direction.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param dir The media direction to activate.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_resume_stream(pjmedia_session *session,
+ unsigned index,
+ pjmedia_dir dir);
+
+/**
+ * Enumerate media streams in the session.
+ *
+ * @param session The media session.
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the number will be filled
+ * with number of streams in the session.
+ * @param strm_info Array of stream info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_enum_streams( const pjmedia_session *session,
+ unsigned *count,
+ pjmedia_stream_info strm_info[]);
+
+
+/**
+ * Get the media port interface of the specified stream. The media port
+ * interface declares put_frame() and get_frame() function, which is the
+ * only way for application to transmit and receive media frames from the
+ * stream.
+ *
+ * @param session The media session.
+ * @param index Stream index.
+ * @param p_port Pointer to receive the media port interface for
+ * the specified stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_port( pjmedia_session *session,
+ unsigned index,
+ pjmedia_port **p_port);
+
+
+/**
+ * Get session statistics. The stream statistic shows various
+ * indicators such as packet count, packet lost, jitter, delay, etc.
+ * See also #pjmedia_session_get_stream_stat_jbuf()
+ *
+ * @param session The media session.
+ * @param index Stream index.
+ * @param stat Stream statistic.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_stream_stat(pjmedia_session *session,
+ unsigned index,
+ pjmedia_rtcp_stat *stat);
+
+
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+/**
+ * Get extended session statistics. The extended statistic shows reports
+ * from RTCP XR, such as per interval statistics summary (packet count,
+ * packet lost, jitter, etc), VoIP metrics (delay, quality, etc)
+ *
+ * @param session The media session.
+ * @param index Stream index.
+ * @param stat_xr Stream extended statistics.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_stream_stat_xr(
+ pjmedia_session *session,
+ unsigned index,
+ pjmedia_rtcp_xr_stat *stat_xr);
+#endif
+
+
+/**
+ * Get current jitter buffer state for the specified stream.
+ * See also #pjmedia_session_get_stream_stat()
+ *
+ * @param session The media session.
+ * @param index Stream index.
+ * @param state Jitter buffer state.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_stream_stat_jbuf(
+ pjmedia_session *session,
+ unsigned index,
+ pjmedia_jb_state *state);
+
+/**
+ * Dial DTMF digit to the stream, using RFC 2833 mechanism.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param ascii_digits String of ASCII digits (i.e. 0-9*##A-B).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_dial_dtmf( pjmedia_session *session,
+ unsigned index,
+ const pj_str_t *ascii_digits );
+
+
+/**
+ * Check if the specified stream has received DTMF digits.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ *
+ * @return Non-zero (PJ_TRUE) if the stream has DTMF digits.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_check_dtmf( pjmedia_session *session,
+ unsigned index);
+
+
+/**
+ * Retrieve DTMF digits from the specified stream.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param ascii_digits Buffer to receive the digits. The length of this
+ * buffer is indicated in the "size" argument.
+ * @param size On input, contains the maximum digits to be copied
+ * to the buffer.
+ * On output, it contains the actual digits that has
+ * been copied to the buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_dtmf( pjmedia_session *session,
+ unsigned index,
+ char *ascii_digits,
+ unsigned *size );
+
+/**
+ * Set callback to be called upon receiving DTMF digits. If callback is
+ * registered, the stream will not buffer incoming DTMF but rather call
+ * the callback as soon as DTMF digit is received completely.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param cb Callback to be called upon receiving DTMF digits.
+ * The DTMF digits will be given to the callback as
+ * ASCII digits.
+ * @param user_data User data to be returned back when the callback
+ * is called.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_set_dtmf_callback(pjmedia_session *session,
+ unsigned index,
+ void (*cb)(pjmedia_stream*,
+ void *user_data,
+ int digit),
+ void *user_data);
+
+/**
+ * Destroy media session.
+ *
+ * @param session The media session.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_destroy(pjmedia_session *session);
+
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_SESSION_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/silencedet.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/silencedet.h
new file mode 100644
index 0000000..7ffe0a7
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/silencedet.h
@@ -0,0 +1,200 @@
+/* $Id: silencedet.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_SILENCE_DET_H__
+#define __PJMEDIA_SILENCE_DET_H__
+
+
+/**
+ * @file silencedet.h
+ * @brief Adaptive silence detector.
+ */
+#include <pjmedia/types.h>
+
+
+/**
+ * @defgroup PJMEDIA_SILENCEDET Adaptive Silence Detection
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Adaptive Silence Detector
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for silence detector.
+ */
+typedef struct pjmedia_silence_det pjmedia_silence_det;
+
+
+
+/**
+ * Create voice activity detector with default settings. The default settings
+ * are set to adaptive silence detection with the default threshold.
+ *
+ * @param pool Pool for allocating the structure.
+ * @param clock_rate Clock rate.
+ * @param samples_per_frame Number of samples per frame. The clock_rate and
+ * samples_per_frame is only used to calculate the
+ * frame time, from which some timing parameters
+ * are calculated from.
+ * @param p_sd Pointer to receive the silence detector instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ pjmedia_silence_det **p_sd );
+
+
+/**
+ * Set silence detector name to identify the particular silence detector
+ * instance in the log.
+ *
+ * @param sd The silence detector.
+ * @param name Name.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_set_name(pjmedia_silence_det *sd,
+ const char *name);
+
+
+/**
+ * Set the sd to operate in fixed threshold mode. With fixed threshold mode,
+ * the threshold will not be changed adaptively.
+ *
+ * @param sd The silence detector
+ * @param threshold The silence threshold, or -1 to use default
+ * threshold.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd,
+ int threshold );
+
+/**
+ * Set the sd to operate in adaptive mode. This is the default mode
+ * when the silence detector is created.
+ *
+ * @param sd The silence detector
+ * @param threshold Initial threshold to be set, or -1 to use default
+ * threshold.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_set_adaptive(pjmedia_silence_det *sd,
+ int threshold);
+
+/**
+ * Set other silence detector parameters.
+ *
+ * @param sd The silence detector
+ * @param before_silence Minimum duration of silence (in msec) before
+ * silence is reported. If -1 is specified, then
+ * the default value will be used. The default is
+ * 400 msec.
+ * @param recalc_time1 The interval (in msec) to recalculate threshold
+ * in non-silence condition when adaptive silence
+ * detection is set. If -1 is specified, then the
+ * default value will be used. The default is 4000
+ * (msec).
+ * @param recalc_time2 The interval (in msec) to recalculate threshold
+ * in silence condition when adaptive silence detection
+ * is set. If -1 is specified, then the default value
+ * will be used. The default value is 2000 (msec).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_set_params( pjmedia_silence_det *sd,
+ int before_silence,
+ int recalc_time1,
+ int recalc_time2);
+
+
+/**
+ * Disable the silence detector.
+ *
+ * @param sd The silence detector
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd );
+
+
+/**
+ * Perform voice activity detection on the given input samples. This
+ * function uses #pjmedia_calc_avg_signal() and #pjmedia_silence_det_apply()
+ * for its calculation.
+ *
+ * @param sd The silence detector instance.
+ * @param samples Pointer to 16-bit PCM input samples.
+ * @param count Number of samples in the input.
+ * @param p_level Optional pointer to receive average signal level
+ * of the input samples.
+ *
+ * @return Non zero if signal is silence.
+ */
+PJ_DECL(pj_bool_t) pjmedia_silence_det_detect( pjmedia_silence_det *sd,
+ const pj_int16_t samples[],
+ pj_size_t count,
+ pj_int32_t *p_level);
+
+
+/**
+ * Calculate average signal level for the given samples.
+ *
+ * @param samples Pointer to 16-bit PCM samples.
+ * @param count Number of samples in the input.
+ *
+ * @return The average signal level, which simply is total level
+ * divided by number of samples.
+ */
+PJ_DECL(pj_int32_t) pjmedia_calc_avg_signal( const pj_int16_t samples[],
+ pj_size_t count );
+
+
+
+/**
+ * Perform voice activity detection, given the specified average signal
+ * level.
+ *
+ * @param sd The silence detector instance.
+ * @param level Signal level.
+ *
+ * @return Non zero if signal is silence.
+ */
+PJ_DECL(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd,
+ pj_uint32_t level);
+
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_SILENCE_DET_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound.h
new file mode 100644
index 0000000..7ef818c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound.h
@@ -0,0 +1,336 @@
+/* $Id: sound.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_SOUND_H__
+#define __PJMEDIA_SOUND_H__
+
+
+/**
+ * @file sound.h
+ * @brief Legacy sound device API
+ */
+#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia/types.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMED_SND Portable Sound Hardware Abstraction
+ * @ingroup PJMED_SND_PORT
+ * @brief PJMEDIA abstraction for sound device hardware
+ * @{
+ *
+ * <strong>Warning: this sound device API has been deprecated
+ * and replaced by PJMEDIA Audio Device API. Please see
+ * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more
+ * information.</strong>
+ *
+ * This section describes lower level abstraction for sound device
+ * hardware. Application normally uses the higher layer @ref
+ * PJMED_SND_PORT abstraction since it works seamlessly with
+ * @ref PJMEDIA_PORT.
+ *
+ * The sound hardware abstraction basically runs <b>asychronously</b>,
+ * and application must register callbacks to be called to receive/
+ * supply audio frames from/to the sound hardware.
+ *
+ * A full duplex sound stream (created with #pjmedia_snd_open())
+ * requires application to supply two callbacks:
+ * - <b><tt>rec_cb</tt></b> callback to be called when it has finished
+ * capturing one media frame, and
+ * - <b><tt>play_cb</tt></b> callback to be called when it needs media
+ * frame to be played to the sound playback hardware.
+ *
+ * Half duplex sound stream (created with #pjmedia_snd_open_rec() or
+ * #pjmedia_snd_open_player()) will only need one of the callback to
+ * be specified.
+ *
+ * After sound stream is created, application need to call
+ * #pjmedia_snd_stream_start() to start capturing/playing back media
+ * frames from/to the sound device.
+ */
+
+/** Opaque declaration for pjmedia_snd_stream. */
+typedef struct pjmedia_snd_stream pjmedia_snd_stream;
+
+/**
+ * Device information structure returned by #pjmedia_snd_get_dev_info.
+ */
+typedef struct pjmedia_snd_dev_info
+{
+ char name[64]; /**< Device name. */
+ unsigned input_count; /**< Max number of input channels. */
+ unsigned output_count; /**< Max number of output channels. */
+ unsigned default_samples_per_sec;/**< Default sampling rate. */
+} pjmedia_snd_dev_info;
+
+/**
+ * Stream information, can be retrieved from a live stream by calling
+ * #pjmedia_snd_stream_get_info().
+ */
+typedef struct pjmedia_snd_stream_info
+{
+ pjmedia_dir dir; /**< Stream direction. */
+ int play_id; /**< Playback dev id, or -1 for rec only*/
+ int rec_id; /**< Capture dev id, or -1 for play only*/
+ unsigned clock_rate; /**< Actual clock rate. */
+ unsigned channel_count; /**< Number of channels. */
+ unsigned samples_per_frame; /**< Samples per frame. */
+ unsigned bits_per_sample; /**< Bits per sample. */
+ unsigned rec_latency; /**< Record latency, in samples. */
+ unsigned play_latency; /**< Playback latency, in samples. */
+} pjmedia_snd_stream_info;
+
+/**
+ * This callback is called by player stream when it needs additional data
+ * to be played by the device. Application must fill in the whole of output
+ * buffer with sound samples.
+ *
+ * @param user_data User data associated with the stream.
+ * @param timestamp Timestamp, in samples.
+ * @param output Buffer to be filled out by application.
+ * @param size The size requested in bytes, which will be equal to
+ * the size of one whole packet.
+ *
+ * @return Non-zero to stop the stream.
+ */
+typedef pj_status_t (*pjmedia_snd_play_cb)(/* in */ void *user_data,
+ /* in */ pj_uint32_t timestamp,
+ /* out */ void *output,
+ /* out */ unsigned size);
+
+/**
+ * This callback is called by recorder stream when it has captured the whole
+ * packet worth of audio samples.
+ *
+ * @param user_data User data associated with the stream.
+ * @param timestamp Timestamp, in samples.
+ * @param output Buffer containing the captured audio samples.
+ * @param size The size of the data in the buffer, in bytes.
+ *
+ * @return Non-zero to stop the stream.
+ */
+typedef pj_status_t (*pjmedia_snd_rec_cb)(/* in */ void *user_data,
+ /* in */ pj_uint32_t timestamp,
+ /* in */ void *input,
+ /* in*/ unsigned size);
+
+/**
+ * Init the sound library.
+ *
+ * @param factory The sound factory.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory);
+
+
+/**
+ * Get the number of devices detected by the library.
+ *
+ * @return Number of devices.
+ */
+PJ_DECL(int) pjmedia_snd_get_dev_count(void);
+
+
+/**
+ * Get device info.
+ *
+ * @param index The index of the device, which should be in the range
+ * from zero to #pjmedia_snd_get_dev_count - 1.
+ */
+PJ_DECL(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index);
+
+
+/**
+ * Set sound device latency, this function must be called before sound device
+ * opened, or otherwise default latency setting will be used, @see
+ * PJMEDIA_SND_DEFAULT_REC_LATENCY & PJMEDIA_SND_DEFAULT_PLAY_LATENCY.
+ *
+ * Choosing latency value is not straightforward, it should accomodate both
+ * minimum latency and stability. Lower latency tends to cause sound device
+ * less reliable (producing audio dropouts) on CPU load disturbance. Moreover,
+ * the best latency setting may vary based on many aspects, e.g: sound card,
+ * CPU, OS, kernel, etc.
+ *
+ * @param input_latency The latency of input device, in ms, set to 0
+ * for default PJMEDIA_SND_DEFAULT_REC_LATENCY.
+ * @param output_latency The latency of output device, in ms, set to 0
+ * for default PJMEDIA_SND_DEFAULT_PLAY_LATENCY.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_set_latency(unsigned input_latency,
+ unsigned output_latency);
+
+
+/**
+ * Create sound stream for both capturing audio and audio playback, from the
+ * same device. This is the recommended way to create simultaneous recorder
+ * and player streams (instead of creating separate capture and playback
+ * streams), because it works on backends that does not allow
+ * a device to be opened more than once.
+ *
+ * @param rec_id Device index for recorder/capture stream, or
+ * -1 to use the first capable device.
+ * @param play_id Device index for playback stream, or -1 to use
+ * the first capable device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param rec_cb Callback to handle captured audio samples.
+ * @param play_cb Callback to be called when the sound player needs
+ * more audio samples to play.
+ * @param user_data User data to be associated with the stream.
+ * @param p_snd_strm Pointer to receive the stream instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_open(int rec_id,
+ int play_id,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pjmedia_snd_rec_cb rec_cb,
+ pjmedia_snd_play_cb play_cb,
+ void *user_data,
+ pjmedia_snd_stream **p_snd_strm);
+
+
+/**
+ * Create a unidirectional audio stream for capturing audio samples from
+ * the sound device.
+ *
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param rec_cb Callback to handle captured audio samples.
+ * @param user_data User data to be associated with the stream.
+ * @param p_snd_strm Pointer to receive the stream instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_open_rec( int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pjmedia_snd_rec_cb rec_cb,
+ void *user_data,
+ pjmedia_snd_stream **p_snd_strm);
+
+/**
+ * Create a unidirectional audio stream for playing audio samples to the
+ * sound device.
+ *
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param play_cb Callback to be called when the sound player needs
+ * more audio samples to play.
+ * @param user_data User data to be associated with the stream.
+ * @param p_snd_strm Pointer to receive the stream instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_open_player( int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pjmedia_snd_play_cb play_cb,
+ void *user_data,
+ pjmedia_snd_stream **p_snd_strm );
+
+
+/**
+ * Get information about live stream.
+ *
+ * @param strm The stream to be queried.
+ * @param pi Pointer to stream information to be filled up with
+ * information about the stream.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_stream_get_info(pjmedia_snd_stream *strm,
+ pjmedia_snd_stream_info *pi);
+
+
+/**
+ * Start the stream.
+ *
+ * @param stream The recorder or player stream.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream);
+
+/**
+ * Stop the stream.
+ *
+ * @param stream The recorder or player stream.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_stream_stop(pjmedia_snd_stream *stream);
+
+/**
+ * Destroy the stream.
+ *
+ * @param stream The recorder of player stream.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream);
+
+/**
+ * Deinitialize sound library.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_deinit(void);
+
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_SOUND_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound_port.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound_port.h
new file mode 100644
index 0000000..56cec34
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound_port.h
@@ -0,0 +1,296 @@
+/* $Id: sound_port.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_SOUND_PORT_H__
+#define __PJMEDIA_SOUND_PORT_H__
+
+/**
+ * @file sound_port.h
+ * @brief Media port connection abstraction to sound device.
+ */
+#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia/port.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMED_SND_PORT Sound Device Port
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Media Port Connection Abstraction to the Sound Device
+ @{
+
+ As explained in @ref PJMED_SND, the sound hardware abstraction provides
+ some callbacks for its user:
+ - it calls <b><tt>rec_cb</tt></b> callback when it has finished capturing
+ one media frame, and
+ - it calls <b><tt>play_cb</tt></b> when it needs media frame to be
+ played to the sound playback hardware.
+
+ The @ref PJMED_SND_PORT (the object being explained here) add a
+ thin wrapper to the hardware abstraction:
+ - it will call downstream port's <tt>put_frame()</tt>
+ when <b><tt>rec_cb()</tt></b> is called (i.e. when the sound hardware
+ has finished capturing frame), and
+ - it will call downstream port's <tt>get_frame()</tt> when
+ <b><tt>play_cb()</tt></b> is called (i.e. every time the
+ sound hardware needs more frames to be played to the playback hardware).
+
+ This simple abstraction enables media to flow automatically (and
+ in timely manner) from the downstream media port to the sound device.
+ In other words, the sound device port supplies media clock to
+ the ports. The media clock concept is explained in @ref PJMEDIA_PORT_CLOCK
+ section.
+
+ Application registers downstream port to the sound device port by
+ calling #pjmedia_snd_port_connect();
+
+ */
+
+/**
+ * This opaque type describes sound device port connection.
+ * Sound device port is not a media port, but it is used to connect media
+ * port to the sound device.
+ */
+typedef struct pjmedia_snd_port pjmedia_snd_port;
+
+
+/**
+ * Create bidirectional sound port for both capturing and playback of
+ * audio samples.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param rec_id Device index for recorder/capture stream, or
+ * -1 to use the first capable device.
+ * @param play_id Device index for playback stream, or -1 to use
+ * the first capable device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param options Options flag, currently must be zero.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool,
+ int rec_id,
+ int play_id,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_snd_port **p_port);
+
+/**
+ * Create unidirectional sound device port for capturing audio streams from
+ * the sound device with the specified parameters.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param options Options flag, currently must be zero.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_create_rec(pj_pool_t *pool,
+ int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_snd_port **p_port);
+
+/**
+ * Create unidirectional sound device port for playing audio streams with the
+ * specified parameters.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param options Options flag, currently must be zero.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_create_player(pj_pool_t *pool,
+ int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_snd_port **p_port);
+
+
+/**
+ * Create sound device port according to the specified parameters.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param prm Sound device settings.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool,
+ const pjmedia_aud_param *prm,
+ pjmedia_snd_port **p_port);
+
+
+/**
+ * Destroy sound device port.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port);
+
+
+/**
+ * Retrieve the sound stream associated by this sound device port.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return The sound stream instance.
+ */
+PJ_DECL(pjmedia_aud_stream*) pjmedia_snd_port_get_snd_stream(
+ pjmedia_snd_port *snd_port);
+
+
+/**
+ * Change the echo cancellation settings. The echo cancellation settings
+ * should have been specified when this sound port was created, by setting
+ * the appropriate fields in the pjmedia_aud_param, because not all sound
+ * device implementation supports changing the EC setting once the device
+ * has been opened.
+ *
+ * The behavior of this function depends on whether device or software AEC
+ * is being used. If the device supports AEC, this function will forward
+ * the change request to the device and it will be up to the device whether
+ * to support the request. If software AEC is being used (the software EC
+ * will be used if the device does not support AEC), this function will
+ * change the software EC settings.
+ *
+ * @param snd_port The sound device port.
+ * @param pool Pool to re-create the echo canceller if necessary.
+ * @param tail_ms Maximum echo tail length to be supported, in
+ * miliseconds. If zero is specified, the EC would
+ * be disabled.
+ * @param options The options to be passed to #pjmedia_echo_create().
+ * This is only used if software EC is being used.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_set_ec( pjmedia_snd_port *snd_port,
+ pj_pool_t *pool,
+ unsigned tail_ms,
+ unsigned options);
+
+
+/**
+ * Get current echo canceller tail length, in miliseconds. The tail length
+ * will be zero if EC is not enabled.
+ *
+ * @param snd_port The sound device port.
+ * @param p_length Pointer to receive the tail length.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_get_ec_tail(pjmedia_snd_port *snd_port,
+ unsigned *p_length);
+
+
+/**
+ * Connect a port to the sound device port. If the sound device port has a
+ * sound recorder device, then this will start periodic function call to
+ * the port's put_frame() function. If the sound device has a sound player
+ * device, then this will start periodic function call to the port's
+ * get_frame() function.
+ *
+ * For this version of PJMEDIA, the media port MUST have the same audio
+ * settings as the sound device port, or otherwise the connection will
+ * fail. This means the port MUST have the same clock_rate, channel count,
+ * samples per frame, and bits per sample as the sound device port.
+ *
+ * @param snd_port The sound device port.
+ * @param port The media port to be connected.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_connect(pjmedia_snd_port *snd_port,
+ pjmedia_port *port);
+
+
+/**
+ * Retrieve the port instance currently attached to the sound port, if any.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return The port instance currently attached to the
+ * sound device port, or NULL if there is no port
+ * currently attached to the sound device port.
+ */
+PJ_DECL(pjmedia_port*) pjmedia_snd_port_get_port(pjmedia_snd_port *snd_port);
+
+
+/**
+ * Disconnect currently attached port from the sound device port.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_disconnect(pjmedia_snd_port *snd_port);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_SOUND_PORT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/splitcomb.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/splitcomb.h
new file mode 100644
index 0000000..750cabc
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/splitcomb.h
@@ -0,0 +1,140 @@
+/* $Id: splitcomb.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_SPLITCOMB_H__
+#define __PJMEDIA_SPLITCOMB_H__
+
+
+/**
+ * @file splitcomb.h
+ * @brief Media channel splitter/combiner port.
+ */
+#include <pjmedia/port.h>
+
+
+/**
+ * @addtogroup PJMEDIA_SPLITCOMB Media channel splitter/combiner
+ * @ingroup PJMEDIA_PORT
+ * @brief Split and combine multiple mono-channel media ports into
+ * a single multiple-channels media port
+ * @{
+ *
+ * This section describes media port to split and combine media
+ * channels in the stream.
+ *
+ * A splitter/combiner splits a single stereo/multichannels audio frame into
+ * multiple audio frames to each channel when put_frame() is called,
+ * and combines mono frames from each channel into a stereo/multichannel
+ * frame when get_frame() is called. A common application for the splitter/
+ * combiner is to split frames from stereo to mono and vise versa.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create a media splitter/combiner with the specified parameters.
+ * When the splitter/combiner is created, it creates an instance of
+ * pjmedia_port. This media port represents the stereo/multichannel side
+ * of the splitter/combiner. Application needs to supply the splitter/
+ * combiner with a media port for each audio channels.
+ *
+ * @param pool Pool to allocate memory to create the splitter/
+ * combiner.
+ * @param clock_rate Audio clock rate/sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Bits per sample.
+ * @param options Optional flags.
+ * @param p_splitcomb Pointer to receive the splitter/combiner.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_splitcomb_create(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_splitcomb);
+
+/**
+ * Supply the splitter/combiner with media port for the specified channel
+ * number. The media port will be called at the
+ * same phase as the splitter/combiner; which means that when application
+ * calls get_frame() of the splitter/combiner, it will call get_frame()
+ * for all ports that have the same phase. And similarly for put_frame().
+ *
+ * @param splitcomb The splitter/combiner.
+ * @param ch_num Audio channel starting number (zero based).
+ * @param options Must be zero at the moment.
+ * @param port The media port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_splitcomb_set_channel(pjmedia_port *splitcomb,
+ unsigned ch_num,
+ unsigned options,
+ pjmedia_port *port);
+
+/**
+ * Create a reverse phase media port for the specified channel number.
+ * For channels with reversed phase, when application calls put_frame() to
+ * the splitter/combiner, the splitter/combiner will only put the frame to
+ * a buffer. Later on, when application calls get_frame() on the channel's
+ * media port, it will return the frame that are available in the buffer.
+ * The same process happens when application calls put_frame() to the
+ * channel's media port, it will only put the frame to another buffer, which
+ * will be returned when application calls get_frame() to the splitter's
+ * media port. So this effectively reverse the phase of the media port.
+ *
+ * @param pool The pool to allocate memory for the port and
+ * buffers.
+ * @param splitcomb The splitter/combiner.
+ * @param ch_num Audio channel starting number (zero based).
+ * @param options Normally is zero, but the lower 8-bit of the
+ * options can be used to specify the number of
+ * buffers in the circular buffer. If zero, then
+ * default number will be used (default: 8).
+ * @param p_chport The media port created with reverse phase for
+ * the specified audio channel.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,
+ pjmedia_port *splitcomb,
+ unsigned ch_num,
+ unsigned options,
+ pjmedia_port **p_chport);
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_SPLITCOMB_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stereo.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stereo.h
new file mode 100644
index 0000000..3c7af19
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stereo.h
@@ -0,0 +1,206 @@
+/* $Id: stereo.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_STEREO_H__
+#define __PJMEDIA_STEREO_H__
+
+/**
+ * @file stereo.h
+ * @brief Monochannel and multichannel converter.
+ */
+
+#include <pjmedia/errno.h>
+#include <pjmedia/port.h>
+#include <pjmedia/types.h>
+#include <pj/assert.h>
+
+
+/**
+ * @defgroup PJMEDIA_STEREO Monochannel and multichannel audio frame converter
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Mono - multi-channels audio conversion
+ * @{
+ *
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Multichannel to monochannel conversion mixes samples from all channels
+ * into the monochannel.
+ */
+#define PJMEDIA_STEREO_MIX PJ_TRUE
+
+
+
+/**
+ * Multichannel to monochannel conversion, it has two operation mode specified
+ * by param options, @see pjmedia_stereo_options. This function can work safely
+ * using the same buffer (in place conversion).
+ *
+ * @param mono Output buffer to store the mono frame extracted
+ * from the multichannels frame.
+ * @param multi Input frame containing multichannels audio.
+ * @param channel_count Number of channels in the input frame.
+ * @param samples_per_frame Number of samples in the input frame.
+ * @param mix If the value is PJ_TRUE then the input channels
+ * will be mixed to produce output frame, otherwise
+ * only frame from channel_src will be copied to the
+ * output frame.
+ * @param channel_src When mixing is disabled, the mono output frame
+ * will be copied from this channel number.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_convert_channel_nto1(pj_int16_t mono[],
+ const pj_int16_t multi[],
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ pj_bool_t mix,
+ unsigned channel_src)
+{
+ unsigned i;
+
+ PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame &&
+ channel_src < channel_count, PJ_EINVAL);
+
+ if (mix==PJ_FALSE) {
+ for (i = channel_src; i < samples_per_frame; i += channel_count) {
+ *mono = multi[i];
+ ++mono;
+ }
+ } else {
+ unsigned j;
+ for (i = 0; i < samples_per_frame; i += channel_count) {
+ int tmp = 0;
+ for(j = 0; j < channel_count; ++j)
+ tmp += multi[i+j];
+
+ if (tmp > 32767) tmp = 32767;
+ else if (tmp < -32768) tmp = -32768;
+ *mono = (pj_int16_t) tmp;
+ ++mono;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Monochannel to multichannel conversion, it will just duplicate the samples
+ * from monochannel frame to all channels in the multichannel frame.
+ * This function can work safely using the same buffer (in place conversion)
+ * as long as the buffer is big enough for the multichannel samples.
+ *
+ * @param multi Output buffer to store the multichannels frame
+ * mixed from the mono frame.
+ * @param mono The input monochannel audio frame.
+ * @param channel_count Desired number of channels in the output frame.
+ * @param samples_per_frame Number of samples in the input frame.
+ * @param options Options for conversion, currently must be zero.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_convert_channel_1ton(pj_int16_t multi[],
+ const pj_int16_t mono[],
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned options)
+{
+ const pj_int16_t *src;
+
+ PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);
+
+ PJ_UNUSED_ARG(options);
+
+ src = mono + samples_per_frame - 1;
+ samples_per_frame *= channel_count;
+ while (samples_per_frame) {
+ unsigned i;
+ for (i=1; i<=channel_count; ++i)
+ multi[samples_per_frame-i] = *src;
+ samples_per_frame -= channel_count;
+ --src;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Options for channel converter port. The @pjmedia_stereo_options is also
+ * valid for this port options.
+ */
+enum pjmedia_stereo_port_options
+{
+ /**
+ * Specifies whether this port should not destroy downstream port when
+ * this port is destroyed.
+ */
+ PJMEDIA_STEREO_DONT_DESTROY_DN = 4
+};
+
+
+/**
+ * Create a mono-multi channel converter port. This creates a converter session,
+ * which will adjust the samples of audio frame to a different channel count
+ * when the port's get_frame() and put_frame() is called.
+ *
+ * When the port's get_frame() is called, this port will get a frame from
+ * the downstream port and convert the frame to the target channel count before
+ * returning it to the caller.
+ *
+ * When the port's put_frame() is called, this port will convert the frame
+ * to the downstream port's channel count before giving the frame to the
+ * downstream port.
+ *
+ * @param pool Pool to allocate the structure and buffers.
+ * @param dn_port The downstream port, which channel count is to
+ * be converted to the target channel count.
+ * @param channel_count This port channel count.
+ * @param options Bitmask flags from #pjmedia_stereo_port_options
+ * and also application may add PJMEDIA_STEREO_MIX
+ * to mix channels.
+ * When this flag is zero, the default behavior
+ * is to use simple N-to-1 channel converter and
+ * to destroy downstream port when this port is
+ * destroyed.
+ * @param p_port Pointer to receive the stereo port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool,
+ pjmedia_port *dn_port,
+ unsigned channel_count,
+ unsigned options,
+ pjmedia_port **p_port );
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_STEREO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stream.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stream.h
new file mode 100644
index 0000000..f4c58db
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stream.h
@@ -0,0 +1,354 @@
+/* $Id: stream.h 2844 2009-07-29 12:14:21Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_STREAM_H__
+#define __PJMEDIA_STREAM_H__
+
+
+/**
+ * @file stream.h
+ * @brief Media Stream.
+ */
+
+#include <pjmedia/codec.h>
+#include <pjmedia/endpoint.h>
+#include <pjmedia/jbuf.h>
+#include <pjmedia/port.h>
+#include <pjmedia/rtcp.h>
+#include <pjmedia/transport.h>
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_STRM Streams
+ * @ingroup PJMEDIA_PORT
+ * @brief Communicating with remote peer via the network
+ * @{
+ *
+ * A media stream is a bidirectional multimedia communication between two
+ * endpoints. It corresponds to a media description (m= line) in SDP
+ * session descriptor.
+ *
+ * A media stream consists of two unidirectional channels:
+ * - encoding channel, which transmits unidirectional media to remote, and
+ * - decoding channel, which receives unidirectional media from remote.
+ *
+ * A media stream exports media port interface (see @ref PJMEDIA_PORT)
+ * and application normally uses this interface to interconnect the stream
+ * to other PJMEDIA components.
+ *
+ * A media stream internally manages the following objects:
+ * - an instance of media codec (see @ref PJMEDIA_CODEC),
+ * - an @ref PJMED_JBUF,
+ * - two instances of RTP sessions (#pjmedia_rtp_session, one for each
+ * direction),
+ * - one instance of RTCP session (#pjmedia_rtcp_session),
+ * - and a reference to media transport to send and receive packets
+ * to/from the network (see @ref PJMEDIA_TRANSPORT).
+ *
+ * Streams are created by calling #pjmedia_stream_create(), specifying
+ * #pjmedia_stream_info structure in the parameter. Application can construct
+ * the #pjmedia_stream_info structure manually, or use
+ * #pjmedia_stream_info_from_sdp() or #pjmedia_session_info_from_sdp()
+ * functions to construct the #pjmedia_stream_info from local and remote
+ * SDP session descriptors.
+ *
+ * Application can also use @ref PJMEDIA_SESSION to indirectly create the
+ * streams.
+ */
+
+/**
+ * Opaque declaration for media channel.
+ * Media channel is unidirectional flow of media from sender to
+ * receiver.
+ */
+typedef struct pjmedia_channel pjmedia_channel;
+
+/**
+ * This structure describes media stream information. Each media stream
+ * corresponds to one "m=" line in SDP session descriptor, and it has
+ * its own RTP/RTCP socket pair.
+ */
+struct pjmedia_stream_info
+{
+ pjmedia_type type; /**< Media type (audio, video) */
+ pjmedia_tp_proto proto; /**< Transport protocol (RTP/AVP, etc.) */
+ pjmedia_dir dir; /**< Media direction. */
+ pj_sockaddr rem_addr; /**< Remote RTP address */
+ pj_sockaddr rem_rtcp; /**< Optional remote RTCP address. If
+ sin_family is zero, the RTP address
+ will be calculated from RTP. */
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+ pj_bool_t rtcp_xr_enabled;
+ /**< Specify whether RTCP XR is enabled.*/
+ pj_uint32_t rtcp_xr_interval; /**< RTCP XR interval. */
+ pj_sockaddr rtcp_xr_dest;/**<Additional remote RTCP XR address.
+ This is useful for third-party (e.g:
+ network monitor) to monitor the
+ stream. If sin_family is zero,
+ this will be ignored. */
+#endif
+ pjmedia_codec_info fmt; /**< Incoming codec format info. */
+ pjmedia_codec_param *param; /**< Optional codec param. */
+ unsigned tx_pt; /**< Outgoing codec paylaod type. */
+ unsigned tx_maxptime;/**< Outgoing codec max ptime. */
+ int tx_event_pt;/**< Outgoing pt for telephone-events. */
+ int rx_event_pt;/**< Incoming pt for telephone-events. */
+ pj_uint32_t ssrc; /**< RTP SSRC. */
+ pj_uint32_t rtp_ts; /**< Initial RTP timestamp. */
+ pj_uint16_t rtp_seq; /**< Initial RTP sequence number. */
+ pj_uint8_t rtp_seq_ts_set;
+ /**< Bitmask flags if initial RTP sequence
+ and/or timestamp for sender are set.
+ bit 0/LSB : sequence flag
+ bit 1 : timestamp flag */
+ int jb_init; /**< Jitter buffer init delay in msec.
+ (-1 for default). */
+ int jb_min_pre; /**< Jitter buffer minimum prefetch
+ delay in msec (-1 for default). */
+ int jb_max_pre; /**< Jitter buffer maximum prefetch
+ delay in msec (-1 for default). */
+ int jb_max; /**< Jitter buffer max delay in msec. */
+};
+
+
+/**
+ * @see pjmedia_stream_info.
+ */
+typedef struct pjmedia_stream_info pjmedia_stream_info;
+
+
+
+/**
+ * Create a media stream based on the specified parameter. After the stream
+ * has been created, application normally would want to get the media port
+ * interface of the streams, by calling pjmedia_stream_get_port(). The
+ * media port interface exports put_frame() and get_frame() function, used
+ * to transmit and receive media frames from the stream.
+ *
+ * Without application calling put_frame() and get_frame(), there will be
+ * no media frames transmitted or received by the stream.
+ *
+ * @param endpt Media endpoint.
+ * @param pool Pool to allocate memory for the stream. A large
+ * number of memory may be needed because jitter
+ * buffer needs to preallocate some storage.
+ * @param info Stream information.
+ * @param tp Stream transport instance used to transmit
+ * and receive RTP/RTCP packets to/from the underlying
+ * transport.
+ * @param user_data Arbitrary user data (for future callback feature).
+ * @param p_stream Pointer to receive the media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_create(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pjmedia_stream_info *info,
+ pjmedia_transport *tp,
+ void *user_data,
+ pjmedia_stream **p_stream);
+
+/**
+ * Destroy the media stream.
+ *
+ * @param stream The media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_destroy(pjmedia_stream *stream);
+
+
+/**
+ * Get the media port interface of the stream. The media port interface
+ * declares put_frame() and get_frame() function, which is the only
+ * way for application to transmit and receive media frames from the
+ * stream.
+ *
+ * @param stream The media stream.
+ * @param p_port Pointer to receive the port interface.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_port(pjmedia_stream *stream,
+ pjmedia_port **p_port );
+
+
+/**
+ * Get the media transport object associated with this stream.
+ *
+ * @param st The media stream.
+ *
+ * @return The transport object being used by the stream.
+ */
+PJ_DECL(pjmedia_transport*) pjmedia_stream_get_transport(pjmedia_stream *st);
+
+
+/**
+ * Start the media stream. This will start the appropriate channels
+ * in the media stream, depending on the media direction that was set
+ * when the stream was created.
+ *
+ * @param stream The media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_start(pjmedia_stream *stream);
+
+
+/**
+ * Get the stream statistics. See also
+ * #pjmedia_stream_get_stat_jbuf()
+ *
+ * @param stream The media stream.
+ * @param stat Media stream statistics.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_stat( const pjmedia_stream *stream,
+ pjmedia_rtcp_stat *stat);
+
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+/**
+ * Get the stream extended report statistics (RTCP XR).
+ *
+ * @param stream The media stream.
+ * @param stat Media stream extended report statistics.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_stat_xr( const pjmedia_stream *stream,
+ pjmedia_rtcp_xr_stat *stat);
+#endif
+
+/**
+ * Get current jitter buffer state. See also
+ * #pjmedia_stream_get_stat()
+ *
+ * @param stream The media stream.
+ * @param state Jitter buffer state.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_stat_jbuf(const pjmedia_stream *stream,
+ pjmedia_jb_state *state);
+
+
+/**
+ * Pause the individual channel in the stream.
+ *
+ * @param stream The media channel.
+ * @param dir Which direction to pause.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_pause( pjmedia_stream *stream,
+ pjmedia_dir dir);
+
+/**
+ * Resume the individual channel in the stream.
+ *
+ * @param stream The media channel.
+ * @param dir Which direction to resume.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_resume(pjmedia_stream *stream,
+ pjmedia_dir dir);
+
+/**
+ * Transmit DTMF to this stream. The DTMF will be transmitted uisng
+ * RTP telephone-events as described in RFC 2833. This operation is
+ * only valid for audio stream.
+ *
+ * @param stream The media stream.
+ * @param ascii_digit String containing digits to be sent to remote.
+ * Currently the maximum number of digits are 32.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_dial_dtmf(pjmedia_stream *stream,
+ const pj_str_t *ascii_digit);
+
+
+/**
+ * Check if the stream has incoming DTMF digits in the incoming DTMF
+ * queue. Incoming DTMF digits received via RFC 2833 mechanism are
+ * saved in the incoming digits queue.
+ *
+ * @param stream The media stream.
+ *
+ * @return Non-zero (PJ_TRUE) if the stream has received DTMF
+ * digits in the .
+ */
+PJ_DECL(pj_bool_t) pjmedia_stream_check_dtmf(pjmedia_stream *stream);
+
+
+/**
+ * Retrieve the incoming DTMF digits from the stream, and remove the digits
+ * from stream's DTMF buffer. Note that the digits buffer will not be NULL
+ * terminated.
+ *
+ * @param stream The media stream.
+ * @param ascii_digits Buffer to receive the digits. The length of this
+ * buffer is indicated in the "size" argument.
+ * @param size On input, contains the maximum digits to be copied
+ * to the buffer.
+ * On output, it contains the actual digits that has
+ * been copied to the buffer.
+ *
+ * @return Non-zero (PJ_TRUE) if the stream has received DTMF
+ * digits in the .
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_dtmf( pjmedia_stream *stream,
+ char *ascii_digits,
+ unsigned *size);
+
+
+/**
+ * Set callback to be called upon receiving DTMF digits. If callback is
+ * registered, the stream will not buffer incoming DTMF but rather call
+ * the callback as soon as DTMF digit is received completely.
+ *
+ * @param stream The media stream.
+ * @param cb Callback to be called upon receiving DTMF digits.
+ * The DTMF digits will be given to the callback as
+ * ASCII digits.
+ * @param user_data User data to be returned back when the callback
+ * is called.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
+ void (*cb)(pjmedia_stream*,
+ void *user_data,
+ int digit),
+ void *user_data);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_STREAM_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/symbian_sound_aps.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/symbian_sound_aps.h
new file mode 100644
index 0000000..865ec56
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/symbian_sound_aps.h
@@ -0,0 +1,48 @@
+/* $Id: symbian_sound_aps.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_SYMBIAN_SOUND_APS_H__
+#define __PJMEDIA_SYMBIAN_SOUND_APS_H__
+
+
+/**
+ * @file symbian_sound_aps.h
+ * @brief Sound device wrapper using Audio Proxy Server on
+ * Symbian S60 3rd edition.
+ */
+#include <pjmedia/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * Set audio routing for APS sound device.
+ *
+ * @param stream The sound device stream, the stream should be started
+ * before calling this function.
+ * @param route Audio routing to be set.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_aps_set_route( pjmedia_snd_stream *stream,
+ pjmedia_snd_route route);
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_SYMBIAN_SOUND_APS_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/tonegen.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/tonegen.h
new file mode 100644
index 0000000..3211e66
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/tonegen.h
@@ -0,0 +1,293 @@
+/* $Id: tonegen.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_TONEGEN_PORT_H__
+#define __PJMEDIA_TONEGEN_PORT_H__
+
+/**
+ * @file tonegen.h
+ * @brief Tone (sine, MF, DTMF) generator media port.
+ */
+#include <pjmedia/port.h>
+
+
+/**
+ * @defgroup PJMEDIA_MF_DTMF_TONE_GENERATOR Multi-frequency tone generator
+ * @ingroup PJMEDIA_PORT
+ * @brief Multi-frequency tone generator
+ * @{
+ *
+ * This page describes tone generator media port. A tone generator can be
+ * used to generate a single frequency sine wave or dual frequency tones
+ * such as DTMF.
+ *
+ * The tone generator media port provides two functions to generate tones.
+ * The function #pjmedia_tonegen_play() can be used to generate arbitrary
+ * single or dual frequency tone, and #pjmedia_tonegen_play_digits() is
+ * used to play digits such as DTMF. Each tone specified in the playback
+ * function has individual on and off signal duration that must be
+ * specified by application.
+ *
+ * In order to play digits such as DTMF, the tone generator is equipped
+ * with digit map, which contain information about the frequencies of
+ * the digits. The default digit map is DTMF (0-9,a-d,*,#), but application
+ * may specifiy different digit map to the tone generator by calling
+ * #pjmedia_tonegen_set_digit_map() function.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * This structure describes individual MF digits to be played
+ * with #pjmedia_tonegen_play().
+ */
+typedef struct pjmedia_tone_desc
+{
+ short freq1; /**< First frequency. */
+ short freq2; /**< Optional second frequency. */
+ short on_msec; /**< Playback ON duration, in miliseconds. */
+ short off_msec; /**< Playback OFF duration, ini miliseconds. */
+ short volume; /**< Volume (1-32767), or 0 for default, which
+ PJMEDIA_TONEGEN_VOLUME will be used. */
+ short flags; /**< Currently internal flags, must be 0 */
+} pjmedia_tone_desc;
+
+
+
+/**
+ * This structure describes individual MF digits to be played
+ * with #pjmedia_tonegen_play_digits().
+ */
+typedef struct pjmedia_tone_digit
+{
+ char digit; /**< The ASCI identification for the digit. */
+ short on_msec; /**< Playback ON duration, in miliseconds. */
+ short off_msec; /**< Playback OFF duration, ini miliseconds. */
+ short volume; /**< Volume (1-32767), or 0 for default, which
+ PJMEDIA_TONEGEN_VOLUME will be used. */
+} pjmedia_tone_digit;
+
+
+/**
+ * This structure describes the digit map which is used by the tone generator
+ * to produce tones from an ASCII digits.
+ * Digit map used by a particular tone generator can be retrieved/set with
+ * #pjmedia_tonegen_get_digit_map() and #pjmedia_tonegen_set_digit_map().
+ */
+typedef struct pjmedia_tone_digit_map
+{
+ unsigned count; /**< Number of digits in the map. */
+
+ struct {
+ char digit; /**< The ASCI identification for the digit. */
+ short freq1; /**< First frequency. */
+ short freq2; /**< Optional second frequency. */
+ } digits[16]; /**< Array of digits in the digit map. */
+} pjmedia_tone_digit_map;
+
+
+/**
+ * Tone generator options.
+ */
+enum
+{
+ /**
+ * Play the tones in loop, restarting playing the first tone after
+ * the last tone has been played.
+ */
+ PJMEDIA_TONEGEN_LOOP = 1,
+
+ /**
+ * Disable mutex protection to the tone generator.
+ */
+ PJMEDIA_TONEGEN_NO_LOCK = 2
+};
+
+
+/**
+ * Create an instance of tone generator with the specified parameters.
+ * When the tone generator is first created, it will be loaded with the
+ * default digit map.
+ *
+ * @param pool Pool to allocate memory for the port structure.
+ * @param clock_rate Sampling rate.
+ * @param channel_count Number of channels. Currently only mono and stereo
+ * are supported.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample. This version of PJMEDIA
+ * only supports 16bit per sample.
+ * @param options Option flags. Application may specify
+ * PJMEDIA_TONEGEN_LOOP to play the tone in a loop.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_create(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_port);
+
+
+/**
+ * Create an instance of tone generator with the specified parameters.
+ * When the tone generator is first created, it will be loaded with the
+ * default digit map.
+ *
+ * @param pool Pool to allocate memory for the port structure.
+ * @param name Optional name for the tone generator.
+ * @param clock_rate Sampling rate.
+ * @param channel_count Number of channels. Currently only mono and stereo
+ * are supported.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample. This version of PJMEDIA
+ * only supports 16bit per sample.
+ * @param options Option flags. Application may specify
+ * PJMEDIA_TONEGEN_LOOP to play the tone in a loop.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_create2(pj_pool_t *pool,
+ const pj_str_t *name,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_port);
+
+
+/**
+ * Check if the tone generator is still busy producing some tones.
+ *
+ * @param tonegen The tone generator instance.
+ *
+ * @return Non-zero if busy.
+ */
+PJ_DECL(pj_bool_t) pjmedia_tonegen_is_busy(pjmedia_port *tonegen);
+
+
+/**
+ * Instruct the tone generator to stop current processing.
+ *
+ * @param tonegen The tone generator instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_stop(pjmedia_port *tonegen);
+
+
+/**
+ * Rewind the playback. This will start the playback to the first
+ * tone in the playback list.
+ *
+ * @param tonegen The tone generator instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_rewind(pjmedia_port *tonegen);
+
+
+/**
+ * Instruct the tone generator to play single or dual frequency tones
+ * with the specified duration. The new tones will be appended to currently
+ * playing tones, unless #pjmedia_tonegen_stop() is called before calling
+ * this function. The playback will begin as soon as the first get_frame()
+ * is called to the generator.
+ *
+ * @param tonegen The tone generator instance.
+ * @param count The number of tones in the array.
+ * @param tones Array of tones to be played.
+ * @param options Option flags. Application may specify
+ * PJMEDIA_TONEGEN_LOOP to play the tone in a loop.
+ *
+ * @return PJ_SUCCESS on success, or PJ_ETOOMANY if
+ * there are too many digits in the queue.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_play(pjmedia_port *tonegen,
+ unsigned count,
+ const pjmedia_tone_desc tones[],
+ unsigned options);
+
+/**
+ * Instruct the tone generator to play multiple MF digits with each of
+ * the digits having individual ON/OFF duration. Each of the digit in the
+ * digit array must have the corresponding descriptor in the digit map.
+ * The new tones will be appended to currently playing tones, unless
+ * #pjmedia_tonegen_stop() is called before calling this function.
+ * The playback will begin as soon as the first get_frame() is called
+ * to the generator.
+ *
+ * @param tonegen The tone generator instance.
+ * @param count Number of digits in the array.
+ * @param digits Array of MF digits.
+ * @param options Option flags. Application may specify
+ * PJMEDIA_TONEGEN_LOOP to play the tone in a loop.
+ *
+ * @return PJ_SUCCESS on success, or PJ_ETOOMANY if
+ * there are too many digits in the queue, or
+ * PJMEDIA_RTP_EINDTMF if invalid digit is
+ * specified.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_play_digits(pjmedia_port *tonegen,
+ unsigned count,
+ const pjmedia_tone_digit digits[],
+ unsigned options);
+
+
+/**
+ * Get the digit-map currently used by this tone generator.
+ *
+ * @param tonegen The tone generator instance.
+ * @param m On output, it will be filled with the pointer to
+ * the digitmap currently used by the tone generator.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_get_digit_map(pjmedia_port *tonegen,
+ const pjmedia_tone_digit_map **m);
+
+
+/**
+ * Set digit map to be used by the tone generator.
+ *
+ * @param tonegen The tone generator instance.
+ * @param m Digitmap to be used by the tone generator.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_set_digit_map(pjmedia_port *tonegen,
+ pjmedia_tone_digit_map *m);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TONEGEN_PORT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport.h
new file mode 100644
index 0000000..bc8352b
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport.h
@@ -0,0 +1,820 @@
+/* $Id: transport.h 2945 2009-10-14 13:13:18Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_TRANSPORT_H__
+#define __PJMEDIA_TRANSPORT_H__
+
+
+/**
+ * @file transport.h Media Transport Interface
+ * @brief Transport interface.
+ */
+
+#include <pjmedia/types.h>
+#include <pjmedia/errno.h>
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT Media Transport
+ * @brief Transports.
+ * @{
+ * The media transport (#pjmedia_transport) is the object to send and
+ * receive media packets over the network. The media transport interface
+ * allows the library to be extended to support different types of
+ * transports to send and receive packets.
+ *
+ * The media transport is declared as #pjmedia_transport "class", which
+ * declares "interfaces" to use the class in #pjmedia_transport_op
+ * structure. For the user of the media transport (normally the user of
+ * media transport is media stream, see \ref PJMED_STRM), these transport
+ * "methods" are wrapped with API such as #pjmedia_transport_attach(),
+ * so it should not need to call the function pointer inside
+ * #pjmedia_transport_op directly.
+ *
+ * The connection between \ref PJMED_STRM and media transport is shown in
+ * the diagram below:
+
+ \image html media-transport.PNG
+
+
+ * \section PJMEDIA_TRANSPORT_H_USING Basic Media Transport Usage
+ *
+ * The media transport's life-cycle normally follows the following stages.
+ *
+ * \subsection PJMEDIA_TRANSPORT_H_CREATE Creating the Media Transport
+ *
+ * Application creates the media transport when it needs to establish
+ * media session to remote peer. The media transport is created using
+ * specific function to create that particular transport; for example,
+ * for UDP media transport, it is created with #pjmedia_transport_udp_create()
+ * or #pjmedia_transport_udp_create2() functions. Different media
+ * transports will provide different API to create those transports.
+ *
+ * Alternatively, application may create pool of media transports when
+ * it is first started up. Using this approach probably is better, since
+ * application has to specify the RTP port when sending the initial
+ * session establishment request (e.g. SIP INVITE request), thus if
+ * application only creates the media transport later when media is to be
+ * established (normally when 200/OK is received, or when 18x is received
+ * for early media), there is a possibility that the particular RTP
+ * port might have been occupied by other programs. Also it is more
+ * efficient since sockets don't need to be closed and re-opened between
+ * calls.
+ *
+ *
+ * \subsection PJMEDIA_TRANSPORT_H_ATTACH Attaching and Using the Media Transport.
+ *
+ * Application specifies the media transport instance when creating
+ * the media session (#pjmedia_session_create()). Alternatively, it
+ * may create the media stream directly with #pjmedia_stream_create()
+ * and specify the transport instance in the argument. (Note: media
+ * session is a high-level abstraction for media communications between
+ * two endpoints, and it may contain more than one media streams, for
+ * example, an audio stream and a video stream).
+ *
+ * When stream is created, it will "attach" itself to the media
+ * transport by calling #pjmedia_transport_attach(), which is a thin
+ * wrapper which calls "attach()" method of the media transport's
+ * "virtual function pointer" (#pjmedia_transport_op). Among other things,
+ * the stream specifies two callback functions to the transport: one
+ * callback function will be called by transport when it receives RTP
+ * packet, and another callback for incoming RTCP packet. The
+ * #pjmedia_transport_attach() function also establish the destination
+ * of the outgoing RTP and RTCP packets.
+ *
+ * When the stream needs to send outgoing RTP/RTCP packets, it will
+ * call #pjmedia_transport_send_rtp() and #pjmedia_transport_send_rtcp()
+ * of the media transport API, which is a thin wrapper to call send_rtp()
+ * and send_rtcp() methods in the media transport's "virtual function
+ * pointer" (#pjmedia_transport_op).
+ *
+ * When the stream is destroyed, it will "detach" itself from
+ * the media transport by calling #pjmedia_transport_detach(), which is
+ * a thin wrapper which calls "detach()" method of the media transport's
+ * "virtual function pointer" (#pjmedia_transport_op). After the transport
+ * is detached from its user (the stream), it will no longer report
+ * incoming RTP/RTCP packets to the stream, and it will refuse to send
+ * outgoing packets since the destination has been cleared.
+ *
+ *
+ * \subsection PJMEDIA_TRANSPORT_H_REUSE Reusing the Media Transport.
+ *
+ * After transport has been detached, application may re-attach the
+ * transport to another stream if it wants to. Detaching and re-attaching
+ * media transport may be preferable than closing and re-opening the
+ * transport, since it is more efficient (sockets don't need to be
+ * closed and re-opened). However it is up to the application to choose
+ * which method is most suitable for its uses.
+ *
+ *
+ * \subsection PJMEDIA_TRANSPORT_H_DESTROY Destroying the Media Transport.
+ *
+ * Finally if application no longer needs the media transport, it will
+ * call #pjmedia_transport_close() function, which is thin wrapper which
+ * calls "destroy()" method of the media transport's "virtual function
+ * pointer" (#pjmedia_transport_op). This function releases
+ * all resources used by the transport, such as sockets and memory.
+ *
+ *
+ * \section offer_answer Interaction with SDP Offer/Answer
+
+ For basic UDP transport, the \ref PJMEDIA_TRANSPORT_H_USING above is
+ sufficient to use the media transport. However, more complex media
+ transports such as \ref PJMEDIA_TRANSPORT_SRTP and \ref
+ PJMEDIA_TRANSPORT_ICE requires closer interactions with SDP offer and
+ answer negotiation.
+
+ The media transports can interact with the SDP offer/answer via
+ these APIs:
+ - #pjmedia_transport_media_create(), to initialize the media transport
+ for new media session,
+ - #pjmedia_transport_encode_sdp(), to encode SDP offer or answer,
+ - #pjmedia_transport_media_start(), to activate the settings that
+ have been negotiated by SDP offer answer, and
+ - #pjmedia_transport_media_stop(), to deinitialize the media transport
+ and reset the transport to its idle state.
+
+ The usage of these API in the context of SDP offer answer will be
+ described below.
+
+ \subsection media_create Initializing Transport for New Session
+
+ Application must call #pjmedia_transport_media_create() before using
+ the transport for a new session.
+
+ \subsection creat_oa Creating SDP Offer and Answer
+
+ The #pjmedia_transport_encode_sdp() is used to put additional information
+ from the transport to the local SDP, before the SDP is sent and negotiated
+ with remote SDP.
+
+ When creating an offer, call #pjmedia_transport_encode_sdp() with
+ local SDP (and NULL as \a rem_sdp). The media transport will add the
+ relevant attributes in the local SDP. Application then gives the local
+ SDP to the invite session to be sent to remote agent.
+
+ When creating an answer, also call #pjmedia_transport_encode_sdp(),
+ but this time specify both local and remote SDP to the function. The
+ media transport will once again modify the local SDP and add relevant
+ attributes to the local SDP, if the appropriate attributes related to
+ the transport functionality are present in remote offer. The remote
+ SDP does not contain the relevant attributes, then the specific transport
+ functionality will not be activated for the session.
+
+ The #pjmedia_transport_encode_sdp() should also be called when application
+ sends subsequent SDP offer or answer. The media transport will encode
+ the appropriate attributes based on the state of the session.
+
+ \subsection media_start Offer/Answer Completion
+
+ Once both local and remote SDP have been negotiated by the
+ \ref PJMEDIA_SDP_NEG (normally this is part of PJSIP invite session),
+ application should give both local and remote SDP to
+ #pjmedia_transport_media_start() so that the settings are activated
+ for the session. This function should be called for both initial and
+ subsequent SDP negotiation.
+
+ \subsection media_stop Stopping Transport
+
+ Once session is stop application must call #pjmedia_transport_media_stop()
+ to deactivate the transport feature. Application may reuse the transport
+ for subsequent media session by repeating the #pjmedia_transport_media_create(),
+ #pjmedia_transport_encode_sdp(), #pjmedia_transport_media_start(), and
+ #pjmedia_transport_media_stop() above.
+
+ * \section PJMEDIA_TRANSPORT_H_IMPL Implementing Media Transport
+ *
+ * To implement a new type of media transport, one needs to "subclass" the
+ * media transport "class" (#pjmedia_transport) by providing the "methods"
+ * in the media transport "interface" (#pjmedia_transport_op), and provides
+ * a function to create this new type of transport (similar to
+ * #pjmedia_transport_udp_create() function).
+ *
+ * The media transport is expected to run indepently, that is there should
+ * be no polling like function to poll the transport for incoming RTP/RTCP
+ * packets. This normally can be done by registering the media sockets to
+ * the media endpoint's IOQueue, which allows the transport to be notified
+ * when incoming packet has arrived.
+ *
+ * Alternatively, media transport may utilize thread(s) internally to wait
+ * for incoming packets. The thread then will call the appropriate RTP or
+ * RTCP callback provided by its user (stream) whenever packet is received.
+ * If the transport's user is a stream, then the callbacks provided by the
+ * stream will be thread-safe, so the transport may call these callbacks
+ * without having to serialize the access with some mutex protection. But
+ * the media transport may still have to protect its internal data with
+ * mutex protection, since it may be called by application's thread (for
+ * example, to send RTP/RTCP packets).
+ *
+ */
+
+
+#include <pjmedia/sdp.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Forward declaration for media transport.
+ */
+typedef struct pjmedia_transport pjmedia_transport;
+
+/**
+ * Forward declaration for media transport info.
+ */
+typedef struct pjmedia_transport_info pjmedia_transport_info;
+
+/**
+ * This enumeration specifies the general behaviour of media processing
+ */
+typedef enum pjmedia_tranport_media_option
+{
+ /**
+ * When this flag is specified, the transport will not perform media
+ * transport validation, this is useful when transport is stacked with
+ * other transport, for example when transport UDP is stacked under
+ * transport SRTP, media transport validation only need to be done by
+ * transport SRTP.
+ */
+ PJMEDIA_TPMED_NO_TRANSPORT_CHECKING = 1
+
+} pjmedia_tranport_media_option;
+
+
+/**
+ * This structure describes the operations for the stream transport.
+ */
+struct pjmedia_transport_op
+{
+ /**
+ * Get media socket info from the specified transport.
+ *
+ * Application should call #pjmedia_transport_get_info() instead
+ */
+ pj_status_t (*get_info)(pjmedia_transport *tp,
+ pjmedia_transport_info *info);
+
+ /**
+ * This function is called by the stream when the transport is about
+ * to be used by the stream for the first time, and it tells the transport
+ * about remote RTP address to send the packet and some callbacks to be
+ * called for incoming packets.
+ *
+ * Application should call #pjmedia_transport_attach() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*attach)(pjmedia_transport *tp,
+ void *user_data,
+ const pj_sockaddr_t *rem_addr,
+ const pj_sockaddr_t *rem_rtcp,
+ unsigned addr_len,
+ void (*rtp_cb)(void *user_data,
+ void *pkt,
+ pj_ssize_t size),
+ void (*rtcp_cb)(void *user_data,
+ void *pkt,
+ pj_ssize_t size));
+
+ /**
+ * This function is called by the stream when the stream no longer
+ * needs the transport (normally when the stream is about to be closed).
+ * After the transport is detached, it will ignore incoming
+ * RTP/RTCP packets, and will refuse to send outgoing RTP/RTCP packets.
+ * Application may re-attach the media transport to another transport
+ * user (e.g. stream) after the transport has been detached.
+ *
+ * Application should call #pjmedia_transport_detach() instead of
+ * calling this function directly.
+ */
+ void (*detach)(pjmedia_transport *tp,
+ void *user_data);
+
+ /**
+ * This function is called by the stream to send RTP packet using the
+ * transport.
+ *
+ * Application should call #pjmedia_transport_send_rtp() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*send_rtp)(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size);
+
+ /**
+ * This function is called by the stream to send RTCP packet using the
+ * transport.
+ *
+ * Application should call #pjmedia_transport_send_rtcp() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*send_rtcp)(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size);
+
+ /**
+ * This function is called by the stream to send RTCP packet using the
+ * transport with destination address other than default specified in
+ * #pjmedia_transport_attach().
+ *
+ * Application should call #pjmedia_transport_send_rtcp2() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*send_rtcp2)(pjmedia_transport *tp,
+ const pj_sockaddr_t *addr,
+ unsigned addr_len,
+ const void *pkt,
+ pj_size_t size);
+
+ /**
+ * Prepare the transport for a new media session.
+ *
+ * Application should call #pjmedia_transport_media_create() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*media_create)(pjmedia_transport *tp,
+ pj_pool_t *sdp_pool,
+ unsigned options,
+ const pjmedia_sdp_session *remote_sdp,
+ unsigned media_index);
+
+ /**
+ * This function is called by application to generate the SDP parts
+ * related to transport type, e.g: ICE, SRTP.
+ *
+ * Application should call #pjmedia_transport_encode_sdp() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*encode_sdp)(pjmedia_transport *tp,
+ pj_pool_t *sdp_pool,
+ pjmedia_sdp_session *sdp_local,
+ const pjmedia_sdp_session *rem_sdp,
+ unsigned media_index);
+
+ /**
+ * This function is called by application to start the transport
+ * based on local and remote SDP.
+ *
+ * Application should call #pjmedia_transport_media_start() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*media_start) (pjmedia_transport *tp,
+ pj_pool_t *tmp_pool,
+ const pjmedia_sdp_session *sdp_local,
+ const pjmedia_sdp_session *sdp_remote,
+ unsigned media_index);
+
+ /**
+ * This function is called by application to stop the transport.
+ *
+ * Application should call #pjmedia_transport_media_stop() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*media_stop) (pjmedia_transport *tp);
+
+ /**
+ * This function can be called to simulate packet lost.
+ *
+ * Application should call #pjmedia_transport_simulate_lost() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*simulate_lost)(pjmedia_transport *tp,
+ pjmedia_dir dir,
+ unsigned pct_lost);
+
+ /**
+ * This function can be called to destroy this transport.
+ *
+ * Application should call #pjmedia_transport_close() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*destroy)(pjmedia_transport *tp);
+};
+
+
+/**
+ * @see pjmedia_transport_op.
+ */
+typedef struct pjmedia_transport_op pjmedia_transport_op;
+
+
+/**
+ * Media transport type.
+ */
+typedef enum pjmedia_transport_type
+{
+ /** Media transport using standard UDP */
+ PJMEDIA_TRANSPORT_TYPE_UDP,
+
+ /** Media transport using ICE */
+ PJMEDIA_TRANSPORT_TYPE_ICE,
+
+ /**
+ * Media transport SRTP, this transport is actually security adapter to be
+ * stacked with other transport to enable encryption on the underlying
+ * transport.
+ */
+ PJMEDIA_TRANSPORT_TYPE_SRTP,
+
+ /**
+ * Start of user defined transport.
+ */
+ PJMEDIA_TRANSPORT_TYPE_USER
+
+} pjmedia_transport_type;
+
+
+/**
+ * This structure declares media transport. A media transport is called
+ * by the stream to transmit a packet, and will notify stream when
+ * incoming packet is arrived.
+ */
+struct pjmedia_transport
+{
+ /** Transport name (for logging purpose). */
+ char name[PJ_MAX_OBJ_NAME];
+
+ /** Transport type. */
+ pjmedia_transport_type type;
+
+ /** Transport's "virtual" function table. */
+ pjmedia_transport_op *op;
+};
+
+/**
+ * This structure describes storage buffer of transport specific info.
+ * The actual transport specific info contents will be defined by transport
+ * implementation. Note that some transport implementations do not need to
+ * provide specific info, since the general socket info is enough.
+ */
+typedef struct pjmedia_transport_specific_info
+{
+ /**
+ * Specify media transport type.
+ */
+ pjmedia_transport_type type;
+
+ /**
+ * Specify storage buffer size of transport specific info.
+ */
+ int cbsize;
+
+ /**
+ * Storage buffer of transport specific info.
+ */
+ char buffer[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE];
+
+} pjmedia_transport_specific_info;
+
+
+/**
+ * This structure describes transport informations, including general
+ * socket information and specific information of single transport or
+ * stacked transports (e.g: SRTP stacked on top of UDP)
+ */
+struct pjmedia_transport_info
+{
+ /**
+ * General socket info.
+ */
+ pjmedia_sock_info sock_info;
+
+ /**
+ * Remote address where RTP/RTCP originated from. In case this transport
+ * hasn't ever received packet, the
+ */
+ pj_sockaddr src_rtp_name;
+ pj_sockaddr src_rtcp_name;
+
+ /**
+ * Specifies number of transport specific info included.
+ */
+ unsigned specific_info_cnt;
+
+ /**
+ * Buffer storage of transport specific info.
+ */
+ pjmedia_transport_specific_info spc_info[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT];
+
+};
+
+
+/**
+ * Initialize transport info.
+ *
+ * @param info Transport info to be initialized.
+ */
+PJ_INLINE(void) pjmedia_transport_info_init(pjmedia_transport_info *info)
+{
+ pj_bzero(&info->sock_info, sizeof(pjmedia_sock_info));
+ info->sock_info.rtp_sock = info->sock_info.rtcp_sock = PJ_INVALID_SOCKET;
+ info->specific_info_cnt = 0;
+}
+
+
+/**
+ * Get media transport info from the specified transport and all underlying
+ * transports if any. The transport also contains information about socket info
+ * which describes the local address of the transport, and would be needed
+ * for example to fill in the "c=" and "m=" line of local SDP.
+ *
+ * @param tp The transport.
+ * @param info Media socket info to be initialized.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_get_info(pjmedia_transport *tp,
+ pjmedia_transport_info *info)
+{
+ if (tp && tp->op && tp->op->get_info)
+ return (*tp->op->get_info)(tp, info);
+
+ return PJ_ENOTSUP;
+}
+
+
+/**
+ * Attach callbacks to be called on receipt of incoming RTP/RTCP packets.
+ * This is just a simple wrapper which calls <tt>attach()</tt> member of
+ * the transport.
+ *
+ * @param tp The media transport.
+ * @param user_data Arbitrary user data to be set when the callbacks are
+ * called.
+ * @param rem_addr Remote RTP address to send RTP packet to.
+ * @param rem_rtcp Optional remote RTCP address. If the argument is NULL
+ * or if the address is zero, the RTCP address will be
+ * calculated from the RTP address (which is RTP port
+ * plus one).
+ * @param addr_len Length of the remote address.
+ * @param rtp_cb Callback to be called when RTP packet is received on
+ * the transport.
+ * @param rtcp_cb Callback to be called when RTCP packet is received on
+ * the transport.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_attach(pjmedia_transport *tp,
+ void *user_data,
+ const pj_sockaddr_t *rem_addr,
+ const pj_sockaddr_t *rem_rtcp,
+ unsigned addr_len,
+ void (*rtp_cb)(void *user_data,
+ void *pkt,
+ pj_ssize_t),
+ void (*rtcp_cb)(void *usr_data,
+ void*pkt,
+ pj_ssize_t))
+{
+ return tp->op->attach(tp, user_data, rem_addr, rem_rtcp, addr_len,
+ rtp_cb, rtcp_cb);
+}
+
+
+/**
+ * Detach callbacks from the transport.
+ * This is just a simple wrapper which calls <tt>detach()</tt> member of
+ * the transport. After the transport is detached, it will ignore incoming
+ * RTP/RTCP packets, and will refuse to send outgoing RTP/RTCP packets.
+ * Application may re-attach the media transport to another transport user
+ * (e.g. stream) after the transport has been detached.
+ *
+ * @param tp The media transport.
+ * @param user_data User data which must match the previously set value
+ * on attachment.
+ */
+PJ_INLINE(void) pjmedia_transport_detach(pjmedia_transport *tp,
+ void *user_data)
+{
+ tp->op->detach(tp, user_data);
+}
+
+
+/**
+ * Send RTP packet with the specified media transport. This is just a simple
+ * wrapper which calls <tt>send_rtp()</tt> member of the transport. The
+ * RTP packet will be delivered to the destination address specified in
+ * #pjmedia_transport_attach() function.
+ *
+ * @param tp The media transport.
+ * @param pkt The packet to send.
+ * @param size Size of the packet.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_send_rtp(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size)
+{
+ return (*tp->op->send_rtp)(tp, pkt, size);
+}
+
+
+/**
+ * Send RTCP packet with the specified media transport. This is just a simple
+ * wrapper which calls <tt>send_rtcp()</tt> member of the transport. The
+ * RTCP packet will be delivered to the destination address specified in
+ * #pjmedia_transport_attach() function.
+ *
+ * @param tp The media transport.
+ * @param pkt The packet to send.
+ * @param size Size of the packet.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_send_rtcp(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size)
+{
+ return (*tp->op->send_rtcp)(tp, pkt, size);
+}
+
+
+/**
+ * Send RTCP packet with the specified media transport. This is just a simple
+ * wrapper which calls <tt>send_rtcp2()</tt> member of the transport. The
+ * RTCP packet will be delivered to the destination address specified in
+ * param addr, if addr is NULL, RTCP packet will be delivered to destination
+ * address specified in #pjmedia_transport_attach() function.
+ *
+ * @param tp The media transport.
+ * @param addr The destination address.
+ * @param addr_len Length of destination address.
+ * @param pkt The packet to send.
+ * @param size Size of the packet.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_send_rtcp2(pjmedia_transport *tp,
+ const pj_sockaddr_t *addr,
+ unsigned addr_len,
+ const void *pkt,
+ pj_size_t size)
+{
+ return (*tp->op->send_rtcp2)(tp, addr, addr_len, pkt, size);
+}
+
+
+/**
+ * Prepare the media transport for a new media session, Application must
+ * call this function before starting a new media session using this
+ * transport.
+ *
+ * This is just a simple wrapper which calls <tt>media_create()</tt> member
+ * of the transport.
+ *
+ * @param tp The media transport.
+ * @param sdp_pool Pool object to allocate memory related to SDP
+ * messaging components.
+ * @param options Option flags, from #pjmedia_tranport_media_option
+ * @param rem_sdp Remote SDP if local SDP is an answer, otherwise
+ * specify NULL if SDP is an offer.
+ * @param media_index Media index in SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_media_create(pjmedia_transport *tp,
+ pj_pool_t *sdp_pool,
+ unsigned options,
+ const pjmedia_sdp_session *rem_sdp,
+ unsigned media_index)
+{
+ return (*tp->op->media_create)(tp, sdp_pool, options, rem_sdp,
+ media_index);
+}
+
+
+/**
+ * Put transport specific information into the SDP. This function can be
+ * called to put transport specific information in the initial or
+ * subsequent SDP offer or answer.
+ *
+ * This is just a simple wrapper which calls <tt>encode_sdp()</tt> member
+ * of the transport.
+ *
+ * @param tp The media transport.
+ * @param sdp_pool Pool object to allocate memory related to SDP
+ * messaging components.
+ * @param sdp The local SDP to be filled in information from the
+ * media transport.
+ * @param rem_sdp Remote SDP if local SDP is an answer, otherwise
+ * specify NULL if SDP is an offer.
+ * @param media_index Media index in SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_encode_sdp(pjmedia_transport *tp,
+ pj_pool_t *sdp_pool,
+ pjmedia_sdp_session *sdp,
+ const pjmedia_sdp_session *rem_sdp,
+ unsigned media_index)
+{
+ return (*tp->op->encode_sdp)(tp, sdp_pool, sdp, rem_sdp, media_index);
+}
+
+
+/**
+ * Start the transport session with the settings in both local and remote
+ * SDP. The actual work that is done by this function depends on the
+ * underlying transport type. For SRTP, this will activate the encryption
+ * and decryption based on the keys found the SDPs. For ICE, this will
+ * start ICE negotiation according to the information found in the SDPs.
+ *
+ * This is just a simple wrapper which calls <tt>media_start()</tt> member
+ * of the transport.
+ *
+ * @param tp The media transport.
+ * @param tmp_pool The memory pool for allocating temporary objects.
+ * @param sdp_local Local SDP.
+ * @param sdp_remote Remote SDP.
+ * @param media_index Media index in the SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_media_start(pjmedia_transport *tp,
+ pj_pool_t *tmp_pool,
+ const pjmedia_sdp_session *sdp_local,
+ const pjmedia_sdp_session *sdp_remote,
+ unsigned media_index)
+{
+ return (*tp->op->media_start)(tp, tmp_pool, sdp_local, sdp_remote,
+ media_index);
+}
+
+
+/**
+ * This API should be called when the session is stopped, to allow the media
+ * transport to release its resources used for the session.
+ *
+ * This is just a simple wrapper which calls <tt>media_stop()</tt> member
+ * of the transport.
+ *
+ * @param tp The media transport.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_media_stop(pjmedia_transport *tp)
+{
+ return (*tp->op->media_stop)(tp);
+}
+
+/**
+ * Close media transport. This is just a simple wrapper which calls
+ * <tt>destroy()</tt> member of the transport. This function will free
+ * all resources created by this transport (such as sockets, memory, etc.).
+ *
+ * @param tp The media transport.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_close(pjmedia_transport *tp)
+{
+ if (tp->op->destroy)
+ return (*tp->op->destroy)(tp);
+ else
+ return PJ_SUCCESS;
+}
+
+/**
+ * Simulate packet lost in the specified direction (for testing purposes).
+ * When enabled, the transport will randomly drop packets to the specified
+ * direction.
+ *
+ * @param tp The media transport.
+ * @param dir Media direction to which packets will be randomly dropped.
+ * @param pct_lost Percent lost (0-100). Set to zero to disable packet
+ * lost simulation.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_simulate_lost(pjmedia_transport *tp,
+ pjmedia_dir dir,
+ unsigned pct_lost)
+{
+ return (*tp->op->simulate_lost)(tp, dir, pct_lost);
+}
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_adapter_sample.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_adapter_sample.h
new file mode 100644
index 0000000..9847021
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_adapter_sample.h
@@ -0,0 +1,73 @@
+/* $Id: transport_adapter_sample.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__
+#define __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__
+
+
+/**
+ * @file transport_adapter_sample.h
+ * @brief Sample Media Transport Adapter
+ */
+
+#include <pjmedia/transport.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_ADAPTER_SAMPLE Sample Transport Adapter
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Example on how to create transport adapter.
+ * @{
+ *
+ * This describes a sample implementation of transport adapter, similar to
+ * the way the SRTP transport adapter works.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create the transport adapter, specifying the underlying transport to be
+ * used to send and receive RTP/RTCP packets.
+ *
+ * @param endpt The media endpoint.
+ * @param name Optional name to identify this media transport
+ * for logging purposes.
+ * @param transport The underlying media transport to send and receive
+ * RTP/RTCP packets.
+ * @param p_tp Pointer to receive the media transport instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_tp_adapter_create( pjmedia_endpt *endpt,
+ const char *name,
+ pjmedia_transport *transport,
+ pjmedia_transport **p_tp);
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_ice.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_ice.h
new file mode 100644
index 0000000..8c5d5d2
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_ice.h
@@ -0,0 +1,194 @@
+/* $Id: transport_ice.h 2945 2009-10-14 13:13:18Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_TRANSPORT_ICE_H__
+#define __PJMEDIA_TRANSPORT_ICE_H__
+
+
+/**
+ * @file transport_ice.h
+ * @brief ICE capable media transport.
+ */
+
+#include <pjmedia/stream.h>
+#include <pjnath/ice_strans.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_ICE ICE Media Transport
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Interactive Connectivity Establishment (ICE) transport
+ * @{
+ *
+ * This describes the implementation of media transport using
+ * Interactive Connectivity Establishment (ICE) protocol.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Structure containing callbacks to receive ICE notifications.
+ */
+typedef struct pjmedia_ice_cb
+{
+ /**
+ * This callback will be called when ICE negotiation completes.
+ *
+ * @param tp PJMEDIA ICE transport.
+ * @param op The operation
+ * @param status Operation status.
+ */
+ void (*on_ice_complete)(pjmedia_transport *tp,
+ pj_ice_strans_op op,
+ pj_status_t status);
+
+} pjmedia_ice_cb;
+
+
+/**
+ * This structure specifies ICE transport specific info. This structure
+ * will be filled in media transport specific info.
+ */
+typedef struct pjmedia_ice_transport_info
+{
+ /**
+ * ICE sesion state.
+ */
+ pj_ice_strans_state sess_state;
+
+ /**
+ * Session role.
+ */
+ pj_ice_sess_role role;
+
+ /**
+ * Number of components in the component array. Before ICE negotiation
+ * is complete, the number represents the number of components of the
+ * local agent. After ICE negotiation has been completed successfully,
+ * the number represents the number of common components between local
+ * and remote agents.
+ */
+ unsigned comp_cnt;
+
+ /**
+ * Array of ICE components. Typically the first element denotes RTP and
+ * second element denotes RTCP.
+ */
+ struct
+ {
+ /**
+ * Local candidate type.
+ */
+ pj_ice_cand_type lcand_type;
+
+ /**
+ * Remote candidate type.
+ */
+ pj_ice_cand_type rcand_type;
+
+ } comp[2];
+
+} pjmedia_ice_transport_info;
+
+
+/**
+ * Options that can be specified when creating ICE transport.
+ */
+enum pjmedia_transport_ice_options
+{
+ /**
+ * Normally when remote doesn't use ICE, the ICE transport will
+ * continuously check the source address of incoming packets to see
+ * if it is different than the configured remote address, and switch
+ * the remote address to the source address of the packet if they
+ * are different after several packets are received.
+ * Specifying this option will disable this feature.
+ */
+ PJMEDIA_ICE_NO_SRC_ADDR_CHECKING = 1
+};
+
+
+/**
+ * Create the Interactive Connectivity Establishment (ICE) media transport
+ * using the specified configuration. When STUN or TURN (or both) is used,
+ * the creation operation will complete asynchronously, when STUN resolution
+ * and TURN allocation completes. When the initialization completes, the
+ * \a on_ice_complete() complete will be called with \a op parameter equal
+ * to PJ_ICE_STRANS_OP_INIT.
+ *
+ * In addition, this transport will also notify the application about the
+ * result of ICE negotiation, also in \a on_ice_complete() callback. In this
+ * case the callback will be called with \a op parameter equal to
+ * PJ_ICE_STRANS_OP_NEGOTIATION.
+ *
+ * Other than this, application should use the \ref PJMEDIA_TRANSPORT API
+ * to manipulate this media transport.
+ *
+ * @param endpt The media endpoint.
+ * @param name Optional name to identify this ICE media transport
+ * for logging purposes.
+ * @param comp_cnt Number of components to be created.
+ * @param cfg Pointer to configuration settings.
+ * @param cb Optional structure containing ICE specific callbacks.
+ * @param p_tp Pointer to receive the media transport instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_ice_create(pjmedia_endpt *endpt,
+ const char *name,
+ unsigned comp_cnt,
+ const pj_ice_strans_cfg *cfg,
+ const pjmedia_ice_cb *cb,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * The same as @pjmedia_ice_create with additional \a options param.
+ *
+ * @param endpt The media endpoint.
+ * @param name Optional name to identify this ICE media transport
+ * for logging purposes.
+ * @param comp_cnt Number of components to be created.
+ * @param cfg Pointer to configuration settings.
+ * @param cb Optional structure containing ICE specific callbacks.
+ * @param options Options, see #pjmedia_transport_ice_options.
+ * @param p_tp Pointer to receive the media transport instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt,
+ const char *name,
+ unsigned comp_cnt,
+ const pj_ice_strans_cfg *cfg,
+ const pjmedia_ice_cb *cb,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_ICE_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_loop.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_loop.h
new file mode 100644
index 0000000..3d3fde4
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_loop.h
@@ -0,0 +1,82 @@
+/* $Id: transport_loop.h 2845 2009-07-29 12:19:25Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_TRANSPORT_LOOP_H__
+#define __PJMEDIA_TRANSPORT_LOOP_H__
+
+
+/**
+ * @file transport_loop.h
+ * @brief Loopback transport
+ */
+
+#include <pjmedia/stream.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_LOOP Loopback Media Transport
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Loopback transport for testing.
+ * @{
+ *
+ * This is the loopback media transport, where packets sent to this transport
+ * will be sent back to the streams attached to this transport. Unlike the
+ * other PJMEDIA transports, the loop transport may be attached to multiple
+ * streams (in other words, application should specify the same loop transport
+ * instance when calling #pjmedia_stream_create()). Any RTP or RTCP packets
+ * sent by one stream to this transport by default will be sent back to all
+ * streams that are attached to this transport, including to the stream that
+ * sends the packet. Application may individually select which stream to
+ * receive packets by calling #pjmedia_transport_loop_disable_rx().
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create the loopback transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_loop_create(pjmedia_endpt *endpt,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * Set this stream as the receiver of incoming packets.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_loop_disable_rx(pjmedia_transport *tp,
+ void *user,
+ pj_bool_t disabled);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_LOOP_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_srtp.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_srtp.h
new file mode 100644
index 0000000..8744f19
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_srtp.h
@@ -0,0 +1,313 @@
+/* $Id: transport_srtp.h 2597 2009-04-14 15:18:30Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_TRANSPORT_SRTP_H__
+#define __PJMEDIA_TRANSPORT_SRTP_H__
+
+/**
+ * @file transport_srtp.h
+ * @brief Secure RTP (SRTP) transport.
+ */
+
+#include <pjmedia/transport.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_SRTP Secure RTP (SRTP) Media Transport
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Media transport adapter to add SRTP feature to existing transports
+ * @{
+ *
+ * This module implements SRTP as described by RFC 3711, using RFC 4568 as
+ * key exchange method. It implements \ref PJMEDIA_TRANSPORT to integrate
+ * with the rest of PJMEDIA framework.
+ *
+ * As we know, media transport is separated from the stream object (which
+ * does the encoding/decoding of PCM frames, (de)packetization of RTP/RTCP
+ * packets, and de-jitter buffering). The connection between stream and media
+ * transport is established when the stream is created (we need to specify
+ * media transport during stream creation), and the interconnection can be
+ * depicted from the diagram below:
+ *
+ \image html media-transport.PNG
+
+ * I think the diagram above is self-explanatory.
+ *
+ * SRTP functionality is implemented as some kind of "adapter", which is
+ * plugged between the stream and the actual media transport that does
+ * sending/receiving RTP/RTCP packets. When SRTP is used, the interconnection
+ * between stream and transport is like the diagram below:
+ *
+ \image html media-srtp-transport.PNG
+
+ * So to stream, the SRTP transport behaves as if it is a media transport
+ * (because it is a media transport), and to the media transport it behaves
+ * as if it is a stream. The SRTP object then forwards RTP packets back and
+ * forth between stream and the actual transport, encrypting/decrypting
+ * the RTP/RTCP packets as necessary.
+ *
+ * The neat thing about this design is the SRTP "adapter" then can be used
+ * to encrypt any kind of media transports. We currently have UDP and ICE
+ * media transports that can benefit SRTP, and we could add SRTP to any
+ * media transports that will be added in the future.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Crypto option.
+ */
+typedef enum pjmedia_srtp_crypto_option
+{
+ /** When this flag is specified, encryption will be disabled. */
+ PJMEDIA_SRTP_NO_ENCRYPTION = 1,
+
+ /** When this flag is specified, authentication will be disabled. */
+ PJMEDIA_SRTP_NO_AUTHENTICATION = 2
+
+} pjmedia_srtp_crypto_option;
+
+
+/**
+ * This structure describes an individual crypto setting.
+ */
+typedef struct pjmedia_srtp_crypto
+{
+ /** Optional key. If empty, a random key will be autogenerated. */
+ pj_str_t key;
+
+ /** Crypto name. */
+ pj_str_t name;
+
+ /** Flags, bitmask from #pjmedia_srtp_crypto_option */
+ unsigned flags;
+
+} pjmedia_srtp_crypto;
+
+
+/**
+ * This enumeration specifies the behavior of the SRTP transport regarding
+ * media security offer and answer.
+ */
+typedef enum pjmedia_srtp_use
+{
+ /**
+ * When this flag is specified, SRTP will be disabled, and the transport
+ * will reject RTP/SAVP offer.
+ */
+ PJMEDIA_SRTP_DISABLED,
+
+ /**
+ * When this flag is specified, SRTP will be advertised as optional and
+ * incoming SRTP offer will be accepted.
+ */
+ PJMEDIA_SRTP_OPTIONAL,
+
+ /**
+ * When this flag is specified, the transport will require that RTP/SAVP
+ * media shall be used.
+ */
+ PJMEDIA_SRTP_MANDATORY
+
+} pjmedia_srtp_use;
+
+
+/**
+ * Settings to be given when creating SRTP transport. Application should call
+ * #pjmedia_srtp_setting_default() to initialize this structure with its
+ * default values.
+ */
+typedef struct pjmedia_srtp_setting
+{
+ /**
+ * Specify the usage policy. Default is PJMEDIA_SRTP_OPTIONAL.
+ */
+ pjmedia_srtp_use use;
+
+ /**
+ * Specify whether the SRTP transport should close the member transport
+ * when it is destroyed. Default: PJ_TRUE.
+ */
+ pj_bool_t close_member_tp;
+
+ /**
+ * Specify the number of crypto suite settings.
+ */
+ unsigned crypto_count;
+
+ /**
+ * Specify individual crypto suite setting.
+ */
+ pjmedia_srtp_crypto crypto[8];
+
+} pjmedia_srtp_setting;
+
+
+/**
+ * This structure specifies SRTP transport specific info. This will fit
+ * into \a buffer field of pjmedia_transport_specific_info.
+ */
+typedef struct pjmedia_srtp_info
+{
+ /**
+ * Specify whether the SRTP transport is active for SRTP session.
+ */
+ pj_bool_t active;
+
+ /**
+ * Specify the policy used by the SRTP session for receive direction.
+ */
+ pjmedia_srtp_crypto rx_policy;
+
+ /**
+ * Specify the policy used by the SRTP session for transmit direction.
+ */
+ pjmedia_srtp_crypto tx_policy;
+
+ /**
+ * Specify the usage policy.
+ */
+ pjmedia_srtp_use use;
+
+ /**
+ * Specify the peer's usage policy.
+ */
+ pjmedia_srtp_use peer_use;
+
+} pjmedia_srtp_info;
+
+
+/**
+ * Initialize SRTP library. This function should be called before
+ * any SRTP functions, however calling #pjmedia_transport_srtp_create()
+ * will also invoke this function. This function will also register SRTP
+ * library deinitialization to #pj_atexit(), so the deinitialization
+ * of SRTP library will be performed automatically by PJLIB destructor.
+ */
+PJ_DECL(pj_status_t) pjmedia_srtp_init_lib(void);
+
+
+/**
+ * Initialize SRTP setting with its default values.
+ *
+ * @param opt SRTP setting to be initialized.
+ */
+PJ_DECL(void) pjmedia_srtp_setting_default(pjmedia_srtp_setting *opt);
+
+
+/**
+ * Create an SRTP media transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param tp The actual media transport to send and receive
+ * RTP/RTCP packets. This media transport will be
+ * kept as member transport of this SRTP instance.
+ * @param opt Optional settings. If NULL is given, default
+ * settings will be used.
+ * @param p_tp Pointer to receive the transport SRTP instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_srtp_create(
+ pjmedia_endpt *endpt,
+ pjmedia_transport *tp,
+ const pjmedia_srtp_setting *opt,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * Manually start SRTP session with the given parameters. Application only
+ * needs to call this function when the SRTP transport is used without SDP
+ * offer/answer. When SDP offer/answer framework is used, the SRTP transport
+ * will be started/stopped by #pjmedia_transport_media_start() and
+ * #pjmedia_transport_media_stop() respectively.
+ *
+ * Please note that even if an RTP stream is only one direction, application
+ * will still need to provide both crypto suites, because it is needed by
+ * RTCP.
+
+ * If application specifies the crypto keys, the keys for transmit and receive
+ * direction MUST be different.
+ *
+ * @param srtp The SRTP transport.
+ * @param tx Crypto suite setting for transmit direction.
+ * @param rx Crypto suite setting for receive direction.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_srtp_start(
+ pjmedia_transport *srtp,
+ const pjmedia_srtp_crypto *tx,
+ const pjmedia_srtp_crypto *rx);
+
+/**
+ * Stop SRTP session.
+ *
+ * @param srtp The SRTP media transport.
+ *
+ * @return PJ_SUCCESS on success.
+ *
+ * @see #pjmedia_transport_srtp_start()
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp);
+
+
+/**
+ * This is a utility function to decrypt SRTP packet using SRTP transport.
+ * This function is not part of SRTP transport's API, but it can be used
+ * to decrypt SRTP packets from non-network (for example, from a saved file)
+ * without having to use the transport framework. See pcaputil.c in the
+ * samples collection on how to use this function.
+ *
+ * @param tp The SRTP transport.
+ * @param is_rtp Set to non-zero if the packet is SRTP, otherwise set
+ * to zero if the packet is SRTCP.
+ * @param pkt On input, it contains SRTP or SRTCP packet. On
+ * output, it contains the decrypted RTP/RTCP packet.
+ * @param pkt_len On input, specify the length of the buffer. On
+ * output, it will be filled with the actual length
+ * of decrypted packet.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_srtp_decrypt_pkt(pjmedia_transport *tp,
+ pj_bool_t is_rtp,
+ void *pkt,
+ int *pkt_len);
+
+
+/**
+ * Query member transport of SRTP.
+ *
+ * @param srtp The SRTP media transport.
+ *
+ * @return member media transport.
+ */
+PJ_DECL(pjmedia_transport*) pjmedia_transport_srtp_get_member(
+ pjmedia_transport *srtp);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_TRANSPORT_SRTP_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_udp.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_udp.h
new file mode 100644
index 0000000..0c30c7d
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_udp.h
@@ -0,0 +1,162 @@
+/* $Id: transport_udp.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_TRANSPORT_UDP_H__
+#define __PJMEDIA_TRANSPORT_UDP_H__
+
+
+/**
+ * @file transport_udp.h
+ * @brief Stream transport with UDP.
+ */
+
+#include <pjmedia/stream.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_UDP UDP Media Transport
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Implementation of media transport with UDP sockets.
+ * @{
+ *
+ * The UDP media transport is the standard based media transport
+ * as described by RFC 3550/3551. It can be used to facilitate RTP/RTCP
+ * unicast or multicast communication.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Options that can be specified when creating UDP transport.
+ */
+enum pjmedia_transport_udp_options
+{
+ /**
+ * Normally the UDP transport will continuously check the source address
+ * of incoming packets to see if it is different than the configured
+ * remote address, and switch the remote address to the source address
+ * of the packet if they are different after several packets are
+ * received.
+ * Specifying this option will disable this feature.
+ */
+ PJMEDIA_UDP_NO_SRC_ADDR_CHECKING = 1
+};
+
+
+/**
+ * Create an RTP and RTCP sockets and bind the sockets to the specified
+ * port to create media transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param name Optional name to be assigned to the transport.
+ * @param port UDP port number for the RTP socket. The RTCP port number
+ * will be set to one above RTP port.
+ * @param options Options, bitmask of #pjmedia_transport_udp_options.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_create(pjmedia_endpt *endpt,
+ const char *name,
+ int port,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * Create an RTP and RTCP sockets and bind the sockets to the specified
+ * address and port to create media transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param name Optional name to be assigned to the transport.
+ * @param addr Optional local address to bind the sockets to. If this
+ * argument is NULL or empty, the sockets will be bound
+ * to all interface.
+ * @param port UDP port number for the RTP socket. The RTCP port number
+ * will be set to one above RTP port.
+ * @param options Options, bitmask of #pjmedia_transport_udp_options.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt,
+ const char *name,
+ const pj_str_t *addr,
+ int port,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+/**
+ * Another variant of #pjmedia_transport_udp_create() which allows
+ * the creation of IPv6 transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param af Address family, which can be pj_AF_INET() for IPv4 or
+ * pj_AF_INET6() for IPv6.
+ * @param name Optional name to be assigned to the transport.
+ * @param addr Optional local address to bind the sockets to. If this
+ * argument is NULL or empty, the sockets will be bound
+ * to all interface.
+ * @param port UDP port number for the RTP socket. The RTCP port number
+ * will be set to one above RTP port.
+ * @param options Options, bitmask of #pjmedia_transport_udp_options.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_create3(pjmedia_endpt *endpt,
+ int af,
+ const char *name,
+ const pj_str_t *addr,
+ int port,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * Create UDP stream transport from existing sockets. Use this function when
+ * the sockets have previously been created.
+ *
+ * @param endpt The media endpoint instance.
+ * @param name Optional name to be assigned to the transport.
+ * @param si Media socket info containing the RTP and RTCP sockets.
+ * @param options Options, bitmask of #pjmedia_transport_udp_options.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_attach(pjmedia_endpt *endpt,
+ const char *name,
+ const pjmedia_sock_info *si,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_UDP_H__ */
+
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/types.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/types.h
new file mode 100644
index 0000000..faaee2b
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/types.h
@@ -0,0 +1,533 @@
+/* $Id: types.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_TYPES_H__
+#define __PJMEDIA_TYPES_H__
+
+/**
+ * @file pjmedia/types.h Basic Types
+ * @brief Basic PJMEDIA types.
+ */
+
+#include <pjmedia/config.h>
+#include <pj/sock.h> /* pjmedia_sock_info */
+#include <pj/string.h> /* pj_memcpy(), pj_memset() */
+
+/**
+ * @defgroup PJMEDIA_PORT Media Ports Framework
+ * @brief Extensible framework for media terminations
+ */
+
+
+/**
+ * @defgroup PJMEDIA_FRAME_OP Audio Manipulation Algorithms
+ * @brief Algorithms to manipulate audio frames
+ */
+
+/**
+ * @defgroup PJMEDIA_TYPES Basic Types
+ * @ingroup PJMEDIA_BASE
+ * @brief Basic PJMEDIA types and operations.
+ * @{
+ */
+
+/**
+ * Top most media type.
+ */
+typedef enum pjmedia_type
+{
+ /** No type. */
+ PJMEDIA_TYPE_NONE = 0,
+
+ /** The media is audio */
+ PJMEDIA_TYPE_AUDIO = 1,
+
+ /** The media is video. */
+ PJMEDIA_TYPE_VIDEO = 2,
+
+ /** Unknown media type, in this case the name will be specified in
+ * encoding_name.
+ */
+ PJMEDIA_TYPE_UNKNOWN = 3,
+
+ /** The media is application. */
+ PJMEDIA_TYPE_APPLICATION = 4
+
+} pjmedia_type;
+
+
+/**
+ * Media transport protocol.
+ */
+typedef enum pjmedia_tp_proto
+{
+ /** No transport type */
+ PJMEDIA_TP_PROTO_NONE = 0,
+
+ /** RTP using A/V profile */
+ PJMEDIA_TP_PROTO_RTP_AVP,
+
+ /** Secure RTP */
+ PJMEDIA_TP_PROTO_RTP_SAVP,
+
+ /** Unknown */
+ PJMEDIA_TP_PROTO_UNKNOWN
+
+} pjmedia_tp_proto;
+
+
+/**
+ * Media direction.
+ */
+typedef enum pjmedia_dir
+{
+ /** None */
+ PJMEDIA_DIR_NONE = 0,
+
+ /** Encoding (outgoing to network) stream */
+ PJMEDIA_DIR_ENCODING = 1,
+
+ /** Decoding (incoming from network) stream. */
+ PJMEDIA_DIR_DECODING = 2,
+
+ /** Incoming and outgoing stream. */
+ PJMEDIA_DIR_ENCODING_DECODING = 3
+
+} pjmedia_dir;
+
+
+
+/* Alternate names for media direction: */
+
+/**
+ * Direction is capturing audio frames.
+ */
+#define PJMEDIA_DIR_CAPTURE PJMEDIA_DIR_ENCODING
+
+/**
+ * Direction is playback of audio frames.
+ */
+#define PJMEDIA_DIR_PLAYBACK PJMEDIA_DIR_DECODING
+
+/**
+ * Direction is both capture and playback.
+ */
+#define PJMEDIA_DIR_CAPTURE_PLAYBACK PJMEDIA_DIR_ENCODING_DECODING
+
+
+/**
+ * Create 32bit port signature from ASCII characters.
+ */
+#define PJMEDIA_PORT_SIGNATURE(a,b,c,d) \
+ (a<<24 | b<<16 | c<<8 | d)
+
+
+/**
+ * Opaque declaration of media endpoint.
+ */
+typedef struct pjmedia_endpt pjmedia_endpt;
+
+
+/*
+ * Forward declaration for stream (needed by transport).
+ */
+typedef struct pjmedia_stream pjmedia_stream;
+
+
+/**
+ * Media socket info is used to describe the underlying sockets
+ * to be used as media transport.
+ */
+typedef struct pjmedia_sock_info
+{
+ /** The RTP socket handle */
+ pj_sock_t rtp_sock;
+
+ /** Address to be advertised as the local address for the RTP
+ * socket, which does not need to be equal as the bound
+ * address (for example, this address can be the address resolved
+ * with STUN).
+ */
+ pj_sockaddr rtp_addr_name;
+
+ /** The RTCP socket handle. */
+ pj_sock_t rtcp_sock;
+
+ /** Address to be advertised as the local address for the RTCP
+ * socket, which does not need to be equal as the bound
+ * address (for example, this address can be the address resolved
+ * with STUN).
+ */
+ pj_sockaddr rtcp_addr_name;
+
+} pjmedia_sock_info;
+
+
+/**
+ * Macro for packing format.
+ */
+#define PJMEDIA_FORMAT_PACK(C1, C2, C3, C4) ( C4<<24 | C3<<16 | C2<<8 | C1 )
+
+/**
+ * This enumeration describes format ID.
+ */
+typedef enum pjmedia_format_id
+{
+ /**
+ * 16bit linear
+ */
+ PJMEDIA_FORMAT_L16 = 0,
+
+ /**
+ * Alias for PJMEDIA_FORMAT_L16
+ */
+ PJMEDIA_FORMAT_PCM = PJMEDIA_FORMAT_L16,
+
+ /**
+ * G.711 ALAW
+ */
+ PJMEDIA_FORMAT_PCMA = PJMEDIA_FORMAT_PACK('A', 'L', 'A', 'W'),
+
+ /**
+ * Alias for PJMEDIA_FORMAT_PCMA
+ */
+ PJMEDIA_FORMAT_ALAW = PJMEDIA_FORMAT_PCMA,
+
+ /**
+ * G.711 ULAW
+ */
+ PJMEDIA_FORMAT_PCMU = PJMEDIA_FORMAT_PACK('u', 'L', 'A', 'W'),
+
+ /**
+ * Aliaw for PJMEDIA_FORMAT_PCMU
+ */
+ PJMEDIA_FORMAT_ULAW = PJMEDIA_FORMAT_PCMU,
+
+ /**
+ * AMR narrowband
+ */
+ PJMEDIA_FORMAT_AMR = PJMEDIA_FORMAT_PACK(' ', 'A', 'M', 'R'),
+
+ /**
+ * ITU G.729
+ */
+ PJMEDIA_FORMAT_G729 = PJMEDIA_FORMAT_PACK('G', '7', '2', '9'),
+
+ /**
+ * Internet Low Bit-Rate Codec (ILBC)
+ */
+ PJMEDIA_FORMAT_ILBC = PJMEDIA_FORMAT_PACK('I', 'L', 'B', 'C')
+
+} pjmedia_format_id;
+
+
+/**
+ * Media format information.
+ */
+typedef struct pjmedia_format
+{
+ /** Format ID */
+ pjmedia_format_id id;
+
+ /** Bitrate. */
+ pj_uint32_t bitrate;
+
+ /** Flag to indicate whether VAD is enabled */
+ pj_bool_t vad;
+
+} pjmedia_format;
+
+
+
+/**
+ * This is a general purpose function set PCM samples to zero.
+ * Since this function is needed by many parts of the library,
+ * by putting this functionality in one place, it enables some.
+ * clever people to optimize this function.
+ *
+ * @param samples The 16bit PCM samples.
+ * @param count Number of samples.
+ */
+PJ_INLINE(void) pjmedia_zero_samples(pj_int16_t *samples, unsigned count)
+{
+#if 1
+ pj_bzero(samples, (count<<1));
+#elif 0
+ unsigned i;
+ for (i=0; i<count; ++i) samples[i] = 0;
+#else
+ unsigned i;
+ count >>= 1;
+ for (i=0; i<count; ++i) ((pj_int32_t*)samples)[i] = (pj_int32_t)0;
+#endif
+}
+
+
+/**
+ * This is a general purpose function to copy samples from/to buffers with
+ * equal size. Since this function is needed by many parts of the library,
+ * by putting this functionality in one place, it enables some.
+ * clever people to optimize this function.
+ */
+PJ_INLINE(void) pjmedia_copy_samples(pj_int16_t *dst, const pj_int16_t *src,
+ unsigned count)
+{
+#if 1
+ pj_memcpy(dst, src, (count<<1));
+#elif 0
+ unsigned i;
+ for (i=0; i<count; ++i) dst[i] = src[i];
+#else
+ unsigned i;
+ count >>= 1;
+ for (i=0; i<count; ++i)
+ ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];
+#endif
+}
+
+
+/**
+ * This is a general purpose function to copy samples from/to buffers with
+ * equal size. Since this function is needed by many parts of the library,
+ * by putting this functionality in one place, it enables some.
+ * clever people to optimize this function.
+ */
+PJ_INLINE(void) pjmedia_move_samples(pj_int16_t *dst, const pj_int16_t *src,
+ unsigned count)
+{
+#if 1
+ pj_memmove(dst, src, (count<<1));
+#elif 0
+ unsigned i;
+ for (i=0; i<count; ++i) dst[i] = src[i];
+#else
+ unsigned i;
+ count >>= 1;
+ for (i=0; i<count; ++i)
+ ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];
+#endif
+}
+
+/**
+ * Types of media frame.
+ */
+typedef enum pjmedia_frame_type
+{
+ PJMEDIA_FRAME_TYPE_NONE, /**< No frame. */
+ PJMEDIA_FRAME_TYPE_AUDIO, /**< Normal audio frame. */
+ PJMEDIA_FRAME_TYPE_EXTENDED /**< Extended audio frame. */
+
+} pjmedia_frame_type;
+
+
+/**
+ * This structure describes a media frame.
+ */
+typedef struct pjmedia_frame
+{
+ pjmedia_frame_type type; /**< Frame type. */
+ void *buf; /**< Pointer to buffer. */
+ pj_size_t size; /**< Frame size in bytes. */
+ pj_timestamp timestamp; /**< Frame timestamp. */
+ pj_uint32_t bit_info; /**< Bit info of the frame, sample case:
+ a frame may not exactly start and end
+ at the octet boundary, so this field
+ may be used for specifying start &
+ end bit offset. */
+} pjmedia_frame;
+
+
+/**
+ * The pjmedia_frame_ext is used to carry a more complex audio frames than
+ * the typical PCM audio frames, and it is signaled by setting the "type"
+ * field of a pjmedia_frame to PJMEDIA_FRAME_TYPE_EXTENDED. With this set,
+ * application may typecast pjmedia_frame to pjmedia_frame_ext.
+ *
+ * This structure may contain more than one audio frames, which subsequently
+ * will be called subframes in this structure. The subframes section
+ * immediately follows the end of this structure, and each subframe is
+ * represented by pjmedia_frame_ext_subframe structure. Every next
+ * subframe immediately follows the previous subframe, and all subframes
+ * are byte-aligned although its payload may not be byte-aligned.
+ */
+
+#pragma pack(1)
+typedef struct pjmedia_frame_ext {
+ pjmedia_frame base; /**< Base frame info */
+ pj_uint16_t samples_cnt; /**< Number of samples in this frame */
+ pj_uint16_t subframe_cnt; /**< Number of (sub)frames in this frame */
+
+ /* Zero or more (sub)frames follows immediately after this,
+ * each will be represented by pjmedia_frame_ext_subframe
+ */
+} pjmedia_frame_ext;
+#pragma pack()
+
+/**
+ * This structure represents the individual subframes in the
+ * pjmedia_frame_ext structure.
+ */
+#pragma pack(1)
+typedef struct pjmedia_frame_ext_subframe {
+ pj_uint16_t bitlen; /**< Number of bits in the data */
+ pj_uint8_t data[1]; /**< Start of encoded data */
+} pjmedia_frame_ext_subframe;
+
+#pragma pack()
+
+
+/**
+ * Append one subframe to #pjmedia_frame_ext.
+ *
+ * @param frm The #pjmedia_frame_ext.
+ * @param src Subframe data.
+ * @param bitlen Lenght of subframe, in bits.
+ * @param samples_cnt Number of audio samples in subframe.
+ */
+PJ_INLINE(void) pjmedia_frame_ext_append_subframe(pjmedia_frame_ext *frm,
+ const void *src,
+ unsigned bitlen,
+ unsigned samples_cnt)
+{
+ pjmedia_frame_ext_subframe *fsub;
+ pj_uint8_t *p;
+ unsigned i;
+
+ p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
+ for (i = 0; i < frm->subframe_cnt; ++i) {
+ fsub = (pjmedia_frame_ext_subframe*) p;
+ p += sizeof(fsub->bitlen) + ((fsub->bitlen+7) >> 3);
+ }
+
+ fsub = (pjmedia_frame_ext_subframe*) p;
+ fsub->bitlen = (pj_uint16_t)bitlen;
+ if (bitlen)
+ pj_memcpy(fsub->data, src, (bitlen+7) >> 3);
+
+ frm->subframe_cnt++;
+ frm->samples_cnt = (pj_uint16_t)(frm->samples_cnt + samples_cnt);
+}
+
+/**
+ * Get a subframe from #pjmedia_frame_ext.
+ *
+ * @param frm The #pjmedia_frame_ext.
+ * @param n Subframe index, zero based.
+ *
+ * @return The n-th subframe, or NULL if n is out-of-range.
+ */
+PJ_INLINE(pjmedia_frame_ext_subframe*)
+pjmedia_frame_ext_get_subframe(const pjmedia_frame_ext *frm, unsigned n)
+{
+ pjmedia_frame_ext_subframe *sf = NULL;
+
+ if (n < frm->subframe_cnt) {
+ pj_uint8_t *p;
+ unsigned i;
+
+ p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
+ for (i = 0; i < n; ++i) {
+ sf = (pjmedia_frame_ext_subframe*) p;
+ p += sizeof(sf->bitlen) + ((sf->bitlen+7) >> 3);
+ }
+
+ sf = (pjmedia_frame_ext_subframe*) p;
+ }
+
+ return sf;
+}
+
+/**
+ * Extract all frame payload to the specified buffer.
+ *
+ * @param frm The frame.
+ * @param dst Destination buffer.
+ * @param maxsize Maximum size to copy (i.e. the size of the
+ * destination buffer).
+ *
+ * @return Total size of payload copied.
+ */
+PJ_INLINE(unsigned)
+pjmedia_frame_ext_copy_payload(const pjmedia_frame_ext *frm,
+ void *dst,
+ unsigned maxlen)
+{
+ unsigned i, copied=0;
+ for (i=0; i<frm->subframe_cnt; ++i) {
+ pjmedia_frame_ext_subframe *sf;
+ unsigned sz;
+
+ sf = pjmedia_frame_ext_get_subframe(frm, i);
+ if (!sf)
+ continue;
+
+ sz = ((sf->bitlen + 7) >> 3);
+ if (sz + copied > maxlen)
+ break;
+
+ pj_memcpy(((pj_uint8_t*)dst) + copied, sf->data, sz);
+ copied += sz;
+ }
+ return copied;
+}
+
+
+/**
+ * Pop out first n subframes from #pjmedia_frame_ext.
+ *
+ * @param frm The #pjmedia_frame_ext.
+ * @param n Number of first subframes to be popped out.
+ *
+ * @return PJ_SUCCESS when successful.
+ */
+PJ_INLINE(pj_status_t)
+pjmedia_frame_ext_pop_subframes(pjmedia_frame_ext *frm, unsigned n)
+{
+ pjmedia_frame_ext_subframe *sf;
+ pj_uint8_t *move_src;
+ unsigned move_len;
+
+ if (frm->subframe_cnt <= n) {
+ frm->subframe_cnt = 0;
+ frm->samples_cnt = 0;
+ return PJ_SUCCESS;
+ }
+
+ move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n);
+ sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1);
+ move_len = (pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) +
+ ((sf->bitlen+7) >> 3);
+ pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext),
+ move_src, move_len);
+
+ frm->samples_cnt = (pj_uint16_t)
+ (frm->samples_cnt - n*frm->samples_cnt/frm->subframe_cnt);
+ frm->subframe_cnt = (pj_uint16_t) (frm->subframe_cnt - n);
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TYPES_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_playlist.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_playlist.h
new file mode 100644
index 0000000..63b5c62
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_playlist.h
@@ -0,0 +1,105 @@
+/* $Id: wav_playlist.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_WAV_PLAYLIST_H__
+#define __PJMEDIA_WAV_PLAYLIST_H__
+
+/**
+ * @file wav_playlist.h
+ * @brief WAV file playlist.
+ */
+#include <pjmedia/wav_port.h>
+
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_WAV_PLAYLIST WAV File Play List
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio playback of multiple WAV files
+ * @{
+ *
+ * The WAV play list port enables application to play back multiple
+ * WAV files in a playlist.
+ */
+
+/**
+ * Create a WAV playlist from the array of WAV file names. The WAV
+ * files must have the same clock rate, number of channels, and bits
+ * per sample, or otherwise this function will return error.
+ *
+ * @param pool Pool to create memory buffers for this port.
+ * @param port_label Optional label to set as the port name.
+ * @param file_list Array of WAV file names.
+ * @param file_count Number of files in the array.
+ * @param ptime The duration (in miliseconds) of each frame read
+ * from this port. If the value is zero, the default
+ * duration (20ms) will be used.
+ * @param options Optional options. Application may specify
+ * PJMEDIA_FILE_NO_LOOP to prevent play back loop.
+ * @param buff_size Buffer size to be allocated. If the value is zero or
+ * negative, the port will use default buffer size (which
+ * is about 4KB).
+ * @param p_port Pointer to receive the file port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,
+ const pj_str_t *port_label,
+ const pj_str_t file_list[],
+ int file_count,
+ unsigned ptime,
+ unsigned options,
+ pj_ssize_t buff_size,
+ pjmedia_port **p_port);
+
+
+/**
+ * Register a callback to be called when the file reading has reached the
+ * end of file of the last file. If the file is set to play repeatedly,
+ * then the callback will be called multiple times. Note that only one
+ * callback can be registered for each file port.
+ *
+ * @param port The WAV play list port.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the playback will stop. Note that if
+ * application destroys the file port in the callback,
+ * it must return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_wav_playlist_set_eof_cb(pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_WAV_PLAYLIST_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_port.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_port.h
new file mode 100644
index 0000000..e3cd922
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_port.h
@@ -0,0 +1,250 @@
+/* $Id: wav_port.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_WAV_PORT_H__
+#define __PJMEDIA_WAV_PORT_H__
+
+/**
+ * @file wav_port.h
+ * @brief WAV file player and writer.
+ */
+#include <pjmedia/port.h>
+
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_FILE_PLAY WAV File Player
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio playback from WAV file
+ * @{
+ */
+
+/**
+ * WAV file player options.
+ */
+enum pjmedia_file_player_option
+{
+ /**
+ * Tell the file player to return NULL frame when the whole
+ * file has been played.
+ */
+ PJMEDIA_FILE_NO_LOOP = 1
+};
+
+
+/**
+ * Create a media port to play streams from a WAV file. WAV player port
+ * supports for reading WAV file with uncompressed 16 bit PCM format or
+ * compressed G.711 A-law/U-law format.
+ *
+ * @param pool Pool to create memory buffers for this port.
+ * @param filename File name to open.
+ * @param ptime The duration (in miliseconds) of each frame read
+ * from this port. If the value is zero, the default
+ * duration (20ms) will be used.
+ * @param flags Port creation flags.
+ * @param buff_size Buffer size to be allocated. If the value is zero or
+ * negative, the port will use default buffer size (which
+ * is about 4KB).
+ * @param p_port Pointer to receive the file port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
+ const char *filename,
+ unsigned ptime,
+ unsigned flags,
+ pj_ssize_t buff_size,
+ pjmedia_port **p_port );
+
+
+/**
+ * Get the data length, in bytes.
+ *
+ * @param port The file player port.
+ *
+ * @return The length of the data, in bytes. Upon error it will
+ * return negative value.
+ */
+PJ_DECL(pj_ssize_t) pjmedia_wav_player_get_len(pjmedia_port *port);
+
+
+/**
+ * Set the file play position of WAV player.
+ *
+ * @param port The file player port.
+ * @param offset Playback position in bytes, relative to the start of
+ * the payload.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_wav_player_port_set_pos( pjmedia_port *port,
+ pj_uint32_t offset );
+
+
+/**
+ * Get the file play position of WAV player.
+ *
+ * @param port The file player port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_ssize_t) pjmedia_wav_player_port_get_pos( pjmedia_port *port );
+
+
+/**
+ * Register a callback to be called when the file reading has reached the
+ * end of file. If the file is set to play repeatedly, then the callback
+ * will be called multiple times. Note that only one callback can be
+ * registered for each file port.
+ *
+ * @param port The file player port.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the playback will stop. Note that if
+ * application destroys the file port in the callback,
+ * it must return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_wav_player_set_eof_cb( pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup PJMEDIA_FILE_REC File Writer (Recorder)
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio capture/recording to WAV file
+ * @{
+ */
+
+
+/**
+ * WAV file writer options.
+ */
+enum pjmedia_file_writer_option
+{
+ /**
+ * Tell the file writer to save the audio in PCM format.
+ */
+ PJMEDIA_FILE_WRITE_PCM = 0,
+
+ /**
+ * Tell the file writer to save the audio in G711 Alaw format.
+ */
+ PJMEDIA_FILE_WRITE_ALAW = 1,
+
+ /**
+ * Tell the file writer to save the audio in G711 Alaw format.
+ */
+ PJMEDIA_FILE_WRITE_ULAW = 2,
+};
+
+
+/**
+ * Create a media port to record streams to a WAV file. Note that the port
+ * must be closed properly (with #pjmedia_port_destroy()) so that the WAV
+ * header can be filled with correct values (such as the file length).
+ * WAV writer port supports for writing audio in uncompressed 16 bit PCM format
+ * or compressed G.711 U-law/A-law format, this needs to be specified in
+ * \a flags param.
+ *
+ * @param pool Pool to create memory buffers for this port.
+ * @param filename File name.
+ * @param clock_rate The sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample (eg 16).
+ * @param flags Port creation flags, see
+ * #pjmedia_file_writer_option.
+ * @param buff_size Buffer size to be allocated. If the value is
+ * zero or negative, the port will use default buffer
+ * size (which is about 4KB).
+ * @param p_port Pointer to receive the file port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_wav_writer_port_create(pj_pool_t *pool,
+ const char *filename,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned flags,
+ pj_ssize_t buff_size,
+ pjmedia_port **p_port );
+
+
+/**
+ * Get current writing position. Note that this does not necessarily match
+ * the size written to the file, since the WAV writer employs some internal
+ * buffering. Also the value reported here only indicates the payload size
+ * (it does not include the size of the WAV header),
+ *
+ * @param port The file writer port.
+ *
+ * @return Positive value to indicate the position (in bytes),
+ * or negative value containing the error code.
+ */
+PJ_DECL(pj_ssize_t) pjmedia_wav_writer_port_get_pos( pjmedia_port *port );
+
+
+/**
+ * Register the callback to be called when the file writing has reached
+ * certain size. Application can use this callback, for example, to limit
+ * the size of the output file.
+ *
+ * @param port The file writer port.
+ * @param pos The file position on which the callback will be called.
+ * @param user_data User data to be specified in the callback, and will be
+ * given on the callback.
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the writing will stop. Note that if
+ * application destroys the port in the callback, it must
+ * return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_wav_writer_port_set_cb( pjmedia_port *port,
+ pj_size_t pos,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_WAV_PORT_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wave.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wave.h
new file mode 100644
index 0000000..66320f8
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wave.h
@@ -0,0 +1,184 @@
+/* $Id: wave.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_WAVE_H__
+#define __PJMEDIA_WAVE_H__
+
+
+/**
+ * @file wave.h
+ * @brief WAVE file manipulation.
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMEDIA_FILE_FORMAT File Formats
+ * @brief Supported file formats
+ */
+
+
+/**
+ * @defgroup PJMEDIA_WAVE WAVE Header
+ * @ingroup PJMEDIA_FILE_FORMAT
+ * @brief Representation of RIFF/WAVE file format
+ * @{
+ *
+ * This the the low level representation of RIFF/WAVE file format. For
+ * higher abstraction, please see \ref PJMEDIA_FILE_PLAY and
+ * \ref PJMEDIA_FILE_REC.
+ */
+
+
+PJ_BEGIN_DECL
+
+/**
+ * Standard RIFF tag to identify RIFF file format in the WAVE header.
+ */
+#define PJMEDIA_RIFF_TAG ('F'<<24|'F'<<16|'I'<<8|'R')
+
+/**
+ * Standard WAVE tag to identify WAVE header.
+ */
+#define PJMEDIA_WAVE_TAG ('E'<<24|'V'<<16|'A'<<8|'W')
+
+/**
+ * Standard FMT tag to identify format chunks.
+ */
+#define PJMEDIA_FMT_TAG (' '<<24|'t'<<16|'m'<<8|'f')
+
+/**
+ * Standard DATA tag to identify data chunks.
+ */
+#define PJMEDIA_DATA_TAG ('a'<<24|'t'<<16|'a'<<8|'d')
+
+/**
+ * Standard FACT tag to identify fact chunks.
+ */
+#define PJMEDIA_FACT_TAG ('t'<<24|'c'<<16|'a'<<8|'f')
+
+
+/**
+ * Enumeration of format compression tag.
+ */
+typedef enum {
+ PJMEDIA_WAVE_FMT_TAG_PCM = 1,
+ PJMEDIA_WAVE_FMT_TAG_ALAW = 6,
+ PJMEDIA_WAVE_FMT_TAG_ULAW = 7
+} pjmedia_wave_fmt_tag;
+
+
+/**
+ * This file describes the simpler/canonical version of a WAVE file.
+ * It does not support the full RIFF format specification.
+ */
+#pragma pack(2)
+struct pjmedia_wave_hdr
+{
+ /** This structure describes RIFF WAVE file header */
+ struct {
+ pj_uint32_t riff; /**< "RIFF" ASCII tag. */
+ pj_uint32_t file_len; /**< File length minus 8 bytes */
+ pj_uint32_t wave; /**< "WAVE" ASCII tag. */
+ } riff_hdr;
+
+ /** This structure describes format chunks/header */
+ struct {
+ pj_uint32_t fmt; /**< "fmt " ASCII tag. */
+ pj_uint32_t len; /**< 16 for PCM. */
+ pj_uint16_t fmt_tag; /**< 1 for PCM */
+ pj_uint16_t nchan; /**< Number of channels. */
+ pj_uint32_t sample_rate; /**< Sampling rate. */
+ pj_uint32_t bytes_per_sec; /**< Average bytes per second. */
+ pj_uint16_t block_align; /**< nchannels * bits / 8 */
+ pj_uint16_t bits_per_sample; /**< Bits per sample. */
+ } fmt_hdr;
+
+ /** The data header preceeds the actual data in the file. */
+ struct {
+ pj_uint32_t data; /**< "data" ASCII tag. */
+ pj_uint32_t len; /**< Data length. */
+ } data_hdr;
+};
+#pragma pack()
+
+/**
+ * @see pjmedia_wave_hdr
+ */
+typedef struct pjmedia_wave_hdr pjmedia_wave_hdr;
+
+/**
+ * This structure describes generic RIFF subchunk header.
+ */
+typedef struct pjmedia_wave_subchunk
+{
+ pj_uint32_t id; /**< Subchunk ASCII tag. */
+ pj_uint32_t len; /**< Length following this field */
+} pjmedia_wave_subchunk;
+
+
+/**
+ * Normalize subchunk header from little endian (the representation of
+ * RIFF file) into host's endian.
+ */
+#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
+# define PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(ch) \
+ do { \
+ (ch)->id = pj_swap32((ch)->id); \
+ (ch)->len = pj_swap32((ch)->len); \
+ } while (0)
+#else
+# define PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(ch)
+#endif
+
+
+/**
+ * On big-endian hosts, this function swaps the byte order of the values
+ * in the WAVE header fields. On little-endian hosts, this function does
+ * nothing.
+ *
+ * Application SHOULD call this function after reading the WAVE header
+ * chunks from a file.
+ *
+ * @param hdr The WAVE header.
+ */
+PJ_DECL(void) pjmedia_wave_hdr_file_to_host( pjmedia_wave_hdr *hdr );
+
+
+/**
+ * On big-endian hosts, this function swaps the byte order of the values
+ * in the WAVE header fields. On little-endian hosts, this function does
+ * nothing.
+ *
+ * Application SHOULD call this function before writing the WAVE header
+ * to a file.
+ *
+ * @param hdr The WAVE header.
+ */
+PJ_DECL(void) pjmedia_wave_hdr_host_to_file( pjmedia_wave_hdr *hdr );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_WAVE_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wsola.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wsola.h
new file mode 100644
index 0000000..92c3eb8
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wsola.h
@@ -0,0 +1,219 @@
+/* $Id: wsola.h 2850 2009-08-01 09:20:59Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_WSOLA_H__
+#define __PJMEDIA_WSOLA_H__
+
+/**
+ * @file wsola.h
+ * @brief Waveform Similarity Based Overlap-Add (WSOLA)
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMED_WSOLA Waveform Similarity Based Overlap-Add (WSOLA)
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Time-scale modification to audio without affecting the pitch
+ * @{
+ *
+ * This section describes Waveform Similarity Based Overlap-Add (WSOLA)
+ * implementation in PJMEDIA. The WSOLA API here can be used both to
+ * compress (speed-up) and stretch (expand, slow down) audio playback
+ * without altering the pitch, or as a mean for performing packet loss
+ * concealment (WSOLA).
+ *
+ * The WSOLA implementation is used by \ref PJMED_DELAYBUF and \ref PJMED_PLC.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for WSOLA structure.
+ */
+typedef struct pjmedia_wsola pjmedia_wsola;
+
+
+/**
+ * WSOLA options, can be combined with bitmask operation.
+ */
+enum pjmedia_wsola_option
+{
+ /**
+ * Disable Hanning window to conserve memory.
+ */
+ PJMEDIA_WSOLA_NO_HANNING = 1,
+
+ /**
+ * Specify that the WSOLA will not be used for PLC.
+ */
+ PJMEDIA_WSOLA_NO_PLC = 2,
+
+ /**
+ * Specify that the WSOLA will not be used to discard frames in
+ * non-contiguous buffer.
+ */
+ PJMEDIA_WSOLA_NO_DISCARD = 4,
+
+ /**
+ * Disable fade-in and fade-out feature in the transition between
+ * actual and synthetic frames in WSOLA. With fade feature enabled,
+ * WSOLA will only generate a limited number of synthetic frames
+ * (configurable with #pjmedia_wsola_set_max_expand()), fading out
+ * the volume on every more samples it generates, and when it reaches
+ * the limit it will only generate silence.
+ */
+ PJMEDIA_WSOLA_NO_FADING = 8
+};
+
+
+
+/**
+ * Create and initialize WSOLA.
+ *
+ * @param pool Pool to allocate memory for WSOLA.
+ * @param clock_rate Sampling rate of audio playback.
+ * @param samples_per_frame Number of samples per frame.
+ * @param channel_count Number of channels.
+ * @param options Option flags, bitmask combination of
+ * #pjmedia_wsola_option.
+ * @param p_wsola Pointer to receive WSOLA structure.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_create(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ unsigned channel_count,
+ unsigned options,
+ pjmedia_wsola **p_wsola);
+
+
+/**
+ * Specify maximum number of continuous synthetic frames that can be
+ * generated by WSOLA, in milliseconds. This option will only take
+ * effect if fading is not disabled via the option when the WSOLA
+ * session was created. Default value is PJMEDIA_WSOLA_MAX_EXPAND_MSEC
+ * (see also the documentation of PJMEDIA_WSOLA_MAX_EXPAND_MSEC for
+ * more information).
+ *
+ * @param wsola The WSOLA session
+ * @param msec The duration.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_set_max_expand(pjmedia_wsola *wsola,
+ unsigned msec);
+
+
+/**
+ * Destroy WSOLA.
+ *
+ * @param wsola WSOLA session.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_destroy(pjmedia_wsola *wsola);
+
+
+/**
+ * Reset the buffer contents of WSOLA.
+ *
+ * @param wsola WSOLA session.
+ * @param options Reset options, must be zero for now.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_reset(pjmedia_wsola *wsola,
+ unsigned options);
+
+
+/**
+ * Give one good frame to WSOLA to be kept as reference. Application
+ * must continuously give WSOLA good frames to keep its session up to
+ * date with current playback. Depending on the WSOLA implementation,
+ * this function may modify the content of the frame.
+ *
+ * @param wsola WSOLA session.
+ * @param frm The frame, which length must match the samples per
+ * frame setting of the WSOLA session.
+ * @param prev_lost If application previously generated a synthetic
+ * frame with #pjmedia_wsola_generate() before calling
+ * this function, specify whether that was because of
+ * packet lost. If so, set this parameter to PJ_TRUE
+ * to make WSOLA interpolate this frame with its buffer.
+ * Otherwise if this value is PJ_FALSE, WSOLA will
+ * just append this frame to the end of its buffer.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_save(pjmedia_wsola *wsola,
+ pj_int16_t frm[],
+ pj_bool_t prev_lost);
+
+/**
+ * Generate one synthetic frame from WSOLA.
+ *
+ * @param wsola WSOLA session.
+ * @param frm Buffer to receive the frame.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_generate(pjmedia_wsola *wsola,
+ pj_int16_t frm[]);
+
+
+/**
+ * Compress or compact the specified buffer by removing some audio samples
+ * from the buffer, without altering the pitch. For this function to work,
+ * total length of the buffer must be more than twice \a erase_cnt.
+ *
+ * @param wsola WSOLA session.
+ * @param buf1 Pointer to buffer.
+ * @param buf1_cnt Number of samples in the buffer.
+ * @param buf2 Pointer to second buffer, if the buffer is not
+ * contiguous. Otherwise this parameter must be NULL.
+ * @param buf2_cnt Number of samples in the second buffer, if the buffer
+ * is not contiguous. Otherwise this parameter should be
+ * zero.
+ * @param erase_cnt On input, specify the number of samples to be erased.
+ * This function may erase more or less than the requested
+ * number, and the actual number of samples erased will be
+ * given on this argument upon returning from the function.
+ *
+ * @return PJ_SUCCESS if some samples have been erased, PJ_ETOOSMALL
+ * if buffer is too small to be reduced, PJ_EINVAL if any
+ * of the parameters are not valid.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_discard(pjmedia_wsola *wsola,
+ pj_int16_t buf1[],
+ unsigned buf1_cnt,
+ pj_int16_t buf2[],
+ unsigned buf2_cnt,
+ unsigned *erase_cnt);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_WSOLA_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia_audiodev.h b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia_audiodev.h
new file mode 100644
index 0000000..e2d2658
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia_audiodev.h
@@ -0,0 +1,33 @@
+/* $Id: pjmedia_audiodev.h 2506 2009-03-12 18:11:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJMEDIA_AUDIODEV_H__
+#define __PJMEDIA_AUDIODEV_H__
+
+/**
+ * @file pjmedia_audiodev.h
+ * @brief PJMEDIA main header file.
+ */
+
+#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia-audiodev/audiodev_imp.h>
+#include <pjmedia-audiodev/audiotest.h>
+
+#endif /* __PJMEDIA_AUDIODEV_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath.h
new file mode 100644
index 0000000..8897e0d
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath.h
@@ -0,0 +1,35 @@
+/* $Id: pjnath.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <pjnath/config.h>
+#include <pjnath/errno.h>
+#include <pjnath/ice_session.h>
+#include <pjnath/ice_strans.h>
+#include <pjnath/nat_detect.h>
+#include <pjnath/stun_auth.h>
+#include <pjnath/stun_config.h>
+#include <pjnath/stun_msg.h>
+#include <pjnath/stun_session.h>
+#include <pjnath/stun_sock.h>
+#include <pjnath/stun_transaction.h>
+#include <pjnath/turn_session.h>
+#include <pjnath/turn_sock.h>
+#include <pjnath/types.h>
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/config.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/config.h
new file mode 100644
index 0000000..4f1a57e
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/config.h
@@ -0,0 +1,476 @@
+/* $Id: config.h 2966 2009-10-25 09:02:07Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_CONFIG_H__
+#define __PJNATH_CONFIG_H__
+
+
+/**
+ * @file config.h
+ * @brief Compile time settings
+ */
+
+#include <pj/types.h>
+
+/**
+ * @defgroup PJNATH_CONFIG Compile-time configurations
+ * @brief Various compile time settings
+ * @ingroup PJNATH_STUN_BASE
+ * @{
+ */
+
+
+/* **************************************************************************
+ * GENERAL
+ */
+
+/**
+ * The log level for PJNATH error display.
+ *
+ * default 1
+ */
+#ifndef PJNATH_ERROR_LEVEL
+# define PJNATH_ERROR_LEVEL 1
+#endif
+
+
+/* **************************************************************************
+ * STUN CONFIGURATION
+ */
+
+/**
+ * Maximum number of attributes in the STUN packet (for the new STUN
+ * library).
+ *
+ * Default: 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
+
+
+/**
+ * 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 16x RTO (as per RFC 3489-bis).
+ */
+#ifndef PJ_STUN_TIMEOUT_VALUE
+# define PJ_STUN_TIMEOUT_VALUE (16 * PJ_STUN_RTO_VALUE)
+#endif
+
+
+/**
+ * Maximum number of STUN transmission count.
+ *
+ * Default: 7 (as per RFC 3489-bis)
+ */
+#ifndef PJ_STUN_MAX_TRANSMIT_COUNT
+# define PJ_STUN_MAX_TRANSMIT_COUNT 7
+#endif
+
+
+/**
+ * Duration to keep response in the cache, in msec.
+ *
+ * Default: 10000 (as per RFC 3489-bis)
+ */
+#ifndef PJ_STUN_RES_CACHE_DURATION
+# define PJ_STUN_RES_CACHE_DURATION 10000
+#endif
+
+
+/**
+ * Maximum size of STUN message.
+ */
+#ifndef PJ_STUN_MAX_PKT_LEN
+# define PJ_STUN_MAX_PKT_LEN 800
+#endif
+
+
+/**
+ * Default STUN port as defined by RFC 3489.
+ */
+#define PJ_STUN_PORT 3478
+
+
+/**
+ * Padding character for string attributes.
+ *
+ * Default: ASCII 0
+ */
+#ifndef PJ_STUN_STRING_ATTR_PAD_CHR
+# define PJ_STUN_STRING_ATTR_PAD_CHR 0
+#endif
+
+
+/**
+ * Enable pre-RFC3489bis-07 style of STUN MESSAGE-INTEGRITY and FINGERPRINT
+ * calculation. By default this should be disabled since the calculation is
+ * not backward compatible with current STUN specification.
+ */
+#ifndef PJ_STUN_OLD_STYLE_MI_FINGERPRINT
+# define PJ_STUN_OLD_STYLE_MI_FINGERPRINT 0
+#endif
+
+
+/* **************************************************************************
+ * STUN TRANSPORT CONFIGURATION
+ */
+
+/**
+ * The packet buffer size for the STUN transport.
+ */
+#ifndef PJ_STUN_SOCK_PKT_LEN
+# define PJ_STUN_SOCK_PKT_LEN 2000
+#endif
+
+
+/**
+ * The duration of the STUN keep-alive period, in seconds.
+ */
+#ifndef PJ_STUN_KEEP_ALIVE_SEC
+# define PJ_STUN_KEEP_ALIVE_SEC 15
+#endif
+
+
+/* **************************************************************************
+ * TURN CONFIGURATION
+ */
+
+/**
+ * Maximum DNS SRV entries to be processed in the DNS SRV response
+ */
+#ifndef PJ_TURN_MAX_DNS_SRV_CNT
+# define PJ_TURN_MAX_DNS_SRV_CNT 4
+#endif
+
+
+/**
+ * Maximum TURN packet size to be supported.
+ */
+#ifndef PJ_TURN_MAX_PKT_LEN
+# define PJ_TURN_MAX_PKT_LEN 3000
+#endif
+
+
+/**
+ * The TURN permission lifetime setting. This value should be taken from the
+ * TURN protocol specification.
+ */
+#ifndef PJ_TURN_PERM_TIMEOUT
+# define PJ_TURN_PERM_TIMEOUT 300
+#endif
+
+
+/**
+ * The TURN channel binding lifetime. This value should be taken from the
+ * TURN protocol specification.
+ */
+#ifndef PJ_TURN_CHANNEL_TIMEOUT
+# define PJ_TURN_CHANNEL_TIMEOUT 600
+#endif
+
+
+/**
+ * Number of seconds to refresh the permission/channel binding before the
+ * permission/channel binding expires. This value should be greater than
+ * PJ_TURN_PERM_TIMEOUT setting.
+ */
+#ifndef PJ_TURN_REFRESH_SEC_BEFORE
+# define PJ_TURN_REFRESH_SEC_BEFORE 60
+#endif
+
+
+/**
+ * The TURN session timer heart beat interval. When this timer occurs, the
+ * TURN session will scan all the permissions/channel bindings to see which
+ * need to be refreshed.
+ */
+#ifndef PJ_TURN_KEEP_ALIVE_SEC
+# define PJ_TURN_KEEP_ALIVE_SEC 15
+#endif
+
+
+/* **************************************************************************
+ * ICE CONFIGURATION
+ */
+
+/**
+ * Maximum number of ICE candidates.
+ *
+ * Default: 16
+ */
+#ifndef PJ_ICE_MAX_CAND
+# define PJ_ICE_MAX_CAND 16
+#endif
+
+
+/**
+ * Maximum number of candidates for each ICE stream transport component.
+ *
+ * Default: 8
+ */
+#ifndef PJ_ICE_ST_MAX_CAND
+# define PJ_ICE_ST_MAX_CAND 8
+#endif
+
+
+/**
+ * The number of bits to represent component IDs. This will affect
+ * the maximum number of components (PJ_ICE_MAX_COMP) value.
+ */
+#ifndef PJ_ICE_COMP_BITS
+# define PJ_ICE_COMP_BITS 1
+#endif
+
+
+/**
+ * Maximum number of ICE components.
+ */
+#define PJ_ICE_MAX_COMP (2<<PJ_ICE_COMP_BITS)
+
+/**
+ * Use the priority value according to the ice-draft.
+ */
+#ifndef PJNATH_ICE_PRIO_STD
+# define PJNATH_ICE_PRIO_STD 1
+#endif
+
+
+/**
+ * The number of bits to represent candidate type preference.
+ */
+#ifndef PJ_ICE_CAND_TYPE_PREF_BITS
+# if PJNATH_ICE_PRIO_STD
+# define PJ_ICE_CAND_TYPE_PREF_BITS 8
+# else
+# define PJ_ICE_CAND_TYPE_PREF_BITS 2
+# endif
+#endif
+
+
+/**
+ * The number of bits to represent ICE candidate's local preference. The
+ * local preference is used to specify preference among candidates with
+ * the same type, and ICE draft suggests 65535 as the default local
+ * preference, which means we need 16 bits to represent the value. But
+ * since we don't have the facility to specify local preference, we'll
+ * just disable this feature and let the preference sorted by the
+ * type only.
+ *
+ * Default: 0
+ */
+#ifndef PJ_ICE_LOCAL_PREF_BITS
+# define PJ_ICE_LOCAL_PREF_BITS 0
+#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
+
+
+/**
+ * According to ICE Section 8.2. Updating States, if an In-Progress pair in
+ * the check list is for the same component as a nominated pair, the agent
+ * SHOULD cease retransmissions for its check if its pair priority is lower
+ * than the lowest priority nominated pair for that component.
+ *
+ * If a higher priority check is In Progress, this rule would cause that
+ * check to be performed even when it most likely will fail.
+ *
+ * The macro here controls if ICE session should cancel all In Progress
+ * checks for the same component regardless of its priority.
+ *
+ * Default: 1 (yes, cancel all)
+ */
+#ifndef PJ_ICE_CANCEL_ALL
+# define PJ_ICE_CANCEL_ALL 1
+#endif
+
+
+/**
+ * For a controlled agent, specify how long it wants to wait (in milliseconds)
+ * for the controlling agent to complete sending connectivity check with
+ * nominated flag set to true for all components after the controlled agent
+ * has found that all connectivity checks in its checklist have been completed
+ * and there is at least one successful (but not nominated) check for every
+ * component.
+ *
+ * When selecting the value, bear in mind that the connectivity check from
+ * controlling agent may be delayed because of delay in receiving SDP answer
+ * from the controlled agent.
+ *
+ * Application may set this value to -1 to disable this timer.
+ *
+ * Default: 10000 (milliseconds)
+ */
+#ifndef ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT
+# define ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT 10000
+#endif
+
+
+/**
+ * For controlling agent if it uses regular nomination, specify the delay to
+ * perform nominated check (connectivity check with USE-CANDIDATE attribute)
+ * after all components have a valid pair.
+ *
+ * Default: 4*PJ_STUN_RTO_VALUE (milliseconds)
+ */
+#ifndef PJ_ICE_NOMINATED_CHECK_DELAY
+# define PJ_ICE_NOMINATED_CHECK_DELAY (4*PJ_STUN_RTO_VALUE)
+#endif
+
+
+/**
+ * Minimum interval value to be used for sending STUN keep-alive on the ICE
+ * session, in seconds. This minimum interval, plus a random value
+ * which maximum is PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND, specify the actual interval
+ * of the STUN keep-alive.
+ *
+ * Default: 15 seconds
+ *
+ * @see PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND
+ */
+#ifndef PJ_ICE_SESS_KEEP_ALIVE_MIN
+# define PJ_ICE_SESS_KEEP_ALIVE_MIN 20
+#endif
+
+/* Warn about deprecated macro */
+#ifdef PJ_ICE_ST_KEEP_ALIVE_MIN
+# error PJ_ICE_ST_KEEP_ALIVE_MIN is deprecated
+#endif
+
+/**
+ * To prevent STUN keep-alives to be sent simultaneously, application should
+ * add random interval to minimum interval (PJ_ICE_SESS_KEEP_ALIVE_MIN). This
+ * setting specifies the maximum random value to be added to the minimum
+ * interval, in seconds.
+ *
+ * Default: 5 seconds
+ *
+ * @see PJ_ICE_SESS_KEEP_ALIVE_MIN
+ */
+#ifndef PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND
+# define PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND 5
+#endif
+
+/* Warn about deprecated macro */
+#ifdef PJ_ICE_ST_KEEP_ALIVE_MAX_RAND
+# error PJ_ICE_ST_KEEP_ALIVE_MAX_RAND is deprecated
+#endif
+
+
+/**
+ * This constant specifies the length of random string generated for ICE
+ * ufrag and password.
+ *
+ * Default: 8 (characters)
+ */
+#ifndef PJ_ICE_UFRAG_LEN
+# define PJ_ICE_UFRAG_LEN 8
+#endif
+
+
+/** ICE session pool initial size. */
+#ifndef PJNATH_POOL_LEN_ICE_SESS
+# define PJNATH_POOL_LEN_ICE_SESS 512
+#endif
+
+/** ICE session pool increment size */
+#ifndef PJNATH_POOL_INC_ICE_SESS
+# define PJNATH_POOL_INC_ICE_SESS 512
+#endif
+
+/** ICE stream transport pool initial size. */
+#ifndef PJNATH_POOL_LEN_ICE_STRANS
+# define PJNATH_POOL_LEN_ICE_STRANS 1000
+#endif
+
+/** ICE stream transport pool increment size */
+#ifndef PJNATH_POOL_INC_ICE_STRANS
+# define PJNATH_POOL_INC_ICE_STRANS 512
+#endif
+
+/** NAT detect pool initial size */
+#ifndef PJNATH_POOL_LEN_NATCK
+# define PJNATH_POOL_LEN_NATCK 512
+#endif
+
+/** NAT detect pool increment size */
+#ifndef PJNATH_POOL_INC_NATCK
+# define PJNATH_POOL_INC_NATCK 512
+#endif
+
+/** STUN session pool initial size */
+#ifndef PJNATH_POOL_LEN_STUN_SESS
+# define PJNATH_POOL_LEN_STUN_SESS 1000
+#endif
+
+/** STUN session pool increment size */
+#ifndef PJNATH_POOL_INC_STUN_SESS
+# define PJNATH_POOL_INC_STUN_SESS 1000
+#endif
+
+/** STUN session transmit data pool initial size */
+#ifndef PJNATH_POOL_LEN_STUN_TDATA
+# define PJNATH_POOL_LEN_STUN_TDATA 1000
+#endif
+
+/** STUN session transmit data pool increment size */
+#ifndef PJNATH_POOL_INC_STUN_TDATA
+# define PJNATH_POOL_INC_STUN_TDATA 1000
+#endif
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJNATH_CONFIG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/errno.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/errno.h
new file mode 100644
index 0000000..3c28292
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/errno.h
@@ -0,0 +1,221 @@
+/* $Id: errno.h 2724 2009-05-29 13:04:03Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_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
+ * @brief PJNATH specific error code constants
+ * @ingroup PJNATH_STUN_BASE
+ * @{
+ */
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ * This value is 370000.
+ */
+#define PJNATH_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4)
+
+
+/************************************************************
+ * STUN MESSAGING ERRORS
+ ***********************************************************/
+
+/**
+ * Map STUN error code (300-699) into pj_status_t error space.
+ */
+#define PJ_STATUS_FROM_STUN_CODE(code) (PJNATH_ERRNO_START+code)
+
+/**
+ * @hideinitializer
+ * Invalid STUN message
+ */
+#define PJNATH_EINSTUNMSG (PJNATH_ERRNO_START+1) /* 370001 */
+/**
+ * @hideinitializer
+ * Invalid STUN message length.
+ */
+#define PJNATH_EINSTUNMSGLEN (PJNATH_ERRNO_START+2) /* 370002 */
+/**
+ * @hideinitializer
+ * Invalid or unexpected STUN message type
+ */
+#define PJNATH_EINSTUNMSGTYPE (PJNATH_ERRNO_START+3) /* 370003 */
+/**
+ * @hideinitializer
+ * STUN transaction has timed out
+ */
+#define PJNATH_ESTUNTIMEDOUT (PJNATH_ERRNO_START+4) /* 370004 */
+
+
+/**
+ * @hideinitializer
+ * Too many STUN attributes.
+ */
+#define PJNATH_ESTUNTOOMANYATTR (PJNATH_ERRNO_START+21) /* 370021 */
+/**
+ * @hideinitializer
+ * Invalid STUN attribute length.
+ */
+#define PJNATH_ESTUNINATTRLEN (PJNATH_ERRNO_START+22) /* 370022 */
+/**
+ * @hideinitializer
+ * Found duplicate STUN attribute.
+ */
+#define PJNATH_ESTUNDUPATTR (PJNATH_ERRNO_START+23) /* 370023 */
+
+/**
+ * @hideinitializer
+ * STUN FINGERPRINT verification failed
+ */
+#define PJNATH_ESTUNFINGERPRINT (PJNATH_ERRNO_START+30) /* 370030 */
+/**
+ * @hideinitializer
+ * Invalid STUN attribute after MESSAGE-INTEGRITY.
+ */
+#define PJNATH_ESTUNMSGINTPOS (PJNATH_ERRNO_START+31) /* 370031 */
+/**
+ * @hideinitializer
+ * Invalid STUN attribute after FINGERPRINT.
+ */
+#define PJNATH_ESTUNFINGERPOS (PJNATH_ERRNO_START+33) /* 370033 */
+
+
+/**
+ * @hideinitializer
+ * STUN (XOR-)MAPPED-ADDRESS attribute not found
+ */
+#define PJNATH_ESTUNNOMAPPEDADDR (PJNATH_ERRNO_START+40) /* 370040 */
+/**
+ * @hideinitializer
+ * STUN IPv6 attribute not supported
+ */
+#define PJNATH_ESTUNIPV6NOTSUPP (PJNATH_ERRNO_START+41) /* 370041 */
+/**
+ * @hideinitializer
+ * Invalid address family value in STUN message.
+ */
+#define PJNATH_EINVAF (PJNATH_ERRNO_START+42) /* 370042 */
+
+/**
+ * @hideinitializer
+ * Invalid STUN server or server not configured.
+ */
+#define PJNATH_ESTUNINSERVER (PJNATH_ERRNO_START+50) /* 370050 */
+
+
+/************************************************************
+ * STUN SESSION/TRANSPORT ERROR CODES
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * STUN object has been destoyed.
+ */
+#define PJNATH_ESTUNDESTROYED (PJNATH_ERRNO_START+60) /* 370060 */
+
+
+/************************************************************
+ * ICE ERROR CODES
+ ***********************************************************/
+
+/**
+ * @hideinitializer
+ * ICE session not available
+ */
+#define PJNATH_ENOICE (PJNATH_ERRNO_START+80) /* 370080 */
+/**
+ * @hideinitializer
+ * ICE check is in progress
+ */
+#define PJNATH_EICEINPROGRESS (PJNATH_ERRNO_START+81) /* 370081 */
+/**
+ * @hideinitializer
+ * All ICE checklists failed
+ */
+#define PJNATH_EICEFAILED (PJNATH_ERRNO_START+82) /* 370082 */
+/**
+ * @hideinitializer
+ * Default destination does not match any ICE candidates
+ */
+#define PJNATH_EICEMISMATCH (PJNATH_ERRNO_START+83) /* 370083 */
+/**
+ * @hideinitializer
+ * Invalid ICE component ID
+ */
+#define PJNATH_EICEINCOMPID (PJNATH_ERRNO_START+86) /* 370086 */
+/**
+ * @hideinitializer
+ * Invalid ICE candidate ID
+ */
+#define PJNATH_EICEINCANDID (PJNATH_ERRNO_START+87) /* 370087 */
+/**
+ * @hideinitializer
+ * Source address mismatch. This error occurs if the source address
+ * of the response for ICE connectivity check is different than
+ * the destination address of the request.
+ */
+#define PJNATH_EICEINSRCADDR (PJNATH_ERRNO_START+88) /* 370088 */
+/**
+ * @hideinitializer
+ * Missing ICE SDP attribute
+ */
+#define PJNATH_EICEMISSINGSDP (PJNATH_ERRNO_START+90) /* 370090 */
+/**
+ * @hideinitializer
+ * Invalid SDP "candidate" attribute
+ */
+#define PJNATH_EICEINCANDSDP (PJNATH_ERRNO_START+91) /* 370091 */
+/**
+ * @hideinitializer
+ * No host candidate associated with srflx. This error occurs when
+ * a server reflexive candidate is added without the matching
+ * host candidate.
+ */
+#define PJNATH_EICENOHOSTCAND (PJNATH_ERRNO_START+92) /* 370092 */
+/**
+ * @hideinitializer
+ * Controlled agent timed-out in waiting for the controlling agent to
+ * send nominated check after all connectivity checks have completed.
+ */
+#define PJNATH_EICENOMTIMEOUT (PJNATH_ERRNO_START+93) /* 370093 */
+
+/************************************************************
+ * TURN ERROR CODES
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Invalid or unsupported TURN transport.
+ */
+#define PJNATH_ETURNINTP (PJNATH_ERRNO_START+120) /* 370120 */
+
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJNATH_ERRNO_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_session.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_session.h
new file mode 100644
index 0000000..6057247
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_session.h
@@ -0,0 +1,973 @@
+/* $Id: ice_session.h 2724 2009-05-29 13:04:03Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_ICE_SESSION_H__
+#define __PJNATH_ICE_SESSION_H__
+
+/**
+ * @file ice_session.h
+ * @brief ICE session management
+ */
+#include <pjnath/types.h>
+#include <pjnath/stun_session.h>
+#include <pjnath/errno.h>
+#include <pj/sock.h>
+#include <pj/timer.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @addtogroup PJNATH_ICE_SESSION
+ * @{
+ *
+ * This module describes #pj_ice_sess, a transport independent ICE session,
+ * part of PJNATH - the Open Source NAT helper library.
+ *
+ * \section pj_ice_sess_sec ICE Session
+ *
+ * An ICE session, represented by #pj_ice_sess 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.
+ *
+ * \subsection pj_ice_sess_using_sec Using The ICE Session
+ *
+ * The steps below describe how to use ICE session. Alternatively application
+ * can use the higher level ICE API, \ref PJNATH_ICE_STREAM_TRANSPORT,
+ * which has provided the integration of ICE with socket transport.
+ *
+ * The steps to use ICE session is similar for both offerer and
+ * answerer:
+ * - create ICE session with #pj_ice_sess_create(). Among other things,
+ * application needs to specify:
+ * - STUN configuration (pj_stun_config), containing STUN settings
+ * such as timeout values and the instances of timer heap and
+ * ioqueue.
+ * - Session name, useful for identifying this session in the log.
+ * - Initial ICE role (#pj_ice_sess_role). The role can be changed
+ * at later time with #pj_ice_sess_change_role(), and ICE session
+ * can also change its role automatically when it detects role
+ * conflict.
+ * - Number of components in the media session.
+ * - Callback to receive ICE events (#pj_ice_sess_cb)
+ * - Optional local ICE username and password. If these arguments
+ * are NULL, they will be generated randomly.
+ * - Add local candidates for each component, with #pj_ice_sess_add_cand().
+ * A candidate is represented with #pj_ice_sess_cand structure.
+ * Each component must be provided with at least one candidate, and
+ * all components must have the same number of candidates. Failing
+ * to comply with this will cause failure during pairing process.
+ * - Create offer to describe local ICE candidates. ICE session does not
+ * provide a function to create such offer, but application should be
+ * able to create one since it knows about all components and candidates.
+ * If application uses \ref PJNATH_ICE_STREAM_TRANSPORT, it can
+ * enumerate local candidates by calling #pj_ice_strans_enum_cands().
+ * Application may use #pj_ice_sess_find_default_cand() to let ICE
+ * session chooses the default transport address to be used in SDP
+ * c= and m= lines.
+ * - Send the offer to remote endpoint using signaling such as SIP.
+ * - Once application has received the answer, it should parse this
+ * answer, build array of remote candidates, and create check lists by
+ * calling #pj_ice_sess_create_check_list(). This process is known as
+ * pairing the candidates, and will result in the creation of check lists.
+ * - Once checklist has been created, application then can call
+ * #pj_ice_sess_start_check() to instruct ICE session to start
+ * performing connectivity checks. The ICE session performs the
+ * connectivity checks by processing each check in the checklists.
+ * - Application will be notified about the result of ICE connectivity
+ * checks via the callback that was given in #pj_ice_sess_create()
+ * above.
+ *
+ * To send data, application calls #pj_ice_sess_send_data(). If ICE
+ * negotiation has not completed, ICE session would simply drop the data,
+ * and return error to caller. If ICE negotiation has completed
+ * successfully, ICE session will in turn call the \a on_tx_pkt
+ * callback of #pj_ice_sess_cb instance that was previously registered
+ * in #pj_ice_sess_create() above.
+ *
+ * When application receives any packets on the underlying sockets, it
+ * must call #pj_ice_sess_on_rx_pkt(). The ICE session will inspect the
+ * packet to decide whether to process it locally (if the packet is a
+ * STUN message and is part of ICE session) or otherwise pass it back to
+ * application via \a on_rx_data callback.
+ */
+
+/**
+ * Forward declaration for checklist.
+ */
+typedef struct pj_ice_sess_checklist pj_ice_sess_checklist;
+
+/**
+ * This enumeration describes the type of an ICE candidate.
+ */
+typedef enum pj_ice_cand_type
+{
+ /**
+ * ICE host candidate. A host candidate represents the actual local
+ * transport address in the host.
+ */
+ PJ_ICE_CAND_TYPE_HOST,
+
+ /**
+ * ICE server reflexive candidate, which represents the public mapped
+ * address of the local address, and is obtained by sending STUN
+ * Binding request from the host candidate to a STUN server.
+ */
+ PJ_ICE_CAND_TYPE_SRFLX,
+
+ /**
+ * ICE peer reflexive candidate, which is the address as seen by peer
+ * agent during connectivity check.
+ */
+ PJ_ICE_CAND_TYPE_PRFLX,
+
+ /**
+ * ICE relayed candidate, which represents the address allocated in
+ * TURN server.
+ */
+ PJ_ICE_CAND_TYPE_RELAYED
+
+} pj_ice_cand_type;
+
+
+/** Forward declaration for pj_ice_sess */
+typedef struct pj_ice_sess pj_ice_sess;
+
+/** Forward declaration for pj_ice_sess_check */
+typedef struct pj_ice_sess_check pj_ice_sess_check;
+
+
+/**
+ * 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_sess_comp
+{
+ /**
+ * Pointer to ICE check with highest priority which connectivity check
+ * has been successful. The value will be NULL if a no successful check
+ * has not been found for this component.
+ */
+ pj_ice_sess_check *valid_check;
+
+ /**
+ * Pointer to ICE check with highest priority which connectivity check
+ * has been successful and it has been nominated. The value may be NULL
+ * if there is no such check yet.
+ */
+ pj_ice_sess_check *nominated_check;
+
+ /**
+ * The STUN session to be used to send and receive STUN messages for this
+ * component.
+ */
+ pj_stun_session *stun_sess;
+
+} pj_ice_sess_comp;
+
+
+/**
+ * Data structure to be attached to internal message processing.
+ */
+typedef struct pj_ice_msg_data
+{
+ /** Transport ID for this message */
+ unsigned transport_id;
+
+ /** Flag to indicate whether data.req contains data */
+ pj_bool_t has_req_data;
+
+ /** The data */
+ union data {
+ /** Request data */
+ struct request_data {
+ pj_ice_sess *ice; /**< ICE session */
+ pj_ice_sess_checklist *clist; /**< Checklist */
+ unsigned ckid; /**< Check ID */
+ } req;
+ } data;
+
+} pj_ice_msg_data;
+
+
+/**
+ * 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_sess_cand
+{
+ /**
+ * The candidate type, as described in #pj_ice_cand_type enumeration.
+ */
+ pj_ice_cand_type type;
+
+ /**
+ * Status of this candidate. 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 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_uint8_t comp_id;
+
+ /**
+ * Transport ID to be used to send packets for this candidate.
+ */
+ pj_uint8_t transport_id;
+
+ /**
+ * Local preference value, which typically is 65535.
+ */
+ pj_uint16_t local_pref;
+
+ /**
+ * 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;
+
+} pj_ice_sess_cand;
+
+
+/**
+ * This enumeration describes the state of ICE check.
+ */
+typedef enum pj_ice_sess_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_SESS_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_SESS_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_SESS_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_SESS_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_SESS_CHECK_STATE_FAILED
+
+} pj_ice_sess_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_sess_check
+{
+ /**
+ * Pointer to local candidate entry of this check.
+ */
+ pj_ice_sess_cand *lcand;
+
+ /**
+ * Pointer to remote candidate entry of this check.
+ */
+ pj_ice_sess_cand *rcand;
+
+ /**
+ * Check priority.
+ */
+ pj_timestamp prio;
+
+ /**
+ * Connectivity check state.
+ */
+ pj_ice_sess_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_sess_checklist_state
+{
+ /**
+ * The checklist is not yet running.
+ */
+ PJ_ICE_SESS_CHECKLIST_ST_IDLE,
+
+ /**
+ * In this state, ICE checks are still in progress for this
+ * media stream.
+ */
+ PJ_ICE_SESS_CHECKLIST_ST_RUNNING,
+
+ /**
+ * In this state, ICE checks have completed for this media stream,
+ * either successfully or with failure.
+ */
+ PJ_ICE_SESS_CHECKLIST_ST_COMPLETED
+
+} pj_ice_sess_checklist_state;
+
+
+/**
+ * This structure represents ICE check list, that is an ordered set of
+ * candidate pairs that an agent will use to generate checks.
+ */
+struct pj_ice_sess_checklist
+{
+ /**
+ * The checklist state.
+ */
+ pj_ice_sess_checklist_state state;
+
+ /**
+ * Number of candidate pairs (checks).
+ */
+ unsigned count;
+
+ /**
+ * Array of candidate pairs (checks).
+ */
+ pj_ice_sess_check checks[PJ_ICE_MAX_CHECKS];
+
+ /**
+ * A timer used to perform periodic check for this checklist.
+ */
+ pj_timer_entry timer;
+
+};
+
+
+/**
+ * This structure contains callbacks that will be called by the ICE
+ * session.
+ */
+typedef struct pj_ice_sess_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_sess *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 transport_id Transport 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_sess *ice, unsigned comp_id,
+ unsigned transport_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 transport_id Transport 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_sess *ice, unsigned comp_id,
+ unsigned transport_id,
+ void *pkt, pj_size_t size,
+ const pj_sockaddr_t *src_addr,
+ unsigned src_addr_len);
+} pj_ice_sess_cb;
+
+
+/**
+ * This enumeration describes the role of the ICE agent.
+ */
+typedef enum pj_ice_sess_role
+{
+ /**
+ * The role is unknown.
+ */
+ PJ_ICE_SESS_ROLE_UNKNOWN,
+
+ /**
+ * The ICE agent is in controlled role.
+ */
+ PJ_ICE_SESS_ROLE_CONTROLLED,
+
+ /**
+ * The ICE agent is in controlling role.
+ */
+ PJ_ICE_SESS_ROLE_CONTROLLING
+
+} pj_ice_sess_role;
+
+
+/**
+ * This structure represents an incoming check (an incoming Binding
+ * request message), and is mainly used to keep early checks in the
+ * list in the ICE session. An early check is a request received
+ * from remote when we haven't received SDP answer yet, therefore we
+ * can't perform triggered check. For such cases, keep the incoming
+ * request in a list, and we'll do triggered checks (simultaneously)
+ * as soon as we receive answer.
+ */
+typedef struct pj_ice_rx_check
+{
+ PJ_DECL_LIST_MEMBER(struct pj_ice_rx_check); /**< Standard list */
+
+ unsigned comp_id; /**< Component ID. */
+ unsigned transport_id; /**< Transport ID. */
+
+ pj_sockaddr src_addr; /**< Source address of request */
+ unsigned src_addr_len; /**< Length of src address. */
+
+ pj_bool_t use_candidate; /**< USE-CANDIDATE is present? */
+ pj_uint32_t priority; /**< PRIORITY value in the req. */
+ pj_stun_uint64_attr *role_attr; /**< ICE-CONTROLLING/CONTROLLED */
+
+} pj_ice_rx_check;
+
+
+/**
+ * This structure describes various ICE session options. Application
+ * configure the ICE session with these options by calling
+ * #pj_ice_sess_set_options().
+ */
+typedef struct pj_ice_sess_options
+{
+ /**
+ * Specify whether to use aggressive nomination.
+ */
+ pj_bool_t aggressive;
+
+ /**
+ * For controlling agent if it uses regular nomination, specify the delay
+ * to perform nominated check (connectivity check with USE-CANDIDATE
+ * attribute) after all components have a valid pair.
+ *
+ * Default value is PJ_ICE_NOMINATED_CHECK_DELAY.
+ */
+ unsigned nominated_check_delay;
+
+ /**
+ * For a controlled agent, specify how long it wants to wait (in
+ * milliseconds) for the controlling agent to complete sending
+ * connectivity check with nominated flag set to true for all components
+ * after the controlled agent has found that all connectivity checks in
+ * its checklist have been completed and there is at least one successful
+ * (but not nominated) check for every component.
+ *
+ * Default value for this option is
+ * ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT. Specify -1 to disable
+ * this timer.
+ */
+ int controlled_agent_want_nom_timeout;
+
+} pj_ice_sess_options;
+
+
+/**
+ * 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_sess
+{
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Object name. */
+
+ pj_pool_t *pool; /**< Pool instance. */
+ void *user_data; /**< App. data. */
+ pj_mutex_t *mutex; /**< Mutex. */
+ pj_ice_sess_role role; /**< ICE role. */
+ pj_ice_sess_options opt; /**< Options */
+ pj_timestamp tie_breaker; /**< Tie breaker value */
+ pj_uint8_t *prefs; /**< Type preference. */
+ pj_bool_t is_nominating; /**< Nominating stage */
+ pj_bool_t is_complete; /**< Complete? */
+ pj_status_t ice_status; /**< Error status. */
+ pj_timer_entry timer; /**< ICE timer. */
+ pj_ice_sess_cb cb; /**< Callback. */
+
+ pj_stun_config stun_cfg; /**< STUN settings. */
+
+ /* STUN credentials */
+ 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; /**< # of components. */
+ pj_ice_sess_comp comp[PJ_ICE_MAX_COMP]; /**< Component array */
+ unsigned comp_ka; /**< Next comp for KA */
+
+ /* Local candidates */
+ unsigned lcand_cnt; /**< # of local cand. */
+ pj_ice_sess_cand lcand[PJ_ICE_MAX_CAND]; /**< Array of cand. */
+
+ /* Remote candidates */
+ unsigned rcand_cnt; /**< # of remote cand. */
+ pj_ice_sess_cand rcand[PJ_ICE_MAX_CAND]; /**< Array of cand. */
+
+ /** Array of transport datas */
+ pj_ice_msg_data tp_data[4];
+
+ /* List of eearly checks */
+ pj_ice_rx_check early_check; /**< Early checks. */
+
+ /* Checklist */
+ pj_ice_sess_checklist clist; /**< Active checklist */
+
+ /* Valid list */
+ pj_ice_sess_checklist valid_list; /**< Valid list. */
+
+ /** Temporary buffer for misc stuffs to avoid using stack too much */
+ union {
+ char txt[128];
+ char errmsg[PJ_ERR_MSG_SIZE];
+ } tmp;
+};
+
+
+/**
+ * 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);
+
+
+/**
+ * This is a utility function to retrieve the string name for the
+ * particular role type.
+ *
+ * @param role Role type.
+ *
+ * @return The string representation of the role.
+ */
+PJ_DECL(const char*) pj_ice_sess_role_name(pj_ice_sess_role role);
+
+
+/**
+ * This is a utility function to calculate the foundation identification
+ * for a candidate.
+ *
+ * @param pool Pool to allocate the foundation string.
+ * @param foundation Pointer to receive the foundation string.
+ * @param type Candidate type.
+ * @param base_addr Base address of the candidate.
+ */
+PJ_DECL(void) pj_ice_calc_foundation(pj_pool_t *pool,
+ pj_str_t *foundation,
+ pj_ice_cand_type type,
+ const pj_sockaddr *base_addr);
+
+/**
+ * Initialize ICE session options with library default values.
+ *
+ * @param opt ICE session options.
+ */
+PJ_DECL(void) pj_ice_sess_options_default(pj_ice_sess_options *opt);
+
+/**
+ * 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_sess_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_sess_create(pj_stun_config *stun_cfg,
+ const char *name,
+ pj_ice_sess_role role,
+ unsigned comp_cnt,
+ const pj_ice_sess_cb *cb,
+ const pj_str_t *local_ufrag,
+ const pj_str_t *local_passwd,
+ pj_ice_sess **p_ice);
+
+/**
+ * Get the value of various options of the ICE session.
+ *
+ * @param ice The ICE session.
+ * @param opt The options to be initialized with the values
+ * from the ICE session.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pj_ice_sess_get_options(pj_ice_sess *ice,
+ pj_ice_sess_options *opt);
+
+/**
+ * Specify various options for this ICE session. Application MUST only
+ * call this function after the ICE session has been created but before
+ * any connectivity check is started.
+ *
+ * Application should call #pj_ice_sess_get_options() to initialize the
+ * options with their default values.
+ *
+ * @param ice The ICE session.
+ * @param opt Options to be applied to the ICE session.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pj_ice_sess_set_options(pj_ice_sess *ice,
+ const pj_ice_sess_options *opt);
+
+/**
+ * Destroy ICE session. This will cancel any connectivity checks currently
+ * running, if any, and any other events scheduled by this session, as well
+ * as all memory resources.
+ *
+ * @param ice ICE session instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_ice_sess_destroy(pj_ice_sess *ice);
+
+
+/**
+ * Change session role. This happens for example when ICE session was
+ * created with controlled role when receiving an offer, but it turns out
+ * that the offer contains "a=ice-lite" attribute when the SDP gets
+ * inspected.
+ *
+ * @param ice The ICE session.
+ * @param new_role The new role to be set.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pj_ice_sess_change_role(pj_ice_sess *ice,
+ pj_ice_sess_role new_role);
+
+
+/**
+ * Assign a custom preference values for ICE candidate types. By assigning
+ * custom preference value, application can control the order of candidates
+ * to be checked first. The default preference settings is to use 126 for
+ * host candidates, 100 for server reflexive candidates, 110 for peer
+ * reflexive candidates, an 0 for relayed candidates.
+ *
+ * Note that this function must be called before any candidates are added
+ * to the ICE session.
+ *
+ * @param ice The ICE session.
+ * @param prefs Array of candidate preference value. The values are
+ * put in the array indexed by the candidate type as
+ * specified in pj_ice_cand_type.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice,
+ const pj_uint8_t prefs[4]);
+
+
+
+/**
+ * Add a candidate to this ICE session. Application must add candidates for
+ * each components ID before it can start pairing the candidates and
+ * performing connectivity checks.
+ *
+ * @param ice ICE session instance.
+ * @param comp_id Component ID of this candidate.
+ * @param transport_id Transport ID to be used to send packets for 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_sess_add_cand(pj_ice_sess *ice,
+ unsigned comp_id,
+ unsigned transport_id,
+ pj_ice_cand_type type,
+ pj_uint16_t local_pref,
+ const pj_str_t *foundation,
+ const pj_sockaddr_t *addr,
+ const pj_sockaddr_t *base_addr,
+ const pj_sockaddr_t *rel_addr,
+ int addr_len,
+ 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_sess_find_default_cand(pj_ice_sess *ice,
+ unsigned comp_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_sess_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_sess_create_check_list(pj_ice_sess *ice,
+ const pj_str_t *rem_ufrag,
+ const pj_str_t *rem_passwd,
+ unsigned rem_cand_cnt,
+ const pj_ice_sess_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_sess_cb callback.
+ *
+ * @param ice The ICE session instance.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *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.
+ *
+ * This function will in turn call \a on_tx_pkt function in
+ * #pj_ice_sess_cb callback to actually send the packet to the wire.
+ *
+ * @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_sess_send_data(pj_ice_sess *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_sess_cb.
+ *
+ * @param ice The ICE session.
+ * @param comp_id Component ID.
+ * @param transport_id Number to identify where this packet was received
+ * from. This parameter will be returned back to
+ * application in \a on_tx_pkt() callback.
+ * @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_sess_on_rx_pkt(pj_ice_sess *ice,
+ unsigned comp_id,
+ unsigned transport_id,
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_sockaddr_t *src_addr,
+ int src_addr_len);
+
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_ICE_SESSION_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_strans.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_strans.h
new file mode 100644
index 0000000..6788796
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_strans.h
@@ -0,0 +1,792 @@
+/* $Id: ice_strans.h 2966 2009-10-25 09:02:07Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_ICE_STRANS_H__
+#define __PJNATH_ICE_STRANS_H__
+
+
+/**
+ * @file ice_strans.h
+ * @brief ICE Stream Transport
+ */
+#include <pjnath/ice_session.h>
+#include <pjnath/stun_sock.h>
+#include <pjnath/turn_sock.h>
+#include <pjlib-util/resolver.h>
+#include <pj/ioqueue.h>
+#include <pj/timer.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @addtogroup PJNATH_ICE_STREAM_TRANSPORT
+ * @{
+ *
+ * This module describes ICE stream transport, as represented by #pj_ice_strans
+ * structure, and is part of PJNATH - the Open Source NAT traversal helper
+ * library.
+ *
+ * ICE stream transport, as represented by #pj_ice_strans structure, is an ICE
+ * capable class for transporting media streams within a media session.
+ * 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 ice_strans_using_sec Using the ICE stream transport
+ *
+ * The steps below describe how to use ICE session:
+ *
+ * - initialize a #pj_ice_strans_cfg structure. This contains various
+ * settings for the ICE stream transport, and among other things contains
+ * the STUN and TURN settings.\n\n
+ * - create the instance with #pj_ice_strans_create(). Among other things,
+ * the function needs the following arguments:
+ * - the #pj_ice_strans_cfg structure for the main configurations
+ * - number of components to be supported
+ * - instance of #pj_ice_strans_cb structure to report callbacks to
+ * application.\n\n
+ * - while the #pj_ice_strans_create() call completes immediately, the
+ * initialization will be running in the background to gather the
+ * candidates (for example STUN and TURN candidates, if they are enabled
+ * in the #pj_ice_strans_cfg setting). Application will be notified when
+ * the initialization completes in the \a on_ice_complete callback of
+ * the #pj_ice_strans_cb structure (the \a op argument of this callback
+ * will be PJ_ICE_STRANS_OP_INIT).\n\n
+ * - when media stream is to be started (for example, a call is to be
+ * started), create an ICE session by calling #pj_ice_strans_init_ice().\n\n
+ * - the application now typically will need to communicate local ICE
+ * information to remote host. It can achieve this by using the following
+ * functions to query local ICE information:
+ * - #pj_ice_strans_get_ufrag_pwd()
+ * - #pj_ice_strans_enum_cands()
+ * - #pj_ice_strans_get_def_cand()\n
+ * The application may need to encode the above information as SDP.\n\n
+ * - when the application receives remote ICE information (for example, from
+ * the SDP received from remote), it can now start ICE negotiation, by
+ * calling #pj_ice_strans_start_ice(). This function requires some
+ * information about remote ICE agent such as remote ICE username fragment
+ * and password as well as array of remote candidates.\n\n
+ * - note that the PJNATH library does not work with SDP; application would
+ * need to encode and parse the SDP itself.\n\n
+ * - once ICE negotiation has been started, application will be notified
+ * about the completion in the \a on_ice_complete() callback of the
+ * #pj_ice_strans_cb.\n\n
+ * - at any time, application may send or receive data. However the ICE
+ * stream transport may not be able to send it depending on its current
+ * state. Before ICE negotiation is started, the data will be sent using
+ * default candidate of the component. After negotiation is completed,
+ * data will be sent using the candidate from the successful/nominated
+ * pair. The ICE stream transport may not be able to send data while
+ * negotiation is in progress.\n\n
+ * - application sends data by using #pj_ice_strans_sendto(). Incoming
+ * data will be reported in \a on_rx_data() callback of the
+ * #pj_ice_strans_cb.\n\n
+ * - once the media session has finished (e.g. user hangs up the call),
+ * destroy the ICE session with #pj_ice_strans_stop_ice().\n\n
+ * - at this point, application may destroy the ICE stream transport itself,
+ * or let it run so that it can be reused to create other ICE session.
+ * The benefit of letting the ICE stream transport alive (without any
+ * session active) is to avoid delay with the initialization, howerver
+ * keeping the transport alive means the transport needs to keep the
+ * STUN binding open by using keep-alive and also TURN allocation alive,
+ * and this will consume power which is an important issue for mobile
+ * applications.\n\n
+ */
+
+/** Forward declaration for ICE stream transport. */
+typedef struct pj_ice_strans pj_ice_strans;
+
+/** Transport operation types to be reported on \a on_status() callback */
+typedef enum pj_ice_strans_op
+{
+ /** Initialization (candidate gathering) */
+ PJ_ICE_STRANS_OP_INIT,
+
+ /** Negotiation */
+ PJ_ICE_STRANS_OP_NEGOTIATION
+
+} pj_ice_strans_op;
+
+/**
+ * This structure contains callbacks that will be called by the
+ * ICE stream transport.
+ */
+typedef struct pj_ice_strans_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_strans *ice_st,
+ unsigned comp_id,
+ void *pkt, pj_size_t size,
+ const pj_sockaddr_t *src_addr,
+ unsigned src_addr_len);
+
+ /**
+ * Callback to report status.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param op The operation
+ * @param status Operation status.
+ */
+ void (*on_ice_complete)(pj_ice_strans *ice_st,
+ pj_ice_strans_op op,
+ pj_status_t status);
+
+} pj_ice_strans_cb;
+
+
+/**
+ * This structure describes ICE stream transport configuration. Application
+ * should initialize the structure by calling #pj_ice_strans_cfg_default()
+ * before changing the settings.
+ */
+typedef struct pj_ice_strans_cfg
+{
+ /**
+ * Address family, IPv4 or IPv6. Currently only pj_AF_INET() (IPv4)
+ * is supported, and this is the default value.
+ */
+ int af;
+
+ /**
+ * STUN configuration which contains the timer heap and
+ * ioqueue instance to be used, and STUN retransmission
+ * settings. This setting is mandatory.
+ *
+ * The default value is all zero. Application must initialize
+ * this setting with #pj_stun_config_init().
+ */
+ pj_stun_config stun_cfg;
+
+ /**
+ * DNS resolver to be used to resolve servers. If DNS SRV
+ * resolution is required, the resolver must be set.
+ *
+ * The default value is NULL.
+ */
+ pj_dns_resolver *resolver;
+
+ /**
+ * This contains various STUN session options. Once the ICE stream
+ * transport is created, application may also change the options
+ * with #pj_ice_strans_set_options().
+ */
+ pj_ice_sess_options opt;
+
+ /**
+ * STUN and local transport settings. This specifies the
+ * settings for local UDP socket, which will be resolved
+ * to get the STUN mapped address.
+ */
+ struct {
+ /**
+ * Optional configuration for STUN transport. The default
+ * value will be initialized with #pj_stun_sock_cfg_default().
+ */
+ pj_stun_sock_cfg cfg;
+
+ /**
+ * Maximum number of host candidates to be added. If the
+ * value is zero, no host candidates will be added.
+ *
+ * Default: 64
+ */
+ unsigned max_host_cands;
+
+ /**
+ * Include loopback addresses in the host candidates.
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t loop_addr;
+
+ /**
+ * Specify the STUN server domain or hostname or IP address.
+ * If DNS SRV resolution is required, application must fill
+ * in this setting with the domain name of the STUN server
+ * and set the resolver instance in the \a resolver field.
+ * Otherwise if the \a resolver setting is not set, this
+ * field will be resolved with hostname resolution and in
+ * this case the \a port field must be set.
+ *
+ * The \a port field should also be set even when DNS SRV
+ * resolution is used, in case the DNS SRV resolution fails.
+ *
+ * When this field is empty, STUN mapped address resolution
+ * will not be performed. In this case only ICE host candidates
+ * will be added to the ICE transport, unless if \a no_host_cands
+ * field is set. In this case, both host and srflx candidates
+ * are disabled.
+ *
+ * The default value is empty.
+ */
+ pj_str_t server;
+
+ /**
+ * The port number of the STUN server, when \a server
+ * field specifies a hostname rather than domain name. This
+ * field should also be set even when the \a server
+ * specifies a domain name, to allow DNS SRV resolution
+ * to fallback to DNS A/AAAA resolution when the DNS SRV
+ * resolution fails.
+ *
+ * The default value is PJ_STUN_PORT.
+ */
+ pj_uint16_t port;
+
+ } stun;
+
+ /**
+ * TURN specific settings.
+ */
+ struct {
+ /**
+ * Optional TURN socket settings. The default values will be
+ * initialized by #pj_turn_sock_cfg_default(). This contains
+ * settings such as QoS.
+ */
+ pj_turn_sock_cfg cfg;
+
+ /**
+ * Specify the TURN server domain or hostname or IP address.
+ * If DNS SRV resolution is required, application must fill
+ * in this setting with the domain name of the TURN server
+ * and set the resolver instance in the \a resolver field.
+ * Otherwise if the \a resolver setting is not set, this
+ * field will be resolved with hostname resolution and in
+ * this case the \a port field must be set.
+ *
+ * The \a port field should also be set even when DNS SRV
+ * resolution is used, in case the DNS SRV resolution fails.
+ *
+ * When this field is empty, relay candidate will not be
+ * created.
+ *
+ * The default value is empty.
+ */
+ pj_str_t server;
+
+ /**
+ * The port number of the TURN server, when \a server
+ * field specifies a hostname rather than domain name. This
+ * field should also be set even when the \a server
+ * specifies a domain name, to allow DNS SRV resolution
+ * to fallback to DNS A/AAAA resolution when the DNS SRV
+ * resolution fails.
+ *
+ * Default is zero.
+ */
+ pj_uint16_t port;
+
+ /**
+ * Type of connection to the TURN server.
+ *
+ * Default is PJ_TURN_TP_UDP.
+ */
+ pj_turn_tp_type conn_type;
+
+ /**
+ * Credential to be used for the TURN session. This setting
+ * is mandatory.
+ *
+ * Default is to have no credential.
+ */
+ pj_stun_auth_cred auth_cred;
+
+ /**
+ * Optional TURN Allocate parameter. The default value will be
+ * initialized by #pj_turn_alloc_param_default().
+ */
+ pj_turn_alloc_param alloc_param;
+
+ } turn;
+
+ /**
+ * Component specific settings, which will override the settings in
+ * the STUN and TURN settings above. For example, setting the QoS
+ * parameters here allows the application to have different QoS
+ * traffic type for RTP and RTCP component.
+ */
+ struct {
+ /**
+ * QoS traffic type to be set on this transport. When application
+ * wants to apply QoS tagging to the transport, it's preferable to
+ * set this field rather than \a qos_param fields since this is
+ * more portable.
+ *
+ * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a
+ * lower level operation than setting the \a qos_type field and
+ * may not be supported on all platforms.
+ *
+ * By default all settings in this structure are disabled.
+ */
+ pj_qos_params qos_params;
+
+ } comp[PJ_ICE_MAX_COMP];
+
+} pj_ice_strans_cfg;
+
+
+/**
+ * ICE stream transport's state.
+ */
+typedef enum pj_ice_strans_state
+{
+ /**
+ * ICE stream transport is not created.
+ */
+ PJ_ICE_STRANS_STATE_NULL,
+
+ /**
+ * ICE candidate gathering process is in progress.
+ */
+ PJ_ICE_STRANS_STATE_INIT,
+
+ /**
+ * ICE stream transport initialization/candidate gathering process is
+ * complete, ICE session may be created on this stream transport.
+ */
+ PJ_ICE_STRANS_STATE_READY,
+
+ /**
+ * New session has been created and the session is ready.
+ */
+ PJ_ICE_STRANS_STATE_SESS_READY,
+
+ /**
+ * ICE negotiation is in progress.
+ */
+ PJ_ICE_STRANS_STATE_NEGO,
+
+ /**
+ * ICE negotiation has completed successfully and media is ready
+ * to be used.
+ */
+ PJ_ICE_STRANS_STATE_RUNNING,
+
+ /**
+ * ICE negotiation has completed with failure.
+ */
+ PJ_ICE_STRANS_STATE_FAILED
+
+} pj_ice_strans_state;
+
+
+/**
+ * Initialize ICE transport configuration with default values.
+ *
+ * @param cfg The configuration to be initialized.
+ */
+PJ_DECL(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg);
+
+
+/**
+ * Copy configuration.
+ *
+ * @param pool Pool.
+ * @param dst Destination.
+ * @param src Source.
+ */
+PJ_DECL(void) pj_ice_strans_cfg_copy(pj_pool_t *pool,
+ pj_ice_strans_cfg *dst,
+ const pj_ice_strans_cfg *src);
+
+
+/**
+ * Create and initialize the ICE stream transport with the specified
+ * parameters.
+ *
+ * @param name Optional name for logging identification.
+ * @param cfg Configuration.
+ * @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_strans_create(const char *name,
+ const pj_ice_strans_cfg *cfg,
+ unsigned comp_cnt,
+ void *user_data,
+ const pj_ice_strans_cb *cb,
+ pj_ice_strans **p_ice_st);
+
+/**
+ * Get ICE session state.
+ *
+ * @param ice_st The ICE stream transport.
+ *
+ * @return ICE session state.
+ */
+PJ_DECL(pj_ice_strans_state) pj_ice_strans_get_state(pj_ice_strans *ice_st);
+
+
+/**
+ * Get string representation of ICE state.
+ *
+ * @param state ICE stream transport state.
+ *
+ * @return String.
+ */
+PJ_DECL(const char*) pj_ice_strans_state_name(pj_ice_strans_state state);
+
+
+/**
+ * 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_strans_destroy(pj_ice_strans *ice_st);
+
+
+/**
+ * Get the user data associated with the ICE stream transport.
+ *
+ * @param ice_st The ICE stream transport.
+ *
+ * @return The user data.
+ */
+PJ_DECL(void*) pj_ice_strans_get_user_data(pj_ice_strans *ice_st);
+
+
+/**
+ * Get the value of various options of the ICE stream transport.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param opt The options to be initialized with the values
+ * from the ICE stream transport.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_get_options(pj_ice_strans *ice_st,
+ pj_ice_sess_options *opt);
+
+/**
+ * Specify various options for this ICE stream transport. Application
+ * should call #pj_ice_strans_get_options() to initialize the options
+ * with their default values.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param opt Options to be applied to this ICE stream transport.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_set_options(pj_ice_strans *ice_st,
+ const pj_ice_sess_options *opt);
+
+
+/**
+ * Initialize the ICE session in the ICE stream transport.
+ * When application is about to send an offer containing ICE capability,
+ * or when it receives an offer containing ICE capability, it must
+ * call this function to initialize the internal ICE session. This would
+ * register all transport address aliases for each component to the ICE
+ * session as candidates. Then application can enumerate all local
+ * candidates by calling #pj_ice_strans_enum_cands(), and encode these
+ * candidates in the SDP to be sent to remote agent.
+ *
+ * @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_strans_init_ice(pj_ice_strans *ice_st,
+ pj_ice_sess_role role,
+ const pj_str_t *local_ufrag,
+ const pj_str_t *local_passwd);
+
+/**
+ * Check if the ICE stream transport has the ICE session created. The
+ * ICE session is created with #pj_ice_strans_init_ice().
+ *
+ * @param ice_st The ICE stream transport.
+ *
+ * @return PJ_TRUE if #pj_ice_strans_init_ice() has been
+ * called.
+ */
+PJ_DECL(pj_bool_t) pj_ice_strans_has_sess(pj_ice_strans *ice_st);
+
+
+/**
+ * Check if ICE negotiation is still running.
+ *
+ * @param ice_st The ICE stream transport.
+ *
+ * @return PJ_TRUE if ICE session has been created and ICE
+ * negotiation negotiation is in progress.
+ */
+PJ_DECL(pj_bool_t) pj_ice_strans_sess_is_running(pj_ice_strans *ice_st);
+
+
+/**
+ * Check if ICE negotiation has completed.
+ *
+ * @param ice_st The ICE stream transport.
+ *
+ * @return PJ_TRUE if ICE session has been created and the
+ * negotiation is complete.
+ */
+PJ_DECL(pj_bool_t) pj_ice_strans_sess_is_complete(pj_ice_strans *ice_st);
+
+
+/**
+ * Get the current/running component count. If ICE negotiation has not
+ * been started, the number of components will be equal to the number
+ * when the ICE stream transport was created. Once negotiation been
+ * started, the number of components will be the lowest number of
+ * component between local and remote agents.
+ *
+ * @param ice_st The ICE stream transport.
+ *
+ * @return The running number of components.
+ */
+PJ_DECL(unsigned) pj_ice_strans_get_running_comp_cnt(pj_ice_strans *ice_st);
+
+
+/**
+ * Get the ICE username fragment and password of the ICE session. The
+ * local username fragment and password can only be retrieved once ICE
+ * session has been created with #pj_ice_strans_init_ice(). The remote
+ * username fragment and password can only be retrieved once ICE session
+ * has been started with #pj_ice_strans_start_ice().
+ *
+ * Note that the string returned by this function is only valid throughout
+ * the duration of the ICE session, and the application must not modify
+ * these strings. Once the ICE session has been stopped with
+ * #pj_ice_strans_stop_ice(), the pointer in the string will no longer be
+ * valid.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param loc_ufrag Optional pointer to receive ICE username fragment
+ * of local endpoint from the ICE session.
+ * @param loc_pwd Optional pointer to receive ICE password of local
+ * endpoint from the ICE session.
+ * @param rem_ufrag Optional pointer to receive ICE username fragment
+ * of remote endpoint from the ICE session.
+ * @param rem_pwd Optional pointer to receive ICE password of remote
+ * endpoint from the ICE session.
+ *
+ * @return PJ_SUCCESS if the strings have been retrieved
+ * successfully.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_get_ufrag_pwd(pj_ice_strans *ice_st,
+ pj_str_t *loc_ufrag,
+ pj_str_t *loc_pwd,
+ pj_str_t *rem_ufrag,
+ pj_str_t *rem_pwd);
+
+
+/**
+ * Enumerate the local candidates for the specified component.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param comp_id Component ID.
+ * @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_strans_enum_cands(pj_ice_strans *ice_st,
+ unsigned comp_id,
+ unsigned *count,
+ pj_ice_sess_cand cand[]);
+
+/**
+ * Get the default candidate for the specified component. When this
+ * function is called before ICE negotiation completes, the default
+ * candidate is selected according to local preference criteria. When
+ * this function is called after ICE negotiation completes, the
+ * default candidate is the candidate that forms the valid pair.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param comp_id Component ID.
+ * @param cand Pointer to receive the default candidate
+ * information.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_get_def_cand(pj_ice_strans *ice_st,
+ unsigned comp_id,
+ pj_ice_sess_cand *cand);
+
+/**
+ * Get the current ICE role. ICE session must have been initialized
+ * before this function can be called.
+ *
+ * @param ice_st The ICE stream transport.
+ *
+ * @return Current ICE role.
+ */
+PJ_DECL(pj_ice_sess_role) pj_ice_strans_get_role(pj_ice_strans *ice_st);
+
+
+/**
+ * Change session role. This happens for example when ICE session was
+ * created with controlled role when receiving an offer, but it turns out
+ * that the offer contains "a=ice-lite" attribute when the SDP gets
+ * inspected. ICE session must have been initialized before this function
+ * can be called.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param new_role The new role to be set.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_change_role(pj_ice_strans *ice_st,
+ pj_ice_sess_role new_role);
+
+
+/**
+ * Start ICE connectivity checks. This function can only be called
+ * after the ICE session has been created in the ICE stream transport
+ * with #pj_ice_strans_init_ice().
+ *
+ * This function must be called once application has received remote
+ * candidate list (typically from the remote SDP). This function pairs
+ * local candidates with remote candidates, and starts ICE connectivity
+ * checks. The ICE session/transport will then notify the application
+ * via the callback when ICE connectivity checks completes, either
+ * successfully or with failure.
+ *
+ * @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 rcand_cnt Number of remote candidates in the array.
+ * @param rcand Remote candidates array.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_start_ice(pj_ice_strans *ice_st,
+ const pj_str_t *rem_ufrag,
+ const pj_str_t *rem_passwd,
+ unsigned rcand_cnt,
+ const pj_ice_sess_cand rcand[]);
+
+/**
+ * Retrieve the candidate pair that has been nominated and successfully
+ * checked for the specified component. If ICE negotiation is still in
+ * progress or it has failed, this function will return NULL.
+ *
+ * @param ice_st The ICE stream transport.
+ * @param comp_id Component ID.
+ *
+ * @return The valid pair as ICE checklist structure if the
+ * pair exist.
+ */
+PJ_DECL(const pj_ice_sess_check*)
+pj_ice_strans_get_valid_pair(const pj_ice_strans *ice_st,
+ unsigned comp_id);
+
+/**
+ * Stop and destroy the ICE session inside this media transport. Application
+ * needs to call this function once the media session is over (the call has
+ * been disconnected).
+ *
+ * Application MAY reuse this ICE stream transport for subsequent calls.
+ * In this case, it must call #pj_ice_strans_stop_ice() when the call is
+ * disconnected, and reinitialize the ICE stream transport for subsequent
+ * call with #pj_ice_strans_init_ice()/#pj_ice_strans_start_ice(). In this
+ * case, the ICE stream transport will maintain the internal sockets and
+ * continue to send STUN keep-alive packets and TURN Refresh request to
+ * keep the NAT binding/TURN allocation open and to detect change in STUN
+ * mapped address.
+ *
+ * If application does not want to reuse the ICE stream transport for
+ * subsequent calls, it must call #pj_ice_strans_destroy() to destroy the
+ * ICE stream transport altogether.
+ *
+ * @param ice_st The ICE stream transport.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_stop_ice(pj_ice_strans *ice_st);
+
+
+/**
+ * Send outgoing packet using this transport.
+ * Application can send data (normally RTP or RTCP packets) at any time
+ * by calling this function. This function takes a destination
+ * address as one of the arguments, and this destination address should
+ * be taken from the default transport address of the component (that is
+ * the address in SDP c= and m= lines, or in a=rtcp attribute).
+ * If ICE negotiation is in progress, this function will send the data
+ * to the destination address. Otherwise if ICE negotiation has completed
+ * successfully, this function will send the data to the nominated remote
+ * address, as negotiated by ICE.
+ *
+ * @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_strans_sendto(pj_ice_strans *ice_st,
+ unsigned comp_id,
+ const void *data,
+ pj_size_t data_len,
+ const pj_sockaddr_t *dst_addr,
+ int dst_addr_len);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+
+#endif /* __PJNATH_ICE_STRANS_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/nat_detect.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/nat_detect.h
new file mode 100644
index 0000000..e7f854e
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/nat_detect.h
@@ -0,0 +1,208 @@
+/* $Id: nat_detect.h 2642 2009-04-22 17:20:24Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_NAT_DETECT_H__
+#define __PJNATH_NAT_DETECT_H__
+
+/**
+ * @file ice_session.h
+ * @brief ICE session management
+ */
+#include <pjnath/stun_session.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJNATH_NAT_DETECT NAT Classification/Detection Tool
+ * @brief NAT Classification/Detection Tool
+ * @ingroup PJNATH
+ * @{
+ *
+ * This module provides one function to perform NAT classification and
+ * detection. NAT type detection is performed by calling
+ * #pj_stun_detect_nat_type() function.
+ */
+
+
+/**
+ * This enumeration describes the NAT types, as specified by RFC 3489
+ * Section 5, NAT Variations.
+ */
+typedef enum pj_stun_nat_type
+{
+ /**
+ * NAT type is unknown because the detection has not been performed.
+ */
+ PJ_STUN_NAT_TYPE_UNKNOWN,
+
+ /**
+ * NAT type is unknown because there is failure in the detection
+ * process, possibly because server does not support RFC 3489.
+ */
+ PJ_STUN_NAT_TYPE_ERR_UNKNOWN,
+
+ /**
+ * This specifies that the client has open access to Internet (or
+ * at least, its behind a firewall that behaves like a full-cone NAT,
+ * but without the translation)
+ */
+ PJ_STUN_NAT_TYPE_OPEN,
+
+ /**
+ * This specifies that communication with server has failed, probably
+ * because UDP packets are blocked.
+ */
+ PJ_STUN_NAT_TYPE_BLOCKED,
+
+ /**
+ * Firewall that allows UDP out, and responses have to come back to
+ * the source of the request (like a symmetric NAT, but no
+ * translation.
+ */
+ PJ_STUN_NAT_TYPE_SYMMETRIC_UDP,
+
+ /**
+ * A full cone NAT is one where all requests from the same internal
+ * IP address and port are mapped to the same external IP address and
+ * port. Furthermore, any external host can send a packet to the
+ * internal host, by sending a packet to the mapped external address.
+ */
+ PJ_STUN_NAT_TYPE_FULL_CONE,
+
+ /**
+ * A symmetric NAT is one where all requests from the same internal
+ * IP address and port, to a specific destination IP address and port,
+ * are mapped to the same external IP address and port. If the same
+ * host sends a packet with the same source address and port, but to
+ * a different destination, a different mapping is used. Furthermore,
+ * only the external host that receives a packet can send a UDP packet
+ * back to the internal host.
+ */
+ PJ_STUN_NAT_TYPE_SYMMETRIC,
+
+ /**
+ * A restricted cone NAT is one where all requests from the same
+ * internal IP address and port are mapped to the same external IP
+ * address and port. Unlike a full cone NAT, an external host (with
+ * IP address X) can send a packet to the internal host only if the
+ * internal host had previously sent a packet to IP address X.
+ */
+ PJ_STUN_NAT_TYPE_RESTRICTED,
+
+ /**
+ * A port restricted cone NAT is like a restricted cone NAT, but the
+ * restriction includes port numbers. Specifically, an external host
+ * can send a packet, with source IP address X and source port P,
+ * to the internal host only if the internal host had previously sent
+ * a packet to IP address X and port P.
+ */
+ PJ_STUN_NAT_TYPE_PORT_RESTRICTED
+
+} pj_stun_nat_type;
+
+
+/**
+ * This structure contains the result of NAT classification function.
+ */
+typedef struct pj_stun_nat_detect_result
+{
+ /**
+ * Status of the detection process. If this value is not PJ_SUCCESS,
+ * the detection has failed and \a nat_type field will contain
+ * PJ_STUN_NAT_TYPE_UNKNOWN.
+ */
+ pj_status_t status;
+
+ /**
+ * The text describing the status, if the status is not PJ_SUCCESS.
+ */
+ const char *status_text;
+
+ /**
+ * This contains the NAT type as detected by the detection procedure.
+ * This value is only valid when the \a status is PJ_SUCCESS.
+ */
+ pj_stun_nat_type nat_type;
+
+ /**
+ * Text describing that NAT type.
+ */
+ const char *nat_type_name;
+
+} pj_stun_nat_detect_result;
+
+
+/**
+ * Type of callback to be called when the NAT detection function has
+ * completed.
+ */
+typedef void pj_stun_nat_detect_cb(void *user_data,
+ const pj_stun_nat_detect_result *res);
+
+
+/**
+ * Get the NAT name from the specified NAT type.
+ *
+ * @param type NAT type.
+ *
+ * @return NAT name.
+ */
+PJ_DECL(const char*) pj_stun_get_nat_name(pj_stun_nat_type type);
+
+
+/**
+ * Perform NAT classification function according to the procedures
+ * specified in RFC 3489. Once this function returns successfully,
+ * the procedure will run in the "background" and will complete
+ * asynchronously. Application can register a callback to be notified
+ * when such detection has completed.
+ *
+ * @param server STUN server address.
+ * @param stun_cfg A structure containing various STUN configurations,
+ * such as the ioqueue and timer heap instance used
+ * to receive network I/O and timer events.
+ * @param user_data Application data, which will be returned back
+ * in the callback.
+ * @param cb Callback to be registered to receive notification
+ * about detection result.
+ *
+ * @return If this function returns PJ_SUCCESS, the procedure
+ * will complete asynchronously and callback will be
+ * called when it completes. For other return
+ * values, it means that an error has occured and
+ * the procedure did not start.
+ */
+PJ_DECL(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server,
+ pj_stun_config *stun_cfg,
+ void *user_data,
+ pj_stun_nat_detect_cb *cb);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_NAT_DETECT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_auth.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_auth.h
new file mode 100644
index 0000000..57fabb1
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_auth.h
@@ -0,0 +1,457 @@
+/* $Id: stun_auth.h 2642 2009-04-22 17:20:24Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_STUN_AUTH_H__
+#define __PJNATH_STUN_AUTH_H__
+
+/**
+ * @file stun_auth.h
+ * @brief STUN authentication.
+ */
+
+#include <pjnath/stun_msg.h>
+
+
+PJ_BEGIN_DECL
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJNATH_STUN_AUTH STUN Authentication
+ * @brief STUN authentication helper
+ * @ingroup PJNATH_STUN_BASE
+ * @{
+ */
+
+/**
+ * Type of authentication.
+ */
+typedef enum pj_stun_auth_type
+{
+ /**
+ * No authentication.
+ */
+ PJ_STUN_AUTH_NONE = 0,
+
+ /**
+ * Authentication using short term credential.
+ */
+ PJ_STUN_AUTH_SHORT_TERM = 1,
+
+ /**
+ * Authentication using long term credential.
+ */
+ PJ_STUN_AUTH_LONG_TERM = 2
+
+} pj_stun_auth_type;
+
+
+/**
+ * Type of authentication data in the credential.
+ */
+typedef enum pj_stun_auth_cred_type
+{
+ /**
+ * The credential data contains a static credential to be matched
+ * against the credential in the message. A static credential can be
+ * used as both client side or server side authentication.
+ */
+ PJ_STUN_AUTH_CRED_STATIC,
+
+ /**
+ * The credential data contains callbacks to be called to verify the
+ * credential in the message. A dynamic credential is suitable when
+ * performing server side authentication where server does not know
+ * in advance the identity of the user requesting authentication.
+ */
+ PJ_STUN_AUTH_CRED_DYNAMIC
+
+} pj_stun_auth_cred_type;
+
+
+/**
+ * Type of encoding applied to the password stored in the credential.
+ */
+typedef enum pj_stun_passwd_type
+{
+ /**
+ * Plain text password.
+ */
+ PJ_STUN_PASSWD_PLAIN = 0,
+
+ /**
+ * Hashed password, valid for long term credential only. The hash value
+ * of the password is calculated as MD5(USERNAME ":" REALM ":" PASSWD)
+ * with all quotes removed from the username and realm values.
+ */
+ PJ_STUN_PASSWD_HASHED = 1
+
+} pj_stun_passwd_type;
+
+
+/**
+ * This structure contains the descriptions needed to perform server side
+ * authentication. Depending on the \a type set in the structure, application
+ * may specify a static username/password combination, or to have callbacks
+ * called by the function to authenticate the credential dynamically.
+ */
+typedef struct pj_stun_auth_cred
+{
+ /**
+ * The type of authentication information in this structure.
+ */
+ pj_stun_auth_cred_type type;
+
+ /**
+ * This union contains the authentication data.
+ */
+ union
+ {
+ /**
+ * This structure contains static data for performing authentication.
+ * A non-empty realm indicates whether short term or long term
+ * credential is used.
+ */
+ struct
+ {
+ /**
+ * If not-empty, it indicates that this is a long term credential.
+ */
+ pj_str_t realm;
+
+ /**
+ * The username of the credential.
+ */
+ pj_str_t username;
+
+ /**
+ * Data type to indicate the type of password in the \a data field.
+ */
+ pj_stun_passwd_type data_type;
+
+ /**
+ * The data, which depends depends on the value of \a data_type
+ * field. When \a data_type is zero, this field will contain the
+ * plaintext password.
+ */
+ pj_str_t data;
+
+ /**
+ * Optional NONCE.
+ */
+ pj_str_t nonce;
+
+ } static_cred;
+
+ /**
+ * This structure contains callback to be called by the framework
+ * to authenticate the incoming message.
+ */
+ struct
+ {
+ /**
+ * User data which will be passed back to callback functions.
+ */
+ void *user_data;
+
+ /**
+ * This callback is called by pj_stun_verify_credential() when
+ * server needs to challenge the request with 401 response.
+ *
+ * @param user_data The user data as specified in the credential.
+ * @param pool Pool to allocate memory.
+ * @param realm On return, the function should fill in with
+ * realm if application wants to use long term
+ * credential. Otherwise application should set
+ * empty string for the realm.
+ * @param nonce On return, if application wants to use long
+ * term credential, it MUST fill in the nonce
+ * with some value. Otherwise if short term
+ * credential is wanted, it MAY set this value.
+ * If short term credential is wanted and the
+ * application doesn't want to include NONCE,
+ * then it must set this to empty string.
+ *
+ * @return The callback should return PJ_SUCCESS, or
+ * otherwise response message will not be
+ * created.
+ */
+ pj_status_t (*get_auth)(void *user_data,
+ pj_pool_t *pool,
+ pj_str_t *realm,
+ pj_str_t *nonce);
+
+ /**
+ * Get the credential to be put in outgoing request.
+ *
+ * @param msg The outgoing message where the credential is
+ * to be applied.
+ * @param user_data The user data as specified in the credential.
+ * @param pool Pool where the callback can allocate memory
+ * to fill in the credential.
+ * @param realm On return, the callback may specify the realm
+ * if long term credential is desired, otherwise
+ * this string must be set to empty.
+ * @param username On return, the callback must fill in with the
+ * username.
+ * @param nonce On return, the callback may optionally fill in
+ * this argument with NONCE value if desired,
+ * otherwise this argument must be set to empty.
+ * @param data_type On return, the callback must set this argument
+ * with the type of password in the data argument.
+ * @param data On return, the callback must set this with
+ * the password, encoded according to data_type
+ * argument.
+ *
+ * @return The callback must return PJ_SUCCESS, otherwise
+ * the message transmission will be cancelled.
+ */
+ pj_status_t (*get_cred)(const pj_stun_msg *msg,
+ void *user_data,
+ pj_pool_t *pool,
+ pj_str_t *realm,
+ pj_str_t *username,
+ pj_str_t *nonce,
+ pj_stun_passwd_type *data_type,
+ pj_str_t *data);
+
+ /**
+ * Get the password for the specified username. This function
+ * is also used to check whether the username is valid.
+ *
+ * @param msg The STUN message where the password will be
+ * applied to.
+ * @param user_data The user data as specified in the credential.
+ * @param realm The realm as specified in the message.
+ * @param username The username as specified in the message.
+ * @param pool Pool to allocate memory when necessary.
+ * @param data_type On return, application should fill up this
+ * argument with the type of data (which should
+ * be zero if data is a plaintext password).
+ * @param data On return, application should fill up this
+ * argument with the password according to
+ * data_type.
+ *
+ * @return The callback should return PJ_SUCCESS if
+ * username has been successfully verified
+ * and password was obtained. If non-PJ_SUCCESS
+ * is returned, it is assumed that the
+ * username is not valid.
+ */
+ pj_status_t (*get_password)(const pj_stun_msg *msg,
+ void *user_data,
+ const pj_str_t *realm,
+ const pj_str_t *username,
+ pj_pool_t *pool,
+ pj_stun_passwd_type *data_type,
+ pj_str_t *data);
+
+ /**
+ * This callback will be called to verify that the NONCE given
+ * in the message can be accepted. If this callback returns
+ * PJ_FALSE, 438 (Stale Nonce) response will be created.
+ *
+ * This callback is optional.
+ *
+ * @param msg The STUN message where the nonce was received.
+ * @param user_data The user data as specified in the credential.
+ * @param realm The realm as specified in the message.
+ * @param username The username as specified in the message.
+ * @param nonce The nonce to be verified.
+ *
+ * @return The callback MUST return non-zero if the
+ * NONCE can be accepted.
+ */
+ pj_bool_t (*verify_nonce)(const pj_stun_msg *msg,
+ void *user_data,
+ const pj_str_t *realm,
+ const pj_str_t *username,
+ const pj_str_t *nonce);
+
+ } dyn_cred;
+
+ } data;
+
+} pj_stun_auth_cred;
+
+
+/**
+ * This structure contains the credential information that is found and
+ * used to authenticate incoming requests. Application may use this
+ * information when generating authentication for the outgoing response.
+ */
+typedef struct pj_stun_req_cred_info
+{
+ /**
+ * The REALM value found in the incoming request. If short term
+ * credential is used, the value will be empty.
+ */
+ pj_str_t realm;
+
+ /**
+ * The USERNAME value found in the incoming request.
+ */
+ pj_str_t username;
+
+ /**
+ * Optional NONCE.
+ */
+ pj_str_t nonce;
+
+ /**
+ * Authentication key that was used to authenticate the incoming
+ * request. This key is created with #pj_stun_create_key(), and
+ * it can be used to encode the credential of the outgoing
+ * response.
+ */
+ pj_str_t auth_key;
+
+} pj_stun_req_cred_info;
+
+
+/**
+ * Duplicate authentication credential.
+ *
+ * @param pool Pool to be used to allocate memory.
+ * @param dst Destination credential.
+ * @param src Source credential.
+ */
+PJ_DECL(void) pj_stun_auth_cred_dup(pj_pool_t *pool,
+ pj_stun_auth_cred *dst,
+ const pj_stun_auth_cred *src);
+
+/**
+ * Duplicate request credential.
+ *
+ * @param pool Pool to be used to allocate memory.
+ * @param dst Destination credential.
+ * @param src Source credential.
+ */
+PJ_DECL(void) pj_stun_req_cred_info_dup(pj_pool_t *pool,
+ pj_stun_req_cred_info *dst,
+ const pj_stun_req_cred_info *src);
+
+
+/**
+ * Create authentication key to be used for encoding the message with
+ * MESSAGE-INTEGRITY. If short term credential is used (i.e. the realm
+ * argument is NULL or empty), the key will be copied from the password.
+ * If long term credential is used, the key will be calculated from the
+ * MD5 hash of the realm, username, and password.
+ *
+ * @param pool Pool to allocate memory for the key.
+ * @param key String to receive the key.
+ * @param realm The realm of the credential, if long term credential
+ * is to be used. If short term credential is wanted,
+ * application can put NULL or empty string here.
+ * @param username The username.
+ * @param data_type Password encoding.
+ * @param data The password.
+ */
+PJ_DECL(void) pj_stun_create_key(pj_pool_t *pool,
+ pj_str_t *key,
+ const pj_str_t *realm,
+ const pj_str_t *username,
+ pj_stun_passwd_type data_type,
+ const pj_str_t *data);
+
+/**
+ * Verify credential in the STUN request. Note that before calling this
+ * function, application must have checked that the message contains
+ * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()
+ * function, because this function will reject the message with 401 error
+ * if it doesn't contain PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute.
+ *
+ * @param pkt The original packet which has been parsed into
+ * the message. This packet MUST NOT have been modified
+ * after the parsing.
+ * @param pkt_len The length of the packet.
+ * @param msg The parsed message to be verified.
+ * @param cred Pointer to credential to be used to authenticate
+ * the message.
+ * @param pool If response is to be created, then memory will
+ * be allocated from this pool.
+ * @param info Optional pointer to receive authentication information
+ * found in the request and the credential that is used
+ * to authenticate the request.
+ * @param p_response Optional pointer to receive the response message
+ * then the credential in the request fails to
+ * authenticate.
+ *
+ * @return PJ_SUCCESS if credential is verified successfully.
+ * If the verification fails and \a p_response is not
+ * NULL, an appropriate response will be returned in
+ * \a p_response.
+ */
+PJ_DECL(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,
+ unsigned pkt_len,
+ const pj_stun_msg *msg,
+ pj_stun_auth_cred *cred,
+ pj_pool_t *pool,
+ pj_stun_req_cred_info *info,
+ pj_stun_msg **p_response);
+
+
+/**
+ * Determine if STUN message can be authenticated. Some STUN error
+ * responses cannot be authenticated since they cannot contain STUN
+ * MESSAGE-INTEGRITY attribute. STUN Indication messages also cannot
+ * be authenticated.
+ *
+ * @param msg The STUN message.
+ *
+ * @return Non-zero if the STUN message can be authenticated.
+ */
+PJ_DECL(pj_bool_t) pj_stun_auth_valid_for_msg(const pj_stun_msg *msg);
+
+
+/**
+ * Verify credential in the STUN response. Note that before calling this
+ * function, application must have checked that the message contains
+ * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()
+ * function, because otherwise this function will report authentication
+ * failure.
+ *
+ * @param pkt The original packet which has been parsed into
+ * the message. This packet MUST NOT have been modified
+ * after the parsing.
+ * @param pkt_len The length of the packet.
+ * @param msg The parsed message to be verified.
+ * @param key Authentication key to calculate MESSAGE-INTEGRITY
+ * value. Application can create this key by using
+ * #pj_stun_create_key() function.
+ *
+ * @return PJ_SUCCESS if credential is verified successfully.
+ */
+PJ_DECL(pj_status_t) pj_stun_authenticate_response(const pj_uint8_t *pkt,
+ unsigned pkt_len,
+ const pj_stun_msg *msg,
+ const pj_str_t *key);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_STUN_AUTH_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_config.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_config.h
new file mode 100644
index 0000000..9ff1474
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_config.h
@@ -0,0 +1,128 @@
+/* $Id: stun_config.h 2642 2009-04-22 17:20:24Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_STUN_CONFIG_H__
+#define __PJNATH_STUN_CONFIG_H__
+
+/**
+ * @file stun_config.h
+ * @brief STUN endpoint.
+ */
+
+#include <pjnath/stun_msg.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/string.h>
+
+
+PJ_BEGIN_DECL
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJNATH_STUN_CONFIG STUN Config
+ * @brief STUN config
+ * @ingroup PJNATH_STUN_BASE
+ * @{
+ */
+
+/**
+ * STUN configuration.
+ */
+typedef struct pj_stun_config
+{
+ /**
+ * Pool factory to be used.
+ */
+ pj_pool_factory *pf;
+
+ /**
+ * Ioqueue.
+ */
+ pj_ioqueue_t *ioqueue;
+
+ /**
+ * Timer heap instance.
+ */
+ pj_timer_heap_t *timer_heap;
+
+ /**
+ * Options.
+ */
+ unsigned options;
+
+ /**
+ * The default initial STUN round-trip time estimation in msecs.
+ * The value normally is PJ_STUN_RTO_VALUE.
+ */
+ unsigned rto_msec;
+
+ /**
+ * The interval to cache outgoing STUN response in the STUN session,
+ * in miliseconds.
+ *
+ * Default 10000 (10 seconds).
+ */
+ unsigned res_cache_msec;
+
+} pj_stun_config;
+
+
+
+/**
+ * Initialize STUN config.
+ */
+PJ_INLINE(void) pj_stun_config_init(pj_stun_config *cfg,
+ pj_pool_factory *factory,
+ unsigned options,
+ pj_ioqueue_t *ioqueue,
+ pj_timer_heap_t *timer_heap)
+{
+ pj_bzero(cfg, sizeof(*cfg));
+
+ cfg->pf = factory;
+ cfg->options = options;
+ cfg->ioqueue = ioqueue;
+ cfg->timer_heap = timer_heap;
+ cfg->rto_msec = PJ_STUN_RTO_VALUE;
+ cfg->res_cache_msec = PJ_STUN_RES_CACHE_DURATION;
+}
+
+
+/**
+ * Check that STUN config is valid.
+ */
+PJ_INLINE(pj_status_t) pj_stun_config_check_valid(const pj_stun_config *cfg)
+{
+ PJ_ASSERT_RETURN(cfg->ioqueue && cfg->pf && cfg->timer_heap &&
+ cfg->rto_msec && cfg->res_cache_msec, PJ_EINVAL);
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_STUN_CONFIG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_msg.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_msg.h
new file mode 100644
index 0000000..90774b6
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_msg.h
@@ -0,0 +1,1820 @@
+/* $Id: stun_msg.h 2724 2009-05-29 13:04:03Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_STUN_MSG_H__
+#define __PJNATH_STUN_MSG_H__
+
+/**
+ * @file stun_msg.h
+ * @brief STUN message components.
+ */
+
+#include <pjnath/types.h>
+#include <pj/sock.h>
+
+
+PJ_BEGIN_DECL
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJNATH_STUN_MSG STUN Message Representation and Parsing
+ * @ingroup PJNATH_STUN_BASE
+ * @brief Low-level representation and parsing of STUN messages.
+ * @{
+ */
+
+
+/**
+ * STUN magic cookie.
+ */
+#define PJ_STUN_MAGIC 0x2112A442
+
+
+/**
+ * STUN method constants.
+ */
+enum pj_stun_method_e
+{
+ /**
+ * STUN Binding method as defined by RFC 3489-bis.
+ */
+ PJ_STUN_BINDING_METHOD = 1,
+
+ /**
+ * STUN Shared Secret method as defined by RFC 3489-bis.
+ */
+ PJ_STUN_SHARED_SECRET_METHOD = 2,
+
+ /**
+ * STUN/TURN Allocate method as defined by draft-ietf-behave-turn
+ */
+ PJ_STUN_ALLOCATE_METHOD = 3,
+
+ /**
+ * STUN/TURN Refresh method as defined by draft-ietf-behave-turn
+ */
+ PJ_STUN_REFRESH_METHOD = 4,
+
+ /**
+ * STUN/TURN Send indication as defined by draft-ietf-behave-turn
+ */
+ PJ_STUN_SEND_METHOD = 6,
+
+ /**
+ * STUN/TURN Data indication as defined by draft-ietf-behave-turn
+ */
+ PJ_STUN_DATA_METHOD = 7,
+
+ /**
+ * STUN/TURN CreatePermission method as defined by draft-ietf-behave-turn
+ */
+ PJ_STUN_CREATE_PERM_METHOD = 8,
+
+ /**
+ * STUN/TURN ChannelBind as defined by draft-ietf-behave-turn
+ */
+ PJ_STUN_CHANNEL_BIND_METHOD = 9,
+
+ /**
+ * All known methods.
+ */
+ PJ_STUN_METHOD_MAX
+};
+
+
+/**
+ * Retrieve the STUN method from the message-type field of the STUN
+ * message.
+ */
+#define PJ_STUN_GET_METHOD(msg_type) ((msg_type) & 0xFEEF)
+
+
+/**
+ * STUN message classes constants.
+ */
+enum pj_stun_msg_class_e
+{
+ /**
+ * This specifies that the message type is a STUN request message.
+ */
+ PJ_STUN_REQUEST_CLASS = 0,
+
+ /**
+ * This specifies that the message type is a STUN indication message.
+ */
+ PJ_STUN_INDICATION_CLASS = 1,
+
+ /**
+ * This specifies that the message type is a STUN successful response.
+ */
+ PJ_STUN_SUCCESS_CLASS = 2,
+
+ /**
+ * This specifies that the message type is a STUN error response.
+ */
+ PJ_STUN_ERROR_CLASS = 3
+};
+
+
+/**
+ * Determine if the message type is a request.
+ */
+#define PJ_STUN_IS_REQUEST(msg_type) (((msg_type) & 0x0110) == 0x0000)
+
+
+/**
+ * Determine if the message type is a successful response.
+ */
+#define PJ_STUN_IS_SUCCESS_RESPONSE(msg_type) (((msg_type) & 0x0110) == 0x0100)
+
+/**
+ * The response bit in the message type.
+ */
+#define PJ_STUN_SUCCESS_RESPONSE_BIT (0x0100)
+
+
+/**
+ * Determine if the message type is an error response.
+ */
+#define PJ_STUN_IS_ERROR_RESPONSE(msg_type) (((msg_type) & 0x0110) == 0x0110)
+
+/**
+ * The error response bit in the message type.
+ */
+#define PJ_STUN_ERROR_RESPONSE_BIT (0x0110)
+
+/**
+ * Determine if the message type is a response.
+ */
+#define PJ_STUN_IS_RESPONSE(msg_type) (((msg_type) & 0x0100) == 0x0100)
+
+
+/**
+ * Determine if the message type is an indication message.
+ */
+#define PJ_STUN_IS_INDICATION(msg_type) (((msg_type) & 0x0110) == 0x0010)
+
+/**
+ * The error response bit in the message type.
+ */
+#define PJ_STUN_INDICATION_BIT (0x0010)
+
+
+/**
+ * This enumeration describes STUN message types.
+ */
+typedef enum pj_stun_msg_type
+{
+ /**
+ * STUN BINDING request.
+ */
+ PJ_STUN_BINDING_REQUEST = 0x0001,
+
+ /**
+ * Successful response to STUN BINDING-REQUEST.
+ */
+ PJ_STUN_BINDING_RESPONSE = 0x0101,
+
+ /**
+ * Error response to STUN BINDING-REQUEST.
+ */
+ PJ_STUN_BINDING_ERROR_RESPONSE = 0x0111,
+
+ /**
+ * Binding Indication (ICE)
+ */
+ PJ_STUN_BINDING_INDICATION = 0x0011,
+
+ /**
+ * STUN SHARED-SECRET reqeust.
+ */
+ PJ_STUN_SHARED_SECRET_REQUEST = 0x0002,
+
+ /**
+ * Successful response to STUN SHARED-SECRET reqeust.
+ */
+ PJ_STUN_SHARED_SECRET_RESPONSE = 0x0102,
+
+ /**
+ * Error response to STUN SHARED-SECRET reqeust.
+ */
+ PJ_STUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112,
+
+
+ /**
+ * STUN/TURN Allocate Request
+ */
+ PJ_STUN_ALLOCATE_REQUEST = 0x0003,
+
+ /**
+ * Successful response to STUN/TURN Allocate Request
+ */
+ PJ_STUN_ALLOCATE_RESPONSE = 0x0103,
+
+ /**
+ * Failure response to STUN/TURN Allocate Request
+ */
+ PJ_STUN_ALLOCATE_ERROR_RESPONSE = 0x0113,
+
+
+ /**
+ * STUN/TURN REFRESH Request
+ */
+ PJ_STUN_REFRESH_REQUEST = 0x0004,
+
+ /**
+ * Successful response to STUN REFRESH request
+ */
+ PJ_STUN_REFRESH_RESPONSE = 0x0104,
+
+ /**
+ * Error response to STUN REFRESH request.
+ */
+ PJ_STUN_REFRESH_ERROR_RESPONSE = 0x0114,
+
+
+ /**
+ * TURN Send indication
+ */
+ PJ_STUN_SEND_INDICATION = 0x0016,
+
+
+ /**
+ * TURN Data indication
+ */
+ PJ_STUN_DATA_INDICATION = 0x0017,
+
+
+ /**
+ * TURN CreatePermission request
+ */
+ PJ_STUN_CREATE_PERM_REQUEST = 0x0008,
+
+ /**
+ * TURN CreatePermission successful response.
+ */
+ PJ_STUN_CREATE_PERM_RESPONSE = 0x0108,
+
+ /**
+ * TURN CreatePermission failure response
+ */
+ PJ_STUN_CREATE_PERM_ERROR_RESPONSE = 0x0118,
+
+
+ /**
+ * STUN/TURN ChannelBind Request
+ */
+ PJ_STUN_CHANNEL_BIND_REQUEST = 0x0009,
+
+ /**
+ * Successful response to STUN ChannelBind request
+ */
+ PJ_STUN_CHANNEL_BIND_RESPONSE = 0x0109,
+
+ /**
+ * Error response to STUN ChannelBind request.
+ */
+ PJ_STUN_CHANNEL_BIND_ERROR_RESPONSE = 0x0119
+
+} pj_stun_msg_type;
+
+
+
+/**
+ * This enumeration describes STUN attribute types.
+ */
+typedef enum pj_stun_attr_type
+{
+ PJ_STUN_ATTR_MAPPED_ADDR = 0x0001,/**< MAPPED-ADDRESS. */
+ PJ_STUN_ATTR_RESPONSE_ADDR = 0x0002,/**< RESPONSE-ADDRESS (deprcatd)*/
+ PJ_STUN_ATTR_CHANGE_REQUEST = 0x0003,/**< CHANGE-REQUEST (deprecated)*/
+ PJ_STUN_ATTR_SOURCE_ADDR = 0x0004,/**< SOURCE-ADDRESS (deprecated)*/
+ PJ_STUN_ATTR_CHANGED_ADDR = 0x0005,/**< CHANGED-ADDRESS (deprecatd)*/
+ PJ_STUN_ATTR_USERNAME = 0x0006,/**< USERNAME attribute. */
+ PJ_STUN_ATTR_PASSWORD = 0x0007,/**< was PASSWORD attribute. */
+ PJ_STUN_ATTR_MESSAGE_INTEGRITY = 0x0008,/**< MESSAGE-INTEGRITY. */
+ PJ_STUN_ATTR_ERROR_CODE = 0x0009,/**< ERROR-CODE. */
+ PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000A,/**< UNKNOWN-ATTRIBUTES. */
+ PJ_STUN_ATTR_REFLECTED_FROM = 0x000B,/**< REFLECTED-FROM (deprecatd)*/
+ PJ_STUN_ATTR_CHANNEL_NUMBER = 0x000C,/**< TURN CHANNEL-NUMBER */
+ PJ_STUN_ATTR_LIFETIME = 0x000D,/**< TURN LIFETIME attr. */
+ PJ_STUN_ATTR_MAGIC_COOKIE = 0x000F,/**< MAGIC-COOKIE attr (deprec)*/
+ PJ_STUN_ATTR_BANDWIDTH = 0x0010,/**< TURN BANDWIDTH (deprec) */
+ PJ_STUN_ATTR_XOR_PEER_ADDR = 0x0012,/**< TURN XOR-PEER-ADDRESS */
+ PJ_STUN_ATTR_DATA = 0x0013,/**< DATA attribute. */
+ PJ_STUN_ATTR_REALM = 0x0014,/**< REALM attribute. */
+ PJ_STUN_ATTR_NONCE = 0x0015,/**< NONCE attribute. */
+ PJ_STUN_ATTR_XOR_RELAYED_ADDR = 0x0016,/**< TURN XOR-RELAYED-ADDRESS */
+ PJ_STUN_ATTR_REQ_ADDR_TYPE = 0x0017,/**< REQUESTED-ADDRESS-TYPE */
+ PJ_STUN_ATTR_EVEN_PORT = 0x0018,/**< TURN EVEN-PORT */
+ PJ_STUN_ATTR_REQ_TRANSPORT = 0x0019,/**< TURN REQUESTED-TRANSPORT */
+ PJ_STUN_ATTR_DONT_FRAGMENT = 0x001A,/**< TURN DONT-FRAGMENT */
+ PJ_STUN_ATTR_XOR_MAPPED_ADDR = 0x0020,/**< XOR-MAPPED-ADDRESS */
+ PJ_STUN_ATTR_TIMER_VAL = 0x0021,/**< TIMER-VAL attribute. */
+ PJ_STUN_ATTR_RESERVATION_TOKEN = 0x0022,/**< TURN RESERVATION-TOKEN */
+ PJ_STUN_ATTR_XOR_REFLECTED_FROM = 0x0023,/**< XOR-REFLECTED-FROM */
+ PJ_STUN_ATTR_PRIORITY = 0x0024,/**< PRIORITY */
+ PJ_STUN_ATTR_USE_CANDIDATE = 0x0025,/**< USE-CANDIDATE */
+ PJ_STUN_ATTR_ICMP = 0x0030,/**< ICMP (TURN) */
+
+ PJ_STUN_ATTR_END_MANDATORY_ATTR,
+
+ PJ_STUN_ATTR_START_EXTENDED_ATTR= 0x8021,
+
+ PJ_STUN_ATTR_SOFTWARE = 0x8022,/**< SOFTWARE attribute. */
+ PJ_STUN_ATTR_ALTERNATE_SERVER = 0x8023,/**< ALTERNATE-SERVER. */
+ PJ_STUN_ATTR_REFRESH_INTERVAL = 0x8024,/**< REFRESH-INTERVAL. */
+ PJ_STUN_ATTR_FINGERPRINT = 0x8028,/**< FINGERPRINT attribute. */
+ PJ_STUN_ATTR_ICE_CONTROLLED = 0x8029,/**< ICE-CCONTROLLED attribute.*/
+ PJ_STUN_ATTR_ICE_CONTROLLING = 0x802a,/**< ICE-CCONTROLLING attribute*/
+
+ PJ_STUN_ATTR_END_EXTENDED_ATTR
+
+} pj_stun_attr_type;
+
+
+/**
+ * STUN error codes, which goes into STUN ERROR-CODE attribute.
+ */
+typedef enum pj_stun_status
+{
+ PJ_STUN_SC_TRY_ALTERNATE = 300, /**< Try Alternate */
+ PJ_STUN_SC_BAD_REQUEST = 400, /**< Bad Request */
+ PJ_STUN_SC_UNAUTHORIZED = 401, /**< Unauthorized */
+ PJ_STUN_SC_FORBIDDEN = 403, /**< Forbidden (TURN) */
+ PJ_STUN_SC_UNKNOWN_ATTRIBUTE = 420, /**< Unknown Attribute */
+#if 0
+ /* These were obsolete in recent rfc3489bis */
+ //PJ_STUN_SC_STALE_CREDENTIALS = 430, /**< Stale Credentials */
+ //PJ_STUN_SC_INTEGRITY_CHECK_FAILURE= 431, /**< Integrity Chk Fail */
+ //PJ_STUN_SC_MISSING_USERNAME = 432, /**< Missing Username */
+ //PJ_STUN_SC_USE_TLS = 433, /**< Use TLS */
+ //PJ_STUN_SC_MISSING_REALM = 434, /**< Missing Realm */
+ //PJ_STUN_SC_MISSING_NONCE = 435, /**< Missing Nonce */
+ //PJ_STUN_SC_UNKNOWN_USERNAME = 436, /**< Unknown Username */
+#endif
+ PJ_STUN_SC_ALLOCATION_MISMATCH = 437, /**< TURN Alloc Mismatch */
+ PJ_STUN_SC_STALE_NONCE = 438, /**< Stale Nonce */
+ PJ_STUN_SC_TRANSITIONING = 439, /**< Transitioning. */
+ PJ_STUN_SC_WRONG_CREDENTIALS = 441, /**< TURN Wrong Credentials */
+ PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO = 442, /**< Unsupported Transport or
+ Protocol (TURN) */
+ PJ_STUN_SC_OPER_TCP_ONLY = 445, /**< Operation for TCP Only */
+ PJ_STUN_SC_CONNECTION_FAILURE = 446, /**< Connection Failure */
+ PJ_STUN_SC_CONNECTION_TIMEOUT = 447, /**< Connection Timeout */
+ PJ_STUN_SC_ALLOCATION_QUOTA_REACHED = 486, /**< Allocation Quota Reached
+ (TURN) */
+ PJ_STUN_SC_ROLE_CONFLICT = 487, /**< Role Conflict */
+ PJ_STUN_SC_SERVER_ERROR = 500, /**< Server Error */
+ PJ_STUN_SC_INSUFFICIENT_CAPACITY = 508, /**< Insufficient Capacity
+ (TURN) */
+ PJ_STUN_SC_GLOBAL_FAILURE = 600 /**< Global Failure */
+} pj_stun_status;
+
+
+/**
+ * This structure describes STUN message header. A STUN message has the
+ * following format:
+ *
+ * \verbatim
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |0 0| STUN Message Type | Message Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Magic Cookie |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ Transaction ID
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ \endverbatim
+ */
+typedef struct pj_stun_msg_hdr
+{
+ /**
+ * STUN message type, which the first two bits must be zeroes.
+ */
+ pj_uint16_t type;
+
+ /**
+ * The message length is the size, in bytes, of the message not
+ * including the 20 byte STUN header.
+ */
+ pj_uint16_t length;
+
+ /**
+ * The magic cookie is a fixed value, 0x2112A442 (PJ_STUN_MAGIC constant).
+ * In the previous version of this specification [15] this field was part
+ * of the transaction ID.
+ */
+ pj_uint32_t magic;
+
+ /**
+ * The transaction ID is a 96 bit identifier. STUN transactions are
+ * identified by their unique 96-bit transaction ID. For request/
+ * response transactions, the transaction ID is chosen by the STUN
+ * client and MUST be unique for each new STUN transaction generated by
+ * that STUN client. The transaction ID MUST be uniformly and randomly
+ * distributed between 0 and 2**96 - 1.
+ */
+ pj_uint8_t tsx_id[12];
+
+} pj_stun_msg_hdr;
+
+
+/**
+ * This structre describes STUN attribute header. Each attribute is
+ * TLV encoded, with a 16 bit type, 16 bit length, and variable value.
+ * Each STUN attribute ends on a 32 bit boundary:
+ *
+ * \verbatim
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ \endverbatim
+ */
+typedef struct pj_stun_attr_hdr
+{
+ /**
+ * STUN attribute type.
+ */
+ pj_uint16_t type;
+
+ /**
+ * The Length refers to the length of the actual useful content of the
+ * Value portion of the attribute, measured in bytes. The value
+ * in the Length field refers to the length of the Value part of the
+ * attribute prior to padding - i.e., the useful content.
+ */
+ pj_uint16_t length;
+
+} pj_stun_attr_hdr;
+
+
+/**
+ * This structure describes STUN generic IP address attribute, used for
+ * example to represent STUN MAPPED-ADDRESS attribute.
+ *
+ * The generic IP address attribute indicates the transport address.
+ * It consists of an eight bit address family, and a sixteen bit port,
+ * followed by a fixed length value representing the IP address. If the
+ * address family is IPv4, the address is 32 bits, in network byte
+ * order. If the address family is IPv6, the address is 128 bits in
+ * network byte order.
+ *
+ * The format of the generic IP address attribute is:
+ *
+ * \verbatim
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |x x x x x x x x| Family | Port |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Address (variable)
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ \endverbatim
+ */
+typedef struct pj_stun_sockaddr_attr
+{
+ /**
+ * Standard STUN attribute header.
+ */
+ pj_stun_attr_hdr hdr;
+
+ /**
+ * Flag to indicate whether this attribute should be sent in XOR-ed
+ * format, or has been received in XOR-ed format.
+ */
+ pj_bool_t xor_ed;
+
+ /**
+ * The socket address
+ */
+ pj_sockaddr sockaddr;
+
+} pj_stun_sockaddr_attr;
+
+
+/**
+ * This structure represents a generic STUN attributes with no payload,
+ * and it is used for example by ICE USE-CANDIDATE attribute.
+ */
+typedef struct pj_stun_empty_attr
+{
+ /**
+ * Standard STUN attribute header.
+ */
+ pj_stun_attr_hdr hdr;
+
+} pj_stun_empty_attr;
+
+
+/**
+ * This structure represents generic STUN string attributes, such as STUN
+ * USERNAME, PASSWORD, SOFTWARE, REALM, and NONCE attributes.
+ */
+typedef struct pj_stun_string_attr
+{
+ /**
+ * Standard STUN attribute header.
+ */
+ pj_stun_attr_hdr hdr;
+
+ /**
+ * The string value.
+ */
+ pj_str_t value;
+
+} pj_stun_string_attr;
+
+
+/**
+ * This structure represents a generic STUN attributes with 32bit (unsigned)
+ * integer value, such as STUN FINGERPRINT and REFRESH-INTERVAL attributes.
+ */
+typedef struct pj_stun_uint_attr
+{
+ /**
+ * Standard STUN attribute header.
+ */
+ pj_stun_attr_hdr hdr;
+
+ /**
+ * The 32bit value, in host byte order.
+ */
+ pj_uint32_t value;
+
+} pj_stun_uint_attr;
+
+
+/**
+ * This structure represents a generic STUN attributes with 64bit (unsigned)
+ * integer value, such as ICE-CONTROLLED and ICE-CONTROLLING attributes.
+ */
+typedef struct pj_stun_uint64_attr
+{
+ /**
+ * Standard STUN attribute header.
+ */
+ pj_stun_attr_hdr hdr;
+
+ /**
+ * The 64bit value, in host byte order, represented with pj_timestamp.
+ */
+ pj_timestamp value;
+
+} pj_stun_uint64_attr;
+
+
+/**
+ * This structure represents generic STUN attributes to hold a raw binary
+ * data.
+ */
+typedef struct pj_stun_binary_attr
+{
+ /**
+ * Standard STUN attribute header.
+ */
+ pj_stun_attr_hdr hdr;
+
+ /**
+ * Special signature to indicate that this is a valid attribute even
+ * though we don't have meta-data to describe this attribute.
+ */
+ pj_uint32_t magic;
+
+ /**
+ * Length of the data.
+ */
+ unsigned length;
+
+ /**
+ * The raw data.
+ */
+ pj_uint8_t *data;
+
+} pj_stun_binary_attr;
+
+
+/**
+ * This structure describes STUN MESSAGE-INTEGRITY attribute.
+ * The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [10] of the
+ * STUN message. The MESSAGE-INTEGRITY attribute can be present in any
+ * STUN message type. Since it uses the SHA1 hash, the HMAC will be 20
+ * bytes.
+ */
+typedef struct pj_stun_msgint_attr
+{
+ /**
+ * Standard STUN attribute header.
+ */
+ pj_stun_attr_hdr hdr;
+
+ /**
+ * The 20 bytes hmac value.
+ */
+ pj_uint8_t hmac[20];
+
+} pj_stun_msgint_attr;
+
+
+/**
+ * This structure describes STUN FINGERPRINT attribute. The FINGERPRINT
+ * attribute can be present in all STUN messages. It is computed as
+ * the CRC-32 of the STUN message up to (but excluding) the FINGERPRINT
+ * attribute itself, xor-d with the 32 bit value 0x5354554e
+ */
+typedef struct pj_stun_uint_attr pj_stun_fingerprint_attr;
+
+
+/**
+ * This structure represents STUN ERROR-CODE attribute. The ERROR-CODE
+ * attribute is present in the Binding Error Response and Shared Secret
+ * Error Response. It is a numeric value in the range of 100 to 699
+ * plus a textual reason phrase encoded in UTF-8
+ *
+ * \verbatim
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | 0 |Class| Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Reason Phrase (variable) ..
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ \endverbatim
+ */
+typedef struct pj_stun_errcode_attr
+{
+ /**
+ * Standard STUN attribute header.
+ */
+ pj_stun_attr_hdr hdr;
+
+ /**
+ * STUN error code.
+ */
+ int err_code;
+
+ /**
+ * The reason phrase.
+ */
+ pj_str_t reason;
+
+} pj_stun_errcode_attr;
+
+
+/**
+ * This describes STUN REALM attribute.
+ * The REALM attribute is present in requests and responses. It
+ * contains text which meets the grammar for "realm" as described in RFC
+ * 3261 [11], and will thus contain a quoted string (including the
+ * quotes).
+ */
+typedef struct pj_stun_string_attr pj_stun_realm_attr;
+
+
+/**
+ * This describes STUN NONCE attribute.
+ * The NONCE attribute is present in requests and in error responses.
+ * It contains a sequence of qdtext or quoted-pair, which are defined in
+ * RFC 3261 [11]. See RFC 2617 [7] for guidance on selection of nonce
+ * values in a server.
+ */
+typedef struct pj_stun_string_attr pj_stun_nonce_attr;
+
+
+/**
+ * This describes STUN UNKNOWN-ATTRIBUTES attribute.
+ * The UNKNOWN-ATTRIBUTES attribute is present only in an error response
+ * when the response code in the ERROR-CODE attribute is 420.
+ * The attribute contains a list of 16 bit values, each of which
+ * represents an attribute type that was not understood by the server.
+ * If the number of unknown attributes is an odd number, one of the
+ * attributes MUST be repeated in the list, so that the total length of
+ * the list is a multiple of 4 bytes.
+ */
+typedef struct pj_stun_unknown_attr
+{
+ /**
+ * Standard STUN attribute header.
+ */
+ pj_stun_attr_hdr hdr;
+
+ /**
+ * Number of unknown attributes in the array.
+ */
+ unsigned attr_count;
+
+ /**
+ * Array of unknown attribute IDs.
+ */
+ pj_uint16_t attrs[PJ_STUN_MAX_ATTR];
+
+} pj_stun_unknown_attr;
+
+
+/**
+ * This structure describes STUN MAPPED-ADDRESS attribute.
+ * The MAPPED-ADDRESS attribute indicates the mapped transport address.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_mapped_addr_attr;
+
+
+/**
+ * This describes STUN XOR-MAPPED-ADDRESS attribute (which has the same
+ * format as STUN MAPPED-ADDRESS attribute).
+ * The XOR-MAPPED-ADDRESS attribute is present in responses. It
+ * provides the same information that would present in the MAPPED-
+ * ADDRESS attribute but because the NAT's public IP address is
+ * obfuscated through the XOR function, STUN messages are able to pass
+ * through NATs which would otherwise interfere with STUN.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_xor_mapped_addr_attr;
+
+
+/**
+ * This describes STUN SOFTWARE attribute.
+ * The SOFTWARE attribute contains a textual description of the software
+ * being used by the agent sending the message. It is used by clients
+ * and servers. Its value SHOULD include manufacturer and version
+ * number. */
+typedef struct pj_stun_string_attr pj_stun_software_attr;
+
+
+/**
+ * This describes STUN ALTERNATE-SERVER attribute.
+ * The alternate server represents an alternate transport address for a
+ * different STUN server to try. It is encoded in the same way as
+ * MAPPED-ADDRESS.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_alt_server_attr;
+
+
+/**
+ * This describes STUN REFRESH-INTERVAL attribute.
+ * The REFRESH-INTERVAL indicates the number of milliseconds that the
+ * server suggests the client should use between refreshes of the NAT
+ * bindings between the client and server.
+ */
+typedef struct pj_stun_uint_attr pj_stun_refresh_interval_attr;
+
+
+/**
+ * This structure describes STUN RESPONSE-ADDRESS attribute.
+ * The RESPONSE-ADDRESS attribute indicates where the response to a
+ * Binding Request should be sent. Its syntax is identical to MAPPED-
+ * ADDRESS.
+ *
+ * Note that the usage of this attribute has been deprecated by the
+ * RFC 3489-bis standard.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_response_addr_attr;
+
+
+/**
+ * This structure describes STUN CHANGED-ADDRESS attribute.
+ * The CHANGED-ADDRESS attribute indicates the IP address and port where
+ * responses would have been sent from if the "change IP" and "change
+ * port" flags had been set in the CHANGE-REQUEST attribute of the
+ * Binding Request. The attribute is always present in a Binding
+ * Response, independent of the value of the flags. Its syntax is
+ * identical to MAPPED-ADDRESS.
+ *
+ * Note that the usage of this attribute has been deprecated by the
+ * RFC 3489-bis standard.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_changed_addr_attr;
+
+
+/**
+ * This structure describes STUN CHANGE-REQUEST attribute.
+ * The CHANGE-REQUEST attribute is used by the client to request that
+ * the server use a different address and/or port when sending the
+ * response.
+ *
+ * Bit 29 of the value is the "change IP" flag. If true, it requests
+ * the server to send the Binding Response with a different IP address
+ * than the one the Binding Request was received on.
+ *
+ * Bit 30 of the value is the "change port" flag. If true, it requests
+ * the server to send the Binding Response with a different port than
+ * the one the Binding Request was received on.
+ *
+ * Note that the usage of this attribute has been deprecated by the
+ * RFC 3489-bis standard.
+ */
+typedef struct pj_stun_uint_attr pj_stun_change_request_attr;
+
+/**
+ * This structure describes STUN SOURCE-ADDRESS attribute.
+ * The SOURCE-ADDRESS attribute is present in Binding Responses. It
+ * indicates the source IP address and port that the server is sending
+ * the response from. Its syntax is identical to that of MAPPED-
+ * ADDRESS.
+ *
+ * Note that the usage of this attribute has been deprecated by the
+ * RFC 3489-bis standard.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_src_addr_attr;
+
+
+/**
+ * This describes the STUN REFLECTED-FROM attribute.
+ * The REFLECTED-FROM attribute is present only in Binding Responses,
+ * when the Binding Request contained a RESPONSE-ADDRESS attribute. The
+ * attribute contains the identity (in terms of IP address) of the
+ * source where the request came from. Its purpose is to provide
+ * traceability, so that a STUN server cannot be used as a reflector for
+ * denial-of-service attacks.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_reflected_from_attr;
+
+
+/**
+ * This describes STUN USERNAME attribute.
+ * The USERNAME attribute is used for message integrity. It identifies
+ * the shared secret used in the message integrity check. Consequently,
+ * the USERNAME MUST be included in any request that contains the
+ * MESSAGE-INTEGRITY attribute.
+ */
+typedef struct pj_stun_string_attr pj_stun_username_attr;
+
+
+/**
+ * This describes STUN PASSWORD attribute.
+ * If the message type is Shared Secret Response it MUST include the
+ * PASSWORD attribute.
+ */
+typedef struct pj_stun_string_attr pj_stun_password_attr;
+
+
+/**
+ * This describes TURN CHANNEL-NUMBER attribute. In this library,
+ * this attribute is represented with 32bit integer. Application may
+ * use #PJ_STUN_GET_CH_NB() and #PJ_STUN_SET_CH_NB() to extract/set
+ * channel number value from the 32bit integral value.
+ *
+ * The CHANNEL-NUMBER attribute contains the number of the channel.
+ * It is a 16-bit unsigned integer, followed by a two-octet RFFU field
+ * which MUST be set to 0 on transmission and ignored on reception.
+
+ \verbatim
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Channel Number | RFFU |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \endverbatim
+ */
+typedef struct pj_stun_uint_attr pj_stun_channel_number_attr;
+
+/**
+ * Get 16bit channel number from 32bit integral value.
+ * Note that uint32 attributes are always stored in host byte order
+ * after they have been parsed from the PDU, so no need to do ntohs()
+ * here.
+ */
+#define PJ_STUN_GET_CH_NB(u32) ((pj_uint16_t)(u32>>16))
+
+/**
+ * Convert 16bit channel number into 32bit integral value.
+ * Note that uint32 attributes will be converted to network byte order
+ * when the attribute is written to packet, so no need to do htons()
+ * here.
+ */
+#define PJ_STUN_SET_CH_NB(chnum) (((pj_uint32_t)chnum) << 16)
+
+
+/**
+ * This describes STUN LIFETIME attribute.
+ * The lifetime attribute represents the duration for which the server
+ * will maintain an allocation in the absence of data traffic either
+ * from or to the client. It is a 32 bit value representing the number
+ * of seconds remaining until expiration.
+ */
+typedef struct pj_stun_uint_attr pj_stun_lifetime_attr;
+
+
+/**
+ * This describes STUN BANDWIDTH attribute.
+ * The bandwidth attribute represents the peak bandwidth, measured in
+ * kbits per second, that the client expects to use on the binding. The
+ * value represents the sum in the receive and send directions.
+ */
+typedef struct pj_stun_uint_attr pj_stun_bandwidth_attr;
+
+
+/**
+ * This describes the STUN XOR-PEER-ADDRESS attribute.
+ * The XOR-PEER-ADDRESS specifies the address and port of the peer as seen
+ * from the TURN server. It is encoded in the same way as XOR-MAPPED-
+ * ADDRESS.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_xor_peer_addr_attr;
+
+
+/**
+ * This describes the STUN DATA attribute.
+ * The DATA attribute is present in Send Indications and Data
+ * Indications. It contains raw payload data that is to be sent (in the
+ * case of a Send Request) or was received (in the case of a Data
+ * Indication)..
+ */
+typedef struct pj_stun_binary_attr pj_stun_data_attr;
+
+
+/**
+ * This describes the STUN XOR-RELAYED-ADDRESS attribute. The
+ * XOR-RELAYED-ADDRESS is present in Allocate responses. It specifies the
+ * address and port that the server allocated to the client. It is
+ * encoded in the same way as XOR-MAPPED-ADDRESS.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_xor_relayed_addr_attr;
+
+
+/**
+ * This describes the REQUESTED-ADDRESS-TYPE attribute.
+ * The REQUESTED-ADDRESS-TYPE attribute is used by clients to request
+ * the allocation of a specific address type from a server. The
+ * following is the format of the REQUESTED-ADDRESS-TYPE attribute.
+
+ \verbatim
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Family | Reserved |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ \endverbatim
+ */
+typedef struct pj_stun_uint_attr pj_stun_req_addr_type_attr;
+
+
+/**
+ * This describes the TURN REQUESTED-TRANSPORT attribute, encoded in
+ * STUN generic integer attribute.
+ *
+ * This attribute allows the client to request that the port in the
+ * relayed-transport-address be even, and (optionally) that the server
+ * reserve the next-higher port number. The attribute is 8 bits long.
+ * Its format is:
+
+\verbatim
+ 0
+ 0 1 2 3 4 5 6 7
+ +-+-+-+-+-+-+-+-+
+ |R| RFFU |
+ +-+-+-+-+-+-+-+-+
+
+\endverbatim
+
+ * The attribute contains a single 1-bit flag:
+ *
+ * R: If 1, the server is requested to reserve the next higher port
+ * number (on the same IP address) for a subsequent allocation. If
+ * 0, no such reservation is requested.
+ *
+ * The other 7 bits of the attribute must be set to zero on transmission
+ * and ignored on reception.
+ */
+typedef struct pj_stun_uint_attr pj_stun_even_port_attr;
+
+
+/**
+ * This describes the TURN REQUESTED-TRANSPORT attribute, encoded in
+ * STUN generic integer attribute.
+ *
+ * This attribute is used by the client to request a specific transport
+ * protocol for the allocated transport address. It has the following
+ * format:
+
+ \verbatim
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Protocol | RFFU |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+ \endverbatim
+
+ * The Protocol field specifies the desired protocol. The codepoints
+ * used in this field are taken from those allowed in the Protocol field
+ * in the IPv4 header and the NextHeader field in the IPv6 header
+ * [Protocol-Numbers]. This specification only allows the use of
+ * codepoint 17 (User Datagram Protocol).
+ *
+ * The RFFU field is set to zero on transmission and ignored on
+ * receiption. It is reserved for future uses.
+ */
+typedef struct pj_stun_uint_attr pj_stun_req_transport_attr;
+
+/**
+ * Get protocol value from 32bit TURN REQUESTED-TRANSPORT attribute.
+ */
+#define PJ_STUN_GET_RT_PROTO(u32) (u32 >> 24)
+
+/**
+ * Convert protocol value to be placed in 32bit TURN REQUESTED-TRANSPORT
+ * attribute.
+ */
+#define PJ_STUN_SET_RT_PROTO(proto) (((pj_uint32_t)(proto)) << 24)
+
+
+/**
+ * This describes the TURN DONT-FRAGMENT attribute.
+ *
+ * This attribute is used by the client to request that the server set
+ * the DF (Don't Fragment) bit in the IP header when relaying the
+ * application data onward to the peer. This attribute has no value
+ * part and thus the attribute length field is 0.
+ */
+typedef struct pj_stun_empty_attr pj_stun_dont_fragment_attr;
+
+
+/**
+ * This describes the TURN RESERVATION-TOKEN attribute.
+ * The RESERVATION-TOKEN attribute contains a token that uniquely
+ * identifies a relayed transport address being held in reserve by the
+ * server. The server includes this attribute in a success response to
+ * tell the client about the token, and the client includes this
+ * attribute in a subsequent Allocate request to request the server use
+ * that relayed transport address for the allocation.
+ *
+ * The attribute value is a 64-bit-long field containing the token
+ * value.
+ */
+typedef struct pj_stun_uint64_attr pj_stun_res_token_attr;
+
+/**
+ * This describes the XOR-REFLECTED-FROM attribute, as described by
+ * draft-macdonald-behave-nat-behavior-discovery-00.
+ * The XOR-REFLECTED-FROM attribute is used in place of the REFLECTED-
+ * FROM attribute. It provides the same information, but because the
+ * NAT's public address is obfuscated through the XOR function, It can
+ * pass through a NAT that would otherwise attempt to translate it to
+ * the private network address. XOR-REFLECTED-FROM has identical syntax
+ * to XOR-MAPPED-ADDRESS.
+ */
+typedef struct pj_stun_sockaddr_attr pj_stun_xor_reflected_from_attr;
+
+/**
+ * This describes the PRIORITY attribute from draft-ietf-mmusic-ice-13.
+ * The PRIORITY attribute indicates the priority that is to be
+ * associated with a peer reflexive candidate, should one be discovered
+ * by this check. It is a 32 bit unsigned integer, and has an attribute
+ * type of 0x0024.
+ */
+typedef struct pj_stun_uint_attr pj_stun_priority_attr;
+
+/**
+ * This describes the USE-CANDIDATE attribute from draft-ietf-mmusic-ice-13.
+ * The USE-CANDIDATE attribute indicates that the candidate pair
+ * resulting from this check should be used for transmission of media.
+ * The attribute has no content (the Length field of the attribute is
+ * zero); it serves as a flag.
+ */
+typedef struct pj_stun_empty_attr pj_stun_use_candidate_attr;
+
+/**
+ * This describes the STUN TIMER-VAL attribute.
+ * The TIMER-VAL attribute is used only in conjunction with the Set
+ * Active Destination response. It conveys from the server, to the
+ * client, the value of the timer used in the server state machine.
+ */
+typedef struct pj_stun_uint_attr pj_stun_timer_val_attr;
+
+/**
+ * This describes ICE-CONTROLLING attribute.
+ */
+typedef struct pj_stun_uint64_attr pj_stun_ice_controlling_attr;
+
+/**
+ * This describes ICE-CONTROLLED attribute.
+ */
+typedef struct pj_stun_uint64_attr pj_stun_ice_controlled_attr;
+
+/**
+ * This describes TURN ICMP attribute
+ */
+typedef struct pj_stun_uint_attr pj_stun_icmp_attr;
+
+/**
+ * This structure describes a parsed STUN message. All integral fields
+ * in this structure (including IP addresses) will be in the host
+ * byte order.
+ */
+typedef struct pj_stun_msg
+{
+ /**
+ * STUN message header.
+ */
+ pj_stun_msg_hdr hdr;
+
+ /**
+ * Number of attributes in the STUN message.
+ */
+ unsigned attr_count;
+
+ /**
+ * Array of STUN attributes.
+ */
+ pj_stun_attr_hdr *attr[PJ_STUN_MAX_ATTR];
+
+} pj_stun_msg;
+
+
+/** STUN decoding options */
+enum pj_stun_decode_options
+{
+ /**
+ * Tell the decoder that the message was received from datagram
+ * oriented transport (such as UDP).
+ */
+ PJ_STUN_IS_DATAGRAM = 1,
+
+ /**
+ * Tell pj_stun_msg_decode() to check the validity of the STUN
+ * message by calling pj_stun_msg_check() before starting to
+ * decode the packet.
+ */
+ PJ_STUN_CHECK_PACKET = 2,
+
+ /**
+ * This option current is only valid for #pj_stun_session_on_rx_pkt().
+ * When specified, it tells the session NOT to authenticate the
+ * message.
+ */
+ PJ_STUN_NO_AUTHENTICATE = 4,
+
+ /**
+ * Disable FINGERPRINT verification. This option can be used when calling
+ * #pj_stun_msg_check() and #pj_stun_msg_decode() to disable the
+ * verification of FINGERPRINT, for example when the STUN usage says when
+ * FINGERPRINT mechanism shall not be used.
+ */
+ PJ_STUN_NO_FINGERPRINT_CHECK = 8
+};
+
+
+/**
+ * Get STUN message method name.
+ *
+ * @param msg_type The STUN message type (in host byte order)
+ *
+ * @return The STUN message method name string.
+ */
+PJ_DECL(const char*) pj_stun_get_method_name(unsigned msg_type);
+
+
+/**
+ * Get STUN message class name.
+ *
+ * @param msg_type The STUN message type (in host byte order)
+ *
+ * @return The STUN message class name string.
+ */
+PJ_DECL(const char*) pj_stun_get_class_name(unsigned msg_type);
+
+
+/**
+ * Get STUN attribute name.
+ *
+ * @return attr_type The STUN attribute type (in host byte order).
+ *
+ * @return The STUN attribute type name string.
+ */
+PJ_DECL(const char*) pj_stun_get_attr_name(unsigned attr_type);
+
+
+/**
+ * Get STUN standard reason phrase for the specified error code.
+ *
+ * @param err_code The STUN error code.
+ *
+ * @return The STUN error reason phrase.
+ */
+PJ_DECL(pj_str_t) pj_stun_get_err_reason(int err_code);
+
+
+/**
+ * Internal: set the padding character for string attribute.
+ * The default padding character is PJ_STUN_STRING_ATTR_PAD_CHR.
+ *
+ * @return The previous padding character.
+ */
+PJ_DECL(int) pj_stun_set_padding_char(int chr);
+
+
+/**
+ * Initialize a generic STUN message.
+ *
+ * @param msg The message structure to be initialized.
+ * @param msg_type The 14bit message type (see pj_stun_msg_type
+ * constants).
+ * @param magic Magic value to be put to the mesage; for requests,
+ * the value normally should be PJ_STUN_MAGIC.
+ * @param tsx_id Optional transaction ID, or NULL to let the
+ * function generates a random transaction ID.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_init(pj_stun_msg *msg,
+ unsigned msg_type,
+ pj_uint32_t magic,
+ const pj_uint8_t tsx_id[12]);
+
+/**
+ * Create a generic STUN message.
+ *
+ * @param pool Pool to create the STUN message.
+ * @param msg_type The 14bit message type.
+ * @param magic Magic value to be put to the mesage; for requests,
+ * the value should be PJ_STUN_MAGIC.
+ * @param tsx_id Optional transaction ID, or NULL to let the
+ * function generates a random transaction ID.
+ * @param p_msg Pointer to receive the message.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_create(pj_pool_t *pool,
+ unsigned msg_type,
+ pj_uint32_t magic,
+ const pj_uint8_t tsx_id[12],
+ pj_stun_msg **p_msg);
+
+/**
+ * Clone a STUN message with all of its attributes.
+ *
+ * @param pool Pool to allocate memory for the new message.
+ * @param msg The message to be cloned.
+ *
+ * @return The duplicate message.
+ */
+PJ_DECL(pj_stun_msg*) pj_stun_msg_clone(pj_pool_t *pool,
+ const pj_stun_msg *msg);
+
+/**
+ * Create STUN response message.
+ *
+ * @param pool Pool to create the mesage.
+ * @param req_msg The request message.
+ * @param err_code STUN error code. If this value is not zero,
+ * then error response will be created, otherwise
+ * successful response will be created.
+ * @param err_msg Optional error message to explain err_code.
+ * If this value is NULL and err_code is not zero,
+ * the error string will be taken from the default
+ * STUN error message.
+ * @param p_response Pointer to receive the response.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_create_response(pj_pool_t *pool,
+ const pj_stun_msg *req_msg,
+ unsigned err_code,
+ const pj_str_t *err_msg,
+ pj_stun_msg **p_response);
+
+
+/**
+ * Add STUN attribute to STUN message.
+ *
+ * @param msg The STUN message.
+ * @param attr The STUN attribute to be added to the message.
+ *
+ * @return PJ_SUCCESS on success, or PJ_ETOOMANY if there are
+ * already too many attributes in the message.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_attr(pj_stun_msg *msg,
+ pj_stun_attr_hdr *attr);
+
+
+/**
+ * Print the STUN message structure to a packet buffer, ready to be
+ * sent to remote destination. This function will take care about
+ * calculating the MESSAGE-INTEGRITY digest as well as FINGERPRINT
+ * value, if these attributes are present in the message.
+ *
+ * If application wants to apply credential to the message, it MUST
+ * include a blank MESSAGE-INTEGRITY attribute in the message as the
+ * last attribute or the attribute before FINGERPRINT. This function will
+ * calculate the HMAC digest from the message using the supplied key in
+ * the parameter. The key should be set to the password if short term
+ * credential is used, or calculated from the MD5 hash of the realm,
+ * username, and password using #pj_stun_create_key() if long term
+ * credential is used.
+ *
+ * If FINGERPRINT attribute is present, this function will calculate
+ * the FINGERPRINT CRC attribute for the message. The FINGERPRINT MUST
+ * be added as the last attribute of the message.
+ *
+ * @param msg The STUN message to be printed. Upon return,
+ * some fields in the header (such as message
+ * length) will be updated.
+ * @param pkt_buf The buffer to be filled with the packet.
+ * @param buf_size Size of the buffer.
+ * @param options Options, which currently must be zero.
+ * @param key Authentication key to calculate MESSAGE-INTEGRITY
+ * value. Application can create this key by using
+ * #pj_stun_create_key() function.
+ * @param p_msg_len Upon return, it will be filed with the size of
+ * the packet in bytes, or negative value on error.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg,
+ pj_uint8_t *pkt_buf,
+ pj_size_t buf_size,
+ unsigned options,
+ const pj_str_t *key,
+ pj_size_t *p_msg_len);
+
+/**
+ * Check that the PDU is potentially a valid STUN message. This function
+ * is useful when application needs to multiplex STUN packets with other
+ * application traffic. When this function returns PJ_SUCCESS, there is a
+ * big chance that the packet is a STUN packet.
+ *
+ * Note that we cannot be sure that the PDU is a really valid STUN message
+ * until we actually parse the PDU.
+ *
+ * @param pdu The packet buffer.
+ * @param pdu_len The length of the packet buffer.
+ * @param options Additional options to be applied in the checking,
+ * which can be taken from pj_stun_decode_options. One
+ * of the useful option is PJ_STUN_IS_DATAGRAM which
+ * means that the pdu represents a whole STUN packet.
+ *
+ * @return PJ_SUCCESS if the PDU is a potentially valid STUN
+ * message.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu,
+ pj_size_t pdu_len, unsigned options);
+
+
+/**
+ * Decode incoming packet into STUN message.
+ *
+ * @param pool Pool to allocate the message.
+ * @param pdu The incoming packet to be parsed.
+ * @param pdu_len The length of the incoming packet.
+ * @param options Parsing flags, according to pj_stun_decode_options.
+ * @param p_msg Pointer to receive the parsed message.
+ * @param p_parsed_len Optional pointer to receive how many bytes have
+ * been parsed for the STUN message. This is useful
+ * when the packet is received over stream oriented
+ * transport.
+ * @param p_response Optional pointer to receive an instance of response
+ * message, if one can be created. If the packet being
+ * decoded is a request message, and it contains error,
+ * and a response can be created, then the STUN
+ * response message will be returned on this argument.
+ *
+ * @return PJ_SUCCESS if a STUN message has been successfully
+ * decoded.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
+ const pj_uint8_t *pdu,
+ pj_size_t pdu_len,
+ unsigned options,
+ pj_stun_msg **p_msg,
+ pj_size_t *p_parsed_len,
+ pj_stun_msg **p_response);
+
+/**
+ * Dump STUN message to a printable string output.
+ *
+ * @param msg The STUN message
+ * @param buffer Buffer where the printable string output will
+ * be printed on.
+ * @param length Specify the maximum length of the buffer.
+ * @param printed_len Optional pointer, which on output will be filled
+ * up with the actual length of the output string.
+ *
+ * @return The message string output.
+ */
+#if PJ_LOG_MAX_LEVEL > 0
+PJ_DECL(char*) pj_stun_msg_dump(const pj_stun_msg *msg,
+ char *buffer,
+ unsigned length,
+ unsigned *printed_len);
+#else
+# define pj_stun_msg_dump(msg, buf, length, printed_len) ""
+#endif
+
+
+/**
+ * Find STUN attribute in the STUN message, starting from the specified
+ * index.
+ *
+ * @param msg The STUN message.
+ * @param attr_type The attribute type to be found, from pj_stun_attr_type.
+ * @param start_index The start index of the attribute in the message.
+ * Specify zero to start searching from the first
+ * attribute.
+ *
+ * @return The attribute instance, or NULL if it cannot be
+ * found.
+ */
+PJ_DECL(pj_stun_attr_hdr*) pj_stun_msg_find_attr(const pj_stun_msg *msg,
+ int attr_type,
+ unsigned start_index);
+
+
+/**
+ * Clone a STUN attribute.
+ *
+ * @param pool Pool to allocate memory.
+ * @param attr Attribute to clone.
+ *
+ * @return Duplicate attribute.
+ */
+PJ_DECL(pj_stun_attr_hdr*) pj_stun_attr_clone(pj_pool_t *pool,
+ const pj_stun_attr_hdr *attr);
+
+
+/**
+ * Initialize generic STUN IP address attribute. The \a addr_len and
+ * \a addr parameters specify whether the address is IPv4 or IPv4
+ * address.
+ *
+ * @param attr The socket address attribute to initialize.
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param xor_ed If non-zero, the port and address will be XOR-ed
+ * with magic, to make the XOR-MAPPED-ADDRESS attribute.
+ * @param addr A pj_sockaddr_in or pj_sockaddr_in6 structure.
+ * @param addr_len Length of \a addr parameter.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_sockaddr_attr_init(pj_stun_sockaddr_attr *attr,
+ int attr_type,
+ pj_bool_t xor_ed,
+ const pj_sockaddr_t *addr,
+ unsigned addr_len);
+
+/**
+ * Create a generic STUN IP address attribute. The \a addr_len and
+ * \a addr parameters specify whether the address is IPv4 or IPv4
+ * address.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param xor_ed If non-zero, the port and address will be XOR-ed
+ * with magic, to make the XOR-MAPPED-ADDRESS attribute.
+ * @param addr A pj_sockaddr_in or pj_sockaddr_in6 structure.
+ * @param addr_len Length of \a addr parameter.
+ * @param p_attr Pointer to receive the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_sockaddr_attr_create(pj_pool_t *pool,
+ int attr_type,
+ pj_bool_t xor_ed,
+ const pj_sockaddr_t *addr,
+ unsigned addr_len,
+ pj_stun_sockaddr_attr **p_attr);
+
+
+/**
+ * Create and add generic STUN IP address attribute to a STUN message.
+ * The \a addr_len and \a addr parameters specify whether the address is
+ * IPv4 or IPv4 address.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param msg The STUN message.
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param xor_ed If non-zero, the port and address will be XOR-ed
+ * with magic, to make the XOR-MAPPED-ADDRESS attribute.
+ * @param addr A pj_sockaddr_in or pj_sockaddr_in6 structure.
+ * @param addr_len Length of \a addr parameter.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_sockaddr_attr(pj_pool_t *pool,
+ pj_stun_msg *msg,
+ int attr_type,
+ pj_bool_t xor_ed,
+ const pj_sockaddr_t *addr,
+ unsigned addr_len);
+
+/**
+ * Initialize a STUN generic string attribute.
+ *
+ * @param attr The string attribute to be initialized.
+ * @param pool Pool to duplicate the value into the attribute,
+ * if value is not NULL or empty.
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param value The string value to be assigned to the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_string_attr_init(pj_stun_string_attr *attr,
+ pj_pool_t *pool,
+ int attr_type,
+ const pj_str_t *value);
+
+/**
+ * Create a STUN generic string attribute.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param value The string value to be assigned to the attribute.
+ * @param p_attr Pointer to receive the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_string_attr_create(pj_pool_t *pool,
+ int attr_type,
+ const pj_str_t *value,
+ pj_stun_string_attr **p_attr);
+
+/**
+ * Create and add STUN generic string attribute to the message.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param msg The STUN message.
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param value The string value to be assigned to the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_string_attr(pj_pool_t *pool,
+ pj_stun_msg *msg,
+ int attr_type,
+ const pj_str_t *value);
+
+/**
+ * Create a STUN generic 32bit value attribute.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param value The 32bit value to be assigned to the attribute.
+ * @param p_attr Pointer to receive the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_uint_attr_create(pj_pool_t *pool,
+ int attr_type,
+ pj_uint32_t value,
+ pj_stun_uint_attr **p_attr);
+
+/**
+ * Create and add STUN generic 32bit value attribute to the message.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param msg The STUN message
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param value The 32bit value to be assigned to the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_uint_attr(pj_pool_t *pool,
+ pj_stun_msg *msg,
+ int attr_type,
+ pj_uint32_t value);
+
+
+/**
+ * Create a STUN generic 64bit value attribute.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param value Optional value to be assigned.
+ * @param p_attr Pointer to receive the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_uint64_attr_create(pj_pool_t *pool,
+ int attr_type,
+ const pj_timestamp *value,
+ pj_stun_uint64_attr **p_attr);
+
+
+/**
+ * Create and add STUN generic 64bit value attribute to the message.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param msg The STUN message
+ * @param attr_type Attribute type, from #pj_stun_attr_type.
+ * @param value The 64bit value to be assigned to the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_uint64_attr(pj_pool_t *pool,
+ pj_stun_msg *msg,
+ int attr_type,
+ const pj_timestamp *value);
+
+/**
+ * Create a STUN MESSAGE-INTEGRITY attribute.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param p_attr Pointer to receive the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msgint_attr_create(pj_pool_t *pool,
+ pj_stun_msgint_attr **p_attr);
+
+/**
+ * Create and add STUN MESSAGE-INTEGRITY attribute.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param msg The STUN message
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_msgint_attr(pj_pool_t *pool,
+ pj_stun_msg *msg);
+
+/**
+ * Create a STUN ERROR-CODE attribute.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param err_code STUN error code.
+ * @param err_reason Optional STUN error reason. If NULL is given, the
+ * standard error reason will be given.
+ * @param p_attr Pointer to receive the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_errcode_attr_create(pj_pool_t *pool,
+ int err_code,
+ const pj_str_t *err_reason,
+ pj_stun_errcode_attr **p_attr);
+
+
+/**
+ * Create and add STUN ERROR-CODE attribute to the message.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param msg The STUN mesage.
+ * @param err_code STUN error code.
+ * @param err_reason Optional STUN error reason. If NULL is given, the
+ * standard error reason will be given.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_errcode_attr(pj_pool_t *pool,
+ pj_stun_msg *msg,
+ int err_code,
+ const pj_str_t *err_reason);
+
+/**
+ * Create instance of STUN UNKNOWN-ATTRIBUTES attribute and copy the
+ * unknown attribute array to the attribute.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param attr_cnt Number of attributes in the array (can be zero).
+ * @param attr Optional array of attributes.
+ * @param p_attr Pointer to receive the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_unknown_attr_create(pj_pool_t *pool,
+ unsigned attr_cnt,
+ const pj_uint16_t attr[],
+ pj_stun_unknown_attr **p_attr);
+
+/**
+ * Create and add STUN UNKNOWN-ATTRIBUTES attribute to the message.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param msg The STUN message.
+ * @param attr_cnt Number of attributes in the array (can be zero).
+ * @param attr Optional array of attribute types.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_unknown_attr(pj_pool_t *pool,
+ pj_stun_msg *msg,
+ unsigned attr_cnt,
+ const pj_uint16_t attr[]);
+
+/**
+ * Initialize STUN binary attribute.
+ *
+ * @param attr The attribute to be initialized.
+ * @param pool Pool to copy data, if the data and length are set.
+ * @param attr_type The attribute type, from #pj_stun_attr_type.
+ * @param data Data to be coped to the attribute, or NULL
+ * if no data to be copied now.
+ * @param length Length of data, or zero if no data is to be
+ * copied now.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_binary_attr_init(pj_stun_binary_attr *attr,
+ pj_pool_t *pool,
+ int attr_type,
+ const pj_uint8_t *data,
+ unsigned length);
+
+/**
+ * Create STUN binary attribute.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param attr_type The attribute type, from #pj_stun_attr_type.
+ * @param data Data to be coped to the attribute, or NULL
+ * if no data to be copied now.
+ * @param length Length of data, or zero if no data is to be
+ * copied now.
+ * @param p_attr Pointer to receive the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_binary_attr_create(pj_pool_t *pool,
+ int attr_type,
+ const pj_uint8_t *data,
+ unsigned length,
+ pj_stun_binary_attr **p_attr);
+
+/**
+ * Create STUN binary attribute and add the attribute to the message.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param msg The STUN message.
+ * @param attr_type The attribute type, from #pj_stun_attr_type.
+ * @param data Data to be coped to the attribute, or NULL
+ * if no data to be copied now.
+ * @param length Length of data, or zero if no data is to be
+ * copied now.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_binary_attr(pj_pool_t *pool,
+ pj_stun_msg *msg,
+ int attr_type,
+ const pj_uint8_t *data,
+ unsigned length);
+
+/**
+ * Create STUN empty attribute.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param attr_type The attribute type, from #pj_stun_attr_type.
+ * @param p_attr Pointer to receive the attribute.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_empty_attr_create(pj_pool_t *pool,
+ int attr_type,
+ pj_stun_empty_attr **p_attr);
+
+/**
+ * Create STUN empty attribute and add the attribute to the message.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param msg The STUN message.
+ * @param attr_type The attribute type, from #pj_stun_attr_type.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_msg_add_empty_attr(pj_pool_t *pool,
+ pj_stun_msg *msg,
+ int attr_type);
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_STUN_MSG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_session.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_session.h
new file mode 100644
index 0000000..156c934
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_session.h
@@ -0,0 +1,762 @@
+/* $Id: stun_session.h 2724 2009-05-29 13:04:03Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_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>
+#include <pjnath/stun_transaction.h>
+#include <pj/list.h>
+#include <pj/timer.h>
+
+PJ_BEGIN_DECL
+
+
+/* **************************************************************************/
+/**
+ * @addtogroup PJNATH_STUN_SESSION
+ * @{
+ *
+ * This is is a transport-independent object to manage a client or server
+ * STUN session. It has the following features:
+ *
+ * - <b>transport independent</b>:\n
+ * the object does not have it's own socket, but rather it provides
+ * functions and callbacks to send and receive packets. This way the
+ * object can be used by different transport types (e.g. UDP, TCP,
+ * TLS, etc.) as well as better integration to application which
+ * already has its own means to send and receive packets.
+ *
+ * - <b>authentication management</b>:\n
+ * the object manages STUN authentication throughout the lifetime of
+ * the session. For client sessions, once it's given a credential to
+ * authenticate itself with the server, the object will automatically
+ * add authentication info (the MESSAGE-INTEGRITY) to the request as
+ * well as authenticate the response. It will also handle long-term
+ * authentication challenges, including handling of nonce expiration,
+ * and retry the request automatically. For server sessions, it can
+ * be configured to authenticate incoming requests automatically.
+ *
+ * - <b>static or dynamic credential</b>:\n
+ * application may specify static or dynamic credential to be used by
+ * the STUN session. Static credential means a static combination of
+ * username and password (and these cannot change during the session
+ * duration), while dynamic credential provides callback to ask the
+ * application about which username/password to use everytime
+ * authentication is about to be performed.
+ *
+ * - <b>client transaction management</b>:\n
+ * outgoing requests may be sent with a STUN transaction for reliability,
+ * and the object will manage the transaction internally (including
+ * performing retransmissions). Application will be notified about the
+ * result of the request when the response arrives (or the transaction
+ * times out). When the request is challenged with authentication, the
+ * object will retry the request with new authentication info, and
+ * application will be notified about the final result of this request.
+ *
+ * - <b>server transaction management</b>:\n
+ * application may ask response to incoming requests to be cached by
+ * the object, and in this case the object will check for cached
+ * response everytime request is received. The cached response will be
+ * deleted once a timer expires.
+ *
+ * \section using_stun_sess_sec Using the STUN session
+ *
+ * The following steps describes how to use the STUN session:
+ *
+ * - <b>create the object configuration</b>:\n
+ * The #pj_stun_config contains the configuration to create the STUN
+ * session, such as the timer heap to register internal timers and
+ * various STUN timeout values. You can initialize this structure by
+ * calling #pj_stun_config_init()
+ *
+ * - <b>create the STUN session</b>:\n
+ * by calling #pj_stun_session_create(). Among other things, this
+ * function requires the instance of #pj_stun_config and also
+ * #pj_stun_session_cb structure which stores callbacks to send
+ * outgoing packets as well as to notify application about incoming
+ * STUN requests, responses, and indicates and other events.
+ *
+ * - <b>configure credential:</b>\n
+ * if authentication is required for the session, configure the
+ * credential with #pj_stun_session_set_credential()
+ *
+ * - <b>configuring other settings:</b>\n
+ * several APIs are provided to configure the behavior of the STUN
+ * session (for example, to set the SOFTWARE attribute value, controls
+ * the logging behavior, fine tune the mutex locking, etc.). Please see
+ * the API reference for more info.
+ *
+ * - <b>creating outgoing STUN requests or indications:</b>\n
+ * create the STUN message by using #pj_stun_session_create_req() or
+ * #pj_stun_session_create_ind(). This will create a transmit data
+ * buffer containing a blank STUN request or indication. You will then
+ * typically need to add STUN attributes that are relevant to the
+ * request or indication, but note that some default attributes will
+ * be added by the session later when the message is sent (such as
+ * SOFTWARE attribute and attributes related to authentication).
+ * The message is now ready to be sent.
+ *
+ * - <b>sending outgoing message:</b>\n
+ * use #pj_stun_session_send_msg() to send outgoing STUN messages (this
+ * includes STUN requests, indications, and responses). The function has
+ * options whether to retransmit the request (for non reliable transports)
+ * or to cache the response if we're sending response. This function in
+ * turn will call the \a on_send_msg() callback of #pj_stun_session_cb
+ * to request the application to send the packet.
+ *
+ * - <b>handling incoming packet:</b>\n
+ * call #pj_stun_session_on_rx_pkt() everytime the application receives
+ * a STUN packet. This function will decode the packet and process the
+ * packet according to the message, and normally this will cause one
+ * of the callback in the #pj_stun_session_cb to be called to notify
+ * the application about the event.
+ *
+ * - <b>handling incoming requests:</b>\n
+ * incoming requests are notified to application in the \a on_rx_request
+ * callback of the #pj_stun_session_cb. If authentication is enabled in
+ * the session, the application will only receive this callback after
+ * the incoming request has been authenticated (if the authentication
+ * fails, the session would respond automatically with 401 error and
+ * the callback will not be called). Application now must create and
+ * send response for this request.
+ *
+ * - <b>creating and sending response:</b>\n
+ * create the STUN response with #pj_stun_session_create_res(). This will
+ * create a transmit data buffer containing a blank STUN response. You
+ * will then typically need to add STUN attributes that are relevant to
+ * the response, but note that some default attributes will
+ * be added by the session later when the message is sent (such as
+ * SOFTWARE attribute and attributes related to authentication).
+ * The message is now ready to be sent. Use #pj_stun_session_send_msg()
+ * (as explained above) to send the response.
+ *
+ * - <b>convenient way to send response:</b>\n
+ * the #pj_stun_session_respond() is provided as a convenient way to
+ * create and send simple STUN responses, such as error responses.
+ *
+ * - <b>destroying the session:</b>\n
+ * once the session is done, use #pj_stun_session_destroy() to destroy
+ * the session.
+ */
+
+
+/** Forward declaration for pj_stun_tx_data */
+typedef struct pj_stun_tx_data pj_stun_tx_data;
+
+/** Forward declaration for pj_stun_rx_data */
+typedef struct pj_stun_rx_data pj_stun_rx_data;
+
+/** Forward declaration for pj_stun_session */
+typedef struct pj_stun_session pj_stun_session;
+
+
+/**
+ * This is the callback to be registered to pj_stun_session, to send
+ * outgoing message and to receive various notifications from the STUN
+ * session.
+ */
+typedef struct pj_stun_session_cb
+{
+ /**
+ * Callback to be called by the STUN session to send outgoing message.
+ *
+ * @param sess The STUN session.
+ * @param token The token associated with this outgoing message
+ * and was set by the application. This token was
+ * set by application in pj_stun_session_send_msg()
+ * for outgoing messages that are initiated by the
+ * application, or in pj_stun_session_on_rx_pkt()
+ * if this message is a response that was internally
+ * generated by the STUN session (for example, an
+ * 401/Unauthorized response). Application may use
+ * this facility for any purposes.
+ * @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_stun_session *sess,
+ void *token,
+ const void *pkt,
+ pj_size_t pkt_size,
+ const pj_sockaddr_t *dst_addr,
+ unsigned addr_len);
+
+ /**
+ * Callback to be called on incoming STUN request message. This function
+ * is called when application calls pj_stun_session_on_rx_pkt() and when
+ * the STUN session has detected that the incoming STUN message is a
+ * STUN request message. In the
+ * callback processing, application MUST create a response by calling
+ * pj_stun_session_create_response() function and send the response
+ * with pj_stun_session_send_msg() function, before returning from
+ * the callback.
+ *
+ * @param sess The STUN session.
+ * @param pkt Pointer to the original STUN packet.
+ * @param pkt_len Length of the STUN packet.
+ * @param rdata Data containing incoming request message.
+ * @param token The token that was set by the application when
+ * calling pj_stun_session_on_rx_pkt() function.
+ * @param src_addr Source address of the packet.
+ * @param src_addr_len Length of the source address.
+ *
+ * @return The return value of this callback will be
+ * returned back to pj_stun_session_on_rx_pkt()
+ * function.
+ */
+ pj_status_t (*on_rx_request)(pj_stun_session *sess,
+ const pj_uint8_t *pkt,
+ unsigned pkt_len,
+ const pj_stun_rx_data *rdata,
+ void *token,
+ const pj_sockaddr_t *src_addr,
+ unsigned src_addr_len);
+
+ /**
+ * Callback to be called when response is received or the transaction
+ * has timed out. This callback is called either when application calls
+ * pj_stun_session_on_rx_pkt() with the packet containing a STUN
+ * response for the client transaction, or when the internal timer of
+ * the STUN client transaction has timed-out before a STUN response is
+ * received.
+ *
+ * @param sess The STUN session.
+ * @param status Status of the request. If the value if not
+ * PJ_SUCCESS, the transaction has timed-out
+ * or other error has occurred, and the response
+ * argument may be NULL.
+ * Note that when the status is not success, the
+ * response may contain non-NULL value if the
+ * response contains STUN ERROR-CODE attribute.
+ * @param token The token that was set by the application when
+ * calling pj_stun_session_send_msg() function.
+ * Please not that this token IS NOT the token
+ * that was given in pj_stun_session_on_rx_pkt().
+ * @param tdata The original STUN request.
+ * @param response The response message, on successful transaction,
+ * or otherwise MAY BE NULL if status is not success.
+ * Note that when the status is not success, this
+ * argument may contain non-NULL value if the
+ * response contains STUN ERROR-CODE attribute.
+ * @param src_addr The source address where the response was
+ * received, or NULL if the response is NULL.
+ * @param src_addr_len The length of the source address.
+ */
+ void (*on_request_complete)(pj_stun_session *sess,
+ pj_status_t status,
+ void *token,
+ pj_stun_tx_data *tdata,
+ const pj_stun_msg *response,
+ const pj_sockaddr_t *src_addr,
+ unsigned src_addr_len);
+
+
+ /**
+ * Callback to be called on incoming STUN request message. This function
+ * is called when application calls pj_stun_session_on_rx_pkt() and when
+ * the STUN session has detected that the incoming STUN message is a
+ * STUN indication message.
+ *
+ * @param sess The STUN session.
+ * @param pkt Pointer to the original STUN packet.
+ * @param pkt_len Length of the STUN packet.
+ * @param msg The parsed STUN indication.
+ * @param token The token that was set by the application when
+ * calling pj_stun_session_on_rx_pkt() function.
+ * @param src_addr Source address of the packet.
+ * @param src_addr_len Length of the source address.
+ *
+ * @return The return value of this callback will be
+ * returned back to pj_stun_session_on_rx_pkt()
+ * function.
+ */
+ pj_status_t (*on_rx_indication)(pj_stun_session *sess,
+ const pj_uint8_t *pkt,
+ unsigned pkt_len,
+ const pj_stun_msg *msg,
+ void *token,
+ const pj_sockaddr_t *src_addr,
+ unsigned src_addr_len);
+
+} pj_stun_session_cb;
+
+
+/**
+ * This structure describes incoming request message.
+ */
+struct pj_stun_rx_data
+{
+ /**
+ * The parsed request message.
+ */
+ pj_stun_msg *msg;
+
+ /**
+ * Credential information that is found and used to authenticate
+ * incoming request. Application may use this information when
+ * generating authentication for the outgoing response.
+ */
+ pj_stun_req_cred_info info;
+};
+
+
+/**
+ * This structure describe the outgoing STUN transmit data to carry the
+ * message to be sent.
+ */
+struct pj_stun_tx_data
+{
+ /** PJLIB list interface */
+ PJ_DECL_LIST_MEMBER(struct pj_stun_tx_data);
+
+ pj_pool_t *pool; /**< Pool. */
+ pj_stun_session *sess; /**< The STUN session. */
+ pj_stun_msg *msg; /**< The STUN message. */
+
+ void *token; /**< The token. */
+
+ pj_stun_client_tsx *client_tsx; /**< Client STUN transaction. */
+ pj_bool_t retransmit; /**< Retransmit request? */
+ pj_uint32_t msg_magic; /**< Message magic. */
+ pj_uint8_t msg_key[12]; /**< Message/transaction key. */
+
+ pj_stun_req_cred_info auth_info; /**< Credential info */
+
+ void *pkt; /**< The STUN packet. */
+ unsigned max_len; /**< Length of packet buffer. */
+ pj_size_t pkt_size; /**< The actual length of STUN pkt. */
+
+ unsigned addr_len; /**< Length of destination address. */
+ const pj_sockaddr_t *dst_addr; /**< Destination address. */
+
+ pj_timer_entry res_timer; /**< Response cache timer. */
+};
+
+
+/**
+ * These are the flags to control the message logging in the STUN session.
+ */
+typedef enum pj_stun_sess_msg_log_flag
+{
+ PJ_STUN_SESS_LOG_TX_REQ=1, /**< Log outgoing STUN requests. */
+ PJ_STUN_SESS_LOG_TX_RES=2, /**< Log outgoing STUN responses. */
+ PJ_STUN_SESS_LOG_TX_IND=4, /**< Log outgoing STUN indications. */
+
+ PJ_STUN_SESS_LOG_RX_REQ=8, /**< Log incoming STUN requests. */
+ PJ_STUN_SESS_LOG_RX_RES=16, /**< Log incoming STUN responses */
+ PJ_STUN_SESS_LOG_RX_IND=32 /**< Log incoming STUN indications */
+} pj_stun_sess_msg_log_flag;
+
+
+/**
+ * Create a STUN session.
+ *
+ * @param cfg The STUN endpoint, to be used to register timers etc.
+ * @param name Optional name to be associated with this instance. The
+ * name will be used for example for logging purpose.
+ * @param cb Session callback.
+ * @param fingerprint Enable message fingerprint for outgoing messages.
+ * @param p_sess Pointer to receive STUN session instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create(pj_stun_config *cfg,
+ const char *name,
+ const pj_stun_session_cb *cb,
+ pj_bool_t fingerprint,
+ pj_stun_session **p_sess);
+
+/**
+ * Destroy the STUN session and all objects created in the context of
+ * this session.
+ *
+ * @param sess The STUN session instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ * This function will return PJ_EPENDING if the operation
+ * cannot be performed immediately because callbacks are
+ * being called; in this case the session will be destroyed
+ * as soon as the last callback returns.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess);
+
+/**
+ * Associated an arbitrary data with this STUN session. The user data may
+ * be retrieved later with pj_stun_session_get_user_data() function.
+ *
+ * @param sess The STUN session instance.
+ * @param user_data The user data.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_set_user_data(pj_stun_session *sess,
+ void *user_data);
+
+/**
+ * Retrieve the user data previously associated to this STUN session with
+ * pj_stun_session_set_user_data().
+ *
+ * @param sess The STUN session instance.
+ *
+ * @return The user data associated with this STUN session.
+ */
+PJ_DECL(void*) pj_stun_session_get_user_data(pj_stun_session *sess);
+
+/**
+ * Change the lock object used by the STUN session. By default, the STUN
+ * session uses a mutex to protect its internal data. If application already
+ * protects access to STUN session with higher layer lock, it may disable
+ * the mutex protection in the STUN session by changing the STUN session
+ * lock to a NULL mutex.
+ *
+ * @param sess The STUN session instance.
+ * @param lock New lock instance to be used by the STUN session.
+ * @param auto_del Specify whether STUN session should destroy this
+ * lock instance when it's destroyed.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_set_lock(pj_stun_session *sess,
+ pj_lock_t *lock,
+ pj_bool_t auto_del);
+
+/**
+ * Set SOFTWARE name to be included in all requests and responses.
+ *
+ * @param sess The STUN session instance.
+ * @param sw Software name string. If this argument is NULL or
+ * empty, the session will not include SOFTWARE attribute
+ * in STUN requests and responses.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_set_software_name(pj_stun_session *sess,
+ const pj_str_t *sw);
+
+/**
+ * Set credential to be used by this session. Once credential is set, all
+ * outgoing messages will include MESSAGE-INTEGRITY, and all incoming
+ * message will be authenticated against this credential.
+ *
+ * To disable authentication after it has been set, call this function
+ * again with NULL as the argument.
+ *
+ * @param sess The STUN session instance.
+ * @param auth_type Type of authentication.
+ * @param cred The credential to be used by this session. If NULL
+ * is specified, authentication will be disabled.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_set_credential(pj_stun_session *sess,
+ pj_stun_auth_type auth_type,
+ const pj_stun_auth_cred *cred);
+/**
+ * Configure message logging. By default all flags are enabled.
+ *
+ * @param sess The STUN session instance.
+ * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag
+ */
+PJ_DECL(void) pj_stun_session_set_log(pj_stun_session *sess,
+ unsigned flags);
+/**
+ * Configure whether the STUN session should utilize FINGERPRINT in
+ * outgoing messages.
+ *
+ * @param sess The STUN session instance.
+ * @param use Boolean for the setting.
+ *
+ * @return The previous configured value of FINGERPRINT
+ * utilization of the sessoin.
+ */
+PJ_DECL(pj_bool_t) pj_stun_session_use_fingerprint(pj_stun_session *sess,
+ pj_bool_t use);
+
+/**
+ * Create a STUN request message. After the message has been successfully
+ * created, application can send the message by calling
+ * pj_stun_session_send_msg().
+ *
+ * @param sess The STUN session instance.
+ * @param msg_type The STUN request message type, from pj_stun_method_e or
+ * from pj_stun_msg_type.
+ * @param magic STUN magic, use PJ_STUN_MAGIC.
+ * @param tsx_id Optional transaction ID.
+ * @param p_tdata Pointer to receive STUN transmit data instance containing
+ * the request.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create_req(pj_stun_session *sess,
+ int msg_type,
+ pj_uint32_t magic,
+ const pj_uint8_t tsx_id[12],
+ pj_stun_tx_data **p_tdata);
+
+/**
+ * Create a STUN Indication message. After the message has been successfully
+ * created, application can send the message by calling
+ * pj_stun_session_send_msg().
+ *
+ * @param sess The STUN session instance.
+ * @param msg_type The STUN request message type, from pj_stun_method_e or
+ * from pj_stun_msg_type. This function will add the
+ * indication bit as necessary.
+ * @param p_tdata Pointer to receive STUN transmit data instance containing
+ * the message.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create_ind(pj_stun_session *sess,
+ int msg_type,
+ pj_stun_tx_data **p_tdata);
+
+/**
+ * Create a STUN response message. After the message has been
+ * successfully created, application can send the message by calling
+ * pj_stun_session_send_msg(). Alternatively application may use
+ * pj_stun_session_respond() to create and send response in one function
+ * call.
+ *
+ * @param sess The STUN session instance.
+ * @param rdata The STUN request where the response is to be created.
+ * @param err_code Error code to be set in the response, if error response
+ * is to be created, according to pj_stun_status enumeration.
+ * This argument MUST be zero if successful response is
+ * to be created.
+ * @param err_msg Optional pointer for the error message string, when
+ * creating error response. If the value is NULL and the
+ * \a err_code is non-zero, then default error message will
+ * be used.
+ * @param p_tdata Pointer to receive the response message created.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_create_res(pj_stun_session *sess,
+ const pj_stun_rx_data *rdata,
+ unsigned err_code,
+ const pj_str_t *err_msg,
+ pj_stun_tx_data **p_tdata);
+
+/**
+ * Send STUN message to the specified destination. This function will encode
+ * the pj_stun_msg instance to a packet buffer, and add credential or
+ * fingerprint if necessary. If the message is a request, the session will
+ * also create and manage a STUN client transaction to be used to manage the
+ * retransmission of the request. After the message has been encoded and
+ * transaction is setup, the \a on_send_msg() callback of pj_stun_session_cb
+ * (which is registered when the STUN session is created) will be called
+ * to actually send the message to the wire.
+ *
+ * @param sess The STUN session instance.
+ * @param token Optional token which will be given back to application in
+ * \a on_send_msg() callback and \a on_request_complete()
+ * callback, if the message is a STUN request message.
+ * Internally this function will put the token in the
+ * \a token field of pj_stun_tx_data, hence it will
+ * overwrite any value that the application puts there.
+ * @param cache_res If the message is a response message for an incoming
+ * request, specify PJ_TRUE to instruct the STUN session
+ * to cache this response for subsequent incoming request
+ * retransmission. Otherwise this parameter will be ignored
+ * for non-response message.
+ * @param retransmit If the message is a request message, specify whether the
+ * request should be retransmitted. Normally application will
+ * specify TRUE if the underlying transport is UDP and FALSE
+ * if the underlying transport is TCP or TLS.
+ * @param dst_addr The destination socket address.
+ * @param addr_len Length of destination address.
+ * @param tdata The STUN transmit data containing the STUN message to
+ * be sent.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in
+ * \a on_send_msg() callback.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess,
+ void *token,
+ pj_bool_t cache_res,
+ pj_bool_t retransmit,
+ const pj_sockaddr_t *dst_addr,
+ unsigned addr_len,
+ pj_stun_tx_data *tdata);
+
+/**
+ * This is a utility function to create and send response for an incoming
+ * STUN request. Internally this function calls pj_stun_session_create_res()
+ * and pj_stun_session_send_msg(). It is provided here as a matter of
+ * convenience.
+ *
+ * @param sess The STUN session instance.
+ * @param rdata The STUN request message to be responded.
+ * @param code Error code to be set in the response, if error response
+ * is to be created, according to pj_stun_status enumeration.
+ * This argument MUST be zero if successful response is
+ * to be created.
+ * @param err_msg Optional pointer for the error message string, when
+ * creating error response. If the value is NULL and the
+ * \a err_code is non-zero, then default error message will
+ * be used.
+ * @param token Optional token which will be given back to application in
+ * \a on_send_msg() callback and \a on_request_complete()
+ * callback, if the message is a STUN request message.
+ * Internally this function will put the token in the
+ * \a token field of pj_stun_tx_data, hence it will
+ * overwrite any value that the application puts there.
+ * @param cache Specify whether session should cache this response for
+ * future request retransmission. If TRUE, subsequent request
+ * retransmission will be handled by the session and it
+ * will not call request callback.
+ * @param dst_addr Destination address of the response (or equal to the
+ * source address of the original request).
+ * @param addr_len Address length.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in
+ * \a on_send_msg() callback.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_respond(pj_stun_session *sess,
+ const pj_stun_rx_data *rdata,
+ unsigned code,
+ const char *err_msg,
+ void *token,
+ pj_bool_t cache,
+ const pj_sockaddr_t *dst_addr,
+ unsigned addr_len);
+
+/**
+ * Cancel outgoing STUN transaction. This operation is only valid for outgoing
+ * STUN request, to cease retransmission of the request and destroy the
+ * STUN client transaction that is used to send the request.
+ *
+ * @param sess The STUN session instance.
+ * @param tdata The request message previously sent.
+ * @param notify Specify whether \a on_request_complete() callback should
+ * be called.
+ * @param status If \a on_request_complete() callback is to be called,
+ * specify the error status to be given when calling the
+ * callback. This error status MUST NOT be PJ_SUCCESS.
+ *
+ * @return PJ_SUCCESS if transaction is successfully cancelled.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in
+ * \a on_request_complete() callback.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_cancel_req(pj_stun_session *sess,
+ pj_stun_tx_data *tdata,
+ pj_bool_t notify,
+ pj_status_t status);
+
+/**
+ * Explicitly request retransmission of the request. Normally application
+ * doesn't need to do this, but this functionality is needed by ICE to
+ * speed up connectivity check completion.
+ *
+ * @param sess The STUN session instance.
+ * @param tdata The request message previously sent.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in \a on_send_msg()
+ * callback.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess,
+ pj_stun_tx_data *tdata);
+
+
+/**
+ * Application must call this function to notify the STUN session about
+ * the arrival of STUN packet. The STUN packet MUST have been checked
+ * first with #pj_stun_msg_check() to verify that this is indeed a valid
+ * STUN packet.
+ *
+ * The STUN session will decode the packet into pj_stun_msg, and process
+ * the message accordingly. If the message is a response, it will search
+ * through the outstanding STUN client transactions for a matching
+ * transaction ID and hand over the response to the transaction.
+ *
+ * On successful message processing, application will be notified about
+ * the message via one of the pj_stun_session_cb callback.
+ *
+ * @param sess The STUN session instance.
+ * @param packet The packet containing STUN message.
+ * @param pkt_size Size of the packet.
+ * @param 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 token Optional token which will be given back to application
+ * in the \a on_rx_request(), \a on_rx_indication() and
+ * \a on_send_msg() callbacks. The token can be used to
+ * associate processing or incoming request or indication
+ * with some context.
+ * @param src_addr The source address of the packet, which will also
+ * be given back to application callbacks, along with
+ * source address length.
+ * @param src_addr_len Length of the source address.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ * This function will return PJNATH_ESTUNDESTROYED if
+ * application has destroyed the session in one of the
+ * callback.
+ */
+PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
+ const void *packet,
+ pj_size_t pkt_size,
+ unsigned options,
+ void *token,
+ pj_size_t *parsed_len,
+ const pj_sockaddr_t *src_addr,
+ unsigned src_addr_len);
+
+/**
+ * Destroy the transmit data. Call this function only when tdata has been
+ * created but application doesn't want to send the message (perhaps
+ * because of other error).
+ *
+ * @param sess The STUN session.
+ * @param tdata The transmit data.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(void) pj_stun_msg_destroy_tdata(pj_stun_session *sess,
+ pj_stun_tx_data *tdata);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJNATH_STUN_SESSION_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_sock.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_sock.h
new file mode 100644
index 0000000..27d6e96
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_sock.h
@@ -0,0 +1,446 @@
+/* $Id: stun_sock.h 2966 2009-10-25 09:02:07Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_STUN_SOCK_H__
+#define __PJNATH_STUN_SOCK_H__
+
+/**
+ * @file stun_sock.h
+ * @brief STUN aware socket transport
+ */
+#include <pjnath/stun_config.h>
+#include <pjlib-util/resolver.h>
+#include <pj/ioqueue.h>
+#include <pj/sock.h>
+#include <pj/sock_qos.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @addtogroup PJNATH_STUN_SOCK
+ * @{
+ *
+ * The STUN transport provides asynchronous UDP like socket transport
+ * with the additional STUN capability. It has the following features:
+ *
+ * - API to send and receive UDP packets
+ *
+ * - multiplex STUN and non-STUN incoming packets and distinguish between
+ * STUN responses that belong to internal requests with application data
+ * (the application data may be STUN packets as well)
+ *
+ * - DNS SRV resolution to the STUN server (if wanted), along with fallback
+ * to DNS A resolution if SRV record is not found.
+ *
+ * - STUN keep-alive maintenance, and handle changes to the mapped address
+ * (when the NAT binding changes)
+ *
+ */
+
+/**
+ * Opaque type to represent a STUN transport.
+ */
+typedef struct pj_stun_sock pj_stun_sock;
+
+/**
+ * Types of operation being reported in \a on_status() callback of
+ * pj_stun_sock_cb. Application may retrieve the string representation
+ * of these constants with pj_stun_sock_op_name().
+ */
+typedef enum pj_stun_sock_op
+{
+ /**
+ * Asynchronous DNS resolution.
+ */
+ PJ_STUN_SOCK_DNS_OP = 1,
+
+ /**
+ * Initial STUN Binding request.
+ */
+ PJ_STUN_SOCK_BINDING_OP,
+
+ /**
+ * Subsequent STUN Binding request for keeping the binding
+ * alive.
+ */
+ PJ_STUN_SOCK_KEEP_ALIVE_OP,
+
+ /**
+ * IP address change notification from the keep-alive operation.
+ */
+ PJ_STUN_SOCK_MAPPED_ADDR_CHANGE
+
+
+} pj_stun_sock_op;
+
+
+/**
+ * This structure contains callbacks that will be called by the STUN
+ * transport to notify application about various events.
+ */
+typedef struct pj_stun_sock_cb
+{
+ /**
+ * Notification when incoming packet has been received.
+ *
+ * @param stun_sock The STUN transport.
+ * @param data The packet.
+ * @param data_len Length of the packet.
+ * @param src_addr The source address of the packet.
+ * @param addr_len The length of the source address.
+ *
+ * @return Application should normally return PJ_TRUE to let
+ * the STUN transport continue its operation. However
+ * it must return PJ_FALSE if it has destroyed the
+ * STUN transport in this callback.
+ */
+ pj_bool_t (*on_rx_data)(pj_stun_sock *stun_sock,
+ void *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *src_addr,
+ unsigned addr_len);
+
+ /**
+ * Notifification when asynchronous send operation has completed.
+ *
+ * @param stun_sock The STUN transport.
+ * @param send_key The send operation key that was given in
+ * #pj_stun_sock_sendto().
+ * @param sent If value is positive non-zero it indicates the
+ * number of data sent. When the value is negative,
+ * it contains the error code which can be retrieved
+ * by negating the value (i.e. status=-sent).
+ *
+ * @return Application should normally return PJ_TRUE to let
+ * the STUN transport continue its operation. However
+ * it must return PJ_FALSE if it has destroyed the
+ * STUN transport in this callback.
+ */
+ pj_bool_t (*on_data_sent)(pj_stun_sock *stun_sock,
+ pj_ioqueue_op_key_t *send_key,
+ pj_ssize_t sent);
+
+ /**
+ * Notification when the status of the STUN transport has changed. This
+ * callback may be called for the following conditions:
+ * - the first time the publicly mapped address has been resolved from
+ * the STUN server, this callback will be called with \a op argument
+ * set to PJ_STUN_SOCK_BINDING_OP \a status argument set to
+ * PJ_SUCCESS.
+ * - anytime when the transport has detected that the publicly mapped
+ * address has changed, this callback will be called with \a op
+ * argument set to PJ_STUN_SOCK_KEEP_ALIVE_OP and \a status
+ * argument set to PJ_SUCCESS. On this case and the case above,
+ * application will get the resolved public address in the
+ * #pj_stun_sock_info structure.
+ * - for any terminal error (such as STUN time-out, DNS resolution
+ * failure, or keep-alive failure), this callback will be called
+ * with the \a status argument set to non-PJ_SUCCESS.
+ *
+ * @param stun_sock The STUN transport.
+ * @param op The operation that triggers the callback.
+ * @param status The status.
+ *
+ * @return Must return PJ_FALSE if it has destroyed the
+ * STUN transport in this callback. Application should
+ * normally destroy the socket and return PJ_FALSE
+ * upon encountering terminal error, otherwise it
+ * should return PJ_TRUE to let the STUN socket operation
+ * continues.
+ */
+ pj_bool_t (*on_status)(pj_stun_sock *stun_sock,
+ pj_stun_sock_op op,
+ pj_status_t status);
+
+} pj_stun_sock_cb;
+
+
+/**
+ * This structure contains information about the STUN transport. Application
+ * may query this information by calling #pj_stun_sock_get_info().
+ */
+typedef struct pj_stun_sock_info
+{
+ /**
+ * The bound address of the socket.
+ */
+ pj_sockaddr bound_addr;
+
+ /**
+ * IP address of the STUN server.
+ */
+ pj_sockaddr srv_addr;
+
+ /**
+ * The publicly mapped address. It may contain zero address when the
+ * mapped address has not been resolved. Application may query whether
+ * this field contains valid address with pj_sockaddr_has_addr().
+ */
+ pj_sockaddr mapped_addr;
+
+ /**
+ * Number of interface address aliases. The interface address aliases
+ * are list of all interface addresses in this host.
+ */
+ unsigned alias_cnt;
+
+ /**
+ * Array of interface address aliases.
+ */
+ pj_sockaddr aliases[PJ_ICE_ST_MAX_CAND];
+
+} pj_stun_sock_info;
+
+
+/**
+ * This describe the settings to be given to the STUN transport during its
+ * creation. Application should initialize this structure by calling
+ * #pj_stun_sock_cfg_default().
+ */
+typedef struct pj_stun_sock_cfg
+{
+ /**
+ * Packet buffer size. Default value is PJ_STUN_SOCK_PKT_LEN.
+ */
+ unsigned max_pkt_size;
+
+ /**
+ * Specify the number of simultaneous asynchronous read operations to
+ * be invoked to the ioqueue. Having more than one read operations will
+ * increase performance on multiprocessor systems since the application
+ * will be able to process more than one incoming packets simultaneously.
+ * Default value is 1.
+ */
+ unsigned async_cnt;
+
+ /**
+ * Specify the interface where the socket should be bound to. If the
+ * address is zero, socket will be bound to INADDR_ANY. If the address
+ * is non-zero, socket will be bound to this address only, and the
+ * transport will have only one address alias (the \a alias_cnt field
+ * in #pj_stun_sock_info structure.
+ */
+ pj_sockaddr bound_addr;
+
+ /**
+ * Specify the STUN keep-alive duration, in seconds. The STUN transport
+ * does keep-alive by sending STUN Binding request to the STUN server.
+ * If this value is zero, the PJ_STUN_KEEP_ALIVE_SEC value will be used.
+ * If the value is negative, it will disable STUN keep-alive.
+ */
+ int ka_interval;
+
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * By default all settings in this structure are disabled.
+ */
+ pj_qos_params qos_params;
+
+ /**
+ * Specify if STUN socket should ignore any errors when setting the QoS
+ * traffic type/parameters.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t qos_ignore_error;
+
+} pj_stun_sock_cfg;
+
+
+
+/**
+ * Retrieve the name representing the specified operation.
+ */
+PJ_DECL(const char*) pj_stun_sock_op_name(pj_stun_sock_op op);
+
+
+/**
+ * Initialize the STUN transport setting with its default values.
+ *
+ * @param cfg The STUN transport config.
+ */
+PJ_DECL(void) pj_stun_sock_cfg_default(pj_stun_sock_cfg *cfg);
+
+
+/**
+ * Create the STUN transport using the specified configuration. Once
+ * the STUN transport has been create, application should call
+ * #pj_stun_sock_start() to start the transport.
+ *
+ * @param stun_cfg The STUN configuration which contains among other
+ * things the ioqueue and timer heap instance for
+ * the operation of this transport.
+ * @param af Address family of socket. Currently pj_AF_INET()
+ * and pj_AF_INET6() are supported.
+ * @param name Optional name to be given to this transport to
+ * assist debugging.
+ * @param cb Callback to receive events/data from the transport.
+ * @param cfg Optional transport settings.
+ * @param user_data Arbitrary application data to be associated with
+ * this transport.
+ * @param p_sock Pointer to receive the created transport instance.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_create(pj_stun_config *stun_cfg,
+ const char *name,
+ int af,
+ const pj_stun_sock_cb *cb,
+ const pj_stun_sock_cfg *cfg,
+ void *user_data,
+ pj_stun_sock **p_sock);
+
+
+/**
+ * Start the STUN transport. This will start the DNS SRV resolution for
+ * the STUN server (if desired), and once the server is resolved, STUN
+ * Binding request will be sent to resolve the publicly mapped address.
+ * Once the initial STUN Binding response is received, the keep-alive
+ * timer will be started.
+ *
+ * @param stun_sock The STUN transport instance.
+ * @param domain The domain, hostname, or IP address of the TURN
+ * server. When this parameter contains domain name,
+ * the \a resolver parameter must be set to activate
+ * DNS SRV resolution.
+ * @param default_port The default STUN port number to use when DNS SRV
+ * resolution is not used. If DNS SRV resolution is
+ * used, the server port number will be set from the
+ * DNS SRV records. The recommended value for this
+ * parameter is PJ_STUN_PORT.
+ * @param resolver If this parameter is not NULL, then the \a domain
+ * parameter will be first resolved with DNS SRV and
+ * then fallback to using DNS A/AAAA resolution when
+ * DNS SRV resolution fails. If this parameter is
+ * NULL, the \a domain parameter will be resolved as
+ * hostname.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * queued, or the appropriate error code on failure.
+ * When this function returns PJ_SUCCESS, the final
+ * result of the allocation process will be notified
+ * to application in \a on_state() callback.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_start(pj_stun_sock *stun_sock,
+ const pj_str_t *domain,
+ pj_uint16_t default_port,
+ pj_dns_resolver *resolver);
+
+/**
+ * Destroy the STUN transport.
+ *
+ * @param sock The STUN transport socket.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *sock);
+
+
+/**
+ * Associate a user data with this STUN transport. The user data may then
+ * be retrieved later with #pj_stun_sock_get_user_data().
+ *
+ * @param stun_sock The STUN transport instance.
+ * @param user_data Arbitrary data.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_set_user_data(pj_stun_sock *stun_sock,
+ void *user_data);
+
+/**
+ * Retrieve the previously assigned user data associated with this STUN
+ * transport.
+ *
+ * @param stun_sock The STUN transport instance.
+ *
+ * @return The user/application data.
+ */
+PJ_DECL(void*) pj_stun_sock_get_user_data(pj_stun_sock *stun_sock);
+
+
+/**
+ * Get the STUN transport info. The transport info contains, among other
+ * things, the allocated relay address.
+ *
+ * @param stun_sock The STUN transport instance.
+ * @param info Pointer to be filled with STUN transport info.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_get_info(pj_stun_sock *stun_sock,
+ pj_stun_sock_info *info);
+
+
+/**
+ * Send a data to the specified address. This function may complete
+ * asynchronously and in this case \a on_data_sent() will be called.
+ *
+ * @param stun_sock The STUN transport instance.
+ * @param send_key Optional send key for sending the packet down to
+ * the ioqueue. This value will be given back to
+ * \a on_data_sent() callback
+ * @param pkt The data/packet to be sent to peer.
+ * @param pkt_len Length of the data.
+ * @param flag pj_ioqueue_sendto() flag.
+ * @param dst_addr The remote address.
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if data has been sent immediately, or
+ * PJ_EPENDING if data cannot be sent immediately. In
+ * this case the \a on_data_sent() callback will be
+ * called when data is actually sent. Any other return
+ * value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_stun_sock_sendto(pj_stun_sock *stun_sock,
+ pj_ioqueue_op_key_t *send_key,
+ const void *pkt,
+ unsigned pkt_len,
+ unsigned flag,
+ const pj_sockaddr_t *dst_addr,
+ unsigned addr_len);
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_STUN_SOCK_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_transaction.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_transaction.h
new file mode 100644
index 0000000..26bb911
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_transaction.h
@@ -0,0 +1,276 @@
+/* $Id: stun_transaction.h 2642 2009-04-22 17:20:24Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_STUN_TRANSACTION_H__
+#define __PJNATH_STUN_TRANSACTION_H__
+
+/**
+ * @file stun_transaction.h
+ * @brief STUN transaction
+ */
+
+#include <pjnath/stun_msg.h>
+#include <pjnath/stun_config.h>
+
+
+PJ_BEGIN_DECL
+
+
+/* **************************************************************************/
+/**
+ * @defgroup PJNATH_STUN_TRANSACTION STUN Client Transaction
+ * @brief STUN client transaction
+ * @ingroup PJNATH_STUN_BASE
+ * @{
+ *
+ 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.
+
+
+ */
+
+/**
+ * Opaque declaration of STUN client transaction.
+ */
+typedef struct pj_stun_client_tsx pj_stun_client_tsx;
+
+/**
+ * STUN client transaction callback.
+ */
+typedef struct pj_stun_tsx_cb
+{
+ /**
+ * This callback is called when the STUN transaction completed.
+ *
+ * @param tsx The STUN transaction.
+ * @param status Status of the transaction. Status PJ_SUCCESS
+ * means that the request has received a successful
+ * response.
+ * @param response The STUN response, which value may be NULL if
+ * \a status is not PJ_SUCCESS.
+ * @param src_addr The source address of the response, if response
+ * is not NULL.
+ * @param src_addr_len The length of the source address.
+ */
+ void (*on_complete)(pj_stun_client_tsx *tsx,
+ pj_status_t status,
+ const pj_stun_msg *response,
+ const pj_sockaddr_t *src_addr,
+ unsigned src_addr_len);
+
+ /**
+ * This callback is called by the STUN transaction when it wants to send
+ * outgoing message.
+ *
+ * @param tsx The STUN transaction instance.
+ * @param stun_pkt The STUN packet to be sent.
+ * @param pkt_size Size of the STUN packet.
+ *
+ * @return If return value of the callback is not PJ_SUCCESS,
+ * the transaction will fail. Application MUST return
+ * PJNATH_ESTUNDESTROYED if it has destroyed the
+ * transaction in this callback.
+ */
+ pj_status_t (*on_send_msg)(pj_stun_client_tsx *tsx,
+ const void *stun_pkt,
+ pj_size_t pkt_size);
+
+ /**
+ * This callback is called after the timer that was scheduled by
+ * #pj_stun_client_tsx_schedule_destroy() has elapsed. Application
+ * should call #pj_stun_client_tsx_destroy() upon receiving this
+ * callback.
+ *
+ * This callback is optional if application will not call
+ * #pj_stun_client_tsx_schedule_destroy().
+ *
+ * @param tsx The STUN transaction instance.
+ */
+ void (*on_destroy)(pj_stun_client_tsx *tsx);
+
+} pj_stun_tsx_cb;
+
+
+
+/**
+ * Create an instance of STUN client transaction. The STUN client
+ * transaction is used to transmit outgoing STUN request and to
+ * ensure the reliability of the request by periodically retransmitting
+ * the request, if necessary.
+ *
+ * @param cfg The STUN endpoint, which will be used to retrieve
+ * various settings for the transaction.
+ * @param pool Pool to be used to allocate memory from.
+ * @param cb Callback structure, to be used by the transaction
+ * to send message and to notify the application about
+ * the completion of the transaction.
+ * @param p_tsx Pointer to receive the transaction instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_client_tsx_create( pj_stun_config *cfg,
+ pj_pool_t *pool,
+ const pj_stun_tsx_cb *cb,
+ pj_stun_client_tsx **p_tsx);
+
+/**
+ * Schedule timer to destroy the transaction after the transaction is
+ * complete. Application normally calls this function in the on_complete()
+ * callback. When this timer elapsed, the on_destroy() callback will be
+ * called.
+ *
+ * This is convenient to let the STUN transaction absorbs any response
+ * for the previous request retransmissions. If application doesn't want
+ * this, it can destroy the transaction immediately by calling
+ * #pj_stun_client_tsx_destroy().
+ *
+ * @param tsx The STUN transaction.
+ * @param delay The delay interval before on_destroy() callback
+ * is called.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pj_stun_client_tsx_schedule_destroy(pj_stun_client_tsx *tsx,
+ const pj_time_val *delay);
+
+
+/**
+ * Destroy a STUN client transaction immediately. This function can be
+ * called at any time to stop the transaction and destroy it.
+ *
+ * @param tsx The STUN transaction.
+ *
+ * @return PJ_SUCCESS on success or PJ_EINVAL if the parameter
+ * is NULL.
+ */
+PJ_DECL(pj_status_t) pj_stun_client_tsx_destroy(pj_stun_client_tsx *tsx);
+
+
+/**
+ * Check if transaction has completed.
+ *
+ * @param tsx The STUN transaction.
+ *
+ * @return Non-zero if transaction has completed.
+ */
+PJ_DECL(pj_bool_t) pj_stun_client_tsx_is_complete(pj_stun_client_tsx *tsx);
+
+
+/**
+ * Associate an arbitrary data with the STUN transaction. This data
+ * can be then retrieved later from the transaction, by using
+ * pj_stun_client_tsx_get_data() function.
+ *
+ * @param tsx The STUN client transaction.
+ * @param data Application data to be associated with the
+ * STUN transaction.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_stun_client_tsx_set_data(pj_stun_client_tsx *tsx,
+ void *data);
+
+
+/**
+ * Get the user data that was previously associated with the STUN
+ * transaction.
+ *
+ * @param tsx The STUN client transaction.
+ *
+ * @return The user data.
+ */
+PJ_DECL(void*) pj_stun_client_tsx_get_data(pj_stun_client_tsx *tsx);
+
+
+/**
+ * Start the STUN client transaction by sending STUN request using
+ * this transaction. If reliable transport such as TCP or TLS is used,
+ * the retransmit flag should be set to PJ_FALSE because reliablity
+ * will be assured by the transport layer.
+ *
+ * @param tsx The STUN client transaction.
+ * @param retransmit Should this message be retransmitted by the
+ * STUN transaction.
+ * @param pkt The STUN packet to send.
+ * @param pkt_len Length of STUN packet.
+ *
+ * @return PJ_SUCCESS on success, or PJNATH_ESTUNDESTROYED
+ * when the user has destroyed the transaction in
+ * \a on_send_msg() callback, or any other error code
+ * as returned by \a on_send_msg() callback.
+ */
+PJ_DECL(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx,
+ pj_bool_t retransmit,
+ void *pkt,
+ unsigned pkt_len);
+
+/**
+ * Request to retransmit the request. Normally application should not need
+ * to call this function since retransmission would be handled internally,
+ * but this functionality is needed by ICE.
+ *
+ * @param tsx The STUN client transaction instance.
+ *
+ * @return PJ_SUCCESS on success, or PJNATH_ESTUNDESTROYED
+ * when the user has destroyed the transaction in
+ * \a on_send_msg() callback, or any other error code
+ * as returned by \a on_send_msg() callback.
+ */
+PJ_DECL(pj_status_t) pj_stun_client_tsx_retransmit(pj_stun_client_tsx *tsx);
+
+
+/**
+ * Notify the STUN transaction about the arrival of STUN response.
+ * If the STUN response contains a final error (300 and greater), the
+ * transaction will be terminated and callback will be called. If the
+ * STUN response contains response code 100-299, retransmission
+ * will cease, but application must still call this function again
+ * with a final response later to allow the transaction to complete.
+ *
+ * @param tsx The STUN client transaction instance.
+ * @param msg The incoming STUN message.
+ * @param src_addr The source address of the packet.
+ * @param src_addr_len The length of the source address.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx,
+ const pj_stun_msg *msg,
+ const pj_sockaddr_t*src_addr,
+ unsigned src_addr_len);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_STUN_TRANSACTION_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_session.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_session.h
new file mode 100644
index 0000000..a23aac2
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_session.h
@@ -0,0 +1,722 @@
+/* $Id: turn_session.h 2642 2009-04-22 17:20:24Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_SESSION_H__
+#define __PJNATH_TURN_SESSION_H__
+
+/**
+ * @file turn_session.h
+ * @brief Transport independent TURN client session.
+ */
+#include <pjnath/stun_session.h>
+#include <pjlib-util/resolver.h>
+
+
+PJ_BEGIN_DECL
+
+
+/* **************************************************************************/
+/**
+@addtogroup PJNATH_TURN_SESSION
+@{
+
+The \ref PJNATH_TURN_SESSION is a transport-independent object to
+manage a client TURN session. It contains the core logic for manage
+the TURN client session as listed in \ref turn_op_sec, but
+in transport-independent manner (i.e. it doesn't have a socket), so
+that developer can integrate TURN client functionality into existing
+framework that already has its own means to send and receive data,
+or to support new transport types to TURN, such as TLS.
+
+
+\section turn_sess_using_sec Using the TURN session
+
+These steps describes how to use the TURN session:
+
+ - <b>Creating the session</b>:\n
+ use #pj_turn_session_create() to create the session.
+
+ - <b>Configuring credential</b>:\n
+ all TURN operations requires the use of authentication (it uses STUN
+ long term autentication method). Use #pj_turn_session_set_credential()
+ to configure the TURN credential to be used by the session.
+
+ - <b>Configuring server</b>:\n
+ application must call #pj_turn_session_set_server() before it can send
+ Allocate request (with pj_turn_session_alloc()). This function will
+ resolve the TURN server using DNS SRV resolution if the \a resolver
+ is set. The server resolution process will complete asynchronously,
+ and application will be notified in \a on_state() callback of the
+ #pj_turn_session_cb structurewith the session state set to
+ PJ_TURN_STATE_RESOLVED.
+
+ - <b>Creating allocation</b>:\n
+ create one "relay port" (or called <b>relayed-transport-address</b>
+ in TURN terminology) in the TURN server by using #pj_turn_session_alloc().
+ This will send Allocate request to the server. This function will complete
+ immediately, and application will be notified about the allocation
+ result in the \a on_state() callback of the #pj_turn_session_cb structure.
+
+ - <b>Getting the allocation result</b>:\n
+ if allocation is successful, the session state will progress to
+ \a PJ_TURN_STATE_READY, otherwise the state will be
+ \a PJ_TURN_STATE_DEALLOCATED or higher. Session state progression is
+ reported in the \a on_state() callback of the #pj_turn_session_cb
+ structure. On successful allocation, application may retrieve the
+ allocation info by calling #pj_turn_session_get_info().
+
+ - <b>Sending data through the relay</b>.\n
+ Once allocation has been created, client may send data to any remote
+ endpoints (called peers in TURN terminology) via the "relay port". It does
+ so by calling #pj_turn_session_sendto(), giving the peer address
+ in the function argument. But note that at this point peers are not allowed
+ to send data towards the client (via the "relay port") before permission is
+ installed for that peer.
+
+ - <b>Creating permissions</b>.\n
+ Permission needs to be created in the TURN server so that a peer can send
+ data to the client via the relay port (a peer in this case is identified by
+ its IP address). Without this, when the TURN server receives data from the
+ peer in the "relay port", it will drop this data. Create the permission by
+ calling #pj_turn_session_set_perm(), specifying the peer IP address in the
+ argument (the port part of the address is ignored). More than one IP
+ addresses may be specified.
+
+ - <b>Receiving data from peers</b>.\n
+ Once permission has been installed for the peer, any data received by the
+ TURN server (from that peer) in the "relay port" will be relayed back to
+ client by the server, and application will be notified via \a on_rx_data
+ callback of the #pj_turn_session_cb.
+
+ - <b>Using ChannelData</b>.\n
+ TURN provides optimized framing to the data by using ChannelData
+ packetization. The client activates this format for the specified peer by
+ calling #pj_turn_session_bind_channel(). Data sent or received to/for
+ this peer will then use ChannelData format instead of Send or Data
+ Indications.
+
+ - <b>Refreshing the allocation, permissions, and channel bindings</b>.\n
+ Allocations, permissions, and channel bindings will be refreshed by the
+ session automatically when they about to expire.
+
+ - <b>Destroying the allocation</b>.\n
+ Once the "relay port" is no longer needed, client destroys the allocation
+ by calling #pj_turn_session_shutdown(). This function will return
+ immediately, and application will be notified about the deallocation
+ result in the \a on_state() callback of the #pj_turn_session_cb structure.
+ Once the state has reached PJ_TURN_STATE_DESTROYING, application must
+ assume that the session will be destroyed shortly after.
+
+ */
+
+/**
+ * Opaque declaration for TURN client session.
+ */
+typedef struct pj_turn_session pj_turn_session;
+
+
+/**
+ * TURN transport types, which will be used both to specify the connection
+ * type for reaching TURN server and the type of allocation transport to be
+ * requested to server (the REQUESTED-TRANSPORT attribute).
+ */
+typedef enum pj_turn_tp_type
+{
+ /**
+ * UDP transport, which value corresponds to IANA protocol number.
+ */
+ PJ_TURN_TP_UDP = 17,
+
+ /**
+ * TCP transport, which value corresponds to IANA protocol number.
+ */
+ PJ_TURN_TP_TCP = 6,
+
+ /**
+ * TLS transport. The TLS transport will only be used as the connection
+ * type to reach the server and never as the allocation transport type.
+ */
+ PJ_TURN_TP_TLS = 255
+
+} pj_turn_tp_type;
+
+
+/** TURN session state */
+typedef enum pj_turn_state_t
+{
+ /**
+ * TURN session has just been created.
+ */
+ PJ_TURN_STATE_NULL,
+
+ /**
+ * TURN server has been configured and now is being resolved via
+ * DNS SRV resolution.
+ */
+ PJ_TURN_STATE_RESOLVING,
+
+ /**
+ * TURN server has been resolved. If there is pending allocation to
+ * be done, it will be invoked immediately.
+ */
+ PJ_TURN_STATE_RESOLVED,
+
+ /**
+ * TURN session has issued ALLOCATE request and is waiting for response
+ * from the TURN server.
+ */
+ PJ_TURN_STATE_ALLOCATING,
+
+ /**
+ * TURN session has successfully allocated relay resoruce and now is
+ * ready to be used.
+ */
+ PJ_TURN_STATE_READY,
+
+ /**
+ * TURN session has issued deallocate request and is waiting for a
+ * response from the TURN server.
+ */
+ PJ_TURN_STATE_DEALLOCATING,
+
+ /**
+ * Deallocate response has been received. Normally the session will
+ * proceed to DESTROYING state immediately.
+ */
+ PJ_TURN_STATE_DEALLOCATED,
+
+ /**
+ * TURN session is being destroyed.
+ */
+ PJ_TURN_STATE_DESTROYING
+
+} pj_turn_state_t;
+
+
+#pragma pack(1)
+
+/**
+ * This structure ChannelData header. All the fields are in network byte
+ * order when it's on the wire.
+ */
+typedef struct pj_turn_channel_data
+{
+ pj_uint16_t ch_number; /**< Channel number. */
+ pj_uint16_t length; /**< Payload length. */
+} pj_turn_channel_data;
+
+
+#pragma pack()
+
+
+/**
+ * Callback to receive events from TURN session.
+ */
+typedef struct pj_turn_session_cb
+{
+ /**
+ * This callback will be called by the TURN session whenever it
+ * needs to send outgoing message. Since the TURN session doesn't
+ * have a socket on its own, this callback must be implemented.
+ *
+ * @param sess The TURN session.
+ * @param pkt The packet/data to be sent.
+ * @param pkt_len Length of the packet/data.
+ * @param dst_addr Destination address of the packet.
+ * @param addr_len Length of the destination address.
+ *
+ * @return The callback should return the status of the
+ * send operation.
+ */
+ pj_status_t (*on_send_pkt)(pj_turn_session *sess,
+ const pj_uint8_t *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *dst_addr,
+ unsigned addr_len);
+
+ /**
+ * Notification when peer address has been bound successfully to
+ * a channel number.
+ *
+ * This callback is optional since the nature of this callback is
+ * for information only.
+ *
+ * @param sess The TURN session.
+ * @param peer_addr The peer address.
+ * @param addr_len Length of the peer address.
+ * @param ch_num The channel number associated with this peer address.
+ */
+ void (*on_channel_bound)(pj_turn_session *sess,
+ const pj_sockaddr_t *peer_addr,
+ unsigned addr_len,
+ unsigned ch_num);
+
+ /**
+ * Notification when incoming data has been received, either through
+ * Data indication or ChannelData message from the TURN server.
+ *
+ * @param sess The TURN session.
+ * @param pkt The data/payload of the Data Indication or ChannelData
+ * packet.
+ * @param pkt_len Length of the data/payload.
+ * @param peer_addr Peer address where this payload was received by
+ * the TURN server.
+ * @param addr_len Length of the peer address.
+ */
+ void (*on_rx_data)(pj_turn_session *sess,
+ void *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *peer_addr,
+ unsigned addr_len);
+
+ /**
+ * Notification when TURN session state has changed. Application should
+ * implement this callback at least to know that the TURN session is
+ * going to be destroyed.
+ *
+ * @param sess The TURN session.
+ * @param old_state The previous state of the session.
+ * @param new_state The current state of the session.
+ */
+ void (*on_state)(pj_turn_session *sess,
+ pj_turn_state_t old_state,
+ pj_turn_state_t new_state);
+
+} pj_turn_session_cb;
+
+
+/**
+ * Allocation parameter, which can be given when application calls
+ * pj_turn_session_alloc() to allocate relay address in the TURN server.
+ * Application should call pj_turn_alloc_param_default() to initialize
+ * this structure with the default values.
+ */
+typedef struct pj_turn_alloc_param
+{
+ /**
+ * The requested BANDWIDTH. Default is zero to not request any
+ * specific bandwidth. Note that this attribute has been deprecated
+ * after TURN-08 draft, hence application should only use this
+ * attribute when talking to TURN-07 or older version.
+ */
+ int bandwidth;
+
+ /**
+ * The requested LIFETIME. Default is zero to not request any
+ * explicit allocation lifetime.
+ */
+ int lifetime;
+
+ /**
+ * If set to non-zero, the TURN session will periodically send blank
+ * Send Indication every PJ_TURN_KEEP_ALIVE_SEC to refresh local
+ * NAT bindings. Default is zero.
+ */
+ int ka_interval;
+
+} pj_turn_alloc_param;
+
+
+/**
+ * This structure describes TURN session info.
+ */
+typedef struct pj_turn_session_info
+{
+ /**
+ * Session state.
+ */
+ pj_turn_state_t state;
+
+ /**
+ * Last error (if session was terminated because of error)
+ */
+ pj_status_t last_status;
+
+ /**
+ * Type of connection to the TURN server.
+ */
+ pj_turn_tp_type conn_type;
+
+ /**
+ * The selected TURN server address.
+ */
+ pj_sockaddr server;
+
+ /**
+ * Mapped address, as reported by the TURN server.
+ */
+ pj_sockaddr mapped_addr;
+
+ /**
+ * The relay address
+ */
+ pj_sockaddr relay_addr;
+
+ /**
+ * Current seconds before allocation expires.
+ */
+ int lifetime;
+
+} pj_turn_session_info;
+
+
+/**
+ * Initialize pj_turn_alloc_param with the default values.
+ *
+ * @param prm The TURN allocation parameter to be initialized.
+ */
+PJ_DECL(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm);
+
+
+/**
+ * Duplicate pj_turn_alloc_param.
+ *
+ * @param pool Pool to allocate memory (currently not used)
+ * @param dst Destination parameter.
+ * @param src Source parameter.
+ */
+PJ_DECL(void) pj_turn_alloc_param_copy(pj_pool_t *pool,
+ pj_turn_alloc_param *dst,
+ const pj_turn_alloc_param *src);
+
+/**
+ * Get string representation for the given TURN state.
+ *
+ * @param state The TURN session state.
+ *
+ * @return The state name as NULL terminated string.
+ */
+PJ_DECL(const char*) pj_turn_state_name(pj_turn_state_t state);
+
+
+/**
+ * Create a TURN session instance with the specified address family and
+ * connection type. Once TURN session instance is created, application
+ * must call pj_turn_session_alloc() to allocate a relay address in the TURN
+ * server.
+ *
+ * @param cfg The STUN configuration which contains among other
+ * things the ioqueue and timer heap instance for
+ * the operation of this session.
+ * @param name Optional name to identify this session in the log.
+ * @param af Address family of the client connection. Currently
+ * pj_AF_INET() and pj_AF_INET6() are supported.
+ * @param conn_type Connection type to the TURN server.
+ * @param cb Callback to receive events from the TURN session.
+ * @param options Option flags, currently this value must be zero.
+ * @param user_data Arbitrary application data to be associated with
+ * this transport.
+ * @param p_sess Pointer to receive the created instance of the
+ * TURN session.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_create(const pj_stun_config *cfg,
+ const char *name,
+ int af,
+ pj_turn_tp_type conn_type,
+ const pj_turn_session_cb *cb,
+ unsigned options,
+ void *user_data,
+ pj_turn_session **p_sess);
+
+/**
+ * Shutdown TURN client session. This will gracefully deallocate and
+ * destroy the client session.
+ *
+ * @param sess The TURN client session.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_shutdown(pj_turn_session *sess);
+
+
+/**
+ * Forcefully destroy the TURN session. This will destroy the session
+ * immediately. If there is an active allocation, the server will not
+ * be notified about the client destruction.
+ *
+ * @param sess The TURN client session.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_destroy(pj_turn_session *sess);
+
+
+/**
+ * Get the information about this TURN session and the allocation, if
+ * any.
+ *
+ * @param sess The TURN client session.
+ * @param info The structure to be initialized with the TURN
+ * session info.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_get_info(pj_turn_session *sess,
+ pj_turn_session_info *info);
+
+/**
+ * Associate a user data with this TURN session. The user data may then
+ * be retrieved later with pj_turn_session_get_user_data().
+ *
+ * @param sess The TURN client session.
+ * @param user_data Arbitrary data.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_user_data(pj_turn_session *sess,
+ void *user_data);
+
+/**
+ * Retrieve the previously assigned user data associated with this TURN
+ * session.
+ *
+ * @param sess The TURN client session.
+ *
+ * @return The user/application data.
+ */
+PJ_DECL(void*) pj_turn_session_get_user_data(pj_turn_session *sess);
+
+
+/**
+ * Configure message logging. By default all flags are enabled.
+ *
+ * @param sess The TURN client session.
+ * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag
+ */
+PJ_DECL(void) pj_turn_session_set_log(pj_turn_session *sess,
+ unsigned flags);
+
+
+/**
+ * Configure the SOFTWARE name to be sent in all STUN requests by the
+ * TURN session.
+ *
+ * @param sess The TURN client session.
+ * @param sw Software name string. If this argument is NULL or
+ * empty, the session will not include SOFTWARE attribute
+ * in STUN requests and responses.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_software_name(pj_turn_session *sess,
+ const pj_str_t *sw);
+
+
+/**
+ * Set the server or domain name of the server. Before the application
+ * can send Allocate request (with pj_turn_session_alloc()), it must first
+ * resolve the server address(es) using this function. This function will
+ * resolve the TURN server using DNS SRV resolution if the \a resolver
+ * is set. The server resolution process will complete asynchronously,
+ * and application will be notified in \a on_state() callback with the
+ * session state set to PJ_TURN_STATE_RESOLVED.
+ *
+ * Application may call with pj_turn_session_alloc() before the server
+ * resolution completes. In this case, the operation will be queued by
+ * the session, and it will be sent once the server resolution completes.
+ *
+ * @param sess The TURN client session.
+ * @param domain The domain, hostname, or IP address of the TURN
+ * server. When this parameter contains domain name,
+ * the \a resolver parameter must be set to activate
+ * DNS SRV resolution.
+ * @param default_port The default TURN port number to use when DNS SRV
+ * resolution is not used. If DNS SRV resolution is
+ * used, the server port number will be set from the
+ * DNS SRV records.
+ * @param resolver If this parameter is not NULL, then the \a domain
+ * parameter will be first resolved with DNS SRV and
+ * then fallback to using DNS A/AAAA resolution when
+ * DNS SRV resolution fails. If this parameter is
+ * NULL, the \a domain parameter will be resolved as
+ * hostname.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * queued, or the appropriate error code on failure.
+ * When this function returns PJ_SUCCESS, the final
+ * result of the resolution process will be notified
+ * to application in \a on_state() callback.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_server(pj_turn_session *sess,
+ const pj_str_t *domain,
+ int default_port,
+ pj_dns_resolver *resolver);
+
+
+/**
+ * Set credential to be used to authenticate against TURN server.
+ * Application must call this function before sending Allocate request
+ * with pj_turn_session_alloc().
+ *
+ * @param sess The TURN client session
+ * @param cred STUN credential to be used.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_credential(pj_turn_session *sess,
+ const pj_stun_auth_cred *cred);
+
+
+/**
+ * Allocate a relay address/resource in the TURN server by sending TURN
+ * Allocate request. Application must first initiate the server resolution
+ * process with pj_turn_session_set_server() and set the credential to be
+ * used with pj_turn_session_set_credential() before calling this function.
+ *
+ * This function will complete asynchronously, and the application will be
+ * notified about the allocation result in \a on_state() callback. The
+ * TURN session state will move to PJ_TURN_STATE_READY if allocation is
+ * successful, and PJ_TURN_STATE_DEALLOCATING or greater state if allocation
+ * has failed.
+ *
+ * Once allocation has been successful, the TURN session will keep this
+ * allocation alive until the session is destroyed, by sending periodic
+ * allocation refresh to the TURN server.
+ *
+ * @param sess The TURN client session.
+ * @param param Optional TURN allocation parameter.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * initiated or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess,
+ const pj_turn_alloc_param *param);
+
+
+/**
+ * Create or renew permission in the TURN server for the specified peer IP
+ * addresses. Application must install permission for a particular (peer)
+ * IP address before it sends any data to that IP address, or otherwise
+ * the TURN server will drop the data.
+ *
+ * @param sess The TURN client session.
+ * @param addr_cnt Number of IP addresses.
+ * @param addr Array of peer IP addresses. Only the address family
+ * and IP address portion of the socket address matter.
+ * @param options Specify 1 to let the TURN client session automatically
+ * renew the permission later when they are about to
+ * expire.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * issued, or the appropriate error code. Note that
+ * the operation itself will complete asynchronously.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_set_perm(pj_turn_session *sess,
+ unsigned addr_cnt,
+ const pj_sockaddr addr[],
+ unsigned options);
+
+
+/**
+ * Send a data to the specified peer address via the TURN relay. This
+ * function will encapsulate the data as STUN Send Indication or TURN
+ * ChannelData packet and send the message to the TURN server. The TURN
+ * server then will send the data to the peer.
+ *
+ * The allocation (pj_turn_session_alloc()) must have been successfully
+ * created before application can relay any data.
+ *
+ * Since TURN session is transport independent, this function will
+ * ultimately call \a on_send_pkt() callback to request the application
+ * to actually send the packet containing the data to the TURN server.
+ *
+ * @param sess The TURN client session.
+ * @param pkt The data/packet to be sent to peer.
+ * @param pkt_len Length of the data.
+ * @param peer_addr The remote peer address (the ultimate destination
+ * of the data, and not the TURN server address).
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_sendto(pj_turn_session *sess,
+ const pj_uint8_t *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *peer_addr,
+ unsigned addr_len);
+
+/**
+ * Optionally establish channel binding for the specified a peer address.
+ * This function will assign a unique channel number for the peer address
+ * and request channel binding to the TURN server for this address. When
+ * a channel has been bound to a peer, the TURN client and TURN server
+ * will exchange data using ChannelData encapsulation format, which has
+ * lower bandwidth overhead than Send Indication (the default format used
+ * when peer address is not bound to a channel).
+ *
+ * This function will complete asynchronously, and application will be
+ * notified about the result in \a on_channel_bound() callback.
+ *
+ * @param sess The TURN client session.
+ * @param peer The remote peer address.
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * initiated, or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_session_bind_channel(pj_turn_session *sess,
+ const pj_sockaddr_t *peer,
+ unsigned addr_len);
+
+/**
+ * Notify TURN client session upon receiving a packet from server. Since
+ * the TURN session is transport independent, it does not read packet from
+ * any sockets, and rather relies on application giving it packets that
+ * are received from the TURN server. The session then processes this packet
+ * and decides whether it is part of TURN protocol exchange or if it is a
+ * data to be reported back to user, which in this case it will call the
+ * \a on_rx_data() callback.
+ *
+ * @param sess The TURN client session.
+ * @param pkt The packet as received from the TURN server. This
+ * should contain either STUN encapsulated message or
+ * a ChannelData packet.
+ * @param pkt_len The length of the packet.
+ * @param parsed_len Optional argument to receive the number of parsed
+ * or processed data from the packet.
+ *
+ * @return The function may return non-PJ_SUCCESS if it receives
+ * non-STUN and non-ChannelData packet, or if the
+ * \a on_rx_data() returns non-PJ_SUCCESS;
+ */
+PJ_DECL(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess,
+ void *pkt,
+ pj_size_t pkt_len,
+ pj_size_t *parsed_len);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_TURN_SESSION_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_sock.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_sock.h
new file mode 100644
index 0000000..30445e4
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_sock.h
@@ -0,0 +1,397 @@
+/* $Id: turn_sock.h 2966 2009-10-25 09:02:07Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_SOCK_H__
+#define __PJNATH_TURN_SOCK_H__
+
+/**
+ * @file turn_sock.h
+ * @brief TURN relay using UDP client as transport protocol
+ */
+#include <pjnath/turn_session.h>
+#include <pj/sock_qos.h>
+
+
+PJ_BEGIN_DECL
+
+
+/* **************************************************************************/
+/**
+@addtogroup PJNATH_TURN_SOCK
+@{
+
+This is a ready to use object for relaying application data via a TURN server,
+by managing all the operations in \ref turn_op_sec.
+
+\section turnsock_using_sec Using TURN transport
+
+This object provides a thin wrapper to the \ref PJNATH_TURN_SESSION, hence the
+API is very much the same (apart from the obvious difference in the names).
+Please see \ref PJNATH_TURN_SESSION for the documentation on how to use the
+session.
+
+\section turnsock_samples_sec Samples
+
+The \ref turn_client_sample is a sample application to use the
+\ref PJNATH_TURN_SOCK.
+
+Also see <b>\ref samples_page</b> for other samples.
+
+ */
+
+
+/**
+ * Opaque declaration for TURN client.
+ */
+typedef struct pj_turn_sock pj_turn_sock;
+
+/**
+ * This structure contains callbacks that will be called by the TURN
+ * transport.
+ */
+typedef struct pj_turn_sock_cb
+{
+ /**
+ * Notification when incoming data has been received from the remote
+ * peer via the TURN server. The data reported in this callback will
+ * be the exact data as sent by the peer (e.g. the TURN encapsulation
+ * such as Data Indication or ChannelData will be removed before this
+ * function is called).
+ *
+ * @param turn_sock The TURN client transport.
+ * @param data The data as received from the peer.
+ * @param data_len Length of the data.
+ * @param peer_addr The peer address.
+ * @param addr_len The length of the peer address.
+ */
+ void (*on_rx_data)(pj_turn_sock *turn_sock,
+ void *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *peer_addr,
+ unsigned addr_len);
+
+ /**
+ * Notification when TURN session state has changed. Application should
+ * implement this callback to monitor the progress of the TURN session.
+ *
+ * @param turn_sock The TURN client transport.
+ * @param old_state Previous state.
+ * @param new_state Current state.
+ */
+ void (*on_state)(pj_turn_sock *turn_sock,
+ pj_turn_state_t old_state,
+ pj_turn_state_t new_state);
+
+} pj_turn_sock_cb;
+
+
+/**
+ * This structure describes options that can be specified when creating
+ * the TURN socket. Application should call #pj_turn_sock_cfg_default()
+ * to initialize this structure with its default values before using it.
+ */
+typedef struct pj_turn_sock_cfg
+{
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * By default all settings in this structure are not set.
+ */
+ pj_qos_params qos_params;
+
+ /**
+ * Specify if STUN socket should ignore any errors when setting the QoS
+ * traffic type/parameters.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t qos_ignore_error;
+
+} pj_turn_sock_cfg;
+
+
+/**
+ * Initialize pj_turn_sock_cfg structure with default values.
+ */
+PJ_DECL(void) pj_turn_sock_cfg_default(pj_turn_sock_cfg *cfg);
+
+
+/**
+ * Create a TURN transport instance with the specified address family and
+ * connection type. Once TURN transport instance is created, application
+ * must call pj_turn_sock_alloc() to allocate a relay address in the TURN
+ * server.
+ *
+ * @param cfg The STUN configuration which contains among other
+ * things the ioqueue and timer heap instance for
+ * the operation of this transport.
+ * @param af Address family of the client connection. Currently
+ * pj_AF_INET() and pj_AF_INET6() are supported.
+ * @param conn_type Connection type to the TURN server. Both TCP and
+ * UDP are supported.
+ * @param cb Callback to receive events from the TURN transport.
+ * @param setting Optional settings to be specified to the transport.
+ * If this parameter is NULL, default values will be
+ * used.
+ * @param user_data Arbitrary application data to be associated with
+ * this transport.
+ * @param p_turn_sock Pointer to receive the created instance of the
+ * TURN transport.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg,
+ int af,
+ pj_turn_tp_type conn_type,
+ const pj_turn_sock_cb *cb,
+ const pj_turn_sock_cfg *setting,
+ void *user_data,
+ pj_turn_sock **p_turn_sock);
+
+/**
+ * Destroy the TURN transport instance. This will gracefully close the
+ * connection between the client and the TURN server. Although this
+ * function will return immediately, the TURN socket deletion may continue
+ * in the background and the application may still get state changes
+ * notifications from this transport.
+ *
+ * @param turn_sock The TURN transport instance.
+ */
+PJ_DECL(void) pj_turn_sock_destroy(pj_turn_sock *turn_sock);
+
+
+/**
+ * Associate a user data with this TURN transport. The user data may then
+ * be retrieved later with #pj_turn_sock_get_user_data().
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param user_data Arbitrary data.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_set_user_data(pj_turn_sock *turn_sock,
+ void *user_data);
+
+/**
+ * Retrieve the previously assigned user data associated with this TURN
+ * transport.
+ *
+ * @param turn_sock The TURN transport instance.
+ *
+ * @return The user/application data.
+ */
+PJ_DECL(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock);
+
+
+/**
+ * Get the TURN transport info. The transport info contains, among other
+ * things, the allocated relay address.
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param info Pointer to be filled with TURN transport info.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_get_info(pj_turn_sock *turn_sock,
+ pj_turn_session_info *info);
+
+/**
+ * Acquire the internal mutex of the TURN transport. Application may need
+ * to call this function to synchronize access to other objects alongside
+ * the TURN transport, to avoid deadlock.
+ *
+ * @param turn_sock The TURN transport instance.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_lock(pj_turn_sock *turn_sock);
+
+
+/**
+ * Release the internal mutex previously held with pj_turn_sock_lock().
+ *
+ * @param turn_sock The TURN transport instance.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_unlock(pj_turn_sock *turn_sock);
+
+
+/**
+ * Set STUN message logging for this TURN session.
+ * See #pj_stun_session_set_log().
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag
+ */
+PJ_DECL(void) pj_turn_sock_set_log(pj_turn_sock *turn_sock,
+ unsigned flags);
+
+/**
+ * Configure the SOFTWARE name to be sent in all STUN requests by the
+ * TURN session.
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param sw Software name string. If this argument is NULL or
+ * empty, the session will not include SOFTWARE attribute
+ * in STUN requests and responses.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_set_software_name(pj_turn_sock *turn_sock,
+ const pj_str_t *sw);
+
+
+/**
+ * Allocate a relay address/resource in the TURN server. This function
+ * will resolve the TURN server using DNS SRV (if desired) and send TURN
+ * \a Allocate request using the specified credential to allocate a relay
+ * address in the server. This function completes asynchronously, and
+ * application will be notified when the allocation process has been
+ * successful in the \a on_state() callback when the state is set to
+ * PJ_TURN_STATE_READY. If the allocation fails, the state will be set
+ * to PJ_TURN_STATE_DEALLOCATING or greater.
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param domain The domain, hostname, or IP address of the TURN
+ * server. When this parameter contains domain name,
+ * the \a resolver parameter must be set to activate
+ * DNS SRV resolution.
+ * @param default_port The default TURN port number to use when DNS SRV
+ * resolution is not used. If DNS SRV resolution is
+ * used, the server port number will be set from the
+ * DNS SRV records.
+ * @param resolver If this parameter is not NULL, then the \a domain
+ * parameter will be first resolved with DNS SRV and
+ * then fallback to using DNS A/AAAA resolution when
+ * DNS SRV resolution fails. If this parameter is
+ * NULL, the \a domain parameter will be resolved as
+ * hostname.
+ * @param cred The STUN credential to be used for the TURN server.
+ * @param param Optional TURN allocation parameter.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * queued, or the appropriate error code on failure.
+ * When this function returns PJ_SUCCESS, the final
+ * result of the allocation process will be notified
+ * to application in \a on_state() callback.
+ *
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_alloc(pj_turn_sock *turn_sock,
+ const pj_str_t *domain,
+ int default_port,
+ pj_dns_resolver *resolver,
+ const pj_stun_auth_cred *cred,
+ const pj_turn_alloc_param *param);
+
+/**
+ * Create or renew permission in the TURN server for the specified peer IP
+ * addresses. Application must install permission for a particular (peer)
+ * IP address before it sends any data to that IP address, or otherwise
+ * the TURN server will drop the data.
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param addr_cnt Number of IP addresses.
+ * @param addr Array of peer IP addresses. Only the address family
+ * and IP address portion of the socket address matter.
+ * @param options Specify 1 to let the TURN client session automatically
+ * renew the permission later when they are about to
+ * expire.
+ *
+ * @return PJ_SUCCESS if the operation has been successfully
+ * issued, or the appropriate error code. Note that
+ * the operation itself will complete asynchronously.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_set_perm(pj_turn_sock *turn_sock,
+ unsigned addr_cnt,
+ const pj_sockaddr addr[],
+ unsigned options);
+
+/**
+ * Send a data to the specified peer address via the TURN relay. This
+ * function will encapsulate the data as STUN Send Indication or TURN
+ * ChannelData packet and send the message to the TURN server. The TURN
+ * server then will send the data to the peer.
+ *
+ * The allocation (pj_turn_sock_alloc()) must have been successfully
+ * created before application can relay any data.
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param pkt The data/packet to be sent to peer.
+ * @param pkt_len Length of the data.
+ * @param peer_addr The remote peer address (the ultimate destination
+ * of the data, and not the TURN server address).
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_sendto(pj_turn_sock *turn_sock,
+ const pj_uint8_t *pkt,
+ unsigned pkt_len,
+ const pj_sockaddr_t *peer_addr,
+ unsigned addr_len);
+
+/**
+ * Optionally establish channel binding for the specified a peer address.
+ * This function will assign a unique channel number for the peer address
+ * and request channel binding to the TURN server for this address. When
+ * a channel has been bound to a peer, the TURN transport and TURN server
+ * will exchange data using ChannelData encapsulation format, which has
+ * lower bandwidth overhead than Send Indication (the default format used
+ * when peer address is not bound to a channel).
+ *
+ * @param turn_sock The TURN transport instance.
+ * @param peer The remote peer address.
+ * @param addr_len Length of the address.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_turn_sock_bind_channel(pj_turn_sock *turn_sock,
+ const pj_sockaddr_t *peer,
+ unsigned addr_len);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJNATH_TURN_SOCK_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/types.h b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/types.h
new file mode 100644
index 0000000..07948c6
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjnath/include/pjnath/types.h
@@ -0,0 +1,76 @@
+/* $Id: types.h 2642 2009-04-22 17:20:24Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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_TYPES_H__
+#define __PJNATH_TYPES_H__
+
+/**
+ * @file types.h
+ * @brief PJNATH types.
+ */
+
+#include <pj/types.h>
+#include <pjnath/config.h>
+
+/**
+ * @defgroup PJNATH NAT Traversal Helper Library
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * This constant describes a number to be used to identify an invalid TURN
+ * channel number.
+ */
+#define PJ_TURN_INVALID_CHANNEL 0xFFFF
+
+
+/**
+ * Initialize pjnath library.
+ *
+ * @return Initialization status.
+ */
+PJ_DECL(pj_status_t) pjnath_init(void);
+
+
+/**
+ * Display error to the log.
+ *
+ * @param sender The sender name.
+ * @param title Title message.
+ * @param status The error status.
+ */
+#if PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL
+PJ_DECL(void) pjnath_perror(const char *sender, const char *title,
+ pj_status_t status);
+#else
+# define pjnath_perror(sender, title, status)
+#endif
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJNATH_TYPES_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/errno.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/errno.h
new file mode 100644
index 0000000..491741a
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/errno.h
@@ -0,0 +1,118 @@
+/* $Id: errno.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_ERRNO_H__
+#define __PJSIP_SIMPLE_ERRNO_H__
+
+#include <pjsip/sip_errno.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ */
+#define PJSIP_SIMPLE_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*2)
+
+
+/************************************************************
+ * EVENT PACKAGE ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * No event package with the specified name.
+ */
+#define PJSIP_SIMPLE_ENOPKG (PJSIP_SIMPLE_ERRNO_START+1) /*270001*/
+/**
+ * @hideinitializer
+ * Event package already exists.
+ */
+#define PJSIP_SIMPLE_EPKGEXISTS (PJSIP_SIMPLE_ERRNO_START+2) /*270002*/
+
+
+/************************************************************
+ * PRESENCE ERROR
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Expecting SUBSCRIBE request
+ */
+#define PJSIP_SIMPLE_ENOTSUBSCRIBE (PJSIP_SIMPLE_ERRNO_START+20) /*270020*/
+/**
+ * @hideinitializer
+ * No presence associated with subscription
+ */
+#define PJSIP_SIMPLE_ENOPRESENCE (PJSIP_SIMPLE_ERRNO_START+21) /*270021*/
+/**
+ * @hideinitializer
+ * No presence info in server subscription
+ */
+#define PJSIP_SIMPLE_ENOPRESENCEINFO (PJSIP_SIMPLE_ERRNO_START+22) /*270022*/
+/**
+ * @hideinitializer
+ * Bad Content-Type
+ */
+#define PJSIP_SIMPLE_EBADCONTENT (PJSIP_SIMPLE_ERRNO_START+23) /*270023*/
+/**
+ * @hideinitializer
+ * Bad PIDF Message
+ */
+#define PJSIP_SIMPLE_EBADPIDF (PJSIP_SIMPLE_ERRNO_START+24) /*270024*/
+/**
+ * @hideinitializer
+ * Bad XPIDF Message
+ */
+#define PJSIP_SIMPLE_EBADXPIDF (PJSIP_SIMPLE_ERRNO_START+25) /*270025*/
+/**
+ * @hideinitializer
+ * Bad RPID Message
+ */
+#define PJSIP_SIMPLE_EBADRPID (PJSIP_SIMPLE_ERRNO_START+26) /*270026*/
+
+
+/************************************************************
+ * ISCOMPOSING ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Bad isComposing XML message.
+ */
+#define PJSIP_SIMPLE_EBADISCOMPOSE (PJSIP_SIMPLE_ERRNO_START+40) /*270040*/
+
+/**
+ * Get error message for the specified error code. Note that this
+ * function is only able to decode PJSIP-SIMPLE specific error code.
+ * Application should use pj_strerror(), which should be able to
+ * decode all error codes belonging to all subsystems (e.g. pjlib,
+ * pjmedia, pjsip, etc).
+ *
+ * @param status The error code.
+ * @param buffer The buffer where to put the error message.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pjsipsimple_strerror(pj_status_t status,
+ char *buffer, pj_size_t bufsize);
+
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIMPLE_ERRNO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub.h
new file mode 100644
index 0000000..fec9336
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub.h
@@ -0,0 +1,492 @@
+/* $Id: evsub.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_EVSUB_H__
+#define __PJSIP_SIMPLE_EVSUB_H__
+
+/**
+ * @file evsub.h
+ * @brief SIP Specific Event Notification Extension (RFC 3265)
+ */
+
+#include <pjsip-simple/types.h>
+
+
+/**
+ * @defgroup PJSIP_EVENT_NOT SIP Event Notification (RFC 3265) Module
+ * @ingroup PJSIP_SIMPLE
+ * @brief Core Event Subscription framework, used by presence, call transfer, etc.
+ * @{
+ *
+ * This module provides the implementation of SIP Extension for SIP Specific
+ * Event Notification (RFC 3265). It extends PJSIP by supporting SUBSCRIBE and
+ * NOTIFY methods.
+ *
+ * This module itself is extensible; new event packages can be registered to
+ * this module to handle specific extensions (such as presence).
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque type for event subscription session.
+ */
+typedef struct pjsip_evsub pjsip_evsub;
+
+
+/**
+ * This enumeration describes basic subscription state as described in the
+ * RFC 3265. The standard specifies that extensions may define additional
+ * states. In the case where the state is not known, the subscription state
+ * will be set to PJSIP_EVSUB_STATE_UNKNOWN, and the token will be kept
+ * in state_str member of the susbcription structure.
+ */
+enum pjsip_evsub_state
+{
+ PJSIP_EVSUB_STATE_NULL, /**< State is NULL. */
+ PJSIP_EVSUB_STATE_SENT, /**< Client has sent SUBSCRIBE request. */
+ PJSIP_EVSUB_STATE_ACCEPTED, /**< 2xx response to SUBSCRIBE has been
+ sent/received. */
+ PJSIP_EVSUB_STATE_PENDING, /**< Subscription is pending. */
+ PJSIP_EVSUB_STATE_ACTIVE, /**< Subscription is active. */
+ PJSIP_EVSUB_STATE_TERMINATED,/**< Subscription is terminated. */
+ PJSIP_EVSUB_STATE_UNKNOWN, /**< Subscription state can not be determined.
+ Application can query the state by
+ calling #pjsip_evsub_get_state_name().*/
+};
+
+/**
+ * @see pjsip_evsub_state
+ */
+typedef enum pjsip_evsub_state pjsip_evsub_state;
+
+
+/**
+ * Some options for the event subscription.
+ */
+enum
+{
+ /**
+ * If this flag is set, then outgoing request to create subscription
+ * will not have id in the Event header (e.g. in REFER request). But if
+ * there is an id in the incoming NOTIFY, that id will be used.
+ */
+ PJSIP_EVSUB_NO_EVENT_ID = 1,
+};
+
+
+/**
+ * This structure describes callback that is registered by application or
+ * package to receive notifications about subscription events.
+ */
+struct pjsip_evsub_user
+{
+ /**
+ * This callback is called when subscription state has changed.
+ * Application MUST be prepared to receive NULL event and events with
+ * type other than PJSIP_EVENT_TSX_STATE
+ *
+ * This callback is OPTIONAL.
+ *
+ * @param sub The subscription instance.
+ * @param event The event that has caused the state to change,
+ * which may be NULL or may have type other than
+ * PJSIP_EVENT_TSX_STATE.
+ */
+ void (*on_evsub_state)( pjsip_evsub *sub, pjsip_event *event);
+
+ /**
+ * This callback is called when transaction state has changed.
+ *
+ * @param sub The subscription instance.
+ * @param tsx Transaction.
+ * @param event The event.
+ */
+ void (*on_tsx_state)(pjsip_evsub *sub, pjsip_transaction *tsx,
+ pjsip_event *event);
+
+ /**
+ * This callback is called when incoming SUBSCRIBE (or any method that
+ * establishes the subscription in the first place) is received. It
+ * allows application to specify what response should be sent to
+ * remote, along with additional headers and message body to be put
+ * in the response.
+ *
+ * This callback is OPTIONAL.
+ *
+ * However, implementation MUST send NOTIFY request upon receiving this
+ * callback. The suggested behavior is to call
+ * #pjsip_evsub_current_notify(), since this function takes care
+ * about unsubscription request and calculates the appropriate expiration
+ * interval.
+ */
+ void (*on_rx_refresh)( pjsip_evsub *sub,
+ pjsip_rx_data *rdata,
+ int *p_st_code,
+ pj_str_t **p_st_text,
+ pjsip_hdr *res_hdr,
+ pjsip_msg_body **p_body);
+
+ /**
+ * This callback is called when client/subscriber received incoming
+ * NOTIFY request. It allows the application to specify what response
+ * should be sent to remote, along with additional headers and message
+ * body to be put in the response.
+ *
+ * This callback is OPTIONAL. When it is not implemented, the default
+ * behavior is to respond incoming NOTIFY request with 200 (OK).
+ *
+ * @param sub The subscription instance.
+ * @param rdata The received NOTIFY request.
+ * @param p_st_code Application MUST set the value of this argument with
+ * final status code (200-699) upon returning from the
+ * callback.
+ * @param p_st_text Custom status text, if any.
+ * @param res_hdr Upon return, application can put additional headers
+ * to be sent in the response in this list.
+ * @param p_body Application MAY specify message body to be sent in
+ * the response.
+ */
+ void (*on_rx_notify)(pjsip_evsub *sub,
+ pjsip_rx_data *rdata,
+ int *p_st_code,
+ pj_str_t **p_st_text,
+ pjsip_hdr *res_hdr,
+ pjsip_msg_body **p_body);
+
+ /**
+ * This callback is called when it is time for the client to refresh
+ * the subscription.
+ *
+ * This callback is OPTIONAL when PJSIP package such as presence or
+ * refer is used; the event package will refresh subscription by sending
+ * SUBSCRIBE with the interval set to current/last interval.
+ *
+ * @param sub The subscription instance.
+ */
+ void (*on_client_refresh)(pjsip_evsub *sub);
+
+ /**
+ * This callback is called when server doesn't receive subscription
+ * refresh after the specified subscription interval.
+ *
+ * This callback is OPTIONAL when PJSIP package such as presence or
+ * refer is used; the event package send NOTIFY to terminate the
+ * subscription.
+ */
+ void (*on_server_timeout)(pjsip_evsub *sub);
+
+};
+
+
+/**
+ * @see pjsip_evsub_user
+ */
+typedef struct pjsip_evsub_user pjsip_evsub_user;
+
+
+/**
+ * SUBSCRIBE method constant. @see pjsip_get_subscribe_method()
+ */
+PJ_DECL_DATA(const pjsip_method) pjsip_subscribe_method;
+
+/**
+ * NOTIFY method constant. @see pjsip_get_notify_method()
+ */
+PJ_DECL_DATA(const pjsip_method) pjsip_notify_method;
+
+/**
+ * SUBSCRIBE method constant.
+ */
+PJ_DECL(const pjsip_method*) pjsip_get_subscribe_method(void);
+
+/**
+ * NOTIFY method constant.
+ */
+PJ_DECL(const pjsip_method*) pjsip_get_notify_method(void);
+
+
+/**
+ * Initialize the event subscription module and register the module to the
+ * specified endpoint.
+ *
+ * @param endpt The endpoint instance.
+ *
+ * @return PJ_SUCCESS if module can be created and registered
+ * successfully.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_init_module(pjsip_endpoint *endpt);
+
+
+/**
+ * Get the event subscription module instance that was previously created
+ * and registered to endpoint.
+ *
+ * @return The event subscription module instance.
+ */
+PJ_DECL(pjsip_module*) pjsip_evsub_instance(void);
+
+
+/**
+ * Register event package to the event subscription framework.
+ *
+ * @param pkg_mod The module that implements the event package being
+ * registered.
+ * @param event_name Event package identification.
+ * @param expires Default subscription expiration time, in seconds.
+ * @param accept_cnt Number of strings in Accept array.
+ * @param accept Array of Accept value.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_register_pkg( pjsip_module *pkg_mod,
+ const pj_str_t *event_name,
+ unsigned expires,
+ unsigned accept_cnt,
+ const pj_str_t accept[]);
+
+/**
+ * Get the Allow-Events header. This header is built based on the packages
+ * that are registered to the evsub module.
+ *
+ * @param m Pointer to event subscription module instance, or
+ * NULL to use default instance (equal to
+ * #pjsip_evsub_instance()).
+ *
+ * @return The Allow-Events header.
+ */
+PJ_DECL(const pjsip_hdr*) pjsip_evsub_get_allow_events_hdr(pjsip_module *m);
+
+
+/**
+ * Create client subscription session.
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Callback to receive event subscription notifications.
+ * @param event Event name.
+ * @param option Bitmask of options.
+ * @param p_evsub Pointer to receive event subscription instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_create_uac( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ const pj_str_t *event,
+ unsigned option,
+ pjsip_evsub **p_evsub);
+
+/**
+ * Create server subscription session.
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Callback to receive event subscription notifications.
+ * @param rdata The incoming request that creates the event
+ * subscription, such as SUBSCRIBE or REFER.
+ * @param option Bitmask of options.
+ * @param p_evsub Pointer to receive event subscription instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_create_uas( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ pjsip_rx_data *rdata,
+ unsigned option,
+ pjsip_evsub **p_evsub);
+
+/**
+ * Forcefully destroy the subscription session. This function should only
+ * be called on special condition, such as when the subscription
+ * initialization has failed. For other conditions, application MUST terminate
+ * the subscription by sending the appropriate un(SUBSCRIBE) or NOTIFY.
+ *
+ * @param sub The event subscription.
+ * @param notify Specify whether the state notification callback
+ * should be called.
+ *
+ * @return PJ_SUCCESS if subscription session has been destroyed.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_terminate( pjsip_evsub *sub,
+ pj_bool_t notify );
+
+
+/**
+ * Get subscription state.
+ *
+ * @param sub Event subscription instance.
+ *
+ * @return Subscription state.
+ */
+PJ_DECL(pjsip_evsub_state) pjsip_evsub_get_state(pjsip_evsub *sub);
+
+
+/**
+ * Get the string representation of the subscription state.
+ *
+ * @param sub Event subscription instance.
+ *
+ * @return NULL terminated string.
+ */
+PJ_DECL(const char*) pjsip_evsub_get_state_name(pjsip_evsub *sub);
+
+
+/**
+ * Get subscription termination reason, if any. If remote did not
+ * send termination reason, this function will return empty string.
+ *
+ * @param sub Event subscription instance.
+ *
+ * @return NULL terminated string.
+ */
+PJ_DECL(const pj_str_t*) pjsip_evsub_get_termination_reason(pjsip_evsub *sub);
+
+
+/**
+ * Call this function to create request to initiate subscription, to
+ * refresh subcription, or to request subscription termination.
+ *
+ * @param sub Client subscription instance.
+ * @param method The method that establishes the subscription, such as
+ * SUBSCRIBE or REFER. If this argument is NULL, then
+ * SUBSCRIBE will be used.
+ * @param expires Subscription expiration. If the value is set to zero,
+ * this will request unsubscription. If the value is
+ * negative, default expiration as defined by the package
+ * will be used.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_initiate( pjsip_evsub *sub,
+ const pjsip_method *method,
+ pj_int32_t expires,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Accept the incoming subscription request by sending 2xx response to
+ * incoming SUBSCRIBE request.
+ *
+ * @param sub Server subscription instance.
+ * @param rdata The incoming subscription request message.
+ * @param st_code Status code, which MUST be final response.
+ * @param hdr_list Optional list of headers to be added in the response.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_accept( pjsip_evsub *sub,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pjsip_hdr *hdr_list );
+
+
+/**
+ * For notifier, create NOTIFY request to subscriber, and set the state
+ * of the subscription.
+ *
+ * @param sub The server subscription (notifier) instance.
+ * @param state New state to set.
+ * @param state_str The state string name, if state contains value other
+ * than active, pending, or terminated. Otherwise this
+ * argument is ignored.
+ * @param reason Specify reason if new state is terminated, otherwise
+ * put NULL.
+ * @param p_tdata Pointer to receive request message.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_notify( pjsip_evsub *sub,
+ pjsip_evsub_state state,
+ const pj_str_t *state_str,
+ const pj_str_t *reason,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * For notifier, create a NOTIFY request that reflects current subscription
+ * status.
+ *
+ * @param sub The server subscription instance.
+ * @param p_tdata Pointer to receive the request messge.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_current_notify( pjsip_evsub *sub,
+ pjsip_tx_data **p_tdata );
+
+
+
+/**
+ * Send request message that was previously created with initiate(), notify(),
+ * or current_notify(). Application may also send request created with other
+ * functions, e.g. authentication. But the request MUST be either request
+ * that creates/refresh subscription or NOTIFY request.
+ *
+ * @param sub The event subscription object.
+ * @param tdata Request message to be send.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_evsub_send_request( pjsip_evsub *sub,
+ pjsip_tx_data *tdata);
+
+
+
+/**
+ * Get the event subscription instance associated with the specified
+ * transaction.
+ *
+ * @param tsx The transaction.
+ *
+ * @return The event subscription instance registered in the
+ * transaction, if any.
+ */
+PJ_DECL(pjsip_evsub*) pjsip_tsx_get_evsub(pjsip_transaction *tsx);
+
+
+/**
+ * Set event subscription's module data.
+ *
+ * @param sub The event subscription.
+ * @param mod_id The module id.
+ * @param data Arbitrary data.
+ */
+PJ_DECL(void) pjsip_evsub_set_mod_data( pjsip_evsub *sub, unsigned mod_id,
+ void *data );
+
+
+/**
+ * Get event subscription's module data.
+ *
+ * @param sub The event subscription.
+ * @param mod_id The module id.
+ *
+ * @return Data previously set at the specified id.
+ */
+PJ_DECL(void*) pjsip_evsub_get_mod_data( pjsip_evsub *sub, unsigned mod_id );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_SIMPLE_EVSUB_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub_msg.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub_msg.h
new file mode 100644
index 0000000..f868749
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub_msg.h
@@ -0,0 +1,119 @@
+/* $Id: evsub_msg.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_EVENT_NOTIFY_MSG_H__
+#define __PJSIP_SIMPLE_EVENT_NOTIFY_MSG_H__
+
+/**
+ * @file evsub_msg.h
+ * @brief SIP Event Notification Headers (RFC 3265)
+ */
+#include <pjsip/sip_msg.h>
+
+/**
+ * @defgroup PJSIP_EVENT_HDRS Additional Header Fields
+ * @ingroup PJSIP_EVENT_NOT
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+
+/** Max events in Allow-Events header. */
+#define PJSIP_MAX_ALLOW_EVENTS 16
+
+/**
+ * This structure describes Event header.
+ */
+typedef struct pjsip_event_hdr
+{
+ /** Standard header fields. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_event_hdr);
+
+ pj_str_t event_type; /**< Event name. */
+ pj_str_t id_param; /**< Optional event ID parameter. */
+ pjsip_param other_param; /**< Other parameter. */
+} pjsip_event_hdr;
+
+/**
+ * Create an Event header.
+ *
+ * @param pool The pool.
+ *
+ * @return New Event header instance.
+ */
+PJ_DECL(pjsip_event_hdr*) pjsip_event_hdr_create(pj_pool_t *pool);
+
+
+/**
+ * This structure describes Allow-Events header.
+ */
+typedef pjsip_generic_array_hdr pjsip_allow_events_hdr;
+
+
+/**
+ * Create a new Allow-Events header.
+ *
+ * @param pool The pool.
+ *
+ * @return Allow-Events header.
+ */
+PJ_DECL(pjsip_allow_events_hdr*)
+pjsip_allow_events_hdr_create(pj_pool_t *pool);
+
+
+/**
+ * This structure describes Subscription-State header.
+ */
+typedef struct pjsip_sub_state_hdr
+{
+ /** Standard header fields. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_sub_state_hdr);
+
+ pj_str_t sub_state; /**< Subscription state. */
+ pj_str_t reason_param; /**< Optional termination reason. */
+ int expires_param; /**< Expires param, or -1. */
+ int retry_after; /**< Retry after param, or -1. */
+ pjsip_param other_param; /**< Other parameters. */
+} pjsip_sub_state_hdr;
+
+/**
+ * Create new Subscription-State header.
+ *
+ * @param pool The pool.
+ *
+ * @return Subscription-State header.
+ */
+PJ_DECL(pjsip_sub_state_hdr*) pjsip_sub_state_hdr_create(pj_pool_t *pool);
+
+/**
+ * Initialize parser for event notify module.
+ */
+PJ_DECL(void) pjsip_evsub_init_parser(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_SIMPLE_EVENT_NOTIFY_MSG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/iscomposing.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/iscomposing.h
new file mode 100644
index 0000000..9d3d78b
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/iscomposing.h
@@ -0,0 +1,135 @@
+/* $Id: iscomposing.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_ISCOMPOSING_H__
+#define __PJSIP_SIMPLE_ISCOMPOSING_H__
+
+/**
+ * @file iscomposing.h
+ * @brief Support for Indication of Message Composition (RFC 3994)
+ */
+#include <pjsip-simple/types.h>
+#include <pjlib-util/xml.h>
+
+/**
+ * @defgroup PJSIP_ISCOMPOSING Message Composition Indication (RFC 3994)
+ * @ingroup PJSIP_SIMPLE
+ * @brief Support for Indication of Message Composition (RFC 3994)
+ * @{
+ *
+ * This implements message composition indication, as described in
+ * RFC 3994.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create XML message with MIME type "application/im-iscomposing+xml"
+ * to indicate the message composition status.
+ *
+ * @param pool Pool to allocate memory.
+ * @param is_composing Message composition indication status. Set to
+ * PJ_TRUE (or non-zero) to indicate that application
+ * is currently composing an instant message.
+ * @param lst_actv Optional attribute to indicate time of last
+ * activity. If none is to be specified, the value
+ * MUST be set to NULL.
+ * @param content_tp Optional attribute to indicate the content type of
+ * message being composed. If none is to be specified,
+ * the value MUST be set to NULL.
+ * @param refresh Optional attribute to indicate the interval when
+ * next indication will be sent, only when
+ * is_composing is non-zero. If none is to be
+ * specified, the value MUST be set to -1.
+ *
+ * @return An XML message containing the message indication.
+ * NULL will be returned when there's not enough
+ * memory to allocate the message.
+ */
+PJ_DECL(pj_xml_node*) pjsip_iscomposing_create_xml(pj_pool_t *pool,
+ pj_bool_t is_composing,
+ const pj_time_val *lst_actv,
+ const pj_str_t *content_tp,
+ int refresh);
+
+
+/**
+ * Create message body with Content-Type "application/im-iscomposing+xml"
+ * to indicate the message composition status.
+ *
+ * @param pool Pool to allocate memory.
+ * @param is_composing Message composition indication status. Set to
+ * PJ_TRUE (or non-zero) to indicate that application
+ * is currently composing an instant message.
+ * @param lst_actv Optional attribute to indicate time of last
+ * activity. If none is to be specified, the value
+ * MUST be set to NULL.
+ * @param content_tp Optional attribute to indicate the content type of
+ * message being composed. If none is to be specified,
+ * the value MUST be set to NULL.
+ * @param refresh Optional attribute to indicate the interval when
+ * next indication will be sent, only when
+ * is_composing is non-zero. If none is to be
+ * specified, the value MUST be set to -1.
+ *
+ * @return The SIP message body containing XML message
+ * indication. NULL will be returned when there's not
+ * enough memory to allocate the message.
+ */
+PJ_DECL(pjsip_msg_body*) pjsip_iscomposing_create_body( pj_pool_t *pool,
+ pj_bool_t is_composing,
+ const pj_time_val *lst_actv,
+ const pj_str_t *content_tp,
+ int refresh);
+
+
+/**
+ * Parse the buffer and return message composition indication in the
+ * message.
+ *
+ * @param pool Pool to allocate memory for the parsing process.
+ * @param msg The message to be parsed.
+ * @param len Length of the message.
+ * @param p_is_composing Optional pointer to receive iscomposing status.
+ * @param p_last_active Optional pointer to receive last active attribute.
+ * @param p_content_type Optional pointer to receive content type attribute.
+ * @param p_refresh Optional pointer to receive refresh time.
+ *
+ * @return PJ_SUCCESS if message can be successfully parsed.
+ */
+PJ_DECL(pj_status_t) pjsip_iscomposing_parse( pj_pool_t *pool,
+ char *msg,
+ pj_size_t len,
+ pj_bool_t *p_is_composing,
+ pj_str_t **p_last_active,
+ pj_str_t **p_content_type,
+ int *p_refresh );
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIMPLE_ISCOMPOSING_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/mwi.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/mwi.h
new file mode 100644
index 0000000..41c0117
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/mwi.h
@@ -0,0 +1,208 @@
+/* $Id: mwi.h 2968 2009-10-26 11:21:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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 __PJSIP_SIMPLE_MWI_H__
+#define __PJSIP_SIMPLE_MWI_H__
+
+/**
+ * @file mwi.h
+ * @brief SIP Extension for MWI (RFC 3842)
+ */
+#include <pjsip-simple/evsub.h>
+#include <pjsip/sip_msg.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup mwi SIP Message Summary and Message Waiting Indication (RFC 3842)
+ * @ingroup PJSIP_SIMPLE
+ * @brief Support for SIP MWI Extension (RFC 3842)
+ * @{
+ *
+ * This module implements RFC 3842: A Message Summary and Message Waiting
+ * Indication Event Package for the Session Initiation Protocol (SIP).
+ * It uses the SIP Event Notification framework (evsub.h) and extends the
+ * framework by implementing "message-summary" event package.
+ */
+
+
+/**
+ * Initialize the MWI module and register it as endpoint module and
+ * package to the event subscription module.
+ *
+ * @param endpt The endpoint instance.
+ * @param mod_evsub The event subscription module instance.
+ *
+ * @return PJ_SUCCESS if the module is successfully
+ * initialized and registered to both endpoint
+ * and the event subscription module.
+ */
+PJ_DECL(pj_status_t) pjsip_mwi_init_module(pjsip_endpoint *endpt,
+ pjsip_module *mod_evsub);
+
+/**
+ * Get the MWI module instance.
+ *
+ * @return The MWI module instance.
+ */
+PJ_DECL(pjsip_module*) pjsip_mwi_instance(void);
+
+/**
+ * Create MWI client subscription session.
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Pointer to callbacks to receive MWI subscription
+ * events.
+ * @param options Option flags. Currently only PJSIP_EVSUB_NO_EVENT_ID
+ * is recognized.
+ * @param p_evsub Pointer to receive the MWI subscription
+ * session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_mwi_create_uac( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ unsigned options,
+ pjsip_evsub **p_evsub );
+
+/**
+ * Create MWI server subscription session.
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Pointer to callbacks to receive MWI subscription
+ * events.
+ * @param rdata The incoming SUBSCRIBE request that creates the event
+ * subscription.
+ * @param p_evsub Pointer to receive the MWI subscription
+ * session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_mwi_create_uas( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ pjsip_rx_data *rdata,
+ pjsip_evsub **p_evsub );
+
+/**
+ * Forcefully destroy the MWI subscription. This function should only
+ * be called on special condition, such as when the subscription
+ * initialization has failed. For other conditions, application MUST terminate
+ * the subscription by sending the appropriate un(SUBSCRIBE) or NOTIFY.
+ *
+ * @param sub The MWI subscription.
+ * @param notify Specify whether the state notification callback
+ * should be called.
+ *
+ * @return PJ_SUCCESS if subscription session has been destroyed.
+ */
+PJ_DECL(pj_status_t) pjsip_mwi_terminate( pjsip_evsub *sub,
+ pj_bool_t notify );
+
+/**
+ * Call this function to create request to initiate MWI subscription, to
+ * refresh subcription, or to request subscription termination.
+ *
+ * @param sub Client subscription instance.
+ * @param expires Subscription expiration. If the value is set to zero,
+ * this will request unsubscription.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_mwi_initiate( pjsip_evsub *sub,
+ pj_int32_t expires,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Accept the incoming subscription request by sending 2xx response to
+ * incoming SUBSCRIBE request.
+ *
+ * @param sub Server subscription instance.
+ * @param rdata The incoming subscription request message.
+ * @param st_code Status code, which MUST be final response.
+ * @param hdr_list Optional list of headers to be added in the response.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_mwi_accept( pjsip_evsub *sub,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pjsip_hdr *hdr_list );
+
+/**
+ * For notifier, create NOTIFY request to subscriber, and set the state
+ * of the subscription.
+ *
+ * @param sub The server subscription (notifier) instance.
+ * @param state New state to set.
+ * @param state_str The state string name, if state contains value other
+ * than active, pending, or terminated. Otherwise this
+ * argument is ignored.
+ * @param reason Specify reason if new state is terminated, otherwise
+ * put NULL.
+ * @param mime_type MIME type/content type of the message body.
+ * @param body Message body to be included in the NOTIFY request.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_mwi_notify( pjsip_evsub *sub,
+ pjsip_evsub_state state,
+ const pj_str_t *state_str,
+ const pj_str_t *reason,
+ const pjsip_media_type *mime_type,
+ const pj_str_t *body,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Create NOTIFY request containing message body from the last NOITFY
+ * message created.
+ *
+ * @param sub Server subscription object.
+ * @param p_tdata Pointer to receive request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_mwi_current_notify( pjsip_evsub *sub,
+ pjsip_tx_data **p_tdata );
+
+
+/**
+ * Send request message that was previously created with initiate(), notify(),
+ * or current_notify(). Application may also send request created with other
+ * functions, e.g. authentication. But the request MUST be either request
+ * that creates/refresh subscription or NOTIFY request.
+ *
+ * @param sub The subscription object.
+ * @param tdata Request message to be sent.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_mwi_send_request( pjsip_evsub *sub,
+ pjsip_tx_data *tdata );
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIMPLE_MWI_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/pidf.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/pidf.h
new file mode 100644
index 0000000..8ea0f70
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/pidf.h
@@ -0,0 +1,178 @@
+/* $Id: pidf.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_PIDF_H__
+#define __PJSIP_SIMPLE_PIDF_H__
+
+/**
+ * @file pidf.h
+ * @brief PIDF/Presence Information Data Format (RFC 3863)
+ */
+#include <pjsip-simple/types.h>
+#include <pjlib-util/xml.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJSIP_SIMPLE_PIDF PIDF/Presence Information Data Format (RFC 3863)
+ * @ingroup PJSIP_SIMPLE
+ * @brief Support for PIDF/Presence Information Data Format (RFC 3863)
+ * @{
+ *
+ * This file provides tools for manipulating Presence Information Data
+ * Format (PIDF) as described in RFC 3863.
+ */
+typedef struct pj_xml_node pjpidf_pres;
+typedef struct pj_xml_node pjpidf_tuple;
+typedef struct pj_xml_node pjpidf_status;
+typedef struct pj_xml_node pjpidf_note;
+
+typedef struct pjpidf_status_op
+{
+ void (*construct)(pj_pool_t*, pjpidf_status*);
+ pj_bool_t (*is_basic_open)(const pjpidf_status*);
+ void (*set_basic_open)(pjpidf_status*, pj_bool_t);
+} pjpidf_status_op;
+
+typedef struct pjpidf_tuple_op
+{
+ void (*construct)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);
+
+ const pj_str_t* (*get_id)(const pjpidf_tuple* );
+ void (*set_id)(pj_pool_t*, pjpidf_tuple *, const pj_str_t*);
+
+ pjpidf_status* (*get_status)(pjpidf_tuple* );
+
+ const pj_str_t* (*get_contact)(const pjpidf_tuple*);
+ void (*set_contact)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);
+ void (*set_contact_prio)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);
+ const pj_str_t* (*get_contact_prio)(const pjpidf_tuple*);
+
+ pjpidf_note* (*add_note)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);
+ pjpidf_note* (*get_first_note)(pjpidf_tuple*);
+ pjpidf_note* (*get_next_note)(pjpidf_tuple*, pjpidf_note*);
+
+ const pj_str_t* (*get_timestamp)(const pjpidf_tuple*);
+ void (*set_timestamp)(pj_pool_t*, pjpidf_tuple*, const pj_str_t*);
+ void (*set_timestamp_np)(pj_pool_t*,pjpidf_tuple*, pj_str_t*);
+
+} pjpidf_tuple_op;
+
+typedef struct pjpidf_pres_op
+{
+ void (*construct)(pj_pool_t*, pjpidf_pres*, const pj_str_t*);
+
+ pjpidf_tuple* (*add_tuple)(pj_pool_t*, pjpidf_pres*, const pj_str_t*);
+ pjpidf_tuple* (*get_first_tuple)(pjpidf_pres*);
+ pjpidf_tuple* (*get_next_tuple)(pjpidf_pres*, pjpidf_tuple*);
+ pjpidf_tuple* (*find_tuple)(pjpidf_pres*, const pj_str_t*);
+ void (*remove_tuple)(pjpidf_pres*, pjpidf_tuple*);
+
+ pjpidf_note* (*add_note)(pj_pool_t*, pjpidf_pres*, const pj_str_t*);
+ pjpidf_note* (*get_first_note)(pjpidf_pres*);
+ pjpidf_note* (*get_next_note)(pjpidf_pres*, pjpidf_note*);
+
+} pjpidf_pres_op;
+
+
+extern struct pjpidf_op_desc
+{
+ pjpidf_pres_op pres;
+ pjpidf_tuple_op tuple;
+ pjpidf_status_op status;
+} pjpidf_op;
+
+
+/******************************************************************************
+ * Top level API for managing presence document.
+ *****************************************************************************/
+PJ_DECL(pjpidf_pres*) pjpidf_create(pj_pool_t *pool, const pj_str_t *entity);
+PJ_DECL(pjpidf_pres*) pjpidf_parse(pj_pool_t *pool, char *text, int len);
+PJ_DECL(int) pjpidf_print(const pjpidf_pres* pres, char *buf, int len);
+
+
+/******************************************************************************
+ * API for managing Presence node.
+ *****************************************************************************/
+PJ_DECL(void) pjpidf_pres_construct(pj_pool_t *pool, pjpidf_pres *pres,
+ const pj_str_t *entity);
+PJ_DECL(pjpidf_tuple*) pjpidf_pres_add_tuple(pj_pool_t *pool, pjpidf_pres *pres,
+ const pj_str_t *id);
+PJ_DECL(pjpidf_tuple*) pjpidf_pres_get_first_tuple(pjpidf_pres *pres);
+PJ_DECL(pjpidf_tuple*) pjpidf_pres_get_next_tuple(pjpidf_pres *pres,
+ pjpidf_tuple *t);
+PJ_DECL(pjpidf_tuple*) pjpidf_pres_find_tuple(pjpidf_pres *pres,
+ const pj_str_t *id);
+PJ_DECL(void) pjpidf_pres_remove_tuple(pjpidf_pres *pres,
+ pjpidf_tuple*);
+
+PJ_DECL(pjpidf_note*) pjpidf_pres_add_note(pj_pool_t *pool, pjpidf_pres *pres,
+ const pj_str_t *text);
+PJ_DECL(pjpidf_note*) pjpidf_pres_get_first_note(pjpidf_pres *pres);
+PJ_DECL(pjpidf_note*) pjpidf_pres_get_next_note(pjpidf_pres*, pjpidf_note*);
+
+
+/******************************************************************************
+ * API for managing Tuple node.
+ *****************************************************************************/
+PJ_DECL(void) pjpidf_tuple_construct(pj_pool_t *pool, pjpidf_tuple *t,
+ const pj_str_t *id);
+PJ_DECL(const pj_str_t*) pjpidf_tuple_get_id(const pjpidf_tuple *t );
+PJ_DECL(void) pjpidf_tuple_set_id(pj_pool_t *pool, pjpidf_tuple *t,
+ const pj_str_t *id);
+
+PJ_DECL(pjpidf_status*) pjpidf_tuple_get_status(pjpidf_tuple *t);
+
+PJ_DECL(const pj_str_t*) pjpidf_tuple_get_contact(const pjpidf_tuple *t);
+PJ_DECL(void) pjpidf_tuple_set_contact(pj_pool_t *pool, pjpidf_tuple *t,
+ const pj_str_t *contact);
+PJ_DECL(void) pjpidf_tuple_set_contact_prio(pj_pool_t *pool, pjpidf_tuple *t,
+ const pj_str_t *prio);
+PJ_DECL(const pj_str_t*) pjpidf_tuple_get_contact_prio(const pjpidf_tuple *t);
+
+PJ_DECL(pjpidf_note*) pjpidf_tuple_add_note(pj_pool_t *pool, pjpidf_tuple *t,
+ const pj_str_t *text);
+PJ_DECL(pjpidf_note*) pjpidf_tuple_get_first_note(pjpidf_tuple *t);
+PJ_DECL(pjpidf_note*) pjpidf_tuple_get_next_note(pjpidf_tuple *t, pjpidf_note *n);
+
+PJ_DECL(const pj_str_t*) pjpidf_tuple_get_timestamp(const pjpidf_tuple *t);
+PJ_DECL(void) pjpidf_tuple_set_timestamp(pj_pool_t *pool, pjpidf_tuple *t,
+ const pj_str_t *ts);
+PJ_DECL(void) pjpidf_tuple_set_timestamp_np( pj_pool_t*, pjpidf_tuple *t,
+ pj_str_t *ts);
+
+
+/******************************************************************************
+ * API for managing Status node.
+ *****************************************************************************/
+PJ_DECL(void) pjpidf_status_construct(pj_pool_t*, pjpidf_status*);
+PJ_DECL(pj_bool_t) pjpidf_status_is_basic_open(const pjpidf_status*);
+PJ_DECL(void) pjpidf_status_set_basic_open(pjpidf_status*, pj_bool_t);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIMPLE_PIDF_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/presence.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/presence.h
new file mode 100644
index 0000000..1b9c25d
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/presence.h
@@ -0,0 +1,361 @@
+/* $Id: presence.h 2762 2009-06-15 16:03:40Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_PRESENCE_H__
+#define __PJSIP_SIMPLE_PRESENCE_H__
+
+/**
+ * @file presence.h
+ * @brief SIP Extension for Presence (RFC 3856)
+ */
+#include <pjsip-simple/evsub.h>
+#include <pjsip-simple/pidf.h>
+#include <pjsip-simple/xpidf.h>
+#include <pjsip-simple/rpid.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJSIP_SIMPLE_PRES SIP Extension for Presence (RFC 3856)
+ * @ingroup PJSIP_SIMPLE
+ * @brief Support for SIP Extension for Presence (RFC 3856)
+ * @{
+ *
+ * This module contains the implementation of SIP Presence Extension as
+ * described in RFC 3856. It uses the SIP Event Notification framework
+ * (evsub.h) and extends the framework by implementing "presence"
+ * event package.
+ */
+
+
+
+/**
+ * Initialize the presence module and register it as endpoint module and
+ * package to the event subscription module.
+ *
+ * @param endpt The endpoint instance.
+ * @param mod_evsub The event subscription module instance.
+ *
+ * @return PJ_SUCCESS if the module is successfully
+ * initialized and registered to both endpoint
+ * and the event subscription module.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_init_module(pjsip_endpoint *endpt,
+ pjsip_module *mod_evsub);
+
+
+/**
+ * Get the presence module instance.
+ *
+ * @return The presence module instance.
+ */
+PJ_DECL(pjsip_module*) pjsip_pres_instance(void);
+
+
+/**
+ * Maximum presence status info.
+ */
+#define PJSIP_PRES_STATUS_MAX_INFO 8
+
+
+/**
+ * This structure describes presence status of a presentity.
+ */
+struct pjsip_pres_status
+{
+ unsigned info_cnt; /**< Number of info in the status. */
+ struct {
+
+ pj_bool_t basic_open; /**< Basic status/availability. */
+ pjrpid_element rpid; /**< Optional RPID info. */
+
+ pj_str_t id; /**< Tuple id. */
+ pj_str_t contact; /**< Optional contact address. */
+
+ pj_xml_node *tuple_node; /**< Pointer to tuple XML node of
+ parsed PIDF body received from
+ remote agent. Only valid for
+ client subscription. If the
+ last received NOTIFY request
+ does not contain any PIDF body,
+ this valud will be set to NULL */
+
+ } info[PJSIP_PRES_STATUS_MAX_INFO]; /**< Array of info. */
+
+ pj_bool_t _is_valid; /**< Internal flag. */
+};
+
+
+/**
+ * @see pjsip_pres_status
+ */
+typedef struct pjsip_pres_status pjsip_pres_status;
+
+
+/**
+ * Create presence client subscription session.
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Pointer to callbacks to receive presence subscription
+ * events.
+ * @param options Option flags. Currently only PJSIP_EVSUB_NO_EVENT_ID
+ * is recognized.
+ * @param p_evsub Pointer to receive the presence subscription
+ * session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_create_uac( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ unsigned options,
+ pjsip_evsub **p_evsub );
+
+
+/**
+ * Create presence server subscription session.
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Pointer to callbacks to receive presence subscription
+ * events.
+ * @param rdata The incoming SUBSCRIBE request that creates the event
+ * subscription.
+ * @param p_evsub Pointer to receive the presence subscription
+ * session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_create_uas( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ pjsip_rx_data *rdata,
+ pjsip_evsub **p_evsub );
+
+
+/**
+ * Forcefully destroy the presence subscription. This function should only
+ * be called on special condition, such as when the subscription
+ * initialization has failed. For other conditions, application MUST terminate
+ * the subscription by sending the appropriate un(SUBSCRIBE) or NOTIFY.
+ *
+ * @param sub The presence subscription.
+ * @param notify Specify whether the state notification callback
+ * should be called.
+ *
+ * @return PJ_SUCCESS if subscription session has been destroyed.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_terminate( pjsip_evsub *sub,
+ pj_bool_t notify );
+
+
+
+/**
+ * Call this function to create request to initiate presence subscription, to
+ * refresh subcription, or to request subscription termination.
+ *
+ * @param sub Client subscription instance.
+ * @param expires Subscription expiration. If the value is set to zero,
+ * this will request unsubscription.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_initiate( pjsip_evsub *sub,
+ pj_int32_t expires,
+ pjsip_tx_data **p_tdata);
+
+
+
+/**
+ * Accept the incoming subscription request by sending 2xx response to
+ * incoming SUBSCRIBE request.
+ *
+ * @param sub Server subscription instance.
+ * @param rdata The incoming subscription request message.
+ * @param st_code Status code, which MUST be final response.
+ * @param hdr_list Optional list of headers to be added in the response.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_accept( pjsip_evsub *sub,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pjsip_hdr *hdr_list );
+
+
+
+
+/**
+ * For notifier, create NOTIFY request to subscriber, and set the state
+ * of the subscription. Application MUST set the presence status to the
+ * appropriate state (by calling #pjsip_pres_set_status()) before calling
+ * this function.
+ *
+ * @param sub The server subscription (notifier) instance.
+ * @param state New state to set.
+ * @param state_str The state string name, if state contains value other
+ * than active, pending, or terminated. Otherwise this
+ * argument is ignored.
+ * @param reason Specify reason if new state is terminated, otherwise
+ * put NULL.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_notify( pjsip_evsub *sub,
+ pjsip_evsub_state state,
+ const pj_str_t *state_str,
+ const pj_str_t *reason,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Create NOTIFY request to reflect current subscription status.
+ *
+ * @param sub Server subscription object.
+ * @param p_tdata Pointer to receive request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_current_notify( pjsip_evsub *sub,
+ pjsip_tx_data **p_tdata );
+
+
+
+/**
+ * Send request message that was previously created with initiate(), notify(),
+ * or current_notify(). Application may also send request created with other
+ * functions, e.g. authentication. But the request MUST be either request
+ * that creates/refresh subscription or NOTIFY request.
+ *
+ * @param sub The subscription object.
+ * @param tdata Request message to be sent.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_send_request( pjsip_evsub *sub,
+ pjsip_tx_data *tdata );
+
+
+/**
+ * Get the presence status. Client normally would call this function
+ * after receiving NOTIFY request from server.
+ *
+ * @param sub The client or server subscription.
+ * @param status The structure to receive presence status.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_get_status( pjsip_evsub *sub,
+ pjsip_pres_status *status );
+
+
+/**
+ * Set the presence status. This operation is only valid for server
+ * subscription. After calling this function, application would need to
+ * send NOTIFY request to client.
+ *
+ * @param sub The server subscription.
+ * @param status Status to be set.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_set_status( pjsip_evsub *sub,
+ const pjsip_pres_status *status );
+
+
+/**
+ * This is a utility function to create PIDF message body from PJSIP
+ * presence status (pjsip_pres_status).
+ *
+ * @param pool The pool to allocate memory for the message body.
+ * @param status Presence status to be converted into PIDF message
+ * body.
+ * @param entity The entity ID, which normally is equal to the
+ * presentity ID publishing this presence info.
+ * @param p_body Pointer to receive the SIP message body.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_create_pidf( pj_pool_t *pool,
+ const pjsip_pres_status *status,
+ const pj_str_t *entity,
+ pjsip_msg_body **p_body );
+
+
+/**
+ * This is a utility function to create X-PIDF message body from PJSIP
+ * presence status (pjsip_pres_status).
+ *
+ * @param pool The pool to allocate memory for the message body.
+ * @param status Presence status to be converted into X-PIDF message
+ * body.
+ * @param entity The entity ID, which normally is equal to the
+ * presentity ID publishing this presence info.
+ * @param p_body Pointer to receive the SIP message body.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_create_xpidf(pj_pool_t *pool,
+ const pjsip_pres_status *status,
+ const pj_str_t *entity,
+ pjsip_msg_body **p_body );
+
+
+
+/**
+ * This is a utility function to parse PIDF body into PJSIP presence status.
+ *
+ * @param rdata The incoming SIP message containing the PIDF body.
+ * @param pool Pool to allocate memory to copy the strings into
+ * the presence status structure.
+ * @param status The presence status to be initialized.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_parse_pidf(pjsip_rx_data *rdata,
+ pj_pool_t *pool,
+ pjsip_pres_status *status);
+
+
+
+/**
+ * This is a utility function to parse X-PIDF body into PJSIP presence status.
+ *
+ * @param rdata The incoming SIP message containing the X-PIDF body.
+ * @param pool Pool to allocate memory to copy the strings into
+ * the presence status structure.
+ * @param status The presence status to be initialized.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_pres_parse_xpidf(pjsip_rx_data *rdata,
+ pj_pool_t *pool,
+ pjsip_pres_status *status);
+
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIMPLE_PRESENCE_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/publish.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/publish.h
new file mode 100644
index 0000000..6b3373d
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/publish.h
@@ -0,0 +1,333 @@
+/* $Id: publish.h 2940 2009-10-12 07:44:14Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_PUBLISH_H__
+#define __PJSIP_SIMPLE_PUBLISH_H__
+
+/**
+ * @file publish.h
+ * @brief SIP Extension for Event State Publication (PUBLISH, RFC 3903)
+ */
+
+#include <pjsip/sip_util.h>
+#include <pjsip/sip_auth.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ @defgroup PJSIP_SIMPLE_PUBLISH SIP Event State Publication (PUBLISH, RFC 3903)
+ @ingroup PJSIP_SIMPLE
+ @brief Support for SIP Event State Publication (PUBLISH, RFC 3903)
+ @{
+
+ This module contains the implementation of Session Initiation Protocol (SIP)
+ Extension for Event State Publication (PUBLISH) as defined by RFC 3903.
+ */
+
+/**
+ * The SIP PUBLISH method constant.
+ */
+extern const pjsip_method pjsip_publish_method;
+
+
+/*****************************************************************************
+ * @defgroup PJSIP_SIMPLE_PUBLISH_CLIENT SIP Event State Publication Client
+ * @ingroup PJSIP_SIMPLE
+ * @brief Event State Publication Clien
+ * @{
+ */
+
+
+/** Expiration not specified. */
+#define PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED ((pj_uint32_t)0xFFFFFFFFUL)
+
+/**
+ * Opaque declaration for client side event publication session.
+ */
+typedef struct pjsip_publishc pjsip_publishc;
+
+
+/**
+ * Client publication options. Application should initialize this structure
+ * with its default values by calling #pjsip_publishc_opt_default()
+ */
+typedef struct pjsip_publishc_opt
+{
+ /**
+ * Specify whether the client publication session should queue the
+ * PUBLISH request should there be another PUBLISH transaction still
+ * pending. If this is set to false, the client will return error
+ * on the PUBLISH request if there is another PUBLISH transaction still
+ * in progress.
+ *
+ * Default: PJSIP_PUBLISHC_QUEUE_REQUEST
+ */
+ pj_bool_t queue_request;
+
+} pjsip_publishc_opt;
+
+
+/** Structure to hold parameters when calling application's callback.
+ * The application's callback is called when the client publication process
+ * has finished.
+ */
+struct pjsip_publishc_cbparam
+{
+ pjsip_publishc *pubc; /**< Client publication structure. */
+ void *token; /**< Arbitrary token. */
+ pj_status_t status; /**< Error status. */
+ int code; /**< SIP status code received. */
+ pj_str_t reason; /**< SIP reason phrase received. */
+ pjsip_rx_data *rdata; /**< The complete received response. */
+ int expiration;/**< Next expiration interval. If the
+ value is -1, it means the session
+ will not renew itself. */
+};
+
+
+/** Type declaration for callback to receive publication result. */
+typedef void pjsip_publishc_cb(struct pjsip_publishc_cbparam *param);
+
+
+/**
+ * Initialize client publication session option with default values.
+ *
+ * @param opt The option.
+ */
+PJ_DECL(void) pjsip_publishc_opt_default(pjsip_publishc_opt *opt);
+
+
+/**
+ * Initialize client publication module.
+ *
+ * @param endpt SIP endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_init_module(pjsip_endpoint *endpt);
+
+
+/**
+ * Create client publication structure.
+ *
+ * @param endpt Endpoint, used to allocate pool from.
+ * @param opt Options, or NULL to specify default options.
+ * @param token Opaque data to be associated with the client publication.
+ * @param cb Pointer to callback function to receive publication status.
+ * @param p_pubc Pointer to receive client publication structure.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt,
+ const pjsip_publishc_opt *opt,
+ void *token,
+ pjsip_publishc_cb *cb,
+ pjsip_publishc **p_pubc);
+
+
+/**
+ * Destroy client publication structure. If a publication transaction is
+ * in progress, then the structure will be deleted only after a final response
+ * has been received, and in this case, the callback won't be called.
+ *
+ * @param pubc The client publication structure.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_destroy(pjsip_publishc *pubc);
+
+
+
+/**
+ * Get the memory pool associated with a publication client session.
+ *
+ * @param pubc The client publication structure.
+ * @return pool handle.
+ */
+PJ_DECL(pj_pool_t*) pjsip_publishc_get_pool(pjsip_publishc *pubc);
+
+
+/**
+ * Initialize client publication structure with various information needed to
+ * perform the publication.
+ *
+ * @param pubc The client publication structure.
+ * @param event The Event identification (e.g. "presence").
+ * @param target_uri The URI of the presentity which the which the status
+ * is being published.
+ * @param from_uri The URI of the endpoint who sends the event
+ * publication. Normally the value would be the same as
+ * target_uri.
+ * @param to_uri The URI to be put in To header. Normally the value
+ * would be the same as target_uri.
+ * @param expires The default expiration of the event publication.
+ * If the value PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED is
+ * given, then no default expiration will be applied.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_init(pjsip_publishc *pubc,
+ const pj_str_t *event,
+ const pj_str_t *target_uri,
+ const pj_str_t *from_uri,
+ const pj_str_t *to_uri,
+ pj_uint32_t expires);
+
+
+/**
+ * Set authentication credentials to use by this publication.
+ *
+ * @param pubc The publication structure.
+ * @param count Number of credentials in the array.
+ * @param c Array of credentials.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_set_credentials(pjsip_publishc *pubc,
+ int count,
+ const pjsip_cred_info c[]);
+
+/**
+ * Set route set to be used for outgoing requests.
+ *
+ * @param pubc The client publication structure.
+ * @param rs List containing Route headers.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_set_route_set(pjsip_publishc *pubc,
+ const pjsip_route_hdr *rs);
+
+
+/**
+ * Set list of headers to be added to each PUBLISH request generated by
+ * the client publication session. Note that application can also add
+ * the headers to the request after calling #pjsip_publishc_publish()
+ * or #pjsip_publishc_unpublish(), but the benefit of this function is
+ * the headers will also be added to requests generated internally by
+ * the session, such as during session renewal/refresh.
+ *
+ * Note that calling this function will clear the previously added list
+ * of headers.
+ *
+ * @param pubc The client publication structure.
+ * @param hdr_list The list of headers.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_set_headers(pjsip_publishc *pubc,
+ const pjsip_hdr *hdr_list);
+
+/**
+ * Create PUBLISH request for the specified client publication structure.
+ * Application can use this function to both create initial publication
+ * or to modify existing publication.
+ *
+ * After the PUBLISH request is created, application MUST fill in the
+ * body part of the request with the appropriate content for the Event
+ * being published.
+ *
+ * Note that publication refresh are handled automatically by the session
+ * (as long as auto_refresh argument below is non-zero), and application
+ * should not use this function to perform publication refresh.
+ *
+ * @param pubc The client publication session.
+ * @param auto_refresh If non zero, the library will automatically
+ * refresh the next publication until application
+ * unpublish.
+ * @param p_tdata Pointer to receive the PUBLISH request. Note that
+ * the request DOES NOT have a message body.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_publish(pjsip_publishc *pubc,
+ pj_bool_t auto_refresh,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Create PUBLISH request to unpublish the current client publication.
+ *
+ * @param pubc The client publication structure.
+ * @param p_tdata Pointer to receive the PUBLISH request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_unpublish(pjsip_publishc *pubc,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Update the client publication expiration value. Note that this DOES NOT
+ * automatically send outgoing PUBLISH request to update the publication
+ * session. If application wants to do this, then it must construct a
+ * PUBLISH request and send it to the server.
+ *
+ * @param pubc The client publication structure.
+ * @param expires The new expires value.
+ *
+ * @return PU_SUCCESS on successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_update_expires(pjsip_publishc *pubc,
+ pj_uint32_t expires );
+
+
+/**
+ * Sends outgoing PUBLISH request. The process will complete asynchronously,
+ * and application will be notified via the callback when the process
+ * completes.
+ *
+ * If the session has another PUBLISH request outstanding, the behavior
+ * depends on whether request queueing is enabled in the session (this was
+ * set by setting \a queue_request field of #pjsip_publishc_opt to true
+ * when calling #pjsip_publishc_create(). Default is true). If request
+ * queueing is enabled, the request will be queued and the function will
+ * return PJ_EPENDING. One the outstanding request is complete, the queued
+ * request will be sent automatically. If request queueing is disabled, the
+ * function will reject the request and return PJ_EBUSY.
+ *
+ * @param pubc The client publication structure.
+ * @param tdata Transmit data.
+ *
+ * @return - PJ_SUCCESS on success, or
+ * - PJ_EPENDING if request is queued, or
+ * - PJ_EBUSY if request is rejected because another PUBLISH
+ * request is in progress, or
+ * - other status code to indicate the error.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_send(pjsip_publishc *pubc,
+ pjsip_tx_data *tdata);
+
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIMPLE_PUBLISH_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/rpid.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/rpid.h
new file mode 100644
index 0000000..8e09271
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/rpid.h
@@ -0,0 +1,149 @@
+/* $Id: rpid.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_RPID_H__
+#define __PJSIP_SIMPLE_RPID_H__
+
+/**
+ * @file rpid.h
+ * @brief RPID: Rich Presence Extensions to the PIDF (RFC 4480)
+ */
+#include <pjsip-simple/types.h>
+#include <pjsip-simple/pidf.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJSIP_SIMPLE_RPID RPID/Rich Presence Extensions to PIDF (RFC 4480)
+ * @ingroup PJSIP_SIMPLE
+ * @brief RPID/Rich Presence Extensions to PIDF (RFC 4480)
+ * @{
+ *
+ * This file provides tools for managing subset of RPID elements into
+ * PIDF document.
+ */
+
+/**
+ * This enumeration describes subset of standard activities as
+ * described by RFC 4880, RPID: Rich Presence Extensions to the
+ * Presence Information Data Format (PIDF).
+ */
+typedef enum pjrpid_activity
+{
+ /** Activity is unknown. The activity would then be conceived
+ * in the "note" field.
+ */
+ PJRPID_ACTIVITY_UNKNOWN,
+
+ /** The person is away */
+ PJRPID_ACTIVITY_AWAY,
+
+ /** The person is busy */
+ PJRPID_ACTIVITY_BUSY
+
+} pjrpid_activity;
+
+
+/**
+ * This enumeration describes types of RPID element.
+ */
+typedef enum pjrpid_element_type
+{
+ /** RPID <person> element */
+ PJRPID_ELEMENT_TYPE_PERSON
+
+} pjrpid_element_type;
+
+
+/**
+ * This structure describes person information in RPID document.
+ */
+typedef struct pjrpid_element
+{
+ /** Element type. */
+ pjrpid_element_type type;
+
+ /** Optional id to set on the element. */
+ pj_str_t id;
+
+ /** Activity type. */
+ pjrpid_activity activity;
+
+ /** Optional text describing the person/element. */
+ pj_str_t note;
+
+} pjrpid_element;
+
+
+/**
+ * Duplicate RPID element.
+ *
+ * @param pool Pool.
+ * @param dst Destination structure.
+ * @param src Source structure.
+ */
+PJ_DECL(void) pjrpid_element_dup(pj_pool_t *pool, pjrpid_element *dst,
+ const pjrpid_element *src);
+
+
+/**
+ * Add RPID element information into existing PIDF document. This will also
+ * add the appropriate XML namespace attributes into the presence's XML
+ * node, if the attributes are not already present, and also a <note> element
+ * to the first <tuple> element of the PIDF document.
+ *
+ * @param pres The PIDF presence document.
+ * @param pool Pool.
+ * @param options Currently unused, and must be zero.
+ * @param elem RPID element information to be added into the PIDF
+ * document.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjrpid_add_element(pjpidf_pres *pres,
+ pj_pool_t *pool,
+ unsigned options,
+ const pjrpid_element *elem);
+
+/**
+ * Get RPID element information from PIDF document, if any.
+ *
+ * @param pres The PIDF document containing RPID elements.
+ * @param pool Pool to duplicate the information.
+ * @param elem Structure to receive the element information.
+ *
+ * @return PJ_SUCCESS if the document does contain RPID element
+ * and the information has been parsed successfully.
+ */
+PJ_DECL(pj_status_t) pjrpid_get_element(const pjpidf_pres *pres,
+ pj_pool_t *pool,
+ pjrpid_element *elem);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIMPLE_RPID_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/types.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/types.h
new file mode 100644
index 0000000..474ffcc
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/types.h
@@ -0,0 +1,31 @@
+/* $Id: types.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_TYPES_H__
+#define __PJSIP_SIMPLE_TYPES_H__
+
+#include <pjsip/sip_types.h>
+
+
+#define PJSIP_EVSUB_POOL_LEN 4000
+#define PJSIP_EVSUB_POOL_INC 4000
+
+
+#endif /* __PJSIP_SIMPLE_TYPES_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/xpidf.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/xpidf.h
new file mode 100644
index 0000000..c4b34e9
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/xpidf.h
@@ -0,0 +1,135 @@
+/* $Id: xpidf.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIMPLE_XPIDF_H__
+#define __PJSIP_SIMPLE_XPIDF_H__
+
+/**
+ * @file xpidf.h
+ * @brief XPIDF/Presence Information Data Format
+ */
+#include <pjsip-simple/types.h>
+#include <pjlib-util/xml.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_SIMPLE_XPIDF XPIDF/Presence Information Data Format
+ * @ingroup PJSIP_SIMPLE
+ * @brief Support for XPIDF/Presence Information Data Format
+ * @{
+ *
+ * This is an old presence data format as described in:
+ * draft-rosenberg-impp-pidf-00.txt.
+ *
+ * We won't support this format extensively here, as it seems there's not
+ * too many implementations support this anymore, as it shouldn't.
+ */
+
+/** Type definitions for XPIDF root document. */
+typedef pj_xml_node pjxpidf_pres;
+
+
+/**
+ * Create a new XPIDF document.
+ *
+ * @param pool Pool.
+ * @param uri URI to set in the XPIDF document.
+ *
+ * @return XPIDF document.
+ */
+PJ_DECL(pjxpidf_pres*) pjxpidf_create(pj_pool_t *pool, const pj_str_t *uri);
+
+
+/**
+ * Parse XPIDF document.
+ *
+ * @param pool Pool.
+ * @param text Input text.
+ * @param len Length of input text.
+ *
+ * @return XPIDF document.
+ */
+PJ_DECL(pjxpidf_pres*) pjxpidf_parse(pj_pool_t *pool, char *text, pj_size_t len);
+
+
+/**
+ * Print XPIDF document.
+ *
+ * @param pres The XPIDF document to print.
+ * @param text Buffer to place the output.
+ * @param len Length of the buffer.
+ *
+ * @return The length printed.
+ */
+PJ_DECL(int) pjxpidf_print( pjxpidf_pres *pres, char *text, pj_size_t len);
+
+
+/**
+ * Get URI in the XPIDF document
+ *
+ * @param pres XPIDF document
+ *
+ * @return The URI, or an empty string.
+ */
+PJ_DECL(pj_str_t*) pjxpidf_get_uri(pjxpidf_pres *pres);
+
+
+/**
+ * Set the URI of the XPIDF document.
+ *
+ * @param pool Pool.
+ * @param pres The XPIDF document.
+ * @param uri URI to set in the XPIDF document.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjxpidf_set_uri(pj_pool_t *pool, pjxpidf_pres *pres,
+ const pj_str_t *uri);
+
+
+/**
+ * Get presence status in the XPIDF document.
+ *
+ * @param pres XPIDF document.
+ *
+ * @return True to indicate the contact is online.
+ */
+PJ_DECL(pj_bool_t) pjxpidf_get_status(pjxpidf_pres *pres);
+
+
+/**
+ * Set presence status in the XPIDF document.
+ *
+ * @param pres XPIDF document.
+ * @param status Status to set, True for online, False for offline.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjxpidf_set_status(pjxpidf_pres *pres, pj_bool_t status);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIMPLE_XPIDF_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_100rel.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_100rel.h
new file mode 100644
index 0000000..8f87289
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_100rel.h
@@ -0,0 +1,245 @@
+/* $Id: sip_100rel.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __SIP_100REL_H__
+#define __SIP_100REL_H__
+
+/**
+ * @file sip_100rel.h
+ * @brief PRACK (Reliability of Provisional Responses)
+ */
+
+
+#include <pjsip-ua/sip_inv.h>
+
+
+/**
+ * @defgroup PJSIP_100REL 100rel/PRACK - Reliability of Provisional Responses
+ * @ingroup PJSIP_HIGH_UA
+ * @brief PRACK - Reliability of Provisional Responses
+ * @{
+ *
+ * This module provides management of Reliability of Provisional Responses
+ * (\a 100rel and \a PRACK), as described in RFC 3262.
+ *
+ * Other than the #pjsip_100rel_init_module() function, the 100rel API
+ * exported by this module are not intended to be used by application, but
+ * rather they will be invoked by the \ref PJSIP_INV.
+ *
+ * \section pjsip_100rel_using Using Reliable Provisional Response
+ *
+ * \subsection pjsip_100rel_init Initializing 100rel Module
+ *
+ * Application must explicitly initialize 100rel module by calling
+ * #pjsip_100rel_init_module() in application initialization function.
+ *
+ * Once the 100rel module is initialized, it will register \a PRACK method
+ * in \a Allow header, and \a 100rel tag in \a Supported header.
+ *
+ * \subsection pjsip_100rel_sess Using 100rel in a Session
+ *
+ * For UAC, \a 100rel support will be enabled in the session if \a 100rel
+ * support is enabled in the library (default is yes).
+ * Outgoing INVITE request will include \a 100rel tag in \a Supported
+ * header and \a PRACK method in \a Allow header. When callee endpoint
+ * sends reliable provisional responses, the UAC will automatically send
+ * \a PRACK request to acknowledge the response. If callee endpoint doesn't
+ * send reliable provisional response, the response will be handled using
+ * normal, non-100rel procedure (that is, \a PRACK will not be sent).
+ *
+ * If the UAC wants to <b>mandate</b> \a 100rel support, it can specify
+ * #PJSIP_INV_REQUIRE_100REL in the \a options argument when calling
+ * #pjsip_inv_create_uac(). In this case, PJSIP will add \a 100rel tag
+ * in the \a Require header of the outgoing INVITE request.
+ *
+ * For UAS, if it wants to support \a 100rel but not to mandate it,
+ * it must specify #PJSIP_INV_SUPPORT_100REL flag in the \a options
+ * argument when calling #pjsip_inv_verify_request(), and pass the same
+ * \a options variable when calling #pjsip_inv_verify_request. If UAC had
+ * specified \a 100rel in it's list of extensions in \a Require header,
+ * the UAS will send provisional responses reliably. If UAC only listed
+ * \a 100rel in its \a Supported header but not in \a Require header,
+ * or if UAC does not list \a 100rel support at all, the UAS WILL NOT
+ * send provisional responses reliably.
+ * The snippet below can be used to accomplish this task:
+ *
+ * \verbatim
+ unsigned options = 0;
+
+ options |= PJSIP_INV_SUPPORT_100REL;
+
+ status = pjsip_inv_verify_request(rdata, &options, answer, NULL,
+ endpt, &resp);
+ if (status != PJ_SUCCESS) {
+ // INVITE request cannot be handled.
+ // Reject the request with the response in resp.
+ ...
+ return;
+ }
+
+ // Create UAS dialog, populate Contact header, etc.
+ ...
+
+ // Create UAS invite session
+ status = pjsip_inv_create_uas( dlg, rdata, answer, options, &inv);
+
+ ..
+
+ \endverbatim
+ *
+ * For another requirement, if UAS wants to <b>mandate</b> \a 100rel support,
+ * it can specify #PJSIP_INV_REQUIRE_100REL flag when calling
+ * #pjsip_inv_verify_request(), and pass the \a options when calling
+ * #pjsip_inv_verify_request. In this case,
+ * \a 100rel extension will be used if UAC specifies \a 100rel in its
+ * \a Supported header. If UAC does not list \a 100rel in \a Supported header,
+ * the incoming INVITE request will be rejected with 421 (Extension Required)
+ * response. For the sample code, it should be identical to the snippet
+ * above, except that application must specify #PJSIP_INV_REQUIRE_100REL
+ * flag in the \a options instead of #PJSIP_INV_SUPPORT_100REL.
+ *
+ * For yet another requirement, if UAS <b>does not</b> want to support
+ * \a 100rel extension, it can reject incoming INVITE request with
+ * 420 (Bad Extension) response whenever incoming INVITE request has
+ * \a 100rel tag in its \a Require header. This can be done by specifying
+ * zero as the \a options when calling #pjsip_inv_verify_request().
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * PRACK method constant.
+ * @see pjsip_get_prack_method()
+ */
+PJ_DECL_DATA(const pjsip_method) pjsip_prack_method;
+
+
+/**
+ * Get #pjsip_invite_method constant.
+ */
+PJ_DECL(const pjsip_method*) pjsip_get_prack_method(void);
+
+
+/**
+ * Initialize 100rel module. This function must be called once during
+ * application initialization, to register 100rel module to SIP endpoint.
+ *
+ * @param endpt The SIP endpoint instance.
+ *
+ * @return PJ_SUCCESS if module is successfully initialized.
+ */
+PJ_DECL(pj_status_t) pjsip_100rel_init_module(pjsip_endpoint *endpt);
+
+
+/**
+ * Add 100rel support to the specified invite session. This function will
+ * be called internally by the invite session if it detects that the
+ * session needs 100rel support.
+ *
+ * @param inv The invite session.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_100rel_attach(pjsip_inv_session *inv);
+
+
+/**
+ * Check if incoming response has reliable provisional response feature.
+ *
+ * @param rdata Receive data buffer containing the response.
+ *
+ * @return PJ_TRUE if the provisional response is reliable.
+ */
+PJ_DECL(pj_bool_t) pjsip_100rel_is_reliable(pjsip_rx_data *rdata);
+
+
+/**
+ * Create PRACK request for the incoming reliable provisional response.
+ * Note that PRACK request MUST be sent using #pjsip_100rel_send_prack().
+ *
+ * @param inv The invite session.
+ * @param rdata The incoming reliable provisional response.
+ * @param p_tdata Upon return, it will be initialized with the
+ * PRACK request.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_100rel_create_prack(pjsip_inv_session *inv,
+ pjsip_rx_data *rdata,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Send PRACK request.
+ *
+ * @param inv The invite session.
+ * @param tdata The PRACK request.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_100rel_send_prack(pjsip_inv_session *inv,
+ pjsip_tx_data *tdata);
+
+
+/**
+ * Handle incoming PRACK request.
+ *
+ * @param inv The invite session.
+ * @param rdata Incoming PRACK request.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_100rel_on_rx_prack(pjsip_inv_session *inv,
+ pjsip_rx_data *rdata);
+
+
+/**
+ * Transmit INVITE response (provisional or final) reliably according to
+ * 100rel specification. The 100rel module will take care of retransmitting
+ * or enqueueing the response according to the current state of the
+ * reliable response processing. This function will be called internally
+ * by invite session.
+ *
+ * @param inv The invite session.
+ * @param tdata The INVITE response.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_100rel_tx_response(pjsip_inv_session *inv,
+ pjsip_tx_data *tdata);
+
+
+/**
+ * Notify 100rel module that the invite session has been disconnected.
+ *
+ * @param inv The invite session.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_100rel_end_session(pjsip_inv_session *inv);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __SIP_100REL_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_inv.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_inv.h
new file mode 100644
index 0000000..e13396d
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_inv.h
@@ -0,0 +1,875 @@
+/* $Id: sip_inv.h 2869 2009-08-12 17:53:47Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __SIP_INVITE_SESSION_H__
+#define __SIP_INVITE_SESSION_H__
+
+/**
+ * @file sip_inv.h
+ * @brief INVITE sessions
+ */
+
+
+#include <pjsip/sip_dialog.h>
+#include <pjmedia/sdp_neg.h>
+
+
+/**
+ * @defgroup PJSIP_HIGH_UA User Agent Library
+ * @brief Mid-level User Agent Library.
+ *
+ * This is the high level user agent library, which consists of:
+ * - @ref PJSIP_INV, to encapsulate INVITE sessions and SDP
+ * negotiation in the session,
+ * - @ref PJSUA_REGC, high level client registration API, and
+ * - @ref PJSUA_XFER.
+ *
+ * More detailed information is explained in
+ * <A HREF="/docs.htm">PJSIP Developer's Guide</A>
+ * PDF document, and readers are encouraged to read the document to
+ * get the concept behind dialog, dialog usages, and INVITE sessions.
+ *
+ * The User Agent Library is implemented in <b>pjsip-ua</b> static
+ * library.
+ */
+
+/**
+ * @defgroup PJSIP_INV INVITE Session
+ * @ingroup PJSIP_HIGH_UA
+ * @brief Provides INVITE session management.
+ * @{
+ *
+ * The INVITE session uses the @ref PJSIP_DIALOG framework to manage
+ * the underlying dialog, and is one type of usages that can use
+ * a particular dialog instance (other usages are event subscription,
+ * discussed in @ref PJSIP_EVENT_NOT). The INVITE session manages
+ * the life-time of the session, and also manages the SDP negotiation.
+ *
+ * Application must link with <b>pjsip-ua</b> static library to use this API.
+ *
+ * More detailed information is explained in
+ * <A HREF="/docs.htm">PJSIP Developer's Guide</A>
+ * PDF document, and readers are encouraged to read the document to
+ * get the concept behind dialog, dialog usages, and INVITE sessions.
+ *
+ * The INVITE session does NOT manage media. If application wants to
+ * use API that encapsulates both signaling and media in a very easy
+ * to use API, it can use @ref PJSUA_LIB for this purpose.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @see pjsip_inv_session
+ */
+typedef struct pjsip_inv_session pjsip_inv_session;
+
+
+/**
+ * This enumeration describes invite session state.
+ */
+typedef enum pjsip_inv_state
+{
+ PJSIP_INV_STATE_NULL, /**< Before INVITE is sent or received */
+ PJSIP_INV_STATE_CALLING, /**< After INVITE is sent */
+ PJSIP_INV_STATE_INCOMING, /**< After INVITE is received. */
+ PJSIP_INV_STATE_EARLY, /**< After response with To tag. */
+ PJSIP_INV_STATE_CONNECTING, /**< After 2xx is sent/received. */
+ PJSIP_INV_STATE_CONFIRMED, /**< After ACK is sent/received. */
+ PJSIP_INV_STATE_DISCONNECTED, /**< Session is terminated. */
+} pjsip_inv_state;
+
+/**
+ * This structure contains callbacks to be registered by application to
+ * receieve notifications from the framework about various events in
+ * the invite session.
+ */
+typedef struct pjsip_inv_callback
+{
+ /**
+ * This callback is called when the invite sesion state has changed.
+ * Application should inspect the session state (inv_sess->state) to get
+ * the current state of the session.
+ *
+ * This callback is mandatory.
+ *
+ * @param inv The invite session.
+ * @param e The event which has caused the invite session's
+ * state to change.
+ */
+ void (*on_state_changed)(pjsip_inv_session *inv, pjsip_event *e);
+
+ /**
+ * This callback is called when the invite usage module has created
+ * a new dialog and invite because of forked outgoing request.
+ *
+ * This callback is mandatory.
+ *
+ * @param inv The new invite session.
+ * @param e The event which has caused the dialog to fork.
+ * The type of this event can be either
+ * PJSIP_EVENT_RX_MSG or PJSIP_EVENT_RX_200_MSG.
+ */
+ void (*on_new_session)(pjsip_inv_session *inv, pjsip_event *e);
+
+ /**
+ * This callback is called whenever any transactions within the session
+ * has changed their state. Application MAY implement this callback,
+ * e.g. to monitor the progress of an outgoing request, or to send
+ * response to unhandled incoming request (such as INFO).
+ *
+ * This callback is optional.
+ *
+ * @param inv The invite session.
+ * @param tsx The transaction, which state has changed.
+ * @param e The event which has caused the transation state's
+ * to change.
+ */
+ void (*on_tsx_state_changed)(pjsip_inv_session *inv,
+ pjsip_transaction *tsx,
+ pjsip_event *e);
+
+ /**
+ * This callback is called when the invite session has received
+ * new offer from peer. Application can inspect the remote offer
+ * in "offer", and set the SDP answer with #pjsip_inv_set_sdp_answer().
+ * When the application sends a SIP message to send the answer,
+ * this SDP answer will be negotiated with the offer, and the result
+ * will be sent with the SIP message.
+ *
+ * @param inv The invite session.
+ * @param offer Remote offer.
+ */
+ void (*on_rx_offer)(pjsip_inv_session *inv,
+ const pjmedia_sdp_session *offer);
+
+ /**
+ * This callback is optional, and it is used to ask the application
+ * to create a fresh offer, when the invite session has received
+ * re-INVITE without offer. This offer then will be sent in the
+ * 200/OK response to the re-INVITE request.
+ *
+ * If application doesn't implement this callback, the invite session
+ * will send the currently active SDP as the offer.
+ *
+ * @param inv The invite session.
+ * @param p_offer Pointer to receive the SDP offer created by
+ * application.
+ */
+ void (*on_create_offer)(pjsip_inv_session *inv,
+ pjmedia_sdp_session **p_offer);
+
+ /**
+ * This callback is called after SDP offer/answer session has completed.
+ * The status argument specifies the status of the offer/answer,
+ * as returned by pjmedia_sdp_neg_negotiate().
+ *
+ * This callback is optional (from the point of view of the framework),
+ * but all useful applications normally need to implement this callback.
+ *
+ * @param inv The invite session.
+ * @param status The negotiation status.
+ */
+ void (*on_media_update)(pjsip_inv_session *inv_ses,
+ pj_status_t status);
+
+ /**
+ * This callback is called when the framework needs to send
+ * ACK request after it receives incoming 2xx response for
+ * INVITE. It allows application to manually handle the
+ * transmission of ACK request, which is required by some 3PCC
+ * scenarios. If this callback is not implemented, the framework
+ * will handle the ACK transmission automatically.
+ *
+ * When this callback is overridden, application may delay the
+ * sending of the ACK request (for example, when it needs to
+ * wait for answer from the other call leg, in 3PCC scenarios).
+ *
+ * Application creates the ACK request
+ *
+ * Once it has sent the ACK request, the framework will keep
+ * this ACK request in the cache. Subsequent receipt of 2xx response
+ * will not cause this callback to be called, and instead automatic
+ * retransmission of this ACK request from the cache will be done
+ * by the framework.
+ *
+ * This callback is optional.
+ */
+ void (*on_send_ack)(pjsip_inv_session *inv, pjsip_rx_data *rdata);
+
+ /**
+ * This callback is called when the session is about to resend the
+ * INVITE request to the specified target, following the previously
+ * received redirection response.
+ *
+ * Application may accept the redirection to the specified target
+ * (the default behavior if this callback is implemented), reject
+ * this target only and make the session continue to try the next
+ * target in the list if such target exists, stop the whole
+ * redirection process altogether and cause the session to be
+ * disconnected, or defer the decision to ask for user confirmation.
+ *
+ * This callback is optional. If this callback is not implemented,
+ * the default behavior is to NOT follow the redirection response.
+ *
+ * @param inv The invite session.
+ * @param target The current target to be tried.
+ * @param e The event that caused this callback to be called.
+ * This could be the receipt of 3xx response, or
+ * 4xx/5xx response received for the INVITE sent to
+ * subsequent targets, or NULL if this callback is
+ * called from within #pjsip_inv_process_redirect()
+ * context.
+ *
+ * @return Action to be performed for the target. Set this
+ * parameter to one of the value below:
+ * - PJSIP_REDIRECT_ACCEPT: immediately accept the
+ * redirection to this target. When set, the
+ * session will immediately resend INVITE request
+ * to the target after this callback returns.
+ * - PJSIP_REDIRECT_REJECT: immediately reject this
+ * target. The session will continue retrying with
+ * next target if present, or disconnect the call
+ * if there is no more target to try.
+ * - PJSIP_REDIRECT_STOP: stop the whole redirection
+ * process and immediately disconnect the call. The
+ * on_state_changed() callback will be called with
+ * PJSIP_INV_STATE_DISCONNECTED state immediately
+ * after this callback returns.
+ * - PJSIP_REDIRECT_PENDING: set to this value if
+ * no decision can be made immediately (for example
+ * to request confirmation from user). Application
+ * then MUST call #pjsip_inv_process_redirect()
+ * to either accept or reject the redirection upon
+ * getting user decision.
+ */
+ pjsip_redirect_op (*on_redirected)(pjsip_inv_session *inv,
+ const pjsip_uri *target,
+ const pjsip_event *e);
+
+} pjsip_inv_callback;
+
+
+
+/**
+ * This enumeration shows various options that can be applied to a session.
+ * The bitmask combination of these options need to be specified when
+ * creating a session. After the dialog is established (including early),
+ * the options member of #pjsip_inv_session shows which capabilities are
+ * common in both endpoints.
+ */
+enum pjsip_inv_option
+{
+ /**
+ * Indicate support for reliable provisional response extension
+ */
+ PJSIP_INV_SUPPORT_100REL = 1,
+
+ /**
+ * Indicate support for session timer extension.
+ */
+ PJSIP_INV_SUPPORT_TIMER = 2,
+
+ /**
+ * Indicate support for UPDATE method. This is automatically implied
+ * when creating outgoing dialog. After the dialog is established,
+ * the options member of #pjsip_inv_session shows whether peer supports
+ * this method as well.
+ */
+ PJSIP_INV_SUPPORT_UPDATE = 4,
+
+ /**
+ * Require reliable provisional response extension.
+ */
+ PJSIP_INV_REQUIRE_100REL = 32,
+
+ /**
+ * Require session timer extension.
+ */
+ PJSIP_INV_REQUIRE_TIMER = 64,
+
+ /**
+ * Session timer extension will always be used even when peer doesn't
+ * support/want session timer.
+ */
+ PJSIP_INV_ALWAYS_USE_TIMER = 128,
+
+};
+
+/* Forward declaration of Session Timers */
+struct pjsip_timer;
+
+/**
+ * This structure describes the invite session.
+ *
+ * Note regarding the invite session's pools. The inv_sess used to have
+ * only one pool, which is just a pointer to the dialog's pool. Ticket
+ * http://trac.pjsip.org/repos/ticket/877 has found that the memory
+ * usage will grow considerably everytime re-INVITE or UPDATE is
+ * performed.
+ *
+ * Ticket #877 then created two more memory pools for the inv_sess, so
+ * now we have three memory pools:
+ * - pool: to be used to allocate long term data for the session
+ * - pool_prov and pool_active: this is a flip-flop pools to be used
+ * interchangably during re-INVITE and UPDATE. pool_prov is
+ * "provisional" pool, used to allocate SDP offer or answer for
+ * the re-INVITE and UPDATE. Once SDP negotiation is done, the
+ * provisional pool will be made as the active pool, then the
+ * existing active pool will be reset, to release the memory
+ * back to the OS. So these pool's lifetime is synchronized to
+ * the SDP offer-answer negotiation.
+ *
+ * Higher level application such as PJSUA-LIB has been modified to
+ * make use of these flip-flop pools, i.e. by creating media objects
+ * from the provisional pool rather than from the long term pool.
+ *
+ * Other applications that want to use these pools must understand
+ * that the flip-flop pool's lifetimes are synchronized to the
+ * SDP offer-answer negotiation.
+ */
+struct pjsip_inv_session
+{
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Log identification */
+ pj_pool_t *pool; /**< Long term pool. */
+ pj_pool_t *pool_prov; /**< Provisional pool */
+ pj_pool_t *pool_active; /**< Active/current pool*/
+ pjsip_inv_state state; /**< Invite sess state. */
+ pj_bool_t cancelling; /**< CANCEL requested */
+ pj_bool_t pending_cancel; /**< Wait to send CANCEL*/
+ pjsip_status_code cause; /**< Disconnect cause. */
+ pj_str_t cause_text; /**< Cause text. */
+ pj_bool_t notify; /**< Internal. */
+ pjsip_dialog *dlg; /**< Underlying dialog. */
+ pjsip_role_e role; /**< Invite role. */
+ unsigned options; /**< Options in use. */
+ pjmedia_sdp_neg *neg; /**< Negotiator. */
+ pjsip_transaction *invite_tsx; /**< 1st invite tsx. */
+ pjsip_tx_data *invite_req; /**< Saved invite req */
+ pjsip_tx_data *last_answer; /**< Last INVITE resp. */
+ pjsip_tx_data *last_ack; /**< Last ACK request */
+ pj_int32_t last_ack_cseq; /**< CSeq of last ACK */
+ void *mod_data[PJSIP_MAX_MODULE];/**< Modules data. */
+ struct pjsip_timer *timer; /**< Session Timers. */
+};
+
+
+/**
+ * Initialize the invite usage module and register it to the endpoint.
+ * The callback argument contains pointer to functions to be called on
+ * occurences of events in invite sessions.
+ *
+ * @param endpt The endpoint instance.
+ * @param cb Callback structure.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_usage_init(pjsip_endpoint *endpt,
+ const pjsip_inv_callback *cb);
+
+/**
+ * Get the INVITE usage module instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pjsip_module*) pjsip_inv_usage_instance(void);
+
+
+/**
+ * Dump user agent contents (e.g. all dialogs).
+ */
+PJ_DECL(void) pjsip_inv_usage_dump(void);
+
+
+/**
+ * Create UAC invite session for the specified dialog in dlg.
+ *
+ * @param dlg The dialog which will be used by this invite session.
+ * @param local_sdp If application has determined its media capability,
+ * it can specify the SDP here. Otherwise it can leave
+ * this to NULL, to let remote UAS specifies an offer.
+ * @param options The options argument is bitmask combination of SIP
+ * features in pjsip_inv_options enumeration.
+ * @param p_inv On successful return, the invite session will be put
+ * in this argument.
+ *
+ * @return The function will return PJ_SUCCESS if it can create
+ * the session. Otherwise the appropriate error status
+ * will be returned on failure.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_create_uac(pjsip_dialog *dlg,
+ const pjmedia_sdp_session *local_sdp,
+ unsigned options,
+ pjsip_inv_session **p_inv);
+
+
+/**
+ * Application SHOULD call this function upon receiving the initial INVITE
+ * request in rdata before creating the invite session (or even dialog),
+ * to verify that the invite session can handle the INVITE request.
+ * This function verifies that local endpoint is capable to handle required
+ * SIP extensions in the request (i.e. Require header) and also the media,
+ * if media description is present in the request.
+ *
+ * @param rdata The incoming INVITE request.
+ *
+ * @param options Upon calling this function, the options argument
+ * MUST contain the desired SIP extensions to be
+ * applied to the session. Upon return, this argument
+ * will contain the SIP extension that will be applied
+ * to the session, after considering the Supported,
+ * Require, and Allow headers in the request.
+ *
+ * @param sdp If local media capability has been determined,
+ * and if application wishes to verify that it can
+ * handle the media offer in the incoming INVITE
+ * request, it SHOULD specify its local media capability
+ * in this argument.
+ * If it is not specified, media verification will not
+ * be performed by this function.
+ *
+ * @param dlg If tdata is not NULL, application needs to specify
+ * how to create the response. Either dlg or endpt
+ * argument MUST be specified, with dlg argument takes
+ * precedence when both are specified.
+ *
+ * If a dialog has been created prior to calling this
+ * function, then it MUST be specified in dlg argument.
+ * Otherwise application MUST specify the endpt argument
+ * (this is useful e.g. when application wants to send
+ * the response statelessly).
+ *
+ * @param endpt If tdata is not NULL, application needs to specify
+ * how to create the response. Either dlg or endpt
+ * argument MUST be specified, with dlg argument takes
+ * precedence when both are specified.
+ *
+ * @param tdata If this argument is not NULL, this function will
+ * create the appropriate non-2xx final response message
+ * when the verification fails.
+ *
+ * @return If everything has been negotiated successfully,
+ * the function will return PJ_SUCCESS. Otherwise it
+ * will return the reason of the failure as the return
+ * code.
+ *
+ * This function is capable to create the appropriate
+ * response message when the verification has failed.
+ * If tdata is specified, then a non-2xx final response
+ * will be created and put in this argument upon return,
+ * when the verification has failed.
+ *
+ * If a dialog has been created prior to calling this
+ * function, then it MUST be specified in dlg argument.
+ * Otherwise application MUST specify the endpt argument
+ * (this is useful e.g. when application wants to send
+ * the response statelessly).
+ *
+ * @see pjsip_inv_verify_request2()
+ */
+PJ_DECL(pj_status_t) pjsip_inv_verify_request( pjsip_rx_data *rdata,
+ unsigned *options,
+ const pjmedia_sdp_session *sdp,
+ pjsip_dialog *dlg,
+ pjsip_endpoint *endpt,
+ pjsip_tx_data **tdata);
+
+/**
+ * Variant of #pjsip_inv_verify_request() which allows application to specify
+ * the parsed SDP in the \a offer argument. This is useful to avoid having to
+ * re-parse the SDP in the incoming request.
+ *
+ * @see pjsip_inv_verify_request()
+ */
+PJ_DECL(pj_status_t) pjsip_inv_verify_request2( pjsip_rx_data *rdata,
+ unsigned *options,
+ const pjmedia_sdp_session *offer,
+ const pjmedia_sdp_session *answer,
+ pjsip_dialog *dlg,
+ pjsip_endpoint *endpt,
+ pjsip_tx_data **tdata);
+
+/**
+ * Create UAS invite session for the specified dialog in dlg. Application
+ * SHOULD call the verification function before calling this function,
+ * to ensure that it can create the session successfully.
+ *
+ * @param dlg The dialog to be used.
+ * @param rdata Application MUST specify the received INVITE request
+ * in rdata. The invite session needs to inspect the
+ * received request to see if the request contains
+ * features that it supports.
+ * @param local_sdp If application has determined its media capability,
+ * it can specify this capability in this argument.
+ * If SDP is received in the initial INVITE, the UAS
+ * capability specified in this argument doesn't have to
+ * match the received offer; the SDP negotiator is able
+ * to rearrange the media lines in the answer so that it
+ * matches the offer.
+ * @param options The options argument is bitmask combination of SIP
+ * features in pjsip_inv_options enumeration.
+ * @param p_inv Pointer to receive the newly created invite session.
+ *
+ * @return On successful, the invite session will be put in
+ * p_inv argument and the function will return PJ_SUCCESS.
+ * Otherwise the appropriate error status will be returned
+ * on failure.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_create_uas(pjsip_dialog *dlg,
+ pjsip_rx_data *rdata,
+ const pjmedia_sdp_session *local_sdp,
+ unsigned options,
+ pjsip_inv_session **p_inv);
+
+
+/**
+ * Forcefully terminate and destroy INVITE session, regardless of
+ * the state of the session. Note that this function should only be used
+ * when there is failure in the INVITE session creation. After the
+ * invite session has been created and initialized, normally application
+ * SHOULD use #pjsip_inv_end_session() to end the INVITE session instead.
+ *
+ * Note also that this function may terminate the underlying dialog, if
+ * there are no other sessions in the dialog.
+ *
+ * @param inv The invite session.
+ * @param st_code Status code for the reason of the termination.
+ * @param notify If set to non-zero, then on_state_changed()
+ * callback will be called.
+ *
+ * @return PJ_SUCCESS if the INVITE session has been
+ * terminated.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_terminate( pjsip_inv_session *inv,
+ int st_code,
+ pj_bool_t notify );
+
+
+/**
+ * Restart UAC session and prepare the session for a new initial INVITE.
+ * This function can be called for example when the application wants to
+ * follow redirection response with a new call reusing this session so
+ * that the new call will have the same Call-ID and From headers. After
+ * the session is restarted, application may create and send a new INVITE
+ * request.
+ *
+ * @param inv The invite session.
+ * @param new_offer Should be set to PJ_TRUE since the application will
+ * restart the session.
+ *
+ * @return PJ_SUCCESS on successful operation.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_uac_restart(pjsip_inv_session *inv,
+ pj_bool_t new_offer);
+
+
+/**
+ * Accept or reject redirection response. Application MUST call this function
+ * after it signaled PJSIP_REDIRECT_PENDING in the \a on_redirected()
+ * callback, to notify the invite session whether to accept or reject the
+ * redirection to the current target. Application can use the combination of
+ * PJSIP_REDIRECT_PENDING command in \a on_redirected() callback and this
+ * function to ask for user permission before redirecting the call.
+ *
+ * Note that if the application chooses to reject or stop redirection (by
+ * using PJSIP_REDIRECT_REJECT or PJSIP_REDIRECT_STOP respectively), the
+ * session disconnection callback will be called before this function returns.
+ * And if the application rejects the target, the \a on_redirected() callback
+ * may also be called before this function returns if there is another target
+ * to try.
+ *
+ * @param inv The invite session.
+ * @param cmd Redirection operation. The semantic of this argument
+ * is similar to the description in the \a on_redirected()
+ * callback, except that the PJSIP_REDIRECT_PENDING is
+ * not accepted here.
+ * @param e Should be set to NULL.
+ *
+ * @return PJ_SUCCESS on successful operation.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_process_redirect(pjsip_inv_session *inv,
+ pjsip_redirect_op cmd,
+ pjsip_event *e);
+
+
+/**
+ * Create the initial INVITE request for this session. This function can only
+ * be called for UAC session. If local media capability is specified when
+ * the invite session was created, then this function will put an SDP offer
+ * in the outgoing INVITE request. Otherwise the outgoing request will not
+ * contain SDP body.
+ *
+ * @param inv The UAC invite session.
+ * @param p_tdata The initial INVITE request will be put in this
+ * argument if it can be created successfully.
+ *
+ * @return PJ_SUCCESS if the INVITE request can be created.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_invite( pjsip_inv_session *inv,
+ pjsip_tx_data **p_tdata );
+
+
+/**
+ * Create the initial response message for the incoming INVITE request in
+ * rdata with status code st_code and optional status text st_text. Use
+ * #pjsip_inv_answer() to create subsequent response message.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_initial_answer( pjsip_inv_session *inv,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ const pjmedia_sdp_session *sdp,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Create a response message to the initial INVITE request. This function
+ * can only be called for the initial INVITE request, as subsequent
+ * re-INVITE request will be answered automatically.
+ *
+ * @param inv The UAS invite session.
+ * @param st_code The st_code contains the status code to be sent,
+ * which may be a provisional or final response.
+ * @param st_text If custom status text is desired, application can
+ * specify the text in st_text; otherwise if this
+ * argument is NULL, default status text will be used.
+ * @param local_sdp If application has specified its media capability
+ * during creation of UAS invite session, the local_sdp
+ * argument MUST be NULL. This is because application
+ * can not perform more than one SDP offer/answer session
+ * in a single INVITE transaction.
+ * If application has not specified its media capability
+ * during creation of UAS invite session, it MAY or MUST
+ * specify its capability in local_sdp argument,
+ * depending whether st_code indicates a 2xx final
+ * response.
+ * @param p_tdata Pointer to receive the response message created by
+ * this function.
+ *
+ * @return PJ_SUCCESS if response message was created
+ * successfully.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_answer( pjsip_inv_session *inv,
+ int st_code,
+ const pj_str_t *st_text,
+ const pjmedia_sdp_session *local_sdp,
+ pjsip_tx_data **p_tdata );
+
+
+/**
+ * Set local answer to respond to remote SDP offer, to be carried by
+ * subsequent response (or request).
+ *
+ * @param inv The invite session.
+ * @param sdp The SDP description which will be set as answer
+ * to remote.
+ *
+ * @return PJ_SUCCESS if local answer can be accepted by
+ * SDP negotiator.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_set_sdp_answer(pjsip_inv_session *inv,
+ const pjmedia_sdp_session *sdp );
+
+
+/**
+ * Create a SIP message to initiate invite session termination. Depending on
+ * the state of the session, this function may return CANCEL request,
+ * a non-2xx final response, a BYE request, or even no request.
+ *
+ * For UAS, if the session has not answered the incoming INVITE, this function
+ * creates the non-2xx final response with the specified status code in
+ * \a st_code and optional status text in \a st_text.
+ *
+ * For UAC, if the original INVITE has not been answered with a final
+ * response, the behavior depends on whether provisional response has been
+ * received. If provisional response has been received, this function will
+ * create CANCEL request. If no provisional response has been received, the
+ * function will not create CANCEL request (the function will return
+ * PJ_SUCCESS but the \a p_tdata will contain NULL) because we cannot send
+ * CANCEL before receiving provisional response. If then a provisional
+ * response is received, the invite session will send CANCEL automatically.
+ *
+ * For both UAC and UAS, if the INVITE session has been answered with final
+ * response, a BYE request will be created.
+ *
+ * @param inv The invite session.
+ * @param st_code Status code to be used for terminating the session.
+ * @param st_text Optional status text.
+ * @param p_tdata Pointer to receive the message to be created. Note
+ * that it's possible to receive NULL here while the
+ * function returns PJ_SUCCESS, see the description.
+ *
+ * @return PJ_SUCCESS if termination is initiated.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_end_session( pjsip_inv_session *inv,
+ int st_code,
+ const pj_str_t *st_text,
+ pjsip_tx_data **p_tdata );
+
+
+
+/**
+ * Create a re-INVITE request.
+ *
+ * @param inv The invite session.
+ * @param new_contact If application wants to update its local contact and
+ * inform peer to perform target refresh with a new
+ * contact, it can specify the new contact in this
+ * argument; otherwise this argument must be NULL.
+ * @param new_offer Application MAY initiate a new SDP offer/answer
+ * session in the request when there is no pending
+ * answer to be sent or received. It can detect this
+ * condition by observing the state of the SDP
+ * negotiator of the invite session. If new offer
+ * should be sent to remote, the offer must be specified
+ * in this argument, otherwise it must be NULL.
+ * @param p_tdata Pointer to receive the re-INVITE request message to
+ * be created.
+ *
+ * @return PJ_SUCCESS if a re-INVITE request with the specified
+ * characteristics (e.g. to contain new offer) can be
+ * created.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_reinvite(pjsip_inv_session *inv,
+ const pj_str_t *new_contact,
+ const pjmedia_sdp_session *new_offer,
+ pjsip_tx_data **p_tdata );
+
+
+
+/**
+ * Create an UPDATE request to initiate new SDP offer.
+ *
+ * @param inv The invite session.
+ * @param new_contact If application wants to update its local contact
+ * and inform peer to perform target refresh with a new
+ * contact, it can specify the new contact in this
+ * argument; otherwise this argument must be NULL.
+ * @param offer Offer to be sent to remote. This argument is
+ * mandatory.
+ * @param p_tdata Pointer to receive the UPDATE request message to
+ * be created.
+ *
+ * @return PJ_SUCCESS if a UPDATE request with the specified
+ * characteristics (e.g. to contain new offer) can be
+ * created.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_update ( pjsip_inv_session *inv,
+ const pj_str_t *new_contact,
+ const pjmedia_sdp_session *offer,
+ pjsip_tx_data **p_tdata );
+
+
+/**
+ * Create an ACK request. Normally ACK request transmission is handled
+ * by the framework. Application only needs to use this function if it
+ * handles the ACK transmission manually, by overriding \a on_send_ack()
+ * callback in #pjsip_inv_callback.
+ *
+ * Note that if the invite session has a pending offer to be answered
+ * (for example when the last 2xx response to INVITE contains an offer),
+ * application MUST have set the SDP answer with #pjsip_create_sdp_body()
+ * prior to creating the ACK request. In this case, the ACK request
+ * will be added with SDP message body.
+ *
+ * @param inv The invite session.
+ * @param cseq Mandatory argument to specify the CSeq of the
+ * ACK request. This value MUST match the value
+ * of the INVITE transaction to be acknowledged.
+ * @param p_tdata Pointer to receive the ACK request message to
+ * be created.
+ *
+ * @return PJ_SUCCESS if ACK request has been created.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_create_ack(pjsip_inv_session *inv,
+ int cseq,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Send request or response message in tdata.
+ *
+ * @param inv The invite session.
+ * @param tdata The message to be sent.
+ *
+ * @return PJ_SUCCESS if transaction can be initiated
+ * successfully to send this message. Note that the
+ * actual final state of the transaction itself will
+ * be reported later, in on_tsx_state_changed()
+ * callback.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_send_msg(pjsip_inv_session *inv,
+ pjsip_tx_data *tdata);
+
+
+/**
+ * Get the invite session for the dialog, if any.
+ *
+ * @param dlg The dialog which invite session is being queried.
+ *
+ * @return The invite session instance which has been
+ * associated with this dialog, or NULL.
+ */
+PJ_DECL(pjsip_inv_session*) pjsip_dlg_get_inv_session(pjsip_dialog *dlg);
+
+/**
+ * Get the invite session instance associated with transaction tsx, if any.
+ *
+ * @param tsx The transaction, which invite session is being
+ * queried.
+ *
+ * @return The invite session instance which has been
+ * associated with this transaction, or NULL.
+ */
+PJ_DECL(pjsip_inv_session*) pjsip_tsx_get_inv_session(pjsip_transaction *tsx);
+
+
+/**
+ * Get state names for INVITE session state.
+ *
+ * @param state The invite state.
+ *
+ * @return String describing the state.
+ */
+PJ_DECL(const char *) pjsip_inv_state_name(pjsip_inv_state state);
+
+
+/**
+ * This is a utility function to create SIP body for SDP content.
+ *
+ * @param pool Pool to allocate memory.
+ * @param sdp SDP session to be put in the SIP message body.
+ * @param p_body Pointer to receive SIP message body containing
+ * the SDP session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_create_sdp_body(pj_pool_t *pool,
+ pjmedia_sdp_session *sdp,
+ pjsip_msg_body **p_body);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __SIP_INVITE_SESSION_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_regc.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_regc.h
new file mode 100644
index 0000000..dadb31e
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_regc.h
@@ -0,0 +1,373 @@
+/* $Id: sip_regc.h 2855 2009-08-05 18:41:23Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_REG_H__
+#define __PJSIP_SIP_REG_H__
+
+/**
+ * @file sip_regc.h
+ * @brief SIP Registration Client
+ */
+
+#include <pjsip/sip_types.h>
+#include <pjsip/sip_auth.h>
+#include <pjsip/sip_transport.h>
+
+
+/**
+ * @defgroup PJSUA_REGC Client Registration
+ * @ingroup PJSIP_HIGH_UA
+ * @brief High Layer API for performing client registration.
+ * @{
+ *
+ * This provides API for performing client registration. Application must
+ * link with <b>pjsip-ua</b> static library to use this API.
+
+ */
+
+
+PJ_BEGIN_DECL
+
+/** Typedef for client registration data. */
+typedef struct pjsip_regc pjsip_regc;
+
+/** Maximum contacts in registration. */
+#define PJSIP_REGC_MAX_CONTACT 10
+
+/** Expiration not specified. */
+#define PJSIP_REGC_EXPIRATION_NOT_SPECIFIED ((pj_uint32_t)0xFFFFFFFFUL)
+
+/** Buffer to hold all contacts. */
+#define PJSIP_REGC_CONTACT_BUF_SIZE 512
+
+/** Structure to hold parameters when calling application's callback.
+ * The application's callback is called when the client registration process
+ * has finished.
+ */
+struct pjsip_regc_cbparam
+{
+ pjsip_regc *regc; /**< Client registration structure. */
+ void *token; /**< Arbitrary token set by application */
+
+ /** Error status. If this value is non-PJ_SUCCESS, some error has occured.
+ * Note that even when this contains PJ_SUCCESS the registration might
+ * have failed; in this case the \a code field will contain non
+ * successful (non-2xx status class) code
+ */
+ pj_status_t status;
+ int code; /**< SIP status code received. */
+ pj_str_t reason; /**< SIP reason phrase received. */
+ pjsip_rx_data *rdata; /**< The complete received response. */
+ int expiration;/**< Next expiration interval. */
+ int contact_cnt;/**<Number of contacts in response. */
+ pjsip_contact_hdr *contact[PJSIP_REGC_MAX_CONTACT]; /**< Contacts. */
+};
+
+
+/** Type declaration for callback to receive registration result. */
+typedef void pjsip_regc_cb(struct pjsip_regc_cbparam *param);
+
+/**
+ * Client registration information.
+ */
+struct pjsip_regc_info
+{
+ pj_str_t server_uri; /**< Server URI, */
+ pj_str_t client_uri; /**< Client URI (From header). */
+ pj_bool_t is_busy; /**< Have pending transaction? */
+ pj_bool_t auto_reg; /**< Will register automatically? */
+ int interval; /**< Registration interval (seconds). */
+ int next_reg; /**< Time until next registration (seconds). */
+};
+
+/**
+ * @see pjsip_regc_info
+ */
+typedef struct pjsip_regc_info pjsip_regc_info;
+
+
+/**
+ * Get the module instance for client registration module.
+ *
+ * @return client registration module.
+ */
+PJ_DECL(pjsip_module*) pjsip_regc_get_module(void);
+
+
+/**
+ * Create client registration structure.
+ *
+ * @param endpt Endpoint, used to allocate pool from.
+ * @param token A data to be associated with the client registration struct.
+ * @param cb Pointer to callback function to receive registration status.
+ * @param p_regc Pointer to receive client registration structure.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token,
+ pjsip_regc_cb *cb,
+ pjsip_regc **p_regc);
+
+
+/**
+ * Destroy client registration structure. If a registration transaction is
+ * in progress, then the structure will be deleted only after a final response
+ * has been received, and in this case, the callback won't be called.
+ *
+ * @param regc The client registration structure.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc);
+
+/**
+ * Get registration info.
+ *
+ * @param regc The client registration structure.
+ * @param info Client registration info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_get_info( pjsip_regc *regc,
+ pjsip_regc_info *info );
+
+
+/**
+ * Get the memory pool associated with a registration client handle.
+ *
+ * @param regc The client registration structure.
+ * @return pool handle.
+ */
+PJ_DECL(pj_pool_t*) pjsip_regc_get_pool(pjsip_regc *regc);
+
+/**
+ * Initialize client registration structure with various information needed to
+ * perform the registration.
+ *
+ * @param regc The client registration structure.
+ * @param srv_url Server URL.
+ * @param from_url The person performing the registration, must be a SIP URL type.
+ * @param to_url The address of record for which the registration is targetd, must
+ * be a SIP/SIPS URL.
+ * @param ccnt Number of contacts in the array.
+ * @param contact Array of contacts, each contact item must be formatted
+ * as described in RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * @param expires Default expiration interval (in seconds) to be applied for
+ * contact URL that doesn't have expiration settings. If the
+ * value PJSIP_REGC_EXPIRATION_NOT_SPECIFIED is given, then
+ * no default expiration will be applied.
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_init(pjsip_regc *regc,
+ const pj_str_t *srv_url,
+ const pj_str_t *from_url,
+ const pj_str_t *to_url,
+ int ccnt,
+ const pj_str_t contact[],
+ pj_uint32_t expires);
+
+
+/**
+ * Set authentication credentials to use by this registration.
+ *
+ * @param regc The registration structure.
+ * @param count Number of credentials in the array.
+ * @param cred Array of credentials.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc,
+ int count,
+ const pjsip_cred_info cred[] );
+
+/**
+ * Set authentication preference.
+ *
+ * @param regc The registration structure.
+ * @param pref Authentication preference.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_set_prefs( pjsip_regc *regc,
+ const pjsip_auth_clt_pref *pref);
+
+/**
+ * Set route set to be used for outgoing requests.
+ *
+ * @param regc The client registration structure.
+ * @param route_set List containing Route headers.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_set_route_set(pjsip_regc *regc,
+ const pjsip_route_hdr*route_set);
+
+
+/**
+ * Lock/bind client registration to a specific transport/listener.
+ * This is optional, as normally transport will be selected automatically
+ * based on the destination of requests upon resolver completion.
+ * When the client registration is explicitly bound to the specific
+ * transport/listener, all UAC transactions originated by the client
+ * registration will use the specified transport/listener when sending
+ * outgoing requests.
+ *
+ * Note that this doesn't affect the Contact header set for this client
+ * registration. Application must manually update the Contact header if
+ * necessary, to adjust the address according to the transport being
+ * selected.
+ *
+ * @param regc The client registration instance.
+ * @param sel Transport selector containing the specification of
+ * transport or listener to be used by this session
+ * to send requests.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_set_transport(pjsip_regc *regc,
+ const pjsip_tpselector *sel);
+
+
+/**
+ * Add headers to be added to outgoing REGISTER requests.
+ *
+ * @param regc The client registration structure.
+ * @param hdr_list List containing SIP headers to be added for all outgoing
+ * REGISTER requests.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_add_headers(pjsip_regc *regc,
+ const pjsip_hdr *hdr_list);
+
+
+/**
+ * Create REGISTER request for the specified client registration structure.
+ *
+ * After successfull registration, application can inspect the contacts in
+ * the client registration structure to list what contacts are associaciated
+ * with the address of record being targeted in the registration.
+ *
+ * @param regc The client registration structure.
+ * @param autoreg If non zero, the library will automatically refresh the
+ * next registration until application unregister.
+ * @param p_tdata Pointer to receive the REGISTER request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Create REGISTER request to unregister the contacts that were previously
+ * registered by this client registration.
+ *
+ * @param regc The client registration structure.
+ * @param p_tdata Pointer to receive the REGISTER request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Create REGISTER request to unregister all contacts from server records.
+ * Note that this will unregister all registered contact for the AOR
+ * including contacts registered by other user agents. To only unregister
+ * contact registered by this client registration instance, use
+ * #pjsip_regc_unregister() instead.
+ *
+ * @param regc The client registration structure.
+ * @param p_tdata Pointer to receive the REGISTER request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_unregister_all(pjsip_regc *regc,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Update Contact details in the client registration structure. For each
+ * contact, if the contact is not found in existing contact, it will be
+ * added to the Contact list. If it matches existing contact, nothing
+ * will be added. This function will also mark existing contacts which
+ * are not specified in the new contact list as to be removed, by adding
+ * "expires=0" parameter to these contacts.
+ *
+ * Once the contact list has been updated, application must update the
+ * registration by creating a new REGISTER request and send it to the
+ * registrar. This request will contain both old and new contacts; the
+ * old contacts will have it's expires parameter set to zero to instruct
+ * the registrar to remove the bindings.
+ *
+ * @param regc The client registration structure.
+ * @param ccnt Number of contacts.
+ * @param contact Array of contacts, each contact item must be formatted
+ * as described in RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * @return PJ_SUCCESS if sucessfull.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_update_contact( pjsip_regc *regc,
+ int ccnt,
+ const pj_str_t contact[] );
+
+/**
+ * Update the expires value. The next REGISTER request will contain
+ * new expires value for the registration.
+ *
+ * @param regc The client registration structure.
+ * @param expires The new expires value.
+ * @return zero on successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_update_expires( pjsip_regc *regc,
+ pj_uint32_t expires );
+
+/**
+ * Sends outgoing REGISTER request.
+ * The process will complete asynchronously, and application
+ * will be notified via the callback when the process completes.
+ *
+ * @param regc The client registration structure.
+ * @param tdata Transmit data.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_REG_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_replaces.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_replaces.h
new file mode 100644
index 0000000..af3ce31
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_replaces.h
@@ -0,0 +1,301 @@
+/* $Id: sip_replaces.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_REPLACES_H__
+#define __PJSIP_REPLACES_H__
+
+
+/**
+ * @file sip_replaces.h
+ * @brief SIP Replaces support (RFC 3891 - SIP "Replaces" Header)
+ */
+#include <pjsip/sip_msg.h>
+
+/**
+ * @defgroup PJSIP_REPLACES SIP Replaces support (RFC 3891 - "Replaces" Header)
+ * @ingroup PJSIP_HIGH_UA
+ * @brief SIP Replaces support (RFC 3891 - "Replaces" Header)
+ * @{
+ *
+ * This module implements support for Replaces header in PJSIP. The Replaces
+ * specification is written in RFC 3891 - The Session Initiation Protocol (SIP)
+ * "Replaces" Header, and can be used to enable a variety of features,
+ * for example: "Attended Transfer" and "Call Pickup".
+ *
+ *
+ *
+ * \section PJSIP_REPLACES_USING_SEC Using PJSIP Replaces Support
+ *
+ * \subsection PJSIP_REPLACES_INIT_SUBSEC Initialization
+ *
+ * Application needs to call #pjsip_replaces_init_module() during application
+ * initialization stage to register "replaces" support in PJSIP.
+ *
+ *
+ *
+ * \subsection PJSIP_REPLACES_UAC_SUBSEC UAC Behavior: Sending a Replaces Header
+ *
+ * A User Agent that wishes to replace a single existing early or
+ * confirmed dialog with a new dialog of its own, MAY send the target
+ * User Agent an INVITE request containing a Replaces header field. The
+ * User Agent Client (UAC) places the Call-ID, to-tag, and from-tag
+ * information for the target dialog in a single Replaces header field
+ * and sends the new INVITE to the target.
+ *
+ * To initiate outgoing INVITE request with Replaces header, application
+ * would create the INVITE request with #pjsip_inv_invite(), then adds
+ * #pjsip_replaces_hdr instance into the request, filling up the Call-ID,
+ * To-tag, and From-tag properties of the header with the identification
+ * of the dialog to be replaced. Application may also optionally
+ * set the \a early_only property of the header to indicate that it only
+ * wants to replace early dialog.
+ *
+ * Note that when the outgoing INVITE request (with Replaces) is initiated
+ * from an incoming REFER request (as in Attended Call Transfer case),
+ * this process should be done rather more automatically by PJSIP. Upon
+ * receiving incoming incoming REFER request, normally these processes
+ * will be performed:
+ * - Application finds \a Refer-To header,
+ * - Application creates outgoing dialog/invite session, specifying
+ * the URI in the \a Refer-To header as the initial remote target,
+ * - The URI in the \a Refer-To header may contain header parameters such
+ * as \a Replaces and \a Require headers.
+ * - The dialog keeps the header fields in the header parameters
+ * of the URI, and the invite session would add these headers into
+ * the outgoing INVITE request. Because of this, the outgoing
+ * INVITE request will contain the \a Replaces and \a Require headers.
+ *
+ *
+ * For more information, please see the implementation of
+ * #pjsua_call_xfer_replaces() in \ref PJSUA_LIB source code.
+ *
+ *
+ * \subsection PJSIP_REPLACES_UAS_SUBSEC UAS Behavior: Receiving a Replaces Header
+ *
+ * The Replaces header contains information used to match an existing
+ * SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE
+ * with a Replaces header, the User Agent (UA) attempts to match this
+ * information with a confirmed or early dialog.
+ *
+ * In PJSIP, if application wants to process the Replaces header in the
+ * incoming INVITE request, it should call #pjsip_replaces_verify_request()
+ * before creating the INVITE session. The #pjsip_replaces_verify_request()
+ * function checks and verifies the request to see if Replaces request
+ * can be processed. To be more specific, it performs the following
+ * verification:
+ * - checks that Replaces header is present. If not, the function will
+ * return PJ_SUCCESS without doing anything.
+ * - checks that no duplicate Replaces headers are present, or otherwise
+ * it will return 400 "Bad Request" response.
+ * - checks for matching dialog and verifies that the invite session has
+ * the correct state, and may return 481 "Call/Transaction Does Not Exist",
+ * 603 "Declined", or 486 "Busy Here" according to the processing rules
+ * specified in RFC 3891.
+ * - if matching dialog with correct state is found, it will give PJ_SUCCESS
+ * status and return the matching dialog back to the application.
+ *
+ * The following pseudocode illustrates how application can process the
+ * incoming INVITE if it wants to support Replaces extension:
+ *
+ \code
+ // Incoming INVITE request handler
+ pj_bool_t on_rx_invite(pjsip_rx_data *rdata)
+ {
+ pjsip_dialog *dlg, *replaced_dlg;
+ pjsip_inv_session *inv;
+ pjsip_tx_data *response;
+ pj_status_t status;
+
+ // Check whether Replaces header is present in the request and process accordingly.
+ //
+ status = pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, &response);
+ if (status != PJ_SUCCESS) {
+ // Something wrong with Replaces request.
+ //
+ if (response) {
+ pjsip_endpt_send_response(endpt, rdata, response, NULL, NULL);
+ } else {
+ // Respond with 500 (Internal Server Error)
+ pjsip_endpt_respond_stateless(endpt, rdata, 500, NULL, NULL, NULL);
+ }
+ }
+
+ // Create UAS Invite session as usual.
+ //
+ status = pjsip_dlg_create_uas(.., rdata, .., &dlg);
+ ..
+ status = pjsip_inv_create_uas(dlg, .., &inv);
+
+ // Send initial 100 "Trying" to the INVITE request
+ //
+ status = pjsip_inv_initial_answer(inv, rdata, 100, ..., &response);
+ if (status == PJ_SUCCESS)
+ pjsip_inv_send_msg(inv, response);
+
+
+ // This is where processing is different between normal call
+ // (without Replaces) and call with Replaces.
+ //
+ if (replaced_dlg) {
+ pjsip_inv_session *replaced_inv;
+
+ // Always answer the new INVITE with 200, regardless whether
+ // the replaced call is in early or confirmed state.
+ //
+ status = pjsip_inv_answer(inv, 200, NULL, NULL, &response);
+ if (status == PJ_SUCCESS)
+ pjsip_inv_send_msg(inv, response);
+
+
+ // Get the INVITE session associated with the replaced dialog.
+ //
+ replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);
+
+
+ // Disconnect the "replaced" INVITE session.
+ //
+ status = pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL, &tdata);
+ if (status == PJ_SUCCESS && tdata)
+ status = pjsip_inv_send_msg(replaced_inv, tdata);
+
+
+ // It's up to application to associate the new INVITE session
+ // with the old (now terminated) session. For example, application
+ // may assign the same User Interface object for the new INVITE
+ // session.
+
+ } else {
+ // Process normal INVITE without Replaces.
+ ...
+ }
+ }
+
+ \endcode
+ *
+ *
+ * For a complete sample implementation, please see \a pjsua_call_on_incoming()
+ * function of \ref PJSUA_LIB in \a pjsua_call.c file.
+ *
+ *
+ * \section PJSIP_REPLACES_REFERENCE References
+ *
+ * References:
+ * - <A HREF="http://www.ietf.org/rfc/rfc3891.txt">RFC 3891: The Session
+ * Initiation Protocol (SIP) "Replaces" Header</A>
+ * - \ref PJSUA_XFER
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Declaration of SIP Replaces header (RFC 3891).
+ */
+typedef struct pjsip_replaces_hdr
+{
+ /** Standard header field. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_replaces_hdr);
+
+ /** Call-Id */
+ pj_str_t call_id;
+
+ /** to-tag */
+ pj_str_t to_tag;
+
+ /** from-tag */
+ pj_str_t from_tag;
+
+ /** early-only? */
+ pj_bool_t early_only;
+
+ /** Other parameters */
+ pjsip_param other_param;
+
+} pjsip_replaces_hdr;
+
+
+
+/**
+ * Initialize Replaces support in PJSIP. This would, among other things,
+ * register the header parser for Replaces header.
+ *
+ * @param endpt The endpoint instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_replaces_init_module(pjsip_endpoint *endpt);
+
+
+/**
+ * Create Replaces header.
+ *
+ * @param pool Pool to allocate the header instance from.
+ *
+ * @return An empty Replaces header instance.
+ */
+PJ_DECL(pjsip_replaces_hdr*) pjsip_replaces_hdr_create(pj_pool_t *pool);
+
+
+/**
+ * Verify that incoming request with Replaces header can be processed.
+ * This function will perform all necessary checks according to RFC 3891
+ * Section 3 "User Agent Server Behavior: Receiving a Replaces Header".
+ *
+ * @param rdata The incoming request to be verified.
+ * @param p_dlg On return, it will be filled with the matching
+ * dialog.
+ * @param lock_dlg Specifies whether this function should acquire lock
+ * to the matching dialog. If yes (and should be yes!),
+ * then application will need to release the dialog's
+ * lock with #pjsip_dlg_dec_lock() when the function
+ * returns PJ_SUCCESS and the \a p_dlg parameter is filled
+ * with the dialog instance.
+ * @param p_tdata Upon error, it will be filled with the final response
+ * to be sent to the request sender.
+ *
+ * @return The function returns the following:
+ * - If the request doesn't contain Replaces header, the
+ * function returns PJ_SUCCESS and \a p_dlg parameter
+ * will be set to NULL.
+ * - If the request contains Replaces header and a valid,
+ * matching dialog is found, the function returns
+ * PJ_SUCCESS and \a p_dlg parameter will be set to the
+ * matching dialog instance.
+ * - Upon error condition (as described by RFC 3891), the
+ * function returns non-PJ_SUCCESS, and \a p_tdata
+ * parameter SHOULD be set with a final response message
+ * to be sent to the sender of the request.
+ */
+PJ_DECL(pj_status_t) pjsip_replaces_verify_request(pjsip_rx_data *rdata,
+ pjsip_dialog **p_dlg,
+ pj_bool_t lock_dlg,
+ pjsip_tx_data **p_tdata);
+
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJSIP_REPLACES_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_timer.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_timer.h
new file mode 100644
index 0000000..797129c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_timer.h
@@ -0,0 +1,262 @@
+/* $Id: sip_timer.h 2859 2009-08-11 16:26:20Z nanang $ */
+/*
+ * Copyright (C) 2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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 __PJSIP_TIMER_H__
+#define __PJSIP_TIMER_H__
+
+
+/**
+ * @file sip_timer.h
+ * @brief SIP Session Timers support (RFC 4028 - Session Timer in SIP)
+ */
+
+#include <pjsip-ua/sip_inv.h>
+#include <pjsip/sip_msg.h>
+
+/**
+ * @defgroup PJSIP_TIMER SIP Session Timers support (RFC 4028 - Session Timers in SIP)
+ * @ingroup PJSIP_HIGH_UA
+ * @brief SIP Session Timers support (RFC 4028 - Session Timers in SIP)
+ * @{
+ *
+ * \section PJSIP_TIMER_REFERENCE References
+ *
+ * References:
+ * - <A HREF="http://www.ietf.org/rfc/rfc4028.txt">RFC 4028: Session Timers
+ * in the Session Initiation Protocol (SIP)</A>
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Opaque declaration of Session Timers.
+ */
+typedef struct pjsip_timer pjsip_timer;
+
+
+/**
+ * This structure describes Session Timers settings in an invite session.
+ */
+typedef struct pjsip_timer_setting
+{
+ /**
+ * Specify minimum session expiration period, in seconds. Must not be
+ * lower than 90. Default is 90.
+ */
+ unsigned min_se;
+
+ /**
+ * Specify session expiration period, in seconds. Must not be lower than
+ * #min_se. Default is 1800.
+ */
+ unsigned sess_expires;
+
+} pjsip_timer_setting;
+
+
+/**
+ * SIP Session-Expires header (RFC 4028).
+ */
+typedef struct pjsip_sess_expires_hdr
+{
+ /** Standard header field. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_sess_expires_hdr);
+
+ /** Session expiration period */
+ unsigned sess_expires;
+
+ /** Refresher */
+ pj_str_t refresher;
+
+ /** Other parameters */
+ pjsip_param other_param;
+
+} pjsip_sess_expires_hdr;
+
+
+/**
+ * SIP Min-SE header (RFC 4028).
+ */
+typedef struct pjsip_min_se_hdr
+{
+ /** Standard header field. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_min_se_hdr);
+
+ /** Minimum session expiration period */
+ unsigned min_se;
+
+ /** Other parameters */
+ pjsip_param other_param;
+
+} pjsip_min_se_hdr;
+
+
+
+/**
+ * Initialize Session Timers module. This function must be called once during
+ * application initialization, to register this module to SIP endpoint.
+ *
+ * @param endpt The SIP endpoint instance.
+ *
+ * @return PJ_SUCCESS if module is successfully initialized.
+ */
+PJ_DECL(pj_status_t) pjsip_timer_init_module(pjsip_endpoint *endpt);
+
+
+/**
+ * Initialize Session Timers setting with default values.
+ *
+ * @param setting Session Timers setting to be initialized.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_timer_setting_default(pjsip_timer_setting *setting);
+
+
+/**
+ * Initialize Session Timers for an invite session. This function should be
+ * called by application to apply Session Timers setting, otherwise invite
+ * session will apply default setting to the Session Timers.
+ *
+ * @param inv The invite session.
+ * @param setting Session Timers setting, see @pjsip_timer_setting.
+ * If setting is NULL, default setting will be applied.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_timer_init_session(
+ pjsip_inv_session *inv,
+ const pjsip_timer_setting *setting);
+
+
+/**
+ * Create Session-Expires header.
+ *
+ * @param pool Pool to allocate the header instance from.
+ *
+ * @return An empty Session-Expires header instance.
+ */
+PJ_DECL(pjsip_sess_expires_hdr*) pjsip_sess_expires_hdr_create(
+ pj_pool_t *pool);
+
+
+/**
+ * Create Min-SE header.
+ *
+ * @param pool Pool to allocate the header instance from.
+ *
+ * @return An empty Min-SE header instance.
+ */
+PJ_DECL(pjsip_min_se_hdr*) pjsip_min_se_hdr_create(pj_pool_t *pool);
+
+
+/**
+ * Update outgoing request to insert Session Timers headers and also
+ * signal Session Timers capability in Supported and/or Require headers.
+ *
+ * This function will be called internally by the invite session if it
+ * detects that the session needs Session Timers support.
+ *
+ * @param inv The invite session.
+ * @param tdata Outgoing INVITE or UPDATE request.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_timer_update_req(pjsip_inv_session *inv,
+ pjsip_tx_data *tdata);
+
+
+/**
+ * Process Session Timers headers in incoming response, this function
+ * will only process incoming response with status code 422 (Session
+ * Interval Too Small) or 2xx (final response).
+ *
+ * This function will be called internally by the invite session if it
+ * detects that the session needs Session Timers support.
+ *
+ * @param inv The invite session.
+ * @param rdata Incoming response data.
+ * @param st_code Output buffer to store corresponding SIP status code
+ * when function returning non-PJ_SUCCESS.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_timer_process_resp(pjsip_inv_session *inv,
+ const pjsip_rx_data *rdata,
+ pjsip_status_code *st_code);
+
+
+/**
+ * Process Session Timers headers in incoming request, this function
+ * will only process incoming INVITE and UPDATE request.
+ *
+ * This function will be called internally by the invite session if it
+ * detects that the session needs Session Timers support.
+ *
+ * @param inv The invite session.
+ * @param rdata Incoming INVITE or UPDATE request.
+ * @param st_code Output buffer to store corresponding SIP status code
+ * when function returning non-PJ_SUCCESS.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_timer_process_req(pjsip_inv_session *inv,
+ const pjsip_rx_data *rdata,
+ pjsip_status_code *st_code);
+
+
+/**
+ * Update outgoing response to insert Session Timers headers and also
+ * signal Session Timers capability in Supported and/or Require headers.
+ * This function will only update outgoing response with status code
+ * 422 (Session Interval Too Small) or 2xx (final response).
+ *
+ * This function will be called internally by the invite session if it
+ * detects that the session needs Session Timers support.
+ *
+ * @param inv The invite session.
+ * @param tdata Outgoing 422/2xx response.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_timer_update_resp(pjsip_inv_session *inv,
+ pjsip_tx_data *tdata);
+
+/**
+ * End Session Timers in an invite session.
+ *
+ * This function will be called internally by the invite session if it
+ * detects that the session needs Session Timers support.
+ *
+ * @param inv The invite session.
+ *
+ * @return PJ_SUCCESS on successful.
+ */
+PJ_DECL(pj_status_t) pjsip_timer_end_session(pjsip_inv_session *inv);
+
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJSIP_TIMER_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_xfer.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_xfer.h
new file mode 100644
index 0000000..de9cf72
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_xfer.h
@@ -0,0 +1,208 @@
+/* $Id: sip_xfer.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_XFER_H__
+#define __PJSIP_XFER_H__
+
+
+
+/**
+ * @file sip_xfer.h
+ * @brief SIP Transfer (REFER, RFC 3515)
+ */
+#include <pjsip-simple/evsub.h>
+#include <pjsip/sip_msg.h>
+
+/**
+ * @defgroup PJSUA_XFER SIP REFER (RFC 3515) for Call Transfer etc.
+ * @ingroup PJSIP_HIGH_UA
+ * @brief SIP REFER dialog usage (call transfer, etc.)
+ * @{
+ *
+ * This describes a generic handling of SIP REFER request. The SIP REFER
+ * request is described in RFC 3515, and commonly used to perform call
+ * transfer functionality. Other types of SIP REFER usages are described
+ * in draft-worley-sip-many-refers-00 draft, for example:
+ * - Remote Dial: where UAC sends REFER to instruct REFER recipient to
+ * initiate an INVITE session to some target.
+ *
+ * A REFER request can be sent inside or outside existing dialog context,
+ * although for call transfer case, it is more common to send REFER inside
+ * existing INVITE session context. PJSIP supports both sending REFER request
+ * inside or outside dialog context.
+ *
+ * The REFER framework uses @ref PJSIP_EVENT_NOT to manage the event
+ * subscription created by the REFER request. Because of this, application
+ * must link with <b>pjsip-ua</b> AND <b>pjsip-simple</b> static libraries
+ * to use REFER functionality.
+ *
+ * Reference:
+ * - <A HREF="http://www.ietf.org/rfc/rfc3515.txt">RFC 3515: The Session
+ * Initiation Protocol (SIP) Refer Method</A>
+ * - @ref PJSIP_EVENT_NOT
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/** Declaration for REFER method constant. */
+PJ_DECL_DATA(const pjsip_method) pjsip_refer_method;
+
+/** Get REFER method constant */
+PJ_DECL(const pjsip_method*) pjsip_get_refer_method(void);
+
+
+/**
+ * Initialize the REFER subsystem.
+ * This currently does very little (only register REFER as supported method).
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_init_module(pjsip_endpoint *endpt);
+
+
+
+/**
+ * Create transferer (sender of REFER request).
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Pointer to callbacks to receive presence subscription
+ * events.
+ * @param p_evsub Pointer to receive the presence subscription
+ * session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_create_uac( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ pjsip_evsub **p_evsub );
+
+
+/**
+ * Create transferee (receiver of REFER request).
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Pointer to callbacks to receive presence subscription
+ * events.
+ * @param rdata The incoming SUBSCRIBE request that creates the event
+ * subscription.
+ * @param p_evsub Pointer to receive the presence subscription
+ * session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_create_uas( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ pjsip_rx_data *rdata,
+ pjsip_evsub **p_evsub );
+
+/**
+ * Call this function to create request to initiate REFER subscription,
+ * to refresh subscription, or to unsubscribe. For request other than
+ * the initial REFER request, "refer_to_uri" argument may be NULL.
+ *
+ * @param sub Client subscription instance.
+ * @param refer_to_uri URI to be put to the Refer-To header. This argument
+ * may be NULL for subsequent REFER requests.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_initiate( pjsip_evsub *sub,
+ const pj_str_t *refer_to_uri,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Accept the incoming REFER request by sending 2xx response.
+ *
+ * @param sub Server subscription instance.
+ * @param rdata The incoming subscription request message.
+ * @param st_code Status code, which MUST be 2xx.
+ * @param hdr_list Optional list of headers to be added in the response.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_accept( pjsip_evsub *sub,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pjsip_hdr *hdr_list );
+
+
+/**
+ * For notifier, create NOTIFY request to subscriber, and set the state
+ * of the subscription.
+ *
+ * @param sub The server subscription (notifier) instance.
+ * @param state New state to set.
+ * @param xfer_st_code The call status code to be reported with the NOTIFY
+ * request.
+ * @param xfer_st_text Optional call status text to be reported with the
+ * NOTIFY request. If the value is NULL, default
+ * status text will be used.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_notify( pjsip_evsub *sub,
+ pjsip_evsub_state state,
+ int xfer_st_code,
+ const pj_str_t *xfer_st_text,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Create NOTIFY request to reflect current subscription status. Application
+ * can only call this function after it has sent NOTIFY before.
+ * This will also re-send the last "message/sipfrag" body that was sent
+ * in the previous NOTIFY.
+ *
+ * @param sub Server subscription object.
+ * @param p_tdata Pointer to receive request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_current_notify( pjsip_evsub *sub,
+ pjsip_tx_data **p_tdata );
+
+
+
+/**
+ * Send request message that was previously created with initiate(), notify(),
+ * or current_notify(). Application may also send request created with other
+ * functions, e.g. authentication. But the request MUST be either request
+ * that creates/refresh subscription or NOTIFY request.
+ *
+ *
+ * @param sub The event subscription object.
+ * @param tdata Request message to be send.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_send_request( pjsip_evsub *sub,
+ pjsip_tx_data *tdata);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_XFER_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip.h
new file mode 100644
index 0000000..b595288
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip.h
@@ -0,0 +1,60 @@
+/* $Id: pjsip.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_H__
+#define __PJSIP_H__
+
+/* Base types. */
+#include <pjsip/sip_types.h>
+#include <pjsip/sip_errno.h>
+
+/* Messaging and parsing. */
+#include <pjsip/sip_uri.h>
+#include <pjsip/sip_tel_uri.h>
+#include <pjsip/sip_msg.h>
+#include <pjsip/sip_parser.h>
+
+/* Core */
+#include <pjsip/sip_event.h>
+#include <pjsip/sip_module.h>
+#include <pjsip/sip_endpoint.h>
+#include <pjsip/sip_util.h>
+
+/* Transport layer */
+#include <pjsip/sip_transport.h>
+#include <pjsip/sip_transport_udp.h>
+#include <pjsip/sip_transport_loop.h>
+#include <pjsip/sip_transport_tcp.h>
+#include <pjsip/sip_transport_tls.h>
+#include <pjsip/sip_resolve.h>
+
+/* Authentication. */
+#include <pjsip/sip_auth.h>
+#include <pjsip/sip_auth_aka.h>
+
+/* Transaction layer. */
+#include <pjsip/sip_transaction.h>
+
+/* UA Layer. */
+#include <pjsip/sip_ua_layer.h>
+#include <pjsip/sip_dialog.h>
+
+
+#endif /* __PJSIP_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/print_util.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/print_util.h
new file mode 100644
index 0000000..76dbc9f
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/print_util.h
@@ -0,0 +1,141 @@
+/* $Id: print_util.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_PRINT_H__
+#define __PJSIP_PRINT_H__
+
+#define copy_advance_check(buf,str) \
+ do { \
+ if ((str).slen >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf, (str).ptr, (str).slen); \
+ buf += (str).slen; \
+ } while (0)
+
+#define copy_advance_pair_check(buf,str1,len1,str2) \
+ do { \
+ if (str2.slen) { \
+ printed = len1+str2.slen; \
+ if (printed >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf,str1,len1); \
+ pj_memcpy(buf+len1, str2.ptr, str2.slen); \
+ buf += printed; \
+ } \
+ } while (0)
+
+#define copy_advance_pair_quote_check(buf,str1,len1,str2,quotebegin,quoteend) \
+ do { \
+ if (str2.slen) { \
+ printed = len1+str2.slen+2; \
+ if (printed >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf,str1,len1); \
+ *(buf+len1)=quotebegin; \
+ pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \
+ *(buf+printed-1) = quoteend; \
+ buf += printed; \
+ } \
+ } while (0)
+
+#define copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend) \
+ do { \
+ printed = len1+str2.slen+2; \
+ if (printed >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf,str1,len1); \
+ *(buf+len1)=quotebegin; \
+ pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \
+ *(buf+printed-1) = quoteend; \
+ buf += printed; \
+ } while (0)
+
+#define copy_advance_pair_escape(buf,str1,len1,str2,unres) \
+ do { \
+ if (str2.slen) { \
+ if (len1+str2.slen >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf,str1,len1); \
+ printed=pj_strncpy2_escape(buf+len1,&str2,(endbuf-buf-len1),&unres);\
+ if (printed < 0) return -1; \
+ buf += (printed+len1); \
+ } \
+ } while (0)
+
+
+#define copy_advance_no_check(buf,str) \
+ do { \
+ pj_memcpy(buf, (str).ptr, (str).slen); \
+ buf += (str).slen; \
+ } while (0)
+
+#define copy_advance_escape(buf,str,unres) \
+ do { \
+ printed = \
+ pj_strncpy2_escape(buf, &(str), (endbuf-buf), &(unres)); \
+ if (printed < 0) return -1; \
+ buf += printed; \
+ } while (0)
+
+#define copy_advance_pair_no_check(buf,str1,len1,str2) \
+ if (str2.slen) { \
+ pj_memcpy(buf,str1,len1); \
+ pj_memcpy(buf+len1, str2.ptr, str2.slen); \
+ buf += len1+str2.slen; \
+ }
+
+#define copy_advance copy_advance_check
+#define copy_advance_pair copy_advance_pair_check
+
+#define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \
+ do { \
+ if (str2.slen && *str2.ptr!=quotebegin) \
+ copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \
+ else \
+ copy_advance_pair(buf,str1,len1,str2); \
+ } while (0)
+
+/*
+ * Internal type declarations.
+ */
+typedef void* (*pjsip_hdr_clone_fptr)(pj_pool_t *, const void*);
+typedef int (*pjsip_hdr_print_fptr)(void *hdr, char *buf, pj_size_t len);
+
+typedef struct pjsip_hdr_name_info_t
+{
+ char *name;
+ unsigned name_len;
+ char *sname;
+} pjsip_hdr_name_info_t;
+
+extern const pjsip_hdr_name_info_t pjsip_hdr_names[];
+
+PJ_INLINE(void) init_hdr(void *hptr, pjsip_hdr_e htype, void *vptr)
+{
+ pjsip_hdr *hdr = (pjsip_hdr*) hptr;
+ hdr->type = htype;
+ hdr->name.ptr = pjsip_hdr_names[htype].name;
+ hdr->name.slen = pjsip_hdr_names[htype].name_len;
+ if (pjsip_hdr_names[htype].sname) {
+ hdr->sname.ptr = pjsip_hdr_names[htype].sname;
+ hdr->sname.slen = 1;
+ } else {
+ hdr->sname = hdr->name;
+ }
+ hdr->vptr = (pjsip_hdr_vptr*) vptr;
+ pj_list_init(hdr);
+}
+
+#endif /* __PJSIP_PRINT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth.h
new file mode 100644
index 0000000..09c8379
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth.h
@@ -0,0 +1,495 @@
+/* $Id: sip_auth.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_AUTH_SIP_AUTH_H__
+#define __PJSIP_AUTH_SIP_AUTH_H__
+
+/**
+ * @file pjsip_auth.h
+ * @brief SIP Authorization Module.
+ */
+
+#include <pjsip/sip_config.h>
+#include <pjsip/sip_auth_msg.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @addtogroup PJSIP_AUTH
+ * @ingroup PJSIP_CORE
+ * @brief Client and server side authentication framework.
+ */
+
+/**
+ * @defgroup PJSIP_AUTH_API Authentication API's
+ * @ingroup PJSIP_AUTH
+ * @brief Structures and functions to perform authentication.
+ * @{
+ */
+
+/** Length of digest string. */
+#define PJSIP_MD5STRLEN 32
+
+
+/** Type of data in the credential information in #pjsip_cred_info. */
+typedef enum pjsip_cred_data_type
+{
+ PJSIP_CRED_DATA_PLAIN_PASSWD=0, /**< Plain text password. */
+ PJSIP_CRED_DATA_DIGEST =1, /**< Hashed digest. */
+
+ PJSIP_CRED_DATA_EXT_AKA =16 /**< Extended AKA info is available */
+
+} pjsip_cred_data_type;
+
+/** Authentication's quality of protection (qop) type. */
+typedef enum pjsip_auth_qop_type
+{
+ PJSIP_AUTH_QOP_NONE, /**< No quality of protection. */
+ PJSIP_AUTH_QOP_AUTH, /**< Authentication. */
+ PJSIP_AUTH_QOP_AUTH_INT, /**< Authentication with integrity protection. */
+ PJSIP_AUTH_QOP_UNKNOWN /**< Unknown protection. */
+} pjsip_auth_qop_type;
+
+
+/**
+ * Type of callback function to create authentication response.
+ * Application can specify this callback in \a cb field of the credential info
+ * (#pjsip_cred_info) and specifying PJSIP_CRED_DATA_DIGEST_CALLBACK as
+ * \a data_type. When this function is called, most of the fields in the
+ * \a auth authentication response will have been filled by the framework.
+ * Application normally should just need to calculate the response digest
+ * of the authentication response.
+ *
+ * @param pool Pool to allocate memory from if application needs to.
+ * @param chal The authentication challenge sent by server in 401
+ * or 401 response, in either Proxy-Authenticate or
+ * WWW-Authenticate header.
+ * @param cred The credential that has been selected by the framework
+ * to authenticate against the challenge.
+ * @param auth The authentication response which application needs to
+ * calculate the response digest.
+ *
+ * @return Application may return non-PJ_SUCCESS to abort the
+ * authentication process. When this happens, the
+ * framework will return failure to the original function
+ * that requested authentication.
+ */
+typedef pj_status_t (*pjsip_cred_cb)(pj_pool_t *pool,
+ const pjsip_digest_challenge *chal,
+ const pjsip_cred_info *cred,
+ const pj_str_t *method,
+ pjsip_digest_credential *auth);
+
+
+/**
+ * This structure describes credential information.
+ * A credential information is a static, persistent information that identifies
+ * username and password required to authorize to a specific realm.
+ *
+ * Note that since PJSIP 0.7.0.1, it is possible to make a credential that is
+ * valid for any realms, by setting the realm to star/wildcard character,
+ * i.e. realm = pj_str("*");.
+ */
+struct pjsip_cred_info
+{
+ pj_str_t realm; /**< Realm. Use "*" to make a credential that
+ can be used to authenticate against any
+ challenges. */
+ pj_str_t scheme; /**< Scheme (e.g. "digest"). */
+ pj_str_t username; /**< User name. */
+ int data_type; /**< Type of data (0 for plaintext passwd). */
+ pj_str_t data; /**< The data, which can be a plaintext
+ password or a hashed digest. */
+
+ /** Extended data */
+ union {
+ /** Digest AKA credential information. Note that when AKA credential
+ * is being used, the \a data field of this #pjsip_cred_info is
+ * not used, but it still must be initialized to an empty string.
+ * Please see \ref PJSIP_AUTH_AKA_API for more information.
+ */
+ struct {
+ pj_str_t k; /**< Permanent subscriber key. */
+ pj_str_t op; /**< Operator variant key. */
+ pj_str_t amf; /**< Authentication Management Field */
+ pjsip_cred_cb cb; /**< Callback to create AKA digest. */
+ } aka;
+
+ } ext;
+};
+
+/**
+ * This structure describes cached value of previously sent Authorization
+ * or Proxy-Authorization header. The authentication framework keeps a list
+ * of this structure and will resend the same header to the same server
+ * as long as the method, uri, and nonce stays the same.
+ */
+typedef struct pjsip_cached_auth_hdr
+{
+ /** Standard list member */
+ PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth_hdr);
+
+ pjsip_method method; /**< To quickly see the method. */
+ pjsip_authorization_hdr *hdr; /**< The cached header. */
+
+} pjsip_cached_auth_hdr;
+
+
+/**
+ * This structure describes authentication information for the specified
+ * realm. Each instance of this structure describes authentication "session"
+ * between this endpoint and remote server. This "session" information is
+ * usefull to keep information that persists for more than one challenge,
+ * such as nonce-count and cnonce value.
+ *
+ * Other than that, this structure also keeps the last authorization headers
+ * that have been sent in the cache list.
+ */
+typedef struct pjsip_cached_auth
+{
+ /** Standard list member */
+ PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth);
+
+ pj_str_t realm; /**< Realm. */
+ pj_bool_t is_proxy; /**< Server type (401/407) */
+ pjsip_auth_qop_type qop_value; /**< qop required by server. */
+ unsigned stale_cnt; /**< Number of stale retry. */
+#if PJSIP_AUTH_QOP_SUPPORT
+ pj_uint32_t nc; /**< Nonce count. */
+ pj_str_t cnonce; /**< Cnonce value. */
+#endif
+ pjsip_www_authenticate_hdr *last_chal; /**< Last challenge seen. */
+#if PJSIP_AUTH_HEADER_CACHING
+ pjsip_cached_auth_hdr cached_hdr;/**< List of cached header for
+ each method. */
+#endif
+
+} pjsip_cached_auth;
+
+
+/**
+ * This structure describes client authentication session preference.
+ * The preference can be set by calling #pjsip_auth_clt_set_prefs().
+ */
+typedef struct pjsip_auth_clt_pref
+{
+ /**
+ * If this flag is set, the authentication client framework will
+ * send an empty Authorization header in each initial request.
+ * Default is no.
+ */
+ pj_bool_t initial_auth;
+
+ /**
+ * Specify the algorithm to use when empty Authorization header
+ * is to be sent for each initial request (see above)
+ */
+ pj_str_t algorithm;
+
+} pjsip_auth_clt_pref;
+
+
+/**
+ * This structure describes client authentication sessions. It keeps
+ * all the information needed to authorize the client against all downstream
+ * servers.
+ */
+typedef struct pjsip_auth_clt_sess
+{
+ pj_pool_t *pool; /**< Pool to use. */
+ pjsip_endpoint *endpt; /**< Endpoint where this belongs. */
+ pjsip_auth_clt_pref pref; /**< Preference/options. */
+ unsigned cred_cnt; /**< Number of credentials. */
+ pjsip_cred_info *cred_info; /**< Array of credential information*/
+ pjsip_cached_auth cached_auth; /**< Cached authorization info. */
+
+} pjsip_auth_clt_sess;
+
+
+/**
+ * Duplicate a credential info.
+ *
+ * @param pool The memory pool.
+ * @param dst Destination credential.
+ * @param src Source credential.
+ */
+PJ_DECL(void) pjsip_cred_info_dup(pj_pool_t *pool,
+ pjsip_cred_info *dst,
+ const pjsip_cred_info *src);
+
+/**
+ * Type of function to lookup credential for the specified name.
+ *
+ * @param pool Pool to initialize the credential info.
+ * @param realm Realm to find the account.
+ * @param acc_name Account name to look for.
+ * @param cred_info The structure to put the credential when it's found.
+ *
+ * @return The function MUST return PJ_SUCCESS when it found
+ * a correct credential for the specified account and
+ * realm. Otherwise it may return PJSIP_EAUTHACCNOTFOUND
+ * or PJSIP_EAUTHACCDISABLED.
+ */
+typedef pj_status_t pjsip_auth_lookup_cred( pj_pool_t *pool,
+ const pj_str_t *realm,
+ const pj_str_t *acc_name,
+ pjsip_cred_info *cred_info );
+
+/** Flag to specify that server is a proxy. */
+#define PJSIP_AUTH_SRV_IS_PROXY 1
+
+/**
+ * This structure describes server authentication information.
+ */
+typedef struct pjsip_auth_srv
+{
+ pj_str_t realm; /**< Realm to serve. */
+ pj_bool_t is_proxy; /**< Will issue 407 instead of 401 */
+ pjsip_auth_lookup_cred *lookup; /**< Lookup function. */
+
+} pjsip_auth_srv;
+
+
+/**
+ * Initialize client authentication session data structure, and set the
+ * session to use pool for its subsequent memory allocation. The argument
+ * options should be set to zero for this PJSIP version.
+ *
+ * @param sess The client authentication session.
+ * @param endpt Endpoint where this session belongs.
+ * @param pool Pool to use.
+ * @param options Must be zero.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_init( pjsip_auth_clt_sess *sess,
+ pjsip_endpoint *endpt,
+ pj_pool_t *pool,
+ unsigned options);
+
+
+/**
+ * Clone client initialization session.
+ *
+ * @param pool Pool to use.
+ * @param sess Structure to put the duplicated session.
+ * @param rhs The client session to be cloned.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_clone( pj_pool_t *pool,
+ pjsip_auth_clt_sess *sess,
+ const pjsip_auth_clt_sess *rhs);
+
+/**
+ * Set the credentials to be used during the session. This will duplicate
+ * the specified credentials using client authentication's pool.
+ *
+ * @param sess The client authentication session.
+ * @param cred_cnt Number of credentials.
+ * @param c Array of credentials.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
+ int cred_cnt,
+ const pjsip_cred_info *c);
+
+
+/**
+ * Set the preference for the client authentication session.
+ *
+ * @param sess The client authentication session.
+ * @param p Preference.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess,
+ const pjsip_auth_clt_pref *p);
+
+
+/**
+ * Get the preference for the client authentication session.
+ *
+ * @param sess The client authentication session.
+ * @param p Pointer to receive the preference.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,
+ pjsip_auth_clt_pref *p);
+
+/**
+ * Initialize new request message with authorization headers.
+ * This function will put Authorization/Proxy-Authorization headers to the
+ * outgoing request message. If caching is enabled (PJSIP_AUTH_HEADER_CACHING)
+ * and the session has previously sent Authorization/Proxy-Authorization header
+ * with the same method, then the same Authorization/Proxy-Authorization header
+ * will be resent from the cache only if qop is not present. If the stack is
+ * configured to automatically generate next Authorization/Proxy-Authorization
+ * headers (PJSIP_AUTH_AUTO_SEND_NEXT flag), then new Authorization/Proxy-
+ * Authorization headers are calculated and generated when they are not present
+ * in the case or if authorization session has qop.
+ *
+ * If both PJSIP_AUTH_HEADER_CACHING flag and PJSIP_AUTH_AUTO_SEND_NEXT flag
+ * are not set, this function will do nothing. The stack then will only send
+ * Authorization/Proxy-Authorization to respond 401/407 response.
+ *
+ * @param sess The client authentication session.
+ * @param tdata The request message to be initialized.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
+ pjsip_tx_data *tdata );
+
+
+/**
+ * Call this function when a transaction failed with 401 or 407 response.
+ * This function will reinitialize the original request message with the
+ * authentication challenge found in the response message, and add the
+ * new authorization header in the authorization cache.
+ *
+ * Note that upon return the reference counter of the new transmit data
+ * will be set to 1.
+ *
+ * @param sess The client authentication session.
+ * @param rdata The response message containing 401/407 status.
+ * @param old_request The original request message, which will be re-
+ * created with authorization info.
+ * @param new_request Pointer to receive new request message which
+ * will contain all required authorization headers.
+ *
+ * @return PJ_SUCCESS if new request can be successfully
+ * created to respond all the authentication
+ * challenges.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
+ const pjsip_rx_data *rdata,
+ pjsip_tx_data *old_request,
+ pjsip_tx_data **new_request );
+
+/**
+ * Initialize server authorization session data structure to serve the
+ * specified realm and to use lookup_func function to look for the credential
+ * info.
+ *
+ * @param pool Pool used to initialize the authentication server.
+ * @param auth_srv The authentication server structure.
+ * @param realm Realm to be served by the server.
+ * @param lookup Account lookup function.
+ * @param options Options, bitmask of:
+ * - PJSIP_AUTH_SRV_IS_PROXY: to specify that the server
+ * will authorize clients as a proxy server (instead of
+ * as UAS), which means that Proxy-Authenticate will
+ * be used instead of WWW-Authenticate.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_srv_init( pj_pool_t *pool,
+ pjsip_auth_srv *auth_srv,
+ const pj_str_t *realm,
+ pjsip_auth_lookup_cred *lookup,
+ unsigned options );
+
+
+/**
+ * Request the authorization server framework to verify the authorization
+ * information in the specified request in rdata.
+ *
+ * @param auth_srv The server authentication structure.
+ * @param rdata Incoming request to be authenticated.
+ * @param status_code When not null, it will be filled with suitable
+ * status code to be sent to the client.
+ *
+ * @return PJ_SUCCESS if request is successfully authenticated.
+ * Otherwise the function may return one of the
+ * following error codes:
+ * - PJSIP_EAUTHNOAUTH
+ * - PJSIP_EINVALIDAUTHSCHEME
+ * - PJSIP_EAUTHACCNOTFOUND
+ * - PJSIP_EAUTHACCDISABLED
+ * - PJSIP_EAUTHINVALIDREALM
+ * - PJSIP_EAUTHINVALIDDIGEST
+ */
+PJ_DECL(pj_status_t) pjsip_auth_srv_verify( pjsip_auth_srv *auth_srv,
+ pjsip_rx_data *rdata,
+ int *status_code );
+
+
+/**
+ * Add authentication challenge headers to the outgoing response in tdata.
+ * Application may specify its customized nonce and opaque for the challenge,
+ * or can leave the value to NULL to make the function fills them in with
+ * random characters.
+ *
+ * @param auth_srv The server authentication structure.
+ * @param qop Optional qop value.
+ * @param nonce Optional nonce value.
+ * @param opaque Optional opaque value.
+ * @param stale Stale indication.
+ * @param tdata The outgoing response message. The response must have
+ * 401 or 407 response code.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_srv_challenge( pjsip_auth_srv *auth_srv,
+ const pj_str_t *qop,
+ const pj_str_t *nonce,
+ const pj_str_t *opaque,
+ pj_bool_t stale,
+ pjsip_tx_data *tdata);
+
+/**
+ * Helper function to create MD5 digest out of the specified
+ * parameters.
+ *
+ * @param result String to store the response digest. This string
+ * must have been preallocated by caller with the
+ * buffer at least PJSIP_MD5STRLEN (32 bytes) in size.
+ * @param nonce Optional nonce.
+ * @param nc Nonce count.
+ * @param cnonce Optional cnonce.
+ * @param qop Optional qop.
+ * @param uri URI.
+ * @param realm Realm.
+ * @param cred_info Credential info.
+ * @param method SIP method.
+ */
+PJ_DECL(void) pjsip_auth_create_digest(pj_str_t *result,
+ const pj_str_t *nonce,
+ const pj_str_t *nc,
+ const pj_str_t *cnonce,
+ const pj_str_t *qop,
+ const pj_str_t *uri,
+ const pj_str_t *realm,
+ const pjsip_cred_info *cred_info,
+ const pj_str_t *method);
+
+/**
+ * @}
+ */
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_AUTH_SIP_AUTH_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_aka.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_aka.h
new file mode 100644
index 0000000..8042dcc
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_aka.h
@@ -0,0 +1,213 @@
+/* $Id: sip_auth_aka.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_AUTH_SIP_AUTH_AKA_H__
+#define __PJSIP_AUTH_SIP_AUTH_AKA_H__
+
+/**
+ * @file sip_auth_aka.h
+ * @brief SIP Digest AKA Authorization Module.
+ */
+
+#include <pjsip/sip_auth.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_AUTH_AKA_API Digest AKAv1 and AKAv2 Authentication API
+ * @ingroup PJSIP_AUTH_API
+ * @brief Digest AKAv1 and AKAv2 Authentication API
+ * @{
+ *
+ * This module implements HTTP digest authentication using Authentication
+ * and Key Agreement (AKA) version 1 and version 2 (AKAv1-MD5 and AKAv2-MD5),
+ * as specified in RFC 3310 and RFC 4169. SIP AKA authentication is used
+ * by 3GPP and IMS systems.
+ *
+ * @section pjsip_aka_using Using Digest AKA Authentication
+ *
+ * Support for digest AKA authentication is currently made optional, so
+ * application needs to declare \a PJSIP_HAS_DIGEST_AKA_AUTH to non-zero
+ * in <tt>config_site.h</tt> to enable AKA support:
+ *
+ @code
+ #define PJSIP_HAS_DIGEST_AKA_AUTH 1
+ @endcode
+
+ *
+ * In addition, application would need to link with <b>libmilenage</b>
+ * library from \a third_party directory.
+ *
+ * Application then specifies digest AKA credential by initializing the
+ * authentication credential as follows:
+ *
+ @code
+
+ pjsip_cred_info cred;
+
+ pj_bzero(&cred, sizeof(cred));
+
+ cred.scheme = pj_str("Digest");
+ cred.realm = pj_str("ims-domain.test");
+ cred.username = pj_str("user@ims-domain.test");
+ cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD | PJSIP_CRED_DATA_EXT_AKA;
+ cred.data = pj_str("password");
+
+ // AKA extended info
+ cred.ext.aka.k = pj_str("password");
+ cred.ext.aka.cb = &pjsip_auth_create_aka_response
+
+ @endcode
+ *
+ * Description:
+ * - To support AKA, application adds \a PJSIP_CRED_DATA_EXT_AKA flag in the
+ * \a data_type field. This indicates that extended information specific to
+ * AKA authentication is available in the credential, and that response
+ * digest computation will use the callback function instead of the usual MD5
+ * digest computation.
+ *
+ * - The \a scheme for the credential is "Digest".
+ *
+ * - The \a realm is the expected realm in the challenge. Application may
+ * also specify wildcard realm ("*") if it wishes to respond to any realms
+ * in the challenge.
+ *
+ * - The \a data field is optional. Application may fill this with the password
+ * if it wants to support both MD5 and AKA MD5 in a single credential. The
+ * pjsip_auth_create_aka_response() function will use this field if the
+ * challenge indicates "MD5" as the algorithm instead of "AKAv1-MD5" or
+ * "AKAv2-MD5".
+ *
+ * - The \a ext.aka.k field specifies the permanent subscriber key to be used
+ * for AKA authentication. Application may specify binary password containing
+ * NULL character in this key, since the length of the key is indicated in
+ * the \a slen field of the string.
+ *
+ * - The \a ext.aka.cb field specifies the callback function to calculate the
+ * response digest. Application can specify pjsip_auth_create_aka_response()
+ * in this field to use PJSIP's implementation, but it's free to provide
+ * it's own function.
+ *
+ * - Optionally application may set \a ext.aka.op and \a ext.aka.amf in the
+ * credential to specify AKA Operator variant key and AKA Authentication
+ * Management Field information.
+ */
+
+/**
+ * Length of Authentication Key (AK) in bytes.
+ */
+#define PJSIP_AKA_AKLEN 6
+
+/**
+ * Length of Authentication Management Field (AMF) in bytes.
+ */
+#define PJSIP_AKA_AMFLEN 2
+
+/**
+ * Length of AUTN in bytes.
+ */
+#define PJSIP_AKA_AUTNLEN 16
+
+/**
+ * Length of Confidentiality Key (CK) in bytes.
+ */
+#define PJSIP_AKA_CKLEN 16
+
+/**
+ * Length of Integrity Key (AK) in bytes.
+ */
+#define PJSIP_AKA_IKLEN 16
+
+/**
+ * Length of permanent/subscriber Key (K) in bytes.
+ */
+#define PJSIP_AKA_KLEN 16
+
+/**
+ * Length of AKA authentication code in bytes.
+ */
+#define PJSIP_AKA_MACLEN 8
+
+/**
+ * Length of operator key in bytes.
+ */
+#define PJSIP_AKA_OPLEN 16
+
+/**
+ * Length of random challenge (RAND) in bytes.
+ */
+#define PJSIP_AKA_RANDLEN 16
+
+/**
+ * Length of response digest in bytes.
+ */
+#define PJSIP_AKA_RESLEN 8
+
+/**
+ * Length of sequence number (SQN) in bytes.
+ */
+#define PJSIP_AKA_SQNLEN 6
+
+/**
+ * This function creates MD5, AKAv1-MD5, or AKAv2-MD5 response for
+ * the specified challenge in \a chal, according to the algorithm
+ * specified in the challenge, and based on the information in the
+ * credential \a cred.
+ *
+ * Application may register this function as \a ext.aka.cb field of
+ * #pjsip_cred_info structure to make PJSIP automatically call this
+ * function to calculate the response digest. To do so, it needs to
+ * add \a PJSIP_CRED_DATA_EXT_AKA flag in the \a data_type field of
+ * the credential, and fills up other AKA specific information in
+ * the credential.
+ *
+ * @param pool Pool to allocate memory.
+ * @param chal The authentication challenge sent by server in 401
+ * or 401 response, as either Proxy-Authenticate or
+ * WWW-Authenticate header.
+ * @param cred The credential to be used.
+ * @param method The request method.
+ * @param auth The digest credential where the digest response
+ * will be placed to. Upon calling this function, the
+ * nonce, nc, cnonce, qop, uri, and realm fields of
+ * this structure must have been set by caller. Upon
+ * return, the \a response field will be initialized
+ * by this function.
+ *
+ * @return PJ_SUCCESS if response has been created successfully.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_create_aka_response(
+ pj_pool_t *pool,
+ const pjsip_digest_challenge*chal,
+ const pjsip_cred_info *cred,
+ const pj_str_t *method,
+ pjsip_digest_credential *auth);
+
+
+/**
+ * @}
+ */
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_AUTH_SIP_AUTH_AKA_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_msg.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_msg.h
new file mode 100644
index 0000000..c99b171
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_msg.h
@@ -0,0 +1,252 @@
+/* $Id: sip_auth_msg.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_AUTH_SIP_AUTH_MSG_H__
+#define __PJSIP_AUTH_SIP_AUTH_MSG_H__
+
+#include <pjsip/sip_msg.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @addtogroup PJSIP_MSG_HDR
+ * @{
+ */
+
+/**
+ * Common credential structure represents common credential fields
+ * present in Authorization/Proxy-Authorization header.
+ */
+struct pjsip_common_credential
+{
+ pj_str_t realm; /**< Credential's realm. */
+ pjsip_param other_param; /**< Other parameters. */
+};
+
+/**
+ * @see pjsip_common_credential
+ */
+typedef struct pjsip_common_credential pjsip_common_credential;
+
+
+/**
+ * This structure describe credential used in Authorization and
+ * Proxy-Authorization header for digest authentication scheme.
+ */
+struct pjsip_digest_credential
+{
+ pj_str_t realm; /**< Realm of the credential */
+ pjsip_param other_param; /**< Other parameters. */
+ pj_str_t username; /**< Username parameter. */
+ pj_str_t nonce; /**< Nonce parameter. */
+ pj_str_t uri; /**< URI parameter. */
+ pj_str_t response; /**< Response digest. */
+ pj_str_t algorithm; /**< Algorithm. */
+ pj_str_t cnonce; /**< Cnonce. */
+ pj_str_t opaque; /**< Opaque value. */
+ pj_str_t qop; /**< Quality of protection. */
+ pj_str_t nc; /**< Nonce count. */
+};
+
+/**
+ * @see pjsip_digest_credential
+ */
+typedef struct pjsip_digest_credential pjsip_digest_credential;
+
+/**
+ * This structure describe credential used in Authorization and
+ * Proxy-Authorization header for PGP authentication scheme.
+ */
+struct pjsip_pgp_credential
+{
+ pj_str_t realm; /**< Realm. */
+ pjsip_param other_param; /**< Other parameters. */
+ pj_str_t version; /**< Version parameter. */
+ pj_str_t signature; /**< Signature parameter. */
+ pj_str_t signed_by; /**< Signed by parameter. */
+ pj_str_t nonce; /**< Nonce parameter. */
+};
+
+/**
+ * @see pjsip_pgp_credential
+ */
+typedef struct pjsip_pgp_credential pjsip_pgp_credential;
+
+/**
+ * This structure describes SIP Authorization header (and also SIP
+ * Proxy-Authorization header).
+ */
+struct pjsip_authorization_hdr
+{
+ /** Standard header fiends. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_authorization_hdr);
+
+ /** Authorization scheme. */
+ pj_str_t scheme;
+
+ /** Type of credentials, depending on the scheme. */
+ union
+ {
+ pjsip_common_credential common; /**< Common fields. */
+ pjsip_digest_credential digest; /**< Digest credentials. */
+ pjsip_pgp_credential pgp; /**< PGP credentials. */
+ } credential;
+};
+
+/**
+ * @see pjsip_authorization_hdr.
+ */
+typedef struct pjsip_authorization_hdr pjsip_authorization_hdr;
+
+/** SIP Proxy-Authorization header shares the same structure as SIP
+ Authorization header.
+ */
+typedef struct pjsip_authorization_hdr pjsip_proxy_authorization_hdr;
+
+/**
+ * Create SIP Authorization header.
+ * @param pool Pool where memory will be allocated from.
+ * @return SIP Authorization header.
+ */
+PJ_DECL(pjsip_authorization_hdr*)
+pjsip_authorization_hdr_create(pj_pool_t *pool);
+
+/**
+ * Create SIP Proxy-Authorization header.
+ * @param pool Pool where memory will be allocated from.
+ * @return SIP Proxy-Authorization header.
+ */
+PJ_DECL(pjsip_proxy_authorization_hdr*)
+pjsip_proxy_authorization_hdr_create(pj_pool_t *pool);
+
+
+/**
+ * This structure describes common fields in authentication challenge
+ * headers (WWW-Authenticate and Proxy-Authenticate).
+ */
+struct pjsip_common_challenge
+{
+ pj_str_t realm; /**< Realm for the challenge. */
+ pjsip_param other_param; /**< Other parameters. */
+};
+
+/**
+ * @see pjsip_common_challenge
+ */
+typedef struct pjsip_common_challenge pjsip_common_challenge;
+
+/**
+ * This structure describes authentication challenge used in Proxy-Authenticate
+ * or WWW-Authenticate for digest authentication scheme.
+ */
+struct pjsip_digest_challenge
+{
+ pj_str_t realm; /**< Realm for the challenge. */
+ pjsip_param other_param; /**< Other parameters. */
+ pj_str_t domain; /**< Domain. */
+ pj_str_t nonce; /**< Nonce challenge. */
+ pj_str_t opaque; /**< Opaque value. */
+ int stale; /**< Stale parameter. */
+ pj_str_t algorithm; /**< Algorithm parameter. */
+ pj_str_t qop; /**< Quality of protection. */
+};
+
+/**
+ * @see pjsip_digest_challenge
+ */
+typedef struct pjsip_digest_challenge pjsip_digest_challenge;
+
+/**
+ * This structure describes authentication challenge used in Proxy-Authenticate
+ * or WWW-Authenticate for PGP authentication scheme.
+ */
+struct pjsip_pgp_challenge
+{
+ pj_str_t realm; /**< Realm for the challenge. */
+ pjsip_param other_param; /**< Other parameters. */
+ pj_str_t version; /**< PGP version. */
+ pj_str_t micalgorithm; /**< micalgorithm parameter. */
+ pj_str_t pubalgorithm; /**< pubalgorithm parameter. */
+ pj_str_t nonce; /**< Nonce challenge. */
+};
+
+/**
+ * @see pjsip_pgp_challenge
+ */
+typedef struct pjsip_pgp_challenge pjsip_pgp_challenge;
+
+/**
+ * This structure describe SIP WWW-Authenticate header (Proxy-Authenticate
+ * header also uses the same structure).
+ */
+struct pjsip_www_authenticate_hdr
+{
+ /** Standard header fields. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_www_authenticate_hdr);
+
+ /** Authentication scheme */
+ pj_str_t scheme;
+
+ /** This union contains structures that are only relevant
+ depending on the value of the scheme being used.
+ */
+ union
+ {
+ pjsip_common_challenge common; /**< Common fields. */
+ pjsip_digest_challenge digest; /**< Digest challenge. */
+ pjsip_pgp_challenge pgp; /**< PGP challenge. */
+ } challenge;
+};
+
+/**
+ * WWW-Authenticate header.
+ */
+typedef struct pjsip_www_authenticate_hdr pjsip_www_authenticate_hdr;
+
+/**
+ * Proxy-Authenticate header.
+ */
+typedef struct pjsip_www_authenticate_hdr pjsip_proxy_authenticate_hdr;
+
+
+/**
+ * Create SIP WWW-Authenticate header.
+ *
+ * @param pool Pool where memory will be allocated from.
+ * @return SIP WWW-Authenticate header.
+ */
+PJ_DECL(pjsip_www_authenticate_hdr*)
+pjsip_www_authenticate_hdr_create(pj_pool_t *pool);
+
+/**
+ * Create SIP Proxy-Authenticate header.
+ *
+ * @param pool Pool where memory will be allocated from.
+ * @return SIP Proxy-Authenticate header.
+ */
+PJ_DECL(pjsip_proxy_authenticate_hdr*)
+pjsip_proxy_authenticate_hdr_create(pj_pool_t *pool);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_AUTH_SIP_AUTH_MSG_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_parser.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_parser.h
new file mode 100644
index 0000000..4c1bf13
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_parser.h
@@ -0,0 +1,73 @@
+/* $Id: sip_auth_parser.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_AUTH_SIP_AUTH_PARSER_H__
+#define __PJSIP_AUTH_SIP_AUTH_PARSER_H__
+
+/**
+ * @file sip_auth_parser.h
+ * @brief SIP Authorization Parser Module.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * Initialize and register authorization parser module.
+ * This will register parser handler for various Authorization related headers
+ * such as Authorization, WWW-Authenticate, Proxy-Authorizization, and
+ * Proxy-Authenticate headers.
+ *
+ * This function is called automatically by the main SIP parser.
+ *
+ * @return PJ_SUCCESS or the appropriate status code.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_init_parser(void);
+
+/**
+ * DeInitialize authorization parser module.
+ */
+PJ_DECL(void) pjsip_auth_deinit_parser();
+
+
+
+extern const pj_str_t pjsip_USERNAME_STR, /**< "username" string const. */
+ pjsip_REALM_STR, /**< "realm" string const. */
+ pjsip_NONCE_STR, /**< "nonce" string const. */
+ pjsip_URI_STR, /**< "uri" string const. */
+ pjsip_RESPONSE_STR, /**< "response" string const. */
+ pjsip_ALGORITHM_STR,/**< "algorithm" string const. */
+ pjsip_DOMAIN_STR, /**< "domain" string const. */
+ pjsip_STALE_STR, /**< "stale" string const. */
+ pjsip_QOP_STR, /**< "qop" string const. */
+ pjsip_CNONCE_STR, /**< "cnonce" string const. */
+ pjsip_OPAQUE_STR, /**< "opaque" string const. */
+ pjsip_NC_STR, /**< "nc" string const. */
+ pjsip_TRUE_STR, /**< "true" string const. */
+ pjsip_FALSE_STR, /**< "false" string const. */
+ pjsip_DIGEST_STR, /**< "digest" string const. */
+ pjsip_PGP_STR, /**< "pgp" string const. */
+ pjsip_MD5_STR, /**< "md5" string const. */
+ pjsip_AUTH_STR; /**< "auth" string const. */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_AUTH_SIP_AUTH_PARSER_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_autoconf.h.in b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_autoconf.h.in
new file mode 100644
index 0000000..28e689e
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_autoconf.h.in
@@ -0,0 +1,39 @@
+/* $Id: sip_autoconf.h.in 2973 2009-10-28 06:09:15Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_AUTOCONF_H__
+#define __PJSIP_SIP_AUTOCONF_H__
+
+/**
+ * @file sip_autoconf.h
+ * @brief Describes operating system specifics (automatically detected by
+ * autoconf)
+ */
+
+/*
+ * Enable/disable TLS transport, as configured by autoconf.
+ * But only do this if user doesn't explicitly configure in pj/config_site.h.
+ */
+/* Since 1.5, the default setting will follow PJ_HAS_SSL_SOCK setting. */
+//#ifndef PJSIP_HAS_TLS_TRANSPORT
+//#undef PJSIP_HAS_TLS_TRANSPORT
+//#endif
+
+#endif /* __PJSIP_SIP_AUTOCONF_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_config.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_config.h
new file mode 100644
index 0000000..b808adc
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_config.h
@@ -0,0 +1,924 @@
+/* $Id: sip_config.h 3019 2009-11-20 04:18:27Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_CONFIG_H__
+#define __PJSIP_SIP_CONFIG_H__
+
+/**
+ * @file sip_config.h
+ * @brief Compile time configuration.
+ */
+#include <pj/types.h>
+
+/**
+ * @defgroup PJSIP_CORE Core SIP Library
+ * @brief The core framework from which all other SIP components depends on.
+ *
+ * The PJSIP Core library only provides transport framework, event
+ * dispatching/module framework, and SIP message representation and
+ * parsing. It doesn't do anything usefull in itself!
+ *
+ * If application wants the stack to do anything usefull at all,
+ * it must registers @ref PJSIP_MOD to the core library. Examples
+ * of modules are @ref PJSIP_TRANSACT and @ref PJSUA_UA.
+ */
+
+/**
+ * @defgroup PJSIP_BASE Base Types
+ * @ingroup PJSIP_CORE
+ * @brief Basic PJSIP types and configurations.
+ */
+
+/**
+ * @defgroup PJSIP_CONFIG PJSIP Configurations/Settings
+ * @ingroup PJSIP_BASE
+ * @brief PJSIP compile time configurations.
+ * @{
+ */
+
+/*
+ * Include sip_autoconf.h if autoconf is used (PJ_AUTOCONF is set)
+ */
+#if defined(PJ_AUTOCONF)
+# include <pjsip/sip_autoconf.h>
+#endif
+
+PJ_BEGIN_DECL
+
+/**
+ * This structure describes PJSIP run-time configurations/settings.
+ * Application may use #pjsip_cfg() function to modify the settings
+ * before creating the stack.
+ */
+typedef struct pjsip_cfg_t
+{
+ /** Transaction layer settings. */
+ struct {
+
+ /** Maximum number of transactions. The value is initialized with
+ * PJSIP_MAX_TSX_COUNT
+ */
+ unsigned max_count;
+
+ /* Timeout values: */
+
+ /** Transaction T1 timeout, in msec. Default value is PJSIP_T1_TIMEOUT
+ */
+ unsigned t1;
+
+ /** Transaction T2 timeout, in msec. Default value is PJSIP_T2_TIMEOUT
+ */
+ unsigned t2;
+
+ /** Transaction completed timer for non-INVITE, in msec. Default value
+ * is PJSIP_T4_TIMEOUT
+ */
+ unsigned t4;
+
+ /** Transaction completed timer for INVITE, in msec. Default value is
+ * PJSIP_TD_TIMEOUT.
+ */
+ unsigned td;
+
+ } tsx;
+
+ /* Dialog layer settings .. TODO */
+
+ /** Client registration settings. */
+ struct {
+ /**
+ * Specify whether client registration should check for its
+ * registered contact in Contact header of successful REGISTER
+ * response to determine whether registration has been successful.
+ * This setting may be disabled if non-compliant registrar is unable
+ * to return correct Contact header.
+ *
+ * Default is PJSIP_REGISTER_CLIENT_CHECK_CONTACT
+ */
+ pj_bool_t check_contact;
+
+ /**
+ * Specify whether client registration should add "x-uid" extension
+ * parameter in all Contact URIs that it registers to assist the
+ * matching of Contact URIs in the 200/OK REGISTER response, in
+ * case the registrar is unable to return exact Contact URI in the
+ * 200/OK response.
+ *
+ * Default is PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM.
+ */
+ pj_bool_t add_xuid_param;
+
+ } regc;
+
+} pjsip_cfg_t;
+
+
+#ifdef PJ_DLL
+/**
+ * Get pjsip configuration instance. Application may modify the
+ * settings before creating the SIP endpoint and modules.
+ *
+ * @return Configuration instance.
+ */
+PJ_DECL(pjsip_cfg_t*) pjsip_cfg(void);
+
+#else /* PJ_DLL */
+
+extern pjsip_cfg_t pjsip_sip_cfg_var;
+
+/**
+ * Get pjsip configuration instance. Application may modify the
+ * settings before creating the SIP endpoint and modules.
+ *
+ * @return Configuration instance.
+ */
+PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
+{
+ return &pjsip_sip_cfg_var;
+}
+
+#endif /* PJ_DLL */
+
+
+/**
+ * Specify maximum transaction count in transaction hash table.
+ * For efficiency, the value should be 2^n-1 since it will be
+ * rounded up to 2^n.
+ *
+ * Default value is 1023
+ */
+#ifndef PJSIP_MAX_TSX_COUNT
+# define PJSIP_MAX_TSX_COUNT (1024-1)
+#endif
+
+/**
+ * Specify maximum number of dialogs in the dialog hash table.
+ * For efficiency, the value should be 2^n-1 since it will be
+ * rounded up to 2^n.
+ *
+ * Default value is 511.
+ */
+#ifndef PJSIP_MAX_DIALOG_COUNT
+# define PJSIP_MAX_DIALOG_COUNT (512-1)
+#endif
+
+
+/**
+ * Specify maximum number of transports.
+ * Default value is equal to maximum number of handles in ioqueue.
+ * See also PJSIP_TPMGR_HTABLE_SIZE.
+ */
+#ifndef PJSIP_MAX_TRANSPORTS
+# define PJSIP_MAX_TRANSPORTS (PJ_IOQUEUE_MAX_HANDLES)
+#endif
+
+
+/**
+ * Transport manager hash table size (must be 2^n-1).
+ * See also PJSIP_MAX_TRANSPORTS
+ */
+#ifndef PJSIP_TPMGR_HTABLE_SIZE
+# define PJSIP_TPMGR_HTABLE_SIZE 31
+#endif
+
+
+/**
+ * Specify maximum URL size.
+ * This constant is used mainly when printing the URL for logging purpose
+ * only.
+ */
+#ifndef PJSIP_MAX_URL_SIZE
+# define PJSIP_MAX_URL_SIZE 256
+#endif
+
+
+/**
+ * Specify maximum number of modules.
+ * This mainly affects the size of mod_data array in various components.
+ */
+#ifndef PJSIP_MAX_MODULE
+# define PJSIP_MAX_MODULE 32
+#endif
+
+
+/**
+ * Maximum packet length. We set it more than MTU since a SIP PDU
+ * containing presence information can be quite large (>1500).
+ */
+#ifndef PJSIP_MAX_PKT_LEN
+# define PJSIP_MAX_PKT_LEN 2000
+#endif
+
+
+/**
+ * RFC 3261 section 18.1.1:
+ * If a request is within 200 bytes of the path MTU, or if it is larger
+ * than 1300 bytes and the path MTU is unknown, the request MUST be sent
+ * using an RFC 2914 [43] congestion controlled transport protocol, such
+ * as TCP.
+ *
+ * Disable the behavior of automatic switching to TCP whenever UDP packet
+ * size exceeds the threshold defined in PJSIP_UDP_SIZE_THRESHOLD.
+ *
+ * Default is 0 (no).
+ */
+#ifndef PJSIP_DONT_SWITCH_TO_TCP
+# define PJSIP_DONT_SWITCH_TO_TCP 0
+#endif
+
+
+/**
+ * This setting controls the threshold of the UDP packet, which if it's
+ * larger than this value the request will be sent with TCP. This setting
+ * is useful only when PJSIP_DONT_SWITCH_TO_TCP is set to 0.
+ *
+ * Default is 1300 bytes.
+ */
+#ifndef PJSIP_UDP_SIZE_THRESHOLD
+# define PJSIP_UDP_SIZE_THRESHOLD 1300
+#endif
+
+
+/**
+ * Encode SIP headers in their short forms to reduce size. By default,
+ * SIP headers in outgoing messages will be encoded in their full names.
+ * If this option is enabled, then SIP headers for outgoing messages
+ * will be encoded in their short forms, to reduce message size.
+ * Note that this does not affect the ability of PJSIP to parse incoming
+ * SIP messages, as the parser always supports parsing both the long
+ * and short version of the headers.
+ *
+ * Note that there is also an undocumented variable defined in sip_msg.c
+ * to control whether compact form should be used for encoding SIP
+ * headers. The default value of this variable is PJSIP_ENCODE_SHORT_HNAME.
+ * To change PJSIP behavior during run-time, application can use the
+ * following construct:
+ *
+ \verbatim
+ extern pj_bool_t pjsip_use_compact_form;
+
+ // enable compact form
+ pjsip_use_compact_form = PJ_TRUE;
+ \endverbatim
+ *
+ * Default is 0 (no)
+ */
+#ifndef PJSIP_ENCODE_SHORT_HNAME
+# define PJSIP_ENCODE_SHORT_HNAME 0
+#endif
+
+
+/**
+ * Send Allow header in dialog establishing requests?
+ * RFC 3261 Allow header SHOULD be included in dialog establishing
+ * requests to inform remote agent about which SIP requests are
+ * allowed within dialog.
+ *
+ * Note that there is also an undocumented variable defined in sip_dialog.c
+ * to control whether Allow header should be included. The default value
+ * of this variable is PJSIP_INCLUDE_ALLOW_HDR_IN_DLG.
+ * To change PJSIP behavior during run-time, application can use the
+ * following construct:
+ *
+ \verbatim
+ extern pj_bool_t pjsip_include_allow_hdr_in_dlg;
+
+ // do not transmit Allow header
+ pjsip_include_allow_hdr_in_dlg = PJ_FALSE;
+ \endverbatim
+ *
+ * Default is 1 (Yes)
+ */
+#ifndef PJSIP_INCLUDE_ALLOW_HDR_IN_DLG
+# define PJSIP_INCLUDE_ALLOW_HDR_IN_DLG 1
+#endif
+
+
+/**
+ * Allow SIP modules removal or insertions during operation?
+ * If yes, then locking will be employed when endpoint need to
+ * access module.
+ */
+#ifndef PJSIP_SAFE_MODULE
+# define PJSIP_SAFE_MODULE 1
+#endif
+
+
+/**
+ * Perform Via sent-by checking as specified in RFC 3261 Section 18.1.2,
+ * which says that UAC MUST silently discard responses with Via sent-by
+ * containing values that the UAC doesn't recognize as its transport
+ * address.
+ *
+ * In PJSIP, this will cause response to be discarded and a message is
+ * written to the log, saying something like:
+ * "Dropping response Response msg 200/INVITE/cseq=608594373 (rdata00A99EF4)
+ * from 1.2.3.4:5060 because sent-by is mismatch"
+ *
+ * The default behavior is yes, but when the UA supports IP address change
+ * for the SIP transport, it will need to turn this checking off since
+ * when the transport address is changed between request is sent and
+ * response is received, the response will be discarded since its Via
+ * sent-by now contains address that is different than the transport
+ * address.
+ */
+#ifndef PJSIP_CHECK_VIA_SENT_BY
+# define PJSIP_CHECK_VIA_SENT_BY 1
+#endif
+
+
+/**
+ * If non-zero, SIP parser will unescape the escape characters ('%')
+ * in the original message, which means that it will modify the
+ * original message. Otherwise the parser will create a copy of
+ * the string and store the unescaped string to the new location.
+ *
+ * Unescaping in-place is faster, but less elegant (and it may
+ * break certain applications). So normally it's disabled, unless
+ * when benchmarking (to show off big performance).
+ *
+ * Default: 0
+ */
+#ifndef PJSIP_UNESCAPE_IN_PLACE
+# define PJSIP_UNESCAPE_IN_PLACE 0
+#endif
+
+
+/**
+ * This macro controls maximum numbers of ioqueue events to be processed
+ * in a single pjsip_endpt_handle_events() poll. When PJSIP detects that
+ * there are probably more events available from the network and total
+ * events so far is less than this value, PJSIP will call pj_ioqueue_poll()
+ * again to get more events.
+ *
+ * Value 1 works best for ioqueue with select() back-end, while for IOCP it is
+ * probably best to set this value equal to PJSIP_MAX_TIMED_OUT_ENTRIES
+ * since IOCP only processes one event at a time.
+ *
+ * Default: 1
+ */
+#ifndef PJSIP_MAX_NET_EVENTS
+# define PJSIP_MAX_NET_EVENTS 1
+#endif
+
+
+/**
+ * Max entries to process in timer heap per poll.
+ *
+ * Default: 10
+ */
+#ifndef PJSIP_MAX_TIMED_OUT_ENTRIES
+# define PJSIP_MAX_TIMED_OUT_ENTRIES 10
+#endif
+
+
+/**
+ * Idle timeout interval to be applied to transports with no usage
+ * before the transport is destroyed. Value is in seconds.
+ *
+ * Default: 600
+ */
+#ifndef PJSIP_TRANSPORT_IDLE_TIME
+# define PJSIP_TRANSPORT_IDLE_TIME 600
+#endif
+
+
+/**
+ * Maximum number of usages for a transport before a new transport is
+ * created. This only applies for ephemeral transports such as TCP.
+ *
+ * Currently this is not used.
+ *
+ * Default: -1
+ */
+#ifndef PJSIP_MAX_TRANSPORT_USAGE
+# define PJSIP_MAX_TRANSPORT_USAGE ((unsigned)-1)
+#endif
+
+
+/**
+ * The TCP incoming connection backlog number to be set in accept().
+ *
+ * Default: 5
+ *
+ * @see PJSIP_TLS_TRANSPORT_BACKLOG
+ */
+#ifndef PJSIP_TCP_TRANSPORT_BACKLOG
+# define PJSIP_TCP_TRANSPORT_BACKLOG 5
+#endif
+
+
+/**
+ * Set the interval to send keep-alive packet for TCP transports.
+ * If the value is zero, keep-alive will be disabled for TCP.
+ *
+ * Default: 90 (seconds)
+ *
+ * @see PJSIP_TCP_KEEP_ALIVE_DATA
+ */
+#ifndef PJSIP_TCP_KEEP_ALIVE_INTERVAL
+# define PJSIP_TCP_KEEP_ALIVE_INTERVAL 90
+#endif
+
+
+/**
+ * Set the payload of the TCP keep-alive packet.
+ *
+ * Default: CRLF
+ */
+#ifndef PJSIP_TCP_KEEP_ALIVE_DATA
+# define PJSIP_TCP_KEEP_ALIVE_DATA { "\r\n\r\n", 4 }
+#endif
+
+
+/**
+ * Set the interval to send keep-alive packet for TLS transports.
+ * If the value is zero, keep-alive will be disabled for TLS.
+ *
+ * Default: 90 (seconds)
+ *
+ * @see PJSIP_TLS_KEEP_ALIVE_DATA
+ */
+#ifndef PJSIP_TLS_KEEP_ALIVE_INTERVAL
+# define PJSIP_TLS_KEEP_ALIVE_INTERVAL 90
+#endif
+
+
+/**
+ * Set the payload of the TLS keep-alive packet.
+ *
+ * Default: CRLF
+ */
+#ifndef PJSIP_TLS_KEEP_ALIVE_DATA
+# define PJSIP_TLS_KEEP_ALIVE_DATA { "\r\n\r\n", 4 }
+#endif
+
+
+/**
+ * This macro specifies whether full DNS resolution should be used.
+ * When enabled, #pjsip_resolve() will perform asynchronous DNS SRV and
+ * A (or AAAA, when IPv6 is supported) resolution to resolve the SIP
+ * domain.
+ *
+ * Note that even when this setting is enabled, asynchronous DNS resolution
+ * will only be done when application calls #pjsip_endpt_create_resolver(),
+ * configure the nameservers with pj_dns_resolver_set_ns(), and configure
+ * the SIP endpoint's DNS resolver with #pjsip_endpt_set_resolver(). If
+ * these steps are not followed, the domain will be resolved with normal
+ * pj_gethostbyname() function.
+ *
+ * Turning off this setting will save the footprint by about 16KB, since
+ * it should also exclude dns.o and resolve.o from PJLIB-UTIL.
+ *
+ * Default: 1 (enabled)
+ *
+ * @see PJSIP_MAX_RESOLVED_ADDRESSES
+ */
+#ifndef PJSIP_HAS_RESOLVER
+# define PJSIP_HAS_RESOLVER 1
+#endif
+
+
+/**
+ * Maximum number of addresses returned by the resolver. The number here
+ * will slightly affect stack usage, since each entry will occupy about
+ * 32 bytes of stack memory.
+ *
+ * Default: 8
+ *
+ * @see PJSIP_HAS_RESOLVER
+ */
+#ifndef PJSIP_MAX_RESOLVED_ADDRESSES
+# define PJSIP_MAX_RESOLVED_ADDRESSES 8
+#endif
+
+
+/**
+ * Enable TLS SIP transport support. For most systems this means that
+ * OpenSSL must be installed.
+ *
+ * Default: follow PJ_HAS_SSL_SOCK setting, which is 0 (disabled) by default.
+ */
+#ifndef PJSIP_HAS_TLS_TRANSPORT
+# define PJSIP_HAS_TLS_TRANSPORT PJ_HAS_SSL_SOCK
+#endif
+
+
+/**
+ * The TLS pending incoming connection backlog number to be set in accept().
+ *
+ * Default: 5
+ *
+ * @see PJSIP_TCP_TRANSPORT_BACKLOG
+ */
+#ifndef PJSIP_TLS_TRANSPORT_BACKLOG
+# define PJSIP_TLS_TRANSPORT_BACKLOG 5
+#endif
+
+
+
+/* Endpoint. */
+#define PJSIP_MAX_TIMER_COUNT (2*pjsip_cfg()->tsx.max_count + \
+ 2*PJSIP_MAX_DIALOG_COUNT)
+
+/**
+ * Initial memory block for the endpoint.
+ */
+#ifndef PJSIP_POOL_LEN_ENDPT
+# define PJSIP_POOL_LEN_ENDPT (4000)
+#endif
+
+/**
+ * Memory increment for endpoint.
+ */
+#ifndef PJSIP_POOL_INC_ENDPT
+# define PJSIP_POOL_INC_ENDPT (4000)
+#endif
+
+
+/* Transport related constants. */
+
+/**
+ * Initial memory block for rdata.
+ */
+#ifndef PJSIP_POOL_RDATA_LEN
+# define PJSIP_POOL_RDATA_LEN 4000
+#endif
+
+/**
+ * Memory increment for rdata.
+ */
+#ifndef PJSIP_POOL_RDATA_INC
+# define PJSIP_POOL_RDATA_INC 4000
+#endif
+
+#define PJSIP_POOL_LEN_TRANSPORT 512
+#define PJSIP_POOL_INC_TRANSPORT 512
+
+/**
+ * Initial memory block size for tdata.
+ */
+#ifndef PJSIP_POOL_LEN_TDATA
+# define PJSIP_POOL_LEN_TDATA 4000
+#endif
+
+/**
+ * Memory increment for tdata.
+ */
+#ifndef PJSIP_POOL_INC_TDATA
+# define PJSIP_POOL_INC_TDATA 4000
+#endif
+
+/**
+ * Initial memory size for UA layer
+ */
+#ifndef PJSIP_POOL_LEN_UA
+# define PJSIP_POOL_LEN_UA 512
+#endif
+
+/**
+ * Memory increment for UA layer.
+ */
+#ifndef PJSIP_POOL_INC_UA
+# define PJSIP_POOL_INC_UA 512
+#endif
+
+#define PJSIP_MAX_FORWARDS_VALUE 70
+
+#define PJSIP_RFC3261_BRANCH_ID "z9hG4bK"
+#define PJSIP_RFC3261_BRANCH_LEN 7
+
+/* Transaction related constants. */
+
+/**
+ * Initial memory size for transaction layer. The bulk of pool usage
+ * for transaction layer will be used to create the hash table, so
+ * setting this value too high will not help too much with reducing
+ * fragmentation and the memory will most likely be wasted.
+ */
+#ifndef PJSIP_POOL_TSX_LAYER_LEN
+# define PJSIP_POOL_TSX_LAYER_LEN 512
+#endif
+
+/**
+ * Memory increment for transaction layer. The bulk of pool usage
+ * for transaction layer will be used to create the hash table, so
+ * setting this value too high will not help too much with reducing
+ * fragmentation and the memory will most likely be wasted.
+ */
+#ifndef PJSIP_POOL_TSX_LAYER_INC
+# define PJSIP_POOL_TSX_LAYER_INC 512
+#endif
+
+/**
+ * Initial memory size for a SIP transaction object.
+ */
+#ifndef PJSIP_POOL_TSX_LEN
+# define PJSIP_POOL_TSX_LEN 1536 /* 768 */
+#endif
+
+/**
+ * Memory increment for transaction object.
+ */
+#ifndef PJSIP_POOL_TSX_INC
+# define PJSIP_POOL_TSX_INC 256
+#endif
+
+#define PJSIP_MAX_TSX_KEY_LEN (PJSIP_MAX_URL_SIZE*2)
+
+/* User agent. */
+#define PJSIP_POOL_LEN_USER_AGENT 1024
+#define PJSIP_POOL_INC_USER_AGENT 1024
+
+/* Message/URL related constants. */
+#define PJSIP_MAX_CALL_ID_LEN pj_GUID_STRING_LENGTH()
+#define PJSIP_MAX_TAG_LEN pj_GUID_STRING_LENGTH()
+#define PJSIP_MAX_BRANCH_LEN (PJSIP_RFC3261_BRANCH_LEN + pj_GUID_STRING_LENGTH() + 2)
+#define PJSIP_MAX_HNAME_LEN 64
+
+/* Dialog related constants. */
+#define PJSIP_POOL_LEN_DIALOG 1200
+#define PJSIP_POOL_INC_DIALOG 512
+
+/* Maximum header types. */
+#define PJSIP_MAX_HEADER_TYPES 72
+
+/* Maximum URI types. */
+#define PJSIP_MAX_URI_TYPES 4
+
+/*****************************************************************************
+ * Default timeout settings, in miliseconds.
+ */
+
+/** Transaction T1 timeout value. */
+#if !defined(PJSIP_T1_TIMEOUT)
+# define PJSIP_T1_TIMEOUT 500
+#endif
+
+/** Transaction T2 timeout value. */
+#if !defined(PJSIP_T2_TIMEOUT)
+# define PJSIP_T2_TIMEOUT 4000
+#endif
+
+/** Transaction completed timer for non-INVITE */
+#if !defined(PJSIP_T4_TIMEOUT)
+# define PJSIP_T4_TIMEOUT 5000
+#endif
+
+/** Transaction completed timer for INVITE */
+#if !defined(PJSIP_TD_TIMEOUT)
+# define PJSIP_TD_TIMEOUT 32000
+#endif
+
+
+/*****************************************************************************
+ * Authorization
+ */
+
+/**
+ * If this flag is set, the stack will keep the Authorization/Proxy-Authorization
+ * headers that are sent in a cache. Future requests with the same realm and
+ * the same method will use the headers in the cache (as long as no qop is
+ * required by server).
+ *
+ * Turning on this flag will make authorization process goes faster, but
+ * will grow the memory usage undefinitely until the dialog/registration
+ * session is terminated.
+ *
+ * Default: 0
+ */
+#if !defined(PJSIP_AUTH_HEADER_CACHING)
+# define PJSIP_AUTH_HEADER_CACHING 0
+#endif
+
+/**
+ * If this flag is set, the stack will proactively send Authorization/Proxy-
+ * Authorization header for next requests. If next request has the same method
+ * with any of previous requests, then the last header which is saved in
+ * the cache will be used (if PJSIP_AUTH_CACHING is set). Otherwise a fresh
+ * header will be recalculated. If a particular server has requested qop, then
+ * a fresh header will always be calculated.
+ *
+ * If this flag is NOT set, then the stack will only send Authorization/Proxy-
+ * Authorization headers when it receives 401/407 response from server.
+ *
+ * Turning ON this flag will grow memory usage of a dialog/registration pool
+ * indefinitely until it is terminated, because the stack needs to keep the
+ * last WWW-Authenticate/Proxy-Authenticate challenge.
+ *
+ * Default: 0
+ */
+#if !defined(PJSIP_AUTH_AUTO_SEND_NEXT)
+# define PJSIP_AUTH_AUTO_SEND_NEXT 0
+#endif
+
+/**
+ * Support qop="auth" directive.
+ * This option also requires client to cache the last challenge offered by
+ * server.
+ *
+ * Default: 1
+ */
+#if !defined(PJSIP_AUTH_QOP_SUPPORT)
+# define PJSIP_AUTH_QOP_SUPPORT 1
+#endif
+
+
+/**
+ * Maximum number of stale retries when server keeps rejecting our request
+ * with stale=true.
+ *
+ * Default: 3
+ */
+#ifndef PJSIP_MAX_STALE_COUNT
+# define PJSIP_MAX_STALE_COUNT 3
+#endif
+
+
+/**
+ * Specify support for IMS/3GPP digest AKA authentication version 1 and 2
+ * (AKAv1-MD5 and AKAv2-MD5 respectively).
+ *
+ * Default: 0 (for now)
+ */
+#ifndef PJSIP_HAS_DIGEST_AKA_AUTH
+# define PJSIP_HAS_DIGEST_AKA_AUTH 0
+#endif
+
+
+/**
+ * Specify the number of seconds to refresh the client registration
+ * before the registration expires.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH
+# define PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH 5
+#endif
+
+
+/**
+ * Specify whether client registration should check for its registered
+ * contact in Contact header of successful REGISTE response to determine
+ * whether registration has been successful. This setting may be disabled
+ * if non-compliant registrar is unable to return correct Contact header.
+ *
+ * This setting can be changed in run-time by settting \a regc.check_contact
+ * field of pjsip_cfg().
+ *
+ * Default is 1
+ */
+#ifndef PJSIP_REGISTER_CLIENT_CHECK_CONTACT
+# define PJSIP_REGISTER_CLIENT_CHECK_CONTACT 1
+#endif
+
+
+/**
+ * Specify whether client registration should add "x-uid" extension
+ * parameter in all Contact URIs that it registers to assist the
+ * matching of Contact URIs in the 200/OK REGISTER response, in
+ * case the registrar is unable to return exact Contact URI in the
+ * 200/OK response.
+ *
+ * This setting can be changed in run-time by setting
+ * \a regc.add_xuid_param field of pjsip_cfg().
+ *
+ * Default is 0.
+ */
+#ifndef PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM
+# define PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM 0
+#endif
+
+
+/*****************************************************************************
+ * SIP Event framework and presence settings.
+ */
+
+/**
+ * Specify the time (in seconds) to send SUBSCRIBE to refresh client
+ * subscription before the actual interval expires.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_EVSUB_TIME_UAC_REFRESH
+# define PJSIP_EVSUB_TIME_UAC_REFRESH 5
+#endif
+
+
+/**
+ * Specify the time (in seconds) to send PUBLISH to refresh client
+ * publication before the actual interval expires.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH
+# define PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH 5
+#endif
+
+
+/**
+ * Specify the time (in seconds) to wait for the final NOTIFY from the
+ * server after client has sent un-SUBSCRIBE request.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_EVSUB_TIME_UAC_TERMINATE
+# define PJSIP_EVSUB_TIME_UAC_TERMINATE 5
+#endif
+
+
+/**
+ * Specify the time (in seconds) for client subscription to wait for another
+ * NOTIFY from the server, if it has rejected the last NOTIFY with non-2xx
+ * final response (such as 401). If further NOTIFY is not received within
+ * this period, the client will unsubscribe.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_EVSUB_TIME_UAC_WAIT_NOTIFY
+# define PJSIP_EVSUB_TIME_UAC_WAIT_NOTIFY 5
+#endif
+
+
+/**
+ * Specify the default expiration time for presence event subscription, for
+ * both client and server subscription. For client subscription, application
+ * can override this by specifying positive non-zero value in "expires"
+ * parameter when calling #pjsip_pres_initiate(). For server subscription,
+ * we would take the expiration value from the Expires header sent by client
+ * in the SUBSCRIBE request if the header exists and its value is less than
+ * this setting, otherwise this setting will be used.
+ *
+ * Default: 600 seconds (10 minutes)
+ */
+#ifndef PJSIP_PRES_DEFAULT_EXPIRES
+# define PJSIP_PRES_DEFAULT_EXPIRES 600
+#endif
+
+
+/**
+ * Add "timestamp" information in generated PIDF document for both server
+ * subscription and presence publication.
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJSIP_PRES_PIDF_ADD_TIMESTAMP
+# define PJSIP_PRES_PIDF_ADD_TIMESTAMP 1
+#endif
+
+
+/**
+ * Default session interval for Session Timer (RFC 4028) extension, in
+ * seconds. As specified in RFC 4028 Section 4, this value must not be
+ * less than the absolute minimum for the Session-Expires header field
+ * 90 seconds, and the recommended value is 1800 seconds.
+ *
+ * Default: 1800 seconds
+ */
+#ifndef PJSIP_SESS_TIMER_DEF_SE
+# define PJSIP_SESS_TIMER_DEF_SE 1800
+#endif
+
+
+/**
+ * Specify whether the client publication session should queue the
+ * PUBLISH request should there be another PUBLISH transaction still
+ * pending. If this is set to false, the client will return error
+ * on the PUBLISH request if there is another PUBLISH transaction still
+ * in progress.
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJSIP_PUBLISHC_QUEUE_REQUEST
+# define PJSIP_PUBLISHC_QUEUE_REQUEST 1
+#endif
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#include <pj/config.h>
+
+
+#endif /* __PJSIP_SIP_CONFIG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_dialog.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_dialog.h
new file mode 100644
index 0000000..98d8725
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_dialog.h
@@ -0,0 +1,627 @@
+/* $Id: sip_dialog.h 2855 2009-08-05 18:41:23Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_DIALOG_H__
+#define __PJSIP_SIP_DIALOG_H__
+
+
+/**
+ * @file sip_dialog.h
+ * @brief SIP Dialog abstraction
+ */
+
+#include <pjsip/sip_msg.h>
+#include <pjsip/sip_auth.h>
+#include <pjsip/sip_errno.h>
+#include <pjsip/sip_transport.h>
+#include <pjsip/sip_util.h>
+#include <pj/sock.h>
+#include <pj/assert.h>
+
+
+/**
+ * @defgroup PJSIP_DIALOG Base Dialog
+ * @ingroup PJSIP_UA
+ * @brief The base dialog framework to support dialog usages.
+ * @{
+ *
+ * The base dialog framework provides management for base dialog
+ * properties such as <b>From</b> header, <b>To</b> header, <b>CSeq</b>
+ * sequencing, <b>Call-ID</b> header, <b>Contact</b> header management,
+ * dialog <b>route-set</b> management, and common <b>authentication</b>.
+ * This basic dialog functionality will be shared by all <b>dialog
+ * usages</b> of a particular dialog.
+ *
+ * More detailed information is explained in
+ * <A HREF="/docs.htm">PJSIP Developer's Guide</A>
+ * PDF document, and readers are encouraged to read the document to
+ * get the concept behind dialog, dialog usages, and INVITE sessions.
+ *
+ * Application MUST initialize the user agent layer module by calling
+ * #pjsip_ua_init_module() before using any of the dialog API, and link
+ * the application with with <b>pjsip-core</b> library.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * This structure is used to describe dialog's participants, which in this
+ * case is local party (i.e. us) and remote party.
+ */
+typedef struct pjsip_dlg_party
+{
+ pjsip_fromto_hdr *info; /**< From/To header, inc tag. */
+ pj_str_t info_str; /**< String rep of info header. */
+ pj_uint32_t tag_hval; /**< Hashed value of the tag. */
+ pjsip_contact_hdr *contact; /**< Contact header. */
+ pj_int32_t first_cseq;/**< First CSeq seen. */
+ pj_int32_t cseq; /**< Next sequence number. */
+} pjsip_dlg_party;
+
+
+/**
+ * Dialog state.
+ */
+typedef enum pjsip_dialog_state
+{
+ /** Dialog is not established. */
+ PJSIP_DIALOG_STATE_NULL,
+
+ /** Dialog has been established (probably early) */
+ PJSIP_DIALOG_STATE_ESTABLISHED
+} pjsip_dialog_state;
+
+
+/**
+ * This structure describes the dialog structure. Application MUST NOT
+ * try to SET the values here directly, but instead it MUST use the
+ * appropriate dialog API. The dialog declaration only needs to be made
+ * visible because other PJSIP modules need to see it (e.g. INVITE session,
+ * the event framework, etc.).
+ *
+ * Application MAY READ the dialog contents directly after it acquires
+ * dialog lock.
+ *
+ * To acquire dialog lock, use #pjsip_dlg_inc_lock(), and to release it,
+ * use #pjsip_dlg_dec_lock(). DO NOT USE pj_mutex_lock()/pj_mutex_unlock()
+ * on the dialog's mutex directly, because this will not protect against
+ * dialog being destroyed.
+ */
+struct pjsip_dialog
+{
+ /** The dialog set list. */
+ PJ_DECL_LIST_MEMBER(pjsip_dialog);
+
+ /* Dialog's system properties. */
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Standard id. */
+ pj_pool_t *pool; /**< Dialog's pool. */
+ pj_mutex_t *mutex_; /**< Dialog's mutex. Do not call!!
+ Use pjsip_dlg_inc_lock() instead! */
+ pjsip_user_agent *ua; /**< User agent instance. */
+ pjsip_endpoint *endpt; /**< Endpoint instance. */
+
+ /** The dialog set which this dialog belongs (opaque type). */
+ void *dlg_set;
+
+ /* Dialog's session properties. */
+ pjsip_dialog_state state; /**< Dialog state. */
+ pjsip_uri *target; /**< Current target. */
+ pjsip_target_set target_set; /**< Target set, for UAC only. */
+ pjsip_hdr inv_hdr; /**< Headers from hparam in dest URL */
+ pjsip_dlg_party local; /**< Local party info. */
+ pjsip_dlg_party remote; /**< Remote party info. */
+ pjsip_role_e role; /**< Initial role. */
+ pj_bool_t uac_has_2xx;/**< UAC has received 2xx response? */
+ pj_bool_t secure; /**< Use secure transport? */
+ pj_bool_t add_allow; /**< Add Allow header in requests? */
+ pjsip_cid_hdr *call_id; /**< Call-ID header. */
+ pjsip_route_hdr route_set; /**< Route set. */
+ pj_bool_t route_set_frozen; /**< Route set has been set. */
+ pjsip_auth_clt_sess auth_sess; /**< Client authentication session. */
+
+ /** Session counter. */
+ int sess_count; /**< Number of sessions. */
+
+ /** Transaction counter. */
+ int tsx_count; /**< Number of pending transactions. */
+
+ /** Transport selector. */
+ pjsip_tpselector tp_sel;
+
+ /* Dialog usages. */
+ unsigned usage_cnt; /**< Number of registered usages. */
+ pjsip_module *usage[PJSIP_MAX_MODULE]; /**< Array of usages,
+ priority sorted */
+
+ /** Module specific data. */
+ void *mod_data[PJSIP_MAX_MODULE]; /**< Module data. */
+};
+
+
+/**
+ * This utility function returns PJ_TRUE if the specified method is a
+ * dialog creating request. This method property is used to determine
+ * whether Contact header should be included in outgoing request.
+ *
+ * @param m The SIP method.
+ *
+ * @return PJ_TRUE if the method creates a dialog.
+ */
+PJ_DECL(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m);
+
+/**
+ * Create a new dialog and return the instance in p_dlg parameter.
+ * After creating the dialog, application can add modules as dialog usages
+ * by calling #pjsip_dlg_add_usage().
+ *
+ * If the request has To tag parameter, dialog's local tag will be initialized
+ * from this value. Otherwise a globally unique id generator will be invoked to
+ * create dialog's local tag.
+ *
+ * This function also initializes the dialog's route set based on the
+ * Record-Route headers in the request, if present.
+ *
+ * Note that initially, the session count in the dialog will be initialized
+ * to zero.
+ *
+ * @param ua The user agent module instance.
+ * @param local_uri Dialog local URI (i.e. From header).
+ * @param local_contact Optional dialog local Contact to be put as Contact
+ * header value, hence the format must follow
+ * RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * If this argument is NULL, the Contact will be taken
+ * from the local URI.
+ * @param remote_uri Dialog remote URI (i.e. To header).
+ * @param target Optional initial remote target. If this argument
+ * is NULL, the initial target will be set to
+ * remote URI.
+ * @param p_dlg Pointer to receive the dialog.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
+ const pj_str_t *local_uri,
+ const pj_str_t *local_contact,
+ const pj_str_t *remote_uri,
+ const pj_str_t *target,
+ pjsip_dialog **p_dlg);
+
+
+/**
+ * Initialize UAS dialog from the information found in the incoming request
+ * that creates a dialog (such as INVITE, REFER, or SUBSCRIBE), and set the
+ * local Contact to contact. If contact is not specified, the local contact
+ * is initialized from the URI in the To header in the request.
+ *
+ * This function will also create UAS transaction for the incoming request,
+ * and associate the transaction to the rdata. Application can query the
+ * transaction used to handle this request by calling #pjsip_rdata_get_tsx()
+ * after this function returns.
+ *
+ * Note that initially, the session count in the dialog will be initialized
+ * to zero.
+ *
+ *
+ * @param ua The user agent module instance.
+ * @param rdata The incoming request that creates the dialog,
+ * such as INVITE, SUBSCRIBE, or REFER.
+ * @param contact Optional dialog local Contact to be put as Contact
+ * header value, hence the format must follow
+ * RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * If this argument is NULL, the local contact will be
+ * initialized from the value of To header in the
+ * request.
+ * @param p_dlg Pointer to receive the dialog.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
+ pjsip_rx_data *rdata,
+ const pj_str_t *contact,
+ pjsip_dialog **p_dlg);
+
+
+/**
+ * Lock/bind dialog to a specific transport/listener. This is optional,
+ * as normally transport will be selected automatically based on the
+ * destination of messages upon resolver completion. When the dialog is
+ * explicitly bound to the specific transport/listener, all transactions
+ * originated by this dialog will use the specified transport/listener
+ * when sending outgoing requests.
+ *
+ * Note that this doesn't affect the Contact header generated by this
+ * dialog. Application must manually update the Contact header if
+ * necessary, to adjust the address according to the transport being
+ * selected.
+ *
+ * @param dlg The dialog instance.
+ * @param sel Transport selector containing the specification of
+ * transport or listener to be used by this dialog
+ * to send requests.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_transport(pjsip_dialog *dlg,
+ const pjsip_tpselector *sel);
+
+
+/**
+ * Create a new (forked) dialog on receipt on forked response in rdata.
+ * The new dialog will be created from original_dlg, except that it will have
+ * new remote tag as copied from the To header in the response. Upon return,
+ * the new_dlg will have been registered to the user agent. Applications just
+ * need to add modules as dialog's usages.
+ *
+ * Note that initially, the session count in the dialog will be initialized
+ * to zero.
+ *
+ * @param original_dlg The original UAC dialog.
+ * @param rdata The incoming forked response message.
+ * @param new_dlg Pointer to receive the new dialog.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_fork(const pjsip_dialog *original_dlg,
+ const pjsip_rx_data *rdata,
+ pjsip_dialog **new_dlg );
+
+/**
+ * Forcefully terminate the dialog. Application can only call this function
+ * when there is no session associated to the dialog. If there are sessions
+ * that use this dialog, this function will refuse to terminate the dialog.
+ * For this case, application MUST call the appropriate termination function
+ * for each dialog session (e.g. #pjsip_inv_terminate() to terminate INVITE
+ * session).
+ *
+ * @param dlg The dialog.
+ *
+ * @return PJ_SUCCESS if dialog has been terminated.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg );
+
+
+/**
+ * Set dialog's initial route set to route_set list. This can only be called
+ * for UAC dialog, before any request is sent. After dialog has been
+ * established, the route set can not be changed.
+ *
+ * For UAS dialog,the route set will be initialized in pjsip_dlg_create_uas()
+ * from the Record-Route headers in the incoming request.
+ *
+ * The route_set argument is standard list of Route headers (i.e. with
+ * sentinel).
+ *
+ * @param dlg The UAC dialog.
+ * @param route_set List of Route header.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_route_set( pjsip_dialog *dlg,
+ const pjsip_route_hdr *route_set );
+
+/**
+ * Increment the number of sessions in the dialog. Note that initially
+ * (after created) the dialog has the session counter set to zero.
+ *
+ * @param dlg The dialog.
+ * @param mod The module that increments the session counter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
+ pjsip_module *mod);
+
+
+/**
+ * Decrement the number of sessions in the dialog. Once the session counter
+ * reach zero and there is no pending transaction, the dialog will be
+ * destroyed. Note that this function may destroy the dialog immediately
+ * if there is no pending transaction when this function is called.
+ *
+ * @param dlg The dialog.
+ * @param mod The module that decrements the session counter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,
+ pjsip_module *mod);
+
+/**
+ * Add a module as dialog usage, and optionally set the module specific data.
+ *
+ * @param dlg The dialog.
+ * @param module The module to be registered as dialog usage.
+ * @param mod_data Optional arbitrary data to be attached to dialog's
+ * mod_data array at the module's index.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
+ pjsip_module *module,
+ void *mod_data );
+
+/**
+ * Attach module specific data to the dialog. Application can also set
+ * the value directly by accessing dlg->mod_data[module_id].
+ *
+ * @param dlg The dialog
+ * @param mod_id The ID of the module from which the data is to be
+ * set to the dialog.
+ * @param data Arbitrary data.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,
+ int mod_id,
+ void *data );
+
+/**
+ * Get module specific data previously attached to the dialog. Application
+ * can also get value directly by accessing dlg->mod_data[module_id].
+ *
+ * @param dlg The dialog
+ * @param mod_id The ID of the module from which the data is to be
+ * retrieved from the dialog.
+ *
+ * @return The data that was previously set, or NULL.
+ */
+PJ_DECL(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,
+ int mod_id);
+
+
+/**
+ * Lock dialog and increment session counter termporarily, to prevent it
+ * from being destroyed.
+ *
+ * @param dlg The dialog.
+ */
+PJ_DECL(void) pjsip_dlg_inc_lock( pjsip_dialog *dlg );
+
+/**
+ * Try to acquire dialog's lock, but return immediately if lock can not
+ * be acquired.
+ *
+ * @param dlg The dialog.
+ *
+ * @return PJ_SUCCESS if lock has been acquired.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_try_inc_lock( pjsip_dialog *dlg );
+
+/**
+ * Unlock dialog and decrement temporary session counter. After this function
+ * is called, dialog may be destroyed.
+ *
+ * @param dlg The dialog.
+ */
+PJ_DECL(void) pjsip_dlg_dec_lock( pjsip_dialog *dlg );
+
+
+/**
+ * Get the dialog instance in the incoming rdata. If an incoming message
+ * matches an existing dialog, the user agent must have put the matching
+ * dialog instance in the rdata, or otherwise this function will return
+ * NULL if the message didn't match any existing dialog.
+ *
+ * This function can only be called after endpoint distributes the message
+ * to the transaction layer or UA layer. In other words, application can
+ * only call this function in the context of module that runs in priority
+ * number higher than PJSIP_MOD_PRIORITY_UA_PROXY_LAYER.
+ *
+ * @param rdata Incoming message buffer.
+ *
+ * @return The dialog instance that "owns" the message.
+ */
+PJ_DECL(pjsip_dialog*) pjsip_rdata_get_dlg( pjsip_rx_data *rdata );
+
+/**
+ * Get the associated dialog for the specified transaction, if any.
+ *
+ * @param tsx The transaction.
+ *
+ * @return The dialog instance which has been registered
+ * to the transaction as transaction user, or
+ * NULL if the transaction is outside any dialogs.
+ */
+PJ_DECL(pjsip_dialog*) pjsip_tsx_get_dlg( pjsip_transaction *tsx );
+
+
+/**
+ * Create a basic/generic request with the specified method and optionally
+ * specify the cseq. Use value -1 for cseq to have the dialog automatically
+ * put next cseq number for the request. Otherwise for some requests,
+ * e.q. CANCEL and ACK, application must put the CSeq in the original
+ * INVITE request as the parameter.
+ *
+ * This function will also put Contact header where appropriate.
+ *
+ * @param dlg The dialog instance.
+ * @param method The method of the request.
+ * @param cseq Optional CSeq, which only needs to be specified
+ * when creating ACK and CANCEL. For other requests,
+ * specify -1 to use dialog's internal counter.
+ * @param tdata Pointer to receive the request's transmit
+ * data buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_request( pjsip_dialog *dlg,
+ const pjsip_method *method,
+ int cseq,
+ pjsip_tx_data **tdata);
+
+
+/**
+ * Send request message to remote peer. If the request is not an ACK request,
+ * the dialog will send the request statefully, by creating an UAC transaction
+ * and send the request with the transaction.
+ *
+ * Also when the request is not ACK or CANCEL, the dialog will increment its
+ * local cseq number and update the cseq in the request according to dialog's
+ * cseq.
+ *
+ * If p_tsx is not null, this argument will be set with the transaction
+ * instance that was used to send the request.
+ *
+ * This function will decrement the transmit data's reference counter
+ * regardless the status of the operation.
+ *
+ * @param dlg The dialog.
+ * @param tdata The request message to be sent.
+ * @param mod_data_id Optional module data index to put an optional data
+ * into the transaction. If no module data is to be
+ * attached, this value should be -1.
+ * @param mod_data Optional module data to be attached to the
+ * transaction at mod_data_id index.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_send_request ( pjsip_dialog *dlg,
+ pjsip_tx_data *tdata,
+ int mod_data_id,
+ void *mod_data);
+
+
+/**
+ * Create a response message for the incoming request in rdata with status
+ * code st_code and optional status text st_text. This function is different
+ * than endpoint's API #pjsip_endpt_create_response() in that the dialog
+ * function adds Contact header and Record-Routes headers in the response
+ * where appropriate.
+ *
+ * @param dlg The dialog.
+ * @param rdata The incoming request message for which the
+ * response will be created.
+ * @param st_code Status code.
+ * @param st_text Optional string for custom status reason text.
+ * @param tdata Pointer to receive the response message transmit
+ * data buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_response( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ pjsip_tx_data **tdata);
+
+
+/**
+ * Modify previously sent response with other status code. Contact header
+ * will be added when appropriate.
+ *
+ * @param dlg The dialog.
+ * @param tdata The transmit data buffer containing response
+ * message to be modified.
+ * @param st_code New status code to be set.
+ * @param st_text Optional string for custom status reason text.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_modify_response( pjsip_dialog *dlg,
+ pjsip_tx_data *tdata,
+ int st_code,
+ const pj_str_t *st_text);
+
+
+/**
+ * Send response message statefully. The transaction instance MUST be the
+ * transaction that was reported on on_rx_request() callback.
+ *
+ * This function decrements the transmit data's reference counter regardless
+ * the status of the operation.
+ *
+ * @param dlg The dialog.
+ * @param tsx The UAS transaction associated with the incoming
+ * request. If the request is within a dialog, or
+ * a dialog has been created for the request that
+ * creates the dialog, application can get the
+ * transaction instance for the request by calling
+ * #pjsip_rdata_get_tsx().
+ * @param tdata Response message to be sent.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,
+ pjsip_transaction *tsx,
+ pjsip_tx_data *tdata);
+
+
+/**
+ * This composite function sends response message statefully to an incoming
+ * request message inside dialog.
+ *
+ * @param dlg The endpoint instance.
+ * @param rdata The incoming request message.
+ * @param st_code Status code of the response.
+ * @param st_text Optional status text of the response.
+ * @param hdr_list Optional header list to be added to the response.
+ * @param body Optional message body to be added to the response.
+ *
+ * @return PJ_SUCCESS if response message has successfully been
+ * sent.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_respond( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ const pjsip_hdr *hdr_list,
+ const pjsip_msg_body *body );
+
+
+/**
+ * @}
+ */
+
+/*
+ * Internal (called by sip_ua_layer.c)
+ */
+
+/* Receives transaction event (called by user_agent module) */
+void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
+ pjsip_transaction *tsx,
+ pjsip_event *e );
+
+void pjsip_dlg_on_rx_request( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata );
+
+void pjsip_dlg_on_rx_response( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata );
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIP_DIALOG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_endpoint.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_endpoint.h
new file mode 100644
index 0000000..ec1c756
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_endpoint.h
@@ -0,0 +1,521 @@
+/* $Id: sip_endpoint.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_ENDPOINT_H__
+#define __PJSIP_SIP_ENDPOINT_H__
+
+/**
+ * @file sip_endpoint.h
+ * @brief SIP Endpoint.
+ */
+
+#include <pjsip/sip_transport.h>
+#include <pjsip/sip_resolve.h>
+
+/**
+ * @defgroup PJSIP_CORE_CORE At the Very Core
+ * @ingroup PJSIP_CORE
+ * @brief The very core of PJSIP.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_ENDPT Endpoint
+ * @ingroup PJSIP_CORE_CORE
+ * @brief The master, owner of all objects
+ *
+ * SIP Endpoint instance (pjsip_endpoint) can be viewed as the master/owner of
+ * all SIP objects in an application. It performs the following roles:
+ * - it manages the allocation/deallocation of memory pools for all objects.
+ * - it manages listeners and transports, and how they are used by
+ * transactions.
+ * - it receives incoming messages from transport layer and automatically
+ * dispatches them to the correct transaction (or create a new one).
+ * - it has a single instance of timer management (timer heap).
+ * - it manages modules, which is the primary means of extending the library.
+ * - it provides single polling function for all objects and distributes
+ * events.
+ * - it automatically handles incoming requests which can not be handled by
+ * existing modules (such as when incoming request has unsupported method).
+ * - and so on..
+ *
+ * Theoritically application can have multiple instances of SIP endpoint,
+ * although it's not clear why application may want to do it.
+ *
+ * @{
+ */
+
+/**
+ * Create an instance of SIP endpoint from the specified pool factory.
+ * The pool factory reference then will be kept by the endpoint, so that
+ * future memory allocations by SIP components will be taken from the same
+ * pool factory.
+ *
+ * @param pf Pool factory that will be used for the lifetime of
+ * endpoint.
+ * @param name Optional name to be specified for the endpoint.
+ * If this parameter is NULL, then the name will use
+ * local host name.
+ * @param endpt Pointer to receive endpoint instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,
+ const char *name,
+ pjsip_endpoint **endpt);
+
+/**
+ * Destroy endpoint instance. Application must make sure that all pending
+ * transactions have been terminated properly, because this function does not
+ * check for the presence of pending transactions.
+ *
+ * @param endpt The SIP endpoint to be destroyed.
+ */
+PJ_DECL(void) pjsip_endpt_destroy(pjsip_endpoint *endpt);
+
+/**
+ * Get endpoint name.
+ *
+ * @param endpt The SIP endpoint instance.
+ *
+ * @return Endpoint name, as was registered during endpoint
+ * creation. The string is NULL terminated.
+ */
+PJ_DECL(const pj_str_t*) pjsip_endpt_name(const pjsip_endpoint *endpt);
+
+/**
+ * Poll for events. Application must call this function periodically to ensure
+ * that all events from both transports and timer heap are handled in timely
+ * manner. This function, like all other endpoint functions, is thread safe,
+ * and application may have more than one thread concurrently calling this function.
+ *
+ * @param endpt The endpoint.
+ * @param max_timeout Maximum time to wait for events, or NULL to wait forever
+ * until event is received.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_handle_events( pjsip_endpoint *endpt,
+ const pj_time_val *max_timeout);
+
+
+/**
+ * Handle events with additional info about number of events that
+ * have been handled.
+ *
+ * @param endpt The endpoint.
+ * @param max_timeout Maximum time to wait for events, or NULL to wait forever
+ * until event is received.
+ * @param count Optional argument to receive the number of events that
+ * have been handled by the function.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_handle_events2(pjsip_endpoint *endpt,
+ const pj_time_val *max_timeout,
+ unsigned *count);
+/**
+ * Schedule timer to endpoint's timer heap. Application must poll the endpoint
+ * periodically (by calling #pjsip_endpt_handle_events) to ensure that the
+ * timer events are handled in timely manner. When the timeout for the timer
+ * has elapsed, the callback specified in the entry argument will be called.
+ * This function, like all other endpoint functions, is thread safe.
+ *
+ * @param endpt The endpoint.
+ * @param entry The timer entry.
+ * @param delay The relative delay of the timer.
+ * @return PJ_OK (zero) if successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt,
+ pj_timer_entry *entry,
+ const pj_time_val *delay );
+
+/**
+ * Cancel the previously registered timer.
+ * This function, like all other endpoint functions, is thread safe.
+ *
+ * @param endpt The endpoint.
+ * @param entry The timer entry previously registered.
+ */
+PJ_DECL(void) pjsip_endpt_cancel_timer( pjsip_endpoint *endpt,
+ pj_timer_entry *entry );
+
+/**
+ * Get the timer heap instance of the SIP endpoint.
+ *
+ * @param endpt The endpoint.
+ *
+ * @return The timer heap instance.
+ */
+PJ_DECL(pj_timer_heap_t*) pjsip_endpt_get_timer_heap(pjsip_endpoint *endpt);
+
+
+/**
+ * Register new module to the endpoint.
+ * The endpoint will then call the load and start function in the module to
+ * properly initialize the module, and assign a unique module ID for the
+ * module.
+ *
+ * @param endpt The endpoint.
+ * @param module The module to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_register_module( pjsip_endpoint *endpt,
+ pjsip_module *module );
+
+/**
+ * Unregister a module from the endpoint.
+ * The endpoint will then call the stop and unload function in the module to
+ * properly shutdown the module.
+ *
+ * @param endpt The endpoint.
+ * @param module The module to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_unregister_module( pjsip_endpoint *endpt,
+ pjsip_module *module );
+
+
+/**
+ * Create pool from the endpoint. All SIP components should allocate their
+ * memory pool by calling this function, to make sure that the pools are
+ * allocated from the same pool factory. This function, like all other endpoint
+ * functions, is thread safe.
+ *
+ * @param endpt The SIP endpoint.
+ * @param pool_name Name to be assigned to the pool.
+ * @param initial The initial size of the pool.
+ * @param increment The resize size.
+ * @return Memory pool, or NULL on failure.
+ *
+ * @see pj_pool_create
+ */
+PJ_DECL(pj_pool_t*) pjsip_endpt_create_pool( pjsip_endpoint *endpt,
+ const char *pool_name,
+ pj_size_t initial,
+ pj_size_t increment );
+
+/**
+ * Return back pool to endpoint to be released back to the pool factory.
+ * This function, like all other endpoint functions, is thread safe.
+ *
+ * @param endpt The endpoint.
+ * @param pool The pool to be destroyed.
+ */
+PJ_DECL(void) pjsip_endpt_release_pool( pjsip_endpoint *endpt,
+ pj_pool_t *pool );
+
+/**
+ * Find transaction in endpoint's transaction table by the transaction's key.
+ * This function normally is only used by modules. The key for a transaction
+ * can be created by calling #pjsip_tsx_create_key.
+ *
+ * @param endpt The endpoint instance.
+ * @param key Transaction key, as created with #pjsip_tsx_create_key.
+ *
+ * @return The transaction, or NULL if it's not found.
+ */
+PJ_DECL(pjsip_transaction*) pjsip_endpt_find_tsx( pjsip_endpoint *endpt,
+ const pj_str_t *key );
+
+/**
+ * Register the transaction to the endpoint's transaction table.
+ * This function should only be used internally by the stack.
+ *
+ * @param endpt The SIP endpoint.
+ * @param tsx The transaction.
+ */
+PJ_DECL(void) pjsip_endpt_register_tsx( pjsip_endpoint *endpt,
+ pjsip_transaction *tsx);
+
+/**
+ * Forcefull destroy the transaction. This function should only be used
+ * internally by the stack.
+ *
+ * @param endpt The endpoint.
+ * @param tsx The transaction to destroy.
+ */
+PJ_DECL(void) pjsip_endpt_destroy_tsx( pjsip_endpoint *endpt,
+ pjsip_transaction *tsx);
+
+/**
+ * Create a new transmit data buffer.
+ * This function, like all other endpoint functions, is thread safe.
+ *
+ * @param endpt The endpoint.
+ * @param p_tdata Pointer to receive transmit data buffer.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_tdata( pjsip_endpoint *endpt,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Create the DNS resolver instance. Application creates the DNS
+ * resolver instance, set the nameserver to be used by the DNS
+ * resolver, then set the DNS resolver to be used by the endpoint
+ * by calling #pjsip_endpt_set_resolver().
+ *
+ * @param endpt The SIP endpoint instance.
+ * @param p_resv Pointer to receive the DNS resolver instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_resolver(pjsip_endpoint *endpt,
+ pj_dns_resolver **p_resv);
+
+/**
+ * Set DNS resolver to be used by the SIP resolver. Application can set
+ * the resolver instance to NULL to disable DNS resolution (perhaps
+ * temporarily). When DNS resolver is disabled, the endpoint will resolve
+ * hostnames with the normal pj_gethostbyname() function.
+ *
+ * @param endpt The SIP endpoint instance.
+ * @param resv The resolver instance to be used by the SIP
+ * endpoint.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_set_resolver(pjsip_endpoint *endpt,
+ pj_dns_resolver *resv);
+
+/**
+ * Get the DNS resolver being used by the SIP resolver.
+ *
+ * @param endpt The SIP endpoint instance.
+ *
+ * @return The DNS resolver instance currently being used
+ * by the SIP endpoint.
+ */
+PJ_DECL(pj_dns_resolver*) pjsip_endpt_get_resolver(pjsip_endpoint *endpt);
+
+/**
+ * Asynchronously resolve a SIP target host or domain according to rule
+ * specified in RFC 3263 (Locating SIP Servers). When the resolving operation
+ * has completed, the callback will be called.
+ *
+ * @param endpt The endpoint instance.
+ * @param pool The pool to allocate resolver job.
+ * @param target The target specification to be resolved.
+ * @param token A user defined token to be passed back to callback function.
+ * @param cb The callback function.
+ */
+PJ_DECL(void) pjsip_endpt_resolve( pjsip_endpoint *endpt,
+ pj_pool_t *pool,
+ pjsip_host_info *target,
+ void *token,
+ pjsip_resolver_callback *cb);
+
+/**
+ * Get transport manager instance.
+ *
+ * @param endpt The endpoint.
+ *
+ * @return Transport manager instance.
+ */
+PJ_DECL(pjsip_tpmgr*) pjsip_endpt_get_tpmgr(pjsip_endpoint *endpt);
+
+/**
+ * Get ioqueue instance.
+ *
+ * @param endpt The endpoint.
+ *
+ * @return The ioqueue.
+ */
+PJ_DECL(pj_ioqueue_t*) pjsip_endpt_get_ioqueue(pjsip_endpoint *endpt);
+
+/**
+ * Find a SIP transport suitable for sending SIP message to the specified
+ * address. If transport selector ("sel") is set, then the function will
+ * check if the transport selected is suitable to send requests to the
+ * specified address.
+ *
+ * @see pjsip_tpmgr_acquire_transport
+ *
+ * @param endpt The SIP endpoint instance.
+ * @param type The type of transport to be acquired.
+ * @param remote The remote address to send message to.
+ * @param addr_len Length of the remote address.
+ * @param sel Optional pointer to transport selector instance which is
+ * used to find explicit transport, if required.
+ * @param p_tp Pointer to receive the transport instance, if one is found.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjsip_endpt_acquire_transport( pjsip_endpoint *endpt,
+ pjsip_transport_type_e type,
+ const pj_sockaddr_t *remote,
+ int addr_len,
+ const pjsip_tpselector *sel,
+ pjsip_transport **p_tp);
+
+
+/*****************************************************************************
+ *
+ * Capabilities Management
+ *
+ * Modules may implement new capabilities to the stack. These capabilities
+ * are indicated by the appropriate SIP header fields, such as Accept,
+ * Accept-Encoding, Accept-Language, Allow, Supported, etc.
+ *
+ * When a module provides new capabilities to the stack, it registers these
+ * capabilities to the endpoint by supplying new tags (strings) to the
+ * appropriate header fields. Application (or other modules) can then query
+ * these header fields to get the list of supported capabilities, and may
+ * include these headers in the outgoing message.
+ *****************************************************************************
+ */
+
+/**
+ * Get the value of the specified capability header field.
+ *
+ * @param endpt The endpoint.
+ * @param htype The header type to be retrieved, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ *
+ * @return The appropriate header, or NULL if the header is not
+ * available.
+ */
+PJ_DECL(const pjsip_hdr*) pjsip_endpt_get_capability( pjsip_endpoint *endpt,
+ int htype,
+ const pj_str_t *hname);
+
+
+/**
+ * Check if we have the specified capability.
+ *
+ * @param endpt The endpoint.
+ * @param htype The header type to be retrieved, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ * @param token The capability token to check. For example, if \a htype
+ * is PJSIP_H_ALLOW, then \a token specifies the method
+ * names; if \a htype is PJSIP_H_SUPPORTED, then \a token
+ * specifies the extension names such as "100rel".
+ *
+ * @return PJ_TRUE if the specified capability is supported,
+ * otherwise PJ_FALSE..
+ */
+PJ_DECL(pj_bool_t) pjsip_endpt_has_capability( pjsip_endpoint *endpt,
+ int htype,
+ const pj_str_t *hname,
+ const pj_str_t *token);
+
+
+/**
+ * Add or register new capabilities as indicated by the tags to the
+ * appropriate header fields in the endpoint.
+ *
+ * @param endpt The endpoint.
+ * @param mod The module which registers the capability.
+ * @param htype The header type to be set, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ * @param count The number of tags in the array.
+ * @param tags Array of tags describing the capabilities or extensions
+ * to be added to the appropriate header.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_add_capability( pjsip_endpoint *endpt,
+ pjsip_module *mod,
+ int htype,
+ const pj_str_t *hname,
+ unsigned count,
+ const pj_str_t tags[]);
+
+/**
+ * Get list of additional headers to be put in outgoing request message.
+ * Currently only Max-Forwards are defined.
+ *
+ * @param e The endpoint.
+ *
+ * @return List of headers.
+ */
+PJ_DECL(const pjsip_hdr*) pjsip_endpt_get_request_headers(pjsip_endpoint *e);
+
+
+/**
+ * Dump endpoint status to the log. This will print the status to the log
+ * with log level 3.
+ *
+ * @param endpt The endpoint.
+ * @param detail If non zero, then it will dump a detailed output.
+ * BEWARE that this option may crash the system because
+ * it tries to access all memory pools.
+ */
+PJ_DECL(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail );
+
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * Log an error.
+ */
+PJ_DECL(void) pjsip_endpt_log_error( pjsip_endpoint *endpt,
+ const char *sender,
+ pj_status_t error_code,
+ const char *format,
+ ... );
+
+#define PJSIP_ENDPT_LOG_ERROR(expr) \
+ pjsip_endpt_log_error expr
+
+#define PJSIP_ENDPT_TRACE(tracing,expr) \
+ do { \
+ if ((tracing)) \
+ PJ_LOG(4,expr); \
+ } while (0)
+
+/*
+ * Internal functions.
+ */
+/*
+ * Receive transaction events from transactions and put in the event queue
+ * to be processed later.
+ */
+void pjsip_endpt_send_tsx_event( pjsip_endpoint *endpt, pjsip_event *evt );
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_ENDPOINT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_errno.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_errno.h
new file mode 100644
index 0000000..b134982
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_errno.h
@@ -0,0 +1,535 @@
+/* $Id: sip_errno.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_ERRNO_H__
+#define __PJSIP_SIP_ERRNO_H__
+
+/**
+ * @file sip_errno.h
+ * @brief PJSIP Specific Error Code
+ */
+
+#include <pj/errno.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_CORE_ERRNO PJSIP Specific Error Code
+ * @ingroup PJSIP_BASE
+ * @brief PJSIP specific error constants.
+ * @{
+ */
+
+/*
+ * PJSIP error codes occupies 170000 - 219000, and mapped as follows:
+ * - 170100 - 170799: mapped to SIP status code in response msg.
+ * - 171000 - 171999: mapped to errors generated from PJSIP core.
+ */
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ */
+#define PJSIP_ERRNO_START (PJ_ERRNO_START_USER)
+
+/**
+ * Create error value from SIP status code.
+ * @param code SIP status code.
+ * @return Error code in pj_status_t namespace.
+ */
+#define PJSIP_ERRNO_FROM_SIP_STATUS(code) (PJSIP_ERRNO_START+code)
+
+/**
+ * Get SIP status code from error value.
+ * If conversion to SIP status code is not available, a SIP status code
+ * 599 will be returned.
+ *
+ * @param status Error code in pj_status_t namespace.
+ * @return SIP status code.
+ */
+#define PJSIP_ERRNO_TO_SIP_STATUS(status) \
+ ((status>=PJSIP_ERRNO_FROM_SIP_STATUS(100) && \
+ status<PJSIP_ERRNO_FROM_SIP_STATUS(800)) ? \
+ status-PJSIP_ERRNO_FROM_SIP_STATUS(0) : 599)
+
+
+/**
+ * Start of PJSIP generated error code values.
+ */
+#define PJSIP_ERRNO_START_PJSIP (PJSIP_ERRNO_START + 1000)
+
+/************************************************************
+ * GENERIC/GENERAL SIP ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * SIP object is busy.
+ */
+#define PJSIP_EBUSY (PJSIP_ERRNO_START_PJSIP + 1) /* 171001 */
+/**
+ * @hideinitializer
+ * SIP object with the same type already exists.
+ */
+#define PJSIP_ETYPEEXISTS (PJSIP_ERRNO_START_PJSIP + 2) /* 171002 */
+/**
+ * @hideinitializer
+ * SIP stack is shutting down.
+ */
+#define PJSIP_ESHUTDOWN (PJSIP_ERRNO_START_PJSIP + 3) /* 171003 */
+/**
+ * @hideinitializer
+ * SIP object is not initialized.
+ */
+#define PJSIP_ENOTINITIALIZED (PJSIP_ERRNO_START_PJSIP + 4) /* 171004 */
+
+
+/************************************************************
+ * MESSAGING ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General invalid message error (e.g. syntax error)
+ */
+#define PJSIP_EINVALIDMSG (PJSIP_ERRNO_START_PJSIP + 20) /* 171020 */
+/**
+ * @hideinitializer
+ * Expecting request message.
+ */
+#define PJSIP_ENOTREQUESTMSG (PJSIP_ERRNO_START_PJSIP + 21) /* 171021 */
+/**
+ * @hideinitializer
+ * Expecting response message.
+ */
+#define PJSIP_ENOTRESPONSEMSG (PJSIP_ERRNO_START_PJSIP + 22) /* 171022 */
+/**
+ * @hideinitializer
+ * Message too long. See also PJSIP_ERXOVERFLOW.
+ */
+#define PJSIP_EMSGTOOLONG (PJSIP_ERRNO_START_PJSIP + 23) /* 171023 */
+/**
+ * @hideinitializer
+ * Message not completely received.
+ */
+#define PJSIP_EPARTIALMSG (PJSIP_ERRNO_START_PJSIP + 24) /* 171024 */
+
+/**
+ * @hideinitializer
+ * Status code is invalid.
+ */
+#define PJSIP_EINVALIDSTATUS (PJSIP_ERRNO_START_PJSIP + 30) /* 171030 */
+
+/**
+ * @hideinitializer
+ * General Invalid URI error.
+ */
+#define PJSIP_EINVALIDURI (PJSIP_ERRNO_START_PJSIP + 39) /* 171039 */
+/**
+ * @hideinitializer
+ * Unsupported URL scheme.
+ */
+#define PJSIP_EINVALIDSCHEME (PJSIP_ERRNO_START_PJSIP + 40) /* 171040 */
+/**
+ * @hideinitializer
+ * Missing Request-URI.
+ */
+#define PJSIP_EMISSINGREQURI (PJSIP_ERRNO_START_PJSIP + 41) /* 171041 */
+/**
+ * @hideinitializer
+ * Invalid request URI.
+ */
+#define PJSIP_EINVALIDREQURI (PJSIP_ERRNO_START_PJSIP + 42) /* 171042 */
+/**
+ * @hideinitializer
+ * URI is too long.
+ */
+#define PJSIP_EURITOOLONG (PJSIP_ERRNO_START_PJSIP + 43) /* 171043 */
+
+/**
+ * @hideinitializer
+ * Missing required header(s).
+ */
+#define PJSIP_EMISSINGHDR (PJSIP_ERRNO_START_PJSIP + 50) /* 171050 */
+/**
+ * @hideinitializer
+ * Invalid header field.
+ */
+#define PJSIP_EINVALIDHDR (PJSIP_ERRNO_START_PJSIP + 51) /* 171051 */
+/**
+ * @hideinitializer
+ * Invalid Via header in response (sent-by, etc).
+ */
+#define PJSIP_EINVALIDVIA (PJSIP_ERRNO_START_PJSIP + 52) /* 171052 */
+/**
+ * @hideinitializer
+ * Multiple Via headers in response.
+ */
+#define PJSIP_EMULTIPLEVIA (PJSIP_ERRNO_START_PJSIP + 53) /* 171053 */
+/**
+ * @hideinitializer
+ * Missing message body.
+ */
+#define PJSIP_EMISSINGBODY (PJSIP_ERRNO_START_PJSIP + 54) /* 171054 */
+/**
+ * @hideinitializer
+ * Invalid/unexpected method.
+ */
+#define PJSIP_EINVALIDMETHOD (PJSIP_ERRNO_START_PJSIP + 55) /* 171055 */
+
+
+/************************************************************
+ * TRANSPORT ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Unsupported transport type.
+ */
+#define PJSIP_EUNSUPTRANSPORT (PJSIP_ERRNO_START_PJSIP + 60) /* 171060 */
+/**
+ * @hideinitializer
+ * Buffer is being sent, operation still pending.
+ */
+#define PJSIP_EPENDINGTX (PJSIP_ERRNO_START_PJSIP + 61) /* 171061 */
+/**
+ * @hideinitializer
+ * Rx buffer overflow. See also PJSIP_EMSGTOOLONG.
+ */
+#define PJSIP_ERXOVERFLOW (PJSIP_ERRNO_START_PJSIP + 62) /* 171062 */
+/**
+ * @hideinitializer
+ * This is not really an error, it just informs application that
+ * transmit data has been deleted on return of pjsip_tx_data_dec_ref().
+ */
+#define PJSIP_EBUFDESTROYED (PJSIP_ERRNO_START_PJSIP + 63) /* 171063 */
+/**
+ * @hideinitializer
+ * Unsuitable transport selected. This error occurs when application
+ * has explicitly requested to use a particular transport/listener,
+ * but the selected transport is not suitable to send request to
+ * the specified destination.
+ */
+#define PJSIP_ETPNOTSUITABLE (PJSIP_ERRNO_START_PJSIP + 64) /* 171064 */
+/**
+ * @hideinitializer
+ * Transport not available. This error occurs for example when the SIP stack
+ * is trying to use a SIP transport while the transport is being paused by
+ * application.
+ */
+#define PJSIP_ETPNOTAVAIL (PJSIP_ERRNO_START_PJSIP + 65) /* 171065 */
+
+/************************************************************
+ * TRANSACTION ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Transaction has just been destroyed.
+ */
+#define PJSIP_ETSXDESTROYED (PJSIP_ERRNO_START_PJSIP + 70) /* 171070 */
+/**
+ * @hideinitializer
+ * No transaction.
+ */
+#define PJSIP_ENOTSX (PJSIP_ERRNO_START_PJSIP + 71) /* 171071 */
+
+
+/************************************************************
+ * URI COMPARISON RESULTS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Scheme mismatch.
+ */
+#define PJSIP_ECMPSCHEME (PJSIP_ERRNO_START_PJSIP + 80) /* 171080 */
+/**
+ * @hideinitializer
+ * User part mismatch.
+ */
+#define PJSIP_ECMPUSER (PJSIP_ERRNO_START_PJSIP + 81) /* 171081 */
+/**
+ * @hideinitializer
+ * Password part mismatch.
+ */
+#define PJSIP_ECMPPASSWD (PJSIP_ERRNO_START_PJSIP + 82) /* 171082 */
+/**
+ * @hideinitializer
+ * Host part mismatch.
+ */
+#define PJSIP_ECMPHOST (PJSIP_ERRNO_START_PJSIP + 83) /* 171083 */
+/**
+ * @hideinitializer
+ * Port part mismatch.
+ */
+#define PJSIP_ECMPPORT (PJSIP_ERRNO_START_PJSIP + 84) /* 171084 */
+/**
+ * @hideinitializer
+ * Transport parameter part mismatch.
+ */
+#define PJSIP_ECMPTRANSPORTPRM (PJSIP_ERRNO_START_PJSIP + 85) /* 171085 */
+/**
+ * @hideinitializer
+ * TTL parameter part mismatch.
+ */
+#define PJSIP_ECMPTTLPARAM (PJSIP_ERRNO_START_PJSIP + 86) /* 171086 */
+/**
+ * @hideinitializer
+ * User parameter part mismatch.
+ */
+#define PJSIP_ECMPUSERPARAM (PJSIP_ERRNO_START_PJSIP + 87) /* 171087 */
+/**
+ * @hideinitializer
+ * Method parameter part mismatch.
+ */
+#define PJSIP_ECMPMETHODPARAM (PJSIP_ERRNO_START_PJSIP + 88) /* 171088 */
+/**
+ * @hideinitializer
+ * Maddr parameter part mismatch.
+ */
+#define PJSIP_ECMPMADDRPARAM (PJSIP_ERRNO_START_PJSIP + 89) /* 171089 */
+/**
+ * @hideinitializer
+ * Parameter part in other_param mismatch.
+ */
+#define PJSIP_ECMPOTHERPARAM (PJSIP_ERRNO_START_PJSIP + 90) /* 171090 */
+/**
+ * @hideinitializer
+ * Parameter part in header_param mismatch.
+ */
+#define PJSIP_ECMPHEADERPARAM (PJSIP_ERRNO_START_PJSIP + 91) /* 171091 */
+
+
+/************************************************************
+ * AUTHENTICATION FRAMEWORK
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Credential failed to authenticate. For this failure, right credential
+ * for the realm has been found and used to authenticate against the challenge,
+ * but the server has rejected the authorization request with 401/407 response
+ * (either with no stale parameter or with "stale=false" parameter). In most
+ * cases, this indicates that the username/password combination is incorrect.
+ */
+#define PJSIP_EFAILEDCREDENTIAL (PJSIP_ERRNO_START_PJSIP + 100) /* 171100 */
+/**
+ * @hideinitializer
+ * No suitable credential is found to authenticate the request against
+ * the received authentication challenge in 401/407 response. This often
+ * is caused by different realm supplied in the credential than the realm
+ * found in the challenge.
+ */
+#define PJSIP_ENOCREDENTIAL (PJSIP_ERRNO_START_PJSIP + 101) /* 171101 */
+/**
+ * @hideinitializer
+ * Invalid/unsupported algorithm.
+ */
+#define PJSIP_EINVALIDALGORITHM (PJSIP_ERRNO_START_PJSIP + 102) /* 171102 */
+/**
+ * @hideinitializer
+ * Invalid/unsupported qop.
+ */
+#define PJSIP_EINVALIDQOP (PJSIP_ERRNO_START_PJSIP + 103) /* 171103 */
+/**
+ * @hideinitializer
+ * Invalid/unsupported authentication scheme.
+ */
+#define PJSIP_EINVALIDAUTHSCHEME (PJSIP_ERRNO_START_PJSIP + 104)/* 171104 */
+/**
+ * @hideinitializer
+ * No previous challenge.
+ */
+#define PJSIP_EAUTHNOPREVCHAL (PJSIP_ERRNO_START_PJSIP + 105) /* 171105 */
+/**
+ * @hideinitializer
+ * No authorization is found.
+ */
+#define PJSIP_EAUTHNOAUTH (PJSIP_ERRNO_START_PJSIP + 106) /* 171106 */
+/**
+ * @hideinitializer
+ * Account not found.
+ */
+#define PJSIP_EAUTHACCNOTFOUND (PJSIP_ERRNO_START_PJSIP + 107) /* 171107 */
+/**
+ * @hideinitializer
+ * Account is disabled.
+ */
+#define PJSIP_EAUTHACCDISABLED (PJSIP_ERRNO_START_PJSIP + 108) /* 171108 */
+/**
+ * @hideinitializer
+ * Invalid realm.
+ */
+#define PJSIP_EAUTHINVALIDREALM (PJSIP_ERRNO_START_PJSIP + 109) /* 171109 */
+/**
+ * @hideinitializer
+ * Invalid digest.
+ */
+#define PJSIP_EAUTHINVALIDDIGEST (PJSIP_ERRNO_START_PJSIP+110) /* 171110 */
+/**
+ * @hideinitializer
+ * Maximum number of stale retries exceeded. This happens when server
+ * keeps rejecting our authorization request with stale=true.
+ */
+#define PJSIP_EAUTHSTALECOUNT (PJSIP_ERRNO_START_PJSIP + 111) /* 171111 */
+/**
+ * @hideinitializer
+ * Invalid nonce value in the challenge.
+ */
+#define PJSIP_EAUTHINNONCE (PJSIP_ERRNO_START_PJSIP + 112) /* 171112 */
+/**
+ * @hideinitializer
+ * Invalid AKA credential.
+ */
+#define PJSIP_EAUTHINAKACRED (PJSIP_ERRNO_START_PJSIP + 113) /* 171113 */
+/**
+ * No challenge is found in the challenge.
+ */
+#define PJSIP_EAUTHNOCHAL (PJSIP_ERRNO_START_PJSIP + 114) /* 171114 */
+
+/************************************************************
+ * UA AND DIALOG ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Missing From/To tag.
+ */
+#define PJSIP_EMISSINGTAG (PJSIP_ERRNO_START_PJSIP+120) /* 171120 */
+/**
+ * @hideinitializer
+ * Expecting REFER method
+ */
+#define PJSIP_ENOTREFER (PJSIP_ERRNO_START_PJSIP+121) /* 171121 */
+/**
+ * @hideinitializer
+ * Not associated with REFER subscription
+ */
+#define PJSIP_ENOREFERSESSION (PJSIP_ERRNO_START_PJSIP+122) /* 171122 */
+
+/************************************************************
+ * INVITE SESSIONS ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Session already terminated.
+ */
+#define PJSIP_ESESSIONTERMINATED (PJSIP_ERRNO_START_PJSIP+140) /* 171140 */
+/**
+ * @hideinitializer
+ * Invalid session state for the specified operation.
+ */
+#define PJSIP_ESESSIONSTATE (PJSIP_ERRNO_START_PJSIP+141) /* 171141 */
+/**
+ * @hideinitializer
+ * The feature being requested requires the use of secure session or
+ * transport.
+ */
+#define PJSIP_ESESSIONINSECURE (PJSIP_ERRNO_START_PJSIP+142) /* 171142 */
+
+/************************************************************
+ * TLS TRANSPORT ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Unknown TLS error
+ */
+#define PJSIP_TLS_EUNKNOWN (PJSIP_ERRNO_START_PJSIP+160) /* 171160 */
+/**
+ * @hideinitializer
+ * Invalid SSL protocol method.
+ */
+#define PJSIP_TLS_EINVMETHOD (PJSIP_ERRNO_START_PJSIP+161) /* 171161 */
+/**
+ * @hideinitializer
+ * Error loading/verifying SSL CA list file.
+ */
+#define PJSIP_TLS_ECACERT (PJSIP_ERRNO_START_PJSIP+162) /* 171162 */
+/**
+ * @hideinitializer
+ * Error loading SSL certificate chain file.
+ */
+#define PJSIP_TLS_ECERTFILE (PJSIP_ERRNO_START_PJSIP+163) /* 171163 */
+/**
+ * @hideinitializer
+ * Error adding private key from SSL certificate file.
+ */
+#define PJSIP_TLS_EKEYFILE (PJSIP_ERRNO_START_PJSIP+164) /* 171164 */
+/**
+ * @hideinitializer
+ * Error setting SSL cipher list.
+ */
+#define PJSIP_TLS_ECIPHER (PJSIP_ERRNO_START_PJSIP+165) /* 171165 */
+/**
+ * @hideinitializer
+ * Error creating SSL context.
+ */
+#define PJSIP_TLS_ECTX (PJSIP_ERRNO_START_PJSIP+166) /* 171166 */
+/**
+ * @hideinitializer
+ * Error creating SSL connection object.
+ */
+#define PJSIP_TLS_ESSLCONN (PJSIP_ERRNO_START_PJSIP+167) /* 171167 */
+/**
+ * @hideinitializer
+ * Unknown error when performing SSL connect().
+ */
+#define PJSIP_TLS_ECONNECT (PJSIP_ERRNO_START_PJSIP+168) /* 171168 */
+/**
+ * @hideinitializer
+ * Unknown error when performing SSL accept().
+ */
+#define PJSIP_TLS_EACCEPT (PJSIP_ERRNO_START_PJSIP+169) /* 171169 */
+/**
+ * @hideinitializer
+ * Unknown error when sending SSL data
+ */
+#define PJSIP_TLS_ESEND (PJSIP_ERRNO_START_PJSIP+170) /* 171170 */
+/**
+ * @hideinitializer
+ * Unknown error when reading SSL data
+ */
+#define PJSIP_TLS_EREAD (PJSIP_ERRNO_START_PJSIP+171) /* 171171 */
+/**
+ * @hideinitializer
+ * SSL negotiation has exceeded the maximum configured timeout.
+ */
+#define PJSIP_TLS_ETIMEDOUT (PJSIP_ERRNO_START_PJSIP+172) /* 171172 */
+
+
+/**
+ * Get error message for the specified error code. Note that this
+ * function is only able to decode PJSIP specific error code.
+ * Application should use pj_strerror(), which should be able to
+ * decode all error codes belonging to all subsystems (e.g. pjlib,
+ * pjmedia, pjsip, etc).
+ *
+ * @param status The error code.
+ * @param buffer The buffer where to put the error message.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pjsip_strerror(pj_status_t status,
+ char *buffer, pj_size_t bufsize);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_SIP_ERRNO_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_event.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_event.h
new file mode 100644
index 0000000..5388ae2
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_event.h
@@ -0,0 +1,230 @@
+/* $Id: sip_event.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_EVENT_H__
+#define __PJSIP_SIP_EVENT_H__
+
+/**
+ * @file sip_event.h
+ * @brief SIP Event
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_EVENT Event
+ * @ingroup PJSIP_CORE_CORE
+ * @brief Representation of events as they are distributed among modules.
+ * @{
+ */
+#include <pj/types.h>
+
+
+/**
+ * Event IDs.
+ */
+typedef enum pjsip_event_id_e
+{
+ /** Unidentified event. */
+ PJSIP_EVENT_UNKNOWN,
+
+ /** Timer event, normally only used internally in transaction. */
+ PJSIP_EVENT_TIMER,
+
+ /** Message transmission event. */
+ PJSIP_EVENT_TX_MSG,
+
+ /** Message received event. */
+ PJSIP_EVENT_RX_MSG,
+
+ /** Transport error event. */
+ PJSIP_EVENT_TRANSPORT_ERROR,
+
+ /** Transaction state changed event. */
+ PJSIP_EVENT_TSX_STATE,
+
+ /** Indicates that the event was triggered by user action. */
+ PJSIP_EVENT_USER
+
+} pjsip_event_id_e;
+
+
+/**
+ * This structure describe event descriptor to fully identify a SIP event.
+ *
+ * Events are the only way for a lower layer object to inform something
+ * to higher layer objects. Normally this is achieved by means of callback,
+ * i.e. the higher layer objects register a callback to handle the event on
+ * the lower layer objects.
+ *
+ * This event descriptor is used for example by transactions, to inform
+ * endpoint about events, and by transports, to inform endpoint about
+ * unexpected transport error.
+ */
+struct pjsip_event
+{
+ /** This is necessary so that we can put events as a list. */
+ PJ_DECL_LIST_MEMBER(struct pjsip_event);
+
+ /** The event type, can be any value of \b pjsip_event_id_e.
+ */
+ pjsip_event_id_e type;
+
+ /**
+ * The event body as union, which fields depends on the event type.
+ * By convention, the first member of each struct in the union must be
+ * the pointer which is relevant to the event.
+ */
+ union
+ {
+ /** Timer event. */
+ struct
+ {
+ pj_timer_entry *entry; /**< The timer entry. */
+ } timer;
+
+ /** Transaction state has changed event. */
+ struct
+ {
+ union
+ {
+ pjsip_rx_data *rdata; /**< The incoming message. */
+ pjsip_tx_data *tdata; /**< The outgoing message. */
+ pj_timer_entry *timer; /**< The timer. */
+ pj_status_t status;/**< Transport error status. */
+ void *data; /**< Generic data. */
+ } src;
+ pjsip_transaction *tsx; /**< The transaction. */
+ int prev_state; /**< Previous state. */
+ pjsip_event_id_e type; /**< Type of event source:
+ * - PJSIP_EVENT_TX_MSG
+ * - PJSIP_EVENT_RX_MSG,
+ * - PJSIP_EVENT_TRANSPORT_ERROR
+ * - PJSIP_EVENT_TIMER
+ * - PJSIP_EVENT_USER
+ */
+ } tsx_state;
+
+ /** Message transmission event. */
+ struct
+ {
+ pjsip_tx_data *tdata; /**< The transmit data buffer. */
+
+ } tx_msg;
+
+ /** Transmission error event. */
+ struct
+ {
+ pjsip_tx_data *tdata; /**< The transmit data. */
+ pjsip_transaction *tsx; /**< The transaction. */
+ } tx_error;
+
+ /** Message arrival event. */
+ struct
+ {
+ pjsip_rx_data *rdata; /**< The receive data buffer. */
+ } rx_msg;
+
+ /** User event. */
+ struct
+ {
+ void *user1; /**< User data 1. */
+ void *user2; /**< User data 2. */
+ void *user3; /**< User data 3. */
+ void *user4; /**< User data 4. */
+ } user;
+
+ } body;
+};
+
+/**
+ * Init timer event.
+ */
+#define PJSIP_EVENT_INIT_TIMER(event,pentry) \
+ do { \
+ (event).type = PJSIP_EVENT_TIMER; \
+ (event).body.timer.entry = pentry; \
+ } while (0)
+
+/**
+ * Init tsx state event.
+ */
+#define PJSIP_EVENT_INIT_TSX_STATE(event,ptsx,ptype,pdata,prev) \
+ do { \
+ (event).type = PJSIP_EVENT_TSX_STATE; \
+ (event).body.tsx_state.tsx = ptsx; \
+ (event).body.tsx_state.type = ptype; \
+ (event).body.tsx_state.src.data = pdata; \
+ (event).body.tsx_state.prev_state = prev; \
+ } while (0)
+
+/**
+ * Init tx msg event.
+ */
+#define PJSIP_EVENT_INIT_TX_MSG(event,ptdata) \
+ do { \
+ (event).type = PJSIP_EVENT_TX_MSG; \
+ (event).body.tx_msg.tdata = ptdata; \
+ } while (0)
+
+/**
+ * Init rx msg event.
+ */
+#define PJSIP_EVENT_INIT_RX_MSG(event,prdata) \
+ do { \
+ (event).type = PJSIP_EVENT_RX_MSG; \
+ (event).body.rx_msg.rdata = prdata; \
+ } while (0)
+
+/**
+ * Init transport error event.
+ */
+#define PJSIP_EVENT_INIT_TRANSPORT_ERROR(event,ptsx,ptdata) \
+ do { \
+ (event).type = PJSIP_EVENT_TRANSPORT_ERROR; \
+ (event).body.tx_error.tsx = ptsx; \
+ (event).body.tx_error.tdata = ptdata; \
+ } while (0)
+
+/**
+ * Init user event.
+ */
+#define PJSIP_EVENT_INIT_USER(event,u1,u2,u3,u4) \
+ do { \
+ (event).type = PJSIP_EVENT_USER; \
+ (event).body.user.user1 = (void*)u1; \
+ (event).body.user.user2 = (void*)u2; \
+ (event).body.user.user3 = (void*)u3; \
+ (event).body.user.user4 = (void*)u4; \
+ } while (0)
+
+/**
+ * Get the event string from the event ID.
+ * @param e the event ID.
+ * @note defined in sip_util.c
+ */
+PJ_DECL(const char *) pjsip_event_str(pjsip_event_id_e e);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_EVENT_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_module.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_module.h
new file mode 100644
index 0000000..cf8807a
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_module.h
@@ -0,0 +1,222 @@
+/* $Id: sip_module.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_MODULE_H__
+#define __PJSIP_SIP_MODULE_H__
+
+/**
+ * @file sip_module.h
+ * @brief Module helpers
+ */
+#include <pjsip/sip_types.h>
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_MOD Modules
+ * @ingroup PJSIP_CORE_CORE
+ * @brief Modules are the primary means to extend PJSIP!
+ * @{
+ * Modules are the primary means to extend PJSIP. Without modules, PJSIP
+ * would not know how to handle messages, and will simply discard all
+ * incoming messages.
+ *
+ * Modules are registered by creating and initializing #pjsip_module
+ * structure, and register the structure to PJSIP with
+ * #pjsip_endpt_register_module().
+ *
+ * The <A HREF="/docs.htm">PJSIP Developer's Guide</A>
+ * has a thorough discussion on this subject, and readers are encouraged
+ * to read the document for more information.
+ */
+
+/**
+ * The declaration for SIP module. This structure would be passed to
+ * #pjsip_endpt_register_module() to register the module to PJSIP.
+ */
+struct pjsip_module
+{
+ /** To allow chaining of modules in the endpoint. */
+ PJ_DECL_LIST_MEMBER(struct pjsip_module);
+
+ /**
+ * Module name to identify the module.
+ *
+ * This field MUST be initialized before registering the module.
+ */
+ pj_str_t name;
+
+ /**
+ * Module ID. Application must initialize this field with -1 before
+ * registering the module to PJSIP. After the module is registered,
+ * this field will contain a unique ID to identify the module.
+ */
+ int id;
+
+ /**
+ * Integer number to identify module initialization and start order with
+ * regard to other modules. Higher number will make the module gets
+ * initialized later.
+ *
+ * This field MUST be initialized before registering the module.
+ */
+ int priority;
+
+ /**
+ * Optional function to be called to initialize the module. This function
+ * will be called by endpoint during module registration. If the value
+ * is NULL, then it's equal to returning PJ_SUCCESS.
+ *
+ * @param endpt The endpoint instance.
+ * @return Module should return PJ_SUCCESS to indicate success.
+ */
+ pj_status_t (*load)(pjsip_endpoint *endpt);
+
+ /**
+ * Optional function to be called to start the module. This function
+ * will be called by endpoint during module registration. If the value
+ * is NULL, then it's equal to returning PJ_SUCCESS.
+ *
+ * @return Module should return zero to indicate success.
+ */
+ pj_status_t (*start)(void);
+
+ /**
+ * Optional function to be called to deinitialize the module before
+ * it is unloaded. This function will be called by endpoint during
+ * module unregistration. If the value is NULL, then it's equal to
+ * returning PJ_SUCCESS.
+ *
+ * @return Module should return PJ_SUCCESS to indicate success.
+ */
+ pj_status_t (*stop)(void);
+
+ /**
+ * Optional function to be called to deinitialize the module before
+ * it is unloaded. This function will be called by endpoint during
+ * module unregistration. If the value is NULL, then it's equal to
+ * returning PJ_SUCCESS.
+ *
+ * @param mod The module.
+ *
+ * @return Module should return PJ_SUCCESS to indicate success.
+ */
+ pj_status_t (*unload)(void);
+
+ /**
+ * Optional function to be called to process incoming request message.
+ *
+ * @param rdata The incoming message.
+ *
+ * @return Module should return PJ_TRUE if it handles the request,
+ * or otherwise it should return PJ_FALSE to allow other
+ * modules to handle the request.
+ */
+ pj_bool_t (*on_rx_request)(pjsip_rx_data *rdata);
+
+ /**
+ * Optional function to be called to process incoming response message.
+ *
+ * @param rdata The incoming message.
+ *
+ * @return Module should return PJ_TRUE if it handles the
+ * response, or otherwise it should return PJ_FALSE to
+ * allow other modules to handle the response.
+ */
+ pj_bool_t (*on_rx_response)(pjsip_rx_data *rdata);
+
+ /**
+ * Optional function to be called when transport layer is about to
+ * transmit outgoing request message.
+ *
+ * @param tdata The outgoing request message.
+ *
+ * @return Module should return PJ_SUCCESS in all cases.
+ * If non-zero (or PJ_FALSE) is returned, the message
+ * will not be sent.
+ */
+ pj_status_t (*on_tx_request)(pjsip_tx_data *tdata);
+
+ /**
+ * Optional function to be called when transport layer is about to
+ * transmit outgoing response message.
+ *
+ * @param tdata The outgoing response message.
+ *
+ * @return Module should return PJ_SUCCESS in all cases.
+ * If non-zero (or PJ_FALSE) is returned, the message
+ * will not be sent.
+ */
+ pj_status_t (*on_tx_response)(pjsip_tx_data *tdata);
+
+ /**
+ * Optional function to be called when this module is acting as
+ * transaction user for the specified transaction, when the
+ * transaction's state has changed.
+ *
+ * @param tsx The transaction.
+ * @param event The event which has caused the transaction state
+ * to change.
+ */
+ void (*on_tsx_state)(pjsip_transaction *tsx, pjsip_event *event);
+
+};
+
+
+/**
+ * Module priority guidelines.
+ */
+enum pjsip_module_priority
+{
+ /**
+ * This is the priority used by transport layer.
+ */
+ PJSIP_MOD_PRIORITY_TRANSPORT_LAYER = 8,
+
+ /**
+ * This is the priority used by transaction layer.
+ */
+ PJSIP_MOD_PRIORITY_TSX_LAYER = 16,
+
+ /**
+ * This is the priority used by the user agent and proxy layer.
+ */
+ PJSIP_MOD_PRIORITY_UA_PROXY_LAYER = 32,
+
+ /**
+ * This is the priority used by the dialog usages.
+ */
+ PJSIP_MOD_PRIORITY_DIALOG_USAGE = 48,
+
+ /**
+ * This is the recommended priority to be used by applications.
+ */
+ PJSIP_MOD_PRIORITY_APPLICATION = 64
+};
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_MODULE_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_msg.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_msg.h
new file mode 100644
index 0000000..1c117a2
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_msg.h
@@ -0,0 +1,1988 @@
+/* $Id: sip_msg.h 2968 2009-10-26 11:21:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_MSG_H__
+#define __PJSIP_SIP_MSG_H__
+
+/**
+ * @file pjsip/sip_msg.h
+ * @brief SIP Message Structure.
+ */
+
+#include <pjsip/sip_types.h>
+#include <pjsip/sip_uri.h>
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_MSG Messaging Elements
+ * @ingroup PJSIP_CORE
+ * @brief Various SIP message elements such as methods, headers, URIs, etc.
+ * @{
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJSIP_MSG_METHOD Methods
+ * @brief Method names and manipulation.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * This enumeration declares SIP methods as described by RFC3261. Additional
+ * methods do exist, and they are described by corresponding RFCs for the SIP
+ * extentensions. Since they won't alter the characteristic of the processing
+ * of the message, they don't need to be explicitly mentioned here.
+ */
+typedef enum pjsip_method_e
+{
+ PJSIP_INVITE_METHOD, /**< INVITE method, for establishing dialogs. */
+ PJSIP_CANCEL_METHOD, /**< CANCEL method, for cancelling request. */
+ PJSIP_ACK_METHOD, /**< ACK method. */
+ PJSIP_BYE_METHOD, /**< BYE method, for terminating dialog. */
+ PJSIP_REGISTER_METHOD, /**< REGISTER method. */
+ PJSIP_OPTIONS_METHOD, /**< OPTIONS method. */
+
+ PJSIP_OTHER_METHOD /**< Other method. */
+
+} pjsip_method_e;
+
+
+
+/**
+ * This structure represents a SIP method.
+ * Application must always use either #pjsip_method_init or #pjsip_method_set
+ * to make sure that method name is initialized correctly. This way, the name
+ * member will always contain a valid method string regardless whether the ID
+ * is recognized or not.
+ */
+struct pjsip_method
+{
+ pjsip_method_e id; /**< Method ID, from \a pjsip_method_e. */
+ pj_str_t name; /**< Method name, which will always contain the
+ method string. */
+};
+
+
+/*
+ * For convenience, standard method structures are defined in the library.
+ */
+/** INVITE method constant. @see pjsip_get_invite_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_invite_method;
+
+/** CANCEL method constant. @see pjsip_get_cancel_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_cancel_method;
+
+/** ACK method constant. @see pjsip_get_ack_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_ack_method;
+
+/** BYE method constant. @see pjsip_get_bye_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_bye_method;
+
+/** REGISTER method constant. @see pjsip_get_register_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_register_method;
+
+/** OPTIONS method constant. @see pjsip_get_options_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_options_method;
+
+/*
+ * Accessor functions for standard SIP methods.
+ */
+/** Get INVITE method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_invite_method(void);
+/** Get CANCEL method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_cancel_method(void);
+/** Get ACK method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_ack_method(void);
+/** Get BYE method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_bye_method(void);
+/** Get REGISTER method constant.*/
+PJ_DECL(const pjsip_method*) pjsip_get_register_method(void);
+/** Get OPTIONS method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_options_method(void);
+
+
+/*
+ * Accessor functions
+ */
+
+/**
+ * Initialize the method structure from a string.
+ * This function will check whether the method is a known method then set
+ * both the id and name accordingly.
+ *
+ * @param m The method to initialize.
+ * @param pool Pool where memory allocation will be allocated from, if required.
+ * @param str The method string.
+ */
+PJ_DECL(void) pjsip_method_init( pjsip_method *m,
+ pj_pool_t *pool,
+ const pj_str_t *str);
+
+/**
+ * Initialize the method structure from a string, without cloning the string.
+ * See #pjsip_method_init.
+ *
+ * @param m The method structure to be initialized.
+ * @param str The method string.
+ */
+PJ_DECL(void) pjsip_method_init_np( pjsip_method *m,
+ pj_str_t *str);
+
+/**
+ * Set the method with the predefined method ID.
+ * This function will also set the name member of the structure to the correct
+ * string according to the method.
+ *
+ * @param m The method structure.
+ * @param id The method ID.
+ */
+PJ_DECL(void) pjsip_method_set( pjsip_method *m, pjsip_method_e id );
+
+
+/**
+ * Copy one method structure to another. If the method is of the known methods,
+ * then memory allocation is not required.
+ *
+ * @param pool Pool to allocate memory from, if required.
+ * @param method The destination method to copy to.
+ * @param rhs The source method to copy from.
+ */
+PJ_DECL(void) pjsip_method_copy( pj_pool_t *pool,
+ pjsip_method *method,
+ const pjsip_method *rhs );
+
+/**
+ * Compare one method with another, and conveniently determine whether the
+ * first method is equal, less than, or greater than the second method.
+ *
+ * @param m1 The first method.
+ * @param m2 The second method.
+ *
+ * @return Zero if equal, otherwise will return -1 if less or +1 if greater.
+ */
+PJ_DECL(int) pjsip_method_cmp( const pjsip_method *m1, const pjsip_method *m2);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJSIP_MSG_HDR Header Fields
+ * @brief Declarations for various SIP header fields.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * Header types, as defined by RFC3261.
+ */
+typedef enum pjsip_hdr_e
+{
+ /*
+ * These are the headers documented in RFC3261. Headers not documented
+ * there must have type PJSIP_H_OTHER, and the header type itself is
+ * recorded in the header name string.
+ *
+ * DO NOT CHANGE THE VALUE/ORDER OF THE HEADER IDs!!!.
+ */
+ PJSIP_H_ACCEPT,
+ PJSIP_H_ACCEPT_ENCODING_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_ACCEPT_LANGUAGE_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_ALERT_INFO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_ALLOW,
+ PJSIP_H_AUTHENTICATION_INFO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_AUTHORIZATION,
+ PJSIP_H_CALL_ID,
+ PJSIP_H_CALL_INFO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_CONTACT,
+ PJSIP_H_CONTENT_DISPOSITION_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_CONTENT_ENCODING_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_CONTENT_LANGUAGE_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_CONTENT_LENGTH,
+ PJSIP_H_CONTENT_TYPE,
+ PJSIP_H_CSEQ,
+ PJSIP_H_DATE_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_ERROR_INFO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_EXPIRES,
+ PJSIP_H_FROM,
+ PJSIP_H_IN_REPLY_TO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_MAX_FORWARDS,
+ PJSIP_H_MIME_VERSION_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_MIN_EXPIRES,
+ PJSIP_H_ORGANIZATION_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_PRIORITY_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_PROXY_AUTHENTICATE,
+ PJSIP_H_PROXY_AUTHORIZATION,
+ PJSIP_H_PROXY_REQUIRE_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_RECORD_ROUTE,
+ PJSIP_H_REPLY_TO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_REQUIRE,
+ PJSIP_H_RETRY_AFTER,
+ PJSIP_H_ROUTE,
+ PJSIP_H_SERVER_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_SUBJECT_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_SUPPORTED,
+ PJSIP_H_TIMESTAMP_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_TO,
+ PJSIP_H_UNSUPPORTED,
+ PJSIP_H_USER_AGENT_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_VIA,
+ PJSIP_H_WARNING_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_WWW_AUTHENTICATE,
+
+ PJSIP_H_OTHER
+
+} pjsip_hdr_e;
+
+/**
+ * This structure provides the pointer to basic functions that are needed
+ * for generic header operations. All header fields will have pointer to
+ * this structure, so that they can be manipulated uniformly.
+ */
+typedef struct pjsip_hdr_vptr
+{
+ /**
+ * Function to clone the header.
+ *
+ * @param pool Memory pool to allocate the new header.
+ * @param hdr Header to clone.
+ *
+ * @return A new instance of the header.
+ */
+ void *(*clone)(pj_pool_t *pool, const void *hdr);
+
+ /**
+ * Pointer to function to shallow clone the header.
+ * Shallow cloning will just make a memory copy of the original header,
+ * thus all pointers in original header will be kept intact. Because the
+ * function does not need to perform deep copy, the operation should be
+ * faster, but the application must make sure that the original header
+ * is still valid throughout the lifetime of new header.
+ *
+ * @param pool Memory pool to allocate the new header.
+ * @param hdr The header to clone.
+ */
+ void *(*shallow_clone)(pj_pool_t *pool, const void *hdr);
+
+ /** Pointer to function to print the header to the specified buffer.
+ * Returns the length of string written, or -1 if the remaining buffer
+ * is not enough to hold the header.
+ *
+ * @param hdr The header to print.
+ * @param buf The buffer.
+ * @param len The size of the buffer.
+ *
+ * @return The size copied to buffer, or -1 if there's not enough space.
+ */
+ int (*print_on)(void *hdr, char *buf, pj_size_t len);
+
+} pjsip_hdr_vptr;
+
+
+/**
+ * Generic fields for all SIP headers are declared using this macro, to make
+ * sure that all headers will have exactly the same layout in their start of
+ * the storage. This behaves like C++ inheritance actually.
+ */
+#define PJSIP_DECL_HDR_MEMBER(hdr) \
+ /** List members. */ \
+ PJ_DECL_LIST_MEMBER(hdr); \
+ /** Header type */ \
+ pjsip_hdr_e type; \
+ /** Header name. */ \
+ pj_str_t name; \
+ /** Header short name version. */ \
+ pj_str_t sname; \
+ /** Virtual function table. */ \
+ pjsip_hdr_vptr *vptr
+
+
+/**
+ * Generic SIP header structure, for generic manipulation for headers in the
+ * message. All header fields can be typecasted to this type.
+ */
+struct pjsip_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_hdr);
+};
+
+
+/**
+ * This generic function will clone any header, by calling "clone" function
+ * in header's virtual function table.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param hdr The header to clone.
+ *
+ * @return A new instance copied from the original header.
+ */
+PJ_DECL(void*) pjsip_hdr_clone( pj_pool_t *pool, const void *hdr );
+
+
+/**
+ * This generic function will clone any header, by calling "shallow_clone"
+ * function in header's virtual function table.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param hdr The header to clone.
+ *
+ * @return A new instance copied from the original header.
+ */
+PJ_DECL(void*) pjsip_hdr_shallow_clone( pj_pool_t *pool, const void *hdr );
+
+/**
+ * This generic function will print any header, by calling "print"
+ * function in header's virtual function table.
+ *
+ * @param hdr The header to print.
+ * @param buf The buffer.
+ * @param len The size of the buffer.
+ *
+ * @return The size copied to buffer, or -1 if there's not enough space.
+ */
+PJ_DECL(int) pjsip_hdr_print_on( void *hdr, char *buf, pj_size_t len);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJSIP_MSG_LINE Request and Status Line.
+ * @brief Request and status line structures and manipulation.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * This structure describes SIP request line.
+ */
+typedef struct pjsip_request_line
+{
+ pjsip_method method; /**< Method for this request line. */
+ pjsip_uri *uri; /**< URI for this request line. */
+} pjsip_request_line;
+
+
+/**
+ * This structure describes SIP status line.
+ */
+typedef struct pjsip_status_line
+{
+ int code; /**< Status code. */
+ pj_str_t reason; /**< Reason string. */
+} pjsip_status_line;
+
+
+/**
+ * This enumeration lists standard SIP status codes according to RFC 3261.
+ * In addition, it also declares new status class 7xx for errors generated
+ * by the stack. This status class however should not get transmitted on the
+ * wire.
+ */
+typedef enum pjsip_status_code
+{
+ PJSIP_SC_TRYING = 100,
+ PJSIP_SC_RINGING = 180,
+ PJSIP_SC_CALL_BEING_FORWARDED = 181,
+ PJSIP_SC_QUEUED = 182,
+ PJSIP_SC_PROGRESS = 183,
+
+ PJSIP_SC_OK = 200,
+ PJSIP_SC_ACCEPTED = 202,
+
+ PJSIP_SC_MULTIPLE_CHOICES = 300,
+ PJSIP_SC_MOVED_PERMANENTLY = 301,
+ PJSIP_SC_MOVED_TEMPORARILY = 302,
+ PJSIP_SC_USE_PROXY = 305,
+ PJSIP_SC_ALTERNATIVE_SERVICE = 380,
+
+ PJSIP_SC_BAD_REQUEST = 400,
+ PJSIP_SC_UNAUTHORIZED = 401,
+ PJSIP_SC_PAYMENT_REQUIRED = 402,
+ PJSIP_SC_FORBIDDEN = 403,
+ PJSIP_SC_NOT_FOUND = 404,
+ PJSIP_SC_METHOD_NOT_ALLOWED = 405,
+ PJSIP_SC_NOT_ACCEPTABLE = 406,
+ PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED = 407,
+ PJSIP_SC_REQUEST_TIMEOUT = 408,
+ PJSIP_SC_GONE = 410,
+ PJSIP_SC_REQUEST_ENTITY_TOO_LARGE = 413,
+ PJSIP_SC_REQUEST_URI_TOO_LONG = 414,
+ PJSIP_SC_UNSUPPORTED_MEDIA_TYPE = 415,
+ PJSIP_SC_UNSUPPORTED_URI_SCHEME = 416,
+ PJSIP_SC_BAD_EXTENSION = 420,
+ PJSIP_SC_EXTENSION_REQUIRED = 421,
+ PJSIP_SC_SESSION_TIMER_TOO_SMALL = 422,
+ PJSIP_SC_INTERVAL_TOO_BRIEF = 423,
+ PJSIP_SC_TEMPORARILY_UNAVAILABLE = 480,
+ PJSIP_SC_CALL_TSX_DOES_NOT_EXIST = 481,
+ PJSIP_SC_LOOP_DETECTED = 482,
+ PJSIP_SC_TOO_MANY_HOPS = 483,
+ PJSIP_SC_ADDRESS_INCOMPLETE = 484,
+ PJSIP_AC_AMBIGUOUS = 485,
+ PJSIP_SC_BUSY_HERE = 486,
+ PJSIP_SC_REQUEST_TERMINATED = 487,
+ PJSIP_SC_NOT_ACCEPTABLE_HERE = 488,
+ PJSIP_SC_BAD_EVENT = 489,
+ PJSIP_SC_REQUEST_UPDATED = 490,
+ PJSIP_SC_REQUEST_PENDING = 491,
+ PJSIP_SC_UNDECIPHERABLE = 493,
+
+ PJSIP_SC_INTERNAL_SERVER_ERROR = 500,
+ PJSIP_SC_NOT_IMPLEMENTED = 501,
+ PJSIP_SC_BAD_GATEWAY = 502,
+ PJSIP_SC_SERVICE_UNAVAILABLE = 503,
+ PJSIP_SC_SERVER_TIMEOUT = 504,
+ PJSIP_SC_VERSION_NOT_SUPPORTED = 505,
+ PJSIP_SC_MESSAGE_TOO_LARGE = 513,
+ PJSIP_SC_PRECONDITION_FAILURE = 580,
+
+ PJSIP_SC_BUSY_EVERYWHERE = 600,
+ PJSIP_SC_DECLINE = 603,
+ PJSIP_SC_DOES_NOT_EXIST_ANYWHERE = 604,
+ PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE = 606,
+
+ PJSIP_SC_TSX_TIMEOUT = PJSIP_SC_REQUEST_TIMEOUT,
+ /*PJSIP_SC_TSX_RESOLVE_ERROR = 702,*/
+ PJSIP_SC_TSX_TRANSPORT_ERROR = PJSIP_SC_SERVICE_UNAVAILABLE
+
+} pjsip_status_code;
+
+/**
+ * Get the default status text for the status code.
+ *
+ * @param status_code SIP Status Code
+ *
+ * @return textual message for the status code.
+ */
+PJ_DECL(const pj_str_t*) pjsip_get_status_text(int status_code);
+
+/**
+ * This macro returns non-zero (TRUE) if the specified status_code is
+ * in the same class as the code_class.
+ *
+ * @param status_code The status code.
+ * @param code_class The status code in the class (for example 100, 200).
+ */
+#define PJSIP_IS_STATUS_IN_CLASS(status_code, code_class) \
+ (status_code/100 == code_class/100)
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @addtogroup PJSIP_MSG_MEDIA Media/MIME Type
+ * @brief Media/MIME type declaration and manipulations.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * This structure describes SIP media type, as used for example in
+ * Accept and Content-Type header..
+ */
+typedef struct pjsip_media_type
+{
+ pj_str_t type; /**< Media type. */
+ pj_str_t subtype; /**< Media subtype. */
+ pj_str_t param; /**< Media type parameters (concatenated). */
+} pjsip_media_type;
+
+
+/**
+ * Copy SIP media type to another.
+ *
+ * @param pool Pool to duplicate strings.
+ * @param dst Destination structure.
+ * @param src Source structure.
+ */
+PJ_DECL(void) pjsip_media_type_cp(pj_pool_t *pool,
+ pjsip_media_type *dst,
+ const pjsip_media_type *src);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @addtogroup PJSIP_MSG_BODY Message Body
+ * @brief SIP message body structures and manipulation.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * Generic abstraction to message body.
+ * When an incoming message is parsed (pjsip_parse_msg()), the parser fills in
+ * all members with the appropriate value. The 'data' and 'len' member will
+ * describe portion of incoming packet which denotes the message body.
+ * When application needs to attach message body to outgoing SIP message, it
+ * must fill in all members of this structure.
+ */
+struct pjsip_msg_body
+{
+ /** MIME content type.
+ * For incoming messages, the parser will fill in this member with the
+ * content type found in Content-Type header.
+ *
+ * For outgoing messages, application may fill in this member with
+ * appropriate value, because the stack will generate Content-Type header
+ * based on the value specified here.
+ *
+ * If the content_type is empty, no Content-Type AND Content-Length header
+ * will be added to the message. The stack assumes that application adds
+ * these headers themselves.
+ */
+ pjsip_media_type content_type;
+
+ /** Pointer to buffer which holds the message body data.
+ * For incoming messages, the parser will fill in this member with the
+ * pointer to the body string.
+ *
+ * When sending outgoing message, this member doesn't need to point to the
+ * actual message body string. It can be assigned with arbitrary pointer,
+ * because the value will only need to be understood by the print_body()
+ * function. The stack itself will not try to interpret this value, but
+ * instead will always call the print_body() whenever it needs to get the
+ * actual body string.
+ */
+ void *data;
+
+ /** The length of the data.
+ * For incoming messages, the parser will fill in this member with the
+ * actual length of message body.
+ *
+ * When sending outgoing message, again just like the "data" member, the
+ * "len" member doesn't need to point to the actual length of the body
+ * string.
+ */
+ unsigned len;
+
+ /** Pointer to function to print this message body.
+ * Application must set a proper function here when sending outgoing
+ * message.
+ *
+ * @param msg_body This structure itself.
+ * @param buf The buffer.
+ * @param size The buffer size.
+ *
+ * @return The length of the string printed, or -1 if there is
+ * not enough space in the buffer to print the whole
+ * message body.
+ */
+ int (*print_body)(struct pjsip_msg_body *msg_body,
+ char *buf, pj_size_t size);
+
+ /** Clone the data part only of this message body. Note that this only
+ * duplicates the data part of the body instead of the whole message
+ * body. If application wants to duplicate the entire message body
+ * structure, it must call #pjsip_msg_body_clone().
+ *
+ * @param pool Pool used to clone the data.
+ * @param data The data inside message body, to be cloned.
+ * @param len The length of the data.
+ *
+ * @return New data duplicated from the original data.
+ */
+ void* (*clone_data)(pj_pool_t *pool, const void *data, unsigned len);
+
+};
+
+/**
+ * General purpose function to textual data in a SIP body. Attach this function
+ * in a SIP message body only if the data in pjsip_msg_body is a textual
+ * message ready to be embedded in a SIP message. If the data in the message
+ * body is not a textual body, then application must supply a custom function
+ * to print that body.
+ *
+ * @param msg_body The message body.
+ * @param buf Buffer to copy the message body to.
+ * @param size The size of the buffer.
+ *
+ * @return The length copied to the buffer, or -1.
+ */
+PJ_DECL(int) pjsip_print_text_body( pjsip_msg_body *msg_body,
+ char *buf, pj_size_t size);
+
+/**
+ * General purpose function to clone textual data in a SIP body. Attach this
+ * function as "clone_data" member of the SIP body only if the data type
+ * is a text (i.e. C string, not pj_str_t), and the length indicates the
+ * length of the text.
+ *
+ * @param pool Pool used to clone the data.
+ * @param data Textual data.
+ * @param len The length of the string.
+ *
+ * @return New text duplicated from the original text.
+ */
+PJ_DECL(void*) pjsip_clone_text_data( pj_pool_t *pool, const void *data,
+ unsigned len);
+
+
+/**
+ * Clone the message body in src_body to the dst_body. This will duplicate
+ * the contents of the message body using the \a clone_data member of the
+ * source message body.
+ *
+ * @param pool Pool to use to duplicate the message body.
+ * @param dst_body Destination message body.
+ * @param src_body Source message body to duplicate.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_msg_body_copy( pj_pool_t *pool,
+ pjsip_msg_body *dst_body,
+ const pjsip_msg_body *src_body );
+
+
+/**
+ * Create cloned message body. This will duplicate the contents of the message
+ * body using the \a clone_data member of the source message body.
+ *
+ * @param pool Pool to use to duplicate the message body.
+ * @param body Source message body to duplicate.
+ *
+ * @return The cloned message body on successfull.
+ */
+PJ_DECL(pjsip_msg_body*) pjsip_msg_body_clone( pj_pool_t *pool,
+ const pjsip_msg_body *body );
+
+
+/**
+ * Create a text message body. Use this function to create message body when
+ * the content is a simple text. For non-text message body (e.g.
+ * pjmedia_sdp_session or pj_xml_node), application must construct the message
+ * manually.
+ *
+ * @param pool Pool to allocate message body and its contents.
+ * @param type MIME type (e.g. "text").
+ * @param subtype MIME subtype (e.g. "plain").
+ * @param text The text content to be put in the message body.
+ *
+ * @return A new message body with the specified Content-Type and
+ * text.
+ */
+PJ_DECL(pjsip_msg_body*) pjsip_msg_body_create( pj_pool_t *pool,
+ const pj_str_t *type,
+ const pj_str_t *subtype,
+ const pj_str_t *text );
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJSIP_MSG_MSG Message Structure
+ * @brief SIP message (request and response) structure and operations.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * Message type (request or response).
+ */
+typedef enum pjsip_msg_type_e
+{
+ PJSIP_REQUEST_MSG, /**< Indicates request message. */
+ PJSIP_RESPONSE_MSG /**< Indicates response message. */
+} pjsip_msg_type_e;
+
+
+/**
+ * This structure describes a SIP message.
+ */
+struct pjsip_msg
+{
+ /** Message type (ie request or response). */
+ pjsip_msg_type_e type;
+
+ /** The first line of the message can be either request line for request
+ * messages, or status line for response messages. It is represented here
+ * as a union.
+ */
+ union
+ {
+ /** Request Line. */
+ struct pjsip_request_line req;
+
+ /** Status Line. */
+ struct pjsip_status_line status;
+ } line;
+
+ /** List of message headers. */
+ pjsip_hdr hdr;
+
+ /** Pointer to message body, or NULL if no message body is attached to
+ * this mesage.
+ */
+ pjsip_msg_body *body;
+};
+
+
+/**
+ * Create new request or response message.
+ *
+ * @param pool The pool.
+ * @param type Message type.
+ * @return New message, or THROW exception if failed.
+ */
+PJ_DECL(pjsip_msg*) pjsip_msg_create( pj_pool_t *pool, pjsip_msg_type_e type);
+
+
+/**
+ * Perform a deep clone of a SIP message.
+ *
+ * @param pool The pool for creating the new message.
+ * @param msg The message to be duplicated.
+ *
+ * @return New message, which is duplicated from the original
+ * message.
+ */
+PJ_DECL(pjsip_msg*) pjsip_msg_clone( pj_pool_t *pool, const pjsip_msg *msg);
+
+
+/**
+ * Find a header in the message by the header type.
+ *
+ * @param msg The message.
+ * @param type The header type to find.
+ * @param start The first header field where the search should begin.
+ * If NULL is specified, then the search will begin from the
+ * first header, otherwise the search will begin at the
+ * specified header.
+ *
+ * @return The header field, or NULL if no header with the specified
+ * type is found.
+ */
+PJ_DECL(void*) pjsip_msg_find_hdr( const pjsip_msg *msg,
+ pjsip_hdr_e type, const void *start);
+
+/**
+ * Find a header in the message by its name.
+ *
+ * @param msg The message.
+ * @param name The header name to find.
+ * @param start The first header field where the search should begin.
+ * If NULL is specified, then the search will begin from the
+ * first header, otherwise the search will begin at the
+ * specified header.
+ *
+ * @return The header field, or NULL if no header with the specified
+ * type is found.
+ */
+PJ_DECL(void*) pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,
+ const pj_str_t *name,
+ const void *start);
+
+/**
+ * Find a header in the message by its name and short name version.
+ *
+ * @param msg The message.
+ * @param name The header name to find.
+ * @param sname The short name version of the header name.
+ * @param start The first header field where the search should begin.
+ * If NULL is specified, then the search will begin from the
+ * first header, otherwise the search will begin at the
+ * specified header.
+ *
+ * @return The header field, or NULL if no header with the specified
+ * type is found.
+ */
+PJ_DECL(void*) pjsip_msg_find_hdr_by_names(const pjsip_msg *msg,
+ const pj_str_t *name,
+ const pj_str_t *sname,
+ const void *start);
+
+/**
+ * Find and remove a header in the message.
+ *
+ * @param msg The message.
+ * @param hdr The header type to find.
+ * @param start The first header field where the search should begin,
+ * or NULL to search from the first header in the message.
+ *
+ * @return The header field, or NULL if not found.
+ */
+PJ_DECL(void*) pjsip_msg_find_remove_hdr( pjsip_msg *msg,
+ pjsip_hdr_e hdr, void *start);
+
+/**
+ * Add a header to the message, putting it last in the header list.
+ *
+ * @param msg The message.
+ * @param hdr The header to add.
+ *
+ * @bug Once the header is put in a list (or message), it can not be put in
+ * other list (or message). Otherwise Real Bad Thing will happen.
+ */
+PJ_INLINE(void) pjsip_msg_add_hdr( pjsip_msg *msg, pjsip_hdr *hdr )
+{
+ pj_list_insert_before(&msg->hdr, hdr);
+}
+
+/**
+ * Add header field to the message, putting it in the front of the header list.
+ *
+ * @param msg The message.
+ * @param hdr The header to add.
+ *
+ * @bug Once the header is put in a list (or message), it can not be put in
+ * other list (or message). Otherwise Real Bad Thing will happen.
+ */
+PJ_INLINE(void) pjsip_msg_insert_first_hdr( pjsip_msg *msg, pjsip_hdr *hdr )
+{
+ pj_list_insert_after(&msg->hdr, hdr);
+}
+
+/**
+ * Print the message to the specified buffer.
+ *
+ * @param msg The message to print.
+ * @param buf The buffer
+ * @param size The size of the buffer.
+ *
+ * @return The length of the printed characters (in bytes), or NEGATIVE
+ * value if the message is too large for the specified buffer.
+ */
+PJ_DECL(pj_ssize_t) pjsip_msg_print(const pjsip_msg *msg,
+ char *buf, pj_size_t size);
+
+
+/*
+ * Some usefull macros to find common headers.
+ */
+
+
+/**
+ * Find Call-ID header.
+ *
+ * @param msg The message.
+ * @return Call-ID header instance.
+ */
+#define PJSIP_MSG_CID_HDR(msg) \
+ ((pjsip_cid_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CALL_ID, NULL))
+
+/**
+ * Find CSeq header.
+ *
+ * @param msg The message.
+ * @return CSeq header instance.
+ */
+#define PJSIP_MSG_CSEQ_HDR(msg) \
+ ((pjsip_cseq_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL))
+
+/**
+ * Find From header.
+ *
+ * @param msg The message.
+ * @return From header instance.
+ */
+#define PJSIP_MSG_FROM_HDR(msg) \
+ ((pjsip_from_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL))
+
+/**
+ * Find To header.
+ *
+ * @param msg The message.
+ * @return To header instance.
+ */
+#define PJSIP_MSG_TO_HDR(msg) \
+ ((pjsip_to_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL))
+
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @addtogroup PJSIP_MSG_HDR
+ * @{
+ */
+
+/**
+ * Generic SIP header, which contains hname and a string hvalue.
+ * Note that this header is not supposed to be used as 'base' class for headers.
+ */
+typedef struct pjsip_generic_string_hdr
+{
+ /** Standard header field. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_string_hdr);
+ /** hvalue */
+ pj_str_t hvalue;
+} pjsip_generic_string_hdr;
+
+
+/**
+ * Create a new instance of generic header. A generic header can have an
+ * arbitrary header name.
+ *
+ * @param pool The pool.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string.
+ * @param hvalue Optional string to be assigned as the value.
+ *
+ * @return The header, or THROW exception.
+ */
+PJ_DECL(pjsip_generic_string_hdr*)
+pjsip_generic_string_hdr_create( pj_pool_t *pool,
+ const pj_str_t *hname,
+ const pj_str_t *hvalue);
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string later.
+ * @param hvalue Optional string to be assigned as the value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_generic_string_hdr*)
+pjsip_generic_string_hdr_init( pj_pool_t *pool,
+ void *mem,
+ const pj_str_t *hname,
+ const pj_str_t *hvalue);
+
+
+/**
+ * Construct a generic string header without allocating memory from the pool.
+ * This function is useful to create a temporary header which life-time is
+ * very short (for example, creating the header in the stack to be passed
+ * as argument to a function which will copy the header).
+ *
+ * @param h The header to be initialized.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string.
+ * @param hvalue Optional string to be assigned as the value.
+ *
+ * @return The header, or THROW exception.
+ */
+PJ_DECL(void) pjsip_generic_string_hdr_init2(pjsip_generic_string_hdr *h,
+ pj_str_t *hname,
+ pj_str_t *hvalue);
+
+
+/* **************************************************************************/
+
+/**
+ * Generic SIP header, which contains hname and a string hvalue.
+ */
+typedef struct pjsip_generic_int_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_int_hdr); /**< Standard header field. */
+ pj_int32_t ivalue; /**< ivalue */
+} pjsip_generic_int_hdr;
+
+
+/**
+ * Create a new instance of generic header. A generic header can have an
+ * arbitrary header name.
+ *
+ * @param pool The pool.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string.
+ * @param hvalue The value to be assigned to the header.
+ *
+ * @return The header, or THROW exception.
+ */
+PJ_DECL(pjsip_generic_int_hdr*) pjsip_generic_int_hdr_create( pj_pool_t *pool,
+ const pj_str_t *hname,
+ int hvalue );
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string later.
+ * @param value Value to be assigned to the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_generic_int_hdr*) pjsip_generic_int_hdr_init( pj_pool_t *pool,
+ void *mem,
+ const pj_str_t *hname,
+ int value );
+
+/* **************************************************************************/
+
+/** Maximum elements in the header array. */
+#define PJSIP_GENERIC_ARRAY_MAX_COUNT 32
+
+/**
+ * Generic array of string header.
+ */
+typedef struct pjsip_generic_array_hdr
+{
+ /** Standard header fields. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_array_hdr);
+
+ /** Number of tags/elements. */
+ unsigned count;
+
+ /** Tags/elements. */
+ pj_str_t values[PJSIP_GENERIC_ARRAY_MAX_COUNT];
+
+} pjsip_generic_array_hdr;
+
+/**
+ * Create generic array header.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param hname Header name.
+ *
+ * @return New generic array header.
+ */
+PJ_DECL(pjsip_generic_array_hdr*) pjsip_generic_array_hdr_create(pj_pool_t *pool,
+ const pj_str_t *hname);
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string later.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_generic_array_hdr*) pjsip_generic_array_hdr_init(pj_pool_t *pool,
+ void *mem,
+ const pj_str_t *hname);
+
+
+/* **************************************************************************/
+
+/** Accept header. */
+typedef pjsip_generic_array_hdr pjsip_accept_hdr;
+
+/** Maximum fields in Accept header. */
+#define PJSIP_MAX_ACCEPT_COUNT PJSIP_GENERIC_ARRAY_MAX_COUNT
+
+/**
+ * Create new Accept header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Accept header instance.
+ */
+PJ_DECL(pjsip_accept_hdr*) pjsip_accept_hdr_create(pj_pool_t *pool);
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_accept_hdr*) pjsip_accept_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+/* **************************************************************************/
+
+/**
+ * Allow header.
+ */
+typedef pjsip_generic_array_hdr pjsip_allow_hdr;
+
+/**
+ * Create new Allow header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Allow header instance.
+ */
+PJ_DECL(pjsip_allow_hdr*) pjsip_allow_hdr_create(pj_pool_t *pool);
+
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_allow_hdr*) pjsip_allow_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+
+/**
+ * Call-ID header.
+ */
+typedef struct pjsip_cid_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_cid_hdr);
+ pj_str_t id; /**< Call-ID string. */
+} pjsip_cid_hdr;
+
+
+/**
+ * Create new Call-ID header.
+ *
+ * @param pool The pool.
+ *
+ * @return new Call-ID header.
+ */
+PJ_DECL(pjsip_cid_hdr*) pjsip_cid_hdr_create( pj_pool_t *pool );
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_cid_hdr*) pjsip_cid_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+
+/* **************************************************************************/
+/**
+ * Content-Length header.
+ */
+typedef struct pjsip_clen_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_clen_hdr);
+ int len; /**< Content length. */
+} pjsip_clen_hdr;
+
+/**
+ * Create new Content-Length header.
+ *
+ * @param pool the pool.
+ * @return A new Content-Length header instance.
+ */
+PJ_DECL(pjsip_clen_hdr*) pjsip_clen_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_clen_hdr*) pjsip_clen_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+/* **************************************************************************/
+/**
+ * CSeq header.
+ */
+typedef struct pjsip_cseq_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_cseq_hdr);
+ pj_int32_t cseq; /**< CSeq number. */
+ pjsip_method method; /**< CSeq method. */
+} pjsip_cseq_hdr;
+
+
+/** Create new CSeq header.
+ *
+ * @param pool The pool.
+ * @return A new CSeq header instance.
+ */
+PJ_DECL(pjsip_cseq_hdr*) pjsip_cseq_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_cseq_hdr*) pjsip_cseq_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/**
+ * Contact header.
+ * In this library, contact header only contains single URI. If a message has
+ * multiple URI in the Contact header, the URI will be put in separate Contact
+ * headers.
+ */
+typedef struct pjsip_contact_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_contact_hdr);
+ int star; /**< The contact contains only a '*' character */
+ pjsip_uri *uri; /**< URI in the contact. */
+ int q1000; /**< The "q" value times 1000 (to avoid float) */
+ pj_int32_t expires; /**< Expires parameter, otherwise -1 if not present. */
+ pjsip_param other_param; /**< Other parameters, concatenated in a single string. */
+} pjsip_contact_hdr;
+
+
+/**
+ * Create a new Contact header.
+ *
+ * @param pool The pool.
+ * @return A new instance of Contact header.
+ */
+PJ_DECL(pjsip_contact_hdr*) pjsip_contact_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_contact_hdr*) pjsip_contact_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+/* **************************************************************************/
+/**
+ * Content-Type.
+ */
+typedef struct pjsip_ctype_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_ctype_hdr);
+ pjsip_media_type media; /**< Media type. */
+} pjsip_ctype_hdr;
+
+
+/**
+ * Create a nwe Content Type header.
+ *
+ * @param pool The pool.
+ * @return A new Content-Type header.
+ */
+PJ_DECL(pjsip_ctype_hdr*) pjsip_ctype_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_ctype_hdr*) pjsip_ctype_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/** Expires header. */
+typedef pjsip_generic_int_hdr pjsip_expires_hdr;
+
+/**
+ * Create a new Expires header.
+ *
+ * @param pool The pool.
+ * @param value The expiration value.
+ *
+ * @return A new Expires header.
+ */
+PJ_DECL(pjsip_expires_hdr*) pjsip_expires_hdr_create( pj_pool_t *pool,
+ int value);
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param value The expiration value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_expires_hdr*) pjsip_expires_hdr_init( pj_pool_t *pool,
+ void *mem,
+ int value );
+
+
+
+/* **************************************************************************/
+/**
+ * To or From header.
+ */
+typedef struct pjsip_fromto_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_fromto_hdr);
+ pjsip_uri *uri; /**< URI in From/To header. */
+ pj_str_t tag; /**< Header "tag" parameter. */
+ pjsip_param other_param; /**< Other params, concatenated as a single string. */
+} pjsip_fromto_hdr;
+
+/** Alias for From header. */
+typedef pjsip_fromto_hdr pjsip_from_hdr;
+
+/** Alias for To header. */
+typedef pjsip_fromto_hdr pjsip_to_hdr;
+
+/**
+ * Create a From header.
+ *
+ * @param pool The pool.
+ * @return New instance of From header.
+ */
+PJ_DECL(pjsip_from_hdr*) pjsip_from_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_from_hdr*) pjsip_from_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/**
+ * Create a To header.
+ *
+ * @param pool The pool.
+ * @return New instance of To header.
+ */
+PJ_DECL(pjsip_to_hdr*) pjsip_to_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_to_hdr*) pjsip_to_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/**
+ * Convert the header to a From header.
+ *
+ * @param hdr The generic from/to header.
+ * @return "From" header.
+ */
+PJ_DECL(pjsip_from_hdr*) pjsip_fromto_hdr_set_from( pjsip_fromto_hdr *hdr );
+
+/**
+ * Convert the header to a To header.
+ *
+ * @param hdr The generic from/to header.
+ * @return "To" header.
+ */
+PJ_DECL(pjsip_to_hdr*) pjsip_fromto_hdr_set_to( pjsip_fromto_hdr *hdr );
+
+
+/* **************************************************************************/
+/**
+ * Max-Forwards header.
+ */
+typedef pjsip_generic_int_hdr pjsip_max_fwd_hdr;
+
+/**
+ * Create new Max-Forwards header instance.
+ *
+ * @param pool The pool.
+ * @param value The Max-Forwards value.
+ *
+ * @return New Max-Forwards header instance.
+ */
+PJ_DECL(pjsip_max_fwd_hdr*)
+pjsip_max_fwd_hdr_create(pj_pool_t *pool, int value);
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param value The Max-Forwards value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_max_fwd_hdr*)
+pjsip_max_fwd_hdr_init( pj_pool_t *pool, void *mem, int value );
+
+
+/* **************************************************************************/
+/**
+ * Min-Expires header.
+ */
+typedef pjsip_generic_int_hdr pjsip_min_expires_hdr;
+
+/**
+ * Create new Min-Expires header instance.
+ *
+ * @param pool The pool.
+ * @param value The Min-Expires value.
+ *
+ * @return New Min-Expires header instance.
+ */
+PJ_DECL(pjsip_min_expires_hdr*) pjsip_min_expires_hdr_create(pj_pool_t *pool,
+ int value);
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param value The Min-Expires value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_min_expires_hdr*) pjsip_min_expires_hdr_init( pj_pool_t *pool,
+ void *mem,
+ int value );
+
+
+/* **************************************************************************/
+/**
+ * Record-Route and Route headers.
+ */
+typedef struct pjsip_routing_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_routing_hdr); /**< Generic header fields. */
+ pjsip_name_addr name_addr; /**< The URL in the Route/Record-Route header. */
+ pjsip_param other_param; /**< Other parameter. */
+} pjsip_routing_hdr;
+
+/** Alias for Record-Route header. */
+typedef pjsip_routing_hdr pjsip_rr_hdr;
+
+/** Alias for Route header. */
+typedef pjsip_routing_hdr pjsip_route_hdr;
+
+
+/**
+ * Create new Record-Route header from the pool.
+ *
+ * @param pool The pool.
+ * @return A new instance of Record-Route header.
+ */
+PJ_DECL(pjsip_rr_hdr*) pjsip_rr_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_rr_hdr*) pjsip_rr_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/**
+ * Create new Route header from the pool.
+ *
+ * @param pool The pool.
+ * @return A new instance of "Route" header.
+ */
+PJ_DECL(pjsip_route_hdr*) pjsip_route_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_route_hdr*) pjsip_route_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/**
+ * Convert generic routing header to Record-Route header.
+ *
+ * @param r The generic routing header, or a "Routing" header.
+ * @return Record-Route header.
+ */
+PJ_DECL(pjsip_rr_hdr*) pjsip_routing_hdr_set_rr( pjsip_routing_hdr *r );
+
+/**
+ * Convert generic routing header to "Route" header.
+ *
+ * @param r The generic routing header, or a "Record-Route" header.
+ * @return "Route" header.
+ */
+PJ_DECL(pjsip_route_hdr*) pjsip_routing_hdr_set_route( pjsip_routing_hdr *r );
+
+/* **************************************************************************/
+/**
+ * Require header.
+ */
+typedef pjsip_generic_array_hdr pjsip_require_hdr;
+
+/**
+ * Create new Require header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Require header instance.
+ */
+PJ_DECL(pjsip_require_hdr*) pjsip_require_hdr_create(pj_pool_t *pool);
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_require_hdr*) pjsip_require_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+/* **************************************************************************/
+/**
+ * Retry-After header.
+ */
+typedef struct pjsip_retry_after_hdr
+{
+ /** Standard header field. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_retry_after_hdr);
+ pj_int32_t ivalue; /**< Retry-After value */
+ pjsip_param param; /**< Optional parameters */
+ pj_str_t comment; /**< Optional comments. */
+} pjsip_retry_after_hdr;
+
+
+/**
+ * Create new Retry-After header instance.
+ *
+ * @param pool The pool.
+ * @param value The Retry-After value.
+ *
+ * @return New Retry-After header instance.
+ */
+PJ_DECL(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_create(pj_pool_t *pool,
+ int value);
+
+/**
+ * Initialize a preallocated memory with the header structure.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param value The Retry-After value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_init( pj_pool_t *pool,
+ void *mem,
+ int value );
+
+
+/* **************************************************************************/
+/**
+ * Supported header.
+ */
+typedef pjsip_generic_array_hdr pjsip_supported_hdr;
+
+/**
+ * Create new Supported header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Supported header instance.
+ */
+PJ_DECL(pjsip_supported_hdr*) pjsip_supported_hdr_create(pj_pool_t *pool);
+
+/**
+ * Initialize a preallocated memory with the header structure.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_supported_hdr*) pjsip_supported_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/**
+ * Unsupported header.
+ */
+typedef pjsip_generic_array_hdr pjsip_unsupported_hdr;
+
+/**
+ * Create new Unsupported header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Unsupported header instance.
+ */
+PJ_DECL(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_create(pj_pool_t *pool);
+
+/**
+ * Initialize a preallocated memory with the header structure.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/**
+ * SIP Via header.
+ * In this implementation, Via header can only have one element in each header.
+ * If a message arrives with multiple elements in a single Via, then they will
+ * be split up into multiple Via headers.
+ */
+typedef struct pjsip_via_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_via_hdr);
+ pj_str_t transport; /**< Transport type. */
+ pjsip_host_port sent_by; /**< Host and optional port */
+ int ttl_param; /**< TTL parameter, or -1 if it's not specified. */
+ int rport_param; /**< "rport" parameter, 0 to specify without
+ port number, -1 means doesn't exist. */
+ pj_str_t maddr_param; /**< "maddr" parameter. */
+ pj_str_t recvd_param; /**< "received" parameter. */
+ pj_str_t branch_param; /**< "branch" parameter. */
+ pjsip_param other_param; /**< Other parameters, concatenated as single string. */
+ pj_str_t comment; /**< Comment. */
+} pjsip_via_hdr;
+
+/**
+ * Create a new Via header.
+ *
+ * @param pool The pool.
+ * @return A new "Via" header instance.
+ */
+PJ_DECL(pjsip_via_hdr*) pjsip_via_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_via_hdr*) pjsip_via_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/**
+ * SIP Warning header.
+ * In this version, Warning header is just a typedef for generic string
+ * header.
+ */
+typedef pjsip_generic_string_hdr pjsip_warning_hdr;
+
+/**
+ * Create a warning header with the specified contents.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param code Warning code, 300-399.
+ * @param host The host portion of the Warning header.
+ * @param text The warning text, which MUST not be quoted with
+ * double quote.
+ *
+ * @return The Warning header field.
+ */
+PJ_DECL(pjsip_warning_hdr*) pjsip_warning_hdr_create( pj_pool_t *pool,
+ int code,
+ const pj_str_t *host,
+ const pj_str_t *text);
+
+/**
+ * Create a warning header and initialize the contents from the error
+ * message for the specified status code. The warning code will be
+ * set to 399.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param host The host portion of the Warning header.
+ * @param status The error status code, which error text will be
+ * put in as the Warning text.
+ *
+ * @return The Warning header field.
+ */
+PJ_DECL(pjsip_warning_hdr*)
+pjsip_warning_hdr_create_from_status( pj_pool_t *pool,
+ const pj_str_t *host,
+ pj_status_t status);
+
+/* **************************************************************************/
+/** Accept-Encoding header. */
+typedef pjsip_generic_string_hdr pjsip_accept_encoding_hdr;
+
+/** Create Accept-Encoding header. */
+#define pjsip_accept_encoding_hdr_create pjsip_generic_string_hdr_create
+
+/** Accept-Language header. */
+typedef pjsip_generic_string_hdr pjsip_accept_lang_hdr;
+
+/** Create Accept-Language header. */
+#define pjsip_accept_lang_hdr_create pjsip_generic_string_hdr_create
+
+/** Alert-Info header. */
+typedef pjsip_generic_string_hdr pjsip_alert_info_hdr;
+
+/** Create Alert-Info header. */
+#define pjsip_alert_info_hdr_create pjsip_generic_string_hdr_create
+
+/** Authentication-Info header. */
+typedef pjsip_generic_string_hdr pjsip_auth_info_hdr;
+
+/** Create Authentication-Info header. */
+#define pjsip_auth_info_hdr_create pjsip_generic_string_hdr_create
+
+/** Call-Info header. */
+typedef pjsip_generic_string_hdr pjsip_call_info_hdr;
+
+/** Create Call-Info header. */
+#define pjsip_call_info_hdr_create pjsip_generic_string_hdr_create
+
+/** Content-Disposition header. */
+typedef pjsip_generic_string_hdr pjsip_content_disposition_hdr;
+
+/** Create Content-Disposition header. */
+#define pjsip_content_disposition_hdr_create pjsip_generic_string_hdr_create
+
+/** Content-Encoding header. */
+typedef pjsip_generic_string_hdr pjsip_content_encoding_hdr;
+
+/** Create Content-Encoding header. */
+#define pjsip_content_encoding_hdr_create pjsip_generic_string_hdr_create
+
+/** Content-Language header. */
+typedef pjsip_generic_string_hdr pjsip_content_lang_hdr;
+
+/** Create Content-Language header. */
+#define pjsip_content_lang_hdr_create pjsip_generic_string_hdr_create
+
+/** Date header. */
+typedef pjsip_generic_string_hdr pjsip_date_hdr;
+
+/** Create Date header. */
+#define pjsip_date_hdr_create pjsip_generic_string_hdr_create
+
+/** Error-Info header. */
+typedef pjsip_generic_string_hdr pjsip_err_info_hdr;
+
+/** Create Error-Info header. */
+#define pjsip_err_info_hdr_create pjsip_generic_string_hdr_create
+
+/** In-Reply-To header. */
+typedef pjsip_generic_string_hdr pjsip_in_reply_to_hdr;
+
+/** Create In-Reply-To header. */
+#define pjsip_in_reply_to_hdr_create pjsip_generic_string_hdr_create
+
+/** MIME-Version header. */
+typedef pjsip_generic_string_hdr pjsip_mime_version_hdr;
+
+/** Create MIME-Version header. */
+#define pjsip_mime_version_hdr_create pjsip_generic_string_hdr_create
+
+/** Organization header. */
+typedef pjsip_generic_string_hdr pjsip_organization_hdr;
+
+/** Create Organization header. */
+#define pjsip_organization_hdr_create pjsip_genric_string_hdr_create
+
+/** Priority header. */
+typedef pjsip_generic_string_hdr pjsip_priority_hdr;
+
+/** Create Priority header. */
+#define pjsip_priority_hdr_create pjsip_generic_string_hdr_create
+
+/** Proxy-Require header. */
+typedef pjsip_generic_string_hdr pjsip_proxy_require_hdr;
+
+/** Reply-To header. */
+typedef pjsip_generic_string_hdr pjsip_reply_to_hdr;
+
+/** Create Reply-To header. */
+#define pjsip_reply_to_hdr_create pjsip_generic_string_hdr_create
+
+/** Server header. */
+typedef pjsip_generic_string_hdr pjsip_server_hdr;
+
+/** Create Server header. */
+#define pjsip_server_hdr_create pjsip_generic_string_hdr_create
+
+/** Subject header. */
+typedef pjsip_generic_string_hdr pjsip_subject_hdr;
+
+/** Create Subject header. */
+#define pjsip_subject_hdr_create pjsip_generic_string_hdr_create
+
+/** Timestamp header. */
+typedef pjsip_generic_string_hdr pjsip_timestamp_hdr;
+
+/** Create Timestamp header. */
+#define pjsip_timestamp_hdr_create pjsip_generic_string_hdr_create
+
+/** User-Agent header. */
+typedef pjsip_generic_string_hdr pjsip_user_agent_hdr;
+
+/** Create User-Agent header. */
+#define pjsip_user_agent_hdr_create pjsip_generic_string_hdr_create
+
+
+/**
+ * @}
+ */
+
+/**
+ * @} PJSIP_MSG
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_MSG_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_parser.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_parser.h
new file mode 100644
index 0000000..79e7e24
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_parser.h
@@ -0,0 +1,412 @@
+/* $Id: sip_parser.h 2660 2009-04-28 19:38:43Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_PARSER_H__
+#define __PJSIP_SIP_PARSER_H__
+
+/**
+ * @file sip_parser.h
+ * @brief SIP Message Parser
+ */
+
+#include <pjsip/sip_msg.h>
+#include <pjlib-util/scanner.h>
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_PARSER Parser
+ * @ingroup PJSIP_MSG
+ * @brief Message and message elements parsing.
+ * @{
+ */
+
+/**
+ * URI Parsing options.
+ */
+enum
+{
+ /** If this option is specified, function #pjsip_parse_uri will return
+ * the URI object as pjsip_name_addr instead of the corresponding
+ * URI object.
+ */
+ PJSIP_PARSE_URI_AS_NAMEADDR = 1,
+
+ /** If this option is specified, function #pjsip_parse_uri and other
+ * internal functions that this function calls will parse URI according
+ * to convention for parsing From/To/Contact header. For example, when
+ * the URI is not enclosed in brackets ("<" and ">"), all parameters
+ * are treated as header parameters (not URI parameters).
+ */
+ PJSIP_PARSE_URI_IN_FROM_TO_HDR = 2
+};
+
+/**
+ * Parser syntax error exception value.
+ */
+extern int PJSIP_SYN_ERR_EXCEPTION;
+
+/**
+ * This structure is used to get error reporting from parser.
+ */
+typedef struct pjsip_parser_err_report
+{
+ /** Standard header fields. */
+ PJ_DECL_LIST_MEMBER(struct pjsip_parser_err_report);
+ int except_code; /**< Error exception (e.g. PJSIP_SYN_ERR_EXCEPTION) */
+ int line; /**< Line number. */
+ int col; /**< Column number. */
+ pj_str_t hname; /**< Header name, if any. */
+} pjsip_parser_err_report;
+
+
+/**
+ * Parsing context, the default argument for parsing functions.
+ */
+typedef struct pjsip_parse_ctx
+{
+ pj_scanner *scanner; /**< The scanner. */
+ pj_pool_t *pool; /**< The pool. */
+ pjsip_rx_data *rdata; /**< Optional rdata. */
+} pjsip_parse_ctx;
+
+
+/**
+ * Type of function to parse header. The parsing function must follow these
+ * specification:
+ * - It must not modify the input text.
+ * - The hname and HCOLON has been parsed prior to invoking the handler.
+ * - It returns the header instance on success.
+ * - For error reporting, it must throw PJSIP_SYN_ERR_EXCEPTION exception
+ * instead of just returning NULL.
+ * When exception is thrown, the return value is ignored.
+ * - It must read the header separator after finished reading the header
+ * body. The separator types are described below, and if they don't exist,
+ * exception must be thrown. Header separator can be a:
+ * - newline, such as when the header is part of a SIP message.
+ * - ampersand, such as when the header is part of an URI.
+ * - for the last header, these separator is optional since parsing
+ * can be terminated when seeing EOF.
+ */
+typedef pjsip_hdr* (pjsip_parse_hdr_func)(pjsip_parse_ctx *context);
+
+/**
+ * Type of function to parse URI scheme.
+ * Most of the specification of header parser handler (pjsip_parse_hdr_func)
+ * also applies here (except the separator part).
+ */
+typedef void* (pjsip_parse_uri_func)(pj_scanner *scanner, pj_pool_t *pool,
+ pj_bool_t parse_params);
+
+/**
+ * Register header parser handler. The parser handler MUST follow the
+ * specification of header parser handler function. New registration
+ * overwrites previous registration with the same name.
+ *
+ * @param hname The header name.
+ * @param hshortname The short header name or NULL.
+ * @param fptr The pointer to function to parser the header.
+ *
+ * @return PJ_SUCCESS if success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_register_hdr_parser( const char *hname,
+ const char *hshortname,
+ pjsip_parse_hdr_func *fptr);
+
+/**
+ * Unregister previously registered header parser handler.
+ * All the arguments MUST exactly equal to the value specified upon
+ * registration of the handler.
+ *
+ * @param hname The header name registered.
+ * @param hshortname The short header name registered, or NULL.
+ * @param fptr Previously registered function to parse the header.
+ *
+ * @return zero if unregistration was successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_unregister_hdr_parser( const char *hname,
+ const char *hshortname,
+ pjsip_parse_hdr_func *fptr);
+
+/**
+ * Register URI scheme parser handler.
+ *
+ * @param scheme The URI scheme registered.
+ * @param func The URI parser function.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pjsip_register_uri_parser( char *scheme,
+ pjsip_parse_uri_func *func);
+
+/**
+ * Unregister URI scheme parser handler.
+ * All the arguments MUST exactly equal to the value specified upon
+ * registration of the handler.
+ *
+ * @param scheme The URI scheme as registered previously.
+ * @param func The function handler as registered previously.
+ *
+ * @return zero if the registration was successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_unregister_uri_parser( const char *scheme,
+ pjsip_parse_uri_func *func);
+
+/**
+ * Parse an URI in the input and return the correct instance of URI.
+ *
+ * @param pool The pool to get memory allocations.
+ * @param buf The input buffer, which MUST be NULL terminated.
+ * @param size The length of the string (not counting NULL terminator).
+ * @param options If no options are given (value is zero), the object
+ * returned is dependent on the syntax of the URI,
+ * eg. basic SIP URL, TEL URL, or name address.
+ * If option PJSIP_PARSE_URI_AS_NAMEADDR is given,
+ * then the returned object is always name address object,
+ * with the relevant URI object contained in the name
+ * address object.
+ * @return The URI or NULL when failed. No exception is thrown by
+ * this function (or any public parser functions).
+ */
+PJ_DECL(pjsip_uri*) pjsip_parse_uri( pj_pool_t *pool,
+ char *buf, pj_size_t size,
+ unsigned options);
+
+/**
+ * Parse SIP status line.
+ *
+ * @param buf Text buffer to parse, which MUST be NULL terminated.
+ * @param size The size of the buffer, excluding the NULL character.
+ * @param status_line Structure to receive the parsed elements.
+ *
+ * @return PJ_SUCCESS if a status line is parsed successfully.
+ */
+PJ_DECL(pj_status_t) pjsip_parse_status_line(char *buf, pj_size_t size,
+ pjsip_status_line *status_line);
+
+
+/**
+ * Parse a packet buffer and build a full SIP message from the packet. This
+ * function parses all parts of the message, including request/status line,
+ * all headers, and the message body. The message body however is only
+ * treated as a text block, ie. the function will not try to parse the content
+ * of the body.
+ *
+ * @param pool The pool to allocate memory.
+ * @param buf The input buffer, which MUST be NULL terminated.
+ * @param size The length of the string (not counting NULL terminator).
+ * @param err_list If this parameter is not NULL, then the parser will
+ * put error messages during parsing in this list.
+ *
+ * @return The message or NULL when failed. No exception is thrown
+ * by this function (or any public parser functions).
+ */
+PJ_DECL(pjsip_msg *) pjsip_parse_msg( pj_pool_t *pool,
+ char *buf, pj_size_t size,
+ pjsip_parser_err_report *err_list);
+
+
+/**
+ * Parse a packet buffer and build a rdata. The resulting message will be
+ * stored in \c msg field in the \c rdata. This behaves pretty much like
+ * #pjsip_parse_msg(), except that it will also initialize the header fields
+ * in the \c rdata.
+ *
+ * This function is normally called by the transport layer.
+ *
+ * @param buf The input buffer, which MUST be NULL terminated.
+ * @param size The length of the string (not counting NULL terminator).
+ * @param rdata The receive data buffer to store the message and
+ * its elements.
+ *
+ * @return The message inside the rdata if successfull, or NULL.
+ */
+PJ_DECL(pjsip_msg *) pjsip_parse_rdata( char *buf, pj_size_t size,
+ pjsip_rx_data *rdata );
+
+/**
+ * Check incoming packet to see if a (probably) valid SIP message has been
+ * received.
+ *
+ * @param buf The input buffer, which must be NULL terminated.
+ * @param size The buffer size.
+ * @param is_datagram Put non-zero if transport is datagram oriented.
+ * @param msg_size [out] If message is valid, this parameter will contain
+ * the size of the SIP message (including body, if any).
+ *
+ * @return PJ_SUCCESS if a message is found, or an error code.
+ */
+PJ_DECL(pj_status_t) pjsip_find_msg(const char *buf,
+ pj_size_t size,
+ pj_bool_t is_datagram,
+ pj_size_t *msg_size);
+
+/**
+ * Parse the content of a header and return the header instance.
+ * This function parses the content of a header (ie. part after colon) according
+ * to the expected name, and will return the correct instance of header.
+ *
+ * @param pool Pool to allocate memory for the header.
+ * @param hname Header name which is used to find the correct function
+ * to parse the header.
+ * @param line Header content, which must be NULL terminated.
+ * @param size The length of the string (not counting NULL terminator,
+ * if any).
+ * @param parsed_len If the value is not NULL, then upon return the function
+ * will fill the pointer with the length of the string
+ * that has been parsed. This is usefull for two purposes,
+ * one is when the string may contain more than one header
+ * lines, and two when an error happen the value can
+ * pinpoint the location of the error in the buffer.
+ *
+ * @return The instance of the header if parsing was successfull,
+ * or otherwise a NULL pointer will be returned.
+ */
+PJ_DECL(void*) pjsip_parse_hdr( pj_pool_t *pool, const pj_str_t *hname,
+ char *line, pj_size_t size,
+ int *parsed_len);
+
+/**
+ * Parse header line(s). Multiple headers can be parsed by this function.
+ * When there are multiple headers, the headers MUST be separated by either
+ * a newline (as in SIP message) or ampersand mark (as in URI). This separator
+ * however is optional for the last header.
+ *
+ * @param pool the pool.
+ * @param input the input text to parse, which must be NULL terminated.
+ * @param size the text length.
+ * @param hlist the header list to store the parsed headers.
+ * This list must have been initialized before calling
+ * this function.
+ * @return zero if successfull, or -1 if error is encountered.
+ * Upon error, the \a hlist argument MAY contain
+ * successfully parsed headers.
+ */
+PJ_DECL(pj_status_t) pjsip_parse_headers( pj_pool_t *pool,
+ char *input, pj_size_t size,
+ pj_list *hlist );
+
+
+/**
+ * @}
+ */
+
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4510) // default constructor could not be generated
+# pragma warning(disable:4512) // assignment operator could not be generated
+# pragma warning(disable:4610) // user defined constructor required
+#endif
+
+/**
+ * Parser constants. @see pjsip_parser_const()
+ */
+typedef struct pjsip_parser_const_t
+{
+ const pj_str_t pjsip_USER_STR; /**< "user" string constant. */
+ const pj_str_t pjsip_METHOD_STR; /**< "method" string constant */
+ const pj_str_t pjsip_TRANSPORT_STR; /**< "transport" string const. */
+ const pj_str_t pjsip_MADDR_STR; /**< "maddr" string const. */
+ const pj_str_t pjsip_LR_STR; /**< "lr" string const. */
+ const pj_str_t pjsip_SIP_STR; /**< "sip" string constant. */
+ const pj_str_t pjsip_SIPS_STR; /**< "sips" string constant. */
+ const pj_str_t pjsip_TEL_STR; /**< "tel" string constant. */
+ const pj_str_t pjsip_BRANCH_STR; /**< "branch" string constant. */
+ const pj_str_t pjsip_TTL_STR; /**< "ttl" string constant. */
+ const pj_str_t pjsip_RECEIVED_STR; /**< "received" string const. */
+ const pj_str_t pjsip_Q_STR; /**< "q" string constant. */
+ const pj_str_t pjsip_EXPIRES_STR; /**< "expires" string constant. */
+ const pj_str_t pjsip_TAG_STR; /**< "tag" string constant. */
+ const pj_str_t pjsip_RPORT_STR; /**< "rport" string const. */
+
+ pj_cis_t pjsip_HOST_SPEC; /**< For scanning host part. */
+ pj_cis_t pjsip_DIGIT_SPEC; /**< Decimal digits */
+ pj_cis_t pjsip_ALPHA_SPEC; /**< Alpha (A-Z, a-z) */
+ pj_cis_t pjsip_ALNUM_SPEC; /**< Decimal + Alpha. */
+ pj_cis_t pjsip_TOKEN_SPEC; /**< Token. */
+ pj_cis_t pjsip_TOKEN_SPEC_ESC; /**< Token without '%' character */
+ pj_cis_t pjsip_VIA_PARAM_SPEC; /**< Via param is token + ":" for
+ IPv6. */
+ pj_cis_t pjsip_VIA_PARAM_SPEC_ESC; /**< .. as above without '%' */
+ pj_cis_t pjsip_HEX_SPEC; /**< Hexadecimal digits. */
+ pj_cis_t pjsip_PARAM_CHAR_SPEC; /**< For scanning pname (or pvalue
+ when it's not quoted.) in URI */
+ pj_cis_t pjsip_PARAM_CHAR_SPEC_ESC; /**< Variant without the escape ('%')
+ char */
+ pj_cis_t pjsip_HDR_CHAR_SPEC; /**< Chars in hname/havalue in URL. */
+ pj_cis_t pjsip_HDR_CHAR_SPEC_ESC; /**< Variant without the escape ('%')
+ char */
+ pj_cis_t pjsip_PROBE_USER_HOST_SPEC;/**< Hostname characters. */
+ pj_cis_t pjsip_PASSWD_SPEC; /**< Password. */
+ pj_cis_t pjsip_PASSWD_SPEC_ESC; /**< Variant without the escape ('%')
+ char */
+ pj_cis_t pjsip_USER_SPEC; /**< User */
+ pj_cis_t pjsip_USER_SPEC_ESC; /**< Variant without the escape ('%')
+ char */
+ pj_cis_t pjsip_USER_SPEC_LENIENT; /**< User, with additional '#' char */
+ pj_cis_t pjsip_USER_SPEC_LENIENT_ESC;/**< pjsip_USER_SPEC_ESC with '#' */
+ pj_cis_t pjsip_NOT_NEWLINE; /**< For eating up header, basically
+ any chars except newlines or
+ zero. */
+ pj_cis_t pjsip_NOT_COMMA_OR_NEWLINE;/**< Array elements. */
+ pj_cis_t pjsip_DISPLAY_SPEC; /**< Used when searching for display
+ name. */
+ pj_cis_t pjsip_OTHER_URI_CONTENT; /**< Generic URI content. */
+
+} pjsip_parser_const_t;
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+
+/**
+ * Get parser constants.
+ */
+PJ_DECL(const pjsip_parser_const_t*) pjsip_parser_const(void);
+
+
+/*
+ * Parser utilities.
+ */
+enum
+{
+ PJSIP_PARSE_REMOVE_QUOTE = 1
+};
+
+/* Parse parameter in header (matching the character as token) */
+PJ_DECL(void) pjsip_parse_param_imp(pj_scanner *scanner, pj_pool_t *pool,
+ pj_str_t *pname, pj_str_t *pvalue,
+ unsigned opt);
+/* Parse parameter in URL (matching the character as paramchar) */
+PJ_DECL(void) pjsip_parse_uri_param_imp(pj_scanner *scanner, pj_pool_t *pool,
+ pj_str_t *pname, pj_str_t *pvalue,
+ unsigned opt);
+PJ_DECL(void) pjsip_concat_param_imp(pj_str_t *param, pj_pool_t *pool,
+ const pj_str_t *pname,
+ const pj_str_t *pvalue,
+ int sepchar);
+PJ_DECL(void) pjsip_parse_end_hdr_imp ( pj_scanner *scanner );
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_PARSER_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_private.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_private.h
new file mode 100644
index 0000000..bf07fdd
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_private.h
@@ -0,0 +1,32 @@
+/* $Id: sip_private.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_PRIVATE_H__
+#define __PJSIP_SIP_PRIVATE_H__
+
+/**
+ * @file sip_private.h
+ * @brief Private structures and functions for PJSIP Library.
+ */
+
+#include <pjsip/sip_types.h>
+
+
+#endif /* __PJSIP_PRIVATE_I_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_resolve.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_resolve.h
new file mode 100644
index 0000000..499a7ca
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_resolve.h
@@ -0,0 +1,291 @@
+/* $Id: sip_resolve.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_RESOLVE_H__
+#define __PJSIP_SIP_RESOLVE_H__
+
+/**
+ * @file sip_resolve.h
+ * @brief
+ * This module contains the mechanism to resolve server address as specified by
+ * RFC 3263 - Locating SIP Servers
+ */
+
+#include <pjsip/sip_types.h>
+#include <pjlib-util/resolver.h>
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_RESOLVE SIP SRV Server Resolution (RFC 3263 - Locating SIP Servers)
+ * @ingroup PJSIP_TRANSPORT
+ * @brief Framework to resolve SIP servers based on RFC 3263.
+ * @{
+ * \section PJSIP_RESOLVE_FEATURES Features
+ *
+ * This is the SIP server resolution framework, which is modelled after
+ * RFC 3263 - Locating SIP Servers document. The SIP server resolution
+ * framework is asynchronous; callback will be called once the server
+ * address has been resolved (successfully or with errors).
+ *
+ * \subsection PJSIP_RESOLVE_CONFORMANT Conformance to RFC 3263
+ *
+ * The SIP server resolution framework is modelled after RFC 3263 (Locating
+ * SIP Servers) document, and it provides a single function (#pjsip_resolve())
+ * to resolve a domain into actual IP addresses of the servers, by querying
+ * DNS SRV record and DNS A record where necessary.
+ *
+ * The #pjsip_resolve() function performs the server resolution according
+ * to RFC 3263 with some additional fallback mechanisms, as follows:
+ * - if the target name is an IP address, the callback will be called
+ * immediately with the IP address. If port number was specified, this
+ * port number will be used, otherwise the default port number for the
+ * transport will be used (5060 for TCP/UDP, 5061 for TLS) if the transport
+ * is specified. If the transport is not specified, UDP with port number
+ * 5060 will be used.
+ * - if target name is not an IP address but it contains port number,
+ * then the target name is resolved with DNS A (or AAAA, when IPv6 is
+ * supported in the future) query, and the port is taken from the
+ * port number argument. The callback will be called once the DNS A
+ * resolution completes. If the DNS A resolution returns multiple IP
+ * addresses, these IP addresses will be returned to the caller.
+ * - if target name is not an IP address and port number is not specified,
+ * DNS SRV resolution will be performed for the specified name and
+ * transport type (or UDP when transport is not specified),
+ * then followed by DNS A (or AAAA, when IPv6 is supported)
+ * resolution for each target in the SRV record. If DNS SRV
+ * resolution returns error, DNS A (or AAAA) resolution will be
+ * performed for the original target (it is assumed that the target domain
+ * does not support SRV records). Upon successful completion,
+ * application callback will be called with each IP address of the
+ * target selected based on the load-balancing and fail-over criteria
+ * below.
+ *
+ * The above server resolution procedure differs from RFC 3263 in these
+ * regards:
+ * - currently #pjsip_resolve() doesn't support DNS NAPTR record.
+ * - if transport is not specified, it is assumed to be UDP (the proper
+ * behavior is to query the NAPTR record, but we don't support this
+ * yet).
+ *
+ *
+ * \subsection PJSIP_SIP_RESOLVE_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over
+ *
+ * When multiple targets are returned in the DNS SRV response, server entries
+ * are selected based on the following rule (which is described in RFC 2782):
+ * - targets will be sorted based on the priority first.
+ * - for targets with the same priority, #pjsip_resolve() will select
+ * only one target according to its weight. To select this one target,
+ * the function associates running-sum for all targets, and generates
+ * a random number between zero and the total running-sum (inclusive).
+ * The target selected is the first target with running-sum greater than
+ * or equal to this random number.
+ *
+ * The above procedure will select one target for each priority, allowing
+ * application to fail-over to the next target when the previous target fails.
+ * These targets are returned in the #pjsip_server_addresses structure
+ * argument of the callback.
+ *
+ * \subsection PJSIP_SIP_RESOLVE_SIP_FEATURES SIP SRV Resolver Features
+ *
+ * Some features of the SIP resolver:
+ * - DNS SRV entries are returned on sorted order based on priority
+ * to allow failover to the next appropriate server.
+ * - The procedure in RFC 2782 is used to select server with the same
+ * priority to load-balance the servers load.
+ * - A single function (#pjsip_resolve()) performs all server resolution
+ * works, from resolving the SRV records to getting the actual IP addresses
+ * of the servers with DNS A (or AAAA) resolution.
+ * - When multiple DNS SRV records are returned, parallel DNS A (or AAAA)
+ * queries will be issued simultaneously.
+ * - The PJLIB-UTIL DNS resolver provides additional functionality such as
+ * response caching, query aggregation, parallel nameservers, fallback
+ * nameserver, etc., which will be described below.
+ *
+ *
+ * \subsection PJSIP_RESOLVE_DNS_FEATURES DNS Resolver Features
+ *
+ * The PJSIP server resolution framework uses PJLIB-UTIL DNS resolver engine
+ * for performing the asynchronous DNS request. The PJLIB-UTIL DNS resolver
+ * has some useful features, such as:
+ * - queries are asynchronous with configurable timeout,
+ * - query aggregation to combine multiple pending queries to the same
+ * DNS target into a single DNS request (to save message round-trip and
+ * processing),
+ * - response caching with TTL negotiated between the minimum TTL found in
+ * the response and the maximum TTL allowed in the configuration,
+ * - multiple nameservers, with active nameserver is selected from nameserver
+ * which provides the best response time,
+ * - fallback nameserver, with periodic detection of which name servers are
+ * active or down.
+ * - etc.
+ *
+ * Please consult PJLIB-UTIL DNS resolver documentation for more details.
+ *
+ *
+ * \section PJSIP_RESOLVE_USING Using the Resolver
+ *
+ * To maintain backward compatibility, the resolver MUST be enabled manually.
+ * With the default settings, the resolver WILL NOT perform DNS SRV resolution,
+ * as it will just resolve the name with standard pj_gethostbyname() function.
+ *
+ * Application can enable the SRV resolver by creating the PJLIB-UTIL DNS
+ * resolver with #pjsip_endpt_create_resolver(), configure the
+ * nameservers of the PJLIB-UTIL DNS resolver object by calling
+ * pj_dns_resolver_set_ns() function, and pass the DNS resolver object to
+ * #pjsip_resolver_set_resolver() function.
+ *
+ * Once the resolver is set, it will be used automatically by PJSIP everytime
+ * PJSIP needs to send SIP request/response messages.
+ *
+ *
+ * \section PJSIP_RESOLVE_REFERENCE Reference
+ *
+ * Reference:
+ * - RFC 2782: A DNS RR for specifying the location of services (DNS SRV)
+ * - RFC 3263: Locating SIP Servers
+ */
+
+/**
+ * The server addresses returned by the resolver.
+ */
+typedef struct pjsip_server_addresses
+{
+ /** Number of address records. */
+ unsigned count;
+
+ /** Address records. */
+ struct
+ {
+ /** Preferable transport to be used to contact this address. */
+ pjsip_transport_type_e type;
+
+ /** Server priority (the lower the higher the priority). */
+ unsigned priority;
+
+ /** Server weight (the higher the more load it can handle). */
+ unsigned weight;
+
+ /** The server's address. */
+ pj_sockaddr addr;
+
+ /** Address length. */
+ int addr_len;
+
+ } entry[PJSIP_MAX_RESOLVED_ADDRESSES];
+
+} pjsip_server_addresses;
+
+
+/**
+ * The type of callback function to be called when resolver finishes the job.
+ *
+ * @param status The status of the operation, which is zero on success.
+ * @param token The token that was associated with the job when application
+ * call the resolve function.
+ * @param addr The addresses resolved by the operation.
+ */
+typedef void pjsip_resolver_callback(pj_status_t status,
+ void *token,
+ const struct pjsip_server_addresses *addr);
+
+/**
+ * Create SIP resolver engine. Note that this function is normally called
+ * internally by pjsip_endpoint instance.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param p_res Pointer to receive SIP resolver instance.
+ *
+ * @return PJ_SUCCESS when resolver can be successfully created.
+ */
+PJ_DECL(pj_status_t) pjsip_resolver_create(pj_pool_t *pool,
+ pjsip_resolver_t **p_res);
+
+/**
+ * Set the DNS resolver instance of the SIP resolver engine. Before the
+ * DNS resolver is set, the SIP resolver will use standard pj_gethostbyname()
+ * to resolve addresses.
+ *
+ * Note that application normally will use #pjsip_endpt_set_resolver() instead
+ * since it does not normally have access to the SIP resolver instance.
+ *
+ * @param res The SIP resolver engine.
+ * @param dns_res The DNS resolver instance to be used by the SIP resolver.
+ * This argument can be NULL to reset the internal DNS
+ * instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res,
+ pj_dns_resolver *dns_res);
+
+
+/**
+ * Get the DNS resolver instance of the SIP resolver engine.
+ *
+ * Note that application normally will use #pjsip_endpt_get_resolver() instead
+ * since it does not normally have access to the SIP resolver instance.
+ *
+ * @param res The SIP resolver engine.
+ *
+ * @return The DNS resolver instance (may be NULL)
+ */
+PJ_DECL(pj_dns_resolver*) pjsip_resolver_get_resolver(pjsip_resolver_t *res);
+
+/**
+ * Destroy resolver engine. Note that this will also destroy the internal
+ * DNS resolver inside the engine. If application doesn't want the internal
+ * DNS resolver to be destroyed, it should set the internal DNS resolver
+ * to NULL before calling this function.
+ *
+ * Note that this function will normally called by the SIP endpoint instance
+ * when the SIP endpoint instance is destroyed.
+ *
+ * @param resolver The resolver.
+ */
+PJ_DECL(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver);
+
+/**
+ * Asynchronously resolve a SIP target host or domain according to rule
+ * specified in RFC 3263 (Locating SIP Servers). When the resolving operation
+ * has completed, the callback will be called.
+ *
+ * Note that application normally will use #pjsip_endpt_resolve() instead
+ * since it does not normally have access to the SIP resolver instance.
+ *
+ * @param resolver The resolver engine.
+ * @param pool The pool to allocate resolver job.
+ * @param target The target specification to be resolved.
+ * @param token A user defined token to be passed back to callback function.
+ * @param cb The callback function.
+ */
+PJ_DECL(void) pjsip_resolve( pjsip_resolver_t *resolver,
+ pj_pool_t *pool,
+ const pjsip_host_info *target,
+ void *token,
+ pjsip_resolver_callback *cb);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_RESOLVE_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_tel_uri.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_tel_uri.h
new file mode 100644
index 0000000..03aec7c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_tel_uri.h
@@ -0,0 +1,84 @@
+/* $Id: sip_tel_uri.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_TEL_URI_H__
+#define __PJSIP_TEL_URI_H__
+
+/**
+ * @file sip_tel_uri.h
+ * @brief Tel: URI
+ */
+
+#include <pjsip/sip_uri.h>
+
+/**
+ * @addtogroup PJSIP_TEL_URI tel URI Scheme
+ * @ingroup PJSIP_URI
+ * @brief Support for "tel:" URI scheme.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+/**
+ * tel: URI.
+ */
+typedef struct pjsip_tel_uri
+{
+ pjsip_uri_vptr *vptr; /**< Pointer to virtual function table. */
+ pj_str_t number; /**< Global or local phone number */
+ pj_str_t context; /**< Phone context (for local number). */
+ pj_str_t ext_param; /**< Extension param. */
+ pj_str_t isub_param; /**< ISDN sub-address param. */
+ pjsip_param other_param;/**< Other parameter. */
+} pjsip_tel_uri;
+
+
+/**
+ * Create a new tel: URI.
+ *
+ * @param pool The pool.
+ *
+ * @return New instance of tel: URI.
+ */
+PJ_DECL(pjsip_tel_uri*) pjsip_tel_uri_create(pj_pool_t *pool);
+
+/**
+ * This function compares two numbers for equality, according to rules as
+ * specified in RFC 3966.
+ *
+ * @param nb1 The first number.
+ * @param nb2 The second number.
+ *
+ * @return Zero if equal, -1 if nb1 is less than nb2, or +1 if
+ * nb1 is greater than nb2.
+ */
+PJ_DECL(int) pjsip_tel_nb_cmp(const pj_str_t *nb1, const pj_str_t *nb2);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJSIP_TEL_URI_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transaction.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transaction.h
new file mode 100644
index 0000000..734d891
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transaction.h
@@ -0,0 +1,406 @@
+/* $Id: sip_transaction.h 2646 2009-04-26 11:02:04Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_TRANSACTION_H__
+#define __PJSIP_SIP_TRANSACTION_H__
+
+/**
+ * @file sip_transaction.h
+ * @brief SIP Transaction
+ */
+
+#include <pjsip/sip_msg.h>
+#include <pjsip/sip_util.h>
+#include <pjsip/sip_transport.h>
+#include <pj/timer.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_TRANSACT Transaction Layer
+ * @brief Provides statefull message processing.
+ *
+ * This module provides stateful processing to incoming or outgoing SIP
+ * messages.
+ * Before performing any stateful operations, application must register the
+ * transaction layer module by calling #pjsip_tsx_layer_init_module().
+ *
+ * Application should link with <b>pjsip-core</b> library to
+ * use the transaction layer.
+ */
+
+/**
+ * @defgroup PJSIP_TRANSACT_TRANSACTION Transaction
+ * @ingroup PJSIP_TRANSACT
+ * @brief Transaction instance for all types of SIP transactions.
+ * @{
+ * The pjsip_transaction describes SIP transaction, and is used for
+ * both INVITE and non-INVITE, UAC or UAS. Application must register the
+ * transaction layer module with #pjsip_tsx_layer_init_module() before
+ * performing any stateful operations.
+ */
+
+/**
+ * This enumeration represents transaction state.
+ */
+typedef enum pjsip_tsx_state_e
+{
+ PJSIP_TSX_STATE_NULL, /**< For UAC, before any message is sent. */
+ PJSIP_TSX_STATE_CALLING, /**< For UAC, just after request is sent. */
+ PJSIP_TSX_STATE_TRYING, /**< For UAS, just after request is received.*/
+ PJSIP_TSX_STATE_PROCEEDING, /**< For UAS/UAC, after provisional response.*/
+ PJSIP_TSX_STATE_COMPLETED, /**< For UAS/UAC, after final response. */
+ PJSIP_TSX_STATE_CONFIRMED, /**< For UAS, after ACK is received. */
+ PJSIP_TSX_STATE_TERMINATED, /**< For UAS/UAC, before it's destroyed. */
+ PJSIP_TSX_STATE_DESTROYED, /**< For UAS/UAC, will be destroyed now. */
+ PJSIP_TSX_STATE_MAX /**< Number of states. */
+} pjsip_tsx_state_e;
+
+
+/**
+ * This structure describes SIP transaction object. The transaction object
+ * is used to handle both UAS and UAC transaction.
+ */
+struct pjsip_transaction
+{
+ /*
+ * Administrivia
+ */
+ pj_pool_t *pool; /**< Pool owned by the tsx. */
+ pjsip_module *tsx_user; /**< Transaction user. */
+ pjsip_endpoint *endpt; /**< Endpoint instance. */
+ pj_mutex_t *mutex; /**< Mutex for this tsx. */
+
+ /*
+ * Transaction identification.
+ */
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Log info. */
+ pjsip_role_e role; /**< Role (UAS or UAC) */
+ pjsip_method method; /**< The method. */
+ pj_int32_t cseq; /**< The CSeq */
+ pj_str_t transaction_key;/**< Hash table key. */
+ pj_uint32_t hashed_key; /**< Key's hashed value. */
+ pj_str_t branch; /**< The branch Id. */
+ pjsip_tpselector tp_sel; /**< Transport selector. */
+
+ /*
+ * State and status.
+ */
+ int status_code; /**< Last status code seen. */
+ pj_str_t status_text; /**< Last reason phrase. */
+ pjsip_tsx_state_e state; /**< State. */
+ int handle_200resp; /**< UAS 200/INVITE retrsm.*/
+ int tracing; /**< Tracing enabled? */
+
+ /** Handler according to current state. */
+ pj_status_t (*state_handler)(struct pjsip_transaction *, pjsip_event *);
+
+ /*
+ * Transport.
+ */
+ pjsip_transport *transport; /**< Transport to use. */
+ pj_bool_t is_reliable; /**< Transport is reliable. */
+ pj_sockaddr addr; /**< Destination address. */
+ int addr_len; /**< Address length. */
+ pjsip_response_addr res_addr; /**< Response address. */
+ unsigned transport_flag; /**< Miscelaneous flag. */
+ pj_status_t transport_err; /**< Internal error code. */
+
+ /*
+ * Messages and timer.
+ */
+ pjsip_tx_data *last_tx; /**< Msg kept for retrans. */
+ int retransmit_count;/**< Retransmission count. */
+ pj_timer_entry retransmit_timer;/**< Retransmit timer. */
+ pj_timer_entry timeout_timer; /**< Timeout timer. */
+
+ /** Module specific data. */
+ void *mod_data[PJSIP_MAX_MODULE];
+};
+
+
+/**
+ * Create and register transaction layer module to the specified endpoint.
+ *
+ * @param endpt The endpoint instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_layer_init_module(pjsip_endpoint *endpt);
+
+/**
+ * Get the instance of the transaction layer module.
+ *
+ * @return The transaction layer module.
+ */
+PJ_DECL(pjsip_module*) pjsip_tsx_layer_instance(void);
+
+/**
+ * Unregister and destroy transaction layer module.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_layer_destroy(void);
+
+/**
+ * Retrieve the current number of transactions currently registered
+ * in the hash table.
+ *
+ * @return Number of transactions.
+ */
+PJ_DECL(unsigned) pjsip_tsx_layer_get_tsx_count(void);
+
+/**
+ * Find a transaction with the specified key. The transaction key normally
+ * is created by calling #pjsip_tsx_create_key() from an incoming message.
+ *
+ * @param key The key string to find the transaction.
+ * @param lock If non-zero, transaction will be locked before the
+ * function returns, to make sure that it's not deleted
+ * by other threads.
+ *
+ * @return The matching transaction instance, or NULL if transaction
+ * can not be found.
+ */
+PJ_DECL(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key,
+ pj_bool_t lock );
+
+/**
+ * Create, initialize, and register a new transaction as UAC from the
+ * specified transmit data (\c tdata). The transmit data must have a valid
+ * \c Request-Line and \c CSeq header.
+ *
+ * If \c Via header does not exist, it will be created along with a unique
+ * \c branch parameter. If it exists and contains branch parameter, then
+ * the \c branch parameter will be used as is as the transaction key. If
+ * it exists but branch parameter doesn't exist, a unique branch parameter
+ * will be created.
+ *
+ * @param tsx_user Module to be registered as transaction user of the new
+ * transaction, which will receive notification from the
+ * transaction via on_tsx_state() callback.
+ * @param tdata The outgoing request message.
+ * @param p_tsx On return will contain the new transaction instance.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_create_uac( pjsip_module *tsx_user,
+ pjsip_tx_data *tdata,
+ pjsip_transaction **p_tsx);
+
+/**
+ * Create, initialize, and register a new transaction as UAS from the
+ * specified incoming request in \c rdata. After calling this function,
+ * application MUST call #pjsip_tsx_recv_msg() so that transaction
+ * moves from state NULL.
+ *
+ * @param tsx_user Module to be registered as transaction user of the new
+ * transaction, which will receive notification from the
+ * transaction via on_tsx_state() callback.
+ * @param rdata The received incoming request.
+ * @param p_tsx On return will contain the new transaction instance.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_create_uas( pjsip_module *tsx_user,
+ pjsip_rx_data *rdata,
+ pjsip_transaction **p_tsx );
+
+
+/**
+ * Lock/bind transaction to a specific transport/listener. This is optional,
+ * as normally transport will be selected automatically based on the
+ * destination of the message upon resolver completion.
+ *
+ * @param tsx The transaction.
+ * @param sel Transport selector containing the specification of
+ * transport or listener to be used by this transaction
+ * to send requests.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx,
+ const pjsip_tpselector *sel);
+
+/**
+ * Call this function to manually feed a message to the transaction.
+ * For UAS transaction, application MUST call this function after
+ * UAS transaction has been created.
+ *
+ * This function SHOULD only be called to pass initial request message
+ * to UAS transaction. Before this function returns, on_tsx_state()
+ * callback of the transaction user will be called. If response message
+ * is passed to this function, then on_rx_response() will also be called
+ * before on_tsx_state().
+ *
+ * @param tsx The transaction.
+ * @param rdata The message.
+ */
+PJ_DECL(void) pjsip_tsx_recv_msg( pjsip_transaction *tsx,
+ pjsip_rx_data *rdata);
+
+/**
+ * Transmit message in tdata with this transaction. It is possible to
+ * pass NULL in tdata for UAC transaction, which in this case the last
+ * message transmitted, or the request message which was specified when
+ * calling #pjsip_tsx_create_uac(), will be sent.
+ *
+ * This function decrements the reference counter of the transmit buffer
+ * only when it returns PJ_SUCCESS;
+ *
+ * @param tsx The transaction.
+ * @param tdata The outgoing message. If NULL is specified, then the
+ * last message transmitted (or the message specified
+ * in UAC initialization) will be sent.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_send_msg( pjsip_transaction *tsx,
+ pjsip_tx_data *tdata);
+
+
+/**
+ * Manually retransmit the last message transmitted by this transaction,
+ * without updating the transaction state. This function is useful when
+ * TU wants to maintain the retransmision by itself (for example,
+ * retransmitting reliable provisional response).
+ *
+ * @param tsx The transaction.
+ * @param tdata The outgoing message. If NULL is specified, then the
+ * last message transmitted (or the message specified
+ * in UAC initialization) will be sent.
+ *
+ *
+ * @return PJ_SUCCESS if successful.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_retransmit_no_state(pjsip_transaction *tsx,
+ pjsip_tx_data *tdata);
+
+
+/**
+ * Create transaction key, which is used to match incoming requests
+ * or response (retransmissions) against transactions.
+ *
+ * @param pool The pool
+ * @param key Output key.
+ * @param role The role of the transaction.
+ * @param method The method to be put as a key.
+ * @param rdata The received data to calculate.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_create_key( pj_pool_t *pool,
+ pj_str_t *key,
+ pjsip_role_e role,
+ const pjsip_method *method,
+ const pjsip_rx_data *rdata );
+
+/**
+ * Force terminate transaction.
+ *
+ * @param tsx The transaction.
+ * @param code The status code to report.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_terminate( pjsip_transaction *tsx,
+ int code );
+
+
+/**
+ * Cease retransmission on the UAC transaction. The UAC transaction is
+ * still considered running, and it will complete when either final
+ * response is received or the transaction times out.
+ *
+ * This operation normally is used for INVITE transaction only, when
+ * the transaction is cancelled before any provisional response has been
+ * received.
+ *
+ * @param tsx The transaction.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_stop_retransmit(pjsip_transaction *tsx);
+
+
+/**
+ * Start a timer to terminate transaction after the specified time
+ * has elapsed. This function is only valid for INVITE transaction,
+ * and only before final response is received for the INVITE transaction.
+ * It is normally called after the UAC has sent CANCEL for this
+ * INVITE transaction.
+ *
+ * The purpose of this function is to terminate the transaction if UAS
+ * does not send final response to this INVITE transaction even after
+ * it sends 200/OK to CANCEL (for example when the UAS complies to RFC
+ * 2543).
+ *
+ * Once this timer is set, the transaction will be terminated either when
+ * a final response is received or the timer expires.
+ *
+ * @param tsx The transaction.
+ * @param millisec Timeout value in milliseconds.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_set_timeout(pjsip_transaction *tsx,
+ unsigned millisec);
+
+
+/**
+ * Get the transaction instance in the incoming message. If the message
+ * has a corresponding transaction, this function will return non NULL
+ * value.
+ *
+ * @param rdata The incoming message buffer.
+ *
+ * @return The transaction instance associated with this message,
+ * or NULL if the message doesn't match any transactions.
+ */
+PJ_DECL(pjsip_transaction*) pjsip_rdata_get_tsx( pjsip_rx_data *rdata );
+
+
+/**
+ * @}
+ */
+
+/*
+ * Internal.
+ */
+
+/*
+ * Dump transaction layer.
+ */
+PJ_DECL(void) pjsip_tsx_layer_dump(pj_bool_t detail);
+
+/**
+ * Get the string name for the state.
+ * @param state State
+ */
+PJ_DECL(const char *) pjsip_tsx_state_str(pjsip_tsx_state_e state);
+
+/**
+ * Get the role name.
+ * @param role Role.
+ */
+PJ_DECL(const char *) pjsip_role_name(pjsip_role_e role);
+
+
+PJ_END_DECL
+
+#endif /* __PJSIP_TRANSACT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport.h
new file mode 100644
index 0000000..4a52628
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport.h
@@ -0,0 +1,1193 @@
+/* $Id: sip_transport.h 2985 2009-11-04 13:17:31Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_TRANSPORT_H__
+#define __PJSIP_SIP_TRANSPORT_H__
+
+/**
+ * @file sip_transport.h
+ * @brief SIP Transport
+ */
+
+#include <pjsip/sip_msg.h>
+#include <pjsip/sip_parser.h>
+#include <pjsip/sip_resolve.h>
+#include <pj/sock.h>
+#include <pj/list.h>
+#include <pj/ioqueue.h>
+#include <pj/timer.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_TRANSPORT Transport
+ * @ingroup PJSIP_CORE
+ * @brief This is the transport framework.
+ *
+ * The transport framework is fully extensible. Please see
+ * <A HREF="/docs.htm">PJSIP Developer's Guide</A> PDF
+ * document for more information.
+ *
+ * Application MUST register at least one transport to PJSIP before any
+ * messages can be sent or received. Please see @ref PJSIP_TRANSPORT_UDP
+ * on how to create/register UDP transport to the transport framework.
+ *
+ * @{
+ */
+
+/*****************************************************************************
+ *
+ * GENERAL TRANSPORT (NAMES, TYPES, ETC.)
+ *
+ *****************************************************************************/
+
+/*
+ * Forward declaration for transport factory (since it is referenced by
+ * the transport factory itself).
+ */
+typedef struct pjsip_tpfactory pjsip_tpfactory;
+
+
+/**
+ * Flags for SIP transports.
+ */
+enum pjsip_transport_flags_e
+{
+ PJSIP_TRANSPORT_RELIABLE = 1, /**< Transport is reliable. */
+ PJSIP_TRANSPORT_SECURE = 2, /**< Transport is secure. */
+ PJSIP_TRANSPORT_DATAGRAM = 4 /**< Datagram based transport.
+ (it's also assumed to be
+ connectionless) */
+};
+
+/**
+ * Check if transport tp is reliable.
+ */
+#define PJSIP_TRANSPORT_IS_RELIABLE(tp) \
+ ((tp)->flag & PJSIP_TRANSPORT_RELIABLE)
+
+/**
+ * Check if transport tp is secure.
+ */
+#define PJSIP_TRANSPORT_IS_SECURE(tp) \
+ ((tp)->flag & PJSIP_TRANSPORT_SECURE)
+
+/**
+ * Register new transport type to PJSIP. The PJSIP transport framework
+ * contains the info for some standard transports, as declared by
+ * #pjsip_transport_type_e. Application may use non-standard transport
+ * with PJSIP, but before it does so, it must register the information
+ * about the new transport type to PJSIP by calling this function.
+ *
+ * @param tp_flag The flags describing characteristics of this
+ * transport type.
+ * @param tp_name Transport type name.
+ * @param def_port Default port to be used for the transport.
+ * @param p_tp_type On successful registration, it will be filled with
+ * the registered type. This argument is optional.
+ *
+ * @return PJ_SUCCESS if registration is successful, or
+ * PJSIP_ETYPEEXISTS if the same transport type has
+ * already been registered.
+ */
+PJ_DECL(pj_status_t) pjsip_transport_register_type(unsigned tp_flag,
+ const char *tp_name,
+ int def_port,
+ int *p_tp_type);
+
+
+/**
+ * Get the transport type from the transport name.
+ *
+ * @param name Transport name, such as "TCP", or "UDP".
+ *
+ * @return The transport type, or PJSIP_TRANSPORT_UNSPECIFIED if
+ * the name is not recognized as the name of supported
+ * transport.
+ */
+PJ_DECL(pjsip_transport_type_e)
+pjsip_transport_get_type_from_name(const pj_str_t *name);
+
+/**
+ * Get the transport type for the specified flags.
+ *
+ * @param flag The transport flag.
+ *
+ * @return Transport type.
+ */
+PJ_DECL(pjsip_transport_type_e)
+pjsip_transport_get_type_from_flag(unsigned flag);
+
+/**
+ * Get the socket address family of a given transport type.
+ *
+ * @param type Transport type.
+ *
+ * @return Transport type.
+ */
+PJ_DECL(int) pjsip_transport_type_get_af(pjsip_transport_type_e type);
+
+/**
+ * Get transport flag from type.
+ *
+ * @param type Transport type.
+ *
+ * @return Transport flags.
+ */
+PJ_DECL(unsigned)
+pjsip_transport_get_flag_from_type( pjsip_transport_type_e type );
+
+/**
+ * Get the default SIP port number for the specified type.
+ *
+ * @param type Transport type.
+ *
+ * @return The port number, which is the default SIP port number for
+ * the specified type.
+ */
+PJ_DECL(int)
+pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type);
+
+/**
+ * Get transport type name.
+ *
+ * @param t Transport type.
+ *
+ * @return Transport name.
+ */
+PJ_DECL(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e t);
+
+/**
+ * Get longer description for the specified transport type.
+ *
+ * @param t Transport type.
+ *
+ * @return Transport description.
+ */
+PJ_DECL(const char*) pjsip_transport_get_type_desc(pjsip_transport_type_e t);
+
+
+
+/*****************************************************************************
+ *
+ * TRANSPORT SELECTOR.
+ *
+ *****************************************************************************/
+
+/**
+ * This structure describes the type of data in pjsip_tpselector.
+ */
+typedef enum pjsip_tpselector_type
+{
+ /** Transport is not specified. */
+ PJSIP_TPSELECTOR_NONE,
+
+ /** Use the specific transport to send request. */
+ PJSIP_TPSELECTOR_TRANSPORT,
+
+ /** Use the specific listener to send request. */
+ PJSIP_TPSELECTOR_LISTENER,
+
+} pjsip_tpselector_type;
+
+
+/**
+ * This structure describes the transport/listener preference to be used
+ * when sending outgoing requests.
+ *
+ * Normally transport will be selected automatically according to rules about
+ * sending requests. But some applications (such as proxies or B2BUAs) may
+ * want to explicitly use specific transport to send requests, for example
+ * when they want to make sure that outgoing request should go from a specific
+ * network interface.
+ *
+ * The pjsip_tpselector structure is used for that purpose, i.e. to allow
+ * application specificly request that a particular transport/listener
+ * should be used to send request. This structure is used when calling
+ * pjsip_tsx_set_transport() and pjsip_dlg_set_transport().
+ */
+typedef struct pjsip_tpselector
+{
+ /** The type of data in the union */
+ pjsip_tpselector_type type;
+
+ /** Union representing the transport/listener criteria to be used. */
+ union {
+ pjsip_transport *transport;
+ pjsip_tpfactory *listener;
+ void *ptr;
+ } u;
+
+} pjsip_tpselector;
+
+
+/**
+ * Add transport/listener reference in the selector to prevent the specified
+ * transport/listener from being destroyed while application still has
+ * reference to it.
+ *
+ * @param sel The transport selector.
+ */
+PJ_DECL(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel);
+
+
+/**
+ * Decrement transport/listener reference in the selector.
+ * @param sel The transport selector
+ */
+PJ_DECL(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel);
+
+
+/*****************************************************************************
+ *
+ * RECEIVE DATA BUFFER.
+ *
+ *****************************************************************************/
+
+/**
+ * A customized ioqueue async operation key which is used by transport
+ * to locate rdata when a pending read operation completes.
+ */
+typedef struct pjsip_rx_data_op_key
+{
+ pj_ioqueue_op_key_t op_key; /**< ioqueue op_key. */
+ pjsip_rx_data *rdata; /**< rdata associated with this */
+} pjsip_rx_data_op_key;
+
+
+/**
+ * Incoming message buffer.
+ * This structure keep all the information regarding the received message. This
+ * buffer lifetime is only very short, normally after the transaction has been
+ * called, this buffer will be deleted/recycled. So care must be taken when
+ * allocating storage from the pool of this buffer.
+ */
+struct pjsip_rx_data
+{
+
+ /**
+ * tp_info is part of rdata that remains static for the duration of the
+ * buffer. It is initialized when the buffer was created by transport.
+ */
+ struct
+ {
+ /** Memory pool for this buffer. */
+ pj_pool_t *pool;
+
+ /** The transport object which received this packet. */
+ pjsip_transport *transport;
+
+ /** Other transport specific data to be attached to this buffer. */
+ void *tp_data;
+
+ /** Ioqueue key. */
+ pjsip_rx_data_op_key op_key;
+
+ } tp_info;
+
+
+ /**
+ * pkt_info is initialized by transport when it receives an incoming
+ * packet.
+ */
+ struct
+ {
+ /** Time when the message was received. */
+ pj_time_val timestamp;
+
+ /** Pointer to the original packet. */
+ char packet[PJSIP_MAX_PKT_LEN];
+
+ /** Zero termination for the packet. */
+ pj_uint32_t zero;
+
+ /** The length of the packet received. */
+ pj_ssize_t len;
+
+ /** The source address from which the packet was received. */
+ pj_sockaddr src_addr;
+
+ /** The length of the source address. */
+ int src_addr_len;
+
+ /** The IP source address string (NULL terminated). */
+ char src_name[PJ_INET6_ADDRSTRLEN];
+
+ /** The IP source port number. */
+ int src_port;
+
+ } pkt_info;
+
+
+ /**
+ * msg_info is initialized by transport mgr (tpmgr) before this buffer
+ * is passed to endpoint.
+ */
+ struct
+ {
+ /** Start of msg buffer. */
+ char *msg_buf;
+
+ /** Length fo message. */
+ int len;
+
+ /** The parsed message, if any. */
+ pjsip_msg *msg;
+
+ /** Short description about the message.
+ * Application should use #pjsip_rx_data_get_info() instead.
+ */
+ char *info;
+
+ /** The Call-ID header as found in the message. */
+ pjsip_cid_hdr *cid;
+
+ /** The From header as found in the message. */
+ pjsip_from_hdr *from;
+
+ /** The To header as found in the message. */
+ pjsip_to_hdr *to;
+
+ /** The topmost Via header as found in the message. */
+ pjsip_via_hdr *via;
+
+ /** The CSeq header as found in the message. */
+ pjsip_cseq_hdr *cseq;
+
+ /** Max forwards header. */
+ pjsip_max_fwd_hdr *max_fwd;
+
+ /** The first route header. */
+ pjsip_route_hdr *route;
+
+ /** The first record-route header. */
+ pjsip_rr_hdr *record_route;
+
+ /** Content-type header. */
+ pjsip_ctype_hdr *ctype;
+
+ /** Content-length header. */
+ pjsip_clen_hdr *clen;
+
+ /** "Require" header containing aggregates of all Require
+ * headers found in the message, or NULL.
+ */
+ pjsip_require_hdr *require;
+
+ /** "Supported" header containing aggregates of all Supported
+ * headers found in the message, or NULL.
+ */
+ pjsip_supported_hdr *supported;
+
+ /** The list of error generated by the parser when parsing
+ this message.
+ */
+ pjsip_parser_err_report parse_err;
+
+ } msg_info;
+
+
+ /**
+ * endpt_info is initialized by endpoint after this buffer reaches
+ * endpoint.
+ */
+ struct
+ {
+ /**
+ * Data attached by modules to this message.
+ */
+ void *mod_data[PJSIP_MAX_MODULE];
+
+ } endpt_info;
+
+};
+
+/**
+ * Get printable information about the message in the rdata.
+ *
+ * @param rdata The receive data buffer.
+ *
+ * @return Printable information.
+ */
+PJ_DECL(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata);
+
+
+/*****************************************************************************
+ *
+ * TRANSMIT DATA BUFFER MANIPULATION.
+ *
+ *****************************************************************************/
+
+/** Customized ioqueue async operation key, used by transport to keep
+ * callback parameters.
+ */
+typedef struct pjsip_tx_data_op_key
+{
+ /** ioqueue pending operation key. */
+ pj_ioqueue_op_key_t key;
+
+ /** Transmit data associated with this key. */
+ pjsip_tx_data *tdata;
+
+ /** Arbitrary token (attached by transport) */
+ void *token;
+
+ /** Callback to be called when pending transmit operation has
+ completed.
+ */
+ void (*callback)(pjsip_transport*,void*,pj_ssize_t);
+} pjsip_tx_data_op_key;
+
+
+/**
+ * Data structure for sending outgoing message. Application normally creates
+ * this buffer by calling #pjsip_endpt_create_tdata.
+ *
+ * The lifetime of this buffer is controlled by the reference counter in this
+ * structure, which is manipulated by calling #pjsip_tx_data_add_ref and
+ * #pjsip_tx_data_dec_ref. When the reference counter has reached zero, then
+ * this buffer will be destroyed.
+ *
+ * A transaction object normally will add reference counter to this buffer
+ * when application calls #pjsip_tsx_send_msg, because it needs to keep the
+ * message for retransmission. The transaction will release the reference
+ * counter once its state has reached final state.
+ */
+struct pjsip_tx_data
+{
+ /** This is for transmission queue; it's managed by transports. */
+ PJ_DECL_LIST_MEMBER(struct pjsip_tx_data);
+
+ /** Memory pool for this buffer. */
+ pj_pool_t *pool;
+
+ /** A name to identify this buffer. */
+ char obj_name[PJ_MAX_OBJ_NAME];
+
+ /** Short information describing this buffer and the message in it.
+ * Application should use #pjsip_tx_data_get_info() instead of
+ * directly accessing this member.
+ */
+ char *info;
+
+ /** For response message, this contains the reference to timestamp when
+ * the original request message was received. The value of this field
+ * is set when application creates response message to a request by
+ * calling #pjsip_endpt_create_response.
+ */
+ pj_time_val rx_timestamp;
+
+ /** The transport manager for this buffer. */
+ pjsip_tpmgr *mgr;
+
+ /** Ioqueue asynchronous operation key. */
+ pjsip_tx_data_op_key op_key;
+
+ /** Lock object. */
+ pj_lock_t *lock;
+
+ /** The message in this buffer. */
+ pjsip_msg *msg;
+
+ /** Strict route header saved by #pjsip_process_route_set(), to be
+ * restored by #pjsip_restore_strict_route_set().
+ */
+ pjsip_route_hdr *saved_strict_route;
+
+ /** Buffer to the printed text representation of the message. When the
+ * content of this buffer is set, then the transport will send the content
+ * of this buffer instead of re-printing the message structure. If the
+ * message structure has changed, then application must invalidate this
+ * buffer by calling #pjsip_tx_data_invalidate_msg.
+ */
+ pjsip_buffer buf;
+
+ /** Reference counter. */
+ pj_atomic_t *ref_cnt;
+
+ /** Being processed by transport? */
+ int is_pending;
+
+ /** Transport manager internal. */
+ void *token;
+
+ /** Callback to be called when this tx_data has been transmitted. */
+ void (*cb)(void*, pjsip_tx_data*, pj_ssize_t);
+
+ /** Destination information, to be used to determine the network address
+ * of the message. For a request, this information is initialized when
+ * the request is sent with #pjsip_endpt_send_request_stateless() and
+ * network address is resolved. For CANCEL request, this information
+ * will be copied from the original INVITE to make sure that the CANCEL
+ * request goes to the same physical network address as the INVITE
+ * request.
+ */
+ struct
+ {
+ /** Server addresses resolved.
+ */
+ pjsip_server_addresses addr;
+
+ /** Current server address being tried.
+ */
+ unsigned cur_addr;
+
+ } dest_info;
+
+ /** Transport information, only valid during on_tx_request() and
+ * on_tx_response() callback.
+ */
+ struct
+ {
+ pjsip_transport *transport; /**< Transport being used. */
+ pj_sockaddr dst_addr; /**< Destination address. */
+ int dst_addr_len; /**< Length of address. */
+ char dst_name[PJ_INET6_ADDRSTRLEN]; /**< Destination address. */
+ int dst_port; /**< Destination port. */
+ } tp_info;
+
+ /**
+ * Transport selector, to specify which transport to be used.
+ * The value here must be set with pjsip_tx_data_set_transport(),
+ * to allow reference counter to be set properly.
+ */
+ pjsip_tpselector tp_sel;
+
+};
+
+
+/**
+ * Create a new, blank transmit buffer. The reference count is initialized
+ * to zero.
+ *
+ * @param mgr The transport manager.
+ * @param tdata Pointer to receive transmit data.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ *
+ * @see pjsip_endpt_create_tdata
+ */
+PJ_DECL(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,
+ pjsip_tx_data **tdata );
+
+/**
+ * Add reference counter to the transmit buffer. The reference counter controls
+ * the life time of the buffer, ie. when the counter reaches zero, then it
+ * will be destroyed.
+ *
+ * @param tdata The transmit buffer.
+ */
+PJ_DECL(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata );
+
+/**
+ * Decrement reference counter of the transmit buffer.
+ * When the transmit buffer is no longer used, it will be destroyed and
+ * caller is informed with PJSIP_EBUFDESTROYED return status.
+ *
+ * @param tdata The transmit buffer data.
+ * @return This function will always succeeded eventhough the return
+ * status is non-zero. A status PJSIP_EBUFDESTROYED will be
+ * returned to inform that buffer is destroyed.
+ */
+PJ_DECL(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata );
+
+/**
+ * Print the SIP message to transmit data buffer's internal buffer. This
+ * may allocate memory for the buffer, if the buffer has not been allocated
+ * yet, and encode the SIP message to that buffer.
+ *
+ * @param tdata The transmit buffer.
+ *
+ * @return PJ_SUCCESS on success of the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tx_data_encode(pjsip_tx_data *tdata);
+
+/**
+ * Check if transmit data buffer contains a valid message.
+ *
+ * @param tdata The transmit buffer.
+ * @return Non-zero (PJ_TRUE) if buffer contains a valid message.
+ */
+PJ_DECL(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata );
+
+/**
+ * Invalidate the print buffer to force message to be re-printed. Call
+ * when the message has changed after it has been printed to buffer. The
+ * message is printed to buffer normally by transport when it is about to be
+ * sent to the wire. Subsequent sending of the message will not cause
+ * the message to be re-printed, unless application invalidates the buffer
+ * by calling this function.
+ *
+ * @param tdata The transmit buffer.
+ */
+PJ_DECL(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata );
+
+/**
+ * Get short printable info about the transmit data. This will normally return
+ * short information about the message.
+ *
+ * @param tdata The transmit buffer.
+ *
+ * @return Null terminated info string.
+ */
+PJ_DECL(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata );
+
+/**
+ * Set the explicit transport to be used when sending this transmit data.
+ * Application should not need to call this function, but rather use
+ * pjsip_tsx_set_transport() and pjsip_dlg_set_transport() instead (which
+ * will call this function).
+ *
+ * @param tdata The transmit buffer.
+ * @param sel Transport selector.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,
+ const pjsip_tpselector *sel);
+
+
+/*****************************************************************************
+ *
+ * TRANSPORT
+ *
+ *****************************************************************************/
+/**
+ * Type of callback to receive transport operation status.
+ */
+typedef void (*pjsip_transport_callback)(pjsip_transport *tp, void *token,
+ pj_ssize_t sent_bytes);
+
+/**
+ * This structure describes transport key to be registered to hash table.
+ */
+typedef struct pjsip_transport_key
+{
+ /**
+ * Transport type.
+ */
+ long type;
+
+ /**
+ * Destination address.
+ */
+ pj_sockaddr rem_addr;
+
+} pjsip_transport_key;
+
+/**
+ * This structure represent the "public" interface of a SIP transport.
+ * Applications normally extend this structure to include transport
+ * specific members.
+ */
+struct pjsip_transport
+{
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Name. */
+
+ pj_pool_t *pool; /**< Pool used by transport. */
+ pj_atomic_t *ref_cnt; /**< Reference counter. */
+ pj_lock_t *lock; /**< Lock object. */
+ pj_bool_t tracing; /**< Tracing enabled? */
+ pj_bool_t is_shutdown; /**< Being shutdown? */
+
+ /** Key for indexing this transport in hash table. */
+ pjsip_transport_key key;
+
+ char *type_name; /**< Type name. */
+ unsigned flag; /**< #pjsip_transport_flags_e */
+ char *info; /**< Transport info/description.*/
+
+ int addr_len; /**< Length of addresses. */
+ pj_sockaddr local_addr; /**< Bound address. */
+ pjsip_host_port local_name; /**< Published name (eg. STUN). */
+ pjsip_host_port remote_name; /**< Remote address name. */
+
+ pjsip_endpoint *endpt; /**< Endpoint instance. */
+ pjsip_tpmgr *tpmgr; /**< Transport manager. */
+ pj_timer_entry idle_timer; /**< Timer when ref cnt is zero.*/
+
+ /**
+ * Function to be called by transport manager to send SIP message.
+ *
+ * @param transport The transport to send the message.
+ * @param packet The buffer to send.
+ * @param length The length of the buffer to send.
+ * @param op_key Completion token, which will be supplied to
+ * caller when pending send operation completes.
+ * @param rem_addr The remote destination address.
+ * @param addr_len Size of remote address.
+ * @param callback If supplied, the callback will be called
+ * once a pending transmission has completed. If
+ * the function completes immediately (i.e. return
+ * code is not PJ_EPENDING), the callback will not
+ * be called.
+ *
+ * @return Should return PJ_SUCCESS only if data has been
+ * succesfully queued to operating system for
+ * transmission. Otherwise it may return PJ_EPENDING
+ * if the underlying transport can not send the
+ * data immediately and will send it later, which in
+ * this case caller doesn't have to do anything
+ * except wait the calback to be called, if it
+ * supplies one.
+ * Other return values indicate the error code.
+ */
+ pj_status_t (*send_msg)(pjsip_transport *transport,
+ pjsip_tx_data *tdata,
+ const pj_sockaddr_t *rem_addr,
+ int addr_len,
+ void *token,
+ pjsip_transport_callback callback);
+
+ /**
+ * Instruct the transport to initiate graceful shutdown procedure.
+ * After all objects release their reference to this transport,
+ * the transport will be deleted.
+ *
+ * Note that application MUST use #pjsip_transport_shutdown() instead.
+ *
+ * @param transport The transport.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*do_shutdown)(pjsip_transport *transport);
+
+ /**
+ * Forcefully destroy this transport regardless whether there are
+ * objects that currently use this transport. This function should only
+ * be called by transport manager or other internal objects (such as the
+ * transport itself) who know what they're doing. Application should use
+ * #pjsip_transport_shutdown() instead.
+ *
+ * @param transport The transport.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*destroy)(pjsip_transport *transport);
+
+ /*
+ * Application may extend this structure..
+ */
+};
+
+
+/**
+ * Register a transport instance to the transport manager. This function
+ * is normally called by the transport instance when it is created
+ * by application.
+ *
+ * @param mgr The transport manager.
+ * @param tp The new transport to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
+ pjsip_transport *tp );
+
+
+/**
+ * Start graceful shutdown procedure for this transport. After graceful
+ * shutdown has been initiated, no new reference can be obtained for
+ * the transport. However, existing objects that currently uses the
+ * transport may still use this transport to send and receive packets.
+ *
+ * After all objects release their reference to this transport,
+ * the transport will be destroyed immediately.
+ *
+ * @param tp The transport.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_transport_shutdown(pjsip_transport *tp);
+
+/**
+ * Destroy a transport when there is no object currently uses the transport.
+ * This function is normally called internally by transport manager or the
+ * transport itself. Application should use #pjsip_transport_shutdown()
+ * instead.
+ *
+ * @param tp The transport instance.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ * Some of possible errors are PJSIP_EBUSY if the
+ * transport's reference counter is not zero.
+ */
+PJ_DECL(pj_status_t) pjsip_transport_destroy( pjsip_transport *tp);
+
+/**
+ * Add reference counter to the specified transport. Any objects that wishes
+ * to keep the reference of the transport MUST increment the transport's
+ * reference counter to prevent it from being destroyed.
+ *
+ * @param tp The transport instance.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_transport_add_ref( pjsip_transport *tp );
+
+/**
+ * Decrement reference counter of the specified transport. When an object no
+ * longer want to keep the reference to the transport, it must decrement the
+ * reference counter. When the reference counter of the transport reaches
+ * zero, the transport manager will start the idle timer to destroy the
+ * transport if no objects acquire the reference counter during the idle
+ * interval.
+ *
+ * @param tp The transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp );
+
+
+/**
+ * This function is called by transport instances to report an incoming
+ * packet to the transport manager. The transport manager then would try to
+ * parse all SIP messages in the packet, and for each parsed SIP message, it
+ * would report the message to the SIP endpoint (#pjsip_endpoint).
+ *
+ * @param mgr The transport manager instance.
+ * @param rdata The receive data buffer containing the packet. The
+ * transport MUST fully initialize tp_info and pkt_info
+ * member of the rdata.
+ *
+ * @return The number of bytes successfully processed from the
+ * packet. If the transport is datagram oriented, the
+ * value will be equal to the size of the packet. For
+ * stream oriented transport (e.g. TCP, TLS), the value
+ * returned may be less than the packet size, if
+ * partial message is received. The transport then MUST
+ * keep the remainder part and report it again to
+ * this function once more data/packet is received.
+ */
+PJ_DECL(pj_ssize_t) pjsip_tpmgr_receive_packet(pjsip_tpmgr *mgr,
+ pjsip_rx_data *rdata);
+
+
+/*****************************************************************************
+ *
+ * TRANSPORT FACTORY
+ *
+ *****************************************************************************/
+
+
+/**
+ * A transport factory is normally used for connection oriented transports
+ * (such as TCP or TLS) to create instances of transports. It registers
+ * a new transport type to the transport manager, and the transport manager
+ * would ask the factory to create a transport instance when it received
+ * command from application to send a SIP message using the specified
+ * transport type.
+ */
+struct pjsip_tpfactory
+{
+ /** This list is managed by transport manager. */
+ PJ_DECL_LIST_MEMBER(struct pjsip_tpfactory);
+
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Name. */
+
+ pj_pool_t *pool; /**< Owned memory pool. */
+ pj_lock_t *lock; /**< Lock object. */
+
+ pjsip_transport_type_e type; /**< Transport type. */
+ char *type_name; /**< Type string name. */
+ unsigned flag; /**< Transport flag. */
+
+ pj_sockaddr local_addr; /**< Bound address. */
+ pjsip_host_port addr_name; /**< Published name. */
+
+ /**
+ * Create new outbound connection.
+ * Note that the factory is responsible for both creating the
+ * transport and registering it to the transport manager.
+ */
+ pj_status_t (*create_transport)(pjsip_tpfactory *factory,
+ pjsip_tpmgr *mgr,
+ pjsip_endpoint *endpt,
+ const pj_sockaddr *rem_addr,
+ int addr_len,
+ pjsip_transport **transport);
+
+ /**
+ * Destroy the listener.
+ */
+ pj_status_t (*destroy)(pjsip_tpfactory *factory);
+
+ /*
+ * Application may extend this structure..
+ */
+};
+
+
+
+/**
+ * Register a transport factory.
+ *
+ * @param mgr The transport manager.
+ * @param tpf Transport factory.
+ *
+ * @return PJ_SUCCESS if listener was successfully created.
+ */
+PJ_DECL(pj_status_t) pjsip_tpmgr_register_tpfactory(pjsip_tpmgr *mgr,
+ pjsip_tpfactory *tpf);
+
+/**
+ * Unregister factory.
+ *
+ * @param mgr The transport manager.
+ * @param tpf Transport factory.
+ *
+ * @return PJ_SUCCESS is sucessfully unregistered.
+ */
+PJ_DECL(pj_status_t) pjsip_tpmgr_unregister_tpfactory(pjsip_tpmgr *mgr,
+ pjsip_tpfactory *tpf);
+
+
+/*****************************************************************************
+ *
+ * TRANSPORT MANAGER
+ *
+ *****************************************************************************/
+
+/**
+ * Type of callback to be called when transport manager receives incoming
+ * SIP message.
+ *
+ * @param ep Endpoint.
+ * @param status Receiption status.
+ * @param rd Received packet.
+ */
+typedef void (*pjsip_rx_callback)(pjsip_endpoint *ep, pj_status_t status,
+ pjsip_rx_data *rd);
+
+/**
+ * Type of callback to be called before transport manager is about
+ * to transmit SIP message.
+ *
+ * @param ep Endpoint.
+ * @param td Transmit data.
+ */
+typedef pj_status_t (*pjsip_tx_callback)(pjsip_endpoint *ep, pjsip_tx_data*td);
+
+/**
+ * Create a transport manager. Normally application doesn't need to call
+ * this function directly, since a transport manager will be created and
+ * destroyed automatically by the SIP endpoint.
+ *
+ * @param pool Pool.
+ * @param endpt Endpoint instance.
+ * @param rx_cb Callback to receive incoming message.
+ * @param tx_cb Callback to be called before transport manager is sending
+ * outgoing message.
+ * @param p_mgr Pointer to receive the new transport manager.
+ *
+ * @return PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool,
+ pjsip_endpoint * endpt,
+ pjsip_rx_callback rx_cb,
+ pjsip_tx_callback tx_cb,
+ pjsip_tpmgr **p_mgr);
+
+
+/**
+ * Find out the appropriate local address info (IP address and port) to
+ * advertise in Contact header based on the remote address to be
+ * contacted. The local address info would be the address name of the
+ * transport or listener which will be used to send the request.
+ *
+ * In this implementation, it will only select the transport based on
+ * the transport type in the request.
+ *
+ * @param tpmgr The transport manager.
+ * @param pool Pool to allocate memory for the IP address.
+ * @param type Destination address to contact.
+ * @param sel Optional pointer to prefered transport, if any.
+ * @param ip_addr Pointer to receive the IP address.
+ * @param port Pointer to receive the port number.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr,
+ pj_pool_t *pool,
+ pjsip_transport_type_e type,
+ const pjsip_tpselector *sel,
+ pj_str_t *ip_addr,
+ int *port);
+
+/**
+ * Return number of transports currently registered to the transport
+ * manager.
+ *
+ * @param mgr The transport manager.
+ *
+ * @return Number of transports.
+ */
+PJ_DECL(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr);
+
+
+/**
+ * Destroy a transport manager. Normally application doesn't need to call
+ * this function directly, since a transport manager will be created and
+ * destroyed automatically by the SIP endpoint.
+ *
+ * @param mgr The transport manager.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_tpmgr_destroy(pjsip_tpmgr *mgr);
+
+
+/**
+ * Dump transport info and status to log.
+ *
+ * @param mgr The transport manager.
+ */
+PJ_DECL(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr);
+
+
+/*****************************************************************************
+ *
+ * PUBLIC API
+ *
+ *****************************************************************************/
+
+
+/**
+ * Find transport to be used to send message to remote destination. If no
+ * suitable transport is found, a new one will be created.
+ *
+ * This is an internal function since normally application doesn't have access
+ * to transport manager. Application should use pjsip_endpt_acquire_transport()
+ * instead.
+ *
+ * @param mgr The transport manager instance.
+ * @param type The type of transport to be acquired.
+ * @param remote The remote address to send message to.
+ * @param addr_len Length of the remote address.
+ * @param sel Optional pointer to transport selector instance which is
+ * used to find explicit transport, if required.
+ * @param tp Pointer to receive the transport instance, if one is found.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,
+ pjsip_transport_type_e type,
+ const pj_sockaddr_t *remote,
+ int addr_len,
+ const pjsip_tpselector *sel,
+ pjsip_transport **tp);
+
+/**
+ * Type of callback to receive notification when message or raw data
+ * has been sent.
+ *
+ * @param token The token that was given when calling the function
+ * to send message or raw data.
+ * @param tdata The transmit buffer used to send the message.
+ * @param bytes_sent Number of bytes sent. On success, the value will be
+ * positive number indicating the number of bytes sent.
+ * On failure, the value will be a negative number of
+ * the error code (i.e. bytes_sent = -status).
+ */
+typedef void (*pjsip_tp_send_callback)(void *token, pjsip_tx_data *tdata,
+ pj_ssize_t bytes_sent);
+
+
+/**
+ * This is a low-level function to send a SIP message using the specified
+ * transport to the specified destination.
+ *
+ * @param tr The SIP transport to be used.
+ * @param tdata Transmit data buffer containing SIP message.
+ * @param addr Destination address.
+ * @param addr_len Length of destination address.
+ * @param token Arbitrary token to be returned back to callback.
+ * @param cb Optional callback to be called to notify caller about
+ * the completion status of the pending send operation.
+ *
+ * @return If the message has been sent successfully, this function
+ * will return PJ_SUCCESS and the callback will not be
+ * called. If message cannot be sent immediately, this
+ * function will return PJ_EPENDING, and application will
+ * be notified later about the completion via the callback.
+ * Any statuses other than PJ_SUCCESS or PJ_EPENDING
+ * indicates immediate failure, and in this case the
+ * callback will not be called.
+ */
+PJ_DECL(pj_status_t) pjsip_transport_send( pjsip_transport *tr,
+ pjsip_tx_data *tdata,
+ const pj_sockaddr_t *addr,
+ int addr_len,
+ void *token,
+ pjsip_tp_send_callback cb);
+
+
+/**
+ * This is a low-level function to send raw data to a destination.
+ *
+ * See also #pjsip_endpt_send_raw() and #pjsip_endpt_send_raw_to_uri().
+ *
+ * @param mgr Transport manager.
+ * @param tp_type Transport type.
+ * @param sel Optional pointer to transport selector instance if
+ * application wants to use a specific transport instance
+ * rather then letting transport manager finds the suitable
+ * transport.
+ * @param tdata Optional transmit data buffer to be used. If this value
+ * is NULL, this function will create one internally. If
+ * tdata is specified, this function will decrement the
+ * reference counter upon completion.
+ * @param raw_data The data to be sent.
+ * @param data_len The length of the data.
+ * @param addr Destination address.
+ * @param addr_len Length of destination address.
+ * @param token Arbitrary token to be returned back to callback.
+ * @param cb Optional callback to be called to notify caller about
+ * the completion status of the pending send operation.
+ *
+ * @return If the message has been sent successfully, this function
+ * will return PJ_SUCCESS and the callback will not be
+ * called. If message cannot be sent immediately, this
+ * function will return PJ_EPENDING, and application will
+ * be notified later about the completion via the callback.
+ * Any statuses other than PJ_SUCCESS or PJ_EPENDING
+ * indicates immediate failure, and in this case the
+ * callback will not be called.
+ */
+PJ_DECL(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr,
+ pjsip_transport_type_e tp_type,
+ const pjsip_tpselector *sel,
+ pjsip_tx_data *tdata,
+ const void *raw_data,
+ pj_size_t data_len,
+ const pj_sockaddr_t *addr,
+ int addr_len,
+ void *token,
+ pjsip_tp_send_callback cb);
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_TRANSPORT_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_loop.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_loop.h
new file mode 100644
index 0000000..7232560
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_loop.h
@@ -0,0 +1,147 @@
+/* $Id: sip_transport_loop.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_TRANSPORT_LOOP_H__
+#define __PJSIP_TRANSPORT_LOOP_H__
+
+
+/**
+ * @file sip_transport_loop.h
+ * @brief
+ * Loopback transport (for debugging)
+ */
+
+
+#include <pjsip/sip_transport.h>
+
+/**
+ * @defgroup PJSIP_TRANSPORT_LOOP Loop Transport
+ * @ingroup PJSIP_TRANSPORT
+ * @brief Loopback transport (for testing purposes).
+ * @{
+ * The loopback transport simply bounce back outgoing messages as
+ * incoming messages. This feature is used mostly during automated
+ * testing, to provide controlled behavior.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Create and start datagram loop transport.
+ *
+ * @param endpt The endpoint instance.
+ * @param transport Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_start( pjsip_endpoint *endpt,
+ pjsip_transport **transport);
+
+
+/**
+ * Enable/disable flag to discard any packets sent using the specified
+ * loop transport.
+ *
+ * @param tp The loop transport.
+ * @param discard If non-zero, any outgoing packets will be discarded.
+ * @param prev_value Optional argument to receive previous value of
+ * the discard flag.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_discard( pjsip_transport *tp,
+ pj_bool_t discard,
+ pj_bool_t *prev_value );
+
+
+/**
+ * Enable/disable flag to simulate network error. When this flag is set,
+ * outgoing transmission will return either immediate error or error via
+ * callback. If error is to be notified via callback, then the notification
+ * will occur after some delay, which is controlled by #pjsip_loop_set_delay().
+ *
+ * @param tp The loop transport.
+ * @param fail_flag If set to 1, the transport will return fail to deliver
+ * the message. If delay is zero, failure will occur
+ * immediately; otherwise it will be reported in callback.
+ * If set to zero, the transport will successfully deliver
+ * the packet.
+ * @param prev_value Optional argument to receive previous value of
+ * the failure flag.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_failure( pjsip_transport *tp,
+ int fail_flag,
+ int *prev_value );
+
+
+/**
+ * Set delay (in miliseconds) before packet is received by the other end
+ * of the loop transport. This will also
+ * control the delay for error notification callback.
+ *
+ * @param tp The loop transport.
+ * @param delay Delay, in miliseconds.
+ * @param prev_value Optional argument to receive previous value of the
+ * delay.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_recv_delay( pjsip_transport *tp,
+ unsigned delay,
+ unsigned *prev_value);
+
+
+/**
+ * Set delay (in miliseconds) before send notification is delivered to sender.
+ * This will also control the delay for error notification callback.
+ *
+ * @param tp The loop transport.
+ * @param delay Delay, in miliseconds.
+ * @param prev_value Optional argument to receive previous value of the
+ * delay.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_send_callback_delay( pjsip_transport *tp,
+ unsigned delay,
+ unsigned *prev_value);
+
+
+/**
+ * Set both receive and send notification delay.
+ *
+ * @param tp The loop transport.
+ * @param delay Delay, in miliseconds.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_delay( pjsip_transport *tp,
+ unsigned delay );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_TRANSPORT_LOOP_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tcp.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tcp.h
new file mode 100644
index 0000000..d7e7452
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tcp.h
@@ -0,0 +1,210 @@
+/* $Id: sip_transport_tcp.h 2966 2009-10-25 09:02:07Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_TRANSPORT_TCP_H__
+#define __PJSIP_TRANSPORT_TCP_H__
+
+/**
+ * @file sip_transport_tcp.h
+ * @brief SIP TCP Transport.
+ */
+
+#include <pjsip/sip_transport.h>
+#include <pj/sock_qos.h>
+
+
+/* Only declare the API if PJ_HAS_TCP is true */
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP!=0
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_TRANSPORT_TCP TCP Transport
+ * @ingroup PJSIP_TRANSPORT
+ * @brief API to create and register TCP transport.
+ * @{
+ * The functions below are used to create TCP transport and register
+ * the transport to the framework.
+ */
+
+/**
+ * Settings to be specified when creating the TCP transport. Application
+ * should initialize this structure with its default values by calling
+ * pjsip_tcp_transport_cfg_default().
+ */
+typedef struct pjsip_tcp_transport_cfg
+{
+ /**
+ * Address family to use. Valid values are pj_AF_INET() and
+ * pj_AF_INET6(). Default is pj_AF_INET().
+ */
+ int af;
+
+ /**
+ * Optional address to bind the socket to. Default is to bind to
+ * PJ_INADDR_ANY and to any available port.
+ */
+ pj_sockaddr bind_addr;
+
+ /**
+ * Optional published address, which is the address to be
+ * advertised as the address of this SIP transport.
+ * By default the bound address will be used as the published address.
+ */
+ pjsip_host_port addr_name;
+
+ /**
+ * Number of simultaneous asynchronous accept() operations to be
+ * supported. It is recommended that the number here corresponds to
+ * the number of processors in the system (or the number of SIP
+ * worker threads).
+ *
+ * Default: 1
+ */
+ unsigned async_cnt;
+
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default is QoS not set.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * Default is QoS not set.
+ */
+ pj_qos_params qos_params;
+
+} pjsip_tcp_transport_cfg;
+
+
+/**
+ * Initialize pjsip_tcp_transport_cfg structure with default values for
+ * the specifed address family.
+ *
+ * @param cfg The structure to initialize.
+ * @param af Address family to be used.
+ */
+PJ_DECL(void) pjsip_tcp_transport_cfg_default(pjsip_tcp_transport_cfg *cfg,
+ int af);
+
+
+/**
+ * Register support for SIP TCP transport by creating TCP listener on
+ * the specified address and port. This function will create an
+ * instance of SIP TCP transport factory and register it to the
+ * transport manager.
+ *
+ * @param endpt The SIP endpoint.
+ * @param local Optional local address to bind, or specify the
+ * address to bind the server socket to. Both IP
+ * interface address and port fields are optional.
+ * If IP interface address is not specified, socket
+ * will be bound to PJ_INADDR_ANY. If port is not
+ * specified, socket will be bound to any port
+ * selected by the operating system.
+ * @param async_cnt Number of simultaneous asynchronous accept()
+ * operations to be supported. It is recommended that
+ * the number here corresponds to the number of
+ * processors in the system (or the number of SIP
+ * worker threads).
+ * @param p_factory Optional pointer to receive the instance of the
+ * SIP TCP transport factory just created.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tcp_transport_start(pjsip_endpoint *endpt,
+ const pj_sockaddr_in *local,
+ unsigned async_cnt,
+ pjsip_tpfactory **p_factory);
+
+
+
+/**
+ * A newer variant of #pjsip_tcp_transport_start(), which allows specifying
+ * the published/public address of the TCP transport.
+ *
+ * @param endpt The SIP endpoint.
+ * @param local Optional local address to bind, or specify the
+ * address to bind the server socket to. Both IP
+ * interface address and port fields are optional.
+ * If IP interface address is not specified, socket
+ * will be bound to PJ_INADDR_ANY. If port is not
+ * specified, socket will be bound to any port
+ * selected by the operating system.
+ * @param a_name Optional published address, which is the address to be
+ * advertised as the address of this SIP transport.
+ * If this argument is NULL, then the bound address
+ * will be used as the published address.
+ * @param async_cnt Number of simultaneous asynchronous accept()
+ * operations to be supported. It is recommended that
+ * the number here corresponds to the number of
+ * processors in the system (or the number of SIP
+ * worker threads).
+ * @param p_factory Optional pointer to receive the instance of the
+ * SIP TCP transport factory just created.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tcp_transport_start2(pjsip_endpoint *endpt,
+ const pj_sockaddr_in *local,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_tpfactory **p_factory);
+
+/**
+ * Another variant of #pjsip_tcp_transport_start().
+ *
+ * @param endpt The SIP endpoint.
+ * @param cfg TCP transport settings. Application should initialize
+ * this setting with #pjsip_tcp_transport_cfg_default().
+ * @param p_factory Optional pointer to receive the instance of the
+ * SIP TCP transport factory just created.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tcp_transport_start3(
+ pjsip_endpoint *endpt,
+ const pjsip_tcp_transport_cfg *cfg,
+ pjsip_tpfactory **p_factory
+ );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* PJ_HAS_TCP */
+
+#endif /* __PJSIP_TRANSPORT_TCP_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tls.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tls.h
new file mode 100644
index 0000000..4cae84c
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tls.h
@@ -0,0 +1,272 @@
+/* $Id: sip_transport_tls.h 2998 2009-11-09 08:51:34Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_TRANSPORT_TLS_H__
+#define __PJSIP_TRANSPORT_TLS_H__
+
+/**
+ * @file sip_transport_tls.h
+ * @brief SIP TLS Transport.
+ */
+
+#include <pjsip/sip_transport.h>
+#include <pj/string.h>
+#include <pj/sock_qos.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_TRANSPORT_TLS TLS Transport
+ * @ingroup PJSIP_TRANSPORT
+ * @brief API to create and register TLS transport.
+ * @{
+ * The functions below are used to create TLS transport and register
+ * the transport to the framework.
+ */
+
+/**
+ * The default SSL method to be used by PJSIP.
+ * Default is PJSIP_TLSV1_METHOD
+ */
+#ifndef PJSIP_SSL_DEFAULT_METHOD
+# define PJSIP_SSL_DEFAULT_METHOD PJSIP_TLSV1_METHOD
+#endif
+
+/** SSL protocol method constants. */
+typedef enum pjsip_ssl_method
+{
+ PJSIP_SSL_UNSPECIFIED_METHOD= 0, /**< Default protocol method. */
+ PJSIP_TLSV1_METHOD = 31, /**< Use SSLv1 method. */
+ PJSIP_SSLV2_METHOD = 20, /**< Use SSLv2 method. */
+ PJSIP_SSLV3_METHOD = 30, /**< Use SSLv3 method. */
+ PJSIP_SSLV23_METHOD = 23 /**< Use SSLv23 method. */
+} pjsip_ssl_method;
+
+
+
+
+/**
+ * TLS transport settings.
+ */
+typedef struct pjsip_tls_setting
+{
+ /**
+ * Certificate of Authority (CA) list file.
+ */
+ pj_str_t ca_list_file;
+
+ /**
+ * Public endpoint certificate file, which will be used as client-
+ * side certificate for outgoing TLS connection, and server-side
+ * certificate for incoming TLS connection.
+ */
+ pj_str_t cert_file;
+
+ /**
+ * Optional private key of the endpoint certificate to be used.
+ */
+ pj_str_t privkey_file;
+
+ /**
+ * Password to open private key.
+ */
+ pj_str_t password;
+
+ /**
+ * TLS protocol method from #pjsip_ssl_method, which can be:
+ * - PJSIP_SSL_UNSPECIFIED_METHOD(0): default (which will use
+ * PJSIP_SSL_DEFAULT_METHOD)
+ * - PJSIP_TLSV1_METHOD(1): TLSv1
+ * - PJSIP_SSLV2_METHOD(2): SSLv2
+ * - PJSIP_SSLV3_METHOD(3): SSL3
+ * - PJSIP_SSLV23_METHOD(23): SSL23
+ *
+ * Default is PJSIP_SSL_UNSPECIFIED_METHOD (0), which in turn will
+ * use PJSIP_SSL_DEFAULT_METHOD, which default value is
+ * PJSIP_TLSV1_METHOD.
+ */
+ int method;
+
+ /**
+ * TLS cipher list string in OpenSSL format. If empty, then default
+ * cipher list of the backend will be used.
+ */
+ pj_str_t ciphers;
+
+ /**
+ * Optionally specify the server name instance to be contacted when
+ * making outgoing TLS connection. This setting is useful when the
+ * server is hosting multiple domains for the same TLS listening
+ * socket.
+ *
+ * Default: empty.
+ */
+ pj_str_t server_name;
+
+ /**
+ * When PJSIP is acting as a client (outgoing TLS connections),
+ * it will always receive a certificate from the peer.
+ * If \a verify_server is disabled (set to zero), PJSIP will not
+ * verifiy the certificate and allows TLS connections to servers
+ * which do not present a valid certificate.
+ * If \a tls_verify_server is non-zero, PJSIP verifies the server
+ * certificate and will close the TLS connection if the server
+ * certificate is not valid.
+ *
+ * This setting corresponds to OpenSSL SSL_VERIFY_PEER flag.
+ * Default value is zero.
+ */
+ pj_bool_t verify_server;
+
+ /**
+ * When acting as server (incoming TLS connections), setting
+ * \a verify_client to non-zero will cause the transport to activate
+ * peer verification upon receiving incoming TLS connection.
+ *
+ * This setting corresponds to OpenSSL SSL_VERIFY_PEER flag.
+ * Default value is zero.
+ */
+ pj_bool_t verify_client;
+
+ /**
+ * When acting as server (incoming TLS connections), reject inocming
+ * connection if client doesn't have a valid certificate.
+ *
+ * This setting corresponds to SSL_VERIFY_FAIL_IF_NO_PEER_CERT flag.
+ * Default value is zero.
+ */
+ pj_bool_t require_client_cert;
+
+ /**
+ * TLS negotiation timeout to be applied for both outgoing and
+ * incoming connection. If both sec and msec member is set to zero,
+ * the SSL negotiation doesn't have a timeout.
+ */
+ pj_time_val timeout;
+
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * By default all settings in this structure are disabled.
+ */
+ pj_qos_params qos_params;
+
+ /**
+ * Specify if the transport should ignore any errors when setting the QoS
+ * traffic type/parameters.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t qos_ignore_error;
+
+} pjsip_tls_setting;
+
+
+/**
+ * Initialize TLS setting with default values.
+ *
+ * @param tls_opt The TLS setting to be initialized.
+ */
+PJ_INLINE(void) pjsip_tls_setting_default(pjsip_tls_setting *tls_opt)
+{
+ pj_memset(tls_opt, 0, sizeof(*tls_opt));
+ tls_opt->qos_type = PJ_QOS_TYPE_BEST_EFFORT;
+ tls_opt->qos_ignore_error = PJ_TRUE;
+}
+
+
+/**
+ * Copy TLS setting.
+ *
+ * @param pool The pool to duplicate strings etc.
+ * @param dst Destination structure.
+ * @param src Source structure.
+ */
+PJ_INLINE(void) pjsip_tls_setting_copy(pj_pool_t *pool,
+ pjsip_tls_setting *dst,
+ const pjsip_tls_setting *src)
+{
+ pj_memcpy(dst, src, sizeof(*dst));
+ pj_strdup_with_null(pool, &dst->ca_list_file, &src->ca_list_file);
+ pj_strdup_with_null(pool, &dst->cert_file, &src->cert_file);
+ pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file);
+ pj_strdup_with_null(pool, &dst->password, &src->password);
+ pj_strdup_with_null(pool, &dst->ciphers, &src->ciphers);
+}
+
+
+/**
+ * Register support for SIP TLS transport by creating TLS listener on
+ * the specified address and port. This function will create an
+ * instance of SIP TLS transport factory and register it to the
+ * transport manager.
+ *
+ * @param endpt The SIP endpoint.
+ * @param opt Optional TLS settings.
+ * @param local Optional local address to bind, or specify the
+ * address to bind the server socket to. Both IP
+ * interface address and port fields are optional.
+ * If IP interface address is not specified, socket
+ * will be bound to PJ_INADDR_ANY. If port is not
+ * specified, socket will be bound to any port
+ * selected by the operating system.
+ * @param a_name Optional published address, which is the address to be
+ * advertised as the address of this SIP transport.
+ * If this argument is NULL, then the bound address
+ * will be used as the published address.
+ * @param async_cnt Number of simultaneous asynchronous accept()
+ * operations to be supported. It is recommended that
+ * the number here corresponds to the number of
+ * processors in the system (or the number of SIP
+ * worker threads).
+ * @param p_factory Optional pointer to receive the instance of the
+ * SIP TLS transport factory just created.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tls_transport_start(pjsip_endpoint *endpt,
+ const pjsip_tls_setting *opt,
+ const pj_sockaddr_in *local,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_tpfactory **p_factory);
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_TRANSPORT_TLS_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_udp.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_udp.h
new file mode 100644
index 0000000..035dc28
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_udp.h
@@ -0,0 +1,235 @@
+/* $Id: sip_transport_udp.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_TRANSPORT_UDP_H__
+#define __PJSIP_TRANSPORT_UDP_H__
+
+/**
+ * @file sip_transport_udp.h
+ * @brief SIP UDP Transport.
+ */
+
+#include <pjsip/sip_transport.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_TRANSPORT_UDP UDP Transport
+ * @ingroup PJSIP_TRANSPORT
+ * @brief API to create and register UDP transport.
+ * @{
+ * The functions below are used to create UDP transport and register
+ * the transport to the framework.
+ */
+
+/**
+ * Flag that can be specified when calling #pjsip_udp_transport_pause() or
+ * #pjsip_udp_transport_restart().
+ */
+enum
+{
+ /**
+ * This flag tells the transport to keep the existing/internal socket
+ * handle.
+ */
+ PJSIP_UDP_TRANSPORT_KEEP_SOCKET = 1,
+
+ /**
+ * This flag tells the transport to destroy the existing/internal socket
+ * handle. Naturally this flag and PJSIP_UDP_TRANSPORT_KEEP_SOCKET are
+ * mutually exclusive.
+ */
+ PJSIP_UDP_TRANSPORT_DESTROY_SOCKET = 2
+};
+
+
+/**
+ * Start UDP transport.
+ *
+ * @param endpt The SIP endpoint.
+ * @param local Optional local address to bind. If this argument
+ * is NULL, the UDP transport will be bound to arbitrary
+ * UDP port.
+ * @param a_name Published address (only the host and port portion is
+ * used). If this argument is NULL, then the bound address
+ * will be used as the published address.
+ * @param async_cnt Number of simultaneous async operations.
+ * @param p_transport Pointer to receive the transport.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_start(pjsip_endpoint *endpt,
+ const pj_sockaddr_in *local,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_transport **p_transport);
+
+/**
+ * Start IPv6 UDP transport.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_start6(pjsip_endpoint *endpt,
+ const pj_sockaddr_in6 *local,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_transport **p_transport);
+
+
+/**
+ * Attach IPv4 UDP socket as a new transport and start the transport.
+ *
+ * @param endpt The SIP endpoint.
+ * @param sock UDP socket to use.
+ * @param a_name Published address (only the host and port portion is
+ * used).
+ * @param async_cnt Number of simultaneous async operations.
+ * @param p_transport Pointer to receive the transport.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_attach(pjsip_endpoint *endpt,
+ pj_sock_t sock,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_transport **p_transport);
+
+
+/**
+ * Attach IPv4 or IPv6 UDP socket as a new transport and start the transport.
+ *
+ * @param endpt The SIP endpoint.
+ * @param type Transport type, which is PJSIP_TRANSPORT_UDP for IPv4
+ * or PJSIP_TRANSPORT_UDP6 for IPv6 socket.
+ * @param sock UDP socket to use.
+ * @param a_name Published address (only the host and port portion is
+ * used).
+ * @param async_cnt Number of simultaneous async operations.
+ * @param p_transport Pointer to receive the transport.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_attach2(pjsip_endpoint *endpt,
+ pjsip_transport_type_e type,
+ pj_sock_t sock,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_transport **p_transport);
+
+/**
+ * Retrieve the internal socket handle used by the UDP transport. Note
+ * that this socket normally is registered to ioqueue, so if application
+ * wants to make use of this socket, it should temporarily pause the
+ * transport.
+ *
+ * @param transport The UDP transport.
+ *
+ * @return The socket handle, or PJ_INVALID_SOCKET if no socket
+ * is currently being used (for example, when transport
+ * is being paused).
+ */
+PJ_DECL(pj_sock_t) pjsip_udp_transport_get_socket(pjsip_transport *transport);
+
+
+/**
+ * Temporarily pause or shutdown the transport. When transport is being
+ * paused, it cannot be used by the SIP stack to send or receive SIP
+ * messages.
+ *
+ * Two types of operations are supported by this function:
+ * - to temporarily make this transport unavailable for SIP uses, but
+ * otherwise keep the socket handle intact. Application then can
+ * retrieve the socket handle with #pjsip_udp_transport_get_socket()
+ * and use it to send/receive application data (for example, STUN
+ * messages). In this case, application should specify
+ * PJSIP_UDP_TRANSPORT_KEEP_SOCKET when calling this function, and
+ * also to specify this flag when calling #pjsip_udp_transport_restart()
+ * later.
+ * - to temporarily shutdown the transport, including closing down
+ * the internal socket handle. This is useful for example to
+ * temporarily suspend the application for an indefinite period. In
+ * this case, application should specify PJSIP_UDP_TRANSPORT_DESTROY_SOCKET
+ * flag when calling this function, and specify a new socket when
+ * calling #pjsip_udp_transport_restart().
+ *
+ * @param transport The UDP transport.
+ * @param option Pause option.
+ *
+ * @return PJ_SUCCESS if transport is paused successfully,
+ * or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_pause(pjsip_transport *transport,
+ unsigned option);
+
+/**
+ * Restart the transport. Several operations are supported by this function:
+ * - if transport was made temporarily unavailable to SIP stack with
+ * pjsip_udp_transport_pause() and PJSIP_UDP_TRANSPORT_KEEP_SOCKET,
+ * application can make the transport available to the SIP stack
+ * again, by specifying PJSIP_UDP_TRANSPORT_KEEP_SOCKET flag here.
+ * - if application wants to replace the internal socket with a new
+ * socket, it must specify PJSIP_UDP_TRANSPORT_DESTROY_SOCKET when
+ * calling this function, so that the internal socket will be destroyed
+ * if it hasn't been closed. In this case, application has two choices
+ * on how to create the new socket: 1) to let the transport create
+ * the new socket, in this case the \a sock option should be set
+ * to \a PJ_INVALID_SOCKET and optionally the \a local parameter can be
+ * filled with the desired address and port where the new socket
+ * should be bound to, or 2) to specify its own socket to be used
+ * by this transport, by specifying a valid socket in \a sock argument
+ * and set the \a local argument to NULL. In both cases, application
+ * may specify the published address of the socket in \a a_name
+ * argument.
+ *
+ * @param transport The UDP transport.
+ * @param option Restart option.
+ * @param sock Optional socket to be used by the transport.
+ * @param local The address where the socket should be bound to.
+ * If this argument is NULL, socket will be bound
+ * to any available port.
+ * @param a_name Optionally specify the published address for
+ * this transport. If the socket is not replaced
+ * (PJSIP_UDP_TRANSPORT_KEEP_SOCKET flag is
+ * specified), then if this argument is NULL, the
+ * previous value will be used. If the socket is
+ * replaced and this argument is NULL, the bound
+ * address will be used as the published address
+ * of the transport.
+ *
+ * @return PJ_SUCCESS if transport can be restarted, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_restart(pjsip_transport *transport,
+ unsigned option,
+ pj_sock_t sock,
+ const pj_sockaddr_in *local,
+ const pjsip_host_port *a_name);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_TRANSPORT_UDP_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_types.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_types.h
new file mode 100644
index 0000000..28597e2
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_types.h
@@ -0,0 +1,257 @@
+/* $Id: sip_types.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_TYPES_H__
+#define __PJSIP_SIP_TYPES_H__
+
+
+/*
+ * My note: Doxygen PJSIP and PJSIP_CORE group is declared in
+ * sip_config.h
+ */
+
+/**
+ * @file sip_types.h
+ * @brief Basic PJSIP types.
+ */
+
+#include <pjsip/sip_config.h>
+#include <pj/types.h>
+
+/**
+ * @addtogroup PJSIP_BASE
+ */
+
+/* @defgroup PJSIP_TYPES Basic Data Types
+ * @ingroup PJSIP_BASE
+ * @brief Basic data types.
+ * @{
+ */
+
+
+
+/**
+ * Forward declaration for SIP transport.
+ */
+typedef struct pjsip_transport pjsip_transport;
+
+/**
+ * Forward declaration for transport manager.
+ */
+typedef struct pjsip_tpmgr pjsip_tpmgr;
+
+/**
+ * Transport types.
+ */
+typedef enum pjsip_transport_type_e
+{
+ /** Unspecified. */
+ PJSIP_TRANSPORT_UNSPECIFIED,
+
+ /** UDP. */
+ PJSIP_TRANSPORT_UDP,
+
+ /** TCP. */
+ PJSIP_TRANSPORT_TCP,
+
+ /** TLS. */
+ PJSIP_TRANSPORT_TLS,
+
+ /** SCTP. */
+ PJSIP_TRANSPORT_SCTP,
+
+ /** Loopback (stream, reliable) */
+ PJSIP_TRANSPORT_LOOP,
+
+ /** Loopback (datagram, unreliable) */
+ PJSIP_TRANSPORT_LOOP_DGRAM,
+
+ /** Start of user defined transport */
+ PJSIP_TRANSPORT_START_OTHER,
+
+ /** Start of IPv6 transports */
+ PJSIP_TRANSPORT_IPV6 = 128,
+
+ /** UDP over IPv6 */
+ PJSIP_TRANSPORT_UDP6 = PJSIP_TRANSPORT_UDP + PJSIP_TRANSPORT_IPV6,
+
+ /** TCP over IPv6 */
+ PJSIP_TRANSPORT_TCP6 = PJSIP_TRANSPORT_TCP + PJSIP_TRANSPORT_IPV6
+
+} pjsip_transport_type_e;
+
+
+/**
+ * Forward declaration for endpoint (sip_endpoint.h).
+ */
+typedef struct pjsip_endpoint pjsip_endpoint;
+
+/**
+ * Forward declaration for transactions (sip_transaction.h).
+ */
+typedef struct pjsip_transaction pjsip_transaction;
+
+/**
+ * Forward declaration for events (sip_event.h).
+ */
+typedef struct pjsip_event pjsip_event;
+
+/**
+ * Forward declaration for transmit data/buffer (sip_transport.h).
+ */
+typedef struct pjsip_tx_data pjsip_tx_data;
+
+/**
+ * Forward declaration for receive data/buffer (sip_transport.h).
+ */
+typedef struct pjsip_rx_data pjsip_rx_data;
+
+/**
+ * Forward declaration for message (sip_msg.h).
+ */
+typedef struct pjsip_msg pjsip_msg;
+
+/**
+ * Forward declaration for message body (sip_msg.h).
+ */
+typedef struct pjsip_msg_body pjsip_msg_body;
+
+/**
+ * Forward declaration for header field (sip_msg.h).
+ */
+typedef struct pjsip_hdr pjsip_hdr;
+
+/**
+ * Forward declaration for URI (sip_uri.h).
+ */
+typedef struct pjsip_uri pjsip_uri;
+
+/**
+ * Forward declaration for SIP method (sip_msg.h)
+ */
+typedef struct pjsip_method pjsip_method;
+
+/**
+ * Opaque data type for the resolver engine (sip_resolve.h).
+ */
+typedef struct pjsip_resolver_t pjsip_resolver_t;
+
+/**
+ * Forward declaration for credential.
+ */
+typedef struct pjsip_cred_info pjsip_cred_info;
+
+
+/**
+ * Forward declaration for module (sip_module.h).
+ */
+typedef struct pjsip_module pjsip_module;
+
+
+/**
+ * Forward declaration for user agent type (sip_ua_layer.h).
+ */
+typedef pjsip_module pjsip_user_agent;
+
+/**
+ * Forward declaration for dialog (sip_dialog.h).
+ */
+typedef struct pjsip_dialog pjsip_dialog;
+
+/**
+ * Transaction role.
+ */
+typedef enum pjsip_role_e
+{
+ PJSIP_ROLE_UAC, /**< Role is UAC. */
+ PJSIP_ROLE_UAS, /**< Role is UAS. */
+
+ /* Alias: */
+
+ PJSIP_UAC_ROLE = PJSIP_ROLE_UAC, /**< Role is UAC. */
+ PJSIP_UAS_ROLE = PJSIP_ROLE_UAS /**< Role is UAS. */
+
+} pjsip_role_e;
+
+
+/**
+ * General purpose buffer.
+ */
+typedef struct pjsip_buffer
+{
+ /** The start of the buffer. */
+ char *start;
+
+ /** Pointer to current end of the buffer, which also indicates the position
+ of subsequent buffer write.
+ */
+ char *cur;
+
+ /** The absolute end of the buffer. */
+ char *end;
+
+} pjsip_buffer;
+
+
+/**
+ * General host:port pair, used for example as Via sent-by.
+ */
+typedef struct pjsip_host_port
+{
+ pj_str_t host; /**< Host part or IP address. */
+ int port; /**< Port number. */
+} pjsip_host_port;
+
+/**
+ * Host information.
+ */
+typedef struct pjsip_host_info
+{
+ unsigned flag; /**< Flags of pjsip_transport_flags_e. */
+ pjsip_transport_type_e type; /**< Transport type. */
+ pjsip_host_port addr; /**< Address information. */
+} pjsip_host_info;
+
+
+/**
+ * Convert exception ID into pj_status_t status.
+ *
+ * @param exception_id Exception Id.
+ *
+ * @return Error code for the specified exception Id.
+ */
+PJ_DECL(pj_status_t) pjsip_exception_to_status(int exception_id);
+
+/**
+ * Return standard pj_status_t status from current exception.
+ */
+#define PJSIP_RETURN_EXCEPTION() pjsip_exception_to_status(PJ_GET_EXCEPTION())
+
+/**
+ * Attributes to inform that the function may throw exceptions.
+ */
+#define PJSIP_THROW_SPEC(list)
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_SIP_TYPES_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_ua_layer.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_ua_layer.h
new file mode 100644
index 0000000..ba1bb31
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_ua_layer.h
@@ -0,0 +1,162 @@
+/* $Id: sip_ua_layer.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_UA_LAYER_H__
+#define __PJSIP_SIP_UA_LAYER_H__
+
+/**
+ * @file sip_ua_layer.h
+ * @brief SIP User Agent Layer Module
+ */
+#include <pjsip/sip_types.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_UA Base User Agent Layer/Common Dialog Layer
+ * @brief Dialog management.
+ *
+ * This module provides basic dialog management, which is used by higher
+ * layer dialog usages such as INVITE sessions and SIP Event Subscription
+ * framework (RFC 3265). Application should link with <b>pjsip-core</b>
+ * library to use this base UA layer. The base UA layer module is initialized
+ * with #pjsip_ua_init_module().
+ */
+
+/**
+ * @defgroup PJSUA_UA SIP User Agent Module
+ * @ingroup PJSIP_UA
+ * @brief Provides dialog management.
+ * @{
+ *
+ * Application MUST initialize the user agent layer module by calling
+ * #pjsip_ua_init_module() before using any of the dialog API, and link
+ * the application with with <b>pjsip-core</b> library.
+ */
+
+/** User agent initialization parameter. */
+typedef struct pjsip_ua_init_param
+{
+ /** Callback to be called when the UA layer detects that outgoing
+ * dialog has forked.
+ */
+ pjsip_dialog* (*on_dlg_forked)(pjsip_dialog *first_set, pjsip_rx_data *res);
+} pjsip_ua_init_param;
+
+/**
+ * Initialize user agent layer and register it to the specified endpoint.
+ *
+ * @param endpt The endpoint where the user agent will be
+ * registered.
+ * @param prm UA initialization parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_ua_init_module(pjsip_endpoint *endpt,
+ const pjsip_ua_init_param *prm);
+
+/**
+ * Get the instance of the user agent.
+ *
+ * @return The user agent module instance.
+ */
+PJ_DECL(pjsip_user_agent*) pjsip_ua_instance(void);
+
+
+/**
+ * Retrieve the current number of dialog-set currently registered
+ * in the hash table. Note that dialog-set is different than dialog
+ * when the request forks. In this case, all dialogs created from
+ * the original request will belong to the same dialog set. When
+ * no forking occurs, the number of dialog sets will be equal to
+ * the number of dialogs.
+ *
+ * @return Number of dialog sets.
+ */
+PJ_DECL(pj_uint32_t) pjsip_ua_get_dlg_set_count(void);
+
+
+/**
+ * Find a dialog with the specified Call-ID and tags properties. This
+ * function may optionally lock the matching dialog instance before
+ * returning it back to the caller.
+ *
+ * @param call_id The call ID to be matched.
+ * @param local_tag The local tag to be matched.
+ * @param remote_tag The remote tag to be matched.
+ * @param lock_dialog If non-zero, instruct the function to lock the
+ * matching dialog with #pjsip_dlg_inc_lock().
+ * Application is responsible to release the dialog's
+ * lock after it has finished manipulating the dialog,
+ * by calling #pjsip_dlg_dec_lock().
+ *
+ * @return The matching dialog instance, or NULL if no matching
+ * dialog is found.
+ */
+PJ_DECL(pjsip_dialog*) pjsip_ua_find_dialog(const pj_str_t *call_id,
+ const pj_str_t *local_tag,
+ const pj_str_t *remote_tag,
+ pj_bool_t lock_dialog);
+
+/**
+ * Destroy the user agent layer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_ua_destroy(void);
+
+/**
+ * Dump user agent contents (e.g. all dialogs).
+ *
+ * @param detail If non-zero, list of dialogs will be printed.
+ */
+PJ_DECL(void) pjsip_ua_dump(pj_bool_t detail);
+
+/**
+ * Get the endpoint instance of a user agent module.
+ *
+ * @param ua The user agent instance.
+ *
+ * @return The endpoint instance where the user agent is
+ * registered.
+ */
+PJ_DECL(pjsip_endpoint*) pjsip_ua_get_endpt(pjsip_user_agent *ua);
+
+
+/**
+ * @}
+ */
+
+
+/*
+ * Internal (called by sip_dialog.c).
+ */
+
+PJ_DECL(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,
+ pjsip_dialog *dlg );
+PJ_DECL(pj_status_t) pjsip_ua_unregister_dlg(pjsip_user_agent *ua,
+ pjsip_dialog *dlg );
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIP_UA_LAYER_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_uri.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_uri.h
new file mode 100644
index 0000000..fb1d063
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_uri.h
@@ -0,0 +1,457 @@
+/* $Id: sip_uri.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_URI_H__
+#define __PJSIP_SIP_URI_H__
+
+/**
+ * @file sip_uri.h
+ * @brief SIP URL Structures and Manipulations
+ */
+
+#include <pjsip/sip_types.h>
+#include <pjsip/sip_config.h>
+#include <pj/list.h>
+#include <pjlib-util/scanner.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJSIP_URI URI
+ * @brief URI types and manipulations.
+ * @ingroup PJSIP_MSG
+ */
+
+/**
+ * @addtogroup PJSIP_URI_PARAM URI Parameter Container
+ * @ingroup PJSIP_URI
+ * @brief Generic parameter elements container.
+ * @{
+ */
+
+/**
+ * Generic parameter, normally used in other_param or header_param.
+ */
+typedef struct pjsip_param
+{
+ PJ_DECL_LIST_MEMBER(struct pjsip_param); /**< Generic list member. */
+ pj_str_t name; /**< Param/header name. */
+ pj_str_t value; /**< Param/header value. */
+} pjsip_param;
+
+
+/**
+ * Find the specified parameter name in the list. The name will be compared
+ * in case-insensitive comparison.
+ *
+ * @param param_list List of parameters to find.
+ * @param name Parameter/header name to find.
+ *
+ * @return The parameter if found, or NULL.
+ */
+PJ_DECL(pjsip_param*) pjsip_param_find( pjsip_param *param_list,
+ const pj_str_t *name );
+
+
+/**
+ * Find the specified parameter name in the list. The name will be compared
+ * in case-insensitive comparison.
+ *
+ * @param param_list List of parameters to find.
+ * @param name Parameter/header name to find.
+ *
+ * @return The parameter if found, or NULL.
+ */
+PJ_DECL(const pjsip_param*) pjsip_param_cfind(const pjsip_param *param_list,
+ const pj_str_t *name );
+
+
+/**
+ * Duplicate the parameters.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param dst_list Destination list.
+ * @param src_list Source list.
+ */
+PJ_DECL(void) pjsip_param_clone(pj_pool_t *pool, pjsip_param *dst_list,
+ const pjsip_param *src_list);
+
+/**
+ * Duplicate the parameters.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param dst_list Destination list.
+ * @param src_list Source list.
+ */
+PJ_DECL(void) pjsip_param_shallow_clone(pj_pool_t *pool,
+ pjsip_param *dst_list,
+ const pjsip_param *src_list);
+
+/**
+ * Print parameters.
+ *
+ * @param param_list The parameter list.
+ * @param buf Buffer.
+ * @param size Size of buffer.
+ * @param pname_unres Specification of allowed characters in pname.
+ * @param pvalue_unres Specification of allowed characters in pvalue.
+ * @param sep Separator character (either ';', ',', or '?').
+ * When separator is set to '?', this function will
+ * automatically adjust the separator character to
+ * '&' after the first parameter is printed.
+ *
+ * @return The number of bytes printed, or -1 on errr.
+ */
+PJ_DECL(pj_ssize_t) pjsip_param_print_on(const pjsip_param *param_list,
+ char *buf, pj_size_t size,
+ const pj_cis_t *pname_unres,
+ const pj_cis_t *pvalue_unres,
+ int sep);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_URI_GENERIC Generic URI
+ * @ingroup PJSIP_URI
+ * @brief Generic representation for all types of URI.
+ * @{
+ */
+
+/**
+ * URI context.
+ */
+typedef enum pjsip_uri_context_e
+{
+ PJSIP_URI_IN_REQ_URI, /**< The URI is in Request URI. */
+ PJSIP_URI_IN_FROMTO_HDR, /**< The URI is in From/To header. */
+ PJSIP_URI_IN_CONTACT_HDR, /**< The URI is in Contact header. */
+ PJSIP_URI_IN_ROUTING_HDR, /**< The URI is in Route/Record-Route header. */
+ PJSIP_URI_IN_OTHER /**< Other context (web page, business card, etc.) */
+} pjsip_uri_context_e;
+
+/**
+ * URI 'virtual' function table.
+ * All types of URI in this library (such as sip:, sips:, tel:, and name-addr)
+ * will have pointer to this table as their first struct member. This table
+ * provides polimorphic behaviour to the URI.
+ */
+typedef struct pjsip_uri_vptr
+{
+ /**
+ * Get URI scheme.
+ * @param uri the URI (self).
+ * @return the URI scheme.
+ */
+ const pj_str_t* (*p_get_scheme)(const void *uri);
+
+ /**
+ * Get the URI object contained by this URI, or the URI itself if
+ * it doesn't contain another URI.
+ * @param uri the URI (self).
+ */
+ void* (*p_get_uri)(void *uri);
+
+ /**
+ * Print URI components to the buffer, following the rule of which
+ * components are allowed for the context.
+ * @param context the context where the URI will be placed.
+ * @param uri the URI (self).
+ * @param buf the buffer.
+ * @param size the size of the buffer.
+ * @return the length printed.
+ */
+ pj_ssize_t (*p_print)(pjsip_uri_context_e context,
+ const void *uri,
+ char *buf, pj_size_t size);
+
+ /**
+ * Compare two URIs according to the context.
+ * @param context the context.
+ * @param uri1 the first URI (self).
+ * @param uri2 the second URI.
+ * @return PJ_SUCCESS if equal, or otherwise the error status which
+ * should point to the mismatch part.
+ */
+ pj_status_t (*p_compare)(pjsip_uri_context_e context,
+ const void *uri1, const void *uri2);
+
+ /**
+ * Clone URI.
+ * @param pool the pool.
+ * @param the URI to clone (self).
+ * @return new URI.
+ */
+ void *(*p_clone)(pj_pool_t *pool, const void *uri);
+
+} pjsip_uri_vptr;
+
+
+/**
+ * The declaration of 'base class' for all URI scheme.
+ */
+struct pjsip_uri
+{
+ /** All URIs must have URI virtual function table as their first member. */
+ pjsip_uri_vptr *vptr;
+};
+
+/**
+ * This macro checks that the URL is a "sip:" or "sips:" URL.
+ * @param url The URL (pointer to)
+ * @return non-zero if TRUE.
+ */
+#define PJSIP_URI_SCHEME_IS_SIP(url) \
+ (pj_strnicmp2(pjsip_uri_get_scheme(url), "sip", 3)==0)
+
+/**
+ * This macro checks that the URL is a "sips:" URL (not SIP).
+ * @param url The URL (pointer to)
+ * @return non-zero if TRUE.
+ */
+#define PJSIP_URI_SCHEME_IS_SIPS(url) \
+ (pj_strnicmp2(pjsip_uri_get_scheme(url), "sips", 4)==0)
+
+/**
+ * This macro checks that the URL is a "tel:" URL.
+ * @param url The URL (pointer to)
+ * @return non-zero if TRUE.
+ */
+#define PJSIP_URI_SCHEME_IS_TEL(url) \
+ (pj_strnicmp2(pjsip_uri_get_scheme(url), "tel", 3)==0)
+
+
+/**
+ * Generic function to get the URI scheme.
+ * @param uri the URI object.
+ * @return the URI scheme.
+ */
+PJ_INLINE(const pj_str_t*) pjsip_uri_get_scheme(const void *uri)
+{
+ return (*((pjsip_uri*)uri)->vptr->p_get_scheme)(uri);
+}
+
+/**
+ * Generic function to get the URI object contained by this URI, or the URI
+ * itself if it doesn't contain another URI.
+ *
+ * @param uri the URI.
+ * @return the URI.
+ */
+PJ_INLINE(void*) pjsip_uri_get_uri(const void *uri)
+{
+ return (*((pjsip_uri*)uri)->vptr->p_get_uri)((void*)uri);
+}
+
+/**
+ * Generic function to compare two URIs.
+ *
+ * @param context Comparison context.
+ * @param uri1 The first URI.
+ * @param uri2 The second URI.
+ * @return PJ_SUCCESS if equal, or otherwise the error status which
+ * should point to the mismatch part.
+ */
+PJ_INLINE(pj_status_t) pjsip_uri_cmp(pjsip_uri_context_e context,
+ const void *uri1, const void *uri2)
+{
+ return (*((const pjsip_uri*)uri1)->vptr->p_compare)(context, uri1, uri2);
+}
+
+/**
+ * Generic function to print an URI object.
+ *
+ * @param context Print context.
+ * @param uri The URI to print.
+ * @param buf The buffer.
+ * @param size Size of the buffer.
+ * @return Length printed.
+ */
+PJ_INLINE(int) pjsip_uri_print(pjsip_uri_context_e context,
+ const void *uri,
+ char *buf, pj_size_t size)
+{
+ return (*((const pjsip_uri*)uri)->vptr->p_print)(context, uri, buf, size);
+}
+
+/**
+ * Generic function to clone an URI object.
+ *
+ * @param pool Pool.
+ * @param uri URI to clone.
+ * @return New URI.
+ */
+PJ_INLINE(void*) pjsip_uri_clone( pj_pool_t *pool, const void *uri )
+{
+ return (*((const pjsip_uri*)uri)->vptr->p_clone)(pool, uri);
+}
+
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_SIP_URI SIP URI Scheme and Name address
+ * @ingroup PJSIP_URI
+ * @brief SIP URL structure ("sip:" and "sips:")
+ * @{
+ */
+
+
+/**
+ * SIP and SIPS URL scheme.
+ */
+typedef struct pjsip_sip_uri
+{
+ pjsip_uri_vptr *vptr; /**< Pointer to virtual function table.*/
+ pj_str_t user; /**< Optional user part. */
+ pj_str_t passwd; /**< Optional password part. */
+ pj_str_t host; /**< Host part, always exists. */
+ int port; /**< Optional port number, or zero. */
+ pj_str_t user_param; /**< Optional user parameter */
+ pj_str_t method_param; /**< Optional method parameter. */
+ pj_str_t transport_param; /**< Optional transport parameter. */
+ int ttl_param; /**< Optional TTL param, or -1. */
+ int lr_param; /**< Optional loose routing param, or zero */
+ pj_str_t maddr_param; /**< Optional maddr param */
+ pjsip_param other_param; /**< Other parameters grouped together. */
+ pjsip_param header_param; /**< Optional header parameter. */
+} pjsip_sip_uri;
+
+
+/**
+ * SIP name-addr, which typically appear in From, To, and Contact header.
+ * The SIP name-addr contains a generic URI and a display name.
+ */
+typedef struct pjsip_name_addr
+{
+ /** Pointer to virtual function table. */
+ pjsip_uri_vptr *vptr;
+
+ /** Optional display name. */
+ pj_str_t display;
+
+ /** URI part. */
+ pjsip_uri *uri;
+
+} pjsip_name_addr;
+
+
+/**
+ * Create new SIP URL and initialize all fields with zero or NULL.
+ * @param pool The pool.
+ * @param secure Flag to indicate whether secure transport should be used.
+ * @return SIP URL.
+ */
+PJ_DECL(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool,
+ pj_bool_t secure );
+
+/**
+ * Change the SIP URI scheme to sip or sips based on the secure flag.
+ * This would not change anything except the scheme.
+ * @param uri The URI
+ * @param secure Non-zero if sips is wanted.
+ */
+PJ_DECL(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *uri,
+ pj_bool_t secure );
+
+/**
+ * Initialize SIP URL (all fields are set to NULL or zero).
+ * @param url The URL.
+ * @param secure Create sips URI?
+ */
+PJ_DECL(void) pjsip_sip_uri_init(pjsip_sip_uri *url, pj_bool_t secure);
+
+/**
+ * Perform full assignment to the SIP URL.
+ * @param pool The pool.
+ * @param url Destination URL.
+ * @param rhs The source URL.
+ */
+PJ_DECL(void) pjsip_sip_uri_assign(pj_pool_t *pool, pjsip_sip_uri *url,
+ const pjsip_sip_uri *rhs);
+
+/**
+ * Create new instance of name address and initialize all fields with zero or
+ * NULL.
+ * @param pool The pool.
+ * @return New SIP name address.
+ */
+PJ_DECL(pjsip_name_addr*) pjsip_name_addr_create(pj_pool_t *pool);
+
+/**
+ * Initialize with default value.
+ * @param name_addr The name address.
+ */
+PJ_DECL(void) pjsip_name_addr_init(pjsip_name_addr *name_addr);
+
+/**
+ * Perform full assignment to the name address.
+ * @param pool The pool.
+ * @param addr The destination name address.
+ * @param rhs The source name address.
+ */
+PJ_DECL(void) pjsip_name_addr_assign(pj_pool_t *pool,
+ pjsip_name_addr *addr,
+ const pjsip_name_addr *rhs);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_OTHER_URI Other URI schemes
+ * @ingroup PJSIP_URI
+ * @brief Container for non SIP/tel URI scheme (e.g. "http:", "mailto:")
+ * @{
+ */
+
+/**
+ * Generic URI container for non SIP/tel URI scheme.
+ */
+typedef struct pjsip_other_uri
+{
+ pjsip_uri_vptr *vptr; /**< Pointer to virtual function table. */
+ pj_str_t scheme; /**< The URI scheme (e.g. "mailto") */
+ pj_str_t content; /**< The whole URI content */
+} pjsip_other_uri;
+
+
+/**
+ * Create a generic URI object.
+ *
+ * @param pool The pool to allocate memory from.
+ *
+ * @return The URI instance.
+ */
+PJ_DECL(pjsip_other_uri*) pjsip_other_uri_create(pj_pool_t *pool);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_URL_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_util.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_util.h
new file mode 100644
index 0000000..00189b3
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_util.h
@@ -0,0 +1,861 @@
+/* $Id: sip_util.h 2932 2009-10-09 12:11:07Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_MISC_H__
+#define __PJSIP_SIP_MISC_H__
+
+#include <pjsip/sip_msg.h>
+#include <pjsip/sip_transport.h>
+#include <pjsip/sip_resolve.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_ENDPT_TARGET_URI Target URI Management
+ * @ingroup PJSIP_CORE_CORE
+ * @brief Management of target URI's in case of redirection
+ * @{
+ * This module provides utility functions to manage target set for UAC.
+ * The target set is provided as pjsip_target_set structure. Initially,
+ * the target set for UAC contains only one target, that is the target of
+ * the initial request. When 3xx/redirection class response is received,
+ * the UAC can use the functionality of this module to add the URI's listed
+ * in the Contact header(s) in the response to the target set, and retry
+ * sending the request to the next destination/target. The UAC may retry
+ * this sequentially until one of the target answers with succesful/2xx
+ * response, or one target returns global error/6xx response, or all targets
+ * are exhausted.
+ *
+ * This module is currently used by the \ref PJSIP_INV.
+ */
+
+/**
+ * This structure describes a target, which can be chained together to form
+ * a target set. Each target contains an URI, priority (as q-value), and
+ * the last status code and reason phrase received from the target, if the
+ * target has been contacted. If the target has not been contacted, the
+ * status code field will be zero.
+ */
+typedef struct pjsip_target
+{
+ PJ_DECL_LIST_MEMBER(struct pjsip_target);/**< Standard list element */
+ pjsip_uri *uri; /**< The target URI */
+ int q1000; /**< q-value multiplied by 1000 */
+ pjsip_status_code code; /**< Last status code received */
+ pj_str_t reason; /**< Last reason phrase received */
+} pjsip_target;
+
+
+/**
+ * This describes a target set. A target set contains a linked-list of
+ * pjsip_target.
+ */
+typedef struct pjsip_target_set
+{
+ pjsip_target head; /**< Target linked-list head */
+ pjsip_target *current; /**< Current target. */
+} pjsip_target_set;
+
+
+/**
+ * These enumerations specify the action to be performed to a redirect
+ * response.
+ */
+typedef enum pjsip_redirect_op
+{
+ /**
+ * Reject the redirection to the current target. The UAC will
+ * select the next target from the target set if exists.
+ */
+ PJSIP_REDIRECT_REJECT,
+
+ /**
+ * Accept the redirection to the current target. The INVITE request
+ * will be resent to the current target.
+ */
+ PJSIP_REDIRECT_ACCEPT,
+
+ /**
+ * Defer the redirection decision, for example to request permission
+ * from the end user.
+ */
+ PJSIP_REDIRECT_PENDING,
+
+ /**
+ * Stop the whole redirection process altogether. This will cause
+ * the invite session to be disconnected.
+ */
+ PJSIP_REDIRECT_STOP
+
+} pjsip_redirect_op;
+
+
+/**
+ * Initialize target set. This will empty the list of targets in the
+ * target set.
+ *
+ * @param tset The target set.
+ */
+PJ_INLINE(void) pjsip_target_set_init(pjsip_target_set *tset)
+{
+ pj_list_init(&tset->head);
+ tset->current = NULL;
+}
+
+
+/**
+ * Add an URI to the target set, if the URI is not already in the target set.
+ * The URI comparison rule of pjsip_uri_cmp() will be used to determine the
+ * equality of this URI compared to existing URI's in the target set. The
+ * URI will be cloned using the specified memory pool before it is added to
+ * the list.
+ *
+ * The first URI added to the target set will also be made current target
+ * by this function.
+ *
+ * @param tset The target set.
+ * @param pool The memory pool to be used to duplicate the URI.
+ * @param uri The URI to be checked and added.
+ * @param q1000 The q-value multiplied by 1000.
+ *
+ * @return PJ_SUCCESS if the URI was added to the target set,
+ * or PJ_EEXISTS if the URI already exists in the target
+ * set, or other error codes.
+ */
+PJ_DECL(pj_status_t) pjsip_target_set_add_uri(pjsip_target_set *tset,
+ pj_pool_t *pool,
+ const pjsip_uri *uri,
+ int q1000);
+
+/**
+ * Extract URI's in the Contact headers of the specified (response) message
+ * and add them to the target set. This function will also check if the
+ * URI's already exist in the target set before adding them to the list.
+ *
+ * @param tset The target set.
+ * @param pool The memory pool to be used to duplicate the URI's.
+ * @param msg SIP message from which the Contact headers will be
+ * scanned and the URI's to be extracted, checked, and
+ * added to the target set.
+ *
+ * @return PJ_SUCCESS if at least one URI was added to the
+ * target set, or PJ_EEXISTS if all URI's in the message
+ * already exists in the target set or if the message
+ * doesn't contain usable Contact headers, or other error
+ * codes.
+ */
+PJ_DECL(pj_status_t) pjsip_target_set_add_from_msg(pjsip_target_set *tset,
+ pj_pool_t *pool,
+ const pjsip_msg *msg);
+
+/**
+ * Get the next target to be retried. This function will scan the target set
+ * for target which hasn't been tried, and return one target with the
+ * highest q-value, if such target exists. This function will return NULL
+ * if there is one target with 2xx or 6xx code or if all targets have been
+ * tried.
+ *
+ * @param tset The target set.
+ *
+ * @return The next target to be tried, or NULL if all targets have
+ * been tried or at least one target returns 2xx or 6xx
+ * response.
+ */
+PJ_DECL(pjsip_target*)
+pjsip_target_set_get_next(const pjsip_target_set *tset);
+
+
+/**
+ * Set the specified target as the current target in the target set. The
+ * current target may be used by application to keep track on which target
+ * is currently being operated on.
+ *
+ * @param tset The target set.
+ * @param target The target to be set as current target.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_target_set_set_current(pjsip_target_set *tset,
+ pjsip_target *target);
+
+
+/**
+ * Set the status code and reason phrase of the specified target.
+ *
+ * @param target The target.
+ * @param pool The memory pool to be used to duplicate the reason phrase.
+ * @param code The SIP status code to be set to the target.
+ * @param reason The reason phrase to be set to the target.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjsip_target_assign_status(pjsip_target *target,
+ pj_pool_t *pool,
+ int status_code,
+ const pj_str_t *reason);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_ENDPT_STATELESS Message Creation and Stateless Operations
+ * @ingroup PJSIP_CORE_CORE
+ * @brief Utilities to create various messages and base function to send messages.
+ * @{
+ */
+
+/**
+ * Create an independent request message. This can be used to build any
+ * request outside a dialog, such as OPTIONS, MESSAGE, etc. To create a request
+ * inside a dialog, application should use #pjsip_dlg_create_request.
+ *
+ * This function adds the following headers in the request:
+ * - From, To, Call-ID, and CSeq,
+ * - Contact header, if contact is specified.
+ * - A blank Via header.
+ * - Additional request headers (such as Max-Forwards) which are copied
+ * from endpoint configuration.
+ *
+ * In addition, the function adds a unique tag in the From header.
+ *
+ * Once a transmit data is created, the reference counter is initialized to 1.
+ *
+ * @param endpt Endpoint instance.
+ * @param method SIP Method.
+ * @param target Target URI.
+ * @param from URL to put in From header.
+ * @param to URL to put in To header.
+ * @param contact Contact to be put as Contact header value, hence
+ * the format must follow RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * @param call_id Optional Call-ID (put NULL to generate unique Call-ID).
+ * @param cseq Optional CSeq (put -1 to generate random CSeq).
+ * @param text Optional text body (put NULL to omit body).
+ * @param p_tdata Pointer to receive the transmit data.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_request( pjsip_endpoint *endpt,
+ const pjsip_method *method,
+ const pj_str_t *target,
+ const pj_str_t *from,
+ const pj_str_t *to,
+ const pj_str_t *contact,
+ const pj_str_t *call_id,
+ int cseq,
+ const pj_str_t *text,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Create an independent request message from the specified headers. This
+ * function will clone the headers and put them in the request.
+ *
+ * This function adds the following headers in the request:
+ * - From, To, Call-ID, and CSeq,
+ * - Contact header, if contact is specified.
+ * - A blank Via header.
+ * - Additional request headers (such as Max-Forwards) which are copied
+ * from endpoint configuration.
+ *
+ * In addition, the function adds a unique tag in the From header.
+ *
+ * Once a transmit data is created, the reference counter is initialized to 1.
+ *
+ * @param endpt Endpoint instance.
+ * @param method SIP Method.
+ * @param target Target URI.
+ * @param from From header.
+ * @param to To header.
+ * @param contact Contact header.
+ * @param call_id Optional Call-ID (put NULL to generate unique Call-ID).
+ * @param cseq Optional CSeq (put -1 to generate random CSeq).
+ * @param text Optional text body (put NULL to omit body).
+ * @param p_tdata Pointer to receive the transmit data.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjsip_endpt_create_request_from_hdr( pjsip_endpoint *endpt,
+ const pjsip_method *method,
+ const pjsip_uri *target,
+ const pjsip_from_hdr *from,
+ const pjsip_to_hdr *to,
+ const pjsip_contact_hdr *contact,
+ const pjsip_cid_hdr *call_id,
+ int cseq,
+ const pj_str_t *text,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Construct a minimal response message for the received request. This function
+ * will construct all the Via, Record-Route, Call-ID, From, To, CSeq, and
+ * Call-ID headers from the request.
+ *
+ * Note: the txdata reference counter is set to ZERO!.
+ *
+ * @param endpt The endpoint.
+ * @param rdata The request receive data.
+ * @param st_code Status code to be put in the response.
+ * @param st_text Optional status text, or NULL to get the default text.
+ * @param p_tdata Pointer to receive the transmit data.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt,
+ const pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Construct a full ACK request for the received non-2xx final response.
+ * This utility function is normally called by the transaction to construct
+ * an ACK request to 3xx-6xx final response.
+ * The generation of ACK message for 2xx final response is different than
+ * this one.
+ *
+ * @param endpt The endpoint.
+ * @param tdata This contains the original INVITE request
+ * @param rdata The final response.
+ * @param ack The ACK request created.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_ack( pjsip_endpoint *endpt,
+ const pjsip_tx_data *tdata,
+ const pjsip_rx_data *rdata,
+ pjsip_tx_data **ack);
+
+
+/**
+ * Construct CANCEL request for the previously sent request.
+ *
+ * @param endpt The endpoint.
+ * @param tdata The transmit buffer for the request being cancelled.
+ * @param p_tdata Pointer to receive the transmit data.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
+ const pjsip_tx_data *tdata,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Find which destination to be used to send the request message, based
+ * on the request URI and Route headers in the message. The procedure
+ * used here follows the guidelines on sending the request in RFC 3261
+ * chapter 8.1.2.
+ *
+ * Note there was a change in the behavior of this function since version
+ * 0.5.10.2. Previously this function may modify the request when strict
+ * route is present (to update request URI and route-set). This is no
+ * longer the case now, and this process is done in separate function
+ * (see #pjsip_process_route_set()).
+ *
+ * @param tdata The transmit data containing the request message.
+ * @param dest_info On return, it contains information about destination
+ * host to contact, along with the preferable transport
+ * type, if any. Caller will then normally proceed with
+ * resolving this host with server resolution procedure
+ * described in RFC 3263.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ *
+ * @see pjsip_process_route_set
+ */
+PJ_DECL(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,
+ pjsip_host_info *dest_info );
+
+
+/**
+ * Process route-set found in the request and calculate destination to be
+ * used to send the request message, based on the request URI and Route
+ * headers in the message. The procedure used here follows the guidelines
+ * on sending the request in RFC 3261 chapter 8.1.2.
+ *
+ * This function may modify the message (request line and Route headers),
+ * if the Route information specifies strict routing and the request
+ * URI in the message is different than the calculated target URI. In that
+ * case, the target URI will be put as the request URI of the request and
+ * current request URI will be put as the last entry of the Route headers.
+ *
+ * @param tdata The transmit data containing the request message.
+ * @param dest_info On return, it contains information about destination
+ * host to contact, along with the preferable transport
+ * type, if any. Caller will then normally proceed with
+ * resolving this host with server resolution procedure
+ * described in RFC 3263.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ *
+ * @see pjsip_get_request_addr
+ */
+PJ_DECL(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
+ pjsip_host_info *dest_info );
+
+
+/**
+ * Swap the request URI and strict route back to the original position
+ * before #pjsip_process_route_set() function is called. If no strict
+ * route URI was found by #pjsip_process_route_set(), this function will
+ * do nothing.
+ *
+ * This function should only used internally by PJSIP client authentication
+ * module.
+ *
+ * @param tdata Transmit data containing request message.
+ */
+PJ_DECL(void) pjsip_restore_strict_route_set(pjsip_tx_data *tdata);
+
+
+/**
+ * This structure holds the state of outgoing stateless request.
+ */
+typedef struct pjsip_send_state
+{
+ /** Application token, which was specified when the function
+ * #pjsip_endpt_send_request_stateless() is called.
+ */
+ void *token;
+
+ /** Endpoint instance.
+ */
+ pjsip_endpoint *endpt;
+
+ /** Transmit data buffer being sent.
+ */
+ pjsip_tx_data *tdata;
+
+ /** Current transport being used.
+ */
+ pjsip_transport *cur_transport;
+
+ /** The application callback which was specified when the function
+ * #pjsip_endpt_send_request_stateless() was called.
+ */
+ void (*app_cb)(struct pjsip_send_state*,
+ pj_ssize_t sent,
+ pj_bool_t *cont);
+} pjsip_send_state;
+
+
+/**
+ * Declaration for callback function to be specified in
+ * #pjsip_endpt_send_request_stateless(), #pjsip_endpt_send_response(), or
+ * #pjsip_endpt_send_response2().
+ *
+ * @param st Structure to keep transmission state.
+ * @param sent Number of bytes sent.
+ * @param cont When current transmission fails, specify whether
+ * the function should fallback to next destination.
+ */
+typedef void (*pjsip_send_callback)(pjsip_send_state *st, pj_ssize_t sent,
+ pj_bool_t *cont);
+
+/**
+ * Send outgoing request statelessly The function will take care of which
+ * destination and transport to use based on the information in the message,
+ * taking care of URI in the request line and Route header.
+ *
+ * This function is different than #pjsip_transport_send() in that this
+ * function adds/modify the Via header as necessary.
+ *
+ * @param endpt The endpoint instance.
+ * @param tdata The transmit data to be sent.
+ * @param token Arbitrary token to be given back on the callback.
+ * @param cb Optional callback to notify transmission status (also
+ * gives chance for application to discontinue retrying
+ * sending to alternate address).
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjsip_endpt_send_request_stateless( pjsip_endpoint *endpt,
+ pjsip_tx_data *tdata,
+ void *token,
+ pjsip_send_callback cb);
+
+/**
+ * This is a low-level function to send raw data to a destination.
+ *
+ * See also #pjsip_endpt_send_raw_to_uri().
+ *
+ * @param endpt The SIP endpoint instance.
+ * @param tp_type Transport type.
+ * @param sel Optional pointer to transport selector instance if
+ * application wants to use a specific transport instance
+ * rather then letting transport manager finds the suitable
+ * transport..
+ * @param raw_data The data to be sent.
+ * @param data_len The length of the data.
+ * @param addr Destination address.
+ * @param addr_len Length of destination address.
+ * @param token Arbitrary token to be returned back to callback.
+ * @param cb Optional callback to be called to notify caller about
+ * the completion status of the pending send operation.
+ *
+ * @return If the message has been sent successfully, this function
+ * will return PJ_SUCCESS and the callback will not be
+ * called. If message cannot be sent immediately, this
+ * function will return PJ_EPENDING, and application will
+ * be notified later about the completion via the callback.
+ * Any statuses other than PJ_SUCCESS or PJ_EPENDING
+ * indicates immediate failure, and in this case the
+ * callback will not be called.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_send_raw(pjsip_endpoint *endpt,
+ pjsip_transport_type_e tp_type,
+ const pjsip_tpselector *sel,
+ const void *raw_data,
+ pj_size_t data_len,
+ const pj_sockaddr_t *addr,
+ int addr_len,
+ void *token,
+ pjsip_tp_send_callback cb);
+
+/**
+ * Send raw data to the specified destination URI. The actual destination
+ * address will be calculated from the URI, using normal SIP URI to host
+ * resolution.
+ *
+ * See also #pjsip_endpt_send_raw().
+ *
+ * @param endpt The SIP endpoint instance.
+ * @param dst_uri Destination address URI.
+ * @param sel Optional pointer to transport selector instance if
+ * application wants to use a specific transport instance
+ * rather then letting transport manager finds the suitable
+ * transport..
+ * @param raw_data The data to be sent.
+ * @param data_len The length of the data.
+ * @param token Arbitrary token to be returned back to callback.
+ * @param cb Optional callback to be called to notify caller about
+ * the completion status of the pending send operation.
+ *
+ * @return If the message has been sent successfully, this function
+ * will return PJ_SUCCESS and the callback will not be
+ * called. If message cannot be sent immediately, this
+ * function will return PJ_EPENDING, and application will
+ * be notified later about the completion via the callback.
+ * Any statuses other than PJ_SUCCESS or PJ_EPENDING
+ * indicates immediate failure, and in this case the
+ * callback will not be called.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_send_raw_to_uri(pjsip_endpoint *endpt,
+ const pj_str_t *dst_uri,
+ const pjsip_tpselector *sel,
+ const void *raw_data,
+ pj_size_t data_len,
+ void *token,
+ pjsip_tp_send_callback cb);
+
+/**
+ * This structure describes destination information to send response.
+ * It is initialized by calling #pjsip_get_response_addr().
+ *
+ * If the response message should be sent using transport from which
+ * the request was received, then transport, addr, and addr_len fields
+ * are initialized.
+ *
+ * The dst_host field is also initialized. It should be used when server
+ * fails to send the response using the transport from which the request
+ * was received, or when the transport is NULL, which means server
+ * must send the response to this address (this situation occurs when
+ * maddr parameter is set, or when rport param is not set in the request).
+ */
+typedef struct pjsip_response_addr
+{
+ pjsip_transport *transport; /**< Immediate transport to be used. */
+ pj_sockaddr addr; /**< Immediate address to send to. */
+ int addr_len; /**< Address length. */
+ pjsip_host_info dst_host; /**< Destination host to contact. */
+} pjsip_response_addr;
+
+/**
+ * Determine which address (and transport) to use to send response message
+ * based on the received request. This function follows the specification
+ * in section 18.2.2 of RFC 3261 and RFC 3581 for calculating the destination
+ * address and transport.
+ *
+ * The information about destination to send the response will be returned
+ * in res_addr argument. Please see #pjsip_response_addr for more info.
+ *
+ * @param pool The pool.
+ * @param rdata The incoming request received by the server.
+ * @param res_addr On return, it will be initialized with information about
+ * destination address and transport to send the response.
+ *
+ * @return zero (PJ_OK) if successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool,
+ pjsip_rx_data *rdata,
+ pjsip_response_addr *res_addr);
+
+/**
+ * Send response in tdata statelessly. The function will take care of which
+ * response destination and transport to use based on the information in the
+ * Via header (such as the presence of rport, symmetric transport, etc.).
+ *
+ * This function will create a new ephemeral transport if no existing
+ * transports can be used to send the message to the destination. The ephemeral
+ * transport will be destroyed after some period if it is not used to send any
+ * more messages.
+ *
+ * The behavior of this function complies with section 18.2.2 of RFC 3261
+ * and RFC 3581.
+ *
+ * @param endpt The endpoint instance.
+ * @param res_addr The information about the address and transport to send
+ * the response to. Application can get this information
+ * by calling #pjsip_get_response_addr().
+ * @param tdata The response message to be sent.
+ * @param token Token to be passed back when the callback is called.
+ * @param cb Optional callback to notify the transmission status
+ * to application, and to inform whether next address or
+ * transport will be tried.
+ *
+ * @return PJ_SUCCESS if response has been successfully created and
+ * sent to transport layer, or a non-zero error code.
+ * However, even when it returns PJ_SUCCESS, there is no
+ * guarantee that the response has been successfully sent.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt,
+ pjsip_response_addr *res_addr,
+ pjsip_tx_data *tdata,
+ void *token,
+ pjsip_send_callback cb);
+
+/**
+ * This is a convenient function which wraps #pjsip_get_response_addr() and
+ * #pjsip_endpt_send_response() in a single function.
+ *
+ * @param endpt The endpoint instance.
+ * @param rdata The original request to be responded.
+ * @param tdata The response message to be sent.
+ * @param token Token to be passed back when the callback is called.
+ * @param cb Optional callback to notify the transmission status
+ * to application, and to inform whether next address or
+ * transport will be tried.
+ *
+ * @return PJ_SUCCESS if response has been successfully created and
+ * sent to transport layer, or a non-zero error code.
+ * However, even when it returns PJ_SUCCESS, there is no
+ * guarantee that the response has been successfully sent.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_send_response2(pjsip_endpoint *endpt,
+ pjsip_rx_data *rdata,
+ pjsip_tx_data *tdata,
+ void *token,
+ pjsip_send_callback cb);
+
+/**
+ * This composite function sends response message statelessly to an incoming
+ * request message. Internally it calls #pjsip_endpt_create_response() and
+ * #pjsip_endpt_send_response().
+ *
+ * @param endpt The endpoint instance.
+ * @param rdata The incoming request message.
+ * @param st_code Status code of the response.
+ * @param st_text Optional status text of the response.
+ * @param hdr_list Optional header list to be added to the response.
+ * @param body Optional message body to be added to the response.
+ *
+ * @return PJ_SUCCESS if response message has successfully been
+ * sent.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_respond_stateless(pjsip_endpoint *endpt,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ const pjsip_hdr *hdr_list,
+ const pjsip_msg_body *body);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_TRANSACT_UTIL Stateful Operations
+ * @ingroup PJSIP_TRANSACT
+ * @brief Utility function to send requests/responses statefully.
+ * @{
+ */
+
+/**
+ * This composite function creates and sends response statefully for the
+ * incoming request.
+ *
+ * @param endpt The endpoint instance.
+ * @param tsx_user The module to be registered as transaction user.
+ * @param rdata The incoming request message.
+ * @param st_code Status code of the response.
+ * @param st_text Optional status text of the response.
+ * @param hdr_list Optional header list to be added to the response.
+ * @param body Optional message body to be added to the response.
+ * @param p_tsx Optional pointer to receive the transaction which was
+ * created to send the response.
+ *
+ * @return PJ_SUCCESS if response message has successfully been
+ * created.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_respond( pjsip_endpoint *endpt,
+ pjsip_module *tsx_user,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ const pjsip_hdr *hdr_list,
+ const pjsip_msg_body *body,
+ pjsip_transaction **p_tsx );
+
+/**
+ * Type of callback to be specified in #pjsip_endpt_send_request().
+ *
+ * @param token The token that was given in #pjsip_endpt_send_request()
+ * @param e Completion event.
+ */
+typedef void (*pjsip_endpt_send_callback)(void *token, pjsip_event *e);
+
+/**
+ * Send outgoing request and initiate UAC transaction for the request.
+ * This is an auxiliary function to be used by application to send arbitrary
+ * requests outside a dialog. To send a request within a dialog, application
+ * should use #pjsip_dlg_send_request instead.
+ *
+ * @param endpt The endpoint instance.
+ * @param tdata The transmit data to be sent.
+ * @param timeout Optional timeout for final response to be received, or -1
+ * if the transaction should not have a timeout restriction.
+ * The value is in miliseconds.
+ * @param token Optional token to be associated with the transaction, and
+ * to be passed to the callback.
+ * @param cb Optional callback to be called when the transaction has
+ * received a final response. The callback will be called with
+ * the previously registered token and the event that triggers
+ * the completion of the transaction.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt,
+ pjsip_tx_data *tdata,
+ pj_int32_t timeout,
+ void *token,
+ pjsip_endpt_send_callback cb);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_PROXY_CORE Core Proxy Layer
+ * @brief Core proxy operations
+ * @{
+ */
+
+/**
+ * Create new request message to be forwarded upstream to new destination URI
+ * in uri. The new request is a full/deep clone of the request received in
+ * rdata, unless if other copy mechanism is specified in the options.
+ * The branch parameter, if not NULL, will be used as the branch-param in
+ * the Via header. If it is NULL, then a unique branch parameter will be used.
+ *
+ * Note: this function DOES NOT perform Route information preprocessing as
+ * described in RFC 3261 Section 16.4. Application must take care of
+ * removing/updating the Route headers according of the rules as
+ * described in that section.
+ *
+ * @param endpt The endpoint instance.
+ * @param rdata The incoming request message.
+ * @param uri The URI where the request will be forwarded to.
+ * @param branch Optional branch parameter. Application may specify its
+ * own branch, for example if it wishes to perform loop
+ * detection. If the branch parameter is not specified,
+ * this function will generate its own by calling
+ * #pjsip_calculate_branch_id() function.
+ * @param options Optional option flags when duplicating the message.
+ * @param tdata The result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_request_fwd(pjsip_endpoint *endpt,
+ pjsip_rx_data *rdata,
+ const pjsip_uri *uri,
+ const pj_str_t *branch,
+ unsigned options,
+ pjsip_tx_data **tdata);
+
+
+
+/**
+ * Create new response message to be forwarded downstream by the proxy from
+ * the response message found in rdata. Note that this function practically
+ * will clone the response as is, i.e. without checking the validity of the
+ * response or removing top most Via header. This function will perform
+ * full/deep clone of the response, unless other copy mechanism is used in
+ * the options.
+ *
+ * @param endpt The endpoint instance.
+ * @param rdata The incoming response message.
+ * @param options Optional option flags when duplicate the message.
+ * @param tdata The result
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_response_fwd( pjsip_endpoint *endpt,
+ pjsip_rx_data *rdata,
+ unsigned options,
+ pjsip_tx_data **tdata);
+
+
+
+/**
+ * Create a globally unique branch parameter based on the information in
+ * the incoming request message, for the purpose of creating a new request
+ * for forwarding. This is the default implementation used by
+ * #pjsip_endpt_create_request_fwd() function if the branch parameter is
+ * not specified.
+ *
+ * The default implementation here will just create an MD5 hash of the
+ * top-most Via.
+ *
+ * Note that the returned string was allocated from rdata's pool.
+ *
+ * @param rdata The incoming request message.
+ *
+ * @return Unique branch-ID string.
+ */
+PJ_DECL(pj_str_t) pjsip_calculate_branch_id( pjsip_rx_data *rdata );
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_MISC_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip_auth.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip_auth.h
new file mode 100644
index 0000000..06a88e0
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip_auth.h
@@ -0,0 +1,38 @@
+/* $Id: pjsip_auth.h 2394 2008-12-23 17:27:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_AUTH_H__
+#define __PJSIP_AUTH_H__
+
+/**
+ * @defgroup PJSIP_AUTH SIP Authorization module
+ */
+
+/**
+ * @file pjsip_auth.h
+ * @brief SIP Authorization Module.
+ */
+
+
+#include <pjsip_auth/sip_auth.h>
+#include <pjsip_auth/sip_auth_msg.h>
+#include <pjsip_auth/sip_auth_parser.h>
+
+#endif /* __PJSIP_AUTH_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip_simple.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip_simple.h
new file mode 100644
index 0000000..74983e8
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip_simple.h
@@ -0,0 +1,46 @@
+/* $Id: pjsip_simple.h 2968 2009-10-26 11:21:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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
+ */
+
+/**
+ * @defgroup PJSIP_SIMPLE Event and Presence Framework
+ */
+
+/**
+ * @file pjsip_simple.h
+ * @brief SIP SIMPLE Extension
+ */
+
+/*
+ * Include this header file to get all functionalities for SIMPLE extension
+ * (SIP for Instant Messaging and Presence Leveraging Extension).
+ */
+#ifndef __PJSIP_SIMPLE_H__
+#define __PJSIP_SIMPLE_H__
+
+#include <pjsip-simple/evsub.h>
+#include <pjsip-simple/evsub_msg.h>
+#include <pjsip-simple/iscomposing.h>
+#include <pjsip-simple/mwi.h>
+#include <pjsip-simple/presence.h>
+#include <pjsip-simple/pidf.h>
+#include <pjsip-simple/publish.h>
+#include <pjsip-simple/xpidf.h>
+
+#endif /* __PJSIP_SIMPLE_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsip_ua.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip_ua.h
new file mode 100644
index 0000000..e133cef
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsip_ua.h
@@ -0,0 +1,32 @@
+/* $Id: pjsip_ua.h 2858 2009-08-11 12:42:38Z nanang $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_UA_H__
+#define __PJSIP_UA_H__
+
+#include <pjsip-ua/sip_inv.h>
+#include <pjsip-ua/sip_regc.h>
+#include <pjsip-ua/sip_replaces.h>
+#include <pjsip-ua/sip_xfer.h>
+#include <pjsip-ua/sip_100rel.h>
+#include <pjsip-ua/sip_timer.h>
+
+
+#endif /* __PJSIP_UA_H__ */
+
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua.h
new file mode 100644
index 0000000..116530a
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua.h
@@ -0,0 +1,4542 @@
+/* $Id: pjsua.h 3021 2009-11-20 23:33:07Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSUA_H__
+#define __PJSUA_H__
+
+/**
+ * @file pjsua.h
+ * @brief PJSUA API.
+ */
+
+
+/* Include all PJSIP core headers. */
+#include <pjsip.h>
+
+/* Include all PJMEDIA headers. */
+#include <pjmedia.h>
+
+/* Include all PJMEDIA-CODEC headers. */
+#include <pjmedia-codec.h>
+
+/* Include all PJSIP-UA headers */
+#include <pjsip_ua.h>
+
+/* Include all PJSIP-SIMPLE headers */
+#include <pjsip_simple.h>
+
+/* Include all PJNATH headers */
+#include <pjnath.h>
+
+/* Include all PJLIB-UTIL headers. */
+#include <pjlib-util.h>
+
+/* Include all PJLIB headers. */
+#include <pjlib.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJSUA_LIB PJSUA API - High Level Softphone API
+ * @brief Very high level API for constructing SIP UA applications.
+ * @{
+ *
+ * @section pjsua_api_intro A SIP User Agent API for C/C++
+ *
+ * PJSUA API is very high level API for constructing SIP multimedia user agent
+ * applications. It wraps together the signaling and media functionalities
+ * into an easy to use call API, provides account management, buddy
+ * management, presence, instant messaging, along with multimedia
+ * features such as conferencing, file streaming, local playback,
+ * voice recording, and so on.
+ *
+ * @subsection pjsua_for_c_cpp C/C++ Binding
+ * Application must link with <b>pjsua-lib</b> to use this API. In addition,
+ * this library depends on the following libraries:
+ * - <b>pjsip-ua</b>,
+ * - <b>pjsip-simple</b>,
+ * - <b>pjsip-core</b>,
+ * - <b>pjmedia</b>,
+ * - <b>pjmedia-codec</b>,
+ * - <b>pjlib-util</b>, and
+ * - <b>pjlib</b>,
+ *
+ * so application must also link with these libraries as well. For more
+ * information, please refer to
+ * <A HREF="http://www.pjsip.org/using.htm">Getting Started with PJSIP</A>
+ * page.
+ *
+ * @section pjsua_samples
+ *
+ * Few samples are provided:
+ *
+ - @ref page_pjsip_sample_simple_pjsuaua_c\n
+ Very simple SIP User Agent with registration, call, and media, using
+ PJSUA-API, all in under 200 lines of code.
+
+ - @ref page_pjsip_samples_pjsua\n
+ This is the reference implementation for PJSIP and PJMEDIA.
+ PJSUA is a console based application, designed to be simple enough
+ to be readble, but powerful enough to demonstrate all features
+ available in PJSIP and PJMEDIA.\n
+
+ * @section root_using_pjsua_lib Using PJSUA API
+ *
+ * Please refer to @ref PJSUA_LIB_BASE on how to create and initialize the API.
+ * And then see the Modules on the bottom of this page for more information
+ * about specific subject.
+ */
+
+
+
+/*****************************************************************************
+ * BASE API
+ */
+
+/**
+ * @defgroup PJSUA_LIB_BASE PJSUA-API Basic API
+ * @ingroup PJSUA_LIB
+ * @brief Basic application creation/initialization, logging configuration, etc.
+ * @{
+ *
+ * The base PJSUA API controls PJSUA creation, initialization, and startup, and
+ * also provides various auxiliary functions.
+ *
+ * @section using_pjsua_lib Using PJSUA Library
+ *
+ * @subsection creating_pjsua_lib Creating PJSUA
+ *
+ * Before anything else, application must create PJSUA by calling
+ * #pjsua_create().
+ * This, among other things, will initialize PJLIB, which is crucial before
+ * any PJLIB functions can be called, PJLIB-UTIL, and create a SIP endpoint.
+ *
+ * After this function is called, application can create a memory pool (with
+ * #pjsua_pool_create()) and read configurations from command line or file to
+ * build the settings to initialize PJSUA below.
+ *
+ * @subsection init_pjsua_lib Initializing PJSUA
+ *
+ * After PJSUA is created, application can initialize PJSUA by calling
+ * #pjsua_init(). This function takes several optional configuration settings
+ * in the argument, if application wants to set them.
+ *
+ * @subsubsection init_pjsua_lib_c_cpp PJSUA-LIB Initialization (in C)
+ * Sample code to initialize PJSUA in C code:
+ \code
+
+ #include <pjsua-lib/pjsua.h>
+
+ #define THIS_FILE __FILE__
+
+ static pj_status_t app_init(void)
+ {
+ pjsua_config ua_cfg;
+ pjsua_logging_config log_cfg;
+ pjsua_media_config media_cfg;
+ pj_status_t status;
+
+ // Must create pjsua before anything else!
+ status = pjsua_create();
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Error initializing pjsua", status);
+ return status;
+ }
+
+ // Initialize configs with default settings.
+ pjsua_config_default(&ua_cfg);
+ pjsua_logging_config_default(&log_cfg);
+ pjsua_media_config_default(&media_cfg);
+
+ // At the very least, application would want to override
+ // the call callbacks in pjsua_config:
+ ua_cfg.cb.on_incoming_call = ...
+ ua_cfg.cb.on_call_state = ..
+ ...
+
+ // Customize other settings (or initialize them from application specific
+ // configuration file):
+ ...
+
+ // Initialize pjsua
+ status = pjsua_init(&ua_cfg, &log_cfg, &media_cfg);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Error initializing pjsua", status);
+ return status;
+ }
+ .
+ ...
+ }
+ \endcode
+ *
+ *
+
+
+ * @subsection other_init_pjsua_lib Other Initialization
+ *
+ * After PJSUA is initialized with #pjsua_init(), application will normally
+ * need/want to perform the following tasks:
+ *
+ * - create SIP transport with #pjsua_transport_create(). Application would
+ * to call #pjsua_transport_create() for each transport types that it
+ * wants to support (for example, UDP, TCP, and TLS). Please see
+ * @ref PJSUA_LIB_TRANSPORT section for more info.
+ * - create one or more SIP accounts with #pjsua_acc_add() or
+ * #pjsua_acc_add_local(). The SIP account is used for registering with
+ * the SIP server, if any. Please see @ref PJSUA_LIB_ACC for more info.
+ * - add one or more buddies with #pjsua_buddy_add(). Please see
+ * @ref PJSUA_LIB_BUDDY section for more info.
+ * - optionally configure the sound device, codec settings, and other
+ * media settings. Please see @ref PJSUA_LIB_MEDIA for more info.
+ *
+ *
+ * @subsection starting_pjsua_lib Starting PJSUA
+ *
+ * After all initializations have been done, application must call
+ * #pjsua_start() to start PJSUA. This function will check that all settings
+ * have been properly configured, and apply default settings when they haven't,
+ * or report error status when it is unable to recover from missing settings.
+ *
+ * Most settings can be changed during run-time. For example, application
+ * may add, modify, or delete accounts, buddies, or change media settings
+ * during run-time.
+ *
+ * @subsubsection starting_pjsua_lib_c C Example for Starting PJSUA
+ * Sample code:
+ \code
+ static pj_status_t app_run(void)
+ {
+ pj_status_t status;
+
+ // Start pjsua
+ status = pjsua_start();
+ if (status != PJ_SUCCESS) {
+ pjsua_destroy();
+ pjsua_perror(THIS_FILE, "Error starting pjsua", status);
+ return status;
+ }
+
+ // Run application loop
+ while (1) {
+ char choice[10];
+
+ printf("Select menu: ");
+ fgets(choice, sizeof(choice), stdin);
+ ...
+ }
+ }
+ \endcode
+
+ */
+
+/** Constant to identify invalid ID for all sorts of IDs. */
+#define PJSUA_INVALID_ID (-1)
+
+/** Call identification */
+typedef int pjsua_call_id;
+
+/** Account identification */
+typedef int pjsua_acc_id;
+
+/** Buddy identification */
+typedef int pjsua_buddy_id;
+
+/** File player identification */
+typedef int pjsua_player_id;
+
+/** File recorder identification */
+typedef int pjsua_recorder_id;
+
+/** Conference port identification */
+typedef int pjsua_conf_port_id;
+
+/** Opaque declaration for server side presence subscription */
+typedef struct pjsua_srv_pres pjsua_srv_pres;
+
+/** Forward declaration for pjsua_msg_data */
+typedef struct pjsua_msg_data pjsua_msg_data;
+
+
+/**
+ * Maximum proxies in account.
+ */
+#ifndef PJSUA_ACC_MAX_PROXIES
+# define PJSUA_ACC_MAX_PROXIES 8
+#endif
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+
+/**
+ * Default value of SRTP mode usage. Valid values are PJMEDIA_SRTP_DISABLED,
+ * PJMEDIA_SRTP_OPTIONAL, and PJMEDIA_SRTP_MANDATORY.
+ */
+#ifndef PJSUA_DEFAULT_USE_SRTP
+ #define PJSUA_DEFAULT_USE_SRTP PJMEDIA_SRTP_DISABLED
+#endif
+
+/**
+ * Default value of secure signaling requirement for SRTP.
+ * Valid values are:
+ * 0: SRTP does not require secure signaling
+ * 1: SRTP requires secure transport such as TLS
+ * 2: SRTP requires secure end-to-end transport (SIPS)
+ */
+#ifndef PJSUA_DEFAULT_SRTP_SECURE_SIGNALING
+ #define PJSUA_DEFAULT_SRTP_SECURE_SIGNALING 1
+#endif
+
+#endif
+
+/**
+ * Logging configuration, which can be (optionally) specified when calling
+ * #pjsua_init(). Application must call #pjsua_logging_config_default() to
+ * initialize this structure with the default values.
+ */
+typedef struct pjsua_logging_config
+{
+ /**
+ * Log incoming and outgoing SIP message? Yes!
+ */
+ pj_bool_t msg_logging;
+
+ /**
+ * Input verbosity level. Value 5 is reasonable.
+ */
+ unsigned level;
+
+ /**
+ * Verbosity level for console. Value 4 is reasonable.
+ */
+ unsigned console_level;
+
+ /**
+ * Log decoration.
+ */
+ unsigned decor;
+
+ /**
+ * Optional log filename.
+ */
+ pj_str_t log_filename;
+
+ /**
+ * Additional flags to be given to #pj_file_open() when opening
+ * the log file. By default, the flag is PJ_O_WRONLY. Application
+ * may set PJ_O_APPEND here so that logs are appended to existing
+ * file instead of overwriting it.
+ *
+ * Default is 0.
+ */
+ unsigned log_file_flags;
+
+ /**
+ * Optional callback function to be called to write log to
+ * application specific device. This function will be called for
+ * log messages on input verbosity level.
+ */
+ void (*cb)(int level, const char *data, int len);
+
+
+} pjsua_logging_config;
+
+
+/**
+ * Use this function to initialize logging config.
+ *
+ * @param cfg The logging config to be initialized.
+ */
+PJ_DECL(void) pjsua_logging_config_default(pjsua_logging_config *cfg);
+
+
+/**
+ * Use this function to duplicate logging config.
+ *
+ * @param pool Pool to use.
+ * @param dst Destination config.
+ * @param src Source config.
+ */
+PJ_DECL(void) pjsua_logging_config_dup(pj_pool_t *pool,
+ pjsua_logging_config *dst,
+ const pjsua_logging_config *src);
+
+
+/**
+ * Structure to be passed on MWI callback.
+ */
+typedef struct pjsua_mwi_info
+{
+ pjsip_evsub *evsub; /**< Event subscription session, for
+ reference. */
+ pjsip_rx_data *rdata; /**< The received NOTIFY request. */
+} pjsua_mwi_info;
+
+
+/**
+ * This structure describes application callback to receive various event
+ * notification from PJSUA-API. All of these callbacks are OPTIONAL,
+ * although definitely application would want to implement some of
+ * the important callbacks (such as \a on_incoming_call).
+ */
+typedef struct pjsua_callback
+{
+ /**
+ * Notify application when invite state has changed.
+ * Application may then query the call info to get the
+ * detail call states by calling pjsua_call_get_info() function.
+ *
+ * @param call_id The call index.
+ * @param e Event which causes the call state to change.
+ */
+ void (*on_call_state)(pjsua_call_id call_id, pjsip_event *e);
+
+ /**
+ * Notify application on incoming call.
+ *
+ * @param acc_id The account which match the incoming call.
+ * @param call_id The call id that has just been created for
+ * the call.
+ * @param rdata The incoming INVITE request.
+ */
+ void (*on_incoming_call)(pjsua_acc_id acc_id, pjsua_call_id call_id,
+ pjsip_rx_data *rdata);
+
+ /**
+ * This is a general notification callback which is called whenever
+ * a transaction within the call has changed state. Application can
+ * implement this callback for example to monitor the state of
+ * outgoing requests, or to answer unhandled incoming requests
+ * (such as INFO) with a final response.
+ *
+ * @param call_id Call identification.
+ * @param tsx The transaction which has changed state.
+ * @param e Transaction event that caused the state change.
+ */
+ void (*on_call_tsx_state)(pjsua_call_id call_id,
+ pjsip_transaction *tsx,
+ pjsip_event *e);
+
+ /**
+ * Notify application when media state in the call has changed.
+ * Normal application would need to implement this callback, e.g.
+ * to connect the call's media to sound device. When ICE is used,
+ * this callback will also be called to report ICE negotiation
+ * failure.
+ *
+ * @param call_id The call index.
+ */
+ void (*on_call_media_state)(pjsua_call_id call_id);
+
+
+ /**
+ * Notify application when media session is created and before it is
+ * registered to the conference bridge. Application may return different
+ * media port if it has added media processing port to the stream. This
+ * media port then will be added to the conference bridge instead.
+ *
+ * @param call_id Call identification.
+ * @param sess Media session for the call.
+ * @param stream_idx Stream index in the media session.
+ * @param p_port On input, it specifies the media port of the
+ * stream. Application may modify this pointer to
+ * point to different media port to be registered
+ * to the conference bridge.
+ */
+ void (*on_stream_created)(pjsua_call_id call_id,
+ pjmedia_session *sess,
+ unsigned stream_idx,
+ pjmedia_port **p_port);
+
+ /**
+ * Notify application when media session has been unregistered from the
+ * conference bridge and about to be destroyed.
+ *
+ * @param call_id Call identification.
+ * @param sess Media session for the call.
+ * @param stream_idx Stream index in the media session.
+ */
+ void (*on_stream_destroyed)(pjsua_call_id call_id,
+ pjmedia_session *sess,
+ unsigned stream_idx);
+
+ /**
+ * Notify application upon incoming DTMF digits.
+ *
+ * @param call_id The call index.
+ * @param digit DTMF ASCII digit.
+ */
+ void (*on_dtmf_digit)(pjsua_call_id call_id, int digit);
+
+ /**
+ * Notify application on call being transfered (i.e. REFER is received).
+ * Application can decide to accept/reject transfer request
+ * by setting the code (default is 202). When this callback
+ * is not defined, the default behavior is to accept the
+ * transfer.
+ *
+ * @param call_id The call index.
+ * @param dst The destination where the call will be
+ * transfered to.
+ * @param code Status code to be returned for the call transfer
+ * request. On input, it contains status code 200.
+ */
+ void (*on_call_transfer_request)(pjsua_call_id call_id,
+ const pj_str_t *dst,
+ pjsip_status_code *code);
+
+ /**
+ * Notify application of the status of previously sent call
+ * transfer request. Application can monitor the status of the
+ * call transfer request, for example to decide whether to
+ * terminate existing call.
+ *
+ * @param call_id Call ID.
+ * @param st_code Status progress of the transfer request.
+ * @param st_text Status progress text.
+ * @param final If non-zero, no further notification will
+ * be reported. The st_code specified in
+ * this callback is the final status.
+ * @param p_cont Initially will be set to non-zero, application
+ * can set this to FALSE if it no longer wants
+ * to receie further notification (for example,
+ * after it hangs up the call).
+ */
+ void (*on_call_transfer_status)(pjsua_call_id call_id,
+ int st_code,
+ const pj_str_t *st_text,
+ pj_bool_t final,
+ pj_bool_t *p_cont);
+
+ /**
+ * Notify application about incoming INVITE with Replaces header.
+ * Application may reject the request by setting non-2xx code.
+ *
+ * @param call_id The call ID to be replaced.
+ * @param rdata The incoming INVITE request to replace the call.
+ * @param st_code Status code to be set by application. Application
+ * should only return a final status (200-699).
+ * @param st_text Optional status text to be set by application.
+ */
+ void (*on_call_replace_request)(pjsua_call_id call_id,
+ pjsip_rx_data *rdata,
+ int *st_code,
+ pj_str_t *st_text);
+
+ /**
+ * Notify application that an existing call has been replaced with
+ * a new call. This happens when PJSUA-API receives incoming INVITE
+ * request with Replaces header.
+ *
+ * After this callback is called, normally PJSUA-API will disconnect
+ * \a old_call_id and establish \a new_call_id.
+ *
+ * @param old_call_id Existing call which to be replaced with the
+ * new call.
+ * @param new_call_id The new call.
+ * @param rdata The incoming INVITE with Replaces request.
+ */
+ void (*on_call_replaced)(pjsua_call_id old_call_id,
+ pjsua_call_id new_call_id);
+
+
+ /**
+ * Notify application when registration status has changed.
+ * Application may then query the account info to get the
+ * registration details.
+ *
+ * @param acc_id Account ID.
+ */
+ void (*on_reg_state)(pjsua_acc_id acc_id);
+
+ /**
+ * Notification when incoming SUBSCRIBE request is received. Application
+ * may use this callback to authorize the incoming subscribe request
+ * (e.g. ask user permission if the request should be granted).
+ *
+ * If this callback is not implemented, all incoming presence subscription
+ * requests will be accepted.
+ *
+ * If this callback is implemented, application has several choices on
+ * what to do with the incoming request:
+ * - it may reject the request immediately by specifying non-200 class
+ * final response in the \a code argument.
+ * - it may immediately accept the request by specifying 200 as the
+ * \a code argument. This is the default value if application doesn't
+ * set any value to the \a code argument. In this case, the library
+ * will automatically send NOTIFY request upon returning from this
+ * callback.
+ * - it may delay the processing of the request, for example to request
+ * user permission whether to accept or reject the request. In this
+ * case, the application MUST set the \a code argument to 202, and
+ * later calls #pjsua_pres_notify() to accept or reject the
+ * subscription request.
+ *
+ * Any \a code other than 200 and 202 will be treated as 200.
+ *
+ * Application MUST return from this callback immediately (e.g. it must
+ * not block in this callback while waiting for user confirmation).
+ *
+ * @param srv_pres Server presence subscription instance. If
+ * application delays the acceptance of the request,
+ * it will need to specify this object when calling
+ * #pjsua_pres_notify().
+ * @param acc_id Account ID most appropriate for this request.
+ * @param buddy_id ID of the buddy matching the sender of the
+ * request, if any, or PJSUA_INVALID_ID if no
+ * matching buddy is found.
+ * @param from The From URI of the request.
+ * @param rdata The incoming request.
+ * @param code The status code to respond to the request. The
+ * default value is 200. Application may set this
+ * to other final status code to accept or reject
+ * the request.
+ * @param reason The reason phrase to respond to the request.
+ * @param msg_data If the application wants to send additional
+ * headers in the response, it can put it in this
+ * parameter.
+ */
+ void (*on_incoming_subscribe)(pjsua_acc_id acc_id,
+ pjsua_srv_pres *srv_pres,
+ pjsua_buddy_id buddy_id,
+ const pj_str_t *from,
+ pjsip_rx_data *rdata,
+ pjsip_status_code *code,
+ pj_str_t *reason,
+ pjsua_msg_data *msg_data);
+
+ /**
+ * Notification when server side subscription state has changed.
+ * This callback is optional as application normally does not need
+ * to do anything to maintain server side presence subscription.
+ *
+ * @param acc_id The account ID.
+ * @param srv_pres Server presence subscription object.
+ * @param remote_uri Remote URI string.
+ * @param state New subscription state.
+ * @param event PJSIP event that triggers the state change.
+ */
+ void (*on_srv_subscribe_state)(pjsua_acc_id acc_id,
+ pjsua_srv_pres *srv_pres,
+ const pj_str_t *remote_uri,
+ pjsip_evsub_state state,
+ pjsip_event *event);
+
+ /**
+ * Notify application when the buddy state has changed.
+ * Application may then query the buddy into to get the details.
+ *
+ * @param buddy_id The buddy id.
+ */
+ void (*on_buddy_state)(pjsua_buddy_id buddy_id);
+
+ /**
+ * Notify application on incoming pager (i.e. MESSAGE request).
+ * Argument call_id will be -1 if MESSAGE request is not related to an
+ * existing call.
+ *
+ * See also \a on_pager2() callback for the version with \a pjsip_rx_data
+ * passed as one of the argument.
+ *
+ * @param call_id Containts the ID of the call where the IM was
+ * sent, or PJSUA_INVALID_ID if the IM was sent
+ * outside call context.
+ * @param from URI of the sender.
+ * @param to URI of the destination message.
+ * @param contact The Contact URI of the sender, if present.
+ * @param mime_type MIME type of the message.
+ * @param body The message content.
+ */
+ void (*on_pager)(pjsua_call_id call_id, const pj_str_t *from,
+ const pj_str_t *to, const pj_str_t *contact,
+ const pj_str_t *mime_type, const pj_str_t *body);
+
+ /**
+ * This is the alternative version of the \a on_pager() callback with
+ * \a pjsip_rx_data argument.
+ *
+ * @param call_id Containts the ID of the call where the IM was
+ * sent, or PJSUA_INVALID_ID if the IM was sent
+ * outside call context.
+ * @param from URI of the sender.
+ * @param to URI of the destination message.
+ * @param contact The Contact URI of the sender, if present.
+ * @param mime_type MIME type of the message.
+ * @param body The message content.
+ * @param rdata The incoming MESSAGE request.
+ * @param acc_id Account ID most suitable for this message.
+ */
+ void (*on_pager2)(pjsua_call_id call_id, const pj_str_t *from,
+ const pj_str_t *to, const pj_str_t *contact,
+ const pj_str_t *mime_type, const pj_str_t *body,
+ pjsip_rx_data *rdata, pjsua_acc_id acc_id);
+
+ /**
+ * Notify application about the delivery status of outgoing pager
+ * request. See also on_pager_status2() callback for the version with
+ * \a pjsip_rx_data in the argument list.
+ *
+ * @param call_id Containts the ID of the call where the IM was
+ * sent, or PJSUA_INVALID_ID if the IM was sent
+ * outside call context.
+ * @param to Destination URI.
+ * @param body Message body.
+ * @param user_data Arbitrary data that was specified when sending
+ * IM message.
+ * @param status Delivery status.
+ * @param reason Delivery status reason.
+ */
+ void (*on_pager_status)(pjsua_call_id call_id,
+ const pj_str_t *to,
+ const pj_str_t *body,
+ void *user_data,
+ pjsip_status_code status,
+ const pj_str_t *reason);
+
+ /**
+ * Notify application about the delivery status of outgoing pager
+ * request.
+ *
+ * @param call_id Containts the ID of the call where the IM was
+ * sent, or PJSUA_INVALID_ID if the IM was sent
+ * outside call context.
+ * @param to Destination URI.
+ * @param body Message body.
+ * @param user_data Arbitrary data that was specified when sending
+ * IM message.
+ * @param status Delivery status.
+ * @param reason Delivery status reason.
+ * @param tdata The original MESSAGE request.
+ * @param rdata The incoming MESSAGE response, or NULL if the
+ * message transaction fails because of time out
+ * or transport error.
+ * @param acc_id Account ID from this the instant message was
+ * send.
+ */
+ void (*on_pager_status2)(pjsua_call_id call_id,
+ const pj_str_t *to,
+ const pj_str_t *body,
+ void *user_data,
+ pjsip_status_code status,
+ const pj_str_t *reason,
+ pjsip_tx_data *tdata,
+ pjsip_rx_data *rdata,
+ pjsua_acc_id acc_id);
+
+ /**
+ * Notify application about typing indication.
+ *
+ * @param call_id Containts the ID of the call where the IM was
+ * sent, or PJSUA_INVALID_ID if the IM was sent
+ * outside call context.
+ * @param from URI of the sender.
+ * @param to URI of the destination message.
+ * @param contact The Contact URI of the sender, if present.
+ * @param is_typing Non-zero if peer is typing, or zero if peer
+ * has stopped typing a message.
+ */
+ void (*on_typing)(pjsua_call_id call_id, const pj_str_t *from,
+ const pj_str_t *to, const pj_str_t *contact,
+ pj_bool_t is_typing);
+
+ /**
+ * Notify application about typing indication.
+ *
+ * @param call_id Containts the ID of the call where the IM was
+ * sent, or PJSUA_INVALID_ID if the IM was sent
+ * outside call context.
+ * @param from URI of the sender.
+ * @param to URI of the destination message.
+ * @param contact The Contact URI of the sender, if present.
+ * @param is_typing Non-zero if peer is typing, or zero if peer
+ * has stopped typing a message.
+ * @param rdata The received request.
+ * @param acc_id Account ID most suitable for this message.
+ */
+ void (*on_typing2)(pjsua_call_id call_id, const pj_str_t *from,
+ const pj_str_t *to, const pj_str_t *contact,
+ pj_bool_t is_typing, pjsip_rx_data *rdata,
+ pjsua_acc_id acc_id);
+
+ /**
+ * Callback when the library has finished performing NAT type
+ * detection.
+ *
+ * @param res NAT detection result.
+ */
+ void (*on_nat_detect)(const pj_stun_nat_detect_result *res);
+
+ /**
+ * This callback is called when the call is about to resend the
+ * INVITE request to the specified target, following the previously
+ * received redirection response.
+ *
+ * Application may accept the redirection to the specified target
+ * (the default behavior if this callback is implemented), reject
+ * this target only and make the session continue to try the next
+ * target in the list if such target exists, stop the whole
+ * redirection process altogether and cause the session to be
+ * disconnected, or defer the decision to ask for user confirmation.
+ *
+ * This callback is optional. If this callback is not implemented,
+ * the default behavior is to NOT follow the redirection response.
+ *
+ * @param call_id The call ID.
+ * @param target The current target to be tried.
+ * @param e The event that caused this callback to be called.
+ * This could be the receipt of 3xx response, or
+ * 4xx/5xx response received for the INVITE sent to
+ * subsequent targets, or NULL if this callback is
+ * called from within #pjsua_call_process_redirect()
+ * context.
+ *
+ * @return Action to be performed for the target. Set this
+ * parameter to one of the value below:
+ * - PJSIP_REDIRECT_ACCEPT: immediately accept the
+ * redirection (default value). When set, the
+ * call will immediately resend INVITE request
+ * to the target.
+ * - PJSIP_REDIRECT_REJECT: immediately reject this
+ * target. The call will continue retrying with
+ * next target if present, or disconnect the call
+ * if there is no more target to try.
+ * - PJSIP_REDIRECT_STOP: stop the whole redirection
+ * process and immediately disconnect the call. The
+ * on_call_state() callback will be called with
+ * PJSIP_INV_STATE_DISCONNECTED state immediately
+ * after this callback returns.
+ * - PJSIP_REDIRECT_PENDING: set to this value if
+ * no decision can be made immediately (for example
+ * to request confirmation from user). Application
+ * then MUST call #pjsua_call_process_redirect()
+ * to either accept or reject the redirection upon
+ * getting user decision.
+ */
+ pjsip_redirect_op (*on_call_redirected)(pjsua_call_id call_id,
+ const pjsip_uri *target,
+ const pjsip_event *e);
+
+ /**
+ * This callback is called when a NOTIFY request for message summary /
+ * message waiting indication is received.
+ *
+ * @param acc_id The account ID.
+ * @param mwi_info Structure containing details of the event,
+ * including the received NOTIFY request in the
+ * \a rdata field.
+ */
+ void (*on_mwi_info)(pjsua_acc_id acc_id, pjsua_mwi_info *mwi_info);
+
+} pjsua_callback;
+
+
+
+
+/**
+ * This structure describes the settings to control the API and
+ * user agent behavior, and can be specified when calling #pjsua_init().
+ * Before setting the values, application must call #pjsua_config_default()
+ * to initialize this structure with the default values.
+ */
+typedef struct pjsua_config
+{
+
+ /**
+ * Maximum calls to support (default: 4). The value specified here
+ * must be smaller than the compile time maximum settings
+ * PJSUA_MAX_CALLS, which by default is 32. To increase this
+ * limit, the library must be recompiled with new PJSUA_MAX_CALLS
+ * value.
+ */
+ unsigned max_calls;
+
+ /**
+ * Number of worker threads. Normally application will want to have at
+ * least one worker thread, unless when it wants to poll the library
+ * periodically, which in this case the worker thread can be set to
+ * zero.
+ */
+ unsigned thread_cnt;
+
+ /**
+ * Number of nameservers. If no name server is configured, the SIP SRV
+ * resolution would be disabled, and domain will be resolved with
+ * standard pj_gethostbyname() function.
+ */
+ unsigned nameserver_count;
+
+ /**
+ * Array of nameservers to be used by the SIP resolver subsystem.
+ * The order of the name server specifies the priority (first name
+ * server will be used first, unless it is not reachable).
+ */
+ pj_str_t nameserver[4];
+
+ /**
+ * Force loose-route to be used in all route/proxy URIs (outbound_proxy
+ * and account's proxy settings). When this setting is enabled, the
+ * library will check all the route/proxy URIs specified in the settings
+ * and append ";lr" parameter to the URI if the parameter is not present.
+ *
+ * Default: 1
+ */
+ pj_bool_t force_lr;
+
+ /**
+ * Number of outbound proxies in the \a outbound_proxy array.
+ */
+ unsigned outbound_proxy_cnt;
+
+ /**
+ * Specify the URL of outbound proxies to visit for all outgoing requests.
+ * The outbound proxies will be used for all accounts, and it will
+ * be used to build the route set for outgoing requests. The final
+ * route set for outgoing requests will consists of the outbound proxies
+ * and the proxy configured in the account.
+ */
+ pj_str_t outbound_proxy[4];
+
+ /**
+ * Warning: deprecated, please use \a stun_srv field instead. To maintain
+ * backward compatibility, if \a stun_srv_cnt is zero then the value of
+ * this field will be copied to \a stun_srv field, if present.
+ *
+ * Specify domain name to be resolved with DNS SRV resolution to get the
+ * address of the STUN server. Alternatively application may specify
+ * \a stun_host instead.
+ *
+ * If DNS SRV resolution failed for this domain, then DNS A resolution
+ * will be performed only if \a stun_host is specified.
+ */
+ pj_str_t stun_domain;
+
+ /**
+ * Warning: deprecated, please use \a stun_srv field instead. To maintain
+ * backward compatibility, if \a stun_srv_cnt is zero then the value of
+ * this field will be copied to \a stun_srv field, if present.
+ *
+ * Specify STUN server to be used, in "HOST[:PORT]" format. If port is
+ * not specified, default port 3478 will be used.
+ */
+ pj_str_t stun_host;
+
+ /**
+ * Number of STUN server entries in \a stun_srv array.
+ */
+ unsigned stun_srv_cnt;
+
+ /**
+ * Array of STUN servers to try. The library will try to resolve and
+ * contact each of the STUN server entry until it finds one that is
+ * usable. Each entry may be a domain name, host name, IP address, and
+ * it may contain an optional port number. For example:
+ * - "pjsip.org" (domain name)
+ * - "sip.pjsip.org" (host name)
+ * - "pjsip.org:33478" (domain name and a non-standard port number)
+ * - "10.0.0.1:3478" (IP address and port number)
+ *
+ * When nameserver is configured in the \a pjsua_config.nameserver field,
+ * if entry is not an IP address, it will be resolved with DNS SRV
+ * resolution first, and it will fallback to use DNS A resolution if this
+ * fails. Port number may be specified even if the entry is a domain name,
+ * in case the DNS SRV resolution should fallback to a non-standard port.
+ *
+ * When nameserver is not configured, entries will be resolved with
+ * #pj_gethostbyname() if it's not an IP address. Port number may be
+ * specified if the server is not listening in standard STUN port.
+ */
+ pj_str_t stun_srv[8];
+
+ /**
+ * This specifies if the library startup should ignore failure with the
+ * STUN servers. If this is set to PJ_FALSE, the library will refuse to
+ * start if it fails to resolve or contact any of the STUN servers.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t stun_ignore_failure;
+
+ /**
+ * Support for adding and parsing NAT type in the SDP to assist
+ * troubleshooting. The valid values are:
+ * - 0: no information will be added in SDP, and parsing is disabled.
+ * - 1: only the NAT type number is added.
+ * - 2: add both NAT type number and name.
+ *
+ * Default: 1
+ */
+ int nat_type_in_sdp;
+
+ /**
+ * Specify whether support for reliable provisional response (100rel and
+ * PRACK) should be required by default. Note that this setting can be
+ * further customized in account configuration (#pjsua_acc_config).
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t require_100rel;
+
+ /**
+ * Specify whether support for Session Timers should be required by
+ * default. Note that this setting can be further customized in account
+ * configuration (#pjsua_acc_config).
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t require_timer;
+
+ /**
+ * Handle unsolicited NOTIFY requests containing message waiting
+ * indication (MWI) info. Unsolicited MWI is incoming NOTIFY requests
+ * which are not requested by client with SUBSCRIBE request.
+ *
+ * If this is enabled, the library will respond 200/OK to the NOTIFY
+ * request and forward the request to \a on_mwi_info() callback.
+ *
+ * See also \a mwi_enabled field #on pjsua_acc_config.
+ *
+ * Default: PJ_TRUE
+ *
+ */
+ pj_bool_t enable_unsolicited_mwi;
+
+ /**
+ * Specify Session Timer settings, see #pjsip_timer_setting.
+ * Note that this setting can be further customized in account
+ * configuration (#pjsua_acc_config).
+ */
+ pjsip_timer_setting timer_setting;
+
+ /**
+ * Number of credentials in the credential array.
+ */
+ unsigned cred_count;
+
+ /**
+ * Array of credentials. These credentials will be used by all accounts,
+ * and can be used to authenticate against outbound proxies. If the
+ * credential is specific to the account, then application should set
+ * the credential in the pjsua_acc_config rather than the credential
+ * here.
+ */
+ pjsip_cred_info cred_info[PJSUA_ACC_MAX_PROXIES];
+
+ /**
+ * Application callback to receive various event notifications from
+ * the library.
+ */
+ pjsua_callback cb;
+
+ /**
+ * Optional user agent string (default empty). If it's empty, no
+ * User-Agent header will be sent with outgoing requests.
+ */
+ pj_str_t user_agent;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ /**
+ * Specify default value of secure media transport usage.
+ * Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and
+ * PJMEDIA_SRTP_MANDATORY.
+ *
+ * Note that this setting can be further customized in account
+ * configuration (#pjsua_acc_config).
+ *
+ * Default: #PJSUA_DEFAULT_USE_SRTP
+ */
+ pjmedia_srtp_use use_srtp;
+
+ /**
+ * Specify whether SRTP requires secure signaling to be used. This option
+ * is only used when \a use_srtp option above is non-zero.
+ *
+ * Valid values are:
+ * 0: SRTP does not require secure signaling
+ * 1: SRTP requires secure transport such as TLS
+ * 2: SRTP requires secure end-to-end transport (SIPS)
+ *
+ * Note that this setting can be further customized in account
+ * configuration (#pjsua_acc_config).
+ *
+ * Default: #PJSUA_DEFAULT_SRTP_SECURE_SIGNALING
+ */
+ int srtp_secure_signaling;
+#endif
+
+ /**
+ * Disconnect other call legs when more than one 2xx responses for
+ * outgoing INVITE are received due to forking. Currently the library
+ * is not able to handle simultaneous forked media, so disconnecting
+ * the other call legs is necessary.
+ *
+ * With this setting enabled, the library will handle only one of the
+ * connected call leg, and the other connected call legs will be
+ * disconnected.
+ *
+ * Default: PJ_TRUE (only disable this setting for testing purposes).
+ */
+ pj_bool_t hangup_forked_call;
+
+} pjsua_config;
+
+
+/**
+ * Use this function to initialize pjsua config.
+ *
+ * @param cfg pjsua config to be initialized.
+ */
+PJ_DECL(void) pjsua_config_default(pjsua_config *cfg);
+
+
+/** The implementation has been moved to sip_auth.h */
+#define pjsip_cred_dup pjsip_cred_info_dup
+
+
+/**
+ * Duplicate pjsua_config.
+ *
+ * @param pool The pool to get memory from.
+ * @param dst Destination config.
+ * @param src Source config.
+ */
+PJ_DECL(void) pjsua_config_dup(pj_pool_t *pool,
+ pjsua_config *dst,
+ const pjsua_config *src);
+
+
+/**
+ * This structure describes additional information to be sent with
+ * outgoing SIP message. It can (optionally) be specified for example
+ * with #pjsua_call_make_call(), #pjsua_call_answer(), #pjsua_call_hangup(),
+ * #pjsua_call_set_hold(), #pjsua_call_send_im(), and many more.
+ *
+ * Application MUST call #pjsua_msg_data_init() to initialize this
+ * structure before setting its values.
+ */
+struct pjsua_msg_data
+{
+ /**
+ * Additional message headers as linked list. Application can add
+ * headers to the list by creating the header, either from the heap/pool
+ * or from temporary local variable, and add the header using
+ * linked list operation. See pjsip_apps.c for some sample codes.
+ */
+ pjsip_hdr hdr_list;
+
+ /**
+ * MIME type of optional message body.
+ */
+ pj_str_t content_type;
+
+ /**
+ * Optional message body.
+ */
+ pj_str_t msg_body;
+
+};
+
+
+/**
+ * Initialize message data.
+ *
+ * @param msg_data Message data to be initialized.
+ */
+PJ_DECL(void) pjsua_msg_data_init(pjsua_msg_data *msg_data);
+
+
+/**
+ * Instantiate pjsua application. Application must call this function before
+ * calling any other functions, to make sure that the underlying libraries
+ * are properly initialized. Once this function has returned success,
+ * application must call pjsua_destroy() before quitting.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_create(void);
+
+
+/** Forward declaration */
+typedef struct pjsua_media_config pjsua_media_config;
+
+
+/**
+ * Initialize pjsua with the specified settings. All the settings are
+ * optional, and the default values will be used when the config is not
+ * specified.
+ *
+ * Note that #pjsua_create() MUST be called before calling this function.
+ *
+ * @param ua_cfg User agent configuration.
+ * @param log_cfg Optional logging configuration.
+ * @param media_cfg Optional media configuration.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_init(const pjsua_config *ua_cfg,
+ const pjsua_logging_config *log_cfg,
+ const pjsua_media_config *media_cfg);
+
+
+/**
+ * Application is recommended to call this function after all initialization
+ * is done, so that the library can do additional checking set up
+ * additional
+ *
+ * Application may call this function anytime after #pjsua_init().
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_start(void);
+
+
+/**
+ * Destroy pjsua. Application is recommended to perform graceful shutdown
+ * before calling this function (such as unregister the account from the SIP
+ * server, terminate presense subscription, and hangup active calls), however,
+ * this function will do all of these if it finds there are active sessions
+ * that need to be terminated. This function will approximately block for
+ * one second to wait for replies from remote.
+ *
+ * Application.may safely call this function more than once if it doesn't
+ * keep track of it's state.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_destroy(void);
+
+
+/**
+ * Poll pjsua for events, and if necessary block the caller thread for
+ * the specified maximum interval (in miliseconds).
+ *
+ * Application doesn't normally need to call this function if it has
+ * configured worker thread (\a thread_cnt field) in pjsua_config structure,
+ * because polling then will be done by these worker threads instead.
+ *
+ * @param msec_timeout Maximum time to wait, in miliseconds.
+ *
+ * @return The number of events that have been handled during the
+ * poll. Negative value indicates error, and application
+ * can retrieve the error as (status = -return_value).
+ */
+PJ_DECL(int) pjsua_handle_events(unsigned msec_timeout);
+
+
+/**
+ * Create memory pool to be used by the application. Once application
+ * finished using the pool, it must be released with pj_pool_release().
+ *
+ * @param name Optional pool name.
+ * @param init_size Initial size of the pool.
+ * @param increment Increment size.
+ *
+ * @return The pool, or NULL when there's no memory.
+ */
+PJ_DECL(pj_pool_t*) pjsua_pool_create(const char *name, pj_size_t init_size,
+ pj_size_t increment);
+
+
+/**
+ * Application can call this function at any time (after pjsua_create(), of
+ * course) to change logging settings.
+ *
+ * @param c Logging configuration.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_reconfigure_logging(const pjsua_logging_config *c);
+
+
+/**
+ * Internal function to get SIP endpoint instance of pjsua, which is
+ * needed for example to register module, create transports, etc.
+ * Only valid after #pjsua_init() is called.
+ *
+ * @return SIP endpoint instance.
+ */
+PJ_DECL(pjsip_endpoint*) pjsua_get_pjsip_endpt(void);
+
+/**
+ * Internal function to get media endpoint instance.
+ * Only valid after #pjsua_init() is called.
+ *
+ * @return Media endpoint instance.
+ */
+PJ_DECL(pjmedia_endpt*) pjsua_get_pjmedia_endpt(void);
+
+/**
+ * Internal function to get PJSUA pool factory.
+ * Only valid after #pjsua_create() is called.
+ *
+ * @return Pool factory currently used by PJSUA.
+ */
+PJ_DECL(pj_pool_factory*) pjsua_get_pool_factory(void);
+
+
+
+/*****************************************************************************
+ * Utilities.
+ *
+ */
+
+/**
+ * This structure is used to represent the result of the STUN server
+ * resolution and testing, the #pjsua_resolve_stun_servers() function.
+ * This structure will be passed in #pj_stun_resolve_cb callback.
+ */
+typedef struct pj_stun_resolve_result
+{
+ /**
+ * Arbitrary data that was passed to #pjsua_resolve_stun_servers()
+ * function.
+ */
+ void *token;
+
+ /**
+ * This will contain PJ_SUCCESS if at least one usable STUN server
+ * is found, otherwise it will contain the last error code during
+ * the operation.
+ */
+ pj_status_t status;
+
+ /**
+ * The server name that yields successful result. This will only
+ * contain value if status is successful.
+ */
+ pj_str_t name;
+
+ /**
+ * The server IP address. This will only contain value if status
+ * is successful.
+ */
+ pj_sockaddr addr;
+
+} pj_stun_resolve_result;
+
+
+/**
+ * Typedef of callback to be registered to #pjsua_resolve_stun_servers().
+ */
+typedef void (*pj_stun_resolve_cb)(const pj_stun_resolve_result *result);
+
+/**
+ * This is a utility function to detect NAT type in front of this
+ * endpoint. Once invoked successfully, this function will complete
+ * asynchronously and report the result in \a on_nat_detect() callback
+ * of pjsua_callback.
+ *
+ * After NAT has been detected and the callback is called, application can
+ * get the detected NAT type by calling #pjsua_get_nat_type(). Application
+ * can also perform NAT detection by calling #pjsua_detect_nat_type()
+ * again at later time.
+ *
+ * Note that STUN must be enabled to run this function successfully.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_detect_nat_type(void);
+
+
+/**
+ * Get the NAT type as detected by #pjsua_detect_nat_type() function.
+ * This function will only return useful NAT type after #pjsua_detect_nat_type()
+ * has completed successfully and \a on_nat_detect() callback has been called.
+ *
+ * @param type NAT type.
+ *
+ * @return When detection is in progress, this function will
+ * return PJ_EPENDING and \a type will be set to
+ * PJ_STUN_NAT_TYPE_UNKNOWN. After NAT type has been
+ * detected successfully, this function will return
+ * PJ_SUCCESS and \a type will be set to the correct
+ * value. Other return values indicate error and
+ * \a type will be set to PJ_STUN_NAT_TYPE_ERR_UNKNOWN.
+ *
+ * @see pjsua_call_get_rem_nat_type()
+ */
+PJ_DECL(pj_status_t) pjsua_get_nat_type(pj_stun_nat_type *type);
+
+
+/**
+ * Auxiliary function to resolve and contact each of the STUN server
+ * entries (sequentially) to find which is usable. The #pjsua_init() must
+ * have been called before calling this function.
+ *
+ * @param count Number of STUN server entries to try.
+ * @param srv Array of STUN server entries to try. Please see
+ * the \a stun_srv field in the #pjsua_config
+ * documentation about the format of this entry.
+ * @param wait Specify non-zero to make the function block until
+ * it gets the result. In this case, the function
+ * will block while the resolution is being done,
+ * and the callback will be called before this function
+ * returns.
+ * @param token Arbitrary token to be passed back to application
+ * in the callback.
+ * @param cb Callback to be called to notify the result of
+ * the function.
+ *
+ * @return If \a wait parameter is non-zero, this will return
+ * PJ_SUCCESS if one usable STUN server is found.
+ * Otherwise it will always return PJ_SUCCESS, and
+ * application will be notified about the result in
+ * the callback.
+ */
+PJ_DECL(pj_status_t) pjsua_resolve_stun_servers(unsigned count,
+ pj_str_t srv[],
+ pj_bool_t wait,
+ void *token,
+ pj_stun_resolve_cb cb);
+
+/**
+ * Cancel pending STUN resolution which match the specified token.
+ *
+ * @param token The token to match. This token was given to
+ * #pjsua_resolve_stun_servers()
+ * @param notify_cb Boolean to control whether the callback should
+ * be called for cancelled resolutions. When the
+ * callback is called, the status in the result
+ * will be set as PJ_ECANCELLED.
+ *
+ * @return PJ_SUCCESS if there is at least one pending STUN
+ * resolution cancelled, or PJ_ENOTFOUND if there is
+ * no matching one, or other error.
+ */
+PJ_DECL(pj_status_t) pjsua_cancel_stun_resolution(void *token,
+ pj_bool_t notify_cb);
+
+
+/**
+ * This is a utility function to verify that valid SIP url is given. If the
+ * URL is valid, PJ_SUCCESS will be returned.
+ *
+ * @param url The URL, as NULL terminated string.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_verify_sip_url(const char *url);
+
+
+/**
+ * Schedule a timer entry. Note that the timer callback may be executed
+ * by different thread, depending on whether worker thread is enabled or
+ * not.
+ *
+ * @param entry Timer heap entry.
+ * @param delay The interval to expire.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ *
+ * @see pjsip_endpt_schedule_timer()
+ */
+PJ_DECL(pj_status_t) pjsua_schedule_timer(pj_timer_entry *entry,
+ const pj_time_val *delay);
+
+
+/**
+ * Cancel the previously scheduled timer.
+ *
+ * @param entry Timer heap entry.
+ *
+ * @see pjsip_endpt_cancel_timer()
+ */
+PJ_DECL(void) pjsua_cancel_timer(pj_timer_entry *entry);
+
+
+/**
+ * This is a utility function to display error message for the specified
+ * error code. The error message will be sent to the log.
+ *
+ * @param sender The log sender field.
+ * @param title Message title for the error.
+ * @param status Status code.
+ */
+PJ_DECL(void) pjsua_perror(const char *sender, const char *title,
+ pj_status_t status);
+
+
+/**
+ * This is a utility function to dump the stack states to log, using
+ * verbosity level 3.
+ *
+ * @param detail Will print detailed output (such as list of
+ * SIP transactions) when non-zero.
+ */
+PJ_DECL(void) pjsua_dump(pj_bool_t detail);
+
+/**
+ * @}
+ */
+
+
+
+/*****************************************************************************
+ * TRANSPORT API
+ */
+
+/**
+ * @defgroup PJSUA_LIB_TRANSPORT PJSUA-API Signaling Transport
+ * @ingroup PJSUA_LIB
+ * @brief API for managing SIP transports
+ * @{
+ *
+ * PJSUA-API supports creating multiple transport instances, for example UDP,
+ * TCP, and TLS transport. SIP transport must be created before adding an
+ * account.
+ */
+
+
+/** SIP transport identification.
+ */
+typedef int pjsua_transport_id;
+
+
+/**
+ * Transport configuration for creating transports for both SIP
+ * and media. Before setting some values to this structure, application
+ * MUST call #pjsua_transport_config_default() to initialize its
+ * values with default settings.
+ */
+typedef struct pjsua_transport_config
+{
+ /**
+ * UDP port number to bind locally. This setting MUST be specified
+ * even when default port is desired. If the value is zero, the
+ * transport will be bound to any available port, and application
+ * can query the port by querying the transport info.
+ */
+ unsigned port;
+
+ /**
+ * Optional address to advertise as the address of this transport.
+ * Application can specify any address or hostname for this field,
+ * for example it can point to one of the interface address in the
+ * system, or it can point to the public address of a NAT router
+ * where port mappings have been configured for the application.
+ *
+ * Note: this option can be used for both UDP and TCP as well!
+ */
+ pj_str_t public_addr;
+
+ /**
+ * Optional address where the socket should be bound to. This option
+ * SHOULD only be used to selectively bind the socket to particular
+ * interface (instead of 0.0.0.0), and SHOULD NOT be used to set the
+ * published address of a transport (the public_addr field should be
+ * used for that purpose).
+ *
+ * Note that unlike public_addr field, the address (or hostname) here
+ * MUST correspond to the actual interface address in the host, since
+ * this address will be specified as bind() argument.
+ */
+ pj_str_t bound_addr;
+
+ /**
+ * This specifies TLS settings for TLS transport. It is only be used
+ * when this transport config is being used to create a SIP TLS
+ * transport.
+ */
+ pjsip_tls_setting tls_setting;
+
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default is QoS not set.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * Default is QoS not set.
+ */
+ pj_qos_params qos_params;
+
+} pjsua_transport_config;
+
+
+/**
+ * Call this function to initialize UDP config with default values.
+ *
+ * @param cfg The UDP config to be initialized.
+ */
+PJ_DECL(void) pjsua_transport_config_default(pjsua_transport_config *cfg);
+
+
+/**
+ * Duplicate transport config.
+ *
+ * @param pool The pool.
+ * @param dst The destination config.
+ * @param src The source config.
+ */
+PJ_DECL(void) pjsua_transport_config_dup(pj_pool_t *pool,
+ pjsua_transport_config *dst,
+ const pjsua_transport_config *src);
+
+
+/**
+ * This structure describes transport information returned by
+ * #pjsua_transport_get_info() function.
+ */
+typedef struct pjsua_transport_info
+{
+ /**
+ * PJSUA transport identification.
+ */
+ pjsua_transport_id id;
+
+ /**
+ * Transport type.
+ */
+ pjsip_transport_type_e type;
+
+ /**
+ * Transport type name.
+ */
+ pj_str_t type_name;
+
+ /**
+ * Transport string info/description.
+ */
+ pj_str_t info;
+
+ /**
+ * Transport flag (see ##pjsip_transport_flags_e).
+ */
+ unsigned flag;
+
+ /**
+ * Local address length.
+ */
+ unsigned addr_len;
+
+ /**
+ * Local/bound address.
+ */
+ pj_sockaddr local_addr;
+
+ /**
+ * Published address (or transport address name).
+ */
+ pjsip_host_port local_name;
+
+ /**
+ * Current number of objects currently referencing this transport.
+ */
+ unsigned usage_count;
+
+
+} pjsua_transport_info;
+
+
+/**
+ * Create and start a new SIP transport according to the specified
+ * settings.
+ *
+ * @param type Transport type.
+ * @param cfg Transport configuration.
+ * @param p_id Optional pointer to receive transport ID.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_transport_create(pjsip_transport_type_e type,
+ const pjsua_transport_config *cfg,
+ pjsua_transport_id *p_id);
+
+/**
+ * Register transport that has been created by application. This function
+ * is useful if application wants to implement custom SIP transport and use
+ * it with pjsua.
+ *
+ * @param tp Transport instance.
+ * @param p_id Optional pointer to receive transport ID.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_transport_register(pjsip_transport *tp,
+ pjsua_transport_id *p_id);
+
+
+/**
+ * Enumerate all transports currently created in the system. This function
+ * will return all transport IDs, and application may then call
+ * #pjsua_transport_get_info() function to retrieve detailed information
+ * about the transport.
+ *
+ * @param id Array to receive transport ids.
+ * @param count In input, specifies the maximum number of elements.
+ * On return, it contains the actual number of elements.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_enum_transports( pjsua_transport_id id[],
+ unsigned *count );
+
+
+/**
+ * Get information about transports.
+ *
+ * @param id Transport ID.
+ * @param info Pointer to receive transport info.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_transport_get_info(pjsua_transport_id id,
+ pjsua_transport_info *info);
+
+
+/**
+ * Disable a transport or re-enable it. By default transport is always
+ * enabled after it is created. Disabling a transport does not necessarily
+ * close the socket, it will only discard incoming messages and prevent
+ * the transport from being used to send outgoing messages.
+ *
+ * @param id Transport ID.
+ * @param enabled Non-zero to enable, zero to disable.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_transport_set_enable(pjsua_transport_id id,
+ pj_bool_t enabled);
+
+
+/**
+ * Close the transport. If transport is forcefully closed, it will be
+ * immediately closed, and any pending transactions that are using the
+ * transport may not terminate properly (it may even crash). Otherwise,
+ * the system will wait until all transactions are closed while preventing
+ * new users from using the transport, and will close the transport when
+ * it is safe to do so.
+ *
+ * @param id Transport ID.
+ * @param force Non-zero to immediately close the transport. This
+ * is not recommended!
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_transport_close( pjsua_transport_id id,
+ pj_bool_t force );
+
+/**
+ * @}
+ */
+
+
+
+
+/*****************************************************************************
+ * ACCOUNT API
+ */
+
+
+/**
+ * @defgroup PJSUA_LIB_ACC PJSUA-API Accounts Management
+ * @ingroup PJSUA_LIB
+ * @brief PJSUA Accounts management
+ * @{
+ *
+ * PJSUA accounts provide identity (or identities) of the user who is currently
+ * using the application. In SIP terms, the identity is used as the <b>From</b>
+ * header in outgoing requests.
+ *
+ * PJSUA-API supports creating and managing multiple accounts. The maximum
+ * number of accounts is limited by a compile time constant
+ * <tt>PJSUA_MAX_ACC</tt>.
+ *
+ * Account may or may not have client registration associated with it.
+ * An account is also associated with <b>route set</b> and some <b>authentication
+ * credentials</b>, which are used when sending SIP request messages using the
+ * account. An account also has presence's <b>online status</b>, which
+ * will be reported to remote peer when they subscribe to the account's
+ * presence, or which is published to a presence server if presence
+ * publication is enabled for the account.
+ *
+ * At least one account MUST be created in the application. If no user
+ * association is required, application can create a userless account by
+ * calling #pjsua_acc_add_local(). A userless account identifies local endpoint
+ * instead of a particular user, and it correspond with a particular
+ * transport instance.
+ *
+ * Also one account must be set as the <b>default account</b>, which is used as
+ * the account to use when PJSUA fails to match a request with any other
+ * accounts.
+ *
+ * When sending outgoing SIP requests (such as making calls or sending
+ * instant messages), normally PJSUA requires the application to specify
+ * which account to use for the request. If no account is specified,
+ * PJSUA may be able to select the account by matching the destination
+ * domain name, and fall back to default account when no match is found.
+ */
+
+/**
+ * Maximum accounts.
+ */
+#ifndef PJSUA_MAX_ACC
+# define PJSUA_MAX_ACC 8
+#endif
+
+
+/**
+ * Default registration interval.
+ */
+#ifndef PJSUA_REG_INTERVAL
+# define PJSUA_REG_INTERVAL 300
+#endif
+
+
+/**
+ * Default maximum time to wait for account unregistration transactions to
+ * complete during library shutdown sequence.
+ *
+ * Default: 4000 (4 seconds)
+ */
+#ifndef PJSUA_UNREG_TIMEOUT
+# define PJSUA_UNREG_TIMEOUT 4000
+#endif
+
+
+/**
+ * Default PUBLISH expiration
+ */
+#ifndef PJSUA_PUBLISH_EXPIRATION
+# define PJSUA_PUBLISH_EXPIRATION PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED
+#endif
+
+
+/**
+ * Default account priority.
+ */
+#ifndef PJSUA_DEFAULT_ACC_PRIORITY
+# define PJSUA_DEFAULT_ACC_PRIORITY 0
+#endif
+
+
+/**
+ * This macro specifies the URI scheme to use in Contact header
+ * when secure transport such as TLS is used. Application can specify
+ * either "sip" or "sips".
+ */
+#ifndef PJSUA_SECURE_SCHEME
+# define PJSUA_SECURE_SCHEME "sip"
+#endif
+
+
+/**
+ * Maximum time to wait for unpublication transaction(s) to complete
+ * during shutdown process, before sending unregistration. The library
+ * tries to wait for the unpublication (un-PUBLISH) to complete before
+ * sending REGISTER request to unregister the account, during library
+ * shutdown process. If the value is set too short, it is possible that
+ * the unregistration is sent before unpublication completes, causing
+ * unpublication request to fail.
+ *
+ * Default: 2000 (2 seconds)
+ */
+#ifndef PJSUA_UNPUBLISH_MAX_WAIT_TIME_MSEC
+# define PJSUA_UNPUBLISH_MAX_WAIT_TIME_MSEC 2000
+#endif
+
+
+/**
+ * This structure describes account configuration to be specified when
+ * adding a new account with #pjsua_acc_add(). Application MUST initialize
+ * this structure first by calling #pjsua_acc_config_default().
+ */
+typedef struct pjsua_acc_config
+{
+ /**
+ * Arbitrary user data to be associated with the newly created account.
+ * Application may set this later with #pjsua_acc_set_user_data() and
+ * retrieve it with #pjsua_acc_get_user_data().
+ */
+ void *user_data;
+
+ /**
+ * Account priority, which is used to control the order of matching
+ * incoming/outgoing requests. The higher the number means the higher
+ * the priority is, and the account will be matched first.
+ */
+ int priority;
+
+ /**
+ * The full SIP URL for the account. The value can take name address or
+ * URL format, and will look something like "sip:account@serviceprovider".
+ *
+ * This field is mandatory.
+ */
+ pj_str_t id;
+
+ /**
+ * This is the URL to be put in the request URI for the registration,
+ * and will look something like "sip:serviceprovider".
+ *
+ * This field should be specified if registration is desired. If the
+ * value is empty, no account registration will be performed.
+ */
+ pj_str_t reg_uri;
+
+ /**
+ * Subscribe to message waiting indication events (RFC 3842).
+ *
+ * See also \a enable_unsolicited_mwi field on #pjsua_config.
+ *
+ * Default: no
+ */
+ pj_bool_t mwi_enabled;
+
+ /**
+ * If this flag is set, the presence information of this account will
+ * be PUBLISH-ed to the server where the account belongs.
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t publish_enabled;
+
+ /**
+ * Event publication options.
+ */
+ pjsip_publishc_opt publish_opt;
+
+ /**
+ * Maximum time to wait for unpublication transaction(s) to complete
+ * during shutdown process, before sending unregistration. The library
+ * tries to wait for the unpublication (un-PUBLISH) to complete before
+ * sending REGISTER request to unregister the account, during library
+ * shutdown process. If the value is set too short, it is possible that
+ * the unregistration is sent before unpublication completes, causing
+ * unpublication request to fail.
+ *
+ * Default: PJSUA_UNPUBLISH_MAX_WAIT_TIME_MSEC
+ */
+ unsigned unpublish_max_wait_time_msec;
+
+ /**
+ * Authentication preference.
+ */
+ pjsip_auth_clt_pref auth_pref;
+
+ /**
+ * Optional PIDF tuple ID for outgoing PUBLISH and NOTIFY. If this value
+ * is not specified, a random string will be used.
+ */
+ pj_str_t pidf_tuple_id;
+
+ /**
+ * Optional URI to be put as Contact for this account. It is recommended
+ * that this field is left empty, so that the value will be calculated
+ * automatically based on the transport address.
+ */
+ pj_str_t force_contact;
+
+ /**
+ * Additional parameters that will be appended in the Contact header
+ * for this account. This will affect the Contact header in all SIP
+ * messages sent on behalf of this account, including but not limited to
+ * REGISTER, INVITE, and SUBCRIBE requests or responses.
+ *
+ * The parameters should be preceeded by semicolon, and all strings must
+ * be properly escaped. Example:
+ * ";my-param=X;another-param=Hi%20there"
+ */
+ pj_str_t contact_params;
+
+ /**
+ * Additional URI parameters that will be appended in the Contact URI
+ * for this account. This will affect the Contact URI in all SIP
+ * messages sent on behalf of this account, including but not limited to
+ * REGISTER, INVITE, and SUBCRIBE requests or responses.
+ *
+ * The parameters should be preceeded by semicolon, and all strings must
+ * be properly escaped. Example:
+ * ";my-param=X;another-param=Hi%20there"
+ */
+ pj_str_t contact_uri_params;
+
+ /**
+ * Specify whether support for reliable provisional response (100rel and
+ * PRACK) should be required for all sessions of this account.
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t require_100rel;
+
+ /**
+ * Specify whether support for Session Timers should be required for all
+ * sessions of this account.
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t require_timer;
+
+ /**
+ * Specify Session Timer settings, see #pjsip_timer_setting.
+ */
+ pjsip_timer_setting timer_setting;
+
+ /**
+ * Number of proxies in the proxy array below.
+ */
+ unsigned proxy_cnt;
+
+ /**
+ * Optional URI of the proxies to be visited for all outgoing requests
+ * that are using this account (REGISTER, INVITE, etc). Application need
+ * to specify these proxies if the service provider requires that requests
+ * destined towards its network should go through certain proxies first
+ * (for example, border controllers).
+ *
+ * These proxies will be put in the route set for this account, with
+ * maintaining the orders (the first proxy in the array will be visited
+ * first). If global outbound proxies are configured in pjsua_config,
+ * then these account proxies will be placed after the global outbound
+ * proxies in the routeset.
+ */
+ pj_str_t proxy[PJSUA_ACC_MAX_PROXIES];
+
+ /**
+ * Optional interval for registration, in seconds. If the value is zero,
+ * default interval will be used (PJSUA_REG_INTERVAL, 300 seconds).
+ */
+ unsigned reg_timeout;
+
+ /**
+ * Specify the maximum time to wait for unregistration requests to
+ * complete during library shutdown sequence.
+ *
+ * Default: PJSUA_UNREG_TIMEOUT
+ */
+ unsigned unreg_timeout;
+
+ /**
+ * Number of credentials in the credential array.
+ */
+ unsigned cred_count;
+
+ /**
+ * Array of credentials. If registration is desired, normally there should
+ * be at least one credential specified, to successfully authenticate
+ * against the service provider. More credentials can be specified, for
+ * example when the requests are expected to be challenged by the
+ * proxies in the route set.
+ */
+ pjsip_cred_info cred_info[PJSUA_ACC_MAX_PROXIES];
+
+ /**
+ * Optionally bind this account to specific transport. This normally is
+ * not a good idea, as account should be able to send requests using
+ * any available transports according to the destination. But some
+ * application may want to have explicit control over the transport to
+ * use, so in that case it can set this field.
+ *
+ * Default: -1 (PJSUA_INVALID_ID)
+ *
+ * @see pjsua_acc_set_transport()
+ */
+ pjsua_transport_id transport_id;
+
+ /**
+ * This option is used to update the UDP transport address and the Contact
+ * header of REGISTER request. When this option is enabled, the library
+ * will keep track of the public IP address from the response of REGISTER
+ * request. Once it detects that the address has changed, it will
+ * unregister current Contact, update the Contact with transport address
+ * learned from Via header, and register a new Contact to the registrar.
+ * This will also update the public name of UDP transport if STUN is
+ * configured.
+ *
+ * Default: 1 (yes)
+ */
+ pj_bool_t allow_contact_rewrite;
+
+ /**
+ * Set the interval for periodic keep-alive transmission for this account.
+ * If this value is zero, keep-alive will be disabled for this account.
+ * The keep-alive transmission will be sent to the registrar's address,
+ * after successful registration.
+ *
+ * Default: 15 (seconds)
+ */
+ unsigned ka_interval;
+
+ /**
+ * Specify the data to be transmitted as keep-alive packets.
+ *
+ * Default: CR-LF
+ */
+ pj_str_t ka_data;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ /**
+ * Specify whether secure media transport should be used for this account.
+ * Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and
+ * PJMEDIA_SRTP_MANDATORY.
+ *
+ * Default: #PJSUA_DEFAULT_USE_SRTP
+ */
+ pjmedia_srtp_use use_srtp;
+
+ /**
+ * Specify whether SRTP requires secure signaling to be used. This option
+ * is only used when \a use_srtp option above is non-zero.
+ *
+ * Valid values are:
+ * 0: SRTP does not require secure signaling
+ * 1: SRTP requires secure transport such as TLS
+ * 2: SRTP requires secure end-to-end transport (SIPS)
+ *
+ * Default: #PJSUA_DEFAULT_SRTP_SECURE_SIGNALING
+ */
+ int srtp_secure_signaling;
+#endif
+
+} pjsua_acc_config;
+
+
+/**
+ * Call this function to initialize account config with default values.
+ *
+ * @param cfg The account config to be initialized.
+ */
+PJ_DECL(void) pjsua_acc_config_default(pjsua_acc_config *cfg);
+
+
+/**
+ * Duplicate account config.
+ *
+ * @param pool Pool to be used for duplicating the config.
+ * @param dst Destination configuration.
+ * @param src Source configuration.
+ */
+PJ_DECL(void) pjsua_acc_config_dup(pj_pool_t *pool,
+ pjsua_acc_config *dst,
+ const pjsua_acc_config *src);
+
+
+/**
+ * Account info. Application can query account info by calling
+ * #pjsua_acc_get_info().
+ */
+typedef struct pjsua_acc_info
+{
+ /**
+ * The account ID.
+ */
+ pjsua_acc_id id;
+
+ /**
+ * Flag to indicate whether this is the default account.
+ */
+ pj_bool_t is_default;
+
+ /**
+ * Account URI
+ */
+ pj_str_t acc_uri;
+
+ /**
+ * Flag to tell whether this account has registration setting
+ * (reg_uri is not empty).
+ */
+ pj_bool_t has_registration;
+
+ /**
+ * An up to date expiration interval for account registration session.
+ */
+ int expires;
+
+ /**
+ * Last registration status code. If status code is zero, the account
+ * is currently not registered. Any other value indicates the SIP
+ * status code of the registration.
+ */
+ pjsip_status_code status;
+
+ /**
+ * String describing the registration status.
+ */
+ pj_str_t status_text;
+
+ /**
+ * Presence online status for this account.
+ */
+ pj_bool_t online_status;
+
+ /**
+ * Presence online status text.
+ */
+ pj_str_t online_status_text;
+
+ /**
+ * Extended RPID online status information.
+ */
+ pjrpid_element rpid;
+
+ /**
+ * Buffer that is used internally to store the status text.
+ */
+ char buf_[PJ_ERR_MSG_SIZE];
+
+} pjsua_acc_info;
+
+
+
+/**
+ * Get number of current accounts.
+ *
+ * @return Current number of accounts.
+ */
+PJ_DECL(unsigned) pjsua_acc_get_count(void);
+
+
+/**
+ * Check if the specified account ID is valid.
+ *
+ * @param acc_id Account ID to check.
+ *
+ * @return Non-zero if account ID is valid.
+ */
+PJ_DECL(pj_bool_t) pjsua_acc_is_valid(pjsua_acc_id acc_id);
+
+
+/**
+ * Set default account to be used when incoming and outgoing
+ * requests doesn't match any accounts.
+ *
+ * @param acc_id The account ID to be used as default.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_set_default(pjsua_acc_id acc_id);
+
+
+/**
+ * Get default account to be used when receiving incoming requests (calls),
+ * when the destination of the incoming call doesn't match any other
+ * accounts.
+ *
+ * @return The default account ID, or PJSUA_INVALID_ID if no
+ * default account is configured.
+ */
+PJ_DECL(pjsua_acc_id) pjsua_acc_get_default(void);
+
+
+/**
+ * Add a new account to pjsua. PJSUA must have been initialized (with
+ * #pjsua_init()) before calling this function. If registration is configured
+ * for this account, this function would also start the SIP registration
+ * session with the SIP registrar server. This SIP registration session
+ * will be maintained internally by the library, and application doesn't
+ * need to do anything to maintain the registration session.
+ *
+ *
+ * @param acc_cfg Account configuration.
+ * @param is_default If non-zero, this account will be set as the default
+ * account. The default account will be used when sending
+ * outgoing requests (e.g. making call) when no account is
+ * specified, and when receiving incoming requests when the
+ * request does not match any accounts. It is recommended
+ * that default account is set to local/LAN account.
+ * @param p_acc_id Pointer to receive account ID of the new account.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_add(const pjsua_acc_config *acc_cfg,
+ pj_bool_t is_default,
+ pjsua_acc_id *p_acc_id);
+
+
+/**
+ * Add a local account. A local account is used to identify local endpoint
+ * instead of a specific user, and for this reason, a transport ID is needed
+ * to obtain the local address information.
+ *
+ * @param tid Transport ID to generate account address.
+ * @param is_default If non-zero, this account will be set as the default
+ * account. The default account will be used when sending
+ * outgoing requests (e.g. making call) when no account is
+ * specified, and when receiving incoming requests when the
+ * request does not match any accounts. It is recommended
+ * that default account is set to local/LAN account.
+ * @param p_acc_id Pointer to receive account ID of the new account.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_add_local(pjsua_transport_id tid,
+ pj_bool_t is_default,
+ pjsua_acc_id *p_acc_id);
+
+/**
+ * Set arbitrary data to be associated with the account.
+ *
+ * @param acc_id The account ID.
+ * @param user_data User/application data.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_set_user_data(pjsua_acc_id acc_id,
+ void *user_data);
+
+
+/**
+ * Retrieve arbitrary data associated with the account.
+ *
+ * @param acc_id The account ID.
+ *
+ * @return The user data. In the case where the account ID is
+ * not valid, NULL is returned.
+ */
+PJ_DECL(void*) pjsua_acc_get_user_data(pjsua_acc_id acc_id);
+
+
+/**
+ * Delete an account. This will unregister the account from the SIP server,
+ * if necessary, and terminate server side presence subscriptions associated
+ * with this account.
+ *
+ * @param acc_id Id of the account to be deleted.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_id);
+
+
+/**
+ * Modify account information.
+ *
+ * @param acc_id Id of the account to be modified.
+ * @param acc_cfg New account configuration.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_modify(pjsua_acc_id acc_id,
+ const pjsua_acc_config *acc_cfg);
+
+
+/**
+ * Modify account's presence status to be advertised to remote/presence
+ * subscribers. This would trigger the sending of outgoing NOTIFY request
+ * if there are server side presence subscription for this account, and/or
+ * outgoing PUBLISH if presence publication is enabled for this account.
+ *
+ * @see pjsua_acc_set_online_status2()
+ *
+ * @param acc_id The account ID.
+ * @param is_online True of false.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_set_online_status(pjsua_acc_id acc_id,
+ pj_bool_t is_online);
+
+/**
+ * Modify account's presence status to be advertised to remote/presence
+ * subscribers. This would trigger the sending of outgoing NOTIFY request
+ * if there are server side presence subscription for this account, and/or
+ * outgoing PUBLISH if presence publication is enabled for this account.
+ *
+ * @see pjsua_acc_set_online_status()
+ *
+ * @param acc_id The account ID.
+ * @param is_online True of false.
+ * @param pr Extended information in subset of RPID format
+ * which allows setting custom presence text.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_set_online_status2(pjsua_acc_id acc_id,
+ pj_bool_t is_online,
+ const pjrpid_element *pr);
+
+/**
+ * Update registration or perform unregistration. If registration is
+ * configured for this account, then initial SIP REGISTER will be sent
+ * when the account is added with #pjsua_acc_add(). Application normally
+ * only need to call this function if it wants to manually update the
+ * registration or to unregister from the server.
+ *
+ * @param acc_id The account ID.
+ * @param renew If renew argument is zero, this will start
+ * unregistration process.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_set_registration(pjsua_acc_id acc_id,
+ pj_bool_t renew);
+
+/**
+ * Get information about the specified account.
+ *
+ * @param acc_id Account identification.
+ * @param info Pointer to receive account information.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_get_info(pjsua_acc_id acc_id,
+ pjsua_acc_info *info);
+
+
+/**
+ * Enumerate all account currently active in the library. This will fill
+ * the array with the account Ids, and application can then query the
+ * account information for each id with #pjsua_acc_get_info().
+ *
+ * @see pjsua_acc_enum_info().
+ *
+ * @param ids Array of account IDs to be initialized.
+ * @param count In input, specifies the maximum number of elements.
+ * On return, it contains the actual number of elements.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_enum_accs(pjsua_acc_id ids[],
+ unsigned *count );
+
+
+/**
+ * Enumerate account informations.
+ *
+ * @param info Array of account infos to be initialized.
+ * @param count In input, specifies the maximum number of elements.
+ * On return, it contains the actual number of elements.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_enum_info( pjsua_acc_info info[],
+ unsigned *count );
+
+
+/**
+ * This is an internal function to find the most appropriate account to
+ * used to reach to the specified URL.
+ *
+ * @param url The remote URL to reach.
+ *
+ * @return Account id.
+ */
+PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *url);
+
+
+/**
+ * This is an internal function to find the most appropriate account to be
+ * used to handle incoming calls.
+ *
+ * @param rdata The incoming request message.
+ *
+ * @return Account id.
+ */
+PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata);
+
+
+/**
+ * Create arbitrary requests using the account. Application should only use
+ * this function to create auxiliary requests outside dialog, such as
+ * OPTIONS, and use the call or presence API to create dialog related
+ * requests.
+ *
+ * @param acc_id The account ID.
+ * @param method The SIP method of the request.
+ * @param target Target URI.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS or the error code.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_create_request(pjsua_acc_id acc_id,
+ const pjsip_method *method,
+ const pj_str_t *target,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Create a suitable Contact header value, based on the specified target URI
+ * for the specified account.
+ *
+ * @param pool Pool to allocate memory for the string.
+ * @param contact The string where the Contact will be stored.
+ * @param acc_id Account ID.
+ * @param uri Destination URI of the request.
+ *
+ * @return PJ_SUCCESS on success, other on error.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool,
+ pj_str_t *contact,
+ pjsua_acc_id acc_id,
+ const pj_str_t *uri);
+
+
+
+/**
+ * Create a suitable Contact header value, based on the information in the
+ * incoming request.
+ *
+ * @param pool Pool to allocate memory for the string.
+ * @param contact The string where the Contact will be stored.
+ * @param acc_id Account ID.
+ * @param rdata Incoming request.
+ *
+ * @return PJ_SUCCESS on success, other on error.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool,
+ pj_str_t *contact,
+ pjsua_acc_id acc_id,
+ pjsip_rx_data *rdata );
+
+
+/**
+ * Lock/bind this account to a specific transport/listener. Normally
+ * application shouldn't need to do this, as transports will be selected
+ * automatically by the stack according to the destination.
+ *
+ * When account is locked/bound to a specific transport, all outgoing
+ * requests from this account will use the specified transport (this
+ * includes SIP registration, dialog (call and event subscription), and
+ * out-of-dialog requests such as MESSAGE).
+ *
+ * Note that transport_id may be specified in pjsua_acc_config too.
+ *
+ * @param acc_id The account ID.
+ * @param tp_id The transport ID.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_set_transport(pjsua_acc_id acc_id,
+ pjsua_transport_id tp_id);
+
+
+/**
+ * @}
+ */
+
+
+/*****************************************************************************
+ * CALLS API
+ */
+
+
+/**
+ * @defgroup PJSUA_LIB_CALL PJSUA-API Calls Management
+ * @ingroup PJSUA_LIB
+ * @brief Call manipulation.
+ * @{
+ */
+
+/**
+ * Maximum simultaneous calls.
+ */
+#ifndef PJSUA_MAX_CALLS
+# define PJSUA_MAX_CALLS 32
+#endif
+
+
+
+/**
+ * This enumeration specifies the media status of a call, and it's part
+ * of pjsua_call_info structure.
+ */
+typedef enum pjsua_call_media_status
+{
+ /** Call currently has no media */
+ PJSUA_CALL_MEDIA_NONE,
+
+ /** The media is active */
+ PJSUA_CALL_MEDIA_ACTIVE,
+
+ /** The media is currently put on hold by local endpoint */
+ PJSUA_CALL_MEDIA_LOCAL_HOLD,
+
+ /** The media is currently put on hold by remote endpoint */
+ PJSUA_CALL_MEDIA_REMOTE_HOLD,
+
+ /** The media has reported error (e.g. ICE negotiation) */
+ PJSUA_CALL_MEDIA_ERROR
+
+} pjsua_call_media_status;
+
+
+/**
+ * This structure describes the information and current status of a call.
+ */
+typedef struct pjsua_call_info
+{
+ /** Call identification. */
+ pjsua_call_id id;
+
+ /** Initial call role (UAC == caller) */
+ pjsip_role_e role;
+
+ /** The account ID where this call belongs. */
+ pjsua_acc_id acc_id;
+
+ /** Local URI */
+ pj_str_t local_info;
+
+ /** Local Contact */
+ pj_str_t local_contact;
+
+ /** Remote URI */
+ pj_str_t remote_info;
+
+ /** Remote contact */
+ pj_str_t remote_contact;
+
+ /** Dialog Call-ID string. */
+ pj_str_t call_id;
+
+ /** Call state */
+ pjsip_inv_state state;
+
+ /** Text describing the state */
+ pj_str_t state_text;
+
+ /** Last status code heard, which can be used as cause code */
+ pjsip_status_code last_status;
+
+ /** The reason phrase describing the status. */
+ pj_str_t last_status_text;
+
+ /** Call media status. */
+ pjsua_call_media_status media_status;
+
+ /** Media direction */
+ pjmedia_dir media_dir;
+
+ /** The conference port number for the call */
+ pjsua_conf_port_id conf_slot;
+
+ /** Up-to-date call connected duration (zero when call is not
+ * established)
+ */
+ pj_time_val connect_duration;
+
+ /** Total call duration, including set-up time */
+ pj_time_val total_duration;
+
+ /** Internal */
+ struct {
+ char local_info[128];
+ char local_contact[128];
+ char remote_info[128];
+ char remote_contact[128];
+ char call_id[128];
+ char last_status_text[128];
+ } buf_;
+
+} pjsua_call_info;
+
+
+
+/**
+ * Get maximum number of calls configured in pjsua.
+ *
+ * @return Maximum number of calls configured.
+ */
+PJ_DECL(unsigned) pjsua_call_get_max_count(void);
+
+/**
+ * Get number of currently active calls.
+ *
+ * @return Number of currently active calls.
+ */
+PJ_DECL(unsigned) pjsua_call_get_count(void);
+
+/**
+ * Enumerate all active calls. Application may then query the information and
+ * state of each call by calling #pjsua_call_get_info().
+ *
+ * @param ids Array of account IDs to be initialized.
+ * @param count In input, specifies the maximum number of elements.
+ * On return, it contains the actual number of elements.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_enum_calls(pjsua_call_id ids[],
+ unsigned *count);
+
+
+/**
+ * Make outgoing call to the specified URI using the specified account.
+ *
+ * @param acc_id The account to be used.
+ * @param dst_uri URI to be put in the To header (normally is the same
+ * as the target URI).
+ * @param options Options (must be zero at the moment).
+ * @param user_data Arbitrary user data to be attached to the call, and
+ * can be retrieved later.
+ * @param msg_data Optional headers etc to be added to outgoing INVITE
+ * request, or NULL if no custom header is desired.
+ * @param p_call_id Pointer to receive call identification.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_make_call(pjsua_acc_id acc_id,
+ const pj_str_t *dst_uri,
+ unsigned options,
+ void *user_data,
+ const pjsua_msg_data *msg_data,
+ pjsua_call_id *p_call_id);
+
+
+/**
+ * Check if the specified call has active INVITE session and the INVITE
+ * session has not been disconnected.
+ *
+ * @param call_id Call identification.
+ *
+ * @return Non-zero if call is active.
+ */
+PJ_DECL(pj_bool_t) pjsua_call_is_active(pjsua_call_id call_id);
+
+
+/**
+ * Check if call has an active media session.
+ *
+ * @param call_id Call identification.
+ *
+ * @return Non-zero if yes.
+ */
+PJ_DECL(pj_bool_t) pjsua_call_has_media(pjsua_call_id call_id);
+
+
+/**
+ * Retrieve the media session associated with this call. Note that the media
+ * session may not be available depending on the current call's media status
+ * (the pjsua_call_media_status information in pjsua_call_info). Application
+ * may use the media session to retrieve more detailed information about the
+ * call's media.
+ *
+ * @param call_id Call identification.
+ *
+ * @return Call media session.
+ */
+PJ_DECL(pjmedia_session*) pjsua_call_get_media_session(pjsua_call_id call_id);
+
+
+/**
+ * Retrieve the media transport instance that is used for this call.
+ * Application may use the media transport to query more detailed information
+ * about the media transport.
+ *
+ * @param cid Call identification (the call_id).
+ *
+ * @return Call media transport.
+ */
+PJ_DECL(pjmedia_transport*) pjsua_call_get_media_transport(pjsua_call_id cid);
+
+
+/**
+ * Get the conference port identification associated with the call.
+ *
+ * @param call_id Call identification.
+ *
+ * @return Conference port ID, or PJSUA_INVALID_ID when the
+ * media has not been established or is not active.
+ */
+PJ_DECL(pjsua_conf_port_id) pjsua_call_get_conf_port(pjsua_call_id call_id);
+
+/**
+ * Obtain detail information about the specified call.
+ *
+ * @param call_id Call identification.
+ * @param info Call info to be initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_get_info(pjsua_call_id call_id,
+ pjsua_call_info *info);
+
+
+/**
+ * Attach application specific data to the call. Application can then
+ * inspect this data by calling #pjsua_call_get_user_data().
+ *
+ * @param call_id Call identification.
+ * @param user_data Arbitrary data to be attached to the call.
+ *
+ * @return The user data.
+ */
+PJ_DECL(pj_status_t) pjsua_call_set_user_data(pjsua_call_id call_id,
+ void *user_data);
+
+
+/**
+ * Get user data attached to the call, which has been previously set with
+ * #pjsua_call_set_user_data().
+ *
+ * @param call_id Call identification.
+ *
+ * @return The user data.
+ */
+PJ_DECL(void*) pjsua_call_get_user_data(pjsua_call_id call_id);
+
+
+/**
+ * Get the NAT type of remote's endpoint. This is a proprietary feature
+ * of PJSUA-LIB which sends its NAT type in the SDP when \a nat_type_in_sdp
+ * is set in #pjsua_config.
+ *
+ * This function can only be called after SDP has been received from remote,
+ * which means for incoming call, this function can be called as soon as
+ * call is received as long as incoming call contains SDP, and for outgoing
+ * call, this function can be called only after SDP is received (normally in
+ * 200/OK response to INVITE). As a general case, application should call
+ * this function after or in \a on_call_media_state() callback.
+ *
+ * @param call_id Call identification.
+ * @param p_type Pointer to store the NAT type. Application can then
+ * retrieve the string description of the NAT type
+ * by calling pj_stun_get_nat_name().
+ *
+ * @return PJ_SUCCESS on success.
+ *
+ * @see pjsua_get_nat_type(), nat_type_in_sdp
+ */
+PJ_DECL(pj_status_t) pjsua_call_get_rem_nat_type(pjsua_call_id call_id,
+ pj_stun_nat_type *p_type);
+
+/**
+ * Send response to incoming INVITE request. Depending on the status
+ * code specified as parameter, this function may send provisional
+ * response, establish the call, or terminate the call.
+ *
+ * @param call_id Incoming call identification.
+ * @param code Status code, (100-699).
+ * @param reason Optional reason phrase. If NULL, default text
+ * will be used.
+ * @param msg_data Optional list of headers etc to be added to outgoing
+ * response message.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_answer(pjsua_call_id call_id,
+ unsigned code,
+ const pj_str_t *reason,
+ const pjsua_msg_data *msg_data);
+
+/**
+ * Hangup call by using method that is appropriate according to the
+ * call state. This function is different than answering the call with
+ * 3xx-6xx response (with #pjsua_call_answer()), in that this function
+ * will hangup the call regardless of the state and role of the call,
+ * while #pjsua_call_answer() only works with incoming calls on EARLY
+ * state.
+ *
+ * @param call_id Call identification.
+ * @param code Optional status code to be sent when we're rejecting
+ * incoming call. If the value is zero, "603/Decline"
+ * will be sent.
+ * @param reason Optional reason phrase to be sent when we're rejecting
+ * incoming call. If NULL, default text will be used.
+ * @param msg_data Optional list of headers etc to be added to outgoing
+ * request/response message.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_hangup(pjsua_call_id call_id,
+ unsigned code,
+ const pj_str_t *reason,
+ const pjsua_msg_data *msg_data);
+
+/**
+ * Accept or reject redirection response. Application MUST call this function
+ * after it signaled PJSIP_REDIRECT_PENDING in the \a on_call_redirected()
+ * callback, to notify the call whether to accept or reject the redirection
+ * to the current target. Application can use the combination of
+ * PJSIP_REDIRECT_PENDING command in \a on_call_redirected() callback and
+ * this function to ask for user permission before redirecting the call.
+ *
+ * Note that if the application chooses to reject or stop redirection (by
+ * using PJSIP_REDIRECT_REJECT or PJSIP_REDIRECT_STOP respectively), the
+ * call disconnection callback will be called before this function returns.
+ * And if the application rejects the target, the \a on_call_redirected()
+ * callback may also be called before this function returns if there is
+ * another target to try.
+ *
+ * @param call_id The call ID.
+ * @param cmd Redirection operation to be applied to the current
+ * target. The semantic of this argument is similar
+ * to the description in the \a on_call_redirected()
+ * callback, except that the PJSIP_REDIRECT_PENDING is
+ * not accepted here.
+ *
+ * @return PJ_SUCCESS on successful operation.
+ */
+PJ_DECL(pj_status_t) pjsua_call_process_redirect(pjsua_call_id call_id,
+ pjsip_redirect_op cmd);
+
+/**
+ * Put the specified call on hold. This will send re-INVITE with the
+ * appropriate SDP to inform remote that the call is being put on hold.
+ * The final status of the request itself will be reported on the
+ * \a on_call_media_state() callback, which inform the application that
+ * the media state of the call has changed.
+ *
+ * @param call_id Call identification.
+ * @param msg_data Optional message components to be sent with
+ * the request.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_set_hold(pjsua_call_id call_id,
+ const pjsua_msg_data *msg_data);
+
+
+/**
+ * Send re-INVITE to release hold.
+ * The final status of the request itself will be reported on the
+ * \a on_call_media_state() callback, which inform the application that
+ * the media state of the call has changed.
+ *
+ * @param call_id Call identification.
+ * @param unhold If this argument is non-zero and the call is locally
+ * held, this will release the local hold.
+ * @param msg_data Optional message components to be sent with
+ * the request.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_reinvite(pjsua_call_id call_id,
+ pj_bool_t unhold,
+ const pjsua_msg_data *msg_data);
+
+/**
+ * Send UPDATE request.
+ *
+ * @param call_id Call identification.
+ * @param options Must be zero for now.
+ * @param msg_data Optional message components to be sent with
+ * the request.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_update(pjsua_call_id call_id,
+ unsigned options,
+ const pjsua_msg_data *msg_data);
+
+/**
+ * Initiate call transfer to the specified address. This function will send
+ * REFER request to instruct remote call party to initiate a new INVITE
+ * session to the specified destination/target.
+ *
+ * If application is interested to monitor the successfulness and
+ * the progress of the transfer request, it can implement
+ * \a on_call_transfer_status() callback which will report the progress
+ * of the call transfer request.
+ *
+ * @param call_id The call id to be transfered.
+ * @param dest Address of new target to be contacted.
+ * @param msg_data Optional message components to be sent with
+ * the request.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_xfer(pjsua_call_id call_id,
+ const pj_str_t *dest,
+ const pjsua_msg_data *msg_data);
+
+/**
+ * Flag to indicate that "Require: replaces" should not be put in the
+ * outgoing INVITE request caused by REFER request created by
+ * #pjsua_call_xfer_replaces().
+ */
+#define PJSUA_XFER_NO_REQUIRE_REPLACES 1
+
+/**
+ * Initiate attended call transfer. This function will send REFER request
+ * to instruct remote call party to initiate new INVITE session to the URL
+ * of \a dest_call_id. The party at \a dest_call_id then should "replace"
+ * the call with us with the new call from the REFER recipient.
+ *
+ * @param call_id The call id to be transfered.
+ * @param dest_call_id The call id to be replaced.
+ * @param options Application may specify PJSUA_XFER_NO_REQUIRE_REPLACES
+ * to suppress the inclusion of "Require: replaces" in
+ * the outgoing INVITE request created by the REFER
+ * request.
+ * @param msg_data Optional message components to be sent with
+ * the request.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_xfer_replaces(pjsua_call_id call_id,
+ pjsua_call_id dest_call_id,
+ unsigned options,
+ const pjsua_msg_data *msg_data);
+
+/**
+ * Send DTMF digits to remote using RFC 2833 payload formats.
+ *
+ * @param call_id Call identification.
+ * @param digits DTMF string digits to be sent.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_dial_dtmf(pjsua_call_id call_id,
+ const pj_str_t *digits);
+
+/**
+ * Send instant messaging inside INVITE session.
+ *
+ * @param call_id Call identification.
+ * @param mime_type Optional MIME type. If NULL, then "text/plain" is
+ * assumed.
+ * @param content The message content.
+ * @param msg_data Optional list of headers etc to be included in outgoing
+ * request. The body descriptor in the msg_data is
+ * ignored.
+ * @param user_data Optional user data, which will be given back when
+ * the IM callback is called.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_send_im( pjsua_call_id call_id,
+ const pj_str_t *mime_type,
+ const pj_str_t *content,
+ const pjsua_msg_data *msg_data,
+ void *user_data);
+
+
+/**
+ * Send IM typing indication inside INVITE session.
+ *
+ * @param call_id Call identification.
+ * @param is_typing Non-zero to indicate to remote that local person is
+ * currently typing an IM.
+ * @param msg_data Optional list of headers etc to be included in outgoing
+ * request.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_send_typing_ind(pjsua_call_id call_id,
+ pj_bool_t is_typing,
+ const pjsua_msg_data*msg_data);
+
+/**
+ * Send arbitrary request with the call. This is useful for example to send
+ * INFO request. Note that application should not use this function to send
+ * requests which would change the invite session's state, such as re-INVITE,
+ * UPDATE, PRACK, and BYE.
+ *
+ * @param call_id Call identification.
+ * @param method SIP method of the request.
+ * @param msg_data Optional message body and/or list of headers to be
+ * included in outgoing request.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_send_request(pjsua_call_id call_id,
+ const pj_str_t *method,
+ const pjsua_msg_data *msg_data);
+
+
+/**
+ * Terminate all calls. This will initiate #pjsua_call_hangup() for all
+ * currently active calls.
+ */
+PJ_DECL(void) pjsua_call_hangup_all(void);
+
+
+/**
+ * Dump call and media statistics to string.
+ *
+ * @param call_id Call identification.
+ * @param with_media Non-zero to include media information too.
+ * @param buffer Buffer where the statistics are to be written to.
+ * @param maxlen Maximum length of buffer.
+ * @param indent Spaces for left indentation.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsua_call_dump(pjsua_call_id call_id,
+ pj_bool_t with_media,
+ char *buffer,
+ unsigned maxlen,
+ const char *indent);
+
+/**
+ * @}
+ */
+
+
+/*****************************************************************************
+ * BUDDY API
+ */
+
+
+/**
+ * @defgroup PJSUA_LIB_BUDDY PJSUA-API Buddy, Presence, and Instant Messaging
+ * @ingroup PJSUA_LIB
+ * @brief Buddy management, buddy's presence, and instant messaging.
+ * @{
+ *
+ * This section describes PJSUA-APIs related to buddies management,
+ * presence management, and instant messaging.
+ */
+
+/**
+ * Max buddies in buddy list.
+ */
+#ifndef PJSUA_MAX_BUDDIES
+# define PJSUA_MAX_BUDDIES 256
+#endif
+
+
+/**
+ * This specifies how long the library should wait before retrying failed
+ * SUBSCRIBE request, and there is no rule to automatically resubscribe
+ * (for example, no "retry-after" parameter in Subscription-State header).
+ *
+ * This also controls the duration before failed PUBLISH request will be
+ * retried.
+ *
+ * Default: 300 seconds
+ */
+#ifndef PJSUA_PRES_TIMER
+# define PJSUA_PRES_TIMER 300
+#endif
+
+
+/**
+ * This structure describes buddy configuration when adding a buddy to
+ * the buddy list with #pjsua_buddy_add(). Application MUST initialize
+ * the structure with #pjsua_buddy_config_default() to initialize this
+ * structure with default configuration.
+ */
+typedef struct pjsua_buddy_config
+{
+ /**
+ * Buddy URL or name address.
+ */
+ pj_str_t uri;
+
+ /**
+ * Specify whether presence subscription should start immediately.
+ */
+ pj_bool_t subscribe;
+
+ /**
+ * Specify arbitrary application data to be associated with with
+ * the buddy object.
+ */
+ void *user_data;
+
+} pjsua_buddy_config;
+
+
+/**
+ * This enumeration describes basic buddy's online status.
+ */
+typedef enum pjsua_buddy_status
+{
+ /**
+ * Online status is unknown (possibly because no presence subscription
+ * has been established).
+ */
+ PJSUA_BUDDY_STATUS_UNKNOWN,
+
+ /**
+ * Buddy is known to be online.
+ */
+ PJSUA_BUDDY_STATUS_ONLINE,
+
+ /**
+ * Buddy is offline.
+ */
+ PJSUA_BUDDY_STATUS_OFFLINE,
+
+} pjsua_buddy_status;
+
+
+
+/**
+ * This structure describes buddy info, which can be retrieved by calling
+ * #pjsua_buddy_get_info().
+ */
+typedef struct pjsua_buddy_info
+{
+ /**
+ * The buddy ID.
+ */
+ pjsua_buddy_id id;
+
+ /**
+ * The full URI of the buddy, as specified in the configuration.
+ */
+ pj_str_t uri;
+
+ /**
+ * Buddy's Contact, only available when presence subscription has
+ * been established to the buddy.
+ */
+ pj_str_t contact;
+
+ /**
+ * Buddy's online status.
+ */
+ pjsua_buddy_status status;
+
+ /**
+ * Text to describe buddy's online status.
+ */
+ pj_str_t status_text;
+
+ /**
+ * Flag to indicate that we should monitor the presence information for
+ * this buddy (normally yes, unless explicitly disabled).
+ */
+ pj_bool_t monitor_pres;
+
+ /**
+ * If \a monitor_pres is enabled, this specifies the last state of the
+ * presence subscription. If presence subscription session is currently
+ * active, the value will be PJSIP_EVSUB_STATE_ACTIVE. If presence
+ * subscription request has been rejected, the value will be
+ * PJSIP_EVSUB_STATE_TERMINATED, and the termination reason will be
+ * specified in \a sub_term_reason.
+ */
+ pjsip_evsub_state sub_state;
+
+ /**
+ * String representation of subscription state.
+ */
+ const char *sub_state_name;
+
+ /**
+ * Specifies the last presence subscription termination code. This would
+ * return the last status of the SUBSCRIBE request. If the subscription
+ * is terminated with NOTIFY by the server, this value will be set to
+ * 200, and subscription termination reason will be given in the
+ * \a sub_term_reason field.
+ */
+ unsigned sub_term_code;
+
+ /**
+ * Specifies the last presence subscription termination reason. If
+ * presence subscription is currently active, the value will be empty.
+ */
+ pj_str_t sub_term_reason;
+
+ /**
+ * Extended RPID information about the person.
+ */
+ pjrpid_element rpid;
+
+ /**
+ * Extended presence info.
+ */
+ pjsip_pres_status pres_status;
+
+ /**
+ * Internal buffer.
+ */
+ char buf_[512];
+
+} pjsua_buddy_info;
+
+
+/**
+ * Set default values to the buddy config.
+ */
+PJ_DECL(void) pjsua_buddy_config_default(pjsua_buddy_config *cfg);
+
+
+/**
+ * Get total number of buddies.
+ *
+ * @return Number of buddies.
+ */
+PJ_DECL(unsigned) pjsua_get_buddy_count(void);
+
+
+/**
+ * Check if buddy ID is valid.
+ *
+ * @param buddy_id Buddy ID to check.
+ *
+ * @return Non-zero if buddy ID is valid.
+ */
+PJ_DECL(pj_bool_t) pjsua_buddy_is_valid(pjsua_buddy_id buddy_id);
+
+
+/**
+ * Enumerate all buddy IDs in the buddy list. Application then can use
+ * #pjsua_buddy_get_info() to get the detail information for each buddy
+ * id.
+ *
+ * @param ids Array of ids to be initialized.
+ * @param count On input, specifies max elements in the array.
+ * On return, it contains actual number of elements
+ * that have been initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_enum_buddies(pjsua_buddy_id ids[],
+ unsigned *count);
+
+/**
+ * Find the buddy ID with the specified URI.
+ *
+ * @param uri The buddy URI.
+ *
+ * @return The buddy ID, or PJSUA_INVALID_ID if not found.
+ */
+PJ_DECL(pjsua_buddy_id) pjsua_buddy_find(const pj_str_t *uri);
+
+
+/**
+ * Get detailed buddy info.
+ *
+ * @param buddy_id The buddy identification.
+ * @param info Pointer to receive information about buddy.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_buddy_get_info(pjsua_buddy_id buddy_id,
+ pjsua_buddy_info *info);
+
+/**
+ * Set the user data associated with the buddy object.
+ *
+ * @param buddy_id The buddy identification.
+ * @param user_data Arbitrary application data to be associated with
+ * the buddy object.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_buddy_set_user_data(pjsua_buddy_id buddy_id,
+ void *user_data);
+
+
+/**
+ * Get the user data associated with the budy object.
+ *
+ * @param buddy_id The buddy identification.
+ *
+ * @return The application data.
+ */
+PJ_DECL(void*) pjsua_buddy_get_user_data(pjsua_buddy_id buddy_id);
+
+
+/**
+ * Add new buddy to the buddy list. If presence subscription is enabled
+ * for this buddy, this function will also start the presence subscription
+ * session immediately.
+ *
+ * @param buddy_cfg Buddy configuration.
+ * @param p_buddy_id Pointer to receive buddy ID.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_buddy_add(const pjsua_buddy_config *buddy_cfg,
+ pjsua_buddy_id *p_buddy_id);
+
+
+/**
+ * Delete the specified buddy from the buddy list. Any presence subscription
+ * to this buddy will be terminated.
+ *
+ * @param buddy_id Buddy identification.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_buddy_del(pjsua_buddy_id buddy_id);
+
+
+/**
+ * Enable/disable buddy's presence monitoring. Once buddy's presence is
+ * subscribed, application will be informed about buddy's presence status
+ * changed via \a on_buddy_state() callback.
+ *
+ * @param buddy_id Buddy identification.
+ * @param subscribe Specify non-zero to activate presence subscription to
+ * the specified buddy.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_buddy_subscribe_pres(pjsua_buddy_id buddy_id,
+ pj_bool_t subscribe);
+
+
+/**
+ * Update the presence information for the buddy. Although the library
+ * periodically refreshes the presence subscription for all buddies, some
+ * application may want to refresh the buddy's presence subscription
+ * immediately, and in this case it can use this function to accomplish
+ * this.
+ *
+ * Note that the buddy's presence subscription will only be initiated
+ * if presence monitoring is enabled for the buddy. See
+ * #pjsua_buddy_subscribe_pres() for more info. Also if presence subscription
+ * for the buddy is already active, this function will not do anything.
+ *
+ * Once the presence subscription is activated successfully for the buddy,
+ * application will be notified about the buddy's presence status in the
+ * on_buddy_state() callback.
+ *
+ * @param buddy_id Buddy identification.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_buddy_update_pres(pjsua_buddy_id buddy_id);
+
+
+/**
+ * Send NOTIFY to inform account presence status or to terminate server
+ * side presence subscription. If application wants to reject the incoming
+ * request, it should set the \a state to PJSIP_EVSUB_STATE_TERMINATED.
+ *
+ * @param acc_id Account ID.
+ * @param srv_pres Server presence subscription instance.
+ * @param state New state to set.
+ * @param state_str Optionally specify the state string name, if state
+ * is not "active", "pending", or "terminated".
+ * @param reason If the new state is PJSIP_EVSUB_STATE_TERMINATED,
+ * optionally specify the termination reason.
+ * @param with_body If the new state is PJSIP_EVSUB_STATE_TERMINATED,
+ * this specifies whether the NOTIFY request should
+ * contain message body containing account's presence
+ * information.
+ * @param msg_data Optional list of headers to be sent with the NOTIFY
+ * request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsua_pres_notify(pjsua_acc_id acc_id,
+ pjsua_srv_pres *srv_pres,
+ pjsip_evsub_state state,
+ const pj_str_t *state_str,
+ const pj_str_t *reason,
+ pj_bool_t with_body,
+ const pjsua_msg_data *msg_data);
+
+/**
+ * Dump presence subscriptions to log.
+ *
+ * @param verbose Yes or no.
+ */
+PJ_DECL(void) pjsua_pres_dump(pj_bool_t verbose);
+
+
+/**
+ * The MESSAGE method (defined in pjsua_im.c)
+ */
+extern const pjsip_method pjsip_message_method;
+
+
+
+/**
+ * Send instant messaging outside dialog, using the specified account for
+ * route set and authentication.
+ *
+ * @param acc_id Account ID to be used to send the request.
+ * @param to Remote URI.
+ * @param mime_type Optional MIME type. If NULL, then "text/plain" is
+ * assumed.
+ * @param content The message content.
+ * @param msg_data Optional list of headers etc to be included in outgoing
+ * request. The body descriptor in the msg_data is
+ * ignored.
+ * @param user_data Optional user data, which will be given back when
+ * the IM callback is called.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_im_send(pjsua_acc_id acc_id,
+ const pj_str_t *to,
+ const pj_str_t *mime_type,
+ const pj_str_t *content,
+ const pjsua_msg_data *msg_data,
+ void *user_data);
+
+
+/**
+ * Send typing indication outside dialog.
+ *
+ * @param acc_id Account ID to be used to send the request.
+ * @param to Remote URI.
+ * @param is_typing If non-zero, it tells remote person that local person
+ * is currently composing an IM.
+ * @param msg_data Optional list of headers etc to be added to outgoing
+ * request.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_im_typing(pjsua_acc_id acc_id,
+ const pj_str_t *to,
+ pj_bool_t is_typing,
+ const pjsua_msg_data *msg_data);
+
+
+
+/**
+ * @}
+ */
+
+
+/*****************************************************************************
+ * MEDIA API
+ */
+
+
+/**
+ * @defgroup PJSUA_LIB_MEDIA PJSUA-API Media Manipulation
+ * @ingroup PJSUA_LIB
+ * @brief Media manipulation.
+ * @{
+ *
+ * PJSUA has rather powerful media features, which are built around the
+ * PJMEDIA conference bridge. Basically, all media "ports" (such as calls, WAV
+ * players, WAV playlist, file recorders, sound device, tone generators, etc)
+ * are terminated in the conference bridge, and application can manipulate
+ * the interconnection between these terminations freely.
+ *
+ * The conference bridge provides powerful switching and mixing functionality
+ * for application. With the conference bridge, each conference slot (e.g.
+ * a call) can transmit to multiple destinations, and one destination can
+ * receive from multiple sources. If more than one media terminations are
+ * terminated in the same slot, the conference bridge will mix the signal
+ * automatically.
+ *
+ * Application connects one media termination/slot to another by calling
+ * #pjsua_conf_connect() function. This will establish <b>unidirectional</b>
+ * media flow from the source termination to the sink termination. To
+ * establish bidirectional media flow, application wound need to make another
+ * call to #pjsua_conf_connect(), this time inverting the source and
+ * destination slots in the parameter.
+ *
+ * For example, to stream a WAV file to remote call, application may use
+ * the following steps:
+ *
+ \code
+
+ pj_status_t stream_to_call( pjsua_call_id call_id )
+ {
+ pjsua_player_id player_id;
+
+ status = pjsua_player_create("mysong.wav", 0, NULL, &player_id);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pjsua_conf_connect( pjsua_player_get_conf_port(),
+ pjsua_call_get_conf_port() );
+ }
+ \endcode
+ *
+ *
+ * Other features of PJSUA media:
+ * - efficient N to M interconnections between media terminations.
+ * - media termination can be connected to itself to create loopback
+ * media.
+ * - the media termination may have different clock rates, and resampling
+ * will be done automatically by conference bridge.
+ * - media terminations may also have different frame time; the
+ * conference bridge will perform the necessary bufferring to adjust
+ * the difference between terminations.
+ * - interconnections are removed automatically when media termination
+ * is removed from the bridge.
+ * - sound device may be changed even when there are active media
+ * interconnections.
+ * - correctly report call's media quality (in #pjsua_call_dump()) from
+ * RTCP packet exchange.
+ */
+
+/**
+ * Max ports in the conference bridge. This setting is the default value
+ * for pjsua_media_config.max_media_ports.
+ */
+#ifndef PJSUA_MAX_CONF_PORTS
+# define PJSUA_MAX_CONF_PORTS 254
+#endif
+
+/**
+ * The default clock rate to be used by the conference bridge. This setting
+ * is the default value for pjsua_media_config.clock_rate.
+ */
+#ifndef PJSUA_DEFAULT_CLOCK_RATE
+# define PJSUA_DEFAULT_CLOCK_RATE 16000
+#endif
+
+/**
+ * Default frame length in the conference bridge. This setting
+ * is the default value for pjsua_media_config.audio_frame_ptime.
+ */
+#ifndef PJSUA_DEFAULT_AUDIO_FRAME_PTIME
+# define PJSUA_DEFAULT_AUDIO_FRAME_PTIME 20
+#endif
+
+
+/**
+ * Default codec quality settings. This setting is the default value
+ * for pjsua_media_config.quality.
+ */
+#ifndef PJSUA_DEFAULT_CODEC_QUALITY
+# define PJSUA_DEFAULT_CODEC_QUALITY 8
+#endif
+
+/**
+ * Default iLBC mode. This setting is the default value for
+ * pjsua_media_config.ilbc_mode.
+ */
+#ifndef PJSUA_DEFAULT_ILBC_MODE
+# define PJSUA_DEFAULT_ILBC_MODE 30
+#endif
+
+/**
+ * The default echo canceller tail length. This setting
+ * is the default value for pjsua_media_config.ec_tail_len.
+ */
+#ifndef PJSUA_DEFAULT_EC_TAIL_LEN
+# define PJSUA_DEFAULT_EC_TAIL_LEN 200
+#endif
+
+
+/**
+ * The maximum file player.
+ */
+#ifndef PJSUA_MAX_PLAYERS
+# define PJSUA_MAX_PLAYERS 32
+#endif
+
+
+/**
+ * The maximum file player.
+ */
+#ifndef PJSUA_MAX_RECORDERS
+# define PJSUA_MAX_RECORDERS 32
+#endif
+
+
+/**
+ * This structure describes media configuration, which will be specified
+ * when calling #pjsua_init(). Application MUST initialize this structure
+ * by calling #pjsua_media_config_default().
+ */
+struct pjsua_media_config
+{
+ /**
+ * Clock rate to be applied to the conference bridge.
+ * If value is zero, default clock rate will be used
+ * (PJSUA_DEFAULT_CLOCK_RATE, which by default is 16KHz).
+ */
+ unsigned clock_rate;
+
+ /**
+ * Clock rate to be applied when opening the sound device.
+ * If value is zero, conference bridge clock rate will be used.
+ */
+ unsigned snd_clock_rate;
+
+ /**
+ * Channel count be applied when opening the sound device and
+ * conference bridge.
+ */
+ unsigned channel_count;
+
+ /**
+ * Specify audio frame ptime. The value here will affect the
+ * samples per frame of both the sound device and the conference
+ * bridge. Specifying lower ptime will normally reduce the
+ * latency.
+ *
+ * Default value: PJSUA_DEFAULT_AUDIO_FRAME_PTIME
+ */
+ unsigned audio_frame_ptime;
+
+ /**
+ * Specify maximum number of media ports to be created in the
+ * conference bridge. Since all media terminate in the bridge
+ * (calls, file player, file recorder, etc), the value must be
+ * large enough to support all of them. However, the larger
+ * the value, the more computations are performed.
+ *
+ * Default value: PJSUA_MAX_CONF_PORTS
+ */
+ unsigned max_media_ports;
+
+ /**
+ * Specify whether the media manager should manage its own
+ * ioqueue for the RTP/RTCP sockets. If yes, ioqueue will be created
+ * and at least one worker thread will be created too. If no,
+ * the RTP/RTCP sockets will share the same ioqueue as SIP sockets,
+ * and no worker thread is needed.
+ *
+ * Normally application would say yes here, unless it wants to
+ * run everything from a single thread.
+ */
+ pj_bool_t has_ioqueue;
+
+ /**
+ * Specify the number of worker threads to handle incoming RTP
+ * packets. A value of one is recommended for most applications.
+ */
+ unsigned thread_cnt;
+
+ /**
+ * Media quality, 0-10, according to this table:
+ * 5-10: resampling use large filter,
+ * 3-4: resampling use small filter,
+ * 1-2: resampling use linear.
+ * The media quality also sets speex codec quality/complexity to the
+ * number.
+ *
+ * Default: 5 (PJSUA_DEFAULT_CODEC_QUALITY).
+ */
+ unsigned quality;
+
+ /**
+ * Specify default codec ptime.
+ *
+ * Default: 0 (codec specific)
+ */
+ unsigned ptime;
+
+ /**
+ * Disable VAD?
+ *
+ * Default: 0 (no (meaning VAD is enabled))
+ */
+ pj_bool_t no_vad;
+
+ /**
+ * iLBC mode (20 or 30).
+ *
+ * Default: 30 (PJSUA_DEFAULT_ILBC_MODE)
+ */
+ unsigned ilbc_mode;
+
+ /**
+ * Percentage of RTP packet to drop in TX direction
+ * (to simulate packet lost).
+ *
+ * Default: 0
+ */
+ unsigned tx_drop_pct;
+
+ /**
+ * Percentage of RTP packet to drop in RX direction
+ * (to simulate packet lost).
+ *
+ * Default: 0
+ */
+ unsigned rx_drop_pct;
+
+ /**
+ * Echo canceller options (see #pjmedia_echo_create())
+ *
+ * Default: 0.
+ */
+ unsigned ec_options;
+
+ /**
+ * Echo canceller tail length, in miliseconds.
+ *
+ * Default: PJSUA_DEFAULT_EC_TAIL_LEN
+ */
+ unsigned ec_tail_len;
+
+ /**
+ * Audio capture buffer length, in milliseconds.
+ *
+ * Default: PJMEDIA_SND_DEFAULT_REC_LATENCY
+ */
+ unsigned snd_rec_latency;
+
+ /**
+ * Audio playback buffer length, in milliseconds.
+ *
+ * Default: PJMEDIA_SND_DEFAULT_PLAY_LATENCY
+ */
+ unsigned snd_play_latency;
+
+ /**
+ * Jitter buffer initial prefetch delay in msec. The value must be
+ * between jb_min_pre and jb_max_pre below.
+ *
+ * Default: -1 (to use default stream settings, currently 150 msec)
+ */
+ int jb_init;
+
+ /**
+ * Jitter buffer minimum prefetch delay in msec.
+ *
+ * Default: -1 (to use default stream settings, currently 60 msec)
+ */
+ int jb_min_pre;
+
+ /**
+ * Jitter buffer maximum prefetch delay in msec.
+ *
+ * Default: -1 (to use default stream settings, currently 240 msec)
+ */
+ int jb_max_pre;
+
+ /**
+ * Set maximum delay that can be accomodated by the jitter buffer msec.
+ *
+ * Default: -1 (to use default stream settings, currently 360 msec)
+ */
+ int jb_max;
+
+ /**
+ * Enable ICE
+ */
+ pj_bool_t enable_ice;
+
+ /**
+ * Set the maximum number of host candidates.
+ *
+ * Default: -1 (maximum not set)
+ */
+ int ice_max_host_cands;
+
+ /**
+ * ICE session options.
+ */
+ pj_ice_sess_options ice_opt;
+
+ /**
+ * Disable RTCP component.
+ *
+ * Default: no
+ */
+ pj_bool_t ice_no_rtcp;
+
+ /**
+ * Enable TURN relay candidate in ICE.
+ */
+ pj_bool_t enable_turn;
+
+ /**
+ * Specify TURN domain name or host name, in in "DOMAIN:PORT" or
+ * "HOST:PORT" format.
+ */
+ pj_str_t turn_server;
+
+ /**
+ * Specify the connection type to be used to the TURN server. Valid
+ * values are PJ_TURN_TP_UDP or PJ_TURN_TP_TCP.
+ *
+ * Default: PJ_TURN_TP_UDP
+ */
+ pj_turn_tp_type turn_conn_type;
+
+ /**
+ * Specify the credential to authenticate with the TURN server.
+ */
+ pj_stun_auth_cred turn_auth_cred;
+
+ /**
+ * Specify idle time of sound device before it is automatically closed,
+ * in seconds. Use value -1 to disable the auto-close feature of sound
+ * device
+ *
+ * Default : 1
+ */
+ int snd_auto_close_time;
+};
+
+
+/**
+ * Use this function to initialize media config.
+ *
+ * @param cfg The media config to be initialized.
+ */
+PJ_DECL(void) pjsua_media_config_default(pjsua_media_config *cfg);
+
+
+/**
+ * This structure describes codec information, which can be retrieved by
+ * calling #pjsua_enum_codecs().
+ */
+typedef struct pjsua_codec_info
+{
+ /**
+ * Codec unique identification.
+ */
+ pj_str_t codec_id;
+
+ /**
+ * Codec priority (integer 0-255).
+ */
+ pj_uint8_t priority;
+
+ /**
+ * Internal buffer.
+ */
+ char buf_[32];
+
+} pjsua_codec_info;
+
+
+/**
+ * This structure descibes information about a particular media port that
+ * has been registered into the conference bridge. Application can query
+ * this info by calling #pjsua_conf_get_port_info().
+ */
+typedef struct pjsua_conf_port_info
+{
+ /** Conference port number. */
+ pjsua_conf_port_id slot_id;
+
+ /** Port name. */
+ pj_str_t name;
+
+ /** Clock rate. */
+ unsigned clock_rate;
+
+ /** Number of channels. */
+ unsigned channel_count;
+
+ /** Samples per frame */
+ unsigned samples_per_frame;
+
+ /** Bits per sample */
+ unsigned bits_per_sample;
+
+ /** Number of listeners in the array. */
+ unsigned listener_cnt;
+
+ /** Array of listeners (in other words, ports where this port is
+ * transmitting to.
+ */
+ pjsua_conf_port_id listeners[PJSUA_MAX_CONF_PORTS];
+
+} pjsua_conf_port_info;
+
+
+/**
+ * This structure holds information about custom media transport to
+ * be registered to pjsua.
+ */
+typedef struct pjsua_media_transport
+{
+ /**
+ * Media socket information containing the address information
+ * of the RTP and RTCP socket.
+ */
+ pjmedia_sock_info skinfo;
+
+ /**
+ * The media transport instance.
+ */
+ pjmedia_transport *transport;
+
+} pjsua_media_transport;
+
+
+
+
+/**
+ * Get maxinum number of conference ports.
+ *
+ * @return Maximum number of ports in the conference bridge.
+ */
+PJ_DECL(unsigned) pjsua_conf_get_max_ports(void);
+
+
+/**
+ * Get current number of active ports in the bridge.
+ *
+ * @return The number.
+ */
+PJ_DECL(unsigned) pjsua_conf_get_active_ports(void);
+
+
+/**
+ * Enumerate all conference ports.
+ *
+ * @param id Array of conference port ID to be initialized.
+ * @param count On input, specifies max elements in the array.
+ * On return, it contains actual number of elements
+ * that have been initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_enum_conf_ports(pjsua_conf_port_id id[],
+ unsigned *count);
+
+
+/**
+ * Get information about the specified conference port
+ *
+ * @param port_id Port identification.
+ * @param info Pointer to store the port info.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_conf_get_port_info( pjsua_conf_port_id port_id,
+ pjsua_conf_port_info *info);
+
+
+/**
+ * Add arbitrary media port to PJSUA's conference bridge. Application
+ * can use this function to add the media port that it creates. For
+ * media ports that are created by PJSUA-LIB (such as calls, file player,
+ * or file recorder), PJSUA-LIB will automatically add the port to
+ * the bridge.
+ *
+ * @param pool Pool to use.
+ * @param port Media port to be added to the bridge.
+ * @param p_id Optional pointer to receive the conference
+ * slot id.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_conf_add_port(pj_pool_t *pool,
+ pjmedia_port *port,
+ pjsua_conf_port_id *p_id);
+
+
+/**
+ * Remove arbitrary slot from the conference bridge. Application should only
+ * call this function if it registered the port manually with previous call
+ * to #pjsua_conf_add_port().
+ *
+ * @param port_id The slot id of the port to be removed.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_conf_remove_port(pjsua_conf_port_id port_id);
+
+
+/**
+ * Establish unidirectional media flow from souce to sink. One source
+ * may transmit to multiple destinations/sink. And if multiple
+ * sources are transmitting to the same sink, the media will be mixed
+ * together. Source and sink may refer to the same ID, effectively
+ * looping the media.
+ *
+ * If bidirectional media flow is desired, application needs to call
+ * this function twice, with the second one having the arguments
+ * reversed.
+ *
+ * @param source Port ID of the source media/transmitter.
+ * @param sink Port ID of the destination media/received.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_conf_connect(pjsua_conf_port_id source,
+ pjsua_conf_port_id sink);
+
+
+/**
+ * Disconnect media flow from the source to destination port.
+ *
+ * @param source Port ID of the source media/transmitter.
+ * @param sink Port ID of the destination media/received.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_conf_disconnect(pjsua_conf_port_id source,
+ pjsua_conf_port_id sink);
+
+
+/**
+ * Adjust the signal level to be transmitted from the bridge to the
+ * specified port by making it louder or quieter.
+ *
+ * @param slot The conference bridge slot number.
+ * @param level Signal level adjustment. Value 1.0 means no level
+ * adjustment, while value 0 means to mute the port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_conf_adjust_tx_level(pjsua_conf_port_id slot,
+ float level);
+
+/**
+ * Adjust the signal level to be received from the specified port (to
+ * the bridge) by making it louder or quieter.
+ *
+ * @param slot The conference bridge slot number.
+ * @param level Signal level adjustment. Value 1.0 means no level
+ * adjustment, while value 0 means to mute the port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_conf_adjust_rx_level(pjsua_conf_port_id slot,
+ float level);
+
+/**
+ * Get last signal level transmitted to or received from the specified port.
+ * The signal level is an integer value in zero to 255, with zero indicates
+ * no signal, and 255 indicates the loudest signal level.
+ *
+ * @param slot The conference bridge slot number.
+ * @param tx_level Optional argument to receive the level of signal
+ * transmitted to the specified port (i.e. the direction
+ * is from the bridge to the port).
+ * @param rx_level Optional argument to receive the level of signal
+ * received from the port (i.e. the direction is from the
+ * port to the bridge).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsua_conf_get_signal_level(pjsua_conf_port_id slot,
+ unsigned *tx_level,
+ unsigned *rx_level);
+
+
+/*****************************************************************************
+ * File player and playlist.
+ */
+
+/**
+ * Create a file player, and automatically add this player to
+ * the conference bridge.
+ *
+ * @param filename The filename to be played. Currently only
+ * WAV files are supported, and the WAV file MUST be
+ * formatted as 16bit PCM mono/single channel (any
+ * clock rate is supported).
+ * @param options Optional option flag. Application may specify
+ * PJMEDIA_FILE_NO_LOOP to prevent playback loop.
+ * @param p_id Pointer to receive player ID.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_player_create(const pj_str_t *filename,
+ unsigned options,
+ pjsua_player_id *p_id);
+
+
+/**
+ * Create a file playlist media port, and automatically add the port
+ * to the conference bridge.
+ *
+ * @param file_names Array of file names to be added to the play list.
+ * Note that the files must have the same clock rate,
+ * number of channels, and number of bits per sample.
+ * @param file_count Number of files in the array.
+ * @param label Optional label to be set for the media port.
+ * @param options Optional option flag. Application may specify
+ * PJMEDIA_FILE_NO_LOOP to prevent looping.
+ * @param p_id Optional pointer to receive player ID.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_playlist_create(const pj_str_t file_names[],
+ unsigned file_count,
+ const pj_str_t *label,
+ unsigned options,
+ pjsua_player_id *p_id);
+
+/**
+ * Get conference port ID associated with player or playlist.
+ *
+ * @param id The file player ID.
+ *
+ * @return Conference port ID associated with this player.
+ */
+PJ_DECL(pjsua_conf_port_id) pjsua_player_get_conf_port(pjsua_player_id id);
+
+
+/**
+ * Get the media port for the player or playlist.
+ *
+ * @param id The player ID.
+ * @param p_port The media port associated with the player.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsua_player_get_port(pjsua_player_id id,
+ pjmedia_port **p_port);
+
+/**
+ * Set playback position. This operation is not valid for playlist.
+ *
+ * @param id The file player ID.
+ * @param samples The playback position, in samples. Application can
+ * specify zero to re-start the playback.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_player_set_pos(pjsua_player_id id,
+ pj_uint32_t samples);
+
+
+/**
+ * Close the file of playlist, remove the player from the bridge, and free
+ * resources associated with the file player or playlist.
+ *
+ * @param id The file player ID.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_player_destroy(pjsua_player_id id);
+
+
+/*****************************************************************************
+ * File recorder.
+ */
+
+/**
+ * Create a file recorder, and automatically connect this recorder to
+ * the conference bridge. The recorder currently supports recording WAV file.
+ * The type of the recorder to use is determined by the extension of the file
+ * (e.g. ".wav").
+ *
+ * @param filename Output file name. The function will determine the
+ * default format to be used based on the file extension.
+ * Currently ".wav" is supported on all platforms.
+ * @param enc_type Optionally specify the type of encoder to be used to
+ * compress the media, if the file can support different
+ * encodings. This value must be zero for now.
+ * @param enc_param Optionally specify codec specific parameter to be
+ * passed to the file writer.
+ * For .WAV recorder, this value must be NULL.
+ * @param max_size Maximum file size. Specify zero or -1 to remove size
+ * limitation. This value must be zero or -1 for now.
+ * @param options Optional options.
+ * @param p_id Pointer to receive the recorder instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_recorder_create(const pj_str_t *filename,
+ unsigned enc_type,
+ void *enc_param,
+ pj_ssize_t max_size,
+ unsigned options,
+ pjsua_recorder_id *p_id);
+
+
+/**
+ * Get conference port associated with recorder.
+ *
+ * @param id The recorder ID.
+ *
+ * @return Conference port ID associated with this recorder.
+ */
+PJ_DECL(pjsua_conf_port_id) pjsua_recorder_get_conf_port(pjsua_recorder_id id);
+
+
+/**
+ * Get the media port for the recorder.
+ *
+ * @param id The recorder ID.
+ * @param p_port The media port associated with the recorder.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsua_recorder_get_port(pjsua_recorder_id id,
+ pjmedia_port **p_port);
+
+
+/**
+ * Destroy recorder (this will complete recording).
+ *
+ * @param id The recorder ID.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_recorder_destroy(pjsua_recorder_id id);
+
+
+/*****************************************************************************
+ * Sound devices.
+ */
+
+/**
+ * Enum all audio devices installed in the system.
+ *
+ * @param info Array of info to be initialized.
+ * @param count On input, specifies max elements in the array.
+ * On return, it contains actual number of elements
+ * that have been initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_enum_aud_devs(pjmedia_aud_dev_info info[],
+ unsigned *count);
+
+/**
+ * Enum all sound devices installed in the system (old API).
+ *
+ * @param info Array of info to be initialized.
+ * @param count On input, specifies max elements in the array.
+ * On return, it contains actual number of elements
+ * that have been initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_enum_snd_devs(pjmedia_snd_dev_info info[],
+ unsigned *count);
+
+/**
+ * Get currently active sound devices. If sound devices has not been created
+ * (for example when pjsua_start() is not called), it is possible that
+ * the function returns PJ_SUCCESS with -1 as device IDs.
+ *
+ * @param capture_dev On return it will be filled with device ID of the
+ * capture device.
+ * @param playback_dev On return it will be filled with device ID of the
+ * device ID of the playback device.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_get_snd_dev(int *capture_dev,
+ int *playback_dev);
+
+
+/**
+ * Select or change sound device. Application may call this function at
+ * any time to replace current sound device.
+ *
+ * @param capture_dev Device ID of the capture device.
+ * @param playback_dev Device ID of the playback device.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_set_snd_dev(int capture_dev,
+ int playback_dev);
+
+
+/**
+ * Set pjsua to use null sound device. The null sound device only provides
+ * the timing needed by the conference bridge, and will not interract with
+ * any hardware.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_set_null_snd_dev(void);
+
+
+/**
+ * Disconnect the main conference bridge from any sound devices, and let
+ * application connect the bridge to it's own sound device/master port.
+ *
+ * @return The port interface of the conference bridge,
+ * so that application can connect this to it's own
+ * sound device or master port.
+ */
+PJ_DECL(pjmedia_port*) pjsua_set_no_snd_dev(void);
+
+
+/**
+ * Change the echo cancellation settings.
+ *
+ * The behavior of this function depends on whether the sound device is
+ * currently active, and if it is, whether device or software AEC is
+ * being used.
+ *
+ * If the sound device is currently active, and if the device supports AEC,
+ * this function will forward the change request to the device and it will
+ * be up to the device on whether support the request. If software AEC is
+ * being used (the software EC will be used if the device does not support
+ * AEC), this function will change the software EC settings. In all cases,
+ * the setting will be saved for future opening of the sound device.
+ *
+ * If the sound device is not currently active, this will only change the
+ * default AEC settings and the setting will be applied next time the
+ * sound device is opened.
+ *
+ * @param tail_ms The tail length, in miliseconds. Set to zero to
+ * disable AEC.
+ * @param options Options to be passed to pjmedia_echo_create().
+ * Normally the value should be zero.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsua_set_ec(unsigned tail_ms, unsigned options);
+
+
+/**
+ * Get current echo canceller tail length.
+ *
+ * @param p_tail_ms Pointer to receive the tail length, in miliseconds.
+ * If AEC is disabled, the value will be zero.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsua_get_ec_tail(unsigned *p_tail_ms);
+
+
+/**
+ * Check whether the sound device is currently active. The sound device
+ * may be inactive if the application has set the auto close feature to
+ * non-zero (the snd_auto_close_time setting in #pjsua_media_config), or
+ * if null sound device or no sound device has been configured via the
+ * #pjsua_set_no_snd_dev() function.
+ */
+PJ_DECL(pj_bool_t) pjsua_snd_is_active(void);
+
+
+/**
+ * Configure sound device setting to the sound device being used. If sound
+ * device is currently active, the function will forward the setting to the
+ * sound device instance to be applied immediately, if it supports it.
+ *
+ * The setting will be saved for future opening of the sound device, if the
+ * "keep" argument is set to non-zero. If the sound device is currently
+ * inactive, and the "keep" argument is false, this function will return
+ * error.
+ *
+ * Note that in case the setting is kept for future use, it will be applied
+ * to any devices, even when application has changed the sound device to be
+ * used.
+ *
+ * Note also that the echo cancellation setting should be set with
+ * #pjsua_set_ec() API instead.
+ *
+ * See also #pjmedia_aud_stream_set_cap() for more information about setting
+ * an audio device capability.
+ *
+ * @param cap The sound device setting to change.
+ * @param pval Pointer to value. Please see #pjmedia_aud_dev_cap
+ * documentation about the type of value to be
+ * supplied for each setting.
+ * @param keep Specify whether the setting is to be kept for future
+ * use.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_snd_set_setting(pjmedia_aud_dev_cap cap,
+ const void *pval,
+ pj_bool_t keep);
+
+/**
+ * Retrieve a sound device setting. If sound device is currently active,
+ * the function will forward the request to the sound device. If sound device
+ * is currently inactive, and if application had previously set the setting
+ * and mark the setting as kept, then that setting will be returned.
+ * Otherwise, this function will return error.
+ *
+ * Note that echo cancellation settings should be retrieved with
+ * #pjsua_get_ec_tail() API instead.
+ *
+ * @param cap The sound device setting to retrieve.
+ * @param pval Pointer to receive the value.
+ * Please see #pjmedia_aud_dev_cap documentation about
+ * the type of value to be supplied for each setting.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_snd_get_setting(pjmedia_aud_dev_cap cap,
+ void *pval);
+
+
+/*****************************************************************************
+ * Codecs.
+ */
+
+/**
+ * Enum all supported codecs in the system.
+ *
+ * @param id Array of ID to be initialized.
+ * @param count On input, specifies max elements in the array.
+ * On return, it contains actual number of elements
+ * that have been initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_enum_codecs( pjsua_codec_info id[],
+ unsigned *count );
+
+
+/**
+ * Change codec priority.
+ *
+ * @param codec_id Codec ID, which is a string that uniquely identify
+ * the codec (such as "speex/8000"). Please see pjsua
+ * manual or pjmedia codec reference for details.
+ * @param priority Codec priority, 0-255, where zero means to disable
+ * the codec.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_codec_set_priority( const pj_str_t *codec_id,
+ pj_uint8_t priority );
+
+
+/**
+ * Get codec parameters.
+ *
+ * @param codec_id Codec ID.
+ * @param param Structure to receive codec parameters.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_codec_get_param( const pj_str_t *codec_id,
+ pjmedia_codec_param *param );
+
+
+/**
+ * Set codec parameters.
+ *
+ * @param codec_id Codec ID.
+ * @param param Codec parameter to set.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_codec_set_param( const pj_str_t *codec_id,
+ const pjmedia_codec_param *param);
+
+
+
+
+/**
+ * Create UDP media transports for all the calls. This function creates
+ * one UDP media transport for each call.
+ *
+ * @param cfg Media transport configuration. The "port" field in the
+ * configuration is used as the start port to bind the
+ * sockets.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjsua_media_transports_create(const pjsua_transport_config *cfg);
+
+
+/**
+ * Register custom media transports to be used by calls. There must
+ * enough media transports for all calls.
+ *
+ * @param tp The media transport array.
+ * @param count Number of elements in the array. This number MUST
+ * match the number of maximum calls configured when
+ * pjsua is created.
+ * @param auto_delete Flag to indicate whether the transports should be
+ * destroyed when pjsua is shutdown.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjsua_media_transports_attach( pjsua_media_transport tp[],
+ unsigned count,
+ pj_bool_t auto_delete);
+
+
+/**
+ * @}
+ */
+
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJSUA_H__ */
diff --git a/Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua_internal.h b/Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua_internal.h
new file mode 100644
index 0000000..65557a9
--- /dev/null
+++ b/Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -0,0 +1,550 @@
+/* $Id: pjsua_internal.h 2968 2009-10-26 11:21:37Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSUA_INTERNAL_H__
+#define __PJSUA_INTERNAL_H__
+
+/**
+ * This is the private header used by pjsua library implementation.
+ * Applications should not include this file.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Media transport state.
+ */
+typedef enum pjsua_med_tp_st
+{
+ /** Not initialized */
+ PJSUA_MED_TP_IDLE,
+
+ /** Initialized (media_create() has been called) */
+ PJSUA_MED_TP_INIT,
+
+ /** Running (media_start() has been called) */
+ PJSUA_MED_TP_RUNNING
+
+} pjsua_med_tp_st;
+
+/**
+ * Structure to be attached to invite dialog.
+ * Given a dialog "dlg", application can retrieve this structure
+ * by accessing dlg->mod_data[pjsua.mod.id].
+ */
+typedef struct pjsua_call
+{
+ unsigned index; /**< Index in pjsua array. */
+ pjsip_inv_session *inv; /**< The invite session. */
+ void *user_data; /**< User/application data. */
+ pjsip_status_code last_code; /**< Last status code seen. */
+ pj_str_t last_text; /**< Last status text seen. */
+ pj_time_val start_time;/**< First INVITE sent/received. */
+ pj_time_val res_time; /**< First response sent/received. */
+ pj_time_val conn_time; /**< Connected/confirmed time. */
+ pj_time_val dis_time; /**< Disconnect time. */
+ pjsua_acc_id acc_id; /**< Account index being used. */
+ int secure_level;/**< Signaling security level. */
+ pj_bool_t local_hold;/**< Flag for call-hold by local. */
+ pjsua_call_media_status media_st;/**< Media state. */
+ pjmedia_dir media_dir; /**< Media direction. */
+ pjmedia_session *session; /**< The media session. */
+ int audio_idx; /**< Index of m=audio in SDP. */
+ pj_uint32_t ssrc; /**< RTP SSRC */
+ pj_uint32_t rtp_tx_ts; /**< Initial RTP timestamp for sender. */
+ pj_uint16_t rtp_tx_seq;/**< Initial RTP sequence for sender. */
+ pj_uint8_t rtp_tx_seq_ts_set;
+ /**< Bitmask flags if initial RTP sequence
+ and/or timestamp for sender are set.
+ bit 0/LSB : sequence flag
+ bit 1 : timestamp flag */
+ int conf_slot; /**< Slot # in conference bridge. */
+ pjsip_evsub *xfer_sub; /**< Xfer server subscription, if this
+ call was triggered by xfer. */
+ pjmedia_transport *med_tp; /**< Current media transport. */
+ pj_status_t med_tp_ready;/**< Media transport status. */
+ pjmedia_transport *med_orig; /**< Original media transport */
+ pj_bool_t med_tp_auto_del; /**< May delete media transport */
+ pjsua_med_tp_st med_tp_st; /**< Media transport state */
+ pj_sockaddr med_rtp_addr; /**< Current RTP source address
+ (used to update ICE default
+ address) */
+ pj_stun_nat_type rem_nat_type; /**< NAT type of remote endpoint. */
+ pjmedia_srtp_use rem_srtp_use; /**< Remote's SRTP usage policy. */
+
+ char last_text_buf_[128]; /**< Buffer for last_text. */
+
+} pjsua_call;
+
+
+/**
+ * Server presence subscription list head.
+ */
+struct pjsua_srv_pres
+{
+ PJ_DECL_LIST_MEMBER(struct pjsua_srv_pres);
+ pjsip_evsub *sub; /**< The evsub. */
+ char *remote; /**< Remote URI. */
+ int acc_id; /**< Account ID. */
+ pjsip_dialog *dlg; /**< Dialog. */
+ int expires; /**< "expires" value in the request. */
+};
+
+
+/**
+ * Account
+ */
+typedef struct pjsua_acc
+{
+ pj_pool_t *pool; /**< Pool for this account. */
+ pjsua_acc_config cfg; /**< Account configuration. */
+ pj_bool_t valid; /**< Is this account valid? */
+
+ int index; /**< Index in accounts array. */
+ pj_str_t display; /**< Display name, if any. */
+ pj_str_t user_part; /**< User part of local URI. */
+ pj_str_t contact; /**< Our Contact header. */
+
+ pj_str_t srv_domain; /**< Host part of reg server. */
+ int srv_port; /**< Port number of reg server. */
+
+ pjsip_regc *regc; /**< Client registration session. */
+ pj_status_t reg_last_err; /**< Last registration error. */
+ int reg_last_code; /**< Last status last register. */
+
+ pj_timer_entry ka_timer; /**< Keep-alive timer for UDP. */
+ pjsip_transport *ka_transport; /**< Transport for keep-alive. */
+ pj_sockaddr ka_target; /**< Destination address for K-A */
+ unsigned ka_target_len; /**< Length of ka_target. */
+
+ pjsip_route_hdr route_set; /**< Complete route set inc. outbnd.*/
+
+ unsigned cred_cnt; /**< Number of credentials. */
+ pjsip_cred_info cred[PJSUA_ACC_MAX_PROXIES]; /**< Complete creds. */
+
+ pj_bool_t online_status; /**< Our online status. */
+ pjrpid_element rpid; /**< RPID element information. */
+ pjsua_srv_pres pres_srv_list; /**< Server subscription list. */
+ pjsip_publishc *publish_sess; /**< Client publication session. */
+ pj_bool_t publish_state; /**< Last published online status */
+
+ pjsip_evsub *mwi_sub; /**< MWI client subscription */
+ pjsip_dialog *mwi_dlg; /**< Dialog for MWI sub. */
+} pjsua_acc;
+
+
+/**
+ *Transport.
+ */
+typedef struct pjsua_transport_data
+{
+ int index;
+ pjsip_transport_type_e type;
+ pjsip_host_port local_name;
+
+ union {
+ pjsip_transport *tp;
+ pjsip_tpfactory *factory;
+ void *ptr;
+ } data;
+
+} pjsua_transport_data;
+
+
+/** Maximum length of subscription termination reason. */
+#define PJSUA_BUDDY_SUB_TERM_REASON_LEN 32
+
+/**
+ * Buddy data.
+ */
+typedef struct pjsua_buddy
+{
+ pj_pool_t *pool; /**< Pool for this buddy. */
+ unsigned index; /**< Buddy index. */
+ void *user_data; /**< Application data. */
+ pj_str_t uri; /**< Buddy URI. */
+ pj_str_t contact; /**< Contact learned from subscrp. */
+ pj_str_t name; /**< Buddy name. */
+ pj_str_t display; /**< Buddy display name. */
+ pj_str_t host; /**< Buddy host. */
+ unsigned port; /**< Buddy port. */
+ pj_bool_t monitor; /**< Should we monitor? */
+ pjsip_dialog *dlg; /**< The underlying dialog. */
+ pjsip_evsub *sub; /**< Buddy presence subscription */
+ unsigned term_code; /**< Subscription termination code */
+ pj_str_t term_reason;/**< Subscription termination reason */
+ pjsip_pres_status status; /**< Buddy presence status. */
+ pj_timer_entry timer; /**< Resubscription timer */
+} pjsua_buddy;
+
+
+/**
+ * File player/recorder data.
+ */
+typedef struct pjsua_file_data
+{
+ pj_bool_t type; /* 0=player, 1=playlist */
+ pjmedia_port *port;
+ pj_pool_t *pool;
+ unsigned slot;
+} pjsua_file_data;
+
+
+/**
+ * Additional parameters for conference bridge.
+ */
+typedef struct pjsua_conf_setting
+{
+ unsigned channel_count;
+ unsigned samples_per_frame;
+ unsigned bits_per_sample;
+} pjsua_conf_setting;
+
+typedef struct pjsua_stun_resolve
+{
+ PJ_DECL_LIST_MEMBER(struct pjsua_stun_resolve);
+
+ pj_pool_t *pool; /**< Pool */
+ unsigned count; /**< # of entries */
+ pj_str_t *srv; /**< Array of entries */
+ unsigned idx; /**< Current index */
+ void *token; /**< App token */
+ pj_stun_resolve_cb cb; /**< App callback */
+ pj_bool_t blocking; /**< Blocking? */
+ pj_status_t status; /**< Session status */
+ pj_sockaddr addr; /**< Result */
+ pj_stun_sock *stun_sock; /**< Testing STUN sock */
+} pjsua_stun_resolve;
+
+
+/**
+ * Global pjsua application data.
+ */
+struct pjsua_data
+{
+
+ /* Control: */
+ pj_caching_pool cp; /**< Global pool factory. */
+ pj_pool_t *pool; /**< pjsua's private pool. */
+ pj_mutex_t *mutex; /**< Mutex protection for this data */
+
+ /* Logging: */
+ pjsua_logging_config log_cfg; /**< Current logging config. */
+ pj_oshandle_t log_file; /**<Output log file handle */
+
+ /* SIP: */
+ pjsip_endpoint *endpt; /**< Global endpoint. */
+ pjsip_module mod; /**< pjsua's PJSIP module. */
+ pjsua_transport_data tpdata[8]; /**< Array of transports. */
+
+ /* Threading: */
+ pj_bool_t thread_quit_flag; /**< Thread quit flag. */
+ pj_thread_t *thread[4]; /**< Array of threads. */
+
+ /* STUN and resolver */
+ pj_stun_config stun_cfg; /**< Global STUN settings. */
+ pj_sockaddr stun_srv; /**< Resolved STUN server address */
+ pj_status_t stun_status; /**< STUN server status. */
+ pjsua_stun_resolve stun_res; /**< List of pending STUN resolution*/
+ pj_dns_resolver *resolver; /**< DNS resolver. */
+
+ /* Detected NAT type */
+ pj_stun_nat_type nat_type; /**< NAT type. */
+ pj_status_t nat_status; /**< Detection status. */
+ pj_bool_t nat_in_progress; /**< Detection in progress */
+
+ /* Account: */
+ unsigned acc_cnt; /**< Number of accounts. */
+ pjsua_acc_id default_acc; /**< Default account ID */
+ pjsua_acc acc[PJSUA_MAX_ACC]; /**< Account array. */
+ pjsua_acc_id acc_ids[PJSUA_MAX_ACC]; /**< Acc sorted by prio*/
+
+ /* Calls: */
+ pjsua_config ua_cfg; /**< UA config. */
+ unsigned call_cnt; /**< Call counter. */
+ pjsua_call calls[PJSUA_MAX_CALLS];/**< Calls array. */
+ pjsua_call_id next_call_id; /**< Next call id to use*/
+
+ /* Buddy; */
+ unsigned buddy_cnt; /**< Buddy count. */
+ pjsua_buddy buddy[PJSUA_MAX_BUDDIES]; /**< Buddy array. */
+
+ /* Presence: */
+ pj_timer_entry pres_timer;/**< Presence refresh timer. */
+
+ /* Media: */
+ pjsua_media_config media_cfg; /**< Media config. */
+ pjmedia_endpt *med_endpt; /**< Media endpoint. */
+ pjsua_conf_setting mconf_cfg; /**< Additionan conf. bridge. param */
+ pjmedia_conf *mconf; /**< Conference bridge. */
+ pj_bool_t is_mswitch;/**< Are we using audio switchboard
+ (a.k.a APS-Direct) */
+
+ /* Sound device */
+ pjmedia_aud_dev_index cap_dev; /**< Capture device ID. */
+ pjmedia_aud_dev_index play_dev; /**< Playback device ID. */
+ pj_uint32_t aud_svmask;/**< Which settings to save */
+ pjmedia_aud_param aud_param; /**< User settings to sound dev */
+ pj_bool_t aud_open_cnt;/**< How many # device is opened */
+ pj_bool_t no_snd; /**< No sound (app will manage it) */
+ pj_pool_t *snd_pool; /**< Sound's private pool. */
+ pjmedia_snd_port *snd_port; /**< Sound port. */
+ pj_timer_entry snd_idle_timer;/**< Sound device idle timer. */
+ pjmedia_master_port *null_snd; /**< Master port for null sound. */
+ pjmedia_port *null_port; /**< Null port. */
+
+
+ /* File players: */
+ unsigned player_cnt;/**< Number of file players. */
+ pjsua_file_data player[PJSUA_MAX_PLAYERS];/**< Array of players.*/
+
+ /* File recorders: */
+ unsigned rec_cnt; /**< Number of file recorders. */
+ pjsua_file_data recorder[PJSUA_MAX_RECORDERS];/**< Array of recs.*/
+};
+
+
+extern struct pjsua_data pjsua_var;
+
+/**
+ * Get the instance of pjsua
+ */
+PJ_DECL(struct pjsua_data*) pjsua_get_var(void);
+
+
+
+/**
+ * IM callback data.
+ */
+typedef struct pjsua_im_data
+{
+ pjsua_acc_id acc_id;
+ pjsua_call_id call_id;
+ pj_str_t to;
+ pj_str_t body;
+ void *user_data;
+} pjsua_im_data;
+
+
+/**
+ * Duplicate IM data.
+ */
+PJ_INLINE(pjsua_im_data*) pjsua_im_data_dup(pj_pool_t *pool,
+ const pjsua_im_data *src)
+{
+ pjsua_im_data *dst;
+
+ dst = (pjsua_im_data*) pj_pool_alloc(pool, sizeof(*dst));
+ dst->acc_id = src->acc_id;
+ dst->call_id = src->call_id;
+ pj_strdup_with_null(pool, &dst->to, &src->to);
+ dst->user_data = src->user_data;
+ pj_strdup_with_null(pool, &dst->body, &src->body);
+
+ return dst;
+}
+
+
+#if 1
+#define PJSUA_LOCK() pj_mutex_lock(pjsua_var.mutex)
+#define PJSUA_TRY_LOCK() pj_mutex_trylock(pjsua_var.mutex)
+#define PJSUA_UNLOCK() pj_mutex_unlock(pjsua_var.mutex)
+#else
+#define PJSUA_LOCK()
+#define PJSUA_TRY_LOCK() PJ_SUCCESS
+#define PJSUA_UNLOCK()
+#endif
+
+/******
+ * STUN resolution
+ */
+/* Resolve the STUN server */
+pj_status_t resolve_stun_server(pj_bool_t wait);
+
+/**
+ * Normalize route URI (check for ";lr" and append one if it doesn't
+ * exist and pjsua_config.force_lr is set.
+ */
+pj_status_t normalize_route_uri(pj_pool_t *pool, pj_str_t *uri);
+
+/**
+ * Handle incoming invite request.
+ */
+pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata);
+
+/*
+ * Media channel.
+ */
+pj_status_t pjsua_media_channel_init(pjsua_call_id call_id,
+ pjsip_role_e role,
+ int security_level,
+ pj_pool_t *tmp_pool,
+ const pjmedia_sdp_session *rem_sdp,
+ int *sip_err_code);
+pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
+ pj_pool_t *pool,
+ const pjmedia_sdp_session *rem_sdp,
+ pjmedia_sdp_session **p_sdp,
+ int *sip_err_code);
+pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
+ const pjmedia_sdp_session *local_sdp,
+ const pjmedia_sdp_session *remote_sdp);
+pj_status_t pjsua_media_channel_deinit(pjsua_call_id call_id);
+
+
+/**
+ * Init presence.
+ */
+pj_status_t pjsua_pres_init();
+
+/*
+ * Start presence subsystem.
+ */
+pj_status_t pjsua_pres_start(void);
+
+/**
+ * Refresh presence subscriptions
+ */
+void pjsua_pres_refresh(void);
+
+/*
+ * Update server subscription (e.g. when our online status has changed)
+ */
+void pjsua_pres_update_acc(int acc_id, pj_bool_t force);
+
+/*
+ * Shutdown presence.
+ */
+void pjsua_pres_shutdown(void);
+
+/**
+ * Init presence for aoocunt.
+ */
+pj_status_t pjsua_pres_init_acc(int acc_id);
+
+/**
+ * Send PUBLISH
+ */
+pj_status_t pjsua_pres_init_publish_acc(int acc_id);
+
+/**
+ * Terminate server subscription for the account
+ */
+void pjsua_pres_delete_acc(int acc_id);
+
+/**
+ * Init IM module handler to handle incoming MESSAGE outside dialog.
+ */
+pj_status_t pjsua_im_init(void);
+
+/**
+ * Start MWI subscription
+ */
+void pjsua_start_mwi(pjsua_acc *acc);
+
+/**
+ * Init call subsystem.
+ */
+pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg);
+
+/**
+ * Start call subsystem.
+ */
+pj_status_t pjsua_call_subsys_start(void);
+
+/**
+ * Init media subsystems.
+ */
+pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg);
+
+/**
+ * Start pjsua media subsystem.
+ */
+pj_status_t pjsua_media_subsys_start(void);
+
+/**
+ * Destroy pjsua media subsystem.
+ */
+pj_status_t pjsua_media_subsys_destroy(void);
+
+/**
+ * Private: check if we can accept the message.
+ * If not, then p_accept header will be filled with a valid
+ * Accept header.
+ */
+pj_bool_t pjsua_im_accept_pager(pjsip_rx_data *rdata,
+ pjsip_accept_hdr **p_accept_hdr);
+
+/**
+ * Private: process pager message.
+ * This may trigger pjsua_ui_on_pager() or pjsua_ui_on_typing().
+ */
+void pjsua_im_process_pager(int call_id, const pj_str_t *from,
+ const pj_str_t *to, pjsip_rx_data *rdata);
+
+
+/**
+ * Create Accept header for MESSAGE.
+ */
+pjsip_accept_hdr* pjsua_im_create_accept(pj_pool_t *pool);
+
+/*
+ * Add additional headers etc in msg_data specified by application
+ * when sending requests.
+ */
+void pjsua_process_msg_data(pjsip_tx_data *tdata,
+ const pjsua_msg_data *msg_data);
+
+
+/*
+ * Add route_set to outgoing requests
+ */
+void pjsua_set_msg_route_set( pjsip_tx_data *tdata,
+ const pjsip_route_hdr *route_set );
+
+
+/*
+ * Simple version of MIME type parsing (it doesn't support parameters)
+ */
+void pjsua_parse_media_type( pj_pool_t *pool,
+ const pj_str_t *mime,
+ pjsip_media_type *media_type);
+
+
+/*
+ * Internal function to init transport selector from transport id.
+ */
+void pjsua_init_tpselector(pjsua_transport_id tp_id,
+ pjsip_tpselector *sel);
+
+pjsip_dialog* on_dlg_forked(pjsip_dialog *first_set, pjsip_rx_data *res);
+pj_status_t acquire_call(const char *title,
+ pjsua_call_id call_id,
+ pjsua_call **p_call,
+ pjsip_dialog **p_dlg);
+const char *good_number(char *buf, pj_int32_t val);
+void print_call(const char *title,
+ int call_id,
+ char *buf, pj_size_t size);
+
+
+PJ_END_DECL
+
+#endif /* __PJSUA_INTERNAL_H__ */
+
diff --git a/Protocols/SIP/resource.h b/Protocols/SIP/resource.h
index 4569f2a..daa7fb8 100644
--- a/Protocols/SIP/resource.h
+++ b/Protocols/SIP/resource.h
@@ -9,11 +9,18 @@
#define IDC_USERNAME 1000
#define IDC_PASSWORD 1001
#define IDC_NAME 1002
+#define IDC_REALM 1002
#define IDC_NUMBER 1003
#define IDC_PORT 1004
-#define IDC_STUN_PORT 1005
+#define IDC_REG_PORT 1005
+#define IDC_DNS_PORT 1006
+#define IDC_STUN_PORT 1007
+#define IDC_PROXY_PORT 1008
#define IDC_HOST 1043
-#define IDC_STUN_HOST 1044
+#define IDC_REG_HOST 1044
+#define IDC_DNS_HOST 1045
+#define IDC_STUN_HOST 1046
+#define IDC_PROXY_HOST 1047
#define IDC_SAVEPASSWORD 1048
#define IDC_INPUT_TOO 1060
#define IDC_IGNORE_UPPERCASE 1065
@@ -25,7 +32,10 @@
#define IDC_ONLY_ISOLATED 1086
#define IDC_ONLY_ISOLATED2 1087
#define IDC_CUSTOM_SMILEYS 1087
+#define IDC_PUBLISH 1087
#define IDC_VIDEO 1088
+#define IDC_PUBLISH2 1088
+#define IDC_KEEPALIVE 1088
#define IDC_STATIC -1
// Next default values for new objects
@@ -36,7 +46,7 @@
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 128
#define _APS_NEXT_COMMAND_VALUE 40005
-#define _APS_NEXT_CONTROL_VALUE 1087
+#define _APS_NEXT_CONTROL_VALUE 1088
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/Protocols/SIP/resource.rc b/Protocols/SIP/resource.rc
index 229bfdf..17ca10e 100644
--- a/Protocols/SIP/resource.rc
+++ b/Protocols/SIP/resource.rc
@@ -36,35 +36,65 @@ BEGIN
EDITTEXT IDC_HOST,54,0,92,12,ES_AUTOHSCROLL
CTEXT ":",IDC_STATIC,147,0,8,12,SS_CENTERIMAGE
EDITTEXT IDC_PORT,155,0,30,12,ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "User:",IDC_STATIC,0,16,53,12,SS_CENTERIMAGE
+ LTEXT "Username:",IDC_STATIC,0,16,53,12,SS_CENTERIMAGE
EDITTEXT IDC_USERNAME,54,16,131,12,ES_AUTOHSCROLL
LTEXT "Password:",IDC_STATIC,0,31,53,12,SS_CENTERIMAGE
EDITTEXT IDC_PASSWORD,54,32,131,12,ES_PASSWORD | ES_AUTOHSCROLL
CONTROL "Save password",IDC_SAVEPASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,48,131,10
END
-IDD_OPTIONS DIALOGEX 0, 0, 216, 152
+IDD_OPTIONS DIALOGEX 0, 0, 216, 217
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
GROUPBOX "SIP",IDC_STATIC,3,4,209,76
LTEXT "Server:",IDC_STATIC,14,17,53,12,SS_CENTERIMAGE
- EDITTEXT IDC_HOST,68,17,92,12,ES_AUTOHSCROLL
- CTEXT ":",IDC_STATIC,162,17,8,12,SS_CENTERIMAGE
- EDITTEXT IDC_PORT,170,17,30,12,ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "User:",IDC_STATIC,14,33,53,12,SS_CENTERIMAGE
+ EDITTEXT IDC_HOST,68,17,131,12,ES_AUTOHSCROLL
+ LTEXT "Username:",IDC_STATIC,14,33,53,12,SS_CENTERIMAGE
EDITTEXT IDC_USERNAME,68,33,131,12,ES_AUTOHSCROLL
LTEXT "Password:",IDC_STATIC,14,48,53,12,SS_CENTERIMAGE
EDITTEXT IDC_PASSWORD,68,49,131,12,ES_PASSWORD | ES_AUTOHSCROLL
CONTROL "Save password",IDC_SAVEPASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,68,65,131,10
- GROUPBOX "Advanced",IDC_STATIC,3,84,209,33,NOT WS_VISIBLE
- LTEXT "STUN Server:",IDC_STATIC,14,98,53,12,SS_CENTERIMAGE | NOT WS_VISIBLE
- EDITTEXT IDC_STUN_HOST,68,98,92,12,ES_AUTOHSCROLL | NOT WS_VISIBLE
- CTEXT ":",IDC_STATIC,162,98,8,12,SS_CENTERIMAGE | NOT WS_VISIBLE
- EDITTEXT IDC_STUN_PORT,170,98,30,12,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_VISIBLE
+ GROUPBOX "Advanced",IDC_STATIC,3,84,209,126
+ LTEXT "Registrar:",IDC_STATIC,14,99,53,12,SS_CENTERIMAGE
+ EDITTEXT IDC_REG_HOST,68,99,92,12,ES_AUTOHSCROLL
+ CTEXT ":",IDC_STATIC,161,99,8,12,SS_CENTERIMAGE
+ EDITTEXT IDC_REG_PORT,169,99,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "Auth Realm:",IDC_STATIC,14,115,53,12,SS_CENTERIMAGE
+ EDITTEXT IDC_REALM,68,115,131,12,ES_AUTOHSCROLL
+ LTEXT "DNS SRV:",IDC_STATIC,14,131,53,12,SS_CENTERIMAGE
+ EDITTEXT IDC_DNS_HOST,68,131,92,12,ES_AUTOHSCROLL
+ CTEXT ":",IDC_STATIC,161,131,8,12,SS_CENTERIMAGE
+ EDITTEXT IDC_DNS_PORT,169,131,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "STUN Server:",IDC_STATIC,14,147,53,12,SS_CENTERIMAGE
+ EDITTEXT IDC_STUN_HOST,68,147,92,12,ES_AUTOHSCROLL
+ CTEXT ":",IDC_STATIC,161,147,8,12,SS_CENTERIMAGE
+ EDITTEXT IDC_STUN_PORT,169,147,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "Proxy Server:",IDC_STATIC,14,163,53,12,SS_CENTERIMAGE
+ EDITTEXT IDC_PROXY_HOST,68,163,92,12,ES_AUTOHSCROLL
+ CTEXT ":",IDC_STATIC,161,163,8,12,SS_CENTERIMAGE
+ EDITTEXT IDC_PROXY_PORT,169,163,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "Publish status",IDC_PUBLISH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,181,185,10
+ CTEXT "Leave empty to use default values",IDC_STATIC,14,197,185,12
END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 216
+ END
+END
+#endif // APSTUDIO_INVOKED
+
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
diff --git a/Protocols/SIP/sip.cpp b/Protocols/SIP/sip.cpp
index 1856aa8..0a03fd7 100644
--- a/Protocols/SIP/sip.cpp
+++ b/Protocols/SIP/sip.cpp
@@ -100,12 +100,12 @@ extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
static SIPProto *SIPProtoInit(const char* pszProtoName, const TCHAR* tszUserName)
{
-/* if (instances.getCount() != 0)
+ if (instances.getCount() != 0)
{
MessageBox(NULL, TranslateT("Only one instance is allowed.\nI will crash now."), _T("SIP"), MB_OK | MB_ICONERROR);
return NULL;
}
-*/
+
SIPProto *proto = new SIPProto(pszProtoName, tszUserName);
instances.insert(proto);
return proto;
@@ -131,60 +131,6 @@ static void ShowError(TCHAR *msg, pj_status_t status)
}
-static void static_on_reg_state(pjsua_acc_id acc_id)
-{
- SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(acc_id);
- if (proto == NULL)
- return;
-
- proto->on_reg_state();
-}
-
-static void static_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata)
-{
- SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(acc_id);
- if (proto == NULL)
- return;
-
- proto->on_incoming_call(call_id, rdata);
-}
-
-static void static_on_call_state(pjsua_call_id call_id, pjsip_event *e)
-{
- pjsua_call_info info;
- pj_status_t status = pjsua_call_get_info(call_id, &info);
- if (status != PJ_SUCCESS)
- return;
-
- SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(info.acc_id);
- if (proto == NULL)
- return;
-
- proto->on_call_state(call_id, e);
-}
-
-static void static_on_call_media_state(pjsua_call_id call_id)
-{
- pjsua_call_info info;
- pj_status_t status = pjsua_call_get_info(call_id, &info);
- if (status != PJ_SUCCESS)
- return;
-
- SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(info.acc_id);
- if (proto == NULL)
- return;
-
- proto->on_call_media_state(call_id);
-}
-
-static void static_on_log(int level, const char *data, int len)
-{
- char tmp[1024];
- mir_snprintf(tmp, MAX_REGS(tmp), "Level %d : %*s", level, len, data);
- OutputDebugStringA(tmp);
-}
-
-
extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
{
pluginLink = link;
@@ -195,7 +141,8 @@ extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
mir_getMMI(&mmi);
mir_getUTFI(&utfi);
mir_getLI(&li);
-
+
+/*
pj_status_t status = pjsua_create();
if (status != PJ_SUCCESS)
{
@@ -232,6 +179,7 @@ extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
pjsua_destroy();
return -3;
}
+*/
hHooks.push_back( HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded) );
hHooks.push_back( HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown) );
@@ -250,7 +198,7 @@ extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
extern "C" int __declspec(dllexport) Unload(void)
{
- pjsua_destroy();
+// pjsua_destroy();
return 0;
}