From 18653f6aeb1ee4007df4402f78bbb82b6f915ba7 Mon Sep 17 00:00:00 2001 From: pescuma Date: Tue, 29 Dec 2009 19:21:19 +0000 Subject: sip: start of buddy management git-svn-id: http://pescuma.googlecode.com/svn/trunk/Miranda@197 c086bb3d-8645-0410-b8da-73a8550f86e7 --- .../libpjproject-i386-Win32-vc8-Debug-Dynamic.lib | Bin 0 -> 10311026 bytes .../lib/libpjproject-i386-Win32-vc8-Debug.lib | Bin 0 -> 10133706 bytes ...libpjproject-i386-Win32-vc8-Release-Dynamic.lib | Bin 0 -> 3641098 bytes .../libpjproject-i386-Win32-vc8-Release-Static.lib | Bin 0 -> 3598192 bytes .../lib/libpjproject-i386-Win32-vc8-Release.lib | Bin 0 -> 3635962 bytes .../SIP/lib/pjsip/pjlib-util/include/pjlib-util.h | 63 + .../pjsip/pjlib-util/include/pjlib-util/base64.h | 92 + .../pjsip/pjlib-util/include/pjlib-util/config.h | 263 ++ .../pjsip/pjlib-util/include/pjlib-util/crc32.h | 96 + .../lib/pjsip/pjlib-util/include/pjlib-util/dns.h | 445 ++ .../pjlib-util/include/pjlib-util/dns_server.h | 117 + .../pjsip/pjlib-util/include/pjlib-util/errno.h | 367 ++ .../pjsip/pjlib-util/include/pjlib-util/getopt.h | 146 + .../pjsip/pjlib-util/include/pjlib-util/hmac_md5.h | 109 + .../pjlib-util/include/pjlib-util/hmac_sha1.h | 107 + .../lib/pjsip/pjlib-util/include/pjlib-util/md5.h | 74 + .../lib/pjsip/pjlib-util/include/pjlib-util/pcap.h | 196 + .../pjsip/pjlib-util/include/pjlib-util/resolver.h | 460 ++ .../pjsip/pjlib-util/include/pjlib-util/scanner.h | 555 +++ .../include/pjlib-util/scanner_cis_bitwise.h | 97 + .../include/pjlib-util/scanner_cis_uint.h | 84 + .../lib/pjsip/pjlib-util/include/pjlib-util/sha1.h | 80 + .../pjlib-util/include/pjlib-util/srv_resolver.h | 215 + .../pjsip/pjlib-util/include/pjlib-util/string.h | 102 + .../pjlib-util/include/pjlib-util/stun_simple.h | 208 + .../pjsip/pjlib-util/include/pjlib-util/types.h | 95 + .../lib/pjsip/pjlib-util/include/pjlib-util/xml.h | 246 ++ .../SIP/lib/pjsip/pjlib/include/pj++/file.hpp | 188 + .../SIP/lib/pjsip/pjlib/include/pj++/hash.hpp | 156 + .../SIP/lib/pjsip/pjlib/include/pj++/list.hpp | 352 ++ .../SIP/lib/pjsip/pjlib/include/pj++/lock.hpp | 149 + Protocols/SIP/lib/pjsip/pjlib/include/pj++/os.hpp | 870 ++++ .../SIP/lib/pjsip/pjlib/include/pj++/pool.hpp | 279 ++ .../SIP/lib/pjsip/pjlib/include/pj++/proactor.hpp | 515 +++ .../SIP/lib/pjsip/pjlib/include/pj++/scanner.hpp | 246 ++ .../SIP/lib/pjsip/pjlib/include/pj++/sock.hpp | 444 ++ .../SIP/lib/pjsip/pjlib/include/pj++/string.hpp | 468 ++ .../SIP/lib/pjsip/pjlib/include/pj++/timer.hpp | 198 + .../SIP/lib/pjsip/pjlib/include/pj++/tree.hpp | 129 + .../SIP/lib/pjsip/pjlib/include/pj++/types.hpp | 175 + .../SIP/lib/pjsip/pjlib/include/pj/activesock.h | 526 +++ .../SIP/lib/pjsip/pjlib/include/pj/addr_resolv.h | 165 + Protocols/SIP/lib/pjsip/pjlib/include/pj/array.h | 96 + Protocols/SIP/lib/pjsip/pjlib/include/pj/assert.h | 95 + .../SIP/lib/pjsip/pjlib/include/pj/compat/assert.h | 44 + .../lib/pjsip/pjlib/include/pj/compat/cc_armcc.h | 57 + .../lib/pjsip/pjlib/include/pj/compat/cc_codew.h | 55 + .../SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcc.h | 75 + .../lib/pjsip/pjlib/include/pj/compat/cc_gcce.h | 54 + .../lib/pjsip/pjlib/include/pj/compat/cc_msvc.h | 84 + .../lib/pjsip/pjlib/include/pj/compat/cc_mwcc.h | 55 + .../SIP/lib/pjsip/pjlib/include/pj/compat/ctype.h | 49 + .../SIP/lib/pjsip/pjlib/include/pj/compat/errno.h | 44 + .../pjsip/pjlib/include/pj/compat/high_precision.h | 103 + .../lib/pjsip/pjlib/include/pj/compat/m_alpha.h | 36 + .../lib/pjsip/pjlib/include/pj/compat/m_armv4.h | 39 + .../lib/pjsip/pjlib/include/pj/compat/m_auto.h.in | 60 + .../SIP/lib/pjsip/pjlib/include/pj/compat/m_i386.h | 35 + .../SIP/lib/pjsip/pjlib/include/pj/compat/m_m68k.h | 35 + .../lib/pjsip/pjlib/include/pj/compat/m_powerpc.h | 36 + .../lib/pjsip/pjlib/include/pj/compat/m_sparc.h | 35 + .../lib/pjsip/pjlib/include/pj/compat/m_x86_64.h | 36 + .../SIP/lib/pjsip/pjlib/include/pj/compat/malloc.h | 34 + .../lib/pjsip/pjlib/include/pj/compat/os_auto.h.in | 191 + .../pjsip/pjlib/include/pj/compat/os_darwinos.h | 145 + .../lib/pjsip/pjlib/include/pj/compat/os_linux.h | 129 + .../pjlib/include/pj/compat/os_linux_kernel.h | 149 + .../lib/pjsip/pjlib/include/pj/compat/os_palmos.h | 119 + .../lib/pjsip/pjlib/include/pj/compat/os_rtems.h | 139 + .../lib/pjsip/pjlib/include/pj/compat/os_sunos.h | 132 + .../lib/pjsip/pjlib/include/pj/compat/os_symbian.h | 162 + .../lib/pjsip/pjlib/include/pj/compat/os_win32.h | 139 + .../pjsip/pjlib/include/pj/compat/os_win32_wince.h | 140 + .../SIP/lib/pjsip/pjlib/include/pj/compat/rand.h | 70 + .../SIP/lib/pjsip/pjlib/include/pj/compat/setjmp.h | 98 + .../SIP/lib/pjsip/pjlib/include/pj/compat/size_t.h | 32 + .../SIP/lib/pjsip/pjlib/include/pj/compat/socket.h | 231 + .../SIP/lib/pjsip/pjlib/include/pj/compat/stdarg.h | 32 + .../lib/pjsip/pjlib/include/pj/compat/stdfileio.h | 32 + .../SIP/lib/pjsip/pjlib/include/pj/compat/string.h | 144 + .../SIP/lib/pjsip/pjlib/include/pj/compat/time.h | 42 + Protocols/SIP/lib/pjsip/pjlib/include/pj/config.h | 1122 +++++ .../SIP/lib/pjsip/pjlib/include/pj/config_site.h | 0 .../pjsip/pjlib/include/pj/config_site_sample.h | 345 ++ Protocols/SIP/lib/pjsip/pjlib/include/pj/ctype.h | 175 + Protocols/SIP/lib/pjsip/pjlib/include/pj/doxygen.h | 996 +++++ Protocols/SIP/lib/pjsip/pjlib/include/pj/errno.h | 575 +++ Protocols/SIP/lib/pjsip/pjlib/include/pj/except.h | 421 ++ Protocols/SIP/lib/pjsip/pjlib/include/pj/fifobuf.h | 44 + .../SIP/lib/pjsip/pjlib/include/pj/file_access.h | 109 + Protocols/SIP/lib/pjsip/pjlib/include/pj/file_io.h | 183 + Protocols/SIP/lib/pjsip/pjlib/include/pj/guid.h | 101 + Protocols/SIP/lib/pjsip/pjlib/include/pj/hash.h | 220 + Protocols/SIP/lib/pjsip/pjlib/include/pj/ioqueue.h | 805 ++++ .../SIP/lib/pjsip/pjlib/include/pj/ip_helper.h | 97 + Protocols/SIP/lib/pjsip/pjlib/include/pj/list.h | 273 ++ Protocols/SIP/lib/pjsip/pjlib/include/pj/list_i.h | 121 + Protocols/SIP/lib/pjsip/pjlib/include/pj/lock.h | 154 + Protocols/SIP/lib/pjsip/pjlib/include/pj/log.h | 402 ++ Protocols/SIP/lib/pjsip/pjlib/include/pj/math.h | 197 + Protocols/SIP/lib/pjsip/pjlib/include/pj/os.h | 1343 ++++++ Protocols/SIP/lib/pjsip/pjlib/include/pj/pool.h | 903 ++++ .../SIP/lib/pjsip/pjlib/include/pj/pool_alt.h | 198 + .../SIP/lib/pjsip/pjlib/include/pj/pool_buf.h | 105 + Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_i.h | 94 + Protocols/SIP/lib/pjsip/pjlib/include/pj/rand.h | 66 + Protocols/SIP/lib/pjsip/pjlib/include/pj/rbtree.h | 210 + Protocols/SIP/lib/pjsip/pjlib/include/pj/sock.h | 1375 ++++++ .../SIP/lib/pjsip/pjlib/include/pj/sock_qos.h | 427 ++ .../SIP/lib/pjsip/pjlib/include/pj/sock_select.h | 152 + .../SIP/lib/pjsip/pjlib/include/pj/ssl_sock.h | 874 ++++ Protocols/SIP/lib/pjsip/pjlib/include/pj/string.h | 692 +++ .../SIP/lib/pjsip/pjlib/include/pj/string_i.h | 371 ++ Protocols/SIP/lib/pjsip/pjlib/include/pj/timer.h | 276 ++ Protocols/SIP/lib/pjsip/pjlib/include/pj/types.h | 544 +++ Protocols/SIP/lib/pjsip/pjlib/include/pj/unicode.h | 141 + Protocols/SIP/lib/pjsip/pjlib/include/pjlib++.hpp | 35 + Protocols/SIP/lib/pjsip/pjlib/include/pjlib.h | 63 + .../pjmedia/include/pjmedia-audiodev/audiodev.h | 667 +++ .../include/pjmedia-audiodev/audiodev_imp.h | 181 + .../pjmedia/include/pjmedia-audiodev/audiotest.h | 116 + .../pjmedia/include/pjmedia-audiodev/config.h | 394 ++ .../pjsip/pjmedia/include/pjmedia-audiodev/errno.h | 198 + .../SIP/lib/pjsip/pjmedia/include/pjmedia-codec.h | 39 + .../pjmedia/include/pjmedia-codec/amr_helper.h | 1222 ++++++ .../pjsip/pjmedia/include/pjmedia-codec/config.h | 316 ++ .../pjmedia/include/pjmedia-codec/config_auto.h.in | 71 + .../lib/pjsip/pjmedia/include/pjmedia-codec/g722.h | 74 + .../pjsip/pjmedia/include/pjmedia-codec/g7221.h | 128 + .../lib/pjsip/pjmedia/include/pjmedia-codec/gsm.h | 72 + .../lib/pjsip/pjmedia/include/pjmedia-codec/ilbc.h | 76 + .../pjmedia/include/pjmedia-codec/ipp_codecs.h | 73 + .../lib/pjsip/pjmedia/include/pjmedia-codec/l16.h | 69 + .../pjmedia/include/pjmedia-codec/passthrough.h | 106 + .../pjsip/pjmedia/include/pjmedia-codec/speex.h | 121 + .../pjsip/pjmedia/include/pjmedia-codec/types.h | 93 + Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia.h | 73 + .../lib/pjsip/pjmedia/include/pjmedia/alaw_ulaw.h | 213 + .../pjsip/pjmedia/include/pjmedia/bidirectional.h | 67 + .../lib/pjsip/pjmedia/include/pjmedia/circbuf.h | 435 ++ .../SIP/lib/pjsip/pjmedia/include/pjmedia/clock.h | 208 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/codec.h | 879 ++++ .../lib/pjsip/pjmedia/include/pjmedia/conference.h | 511 +++ .../SIP/lib/pjsip/pjmedia/include/pjmedia/config.h | 833 ++++ .../pjsip/pjmedia/include/pjmedia/config_auto.h.in | 43 + .../lib/pjsip/pjmedia/include/pjmedia/delaybuf.h | 158 + .../lib/pjsip/pjmedia/include/pjmedia/doxygen.h | 174 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/echo.h | 247 ++ .../lib/pjsip/pjmedia/include/pjmedia/echo_port.h | 74 + .../lib/pjsip/pjmedia/include/pjmedia/endpoint.h | 177 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/errno.h | 631 +++ .../SIP/lib/pjsip/pjmedia/include/pjmedia/g711.h | 70 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/jbuf.h | 314 ++ .../pjsip/pjmedia/include/pjmedia/master_port.h | 179 + .../lib/pjsip/pjmedia/include/pjmedia/mem_port.h | 195 + .../lib/pjsip/pjmedia/include/pjmedia/null_port.h | 70 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/plc.h | 115 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/port.h | 326 ++ .../lib/pjsip/pjmedia/include/pjmedia/resample.h | 200 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp.h | 408 ++ .../lib/pjsip/pjmedia/include/pjmedia/rtcp_xr.h | 467 ++ .../SIP/lib/pjsip/pjmedia/include/pjmedia/rtp.h | 394 ++ .../SIP/lib/pjsip/pjmedia/include/pjmedia/sdp.h | 674 +++ .../lib/pjsip/pjmedia/include/pjmedia/sdp_neg.h | 674 +++ .../lib/pjsip/pjmedia/include/pjmedia/session.h | 404 ++ .../lib/pjsip/pjmedia/include/pjmedia/silencedet.h | 200 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/sound.h | 336 ++ .../lib/pjsip/pjmedia/include/pjmedia/sound_port.h | 296 ++ .../lib/pjsip/pjmedia/include/pjmedia/splitcomb.h | 140 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/stereo.h | 206 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/stream.h | 354 ++ .../pjmedia/include/pjmedia/symbian_sound_aps.h | 48 + .../lib/pjsip/pjmedia/include/pjmedia/tonegen.h | 293 ++ .../lib/pjsip/pjmedia/include/pjmedia/transport.h | 820 ++++ .../include/pjmedia/transport_adapter_sample.h | 73 + .../pjsip/pjmedia/include/pjmedia/transport_ice.h | 194 + .../pjsip/pjmedia/include/pjmedia/transport_loop.h | 82 + .../pjsip/pjmedia/include/pjmedia/transport_srtp.h | 313 ++ .../pjsip/pjmedia/include/pjmedia/transport_udp.h | 162 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/types.h | 533 +++ .../pjsip/pjmedia/include/pjmedia/wav_playlist.h | 105 + .../lib/pjsip/pjmedia/include/pjmedia/wav_port.h | 250 ++ .../SIP/lib/pjsip/pjmedia/include/pjmedia/wave.h | 184 + .../SIP/lib/pjsip/pjmedia/include/pjmedia/wsola.h | 219 + .../lib/pjsip/pjmedia/include/pjmedia_audiodev.h | 33 + Protocols/SIP/lib/pjsip/pjnath/include/pjnath.h | 35 + .../SIP/lib/pjsip/pjnath/include/pjnath/config.h | 476 ++ .../SIP/lib/pjsip/pjnath/include/pjnath/errno.h | 221 + .../lib/pjsip/pjnath/include/pjnath/ice_session.h | 973 +++++ .../lib/pjsip/pjnath/include/pjnath/ice_strans.h | 792 ++++ .../lib/pjsip/pjnath/include/pjnath/nat_detect.h | 208 + .../lib/pjsip/pjnath/include/pjnath/stun_auth.h | 457 ++ .../lib/pjsip/pjnath/include/pjnath/stun_config.h | 128 + .../SIP/lib/pjsip/pjnath/include/pjnath/stun_msg.h | 1820 ++++++++ .../lib/pjsip/pjnath/include/pjnath/stun_session.h | 762 ++++ .../lib/pjsip/pjnath/include/pjnath/stun_sock.h | 446 ++ .../pjsip/pjnath/include/pjnath/stun_transaction.h | 276 ++ .../lib/pjsip/pjnath/include/pjnath/turn_session.h | 722 ++++ .../lib/pjsip/pjnath/include/pjnath/turn_sock.h | 397 ++ .../SIP/lib/pjsip/pjnath/include/pjnath/types.h | 76 + .../lib/pjsip/pjsip/include/pjsip-simple/errno.h | 118 + .../lib/pjsip/pjsip/include/pjsip-simple/evsub.h | 492 +++ .../pjsip/pjsip/include/pjsip-simple/evsub_msg.h | 119 + .../pjsip/pjsip/include/pjsip-simple/iscomposing.h | 135 + .../SIP/lib/pjsip/pjsip/include/pjsip-simple/mwi.h | 208 + .../lib/pjsip/pjsip/include/pjsip-simple/pidf.h | 178 + .../pjsip/pjsip/include/pjsip-simple/presence.h | 361 ++ .../lib/pjsip/pjsip/include/pjsip-simple/publish.h | 333 ++ .../lib/pjsip/pjsip/include/pjsip-simple/rpid.h | 149 + .../lib/pjsip/pjsip/include/pjsip-simple/types.h | 31 + .../lib/pjsip/pjsip/include/pjsip-simple/xpidf.h | 135 + .../lib/pjsip/pjsip/include/pjsip-ua/sip_100rel.h | 245 ++ .../SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_inv.h | 875 ++++ .../lib/pjsip/pjsip/include/pjsip-ua/sip_regc.h | 373 ++ .../pjsip/pjsip/include/pjsip-ua/sip_replaces.h | 301 ++ .../lib/pjsip/pjsip/include/pjsip-ua/sip_timer.h | 262 ++ .../lib/pjsip/pjsip/include/pjsip-ua/sip_xfer.h | 208 + Protocols/SIP/lib/pjsip/pjsip/include/pjsip.h | 60 + .../SIP/lib/pjsip/pjsip/include/pjsip/print_util.h | 141 + .../SIP/lib/pjsip/pjsip/include/pjsip/sip_auth.h | 495 +++ .../lib/pjsip/pjsip/include/pjsip/sip_auth_aka.h | 213 + .../lib/pjsip/pjsip/include/pjsip/sip_auth_msg.h | 252 ++ .../pjsip/pjsip/include/pjsip/sip_auth_parser.h | 73 + .../pjsip/pjsip/include/pjsip/sip_autoconf.h.in | 39 + .../SIP/lib/pjsip/pjsip/include/pjsip/sip_config.h | 924 ++++ .../SIP/lib/pjsip/pjsip/include/pjsip/sip_dialog.h | 627 +++ .../lib/pjsip/pjsip/include/pjsip/sip_endpoint.h | 521 +++ .../SIP/lib/pjsip/pjsip/include/pjsip/sip_errno.h | 535 +++ .../SIP/lib/pjsip/pjsip/include/pjsip/sip_event.h | 230 + .../SIP/lib/pjsip/pjsip/include/pjsip/sip_module.h | 222 + .../SIP/lib/pjsip/pjsip/include/pjsip/sip_msg.h | 1988 +++++++++ .../SIP/lib/pjsip/pjsip/include/pjsip/sip_parser.h | 412 ++ .../lib/pjsip/pjsip/include/pjsip/sip_private.h | 32 + .../lib/pjsip/pjsip/include/pjsip/sip_resolve.h | 291 ++ .../lib/pjsip/pjsip/include/pjsip/sip_tel_uri.h | 84 + .../pjsip/pjsip/include/pjsip/sip_transaction.h | 406 ++ .../lib/pjsip/pjsip/include/pjsip/sip_transport.h | 1193 +++++ .../pjsip/pjsip/include/pjsip/sip_transport_loop.h | 147 + .../pjsip/pjsip/include/pjsip/sip_transport_tcp.h | 210 + .../pjsip/pjsip/include/pjsip/sip_transport_tls.h | 272 ++ .../pjsip/pjsip/include/pjsip/sip_transport_udp.h | 235 + .../SIP/lib/pjsip/pjsip/include/pjsip/sip_types.h | 257 ++ .../lib/pjsip/pjsip/include/pjsip/sip_ua_layer.h | 162 + .../SIP/lib/pjsip/pjsip/include/pjsip/sip_uri.h | 457 ++ .../SIP/lib/pjsip/pjsip/include/pjsip/sip_util.h | 861 ++++ Protocols/SIP/lib/pjsip/pjsip/include/pjsip_auth.h | 38 + .../SIP/lib/pjsip/pjsip/include/pjsip_simple.h | 46 + Protocols/SIP/lib/pjsip/pjsip/include/pjsip_ua.h | 32 + .../SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua.h | 4542 ++++++++++++++++++++ .../pjsip/pjsip/include/pjsua-lib/pjsua_internal.h | 550 +++ 250 files changed, 73498 insertions(+) create mode 100644 Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.lib create mode 100644 Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug.lib create mode 100644 Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Dynamic.lib create mode 100644 Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.lib create mode 100644 Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release.lib create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/base64.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/config.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/crc32.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/dns_server.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/errno.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/getopt.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_md5.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/hmac_sha1.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/md5.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/pcap.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/resolver.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/scanner_cis_uint.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/sha1.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/srv_resolver.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/string.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/stun_simple.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/types.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib-util/include/pjlib-util/xml.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/file.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/hash.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/list.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/lock.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/os.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/pool.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/proactor.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/scanner.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/sock.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/string.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/timer.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/tree.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj++/types.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/activesock.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/addr_resolv.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/array.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/assert.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/assert.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_armcc.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_codew.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcc.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_gcce.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_msvc.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/cc_mwcc.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/ctype.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/errno.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/high_precision.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_alpha.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_armv4.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_auto.h.in create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_i386.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_m68k.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_powerpc.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_sparc.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/m_x86_64.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/malloc.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_auto.h.in create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_darwinos.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_linux_kernel.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_palmos.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_rtems.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_sunos.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_symbian.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/os_win32_wince.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/rand.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/setjmp.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/size_t.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/socket.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdarg.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/stdfileio.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/string.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/compat/time.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/config.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/config_site_sample.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/ctype.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/doxygen.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/errno.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/except.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/fifobuf.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/file_access.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/file_io.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/guid.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/hash.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/ioqueue.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/ip_helper.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/list.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/list_i.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/lock.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/log.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/math.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/os.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/pool.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_alt.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_buf.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/pool_i.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/rand.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/rbtree.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/sock.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_qos.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/sock_select.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/ssl_sock.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/string.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/string_i.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/timer.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/types.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pj/unicode.h create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pjlib++.hpp create mode 100644 Protocols/SIP/lib/pjsip/pjlib/include/pjlib.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiodev_imp.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/audiotest.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/config.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-audiodev/errno.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/amr_helper.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/config_auto.h.in create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g722.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/g7221.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/gsm.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ilbc.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/ipp_codecs.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/l16.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/passthrough.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/speex.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia-codec/types.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/alaw_ulaw.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/bidirectional.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/circbuf.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/clock.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/codec.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/conference.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/config_auto.h.in create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/delaybuf.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/doxygen.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/echo_port.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/endpoint.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/errno.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/g711.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/jbuf.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/master_port.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/mem_port.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/null_port.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/plc.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/port.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/resample.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtcp_xr.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/rtp.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sdp_neg.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/session.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/silencedet.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/sound_port.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/splitcomb.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stereo.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/stream.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/symbian_sound_aps.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/tonegen.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_adapter_sample.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_ice.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_loop.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_srtp.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/transport_udp.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/types.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_playlist.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wav_port.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wave.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia/wsola.h create mode 100644 Protocols/SIP/lib/pjsip/pjmedia/include/pjmedia_audiodev.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/config.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/errno.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_session.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/ice_strans.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/nat_detect.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_auth.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_config.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_msg.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_session.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_sock.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/stun_transaction.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_session.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/turn_sock.h create mode 100644 Protocols/SIP/lib/pjsip/pjnath/include/pjnath/types.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/errno.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/evsub_msg.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/iscomposing.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/mwi.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/pidf.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/presence.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/publish.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/rpid.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/types.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-simple/xpidf.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_100rel.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_inv.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_regc.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_replaces.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_timer.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip-ua/sip_xfer.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/print_util.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_aka.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_msg.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_auth_parser.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_autoconf.h.in create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_config.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_dialog.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_endpoint.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_errno.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_event.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_module.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_msg.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_parser.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_private.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_resolve.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_tel_uri.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transaction.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_loop.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tcp.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_tls.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_transport_udp.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_types.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_ua_layer.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_uri.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip/sip_util.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip_auth.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip_simple.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsip_ua.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua.h create mode 100644 Protocols/SIP/lib/pjsip/pjsip/include/pjsua-lib/pjsua_internal.h (limited to 'Protocols/SIP/lib') 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 Binary files /dev/null and b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.lib 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 Binary files /dev/null and b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug.lib 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 Binary files /dev/null and b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Dynamic.lib 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 Binary files /dev/null and b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.lib 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 Binary files /dev/null and b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release.lib 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 + * + * 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 +#include + +/* Getopt */ +#include + +/* Crypto */ +#include +#include +#include +#include +#include +#include + +/* DNS and resolver */ +#include +#include +#include + +/* Simple DNS server */ +#include + +/* Text scanner */ +#include + +/* XML */ +#include + +/* Old STUN */ +#include + +/* PCAP */ +#include + +#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 + * + * 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 + +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 + * + * 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 + * + * 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 + +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 + * + * 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 +#include + +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 + * + * 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 +#include + +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 + * + * 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 + +/** + * @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 + * + * 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 +#include + +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 + * + * 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 +#include + +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 + * + * 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_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 + * + * 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_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 + * + * 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 + + +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: + * - + * RFC 1035: "Domain names - implementation and specification" + * - + * RFC 2782: "A DNS RR for specifying the location of services (DNS SRV)" + * + */ + + + +/** + * 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 + * + * 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 + +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 +#else +# include +#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 + * + * 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_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 + * + * 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_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 + * + * 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_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 + * + * 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 + +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: + * - RFC 2782: + * 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 + * + * 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 +#include + +/** + * @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 + * + * 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 +#include + + +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 + * + * 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 +#include + +/** + * @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 Table of Contents 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 + * + * 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 +#include + +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 ("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 + * + * 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 +#include +#include +#include + +// +// 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 + * + * 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 +#include +#include + +// +// 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 + * + * 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 +#include + + +// +// 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 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 + * + * 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 +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// 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 + * + * 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 +#include +#include +#include + +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 + * + * 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 + +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 + * + * 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 +#include +#include +#include +#include + +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 + * + * 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 +#include + +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 + * + * 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 +#include + +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 + * + * 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 +#include +#include + +// +// 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 + * + * 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 +#include +#include +#include + +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 + * + * 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 + +// +// 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 + * + * 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 + +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 + * + * 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 +#include + + +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 + * + * 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_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: + *
+ *   ...
+ *   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;
+ *   ...
+ * 
+ * + * 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 + * + * 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_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 + * + * 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 +#include + +/** + * @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 + * + * 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 + +#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 + * + * 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 + * + * 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 + * + * 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 + 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 + * + * 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 + * + * 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 + * + * 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 + * + * 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 +#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 + * + * 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 + * + * 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 + 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 + + 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 + * + * 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 + * + * 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 + * + * 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 + * + * 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 + * + * 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 + * + * 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 + * + * 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 + * + * 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 + * + * 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 +#elif defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H != 0 +# include +#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 + * + * 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 + * + * 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 + * + * 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 + * + * 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 . + */ +#define __FD_SETSIZE PJ_IOQUEUE_MAX_HANDLES + +#define NULL ((void*)0) + +#include /* Needed by all modules */ +#include /* 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 + * + * 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 + * + * 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 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 + * + * 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 + * + * 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 . +#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 +#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 + * + * 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 + * + * 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 + * + * 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 +# 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 +# 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 + * + * 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 + 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 + */ +# 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 + * + * 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 +#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 + * + * 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 +#endif + +#if defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H != 0 +# include +#endif + +#if defined(PJ_HAS_WS2TCPIP_H) && PJ_HAS_WS2TCPIP_H != 0 +# include +#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 +# endif + +# define PJ_SOCK_HAS_GETADDRINFO 1 +#endif /* _MSC_VER */ + +#if defined(PJ_HAS_SYS_TYPES_H) && PJ_HAS_SYS_TYPES_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_SOCKET_H) && PJ_HAS_SYS_SOCKET_H != 0 +# include +#endif + +#if defined(PJ_HAS_LINUX_SOCKET_H) && PJ_HAS_LINUX_SOCKET_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_SELECT_H) && PJ_HAS_SYS_SELECT_H != 0 +# include +#endif + +#if defined(PJ_HAS_NETINET_IN_H) && PJ_HAS_NETINET_IN_H != 0 +# include +#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 +#endif + +#if defined(PJ_HAS_NETINET_IP_H) && PJ_HAS_NETINET_IP_H != 0 +/* To pull in IPTOS_* constants */ +# include +#endif + +#if defined(PJ_HAS_NETINET_TCP_H) && PJ_HAS_NETINET_TCP_H != 0 +/* To pull in TCP_NODELAY constants */ +# include +#endif + +#if defined(PJ_HAS_NET_IF_H) && PJ_HAS_NET_IF_H != 0 +/* For interface enumeration in ip_helper */ +# include +#endif + +#if defined(PJ_HAS_IFADDRS_H) && PJ_HAS_IFADDRS_H != 0 +/* Interface enum with getifaddrs() which works with IPv6 */ +# include +#endif + +#if defined(PJ_HAS_ARPA_INET_H) && PJ_HAS_ARPA_INET_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_IOCTL_H) && PJ_HAS_SYS_IOCTL_H != 0 +# include /* FBIONBIO */ +#endif + +#if defined(PJ_HAS_ERRNO_H) && PJ_HAS_ERRNO_H != 0 +# include +#endif + +#if defined(PJ_HAS_NETDB_H) && PJ_HAS_NETDB_H != 0 +# include +#endif + +#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0 +# include +#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 +# include /* FIONBIO */ +# include /* sys_select() */ +# include /* 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 + * + * 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 +#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 + * + * 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 +#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 + * + * 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 +#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 + +/* On WinCE, string stuffs are declared in stdlib.h */ +#if defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H!=0 +# include +#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 +# include + 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 + * + * 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 +#endif + +#if defined(PJ_HAS_SYS_TIME_H) && PJ_HAS_SYS_TIME_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_TIMEB_H) && PJ_HAS_SYS_TIMEB_H != 0 +# include +#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 + * + * 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 +#elif defined(__GNUC__) +# include +#elif defined(__CW32__) +# include +#elif defined(__MWERKS__) +# include +#elif defined(__GCCE__) +# include +#elif defined(__ARMCC__) +# include +#else +# error "Unknown compiler." +#endif + + +/******************************************************************** + * Include target OS specific configuration. + */ +#if defined(PJ_AUTOCONF) + /* + * Autoconf + */ +# include + +#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0 + /* + * SymbianOS + */ +# include + +#elif defined(PJ_WIN32_WINCE) || defined(_WIN32_WCE) || defined(UNDER_CE) + /* + * Windows CE + */ +# undef PJ_WIN32_WINCE +# define PJ_WIN32_WINCE 1 +# include + + /* 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 + +#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL!=0 + /* + * Linux kernel + */ +# include + +#elif defined(PJ_LINUX) || defined(linux) || defined(__linux) + /* + * Linux + */ +# undef PJ_LINUX +# define PJ_LINUX 1 +# include + +#elif defined(PJ_PALMOS) && PJ_PALMOS!=0 + /* + * Palm + */ +# include + +#elif defined(PJ_SUNOS) || defined(sun) || defined(__sun) + /* + * SunOS + */ +# undef PJ_SUNOS +# define PJ_SUNOS 1 +# include + +#elif defined(PJ_DARWINOS) || defined(__MACOSX__) || \ + defined (__APPLE__) || defined (__MACH__) + /* + * MacOS X + */ +# undef PJ_DARWINOS +# define PJ_DARWINOS 1 +# include + +#elif defined(PJ_RTEMS) && PJ_RTEMS!=0 + /* + * RTEMS + */ +# include +#else +# error "Please specify target os." +#endif + + +/******************************************************************** + * Target machine specific configuration. + */ +#if defined(PJ_AUTOCONF) + /* + * Autoconf configured + */ +#include + +#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 + +/* Include site/user specific configuration to control PJLIB features. + * YOU MUST CREATE THIS FILE YOURSELF!! + */ +#include + +/******************************************************************** + * 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. + * + * Note: 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 pjlib/build.symbian directory. These DEF files are + * created by running ./makedef.sh all from this directory, + * inside Mingw. + * + * Macros related for building DLL/DSO files: + * - For platforms that supports dynamic link libraries generation, + * it must declare PJ_EXPORT_SPECIFIER 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 PJ_IMPORT_SPECIFIER 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 PJ_EXPORT_SPECIFIER and PJ_IMPORT_SPECIFIER + * 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 PJ_DLL and + * PJ_EXPORTING macros must be declared, so that + * PJ_EXPORT_SPECIFIER modifier will be added into function + * definition. + * - When application wants to link dynamically with PJLIB, then it + * must declare PJ_DLL macro when using/including PJLIB header, + * so that PJ_IMPORT_SPECIFIER modifier is properly added into + * symbol declarations. + * + * When PJ_DLL 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 PJ_DLL and PJ_EXPORTING + * macros. + * - Declare these macros in your config_site.h: + \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 + * PJ_DLL 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 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 + * 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 + * + * 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 +#include + +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 + * + * 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 Module Index 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: + * + * - How to Build PJLIB + *\n + * Please refer to \ref pjlib_build_sys_pg page for more information. + * + * - How to Use PJLIB in My Application + *\n + * Please refer to \ref configure_app_sec for more information. + * + * - How to Port PJLIB + *\n + * Please refer to \ref porting_pjlib_pg page. + * + * - Where to Read Samples Documentation + *\n + * Most of the modules provide link to the corresponding sample file. + * Alternatively, to get the list of all examples, you can click on + * Related Pages on the top of HTML document or on + * PJLIB Page Documentation on navigation pane of your PDF reader. + * + * - How to Submit Code to PJLIB Project + *\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 kernel module(!)). + * - 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: + * + *
+ *    #define SYNTAX_ERROR  1
+ *
+ *    PJ_TRY {
+ *       msg = NULL;
+ *       msg = parse_msg(buf, len);
+ *    }
+ *    PJ_CATCH ( SYNTAX_ERROR ) {
+ *       .. handle error ..
+ *    }
+ *    PJ_END;
+ * 
+ * + * 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): + *
+ *   $PJLIB/include
+ * 
+ * + * @subsubsection compil_inc_file_sec Include PJLIB Header + * + * To include all PJLIB headers: + * \verbatim + #include + \endverbatim + * + * Alternatively, you can include individual PJLIB headers like this: + * \verbatim + #include + #include + \endverbatim + * + * + * @subsubsection compil_lib_dir_sec Library Path + * + * Add this to your library search path: + *
+ *   $PJLIB/lib
+ * 
+ * + * 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 . 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 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. + * This is very important! 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: + *
+ *  :se ts=8
+ *  :se sts=4
+ * 
+ * + * 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 + * 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). + * + * @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 pjsip_apps.dsw 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 + * pjlib.dsw in $PJPROJECT/pjlib/build directory. + * + * + * @subsubsection config_site_create_vc_sec Create config_site.h + * + * The file $PJPROJECT/pjlib/include/pj/config_site.h + * 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: + * + * "fatal error C1083: Cannot open include file: 'pj/config_site.h': No such file + * or directory". + * + * @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: + * + * - GNU make + *\n + * The Makefiles heavily utilize GNU make commands which most likely + * are not available in other \c make system. + * - bash shell is recommended. + *\n + * Specificly, there is a command "echo -n" which may not work + * in other shells. This command is used when generating dependencies + * (make dep) and it's located in + * $PJPROJECT/build/rules.mak. + * - ar, ranlib from GNU binutils + *\n + * In your system has different ar or ranlib (e.g. they + * may have been installed as gar and granlib), then + * either you create the relevant symbolic links, or modify + * $PJPROJECT/build/cc-gcc.mak and rename ar and + * ranlib to the appropriate names. + * - gcc to generate dependency. + *\n + * Currently the build system uses "gcc -MM" to generate build + * dependencies. If gcc is not desired to generate dependency, + * then either you don't run make dep, or edit + * $PJPROJECT/build/rules.mak 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 configure 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 README-configure 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 *.mak 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 $PJPROJECT/build.mak 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: + * + * - rules.mak: contains generic rules always included during make. + * - cc-gcc.mak: rules when gcc is used for compiler. + * - cc-vc.mak: rules when MSVC compiler is used. + * - host-mingw.mak: rules for building in mingw host. + * - host-unix.mak: rules for building in Unix/Posix host. + * - host-win32.mak: rules for building in Win32 command console + * (only valid when VC is used). + * - m-i386.mak: rules when target machine is an i386 processor. + * - m-m68k.mak: rules when target machine is an m68k processor. + * - os-linux.mak: rules when target OS is Linux. + * - os-linux-kernel.mak: rules when PJLIB is to be build as + * part of Linux kernel. + * - os-win32.mak: rules when target OS is Win32. + * + * + * @subsubsection config_site_create_sec Create config_site.h + * + * The file $PJPROJECT/pjlib/include/pj/config_site.h + * 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 make in $PJPROJECT + * directory, to build all projects under that directory (e.g. + * PJLIB, PJSIP, etc.). + * + * + * @subsubsection linux_kern_target_subsec Linux Kernel Target + * + * \note + * 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. + * + * \note + * User Mode Linux (UML) 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 UML to experiment with PJLIB kernel modules. + * I wouldn't be so foolish to use my host Linux machine to experiment + * with this. + * + * \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 build.mak 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. + * + * 1. Edit Makefile in kernel root source tree. + * + * Add the following lines at the end of the Makefile in your + * $KERNEL_SRC dir: + \verbatim +script: + $(SCRIPT) + \endverbatim + * + * \note Remember to replace spaces with tab 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. + * + * 2. Add Additional Exports. + * + * We need the kernel to export some more symbols for our use. So we declare + * the additional symbols to be exported in extra-exports.c file, and add + * a this file to be compiled into the kernel: + * + * - Copy the file extra-exports.c from pjlib/src/pj + * directory to $KERNEL_SRC/kernel/ directory. + * - Edit Makefile 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 +#include + +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 insmod 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 os-linux.mak file in + * $PJPROJECT/pjlib/build directory, + * which is OS specific configuration file for Linux target that is specific + * for PJLIB project. For \b global OS specific configuration, please see + * $PJPROJECT/build/os-*.mak. + * + * \include build/os-linux.mak + * + */ + + +/*////////////////////////////////////////////////////////////////////////// */ +/* + PORTING PJLIB + */ + + + +/** + * @page porting_pjlib_pg Porting PJLIB + * + * \note + * 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. + * + * + * @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 Linux. + * 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 + * alpha. + * - edit file $PJPROJECT/build.mak, and add new section for + * the new target: + *
+ *      #
+ *      # Linux alpha, gcc
+ *      #
+ *      export MACHINE_NAME := alpha
+ *      export OS_NAME := linux
+ *      export CC_NAME := gcc
+ *      export HOST_NAME := unix
+ *    
+ * + * - create a new file $PJPROJECT/build/m-alpha.mak. + * Alternatively create a copy from other file in this directory. + * The contents of this file will look something like: + *
+ *      export M_CFLAGS := $(CC_DEF)PJ_M_ALPHA=1
+ *      export M_CXXFLAGS :=
+ *      export M_LDFLAGS :=
+ *      export M_SOURCES :=
+ *    
+ * - create a new file $PJPROJECT/pjlib/include/pj/compat/m_alpha.h. + * Alternatively create a copy from other header file in this directory. + * The contents of this file will look something like: + *
+ *      #define PJ_HAS_PENTIUM          0
+ *      #define PJ_IS_LITTLE_ENDIAN     1
+ *      #define PJ_IS_BIG_ENDIAN        0
+ *    
+ * - edit pjlib/include/pj/config.h. Add new processor + * configuration in this header file, like follows: + *
+ *      ...
+ *      #elif defined (PJ_M_ALPHA) && PJ_M_ALPHA != 0
+ *      #   include 
+ *      ...
+ *    
+ * - done. Build PJLIB with: + *
+ *      $ cd $PJPROJECT/pjlib/build
+ *      $ make dep
+ *      $ make clean
+ *      $ make
+ *    
+ * + * @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 xos (for X OS). + * + * @subsection new_compat_os_h_file_sec Create New Compat Header File + * + * You'll need to create a new header file + * include/pj/compat/os_xos.h. 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 include/pj/config.h to include + * this file accordingly (e.g. when macro PJ_XOS is + * defined): + * + \verbatim + ... + #elif defined(PJ_XOS) + # include + #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. os-xos.mak in + * $PJPROJECT/build directory. + * + * At very minimum, the file will normally need to define + * PJ_XOS=1 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 os-xos.mak, + * but its located in pjlib/build 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: + * - os_core_xos.c: core OS specific + * functionality. + * - os_timestamp_xos.c: how to get timestamp + * in this OS. + * + * Depending on how things are done in your OS, you may need + * to create these files: + * - os_error_*.c: how to manipulate + * OS error codes. Alternatively you may use existing + * os_error_unix.c if the OS has \c errno and + * \c strerror() function. + * - ioqueue_*.c: if the OS has specific method + * to perform asynchronous I/O. Alternatively you may + * use existing ioqueue_select.c if the OS supports + * \c select() function call. + * - sock_*.c: if the OS has specific method + * to perform socket communication. Alternatively you may + * use existing sock_bsd.c if the OS supports + * BSD socket API, and edit include/pj/compat/socket.h + * file accordingly. + * + * You will also need to check various files in + * include/pj/compat/*.h, 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 *.c file, and give it #ifdef + * switch for the new OS, or + * - edit include/pj/compat/*.h 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 os_core_xxx.c will + * normally be different for each OS flavour. + * - if the difference can be localized in include/compat + * header file, and existing #ifdef switch is there, + * then preferably you should edit this include/compat + * header file. + * - if the existing *.c file has #ifdef switch, + * then you may add another #elif 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 + * + * 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 +#include +#include + +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 + * + * 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 +#include +#include + + +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 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 . 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 + +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 + * + * 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_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 + * + * 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_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 + * + * 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_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 + * + * 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_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 + * + * 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_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 + * + * 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_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: + * - select(), 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). + * - /dev/epoll 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). + * - I/O Completion ports 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 on the same key 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 differrent + * keys 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. + * - Care must be taken when unregistering a key from the + * ioqueue. Application must take care that when one thread is issuing + * an unregistration, other thread is not simultaneously invoking the + * callback to the same key. + *\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 + * + * 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_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 + * + * 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_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 + * + * 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 + * + * 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_BEGIN_DECL + +/** + * @defgroup PJ_LOCK Lock Objects + * @ingroup PJ_OS + * @{ + * + * Lock Objects 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 + * + * 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 +#include + +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: + * + *
+ *   ...
+ *   PJ_LOG(3, ("main.c", "Starting hello..."));
+ *   ...
+ *   PJ_LOG(3, ("main.c", "Hello world from process %d", pj_getpid()));
+ *   ...
+ * 
+ * + * 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 + * + * 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 +#include + +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 + * + * 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_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 MUST NOT 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 High Resolution Timestamp 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 + * + * 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 + +/* 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 +#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 30 times 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, cannot shrink! Since there is no + * 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 + + #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 + * + * 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 + * + * 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 + +/** + * @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 + + 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 + * + * 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_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 + * + * 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_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 + * + * 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_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 + * + * 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_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 + * + * 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_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 + * + * 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_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 +#include +#include + + +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 + * + * 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 +#include + + +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: + * + *
+ *   typedef struct pj_str_t
+ *   {
+ *       char      *ptr;
+ *       pj_size_t  slen;
+ *   } pj_str_t;
+ * 
+ * + * 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 +#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 + * + * 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_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 = ©1; + } + + if (len < (unsigned)str2->slen) { + copy2.ptr = str2->ptr; + copy2.slen = len; + str2 = ©2; + } + + 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, ©2, 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, ©2); +} + +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, ©2); +} + +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 = ©1; + } + + if (len < (unsigned)str2->slen) { + copy2.ptr = str2->ptr; + copy2.slen = len; + str2 = ©2; + } + + 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, ©2, 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_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 + * + * @{ + * + * \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 + * + * 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_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 + * + * 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 + + +/** + * @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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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 + * + * 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 +#include +#include +#include + + +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 + * + * 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 + +/** + * @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 + * + * 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 + + +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 + * + * 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 +#include + + +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 + + -# Configure the application's project settings.\n + Add the following + include: + \code + #include \endcode\n + And add pjmedia-audiodev library to your application link + specifications.\n + -# Compile time settings.\n + Use the compile time settings to enable or + disable specific audio drivers. For more information, please see + \ref s1_audio_device_config. + -# API initialization and cleaning up.\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 +#include + +/** + * @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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include + + +#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 + * + * 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 + * + * 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 + + +/* + * Include config_auto.h if autoconf is used (PJ_AUTOCONF is set) + */ +#if defined(PJ_AUTOCONF) +# include +#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 + * + * 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 + * + * 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 + +/** + * @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 + * + * 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 + +/** + * @defgroup PJMED_G7221_CODEC G722.1 Codec + * @ingroup PJMEDIA_CODEC_CODECS + * @brief Implementation of G722.1 codec + * @{ + * + * G722.1 licensed from Polycom® + * G722.1 Annex C licensed from Polycom® + * + * 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 + * + * 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 + +/** + * @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 + * + * 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 + +/** + * @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 + * + * 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 + +/** + * @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 + * + * 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 + + +/** + * @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 + * + * 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 + +/** + * @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 + * + * 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 + +/** + * @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 + * + * 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 + +/** + * @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 for list + * of static payload types. + */ +enum +{ + /* PJMEDIA_RTP_PT_TELEPHONE_EVENTS is declared in + * + */ +#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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 + +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 + * + * 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 + + +/** + * @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 + * + * 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 +#include +#include + +/** + * @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, ®1, ®1cnt, + ®2, ®2cnt); + 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, ®1, ®1cnt, + ®2, ®2cnt); + 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, ®1, ®1cnt, + ®2, ®2cnt); + 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, ®1, ®1cnt, + ®2, ®2cnt); + + /* 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 + * + * 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 + + +/** + * @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 asynchronously + * (the default behavior) or synchronously. When it is run + * asynchronously, it will call the application's callback every time + * the clock tick 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 + * + * 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 +#include + +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 open 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 setting 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 + ¶m); + + // 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, ¶m ); + + \endcode + * + * + * @subsection enc_dec_codec Encoding and Decoding Media Frames + * + * Application encodes and decodes media frames by calling + * encode and decode 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 recover + * member of the codec's "virtual" function table (#pjmedia_codec_op). + * + * If the codec's algorithm supports PLC, the recover 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 close 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 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 + * + * 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 + +/** + * @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 ); + + +/** + * Warning: This API has been deprecated since 1.3 and will be + * removed in the future release, use #PJMEDIA_SPLITCOMB instead. + * + * 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: output = input * (adj_level+128) / 128. 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: output = input * (adj_level+128) / 128. 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 + * + * 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 + +/** + * @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 +#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 + * + * 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 + * + * 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 + +/** + * @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 + * + * 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 Table of Contents 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 get_frame() and put_frame() 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 + * + * 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 + + + +/** + * @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 + * + * 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 + + + +/** + * @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 + * + * 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 +#include + + +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 + * + * 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 +#include + +/** + * @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 + * + * 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 + +/** + * @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 + * + * 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 + +/** + * @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 + * + * 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 + +/** + * @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 tick expires, a callback + * will be called, and the master port performs the following tasks: + * - it calls get_frame() from the downstream port, + * when give the frame to the upstream port by calling put_frame + * 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 + * + * 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 + +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 + * + * 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 + + + +/** + * @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 + * + * 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 + +/** + * @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 recover() 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 + * + * 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 +#include +#include + + +/** + @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 (get_frame() + interface), which will be called by #pjmedia_port_get_frame() + public API, and + - pointer to function to store frames to the port (put_frame() + 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 + * + * 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 +#include + +/** + * @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 + * + * 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 +#include +#include + +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 + * + * 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 +#include + + +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 + * + * 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 + + +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 + * + * 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 + + +/** + * @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 . 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 + * + * 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 contains the declaration + * of SDP offer and answer negotiator. SDP offer and answer model is described + * in RFC 3264 "An Offer/Answer Model with Session Description Protocol + * (SDP)". + * + * 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. + * + *
+ *                                              
+ *                                              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() +--------------+
+ *
+ * 
+ * + * + * + * \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 + +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 + * + * 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 +#include +#include + +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 + * + * 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 + + +/** + * @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 + * + * 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 +#include + + +PJ_BEGIN_DECL + +/** + * @defgroup PJMED_SND Portable Sound Hardware Abstraction + * @ingroup PJMED_SND_PORT + * @brief PJMEDIA abstraction for sound device hardware + * @{ + * + * 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. + * + * 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 asychronously, + * 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: + * - rec_cb callback to be called when it has finished + * capturing one media frame, and + * - play_cb 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 + * + * 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 +#include + +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 rec_cb callback when it has finished capturing + one media frame, and + - it calls play_cb 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 put_frame() + when rec_cb() is called (i.e. when the sound hardware + has finished capturing frame), and + - it will call downstream port's get_frame() when + play_cb() 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 + * + * 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 + + +/** + * @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 + * + * 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 +#include +#include +#include + + +/** + * @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 + * + * 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 +#include +#include +#include +#include +#include +#include + +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;/** + * + * 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 + +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 + * + * 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 + + +/** + * @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 + * + * 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 +#include + +/** + * @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 + +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 attach() 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 detach() 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 send_rtp() 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 send_rtcp() 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 send_rtcp2() 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 media_create() 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 encode_sdp() 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 media_start() 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 media_stop() 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 + * destroy() 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 + * + * 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 + + +/** + * @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 + * + * 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 +#include + + +/** + * @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 + * + * 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 + + +/** + * @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 + * + * 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 + + +/** + * @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 + * + * 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 + + +/** + * @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 + * + * 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 +#include /* pjmedia_sock_info */ +#include /* 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>= 1; + for (i=0; i>= 1; + for (i=0; i>= 1; + for (i=0; isubframe_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; isubframe_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 + * + * 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 + + + +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 + * + * 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 + + + +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 + * + * 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 + +/** + * @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 + * + * 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 + +/** + * @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 + * + * 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 +#include +#include + +#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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + 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 + * + * 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 + +/** + * @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< + * + * 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 + +/** + * @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 + * + * 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 +#include +#include +#include +#include + +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 within a + * single media stream (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 + * + * 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 +#include +#include +#include +#include +#include + + +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 + * + * 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 + + +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 + * + * 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 + + +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 + * + * 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 +#include +#include +#include + + +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 + * + * 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 +#include + + +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 + * + * 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 +#include +#include +#include +#include +#include + +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: + * + * - transport independent:\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. + * + * - authentication management:\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. + * + * - static or dynamic credential:\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. + * + * - client transaction management:\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. + * + * - server transaction management:\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: + * + * - create the object configuration:\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() + * + * - create the STUN session:\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. + * + * - configure credential:\n + * if authentication is required for the session, configure the + * credential with #pj_stun_session_set_credential() + * + * - configuring other settings:\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. + * + * - creating outgoing STUN requests or indications:\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. + * + * - sending outgoing message:\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. + * + * - handling incoming packet:\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. + * + * - handling incoming requests:\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. + * + * - creating and sending response:\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. + * + * - convenient way to send response:\n + * the #pj_stun_session_respond() is provided as a convenient way to + * create and send simple STUN responses, such as error responses. + * + * - destroying the session:\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 + * + * 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 +#include +#include +#include +#include + + +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 + * + * 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 +#include + + +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 + * + * 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 +#include + + +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: + + - Creating the session:\n + use #pj_turn_session_create() to create the session. + + - Configuring credential:\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. + + - Configuring server:\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. + + - Creating allocation:\n + create one "relay port" (or called relayed-transport-address + 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. + + - Getting the allocation result:\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(). + + - Sending data through the relay.\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. + + - Creating permissions.\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. + + - Receiving data from peers.\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. + + - Using ChannelData.\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. + + - Refreshing the allocation, permissions, and channel bindings.\n + Allocations, permissions, and channel bindings will be refreshed by the + session automatically when they about to expire. + + - Destroying the allocation.\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 + * + * 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 +#include + + +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 \ref samples_page 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 + * + * 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 +#include + +/** + * @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 + * + * 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 + +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 + * + * 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 + + +/** + * @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 + * + * 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 + +/** + * @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 + * + * 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 +#include + +/** + * @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 +#include + + +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 + * + * 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 +#include + +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 + * + * 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 +#include +#include +#include + + +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 + * + * 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 +#include + + +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 + * + * 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 +#include + +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 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 element + * to the first 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 + * + * 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 + + +#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 + * + * 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 +#include + +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 + * + * 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 + + +/** + * @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 mandate \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 mandate \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 does not 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 + * + * 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 +#include + + +/** + * @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 + * PJSIP Developer's Guide + * 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 pjsip-ua 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 pjsip-ua static library to use this API. + * + * More detailed information is explained in + * PJSIP Developer's Guide + * 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 + * + * 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 +#include +#include + + +/** + * @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 pjsip-ua 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;/**". 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 + * + * 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 + +/** + * @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: + * - RFC 3891: The Session + * Initiation Protocol (SIP) "Replaces" Header + * - \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 +#include + +/** + * @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: + * - RFC 4028: Session Timers + * in the Session Initiation Protocol (SIP) + */ + +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 + * + * 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 +#include + +/** + * @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 pjsip-ua AND pjsip-simple static libraries + * to use REFER functionality. + * + * Reference: + * - RFC 3515: The Session + * Initiation Protocol (SIP) Refer Method + * - @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 + * + * 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 +#include + +/* Messaging and parsing. */ +#include +#include +#include +#include + +/* Core */ +#include +#include +#include +#include + +/* Transport layer */ +#include +#include +#include +#include +#include +#include + +/* Authentication. */ +#include +#include + +/* Transaction layer. */ +#include + +/* UA Layer. */ +#include +#include + + +#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 + * + * 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 + * + * 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 +#include + +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 + * + * 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 + +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 config_site.h to enable AKA support: + * + @code + #define PJSIP_HAS_DIGEST_AKA_AUTH 1 + @endcode + + * + * In addition, application would need to link with libmilenage + * 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 + * + * 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 + +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 + * + * 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_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 + * + * 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 + * + * 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 + +/** + * @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 +#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 + + +#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 + * + * 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 +#include +#include +#include +#include +#include +#include + + +/** + * @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 From header, To header, CSeq + * sequencing, Call-ID header, Contact header management, + * dialog route-set management, and common authentication. + * This basic dialog functionality will be shared by all dialog + * usages of a particular dialog. + * + * More detailed information is explained in + * PJSIP Developer's Guide + * 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 pjsip-core 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 + * + * 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 +#include + +/** + * @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 + * + * 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_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 + * + * 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 + + +/** + * 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 + * + * 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 +#include + +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 PJSIP Developer's Guide + * 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 + * + * 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 +#include +#include + +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 + * + * 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 +#include +#include + +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 + * + * 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 + + +#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 + * + * 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 +#include +#include + +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 + * + * 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 + +/** + * @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 + * + * 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 +#include +#include +#include + +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 pjsip-core 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 + * + * 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 +#include +#include +#include +#include +#include +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJSIP_TRANSPORT Transport + * @ingroup PJSIP_CORE + * @brief This is the transport framework. + * + * The transport framework is fully extensible. Please see + * PJSIP Developer's Guide 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 + * + * 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 + +/** + * @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 + * + * 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 +#include + + +/* 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 + * + * 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 +#include +#include + + +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 + * + * 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 + +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 + * + * 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 +#include + +/** + * @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 + * + * 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 + + +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 pjsip-core + * 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 pjsip-core 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 + * + * 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 +#include +#include +#include + +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 + * + * 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 +#include +#include + +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 + * + * 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 +#include +#include + +#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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 +#include +#include +#include +#include +#include + + +#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 + * + * 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 + +/* Include all PJMEDIA headers. */ +#include + +/* Include all PJMEDIA-CODEC headers. */ +#include + +/* Include all PJSIP-UA headers */ +#include + +/* Include all PJSIP-SIMPLE headers */ +#include + +/* Include all PJNATH headers */ +#include + +/* Include all PJLIB-UTIL headers. */ +#include + +/* Include all PJLIB headers. */ +#include + + +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 pjsua-lib to use this API. In addition, + * this library depends on the following libraries: + * - pjsip-ua, + * - pjsip-simple, + * - pjsip-core, + * - pjmedia, + * - pjmedia-codec, + * - pjlib-util, and + * - pjlib, + * + * so application must also link with these libraries as well. For more + * information, please refer to + * Getting Started with PJSIP + * 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 + + #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 From + * header in outgoing requests. + * + * PJSUA-API supports creating and managing multiple accounts. The maximum + * number of accounts is limited by a compile time constant + * PJSUA_MAX_ACC. + * + * Account may or may not have client registration associated with it. + * An account is also associated with route set and some authentication + * credentials, which are used when sending SIP request messages using the + * account. An account also has presence's online status, 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 default account, 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 unidirectional + * 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 + * + * 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; /**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__ */ + -- cgit v1.2.3