From dcfc0bab7a702ca541bad67c1d216cf9f1816fd7 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sun, 30 Sep 2007 16:50:27 +0000 Subject: [PATCH] Ticket #385: Support for reliable provisional response (100rel, PRACK) git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1463 74dad513-b988-da41-8d7b-12977e46ad98 --- build.symbian/bld.inf | 4 +- build.symbian/makedef.sh | 19 +- build.symbian/pjsipU.def | 65 +- build.symbian/pjsip_ua.mmp | 1 + build.symbian/pjsip_uaU.def | 93 ++- pjsip-apps/src/pjsua/pjsua_app.c | 9 +- pjsip/build/Makefile | 3 +- pjsip/build/pjsip_ua.dsp | 10 + pjsip/build/pjsip_ua.vcproj | 8 + pjsip/build/wince-evc4/pjsip_ua_wince.vcp | 961 ++++++++++++++++++++++ pjsip/include/pjsip-ua/sip_100rel.h | 176 ++++ pjsip/include/pjsip-ua/sip_inv.h | 1 + pjsip/include/pjsip/sip_config.h | 11 + pjsip/include/pjsip/sip_transaction.h | 20 +- pjsip/include/pjsip_ua.h | 1 + pjsip/include/pjsua-lib/pjsua.h | 17 + pjsip/src/pjsip-ua/sip_100rel.c | 833 +++++++++++++++++++ pjsip/src/pjsip-ua/sip_inv.c | 94 ++- pjsip/src/pjsip/sip_transaction.c | 27 + pjsip/src/pjsua-lib/pjsua_call.c | 32 +- pjsip/src/pjsua-lib/pjsua_core.c | 6 + 21 files changed, 2288 insertions(+), 103 deletions(-) create mode 100644 pjsip/include/pjsip-ua/sip_100rel.h create mode 100644 pjsip/src/pjsip-ua/sip_100rel.c diff --git a/build.symbian/bld.inf b/build.symbian/bld.inf index 951468850..5cf4bf04f 100644 --- a/build.symbian/bld.inf +++ b/build.symbian/bld.inf @@ -9,10 +9,10 @@ pjlib.mmp pjlib_util.mmp pjnath.mmp pjsdp.mmp +null_audio.mmp +symbian_ua.mmp pjmedia.mmp pjsip.mmp pjsip_simple.mmp pjsip_ua.mmp pjsua_lib.mmp -null_audio.mmp -symbian_ua.mmp diff --git a/build.symbian/makedef.sh b/build.symbian/makedef.sh index 67629c61b..df90992d8 100644 --- a/build.symbian/makedef.sh +++ b/build.symbian/makedef.sh @@ -2,10 +2,26 @@ MMP=$1 if test "$MMP" == ""; then - echo Usage: makedef.sh FILE.MMP + echo "Usage: makedef.sh FILE.MMP" + echo " or makedef.sh all" exit 1 fi +if test "$MMP" == "all"; then + . $0 pjlib.mmp + . $0 pjlib_util.mmp + . $0 pjnath.mmp + . $0 pjmedia.mmp + . $0 pjsdp.mmp + . $0 pjsip.mmp + . $0 pjsip_simple.mmp + . $0 pjsip_ua.mmp + . $0 pjsua_lib.mmp + . $0 symbian_audio.mmp + . $0 null_audio.mmp + exit 0 +fi + if test -f $MMP; then true else @@ -32,6 +48,7 @@ done echo > tmpnames.def +echo "${TARGET}:" for file in $SOURCES; do #SYMBOLS=`grep PJ_DEF ${SOURCEPATH}/$file | awk -F ')' '{print $2}' | awk -F '(' '{print $1}' | awk -F '=' '{print $1}' | tr -d '[:blank:]' | sort | uniq` diff --git a/build.symbian/pjsipU.def b/build.symbian/pjsipU.def index 57b0ecab5..df6efcc38 100644 --- a/build.symbian/pjsipU.def +++ b/build.symbian/pjsipU.def @@ -235,35 +235,36 @@ EXPORTS pjsip_tsx_layer_init_module @ 234 NONAME pjsip_tsx_layer_instance @ 235 NONAME pjsip_tsx_recv_msg @ 236 NONAME - pjsip_tsx_send_msg @ 237 NONAME - pjsip_tsx_set_transport @ 238 NONAME - pjsip_tsx_state_str @ 239 NONAME - pjsip_tsx_stop_retransmit @ 240 NONAME - pjsip_tsx_terminate @ 241 NONAME - pjsip_tx_data_add_ref @ 242 NONAME - pjsip_tx_data_create @ 243 NONAME - pjsip_tx_data_dec_ref @ 244 NONAME - pjsip_tx_data_get_info @ 245 NONAME - pjsip_tx_data_invalidate_msg @ 246 NONAME - pjsip_tx_data_is_valid @ 247 NONAME - pjsip_tx_data_set_transport @ 248 NONAME - pjsip_ua_destroy @ 249 NONAME - pjsip_ua_dump @ 250 NONAME - pjsip_ua_find_dialog @ 251 NONAME - pjsip_ua_get_endpt @ 252 NONAME - pjsip_ua_init_module @ 253 NONAME - pjsip_ua_instance @ 254 NONAME - pjsip_ua_register_dlg @ 255 NONAME - pjsip_ua_unregister_dlg @ 256 NONAME - pjsip_udp_transport_attach @ 257 NONAME - pjsip_udp_transport_get_socket @ 258 NONAME - pjsip_udp_transport_pause @ 259 NONAME - pjsip_udp_transport_restart @ 260 NONAME - pjsip_udp_transport_start @ 261 NONAME - pjsip_unsupported_hdr_create @ 262 NONAME - pjsip_unsupported_hdr_init @ 263 NONAME - pjsip_via_hdr_create @ 264 NONAME - pjsip_via_hdr_init @ 265 NONAME - pjsip_warning_hdr_create @ 266 NONAME - pjsip_warning_hdr_create_from_status @ 267 NONAME - pjsip_www_authenticate_hdr_create @ 268 NONAME + pjsip_tsx_retransmit_no_state @ 237 NONAME + pjsip_tsx_send_msg @ 238 NONAME + pjsip_tsx_set_transport @ 239 NONAME + pjsip_tsx_state_str @ 240 NONAME + pjsip_tsx_stop_retransmit @ 241 NONAME + pjsip_tsx_terminate @ 242 NONAME + pjsip_tx_data_add_ref @ 243 NONAME + pjsip_tx_data_create @ 244 NONAME + pjsip_tx_data_dec_ref @ 245 NONAME + pjsip_tx_data_get_info @ 246 NONAME + pjsip_tx_data_invalidate_msg @ 247 NONAME + pjsip_tx_data_is_valid @ 248 NONAME + pjsip_tx_data_set_transport @ 249 NONAME + pjsip_ua_destroy @ 250 NONAME + pjsip_ua_dump @ 251 NONAME + pjsip_ua_find_dialog @ 252 NONAME + pjsip_ua_get_endpt @ 253 NONAME + pjsip_ua_init_module @ 254 NONAME + pjsip_ua_instance @ 255 NONAME + pjsip_ua_register_dlg @ 256 NONAME + pjsip_ua_unregister_dlg @ 257 NONAME + pjsip_udp_transport_attach @ 258 NONAME + pjsip_udp_transport_get_socket @ 259 NONAME + pjsip_udp_transport_pause @ 260 NONAME + pjsip_udp_transport_restart @ 261 NONAME + pjsip_udp_transport_start @ 262 NONAME + pjsip_unsupported_hdr_create @ 263 NONAME + pjsip_unsupported_hdr_init @ 264 NONAME + pjsip_via_hdr_create @ 265 NONAME + pjsip_via_hdr_init @ 266 NONAME + pjsip_warning_hdr_create @ 267 NONAME + pjsip_warning_hdr_create_from_status @ 268 NONAME + pjsip_www_authenticate_hdr_create @ 269 NONAME diff --git a/build.symbian/pjsip_ua.mmp b/build.symbian/pjsip_ua.mmp index 3dde4c571..6542c7677 100644 --- a/build.symbian/pjsip_ua.mmp +++ b/build.symbian/pjsip_ua.mmp @@ -35,6 +35,7 @@ SOURCE sip_inv.c SOURCE sip_reg.c SOURCE sip_replaces.c SOURCE sip_xfer.c +SOURCE sip_100rel.c SYSTEMINCLUDE ..\pjlib\include SYSTEMINCLUDE ..\pjlib-util\include diff --git a/build.symbian/pjsip_uaU.def b/build.symbian/pjsip_uaU.def index 9b7edcc86..b158bf92a 100644 --- a/build.symbian/pjsip_uaU.def +++ b/build.symbian/pjsip_uaU.def @@ -1,46 +1,49 @@ EXPORTS - pjsip_create_sdp_body @ 1 NONAME - pjsip_dlg_get_inv_session @ 2 NONAME - pjsip_get_refer_method @ 3 NONAME - pjsip_inv_answer @ 4 NONAME - pjsip_inv_create_uac @ 5 NONAME - pjsip_inv_create_uas @ 6 NONAME - pjsip_inv_end_session @ 7 NONAME - pjsip_inv_initial_answer @ 8 NONAME - pjsip_inv_invite @ 9 NONAME - pjsip_inv_reinvite @ 10 NONAME - pjsip_inv_send_msg @ 11 NONAME - pjsip_inv_set_sdp_answer @ 12 NONAME - pjsip_inv_state_name @ 13 NONAME - pjsip_inv_terminate @ 14 NONAME - pjsip_inv_update @ 15 NONAME - pjsip_inv_usage_init @ 16 NONAME - pjsip_inv_usage_instance @ 17 NONAME - pjsip_inv_verify_request @ 18 NONAME - pjsip_refer_method @ 19 NONAME - pjsip_regc_add_headers @ 20 NONAME - pjsip_regc_create @ 21 NONAME - pjsip_regc_destroy @ 22 NONAME - pjsip_regc_get_info @ 23 NONAME - pjsip_regc_get_pool @ 24 NONAME - pjsip_regc_init @ 25 NONAME - pjsip_regc_register @ 26 NONAME - pjsip_regc_send @ 27 NONAME - pjsip_regc_set_credentials @ 28 NONAME - pjsip_regc_set_route_set @ 29 NONAME - pjsip_regc_set_transport @ 30 NONAME - pjsip_regc_unregister @ 31 NONAME - pjsip_regc_unregister_all @ 32 NONAME - pjsip_regc_update_contact @ 33 NONAME - pjsip_regc_update_expires @ 34 NONAME - pjsip_replaces_hdr_create @ 35 NONAME - pjsip_replaces_init_module @ 36 NONAME - pjsip_replaces_verify_request @ 37 NONAME - pjsip_xfer_accept @ 38 NONAME - pjsip_xfer_create_uac @ 39 NONAME - pjsip_xfer_create_uas @ 40 NONAME - pjsip_xfer_current_notify @ 41 NONAME - pjsip_xfer_init_module @ 42 NONAME - pjsip_xfer_initiate @ 43 NONAME - pjsip_xfer_notify @ 44 NONAME - pjsip_xfer_send_request @ 45 NONAME + pjsip_100rel_attach @ 1 NONAME + pjsip_100rel_init_module @ 2 NONAME + pjsip_100rel_tx_response @ 3 NONAME + pjsip_create_sdp_body @ 4 NONAME + pjsip_dlg_get_inv_session @ 5 NONAME + pjsip_get_refer_method @ 6 NONAME + pjsip_inv_answer @ 7 NONAME + pjsip_inv_create_uac @ 8 NONAME + pjsip_inv_create_uas @ 9 NONAME + pjsip_inv_end_session @ 10 NONAME + pjsip_inv_initial_answer @ 11 NONAME + pjsip_inv_invite @ 12 NONAME + pjsip_inv_reinvite @ 13 NONAME + pjsip_inv_send_msg @ 14 NONAME + pjsip_inv_set_sdp_answer @ 15 NONAME + pjsip_inv_state_name @ 16 NONAME + pjsip_inv_terminate @ 17 NONAME + pjsip_inv_update @ 18 NONAME + pjsip_inv_usage_init @ 19 NONAME + pjsip_inv_usage_instance @ 20 NONAME + pjsip_inv_verify_request @ 21 NONAME + pjsip_refer_method @ 22 NONAME + pjsip_regc_add_headers @ 23 NONAME + pjsip_regc_create @ 24 NONAME + pjsip_regc_destroy @ 25 NONAME + pjsip_regc_get_info @ 26 NONAME + pjsip_regc_get_pool @ 27 NONAME + pjsip_regc_init @ 28 NONAME + pjsip_regc_register @ 29 NONAME + pjsip_regc_send @ 30 NONAME + pjsip_regc_set_credentials @ 31 NONAME + pjsip_regc_set_route_set @ 32 NONAME + pjsip_regc_set_transport @ 33 NONAME + pjsip_regc_unregister @ 34 NONAME + pjsip_regc_unregister_all @ 35 NONAME + pjsip_regc_update_contact @ 36 NONAME + pjsip_regc_update_expires @ 37 NONAME + pjsip_replaces_hdr_create @ 38 NONAME + pjsip_replaces_init_module @ 39 NONAME + pjsip_replaces_verify_request @ 40 NONAME + pjsip_xfer_accept @ 41 NONAME + pjsip_xfer_create_uac @ 42 NONAME + pjsip_xfer_create_uas @ 43 NONAME + pjsip_xfer_current_notify @ 44 NONAME + pjsip_xfer_init_module @ 45 NONAME + pjsip_xfer_initiate @ 46 NONAME + pjsip_xfer_notify @ 47 NONAME + pjsip_xfer_send_request @ 48 NONAME diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c index 13f1dbd2e..f0380fd54 100644 --- a/pjsip-apps/src/pjsua/pjsua_app.c +++ b/pjsip-apps/src/pjsua/pjsua_app.c @@ -127,6 +127,7 @@ static void usage(void) puts (" --username=string Set authentication username"); puts (" --password=string Set authentication password"); puts (" --publish Send presence PUBLISH for this account"); + puts (" --use-100rel Require reliable provisional response (100rel)"); puts (" --next-cred Add another credentials"); puts (""); puts ("SIP Account Control:"); @@ -370,7 +371,7 @@ static pj_status_t parse_args(int argc, char *argv[], OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO, OPT_LOCAL_PORT, OPT_IP_ADDR, OPT_PROXY, OPT_OUTBOUND_PROXY, OPT_REGISTRAR, OPT_REG_TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT, - OPT_REALM, OPT_USERNAME, OPT_PASSWORD, + OPT_100REL, OPT_REALM, OPT_USERNAME, OPT_PASSWORD, OPT_NAMESERVER, OPT_STUN_DOMAIN, OPT_STUN_SRV, OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE, OPT_AUTO_ANSWER, OPT_AUTO_HANGUP, OPT_AUTO_PLAY, OPT_AUTO_LOOP, @@ -406,6 +407,7 @@ static pj_status_t parse_args(int argc, char *argv[], { "registrar", 1, 0, OPT_REGISTRAR}, { "reg-timeout",1, 0, OPT_REG_TIMEOUT}, { "publish", 0, 0, OPT_PUBLISH}, + { "use-100rel", 0, 0, OPT_100REL}, { "id", 1, 0, OPT_ID}, { "contact", 1, 0, OPT_CONTACT}, { "realm", 1, 0, OPT_REALM}, @@ -627,6 +629,11 @@ static pj_status_t parse_args(int argc, char *argv[], cur_acc->publish_enabled = PJ_TRUE; break; + case OPT_100REL: /** 100rel */ + cur_acc->require_100rel = PJ_TRUE; + cfg->cfg.require_100rel = PJ_TRUE; + break; + case OPT_ID: /* id */ if (pjsua_verify_sip_url(pj_optarg) != 0) { PJ_LOG(1,(THIS_FILE, diff --git a/pjsip/build/Makefile b/pjsip/build/Makefile index 849b2c379..a9c363b80 100644 --- a/pjsip/build/Makefile +++ b/pjsip/build/Makefile @@ -51,7 +51,8 @@ export PJSIP_CFLAGS += $(_CFLAGS) # export PJSIP_UA_SRCDIR = ../src/pjsip-ua export PJSIP_UA_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ - sip_inv.o sip_reg.o sip_replaces.o sip_xfer.o + sip_inv.o sip_reg.o sip_replaces.o sip_xfer.o \ + sip_100rel.o export PJSIP_UA_CFLAGS += $(_CFLAGS) diff --git a/pjsip/build/pjsip_ua.dsp b/pjsip/build/pjsip_ua.dsp index 17ccddf3a..4b6874a38 100644 --- a/pjsip/build/pjsip_ua.dsp +++ b/pjsip/build/pjsip_ua.dsp @@ -40,6 +40,7 @@ RSC=rc.exe # PROP Output_Dir ".\output\pjsip-ua-i386-win32-vc6-release" # PROP Intermediate_Dir ".\output\pjsip-ua-i386-win32-vc6-release" # PROP Target_Dir "" +F90=df.exe # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MD /W4 /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /D "NDEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /FR /FD /c # SUBTRACT CPP /YX @@ -64,6 +65,7 @@ LIB32=link.exe -lib # PROP Output_Dir ".\output\pjsip-ua-i386-win32-vc6-debug" # PROP Intermediate_Dir ".\output\pjsip-ua-i386-win32-vc6-debug" # PROP Target_Dir "" +F90=df.exe # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /D "_DEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /FR /FD /GZ /c # SUBTRACT CPP /YX @@ -87,6 +89,10 @@ LIB32=link.exe -lib # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE="..\src\pjsip-ua\sip_100rel.c" +# End Source File +# Begin Source File + SOURCE="..\src\pjsip-ua\sip_inv.c" # End Source File # Begin Source File @@ -111,6 +117,10 @@ SOURCE=..\include\pjsip_ua.h # End Source File # Begin Source File +SOURCE="..\include\pjsip-ua\sip_100rel.h" +# End Source File +# Begin Source File + SOURCE="..\include\pjsip-ua\sip_inv.h" # End Source File # Begin Source File diff --git a/pjsip/build/pjsip_ua.vcproj b/pjsip/build/pjsip_ua.vcproj index f3a1ea695..d24e0b49d 100644 --- a/pjsip/build/pjsip_ua.vcproj +++ b/pjsip/build/pjsip_ua.vcproj @@ -174,6 +174,10 @@ Name="Source Files" Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" > + + @@ -271,6 +275,10 @@ RelativePath="..\include\pjsip_ua.h" > + + diff --git a/pjsip/build/wince-evc4/pjsip_ua_wince.vcp b/pjsip/build/wince-evc4/pjsip_ua_wince.vcp index 109224232..32b792e2d 100644 --- a/pjsip/build/wince-evc4/pjsip_ua_wince.vcp +++ b/pjsip/build/wince-evc4/pjsip_ua_wince.vcp @@ -318,6 +318,963 @@ BSC32=bscmake.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE="..\..\src\pjsip-ua\sip_100rel.c" + +!IF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE emulator) Release" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ELSEIF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE emulator) Debug" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ELSEIF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE ARMV4I) Release" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ELSEIF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE ARMV4I) Debug" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ELSEIF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE ARMV4) Release" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ELSEIF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE ARMV4) Debug" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ELSEIF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE ARMV4T) Release" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ELSEIF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE ARMV4T) Debug" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ELSEIF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE x86) Release" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ELSEIF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE x86) Debug" + +DEP_CPP_SIP_1=\ + "..\..\..\pjlib-util\include\pjlib-util\config.h"\ + "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ + "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_bitwise.h"\ + "..\..\..\pjlib-util\include\pjlib-util\scanner_cis_uint.h"\ + "..\..\..\pjlib-util\include\pjlib-util\types.h"\ + "..\..\..\pjlib\include\pj\addr_resolv.h"\ + "..\..\..\pjlib\include\pj\array.h"\ + "..\..\..\pjlib\include\pj\assert.h"\ + "..\..\..\pjlib\include\pj\compat\assert.h"\ + "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ + "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ + "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ + "..\..\..\pjlib\include\pj\compat\ctype.h"\ + "..\..\..\pjlib\include\pj\compat\errno.h"\ + "..\..\..\pjlib\include\pj\compat\high_precision.h"\ + "..\..\..\pjlib\include\pj\compat\m_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_auto.h"\ + "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux.h"\ + "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ + "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ + "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ + "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ + "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32.h"\ + "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ + "..\..\..\pjlib\include\pj\compat\setjmp.h"\ + "..\..\..\pjlib\include\pj\compat\size_t.h"\ + "..\..\..\pjlib\include\pj\compat\stdarg.h"\ + "..\..\..\pjlib\include\pj\compat\string.h"\ + "..\..\..\pjlib\include\pj\config.h"\ + "..\..\..\pjlib\include\pj\config_site.h"\ + "..\..\..\pjlib\include\pj\ctype.h"\ + "..\..\..\pjlib\include\pj\errno.h"\ + "..\..\..\pjlib\include\pj\except.h"\ + "..\..\..\pjlib\include\pj\fifobuf.h"\ + "..\..\..\pjlib\include\pj\file_access.h"\ + "..\..\..\pjlib\include\pj\file_io.h"\ + "..\..\..\pjlib\include\pj\guid.h"\ + "..\..\..\pjlib\include\pj\hash.h"\ + "..\..\..\pjlib\include\pj\ioqueue.h"\ + "..\..\..\pjlib\include\pj\ip_helper.h"\ + "..\..\..\pjlib\include\pj\list.h"\ + "..\..\..\pjlib\include\pj\list_i.h"\ + "..\..\..\pjlib\include\pj\lock.h"\ + "..\..\..\pjlib\include\pj\log.h"\ + "..\..\..\pjlib\include\pj\os.h"\ + "..\..\..\pjlib\include\pj\pool.h"\ + "..\..\..\pjlib\include\pj\pool_alt.h"\ + "..\..\..\pjlib\include\pj\pool_buf.h"\ + "..\..\..\pjlib\include\pj\pool_i.h"\ + "..\..\..\pjlib\include\pj\rand.h"\ + "..\..\..\pjlib\include\pj\rbtree.h"\ + "..\..\..\pjlib\include\pj\sock.h"\ + "..\..\..\pjlib\include\pj\sock_select.h"\ + "..\..\..\pjlib\include\pj\string.h"\ + "..\..\..\pjlib\include\pj\string_i.h"\ + "..\..\..\pjlib\include\pj\timer.h"\ + "..\..\..\pjlib\include\pj\types.h"\ + "..\..\..\pjlib\include\pj\unicode.h"\ + "..\..\..\pjlib\include\pjlib.h"\ + "..\..\..\pjmedia\include\pjmedia\config.h"\ + "..\..\..\pjmedia\include\pjmedia\config_auto.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp.h"\ + "..\..\..\pjmedia\include\pjmedia\sdp_neg.h"\ + "..\..\..\pjmedia\include\pjmedia\types.h"\ + "..\..\include\pjsip-ua\sip_100rel.h"\ + "..\..\include\pjsip-ua\sip_inv.h"\ + "..\..\include\pjsip\sip_auth.h"\ + "..\..\include\pjsip\sip_auth_msg.h"\ + "..\..\include\pjsip\sip_autoconf.h"\ + "..\..\include\pjsip\sip_config.h"\ + "..\..\include\pjsip\sip_dialog.h"\ + "..\..\include\pjsip\sip_endpoint.h"\ + "..\..\include\pjsip\sip_errno.h"\ + "..\..\include\pjsip\sip_event.h"\ + "..\..\include\pjsip\sip_module.h"\ + "..\..\include\pjsip\sip_msg.h"\ + "..\..\include\pjsip\sip_parser.h"\ + "..\..\include\pjsip\sip_resolve.h"\ + "..\..\include\pjsip\sip_transaction.h"\ + "..\..\include\pjsip\sip_transport.h"\ + "..\..\include\pjsip\sip_types.h"\ + "..\..\include\pjsip\sip_uri.h"\ + "..\..\include\pjsip\sip_util.h"\ + + +!ENDIF + +# End Source File +# Begin Source File + SOURCE="..\..\src\pjsip-ua\sip_inv.c" !IF "$(CFG)" == "pjsip_ua_wince - Win32 (WCE emulator) Release" @@ -3153,6 +4110,10 @@ SOURCE=..\..\include\pjsip_ua.h # End Source File # Begin Source File +SOURCE="..\..\include\pjsip-ua\sip_100rel.h" +# End Source File +# Begin Source File + SOURCE="..\..\include\pjsip-ua\sip_inv.h" # End Source File # Begin Source File diff --git a/pjsip/include/pjsip-ua/sip_100rel.h b/pjsip/include/pjsip-ua/sip_100rel.h new file mode 100644 index 000000000..fc9e27bc7 --- /dev/null +++ b/pjsip/include/pjsip-ua/sip_100rel.h @@ -0,0 +1,176 @@ +/* $Id$ */ +/* + * Copyright (C) 2003-2007 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 + * + * \a PRACK and \a 100rel extension support is built into the library when + * #PJSIP_HAS_100REL macro is enabled. The default is yes. Application can + * set this macro to zero if it does not wish to support reliable provisional + * response extension. + * + * Application must also 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 (with #PJSIP_HAS_100REL macro). + * 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; + +#if PJSIP_HAS_100REL + options |= PJSIP_INV_SUPPORT_100REL; +#endif + + 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 + +/** + * 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); + +/** + * 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); + + +PJ_END_DECL + +/** + * @} + */ + + +#endif /* __SIP_100REL_H__ */ diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h index e74abfac0..f04f4aedc 100644 --- a/pjsip/include/pjsip-ua/sip_inv.h +++ b/pjsip/include/pjsip-ua/sip_inv.h @@ -252,6 +252,7 @@ struct pjsip_inv_session unsigned options; /**< Options in use. */ pjmedia_sdp_neg *neg; /**< Negotiator. */ pjsip_transaction *invite_tsx; /**< 1st invite tsx. */ + pjsip_tx_data *last_answer; /**< Last INVITE resp. */ void *mod_data[PJSIP_MAX_MODULE];/**< Modules data. */ }; diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h index 846c2a57b..3ad94c29e 100644 --- a/pjsip/include/pjsip/sip_config.h +++ b/pjsip/include/pjsip/sip_config.h @@ -64,6 +64,17 @@ #endif +/** + * Specify whether support for reliable provisional response (100rel, PRACK) + * should be built in the library. + * + * Default: 1 + */ +#ifndef PJSIP_HAS_100REL +# define PJSIP_HAS_100REL 1 +#endif + + /** * Specify maximum transaction count in transaction hash table. * Default value is 16*1024 diff --git a/pjsip/include/pjsip/sip_transaction.h b/pjsip/include/pjsip/sip_transaction.h index 657e82ac7..f47005e3c 100644 --- a/pjsip/include/pjsip/sip_transaction.h +++ b/pjsip/include/pjsip/sip_transaction.h @@ -93,7 +93,7 @@ struct pjsip_transaction char obj_name[PJ_MAX_OBJ_NAME]; /**< Log info. */ pjsip_role_e role; /**< Role (UAS or UAC) */ pjsip_method method; /**< The method. */ - int cseq; /**< The CSeq */ + 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. */ @@ -267,6 +267,24 @@ 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. diff --git a/pjsip/include/pjsip_ua.h b/pjsip/include/pjsip_ua.h index ccb65b5b6..160f685ec 100644 --- a/pjsip/include/pjsip_ua.h +++ b/pjsip/include/pjsip_ua.h @@ -23,6 +23,7 @@ #include #include #include +#include #endif /* __PJSIP_UA_H__ */ diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 870ea8d51..4422b0ea5 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -960,6 +960,15 @@ typedef struct pjsua_config */ pj_str_t stun_relay_host; + /** + * 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; + /** * Number of credentials in the credential array. */ @@ -1782,6 +1791,14 @@ typedef struct pjsua_acc_config */ pj_str_t force_contact; + /** + * 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; + /** * Number of proxies in the proxy array below. * diff --git a/pjsip/src/pjsip-ua/sip_100rel.c b/pjsip/src/pjsip-ua/sip_100rel.c new file mode 100644 index 000000000..778d5f1ec --- /dev/null +++ b/pjsip/src/pjsip-ua/sip_100rel.c @@ -0,0 +1,833 @@ +/* $Id$ */ +/* + * Copyright (C) 2003-2007 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 + +#if defined(PJSIP_HAS_100REL) && PJSIP_HAS_100REL!=0 + +#define THIS_FILE "sip_100rel.c" + +typedef struct dlg_data dlg_data; + +/* + * Static prototypes. + */ +static pj_status_t mod_100rel_load(pjsip_endpoint *endpt); +static void mod_100rel_on_tsx_state(pjsip_transaction*, pjsip_event*); + +static void handle_incoming_prack(dlg_data *dd, pjsip_transaction *tsx, + pjsip_event *e); +static void handle_incoming_response(dlg_data *dd, pjsip_transaction *tsx, + pjsip_event *e); +static void on_retransmit(pj_timer_heap_t *timer_heap, + struct pj_timer_entry *entry); + + +/* PRACK method */ +const pjsip_method pjsip_prack_method = +{ + PJSIP_OTHER_METHOD, + { "PRACK", 5 } +}; + +const pj_str_t tag_100rel = { "100rel", 6 }; +const pj_str_t RSEQ = { "RSeq", 4 }; +const pj_str_t RACK = { "RAck", 4 }; + + +/* 100rel module */ +static struct mod_100rel +{ + pjsip_module mod; + pjsip_endpoint *endpt; +} mod_100rel = +{ + { + NULL, NULL, /* prev, next. */ + { "mod-100rel", 10 }, /* Name. */ + -1, /* Id */ + PJSIP_MOD_PRIORITY_DIALOG_USAGE, /* Priority */ + &mod_100rel_load, /* load() */ + NULL, /* start() */ + NULL, /* stop() */ + NULL, /* unload() */ + NULL, /* on_rx_request() */ + NULL, /* on_rx_response() */ + NULL, /* on_tx_request. */ + NULL, /* on_tx_response() */ + &mod_100rel_on_tsx_state, /* on_tsx_state() */ + } + +}; + +/* List of pending transmission (may include the final response as well) */ +typedef struct tx_data_list +{ + PJ_DECL_LIST_MEMBER(struct tx_data_list); + pj_uint32_t rseq; + pjsip_tx_data *tdata; +} tx_data_list; + + +/* Below, UAS and UAC roles are of the INVITE transaction */ + +/* UAS state. */ +typedef struct uas_state +{ + pj_int32_t cseq; + pj_uint32_t rseq; /* Initialized to -1 */ + pj_bool_t has_sdp; + tx_data_list tx_data_list; + unsigned retransmit_count; + pj_timer_entry retransmit_timer; +} uas_state; + + +/* UAC state */ +typedef struct uac_state +{ + pj_int32_t cseq; + pj_uint32_t rseq; /* Initialized to -1 */ +} uac_state; + + +/* State attached to each dialog. */ +struct dlg_data +{ + pjsip_inv_session *inv; + uas_state *uas_state; + uac_state *uac_state; +}; + + +/***************************************************************************** + ** + ** Module + ** + ***************************************************************************** + */ +static pj_status_t mod_100rel_load(pjsip_endpoint *endpt) +{ + mod_100rel.endpt = endpt; + pjsip_endpt_add_capability(endpt, &mod_100rel.mod, + PJSIP_H_ALLOW, NULL, + 1, &pjsip_prack_method.name); + pjsip_endpt_add_capability(endpt, &mod_100rel.mod, + PJSIP_H_SUPPORTED, NULL, + 1, &tag_100rel); + + return PJ_SUCCESS; +} + +static pjsip_require_hdr *find_req_hdr(pjsip_msg *msg) +{ + pjsip_require_hdr *hreq; + + hreq = (pjsip_require_hdr*) + pjsip_msg_find_hdr(msg, PJSIP_H_REQUIRE, NULL); + + while (hreq) { + unsigned i; + for (i=0; icount; ++i) { + if (!pj_stricmp(&hreq->values[i], &tag_100rel)) { + return hreq; + } + } + + if ((void*)hreq->next == (void*)&msg->hdr) + return NULL; + + hreq = (pjsip_require_hdr*) + pjsip_msg_find_hdr(msg, PJSIP_H_REQUIRE, hreq->next); + + } + + return NULL; +} + +static void mod_100rel_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) +{ + pjsip_dialog *dlg; + dlg_data *dd; + + dlg = pjsip_tsx_get_dlg(tsx); + if (!dlg) + return; + + dd = (dlg_data*) dlg->mod_data[mod_100rel.mod.id]; + if (!dd) + return; + + if (tsx->role == PJSIP_ROLE_UAS && + tsx->state == PJSIP_TSX_STATE_TRYING && + pjsip_method_cmp(&tsx->method, &pjsip_prack_method)==0) + { + /* + * Handle incoming PRACK request. + */ + handle_incoming_prack(dd, tsx, e); + + } else if (tsx->role == PJSIP_ROLE_UAC && + tsx->method.id == PJSIP_INVITE_METHOD && + e->type == PJSIP_EVENT_TSX_STATE && + e->body.tsx_state.type == PJSIP_EVENT_RX_MSG && + e->body.tsx_state.src.rdata->msg_info.msg->line.status.code > 100 && + e->body.tsx_state.src.rdata->msg_info.msg->line.status.code < 200 && + e->body.tsx_state.src.rdata->msg_info.require != NULL) + { + /* + * Handle incoming provisional response which wants to + * be PRACK-ed + */ + + if (find_req_hdr(e->body.tsx_state.src.rdata->msg_info.msg)) { + /* Received provisional response which needs to be + * PRACK-ed. + */ + handle_incoming_response(dd, tsx, e); + } + + } else if (tsx->role == PJSIP_ROLE_UAC && + tsx->state == PJSIP_TSX_STATE_COMPLETED && + pjsip_method_cmp(&tsx->method, &pjsip_prack_method)==0) + { + /* + * Handle the status of outgoing PRACK request. + */ + if (tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST || + tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT || + tsx->status_code == PJSIP_SC_TSX_TIMEOUT || + tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR) + { + /* These are fatal errors which should terminate + * the session AND dialog! + */ + PJ_TODO(TERMINATE_SESSION_ON_481); + } + + } else if (tsx == dd->inv->invite_tsx && + tsx->role == PJSIP_ROLE_UAS && + tsx->state == PJSIP_TSX_STATE_TERMINATED) + { + /* Make sure we don't have pending transmission */ + if (dd->uas_state) { + pj_assert(!dd->uas_state->retransmit_timer.id); + pj_assert(pj_list_empty(&dd->uas_state->tx_data_list)); + } + } +} + +static void parse_rack(const pj_str_t *rack, + pj_uint32_t *p_rseq, pj_int32_t *p_seq, + pj_str_t *p_method) +{ + const char *p = rack->ptr, *end = p + rack->slen; + pj_str_t token; + + token.ptr = (char*)p; + while (p < end && pj_isdigit(*p)) + ++p; + token.slen = p - token.ptr; + *p_rseq = pj_strtoul(&token); + + ++p; + token.ptr = (char*)p; + while (p < end && pj_isdigit(*p)) + ++p; + token.slen = p - token.ptr; + *p_seq = pj_strtoul(&token); + + ++p; + if (p < end) { + p_method->ptr = (char*)p; + p_method->slen = end - p; + } else { + p_method->ptr = NULL; + p_method->slen = 0; + } +} + +/* Clear all responses in the transmission list */ +static void clear_all_responses(dlg_data *dd) +{ + tx_data_list *tl; + + tl = dd->uas_state->tx_data_list.next; + while (tl != &dd->uas_state->tx_data_list) { + pjsip_tx_data_dec_ref(tl->tdata); + tl = tl->next; + } + pj_list_init(&dd->uas_state->tx_data_list); +} + + +static void handle_incoming_prack(dlg_data *dd, pjsip_transaction *tsx, + pjsip_event *e) +{ + pjsip_rx_data *rdata; + pjsip_msg *msg; + pjsip_generic_string_hdr *rack_hdr; + pjsip_tx_data *tdata; + pj_uint32_t rseq; + pj_int32_t cseq; + pj_str_t method; + pj_status_t status; + + + rdata = e->body.tsx_state.src.rdata; + msg = rdata->msg_info.msg; + + /* Always reply with 200/OK for PRACK */ + status = pjsip_endpt_create_response(tsx->endpt, rdata, + 200, NULL, &tdata); + if (status == PJ_SUCCESS) + pjsip_tsx_send_msg(tsx, tdata); + + /* Ignore if we don't have pending transmission */ + if (dd->uas_state == NULL || + pj_list_empty(&dd->uas_state->tx_data_list)) + { + PJ_LOG(4,(dd->inv->dlg->obj_name, + "PRACK ignored - no pending response")); + return; + } + + /* Find RAck header */ + rack_hdr = (pjsip_generic_string_hdr*) + pjsip_msg_find_hdr_by_name(msg, &RACK, NULL); + if (!rack_hdr) { + /* RAck header not found */ + PJ_LOG(4,(dd->inv->dlg->obj_name, "No RAck header")); + return; + } + parse_rack(&rack_hdr->hvalue, &rseq, &cseq, &method); + + /* Match RAck against outgoing transmission */ + if (rseq == dd->uas_state->tx_data_list.next->rseq && + cseq == dd->uas_state->cseq) + { + tx_data_list *tl = dd->uas_state->tx_data_list.next; + + /* Yes it match! */ + if (dd->uas_state->retransmit_timer.id) { + pjsip_endpt_cancel_timer(dd->inv->dlg->endpt, + &dd->uas_state->retransmit_timer); + dd->uas_state->retransmit_timer.id = PJ_FALSE; + } + + /* Remove from the list */ + if (tl != &dd->uas_state->tx_data_list) { + pj_list_erase(tl); + + /* Destroy the response */ + pjsip_tx_data_dec_ref(tl->tdata); + } + + /* Schedule next packet */ + dd->uas_state->retransmit_count = 0; + if (!pj_list_empty(&dd->uas_state->tx_data_list)) { + on_retransmit(NULL, &dd->uas_state->retransmit_timer); + } + + } else { + /* No it doesn't match */ + PJ_LOG(4,(dd->inv->dlg->obj_name, + "Rx PRACK with no matching reliable response")); + } +} + + +/* + * Handle incoming provisional response with 100rel requirement. + * In this case we shall transmit PRACK request. + */ +static void handle_incoming_response(dlg_data *dd, pjsip_transaction *tsx, + pjsip_event *e) +{ + pjsip_rx_data *rdata; + pjsip_msg *msg; + pjsip_generic_string_hdr *rseq_hdr; + pjsip_generic_string_hdr *rack_hdr; + unsigned rseq; + pj_str_t rack; + char rack_buf[80]; + pjsip_tx_data *tdata; + pj_status_t status; + + rdata = e->body.tsx_state.src.rdata; + msg = rdata->msg_info.msg; + + /* Check our assumptions */ + pj_assert( tsx->role == PJSIP_ROLE_UAC && + tsx->method.id == PJSIP_INVITE_METHOD && + e->type == PJSIP_EVENT_TSX_STATE && + e->body.tsx_state.type == PJSIP_EVENT_RX_MSG && + msg->line.status.code > 100 && + msg->line.status.code < 200); + + + /* Get the RSeq header */ + rseq_hdr = (pjsip_generic_string_hdr*) + pjsip_msg_find_hdr_by_name(msg, &RSEQ, NULL); + if (rseq_hdr == NULL) { + PJ_LOG(4,(dd->inv->dlg->obj_name, + "Ignoring provisional response with no RSeq header")); + return; + } + rseq = (pj_uint32_t) pj_strtoul(&rseq_hdr->hvalue); + + /* Create new UAC state if we don't have one */ + if (dd->uac_state == NULL) { + dd->uac_state = PJ_POOL_ZALLOC_T(dd->inv->dlg->pool, + struct uac_state); + dd->uac_state->cseq = rdata->msg_info.cseq->cseq; + dd->uac_state->rseq = rseq - 1; + } + + /* If this is from new INVITE transaction, reset UAC state */ + if (rdata->msg_info.cseq->cseq != dd->uac_state->cseq) { + dd->uac_state->cseq = rdata->msg_info.cseq->cseq; + dd->uac_state->rseq = rseq - 1; + } + + /* Ignore provisional response retransmission */ + if (rseq <= dd->uac_state->rseq) { + /* This should have been handled before */ + return; + + /* Ignore provisional response with out-of-order RSeq */ + } else if (rseq != dd->uac_state->rseq + 1) { + PJ_LOG(4,(dd->inv->dlg->obj_name, + "Ignoring provisional response because RSeq jump " + "(expecting %u, got %u)", + dd->uac_state->rseq+1, rseq)); + return; + } + + /* Update our RSeq */ + dd->uac_state->rseq = rseq; + + /* Create PRACK */ + status = pjsip_dlg_create_request(dd->inv->dlg, &pjsip_prack_method, + -1, &tdata); + if (status != PJ_SUCCESS) { + PJ_LOG(4,(dd->inv->dlg->obj_name, + "Error creating PRACK request (status=%d)", status)); + return; + } + + /* Create RAck header */ + rack.ptr = rack_buf; + rack.slen = pj_ansi_snprintf(rack.ptr, sizeof(rack_buf), + "%u %u %.*s", + rseq, rdata->msg_info.cseq->cseq, + (int)tsx->method.name.slen, + tsx->method.name.ptr); + PJ_ASSERT_ON_FAIL(rack.slen > 0 && rack.slen < sizeof(rack_buf), + { pjsip_tx_data_dec_ref(tdata); return; }); + rack_hdr = pjsip_generic_string_hdr_create(tdata->pool, &RACK, &rack); + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) rack_hdr); + + /* Send PRACK */ + pjsip_dlg_send_request(dd->inv->dlg, tdata, + mod_100rel.mod.id, (void*) dd); + +} + + +/* + * API: init module + */ +PJ_DEF(pj_status_t) pjsip_100rel_init_module(pjsip_endpoint *endpt) +{ + return pjsip_endpt_register_module(endpt, &mod_100rel.mod); +} + + +/* + * API: attach 100rel support in invite session. Called by + * sip_inv.c + */ +PJ_DEF(pj_status_t) pjsip_100rel_attach(pjsip_inv_session *inv) +{ + dlg_data *dd; + + /* Check that 100rel module has been initialized */ + PJ_ASSERT_RETURN(mod_100rel.mod.id >= 0, PJ_EINVALIDOP); + + /* Create and attach as dialog usage */ + dd = PJ_POOL_ZALLOC_T(inv->dlg->pool, dlg_data); + dd->inv = inv; + pjsip_dlg_add_usage(inv->dlg, &mod_100rel.mod, (void*)dd); + + PJ_LOG(5,(dd->inv->dlg->obj_name, "100rel module attached")); + + return PJ_SUCCESS; +} + + +/* + * This is retransmit timer callback, called initially to send the response, + * and subsequently when the retransmission time elapses. + */ +static void on_retransmit(pj_timer_heap_t *timer_heap, + struct pj_timer_entry *entry) +{ + dlg_data *dd; + tx_data_list *tl; + pjsip_tx_data *tdata; + pj_bool_t final; + pj_time_val delay; + + PJ_UNUSED_ARG(timer_heap); + + dd = (dlg_data*) entry->user_data; + + entry->id = PJ_FALSE; + + ++dd->uas_state->retransmit_count; + if (dd->uas_state->retransmit_count >= 7) { + /* If a reliable provisional response is retransmitted for + 64*T1 seconds without reception of a corresponding PRACK, + the UAS SHOULD reject the original request with a 5xx + response. + */ + pj_str_t reason = pj_str("Reliable response timed out"); + pj_status_t status; + + /* Clear all pending responses */ + clear_all_responses(dd); + + /* Send 500 response */ + status = pjsip_inv_end_session(dd->inv, 500, &reason, &tdata); + if (status == PJ_SUCCESS) { + pjsip_dlg_send_response(dd->inv->dlg, + dd->inv->invite_tsx, + tdata); + } + return; + } + + pj_assert(!pj_list_empty(&dd->uas_state->tx_data_list)); + tl = dd->uas_state->tx_data_list.next; + tdata = tl->tdata; + + pjsip_tx_data_add_ref(tdata); + final = tdata->msg->line.status.code >= 200; + + if (dd->uas_state->retransmit_count == 1) { + pjsip_tsx_send_msg(dd->inv->invite_tsx, tdata); + } else { + pjsip_tsx_retransmit_no_state(dd->inv->invite_tsx, tdata); + } + + if (final) { + /* This is final response, which will be retransmitted by + * UA layer. There's no more task to do, so clear the + * transmission list and bail out. + */ + clear_all_responses(dd); + return; + } + + /* Schedule next retransmission */ + if (dd->uas_state->retransmit_count < 6) { + delay.sec = 0; + delay.msec = (1 << dd->uas_state->retransmit_count) * + PJSIP_T1_TIMEOUT; + pj_time_val_normalize(&delay); + } else { + delay.sec = 1; + delay.msec = 500; + } + + + pjsip_endpt_schedule_timer(dd->inv->dlg->endpt, + &dd->uas_state->retransmit_timer, + &delay); + + entry->id = PJ_TRUE; +} + +/* Clone response. */ +static pjsip_tx_data *clone_tdata(dlg_data *dd, + const pjsip_tx_data *src) +{ + pjsip_tx_data *dst; + const pjsip_hdr *hsrc; + pjsip_msg *msg; + pj_status_t status; + + status = pjsip_endpt_create_tdata(dd->inv->dlg->endpt, &dst); + if (status != PJ_SUCCESS) + return NULL; + + msg = pjsip_msg_create(dst->pool, PJSIP_RESPONSE_MSG); + dst->msg = msg; + pjsip_tx_data_add_ref(dst); + + /* Duplicate status line */ + msg->line.status.code = src->msg->line.status.code; + pj_strdup(dst->pool, &msg->line.status.reason, + &src->msg->line.status.reason); + + /* Duplicate all headers */ + hsrc = src->msg->hdr.next; + while (hsrc != &src->msg->hdr) { + pjsip_hdr *h = pjsip_hdr_clone(dst->pool, hsrc); + pjsip_msg_add_hdr(msg, h); + hsrc = hsrc->next; + } + + /* Duplicate message body */ + if (src->msg->body) + msg->body = pjsip_msg_body_clone(dst->pool, src->msg->body); + + PJ_LOG(5,(dd->inv->dlg->obj_name, + "Reliable response %s created", + pjsip_tx_data_get_info(dst))); + + return dst; +} + +PJ_DEF(pj_status_t) pjsip_100rel_tx_response(pjsip_inv_session *inv, + pjsip_tx_data *tdata) +{ + pjsip_cseq_hdr *cseq_hdr; + pjsip_generic_string_hdr *rseq_hdr; + pjsip_require_hdr *req_hdr; + int status_code; + dlg_data *dd; + pjsip_tx_data *old_tdata; + pj_status_t status; + + PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG, + PJ_EINVALIDOP); + + status_code = tdata->msg->line.status.code; + + /* 100 response doesn't need PRACK */ + if (status_code == 100) + return pjsip_dlg_send_response(inv->dlg, inv->invite_tsx, tdata); + + /* Get the dialog data */ + dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id]; + PJ_ASSERT_RETURN(dd != NULL, PJ_EINVALIDOP); + + + /* Clone tdata */ + old_tdata = tdata; + tdata = clone_tdata(dd, old_tdata); + pjsip_tx_data_dec_ref(old_tdata); + + /* Get CSeq header */ + cseq_hdr = (pjsip_cseq_hdr*) + pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL); + PJ_ASSERT_RETURN(cseq_hdr != NULL, PJ_EBUG); + PJ_ASSERT_RETURN(cseq_hdr->method.id == PJSIP_INVITE_METHOD, + PJ_EINVALIDOP); + + /* Remove existing Require header */ + req_hdr = find_req_hdr(tdata->msg); + if (req_hdr) { + pj_list_erase(req_hdr); + } + + /* Remove existing RSeq header */ + rseq_hdr = (pjsip_generic_string_hdr*) + pjsip_msg_find_hdr_by_name(tdata->msg, &RSEQ, NULL); + if (rseq_hdr) + pj_list_erase(rseq_hdr); + + /* Different treatment for provisional and final response */ + if (status_code/100 == 2) { + + /* RFC 3262 Section 3: UAS Behavior: + + The UAS MAY send a final response to the initial request + before having received PRACKs for all unacknowledged + reliable provisional responses, unless the final response + is 2xx and any of the unacknowledged reliable provisional + responses contained a session description. In that case, + it MUST NOT send a final response until those provisional + responses are acknowledged. + */ + + if (dd->uas_state && dd->uas_state->has_sdp) { + /* Yes we have transmitted 1xx with SDP reliably. + * In this case, must queue the 2xx response. + */ + tx_data_list *tl; + + tl = PJ_POOL_ZALLOC_T(tdata->pool, tx_data_list); + tl->tdata = tdata; + tl->rseq = (pj_uint32_t)-1; + pj_list_push_back(&dd->uas_state->tx_data_list, tl); + + /* Will send later */ + status = PJ_SUCCESS; + + PJ_LOG(4,(dd->inv->dlg->obj_name, + "2xx response will be sent after PRACK")); + + } else if (dd->uas_state) { + /* + If the UAS does send a final response when reliable + responses are still unacknowledged, it SHOULD NOT + continue to retransmit the unacknowledged reliable + provisional responses, but it MUST be prepared to + process PRACK requests for those outstanding + responses. + */ + + PJ_LOG(4,(dd->inv->dlg->obj_name, + "No SDP sent so far, sending 2xx now")); + + /* Cancel the retransmit timer */ + if (dd->uas_state->retransmit_timer.id) { + pjsip_endpt_cancel_timer(dd->inv->dlg->endpt, + &dd->uas_state->retransmit_timer); + dd->uas_state->retransmit_timer.id = PJ_FALSE; + } + + /* Clear all pending responses (drop 'em) */ + clear_all_responses(dd); + + /* And transmit the 2xx response */ + status=pjsip_dlg_send_response(inv->dlg, + inv->invite_tsx, tdata); + + } else { + /* We didn't send any reliable provisional response */ + + /* Transmit the 2xx response */ + status=pjsip_dlg_send_response(inv->dlg, + inv->invite_tsx, tdata); + } + + } else if (status_code >= 300) { + + /* + If the UAS does send a final response when reliable + responses are still unacknowledged, it SHOULD NOT + continue to retransmit the unacknowledged reliable + provisional responses, but it MUST be prepared to + process PRACK requests for those outstanding + responses. + */ + + /* Cancel the retransmit timer */ + if (dd->uas_state && dd->uas_state->retransmit_timer.id) { + pjsip_endpt_cancel_timer(dd->inv->dlg->endpt, + &dd->uas_state->retransmit_timer); + dd->uas_state->retransmit_timer.id = PJ_FALSE; + + /* Clear all pending responses (drop 'em) */ + clear_all_responses(dd); + } + + /* And transmit the 2xx response */ + status=pjsip_dlg_send_response(inv->dlg, + inv->invite_tsx, tdata); + + } else { + /* + * This is provisional response. + */ + char rseq_str[32]; + pj_str_t rseq; + tx_data_list *tl; + + /* Create UAS state if we don't have one */ + if (dd->uas_state == NULL) { + dd->uas_state = PJ_POOL_ZALLOC_T(inv->dlg->pool, + uas_state); + dd->uas_state->cseq = cseq_hdr->cseq; + dd->uas_state->rseq = pj_rand() % 0x7FFF; + pj_list_init(&dd->uas_state->tx_data_list); + dd->uas_state->retransmit_timer.user_data = dd; + dd->uas_state->retransmit_timer.cb = &on_retransmit; + } + + /* Check that CSeq match */ + PJ_ASSERT_RETURN(cseq_hdr->cseq == dd->uas_state->cseq, + PJ_EINVALIDOP); + + /* Add Require header */ + req_hdr = pjsip_require_hdr_create(tdata->pool); + req_hdr->count = 1; + req_hdr->values[0] = tag_100rel; + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)req_hdr); + + /* Add RSeq header */ + pj_ansi_snprintf(rseq_str, sizeof(rseq_str), "%u", + dd->uas_state->rseq); + rseq = pj_str(rseq_str); + rseq_hdr = pjsip_generic_string_hdr_create(tdata->pool, + &RSEQ, &rseq); + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)rseq_hdr); + + /* Create list entry for this response */ + tl = PJ_POOL_ZALLOC_T(tdata->pool, tx_data_list); + tl->tdata = tdata; + tl->rseq = dd->uas_state->rseq++; + + /* Add to queue if there's pending response, otherwise + * transmit immediately. + */ + if (!pj_list_empty(&dd->uas_state->tx_data_list)) { + + int code = tdata->msg->line.status.code; + + /* Will send later */ + pj_list_push_back(&dd->uas_state->tx_data_list, tl); + status = PJ_SUCCESS; + + PJ_LOG(4,(dd->inv->dlg->obj_name, + "Reliable %d response enqueued (%d pending)", + code, pj_list_size(&dd->uas_state->tx_data_list))); + + } else { + pj_list_push_back(&dd->uas_state->tx_data_list, tl); + + dd->uas_state->retransmit_count = 0; + on_retransmit(NULL, &dd->uas_state->retransmit_timer); + status = PJ_SUCCESS; + } + + /* Update SDP flag. Need to call this after the response + * is scheduled for transmission. + */ + dd->uas_state->has_sdp |= (tdata->msg->body != NULL); + } + + return status; +} + + +#endif /* PJSIP_HAS_100REL */ diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c index 9f5617636..0243452af 100644 --- a/pjsip/src/pjsip-ua/sip_inv.c +++ b/pjsip/src/pjsip-ua/sip_inv.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include #include @@ -31,7 +32,7 @@ #include -#define THIS_FILE "sip_invite_session.c" +#define THIS_FILE "sip_inv.c" static const char *inv_state_names[] = { @@ -305,6 +306,10 @@ static pj_bool_t mod_inv_on_rx_request(pjsip_rx_data *rdata) pjsip_tsx_terminate(inv->invite_tsx, inv->invite_tsx->status_code); inv->invite_tsx = NULL; + if (inv->last_answer) { + pjsip_tx_data_dec_ref(inv->last_answer); + inv->last_answer = NULL; + } } /* On receipt of ACK, only set state to confirmed when state @@ -395,8 +400,13 @@ static void mod_inv_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) * terminated, but this didn't work when ACK has the same Via branch * value as the INVITE (see http://www.pjsip.org/trac/ticket/113) */ - if (tsx->state>=PJSIP_TSX_STATE_CONFIRMED && tsx == inv->invite_tsx) + if (tsx->state>=PJSIP_TSX_STATE_CONFIRMED && tsx == inv->invite_tsx) { inv->invite_tsx = NULL; + if (inv->last_answer) { + pjsip_tx_data_dec_ref(inv->last_answer); + inv->last_answer = NULL; + } + } } @@ -482,6 +492,14 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uac( pjsip_dialog *dlg, if (options & PJSIP_INV_REQUIRE_100REL) options |= PJSIP_INV_SUPPORT_100REL; +#if !PJSIP_HAS_100REL + /* options cannot specify 100rel if 100rel is disabled */ + PJ_ASSERT_RETURN( + (options & (PJSIP_INV_REQUIRE_100REL | PJSIP_INV_SUPPORT_100REL))==0, + PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_EXTENSION)); + +#endif + if (options & PJSIP_INV_REQUIRE_TIMER) options |= PJSIP_INV_SUPPORT_TIMER; @@ -520,6 +538,11 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uac( pjsip_dialog *dlg, /* Increment dialog session */ pjsip_dlg_inc_session(dlg, &mod_inv.mod); +#if PJSIP_HAS_100REL + /* Create 100rel handler */ + pjsip_100rel_attach(inv); +#endif + /* Done */ *p_inv = inv; @@ -829,6 +852,18 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request(pjsip_rx_data *rdata, goto on_return; } + /* If remote Require something that we support, make us Require + * that feature too. + */ + if (rem_option & PJSIP_INV_REQUIRE_100REL) { + pj_assert(*options & PJSIP_INV_SUPPORT_100REL); + *options |= PJSIP_INV_REQUIRE_100REL; + } + if (rem_option & PJSIP_INV_REQUIRE_TIMER) { + pj_assert(*options & PJSIP_INV_SUPPORT_TIMER); + *options |= PJSIP_INV_REQUIRE_TIMER; + } + on_return: /* Create response if necessary */ @@ -908,6 +943,14 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uas( pjsip_dialog *dlg, if (options & PJSIP_INV_REQUIRE_100REL) options |= PJSIP_INV_SUPPORT_100REL; +#if !PJSIP_HAS_100REL + /* options cannot specify 100rel if 100rel is disabled */ + PJ_ASSERT_RETURN( + (options & (PJSIP_INV_REQUIRE_100REL | PJSIP_INV_SUPPORT_100REL))==0, + PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_EXTENSION)); + +#endif + if (options & PJSIP_INV_REQUIRE_TIMER) options |= PJSIP_INV_SUPPORT_TIMER; @@ -977,6 +1020,13 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uas( pjsip_dialog *dlg, tsx_inv_data->inv = inv; inv->invite_tsx->mod_data[mod_inv.mod.id] = tsx_inv_data; +#if PJSIP_HAS_100REL + /* Create 100rel handler */ + if (inv->options & PJSIP_INV_REQUIRE_100REL) { + pjsip_100rel_attach(inv); + } +#endif + /* Done */ pjsip_dlg_dec_lock(dlg); *p_inv = inv; @@ -1168,7 +1218,15 @@ PJ_DEF(pj_status_t) pjsip_inv_invite( pjsip_inv_session *inv, } /* Add Require header. */ - PJ_TODO(INVITE_ADD_REQUIRE_HEADER); + if (inv->options & PJSIP_INV_REQUIRE_100REL) { + const pj_str_t HREQ = { "Require", 7 }; + const pj_str_t tag_100rel = { "100rel", 6 }; + pjsip_generic_string_hdr *hreq; + + hreq = pjsip_generic_string_hdr_create(tdata->pool, &HREQ, + &tag_100rel); + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) hreq); + } /* Done. */ *p_tdata = tdata; @@ -1452,6 +1510,12 @@ PJ_DEF(pj_status_t) pjsip_inv_initial_answer( pjsip_inv_session *inv, goto on_return; } + /* Save this answer */ + inv->last_answer = tdata; + pjsip_tx_data_add_ref(inv->last_answer); + PJ_LOG(5,(inv->dlg->obj_name, "Initial answer %s", + pjsip_tx_data_get_info(inv->last_answer))); + *p_tdata = tdata; on_return: @@ -1479,17 +1543,21 @@ PJ_DEF(pj_status_t) pjsip_inv_answer( pjsip_inv_session *inv, /* Must have INVITE transaction. */ PJ_ASSERT_RETURN(inv->invite_tsx, PJ_EBUG); - /* INVITE transaction MUST have transmitted a response (e.g. 100) */ - PJ_ASSERT_RETURN(inv->invite_tsx->last_tx, PJ_EINVALIDOP); + /* Must have created an answer before */ + PJ_ASSERT_RETURN(inv->last_answer, PJ_EINVALIDOP); pjsip_dlg_inc_lock(inv->dlg); /* Modify last response. */ - last_res = inv->invite_tsx->last_tx; + last_res = inv->last_answer; status = pjsip_dlg_modify_response(inv->dlg, last_res, st_code, st_text); if (status != PJ_SUCCESS) goto on_return; + /* For non-2xx final response, strip message body */ + if (st_code >= 300) { + last_res->msg->body = NULL; + } /* Process SDP in answer */ status = process_answer(inv, st_code, last_res, local_sdp); @@ -1764,7 +1832,15 @@ PJ_DEF(pj_status_t) pjsip_inv_send_msg( pjsip_inv_session *inv, && (cseq->cseq == inv->invite_tsx->cseq), PJ_EINVALIDOP); - status = pjsip_dlg_send_response(inv->dlg, inv->invite_tsx, tdata); +#if PJSIP_HAS_100REL + if (inv->options & PJSIP_INV_REQUIRE_100REL) { + status = pjsip_100rel_tx_response(inv, tdata); + } else +#endif + { + status = pjsip_dlg_send_response(inv->dlg, inv->invite_tsx, tdata); + } + if (status != PJ_SUCCESS) return status; } @@ -2042,6 +2118,10 @@ static void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e) /* Restart session. */ inv->state = PJSIP_INV_STATE_NULL; inv->invite_tsx = NULL; + if (inv->last_answer) { + pjsip_tx_data_dec_ref(inv->last_answer); + inv->last_answer = NULL; + } /* Send the request. */ status = pjsip_inv_send_msg(inv, tdata); diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c index 790d653d6..e721044c7 100644 --- a/pjsip/src/pjsip/sip_transaction.c +++ b/pjsip/src/pjsip/sip_transaction.c @@ -1814,6 +1814,33 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx, } +/* + * Manually retransmit the last messagewithout updating the transaction state. + */ +PJ_DEF(pj_status_t) pjsip_tsx_retransmit_no_state(pjsip_transaction *tsx, + pjsip_tx_data *tdata) +{ + struct tsx_lock_data lck; + pj_status_t status; + + lock_tsx(tsx, &lck); + if (tdata == NULL) { + tdata = tsx->last_tx; + } + status = tsx_send_msg(tsx, tdata); + unlock_tsx(tsx, &lck); + + /* Only decrement reference counter when it returns success. + * (This is the specification from the .PDF design document). + */ + if (status == PJ_SUCCESS) { + pjsip_tx_data_dec_ref(tdata); + } + + return status; +} + + /* * Retransmit last message sent. */ diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index c5d273427..22a110535 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -220,9 +220,6 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id, PJ_ASSERT_RETURN(acc_id>=0 || acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc), PJ_EINVAL); - /* Options must be zero for now */ - PJ_ASSERT_RETURN(options == 0, PJ_EINVAL); - /* Check arguments */ PJ_ASSERT_RETURN(dest_uri, PJ_EINVAL); @@ -322,8 +319,13 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id, } /* Create the INVITE session: */ +#if PJSIP_HAS_100REL + options |= PJSIP_INV_SUPPORT_100REL; +#endif + if (acc->cfg.require_100rel) + options |= PJSIP_INV_REQUIRE_100REL; - status = pjsip_inv_create_uac( dlg, offer, 0, &inv); + status = pjsip_inv_create_uac( dlg, offer, options, &inv); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Invite session creation failed", status); goto on_error; @@ -557,8 +559,20 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) return PJ_TRUE; } + /* + * Get which account is most likely to be associated with this incoming + * call. We need the account to find which contact URI to put for + * the call. + */ + acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata); /* Verify that we can handle the request. */ +#if PJSIP_HAS_100REL + options |= PJSIP_INV_SUPPORT_100REL; +#endif + if (pjsua_var.acc[acc_id].cfg.require_100rel) + options |= PJSIP_INV_REQUIRE_100REL; + status = pjsip_inv_verify_request(rdata, &options, answer, NULL, pjsua_var.endpt, &response); if (status != PJ_SUCCESS) { @@ -566,7 +580,6 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) /* * No we can't handle the incoming INVITE request. */ - if (response) { pjsip_response_addr res_addr; @@ -587,13 +600,6 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) } - /* - * Get which account is most likely to be associated with this incoming - * call. We need the account to find which contact URI to put for - * the call. - */ - acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata); - /* Get suitable Contact header */ status = pjsua_acc_create_uas_contact(rdata->tp_info.pool, &contact, acc_id, rdata); @@ -625,7 +631,7 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) } /* Create invite session: */ - status = pjsip_inv_create_uas( dlg, rdata, answer, 0, &inv); + status = pjsip_inv_create_uas( dlg, rdata, answer, options, &inv); if (status != PJ_SUCCESS) { pjsip_hdr hdr_list; pjsip_warning_hdr *w; diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 3b5126664..8c2b3b561 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -141,6 +141,7 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg) cfg->reg_timeout = PJSUA_REG_INTERVAL; cfg->transport_id = PJSUA_INVALID_ID; cfg->auto_update_nat = PJ_TRUE; + cfg->require_100rel = pjsua_var.ua_cfg.require_100rel; } PJ_DEF(void) pjsua_buddy_config_default(pjsua_buddy_config *cfg) @@ -648,6 +649,11 @@ PJ_DEF(pj_status_t) pjsua_init( const pjsua_config *ua_cfg, status = pjsip_replaces_init_module( pjsua_var.endpt ); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); +#if PJSIP_HAS_100REL + /* Initialize 100rel support */ + status = pjsip_100rel_init_module(pjsua_var.endpt); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); +#endif /* Initialize and register PJSUA application module. */ {