From c35a41e4ca209f822d561f4601f1f387bfc9a82e Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Fri, 1 Mar 2013 15:48:48 -0600 Subject: [PATCH 1/2] FS-3772 --resolve please no vanity comments --- libs/sofia-sip/.update | 2 +- libs/sofia-sip/libsofia-sip-ua/nta/nta.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 4cc6f673f6..e6a01c6b43 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Tue Feb 19 13:10:23 CST 2013 +Fri Mar 1 15:47:13 CST 2013 diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c index dddb3ecd9a..3f6afc03f6 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c @@ -7858,7 +7858,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent, else branch = su_sprintf(home, "branch=%s", branch); } - else if (orq->orq_user_via && sip->sip_via->v_branch) + else if (orq->orq_user_via && sip->sip_via->v_branch && orq->orq_method != sip_method_invite ) branch = su_sprintf(home, "branch=%s", sip->sip_via->v_branch); else if (stateless) branch = stateless_branch(agent, msg, sip, orq->orq_tpn); From 417ad280e0594cd487c53ff5ea3bc2c0d545500d Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 4 Mar 2013 10:40:43 -0500 Subject: [PATCH 2/2] remove unused lib --- libs/sipcc/Makefile.am | 419 - libs/sipcc/core/ccapp/CCProvider.h | 144 - libs/sipcc/core/ccapp/call_logger.c | 303 - libs/sipcc/core/ccapp/call_logger.h | 20 - libs/sipcc/core/ccapp/capability_set.c | 281 - libs/sipcc/core/ccapp/capability_set.h | 33 - libs/sipcc/core/ccapp/cc_blf.c | 50 - libs/sipcc/core/ccapp/cc_call_feature.c | 681 - libs/sipcc/core/ccapp/cc_config.c | 154 - libs/sipcc/core/ccapp/cc_device_feature.c | 62 - libs/sipcc/core/ccapp/cc_device_manager.c | 593 - libs/sipcc/core/ccapp/cc_device_manager.h | 43 - libs/sipcc/core/ccapp/cc_info.c | 43 - libs/sipcc/core/ccapp/cc_service.c | 229 - libs/sipcc/core/ccapp/ccapi_call.c | 375 - libs/sipcc/core/ccapp/ccapi_call_info.c | 784 - libs/sipcc/core/ccapp/ccapi_config.c | 108 - libs/sipcc/core/ccapp/ccapi_device.c | 290 - libs/sipcc/core/ccapp/ccapi_device_info.c | 475 - libs/sipcc/core/ccapp/ccapi_feature_info.c | 154 - libs/sipcc/core/ccapp/ccapi_line.c | 81 - libs/sipcc/core/ccapp/ccapi_line_info.c | 425 - libs/sipcc/core/ccapp/ccapi_service.c | 166 - libs/sipcc/core/ccapp/ccapi_snapshot.c | 715 - libs/sipcc/core/ccapp/ccapi_snapshot.h | 114 - libs/sipcc/core/ccapp/ccapp_task.c | 177 - libs/sipcc/core/ccapp/ccapp_task.h | 20 - libs/sipcc/core/ccapp/ccprovider.c | 2241 --- libs/sipcc/core/ccapp/conf_roster.c | 401 - libs/sipcc/core/ccapp/conf_roster.h | 49 - libs/sipcc/core/ccapp/sessionHash.c | 305 - libs/sipcc/core/ccapp/sessionHash.h | 23 - libs/sipcc/core/common/cfgfile_utils.c | 415 - libs/sipcc/core/common/cfgfile_utils.h | 96 - libs/sipcc/core/common/config_api.c | 498 - libs/sipcc/core/common/config_parser.c | 641 - libs/sipcc/core/common/config_parser.h | 173 - libs/sipcc/core/common/init.c | 576 - libs/sipcc/core/common/logger.c | 87 - libs/sipcc/core/common/logger.h | 17 - libs/sipcc/core/common/logmsg.h | 42 - libs/sipcc/core/common/misc.c | 391 - libs/sipcc/core/common/plat.c | 89 - libs/sipcc/core/common/platform_api.c | 396 - libs/sipcc/core/common/prot_cfgmgr_private.h | 431 - libs/sipcc/core/common/prot_configmgr.c | 890 -- libs/sipcc/core/common/prot_configmgr.h | 298 - libs/sipcc/core/common/resource_manager.c | 300 - libs/sipcc/core/common/resource_manager.h | 23 - libs/sipcc/core/common/sip_socket_api.c | 100 - libs/sipcc/core/common/subscription_handler.c | 342 - libs/sipcc/core/common/subscription_handler.h | 23 - libs/sipcc/core/common/text_strings.c | 361 - libs/sipcc/core/common/text_strings.h | 302 - libs/sipcc/core/common/ui.c | 1666 --- libs/sipcc/core/gsm/ccapi.c | 1749 --- libs/sipcc/core/gsm/ccapi_strings.c | 60 - libs/sipcc/core/gsm/dcsm.c | 723 - libs/sipcc/core/gsm/fim.c | 761 - libs/sipcc/core/gsm/fsm.c | 1385 -- libs/sipcc/core/gsm/fsmb2bcnf.c | 1285 -- libs/sipcc/core/gsm/fsmcac.c | 707 - libs/sipcc/core/gsm/fsmcnf.c | 1750 --- libs/sipcc/core/gsm/fsmdef.c | 8668 ----------- libs/sipcc/core/gsm/fsmxfr.c | 3042 ---- libs/sipcc/core/gsm/gsm.c | 608 - libs/sipcc/core/gsm/gsm_sdp.c | 6610 --------- libs/sipcc/core/gsm/gsm_sdp_crypto.c | 1914 --- libs/sipcc/core/gsm/h/fim.h | 66 - libs/sipcc/core/gsm/h/fsm.h | 768 - libs/sipcc/core/gsm/h/gsm.h | 59 - libs/sipcc/core/gsm/h/gsm_sdp.h | 139 - libs/sipcc/core/gsm/h/lsm.h | 180 - libs/sipcc/core/gsm/h/lsm_private.h | 58 - libs/sipcc/core/gsm/h/sm.h | 44 - libs/sipcc/core/gsm/lsm.c | 6610 --------- libs/sipcc/core/gsm/media_cap_tbl.c | 158 - libs/sipcc/core/gsm/sm.c | 78 - libs/sipcc/core/gsm/subapi.c | 269 - libs/sipcc/core/includes/CSFLog.h | 46 - libs/sipcc/core/includes/ccSession.h | 207 - libs/sipcc/core/includes/ccapi.h | 1578 -- libs/sipcc/core/includes/check_sync.h | 46 - libs/sipcc/core/includes/ci.h | 34 - libs/sipcc/core/includes/config.h | 195 - libs/sipcc/core/includes/configapp.h | 13 - libs/sipcc/core/includes/configmgr.h | 62 - libs/sipcc/core/includes/debug.h | 108 - libs/sipcc/core/includes/dialplan.h | 111 - libs/sipcc/core/includes/dialplanint.h | 93 - libs/sipcc/core/includes/digcalc.h | 42 - libs/sipcc/core/includes/dns_utils.h | 77 - libs/sipcc/core/includes/dtmf.h | 27 - libs/sipcc/core/includes/embedded.h | 24 - libs/sipcc/core/includes/intelpentiumtypes.h | 19 - libs/sipcc/core/includes/kpml_common_util.h | 49 - libs/sipcc/core/includes/kpmlmap.h | 177 - libs/sipcc/core/includes/md5.h | 57 - libs/sipcc/core/includes/memory.h | 35 - libs/sipcc/core/includes/misc_apps_task.h | 14 - libs/sipcc/core/includes/misc_util.h | 9 - libs/sipcc/core/includes/phntask.h | 309 - libs/sipcc/core/includes/phone.h | 504 - libs/sipcc/core/includes/phone_debug.h | 275 - .../core/includes/phone_platform_constants.h | 210 - libs/sipcc/core/includes/phone_types.h | 32 - libs/sipcc/core/includes/platform_api.h | 52 - .../core/includes/pres_sub_not_handler.h | 20 - libs/sipcc/core/includes/publish_int.h | 70 - libs/sipcc/core/includes/rcc_int_types.h | 72 - libs/sipcc/core/includes/regexp.h | 83 - libs/sipcc/core/includes/ringlist.h | 22 - libs/sipcc/core/includes/rtp_defs.h | 123 - libs/sipcc/core/includes/scSession.h | 24 - libs/sipcc/core/includes/session.h | 168 - libs/sipcc/core/includes/sessionConstants.h | 364 - libs/sipcc/core/includes/sessionTypes.h | 427 - libs/sipcc/core/includes/sessuri.h | 171 - libs/sipcc/core/includes/singly_link_list.h | 117 - libs/sipcc/core/includes/sip_socket_api.h | 80 - libs/sipcc/core/includes/sntp.h | 92 - libs/sipcc/core/includes/string_lib.h | 56 - libs/sipcc/core/includes/subapi.h | 43 - libs/sipcc/core/includes/task.h | 28 - libs/sipcc/core/includes/time2.h | 192 - libs/sipcc/core/includes/timer.h | 49 - libs/sipcc/core/includes/tnpphone.h | 65 - libs/sipcc/core/includes/uart.h | 119 - libs/sipcc/core/includes/uiapi.h | 164 - libs/sipcc/core/includes/upgrade.h | 37 - libs/sipcc/core/includes/util_ios_queue.h | 59 - libs/sipcc/core/includes/util_parse.h | 12 - libs/sipcc/core/includes/util_string.h | 28 - libs/sipcc/core/includes/www.h | 25 - libs/sipcc/core/includes/xml_defs.h | 51 - libs/sipcc/core/sdp/ccsdp.c | 326 - libs/sipcc/core/sdp/sdp.h | 2010 --- libs/sipcc/core/sdp/sdp_access.c | 2847 ---- libs/sipcc/core/sdp/sdp_attr.c | 4755 ------ libs/sipcc/core/sdp/sdp_attr_access.c | 11872 --------------- libs/sipcc/core/sdp/sdp_base64.c | 394 - libs/sipcc/core/sdp/sdp_base64.h | 42 - libs/sipcc/core/sdp/sdp_config.c | 299 - libs/sipcc/core/sdp/sdp_main.c | 1463 -- libs/sipcc/core/sdp/sdp_os_defs.h | 33 - libs/sipcc/core/sdp/sdp_private.h | 311 - libs/sipcc/core/sdp/sdp_services_unix.c | 63 - libs/sipcc/core/sdp/sdp_services_win32.c | 63 - libs/sipcc/core/sdp/sdp_token.c | 1763 --- libs/sipcc/core/sdp/sdp_utils.c | 773 - libs/sipcc/core/sipstack/ccsip_callinfo.c | 677 - libs/sipcc/core/sipstack/ccsip_cc.c | 305 - libs/sipcc/core/sipstack/ccsip_common_util.c | 260 - libs/sipcc/core/sipstack/ccsip_core.c | 12298 ---------------- libs/sipcc/core/sipstack/ccsip_debug.c | 392 - libs/sipcc/core/sipstack/ccsip_info.c | 898 -- libs/sipcc/core/sipstack/ccsip_messaging.c | 7639 ---------- libs/sipcc/core/sipstack/ccsip_platform.c | 122 - libs/sipcc/core/sipstack/ccsip_platform_tcp.c | 1220 -- .../core/sipstack/ccsip_platform_timers.c | 989 -- libs/sipcc/core/sipstack/ccsip_platform_tls.c | 176 - libs/sipcc/core/sipstack/ccsip_platform_udp.c | 455 - libs/sipcc/core/sipstack/ccsip_pmh.c | 5751 -------- libs/sipcc/core/sipstack/ccsip_publish.c | 896 -- libs/sipcc/core/sipstack/ccsip_register.c | 3079 ---- libs/sipcc/core/sipstack/ccsip_reldev.c | 284 - libs/sipcc/core/sipstack/ccsip_sdp.c | 354 - libs/sipcc/core/sipstack/ccsip_spi_utils.c | 134 - libs/sipcc/core/sipstack/ccsip_subsmanager.c | 5290 ------- libs/sipcc/core/sipstack/ccsip_task.c | 3032 ---- libs/sipcc/core/sipstack/h/ccsip_callinfo.h | 86 - libs/sipcc/core/sipstack/h/ccsip_cc.h | 41 - libs/sipcc/core/sipstack/h/ccsip_common_cb.h | 56 - libs/sipcc/core/sipstack/h/ccsip_core.h | 866 -- .../sipcc/core/sipstack/h/ccsip_credentials.h | 23 - libs/sipcc/core/sipstack/h/ccsip_macros.h | 24 - libs/sipcc/core/sipstack/h/ccsip_messaging.h | 290 - libs/sipcc/core/sipstack/h/ccsip_platform.h | 65 - .../core/sipstack/h/ccsip_platform_tcp.h | 99 - .../core/sipstack/h/ccsip_platform_timers.h | 164 - .../core/sipstack/h/ccsip_platform_tls.h | 12 - .../core/sipstack/h/ccsip_platform_udp.h | 46 - libs/sipcc/core/sipstack/h/ccsip_pmh.h | 827 -- libs/sipcc/core/sipstack/h/ccsip_protocol.h | 645 - libs/sipcc/core/sipstack/h/ccsip_publish.h | 44 - libs/sipcc/core/sipstack/h/ccsip_register.h | 157 - libs/sipcc/core/sipstack/h/ccsip_reldev.h | 63 - libs/sipcc/core/sipstack/h/ccsip_sdp.h | 159 - libs/sipcc/core/sipstack/h/ccsip_sim.h | 14 - libs/sipcc/core/sipstack/h/ccsip_spi_utils.h | 22 - .../sipcc/core/sipstack/h/ccsip_subsmanager.h | 433 - libs/sipcc/core/sipstack/h/ccsip_task.h | 89 - libs/sipcc/core/sipstack/h/httpish.h | 302 - libs/sipcc/core/sipstack/h/httpish_protocol.h | 32 - libs/sipcc/core/sipstack/h/pmhdefs.h | 12 - libs/sipcc/core/sipstack/h/pmhutils.h | 163 - libs/sipcc/core/sipstack/h/regmgrapi.h | 17 - .../sipcc/core/sipstack/h/sip_ccm_transport.h | 20 - .../sipcc/core/sipstack/h/sip_common_regmgr.h | 157 - .../core/sipstack/h/sip_common_transport.h | 223 - .../core/sipstack/h/sip_csps_transport.h | 47 - .../core/sipstack/h/sip_interface_regmgr.h | 64 - .../sipcc/core/sipstack/h/sip_platform_task.h | 20 - libs/sipcc/core/sipstack/httpish.c | 1642 --- libs/sipcc/core/sipstack/pmhutils.c | 308 - libs/sipcc/core/sipstack/sip_common_regmgr.c | 3471 ----- .../core/sipstack/sip_common_transport.c | 2184 --- libs/sipcc/core/sipstack/sip_csps_transport.c | 206 - .../core/sipstack/sip_interface_regmgr.c | 313 - libs/sipcc/core/sipstack/sip_platform_task.c | 654 - .../core/sipstack/sip_platform_win32_task.c | 340 - libs/sipcc/core/src-common/configapp.c | 145 - libs/sipcc/core/src-common/dialplan.c | 1207 -- libs/sipcc/core/src-common/dialplanint.c | 1349 -- libs/sipcc/core/src-common/digcalc.c | 144 - libs/sipcc/core/src-common/kpml_common_util.c | 388 - libs/sipcc/core/src-common/kpmlmap.c | 2129 --- libs/sipcc/core/src-common/md5.c | 438 - libs/sipcc/core/src-common/misc_apps_task.c | 150 - .../core/src-common/pres_sub_not_handler.c | 1392 -- libs/sipcc/core/src-common/publish_int.c | 174 - libs/sipcc/core/src-common/singly_link_list.c | 306 - libs/sipcc/core/src-common/sll_lite.c | 258 - libs/sipcc/core/src-common/string_lib.c | 386 - libs/sipcc/core/src-common/util_ios_queue.c | 215 - libs/sipcc/core/src-common/util_parse.c | 86 - libs/sipcc/core/src-common/util_string.c | 366 - libs/sipcc/cpr/android/cpr_android_align.h | 82 - libs/sipcc/cpr/android/cpr_android_assert.h | 85 - libs/sipcc/cpr/android/cpr_android_errno.c | 184 - libs/sipcc/cpr/android/cpr_android_errno.h | 19 - libs/sipcc/cpr/android/cpr_android_in.h | 11 - libs/sipcc/cpr/android/cpr_android_init.c | 216 - libs/sipcc/cpr/android/cpr_android_ipc.c | 681 - libs/sipcc/cpr/android/cpr_android_ipc.h | 56 - libs/sipcc/cpr/android/cpr_android_locks.c | 209 - libs/sipcc/cpr/android/cpr_android_locks.h | 13 - libs/sipcc/cpr/android/cpr_android_private.h | 13 - libs/sipcc/cpr/android/cpr_android_rand.h | 15 - libs/sipcc/cpr/android/cpr_android_socket.c | 965 -- libs/sipcc/cpr/android/cpr_android_socket.h | 351 - libs/sipcc/cpr/android/cpr_android_stdio.c | 148 - libs/sipcc/cpr/android/cpr_android_stdio.h | 11 - libs/sipcc/cpr/android/cpr_android_string.c | 173 - libs/sipcc/cpr/android/cpr_android_string.h | 30 - libs/sipcc/cpr/android/cpr_android_strings.h | 10 - libs/sipcc/cpr/android/cpr_android_threads.c | 203 - libs/sipcc/cpr/android/cpr_android_time.h | 12 - libs/sipcc/cpr/android/cpr_android_timers.h | 55 - .../android/cpr_android_timers_using_select.c | 1300 -- libs/sipcc/cpr/android/cpr_android_tst.c | 61 - libs/sipcc/cpr/android/cpr_android_tst.h | 13 - libs/sipcc/cpr/android/cpr_android_types.h | 157 - libs/sipcc/cpr/common/cpr_string.c | 206 - libs/sipcc/cpr/common/strtok.c | 55 - libs/sipcc/cpr/darwin/cpr_darwin_align.h | 82 - libs/sipcc/cpr/darwin/cpr_darwin_assert.h | 86 - libs/sipcc/cpr/darwin/cpr_darwin_errno.c | 146 - libs/sipcc/cpr/darwin/cpr_darwin_errno.h | 19 - libs/sipcc/cpr/darwin/cpr_darwin_in.h | 11 - libs/sipcc/cpr/darwin/cpr_darwin_init.c | 214 - libs/sipcc/cpr/darwin/cpr_darwin_ipc.c | 685 - libs/sipcc/cpr/darwin/cpr_darwin_ipc.h | 58 - libs/sipcc/cpr/darwin/cpr_darwin_locks.c | 200 - libs/sipcc/cpr/darwin/cpr_darwin_locks.h | 12 - libs/sipcc/cpr/darwin/cpr_darwin_private.h | 13 - libs/sipcc/cpr/darwin/cpr_darwin_rand.h | 15 - libs/sipcc/cpr/darwin/cpr_darwin_socket.c | 990 -- libs/sipcc/cpr/darwin/cpr_darwin_socket.h | 313 - libs/sipcc/cpr/darwin/cpr_darwin_stdio.c | 154 - libs/sipcc/cpr/darwin/cpr_darwin_stdio.h | 11 - libs/sipcc/cpr/darwin/cpr_darwin_string.c | 174 - libs/sipcc/cpr/darwin/cpr_darwin_string.h | 49 - libs/sipcc/cpr/darwin/cpr_darwin_strings.h | 10 - libs/sipcc/cpr/darwin/cpr_darwin_threads.c | 200 - libs/sipcc/cpr/darwin/cpr_darwin_time.h | 12 - libs/sipcc/cpr/darwin/cpr_darwin_timers.h | 55 - .../darwin/cpr_darwin_timers_using_select.c | 1309 -- libs/sipcc/cpr/darwin/cpr_darwin_tst.h | 14 - libs/sipcc/cpr/darwin/cpr_darwin_types.h | 136 - libs/sipcc/cpr/include/cpr.h | 58 - libs/sipcc/cpr/include/cpr_assert.h | 39 - libs/sipcc/cpr/include/cpr_debug.h | 24 - libs/sipcc/cpr/include/cpr_errno.h | 181 - libs/sipcc/cpr/include/cpr_in.h | 30 - libs/sipcc/cpr/include/cpr_ipc.h | 165 - libs/sipcc/cpr/include/cpr_locks.h | 129 - libs/sipcc/cpr/include/cpr_memory.h | 16 - libs/sipcc/cpr/include/cpr_rand.h | 20 - libs/sipcc/cpr/include/cpr_socket.h | 702 - libs/sipcc/cpr/include/cpr_stddef.h | 13 - libs/sipcc/cpr/include/cpr_stdio.h | 70 - libs/sipcc/cpr/include/cpr_stdlib.h | 25 - libs/sipcc/cpr/include/cpr_string.h | 116 - libs/sipcc/cpr/include/cpr_strings.h | 60 - libs/sipcc/cpr/include/cpr_threads.h | 126 - libs/sipcc/cpr/include/cpr_time.h | 31 - libs/sipcc/cpr/include/cpr_timers.h | 165 - libs/sipcc/cpr/include/cpr_types.h | 109 - libs/sipcc/cpr/include/plstr.h | 42 - libs/sipcc/cpr/linux/cpr_linux_align.h | 82 - libs/sipcc/cpr/linux/cpr_linux_assert.h | 85 - libs/sipcc/cpr/linux/cpr_linux_errno.c | 184 - libs/sipcc/cpr/linux/cpr_linux_errno.h | 19 - libs/sipcc/cpr/linux/cpr_linux_in.h | 11 - libs/sipcc/cpr/linux/cpr_linux_init.c | 214 - libs/sipcc/cpr/linux/cpr_linux_ipc.c | 948 -- libs/sipcc/cpr/linux/cpr_linux_ipc.h | 56 - libs/sipcc/cpr/linux/cpr_linux_locks.c | 209 - libs/sipcc/cpr/linux/cpr_linux_locks.h | 13 - libs/sipcc/cpr/linux/cpr_linux_private.h | 13 - libs/sipcc/cpr/linux/cpr_linux_rand.h | 15 - libs/sipcc/cpr/linux/cpr_linux_socket.c | 965 -- libs/sipcc/cpr/linux/cpr_linux_socket.h | 351 - libs/sipcc/cpr/linux/cpr_linux_stdio.c | 148 - libs/sipcc/cpr/linux/cpr_linux_stdio.h | 11 - libs/sipcc/cpr/linux/cpr_linux_string.c | 173 - libs/sipcc/cpr/linux/cpr_linux_string.h | 30 - libs/sipcc/cpr/linux/cpr_linux_strings.h | 10 - libs/sipcc/cpr/linux/cpr_linux_threads.c | 203 - libs/sipcc/cpr/linux/cpr_linux_time.h | 12 - libs/sipcc/cpr/linux/cpr_linux_timers.h | 55 - .../cpr/linux/cpr_linux_timers_using_select.c | 1300 -- libs/sipcc/cpr/linux/cpr_linux_tst.c | 61 - libs/sipcc/cpr/linux/cpr_linux_tst.h | 13 - libs/sipcc/cpr/linux/cpr_linux_types.h | 157 - libs/sipcc/include/cc_blf.h | 44 - libs/sipcc/include/cc_blf_listener.h | 20 - libs/sipcc/include/cc_call_feature.h | 340 - libs/sipcc/include/cc_call_listener.h | 201 - libs/sipcc/include/cc_config.h | 289 - libs/sipcc/include/cc_constants.h | 563 - libs/sipcc/include/cc_debug.h | 35 - libs/sipcc/include/cc_device_feature.h | 35 - libs/sipcc/include/cc_device_listener.h | 76 - libs/sipcc/include/cc_info.h | 39 - libs/sipcc/include/cc_info_listener.h | 24 - libs/sipcc/include/cc_service.h | 77 - libs/sipcc/include/cc_service_listener.h | 125 - libs/sipcc/include/cc_types.h | 22 - libs/sipcc/include/ccapi_call.h | 246 - libs/sipcc/include/ccapi_call_info.h | 305 - libs/sipcc/include/ccapi_call_listener.h | 22 - libs/sipcc/include/ccapi_calllog.h | 87 - libs/sipcc/include/ccapi_conf_roster.h | 97 - libs/sipcc/include/ccapi_device.h | 136 - libs/sipcc/include/ccapi_device_info.h | 203 - libs/sipcc/include/ccapi_device_listener.h | 36 - libs/sipcc/include/ccapi_feature_info.h | 67 - libs/sipcc/include/ccapi_line.h | 43 - libs/sipcc/include/ccapi_line_info.h | 165 - libs/sipcc/include/ccapi_line_listener.h | 23 - libs/sipcc/include/ccapi_service.h | 85 - libs/sipcc/include/ccapi_types.h | 160 - libs/sipcc/include/ccsdp.h | 659 - libs/sipcc/include/config_api.h | 120 - libs/sipcc/include/dns_util.h | 82 - libs/sipcc/include/peer_connection_types.h | 35 - libs/sipcc/include/plat_api.h | 720 - libs/sipcc/include/reset_api.h | 51 - libs/sipcc/include/sll_lite.h | 137 - libs/sipcc/include/vcm.h | 1014 -- libs/sipcc/include/xml_parser_defines.h | 636 - libs/sipcc/plat/common/dns_utils.c | 165 - libs/sipcc/plat/common/plat_debug.h | 26 - libs/sipcc/plat/common/tnp_blf.h | 19 - libs/sipcc/plat/csf2g/model.c | 14 - libs/sipcc/plat/csf2g/reset_api.c | 30 - libs/sipcc/plat/darwin/netif.c | 253 - libs/sipcc/plat/darwin/plat_api_stub.c | 448 - libs/sipcc/plat/unix-common/random.c | 76 - libs/sipcc/stub/cc_blf_stub.c | 52 - libs/sipcc/stub/vcm_stub.c | 539 - 373 files changed, 184172 deletions(-) delete mode 100644 libs/sipcc/Makefile.am delete mode 100755 libs/sipcc/core/ccapp/CCProvider.h delete mode 100644 libs/sipcc/core/ccapp/call_logger.c delete mode 100644 libs/sipcc/core/ccapp/call_logger.h delete mode 100644 libs/sipcc/core/ccapp/capability_set.c delete mode 100644 libs/sipcc/core/ccapp/capability_set.h delete mode 100644 libs/sipcc/core/ccapp/cc_blf.c delete mode 100644 libs/sipcc/core/ccapp/cc_call_feature.c delete mode 100644 libs/sipcc/core/ccapp/cc_config.c delete mode 100644 libs/sipcc/core/ccapp/cc_device_feature.c delete mode 100644 libs/sipcc/core/ccapp/cc_device_manager.c delete mode 100644 libs/sipcc/core/ccapp/cc_device_manager.h delete mode 100644 libs/sipcc/core/ccapp/cc_info.c delete mode 100644 libs/sipcc/core/ccapp/cc_service.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_call.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_call_info.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_config.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_device.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_device_info.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_feature_info.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_line.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_line_info.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_service.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_snapshot.c delete mode 100644 libs/sipcc/core/ccapp/ccapi_snapshot.h delete mode 100644 libs/sipcc/core/ccapp/ccapp_task.c delete mode 100644 libs/sipcc/core/ccapp/ccapp_task.h delete mode 100755 libs/sipcc/core/ccapp/ccprovider.c delete mode 100644 libs/sipcc/core/ccapp/conf_roster.c delete mode 100644 libs/sipcc/core/ccapp/conf_roster.h delete mode 100755 libs/sipcc/core/ccapp/sessionHash.c delete mode 100755 libs/sipcc/core/ccapp/sessionHash.h delete mode 100755 libs/sipcc/core/common/cfgfile_utils.c delete mode 100755 libs/sipcc/core/common/cfgfile_utils.h delete mode 100755 libs/sipcc/core/common/config_api.c delete mode 100644 libs/sipcc/core/common/config_parser.c delete mode 100644 libs/sipcc/core/common/config_parser.h delete mode 100755 libs/sipcc/core/common/init.c delete mode 100755 libs/sipcc/core/common/logger.c delete mode 100644 libs/sipcc/core/common/logger.h delete mode 100644 libs/sipcc/core/common/logmsg.h delete mode 100644 libs/sipcc/core/common/misc.c delete mode 100644 libs/sipcc/core/common/plat.c delete mode 100755 libs/sipcc/core/common/platform_api.c delete mode 100755 libs/sipcc/core/common/prot_cfgmgr_private.h delete mode 100755 libs/sipcc/core/common/prot_configmgr.c delete mode 100755 libs/sipcc/core/common/prot_configmgr.h delete mode 100644 libs/sipcc/core/common/resource_manager.c delete mode 100644 libs/sipcc/core/common/resource_manager.h delete mode 100755 libs/sipcc/core/common/sip_socket_api.c delete mode 100755 libs/sipcc/core/common/subscription_handler.c delete mode 100755 libs/sipcc/core/common/subscription_handler.h delete mode 100755 libs/sipcc/core/common/text_strings.c delete mode 100755 libs/sipcc/core/common/text_strings.h delete mode 100755 libs/sipcc/core/common/ui.c delete mode 100755 libs/sipcc/core/gsm/ccapi.c delete mode 100644 libs/sipcc/core/gsm/ccapi_strings.c delete mode 100755 libs/sipcc/core/gsm/dcsm.c delete mode 100755 libs/sipcc/core/gsm/fim.c delete mode 100755 libs/sipcc/core/gsm/fsm.c delete mode 100755 libs/sipcc/core/gsm/fsmb2bcnf.c delete mode 100755 libs/sipcc/core/gsm/fsmcac.c delete mode 100755 libs/sipcc/core/gsm/fsmcnf.c delete mode 100755 libs/sipcc/core/gsm/fsmdef.c delete mode 100755 libs/sipcc/core/gsm/fsmxfr.c delete mode 100755 libs/sipcc/core/gsm/gsm.c delete mode 100644 libs/sipcc/core/gsm/gsm_sdp.c delete mode 100644 libs/sipcc/core/gsm/gsm_sdp_crypto.c delete mode 100755 libs/sipcc/core/gsm/h/fim.h delete mode 100755 libs/sipcc/core/gsm/h/fsm.h delete mode 100755 libs/sipcc/core/gsm/h/gsm.h delete mode 100644 libs/sipcc/core/gsm/h/gsm_sdp.h delete mode 100755 libs/sipcc/core/gsm/h/lsm.h delete mode 100644 libs/sipcc/core/gsm/h/lsm_private.h delete mode 100755 libs/sipcc/core/gsm/h/sm.h delete mode 100755 libs/sipcc/core/gsm/lsm.c delete mode 100644 libs/sipcc/core/gsm/media_cap_tbl.c delete mode 100755 libs/sipcc/core/gsm/sm.c delete mode 100755 libs/sipcc/core/gsm/subapi.c delete mode 100644 libs/sipcc/core/includes/CSFLog.h delete mode 100755 libs/sipcc/core/includes/ccSession.h delete mode 100755 libs/sipcc/core/includes/ccapi.h delete mode 100644 libs/sipcc/core/includes/check_sync.h delete mode 100644 libs/sipcc/core/includes/ci.h delete mode 100755 libs/sipcc/core/includes/config.h delete mode 100644 libs/sipcc/core/includes/configapp.h delete mode 100755 libs/sipcc/core/includes/configmgr.h delete mode 100644 libs/sipcc/core/includes/debug.h delete mode 100755 libs/sipcc/core/includes/dialplan.h delete mode 100755 libs/sipcc/core/includes/dialplanint.h delete mode 100644 libs/sipcc/core/includes/digcalc.h delete mode 100644 libs/sipcc/core/includes/dns_utils.h delete mode 100644 libs/sipcc/core/includes/dtmf.h delete mode 100644 libs/sipcc/core/includes/embedded.h delete mode 100644 libs/sipcc/core/includes/intelpentiumtypes.h delete mode 100755 libs/sipcc/core/includes/kpml_common_util.h delete mode 100755 libs/sipcc/core/includes/kpmlmap.h delete mode 100644 libs/sipcc/core/includes/md5.h delete mode 100755 libs/sipcc/core/includes/memory.h delete mode 100644 libs/sipcc/core/includes/misc_apps_task.h delete mode 100644 libs/sipcc/core/includes/misc_util.h delete mode 100644 libs/sipcc/core/includes/phntask.h delete mode 100644 libs/sipcc/core/includes/phone.h delete mode 100644 libs/sipcc/core/includes/phone_debug.h delete mode 100755 libs/sipcc/core/includes/phone_platform_constants.h delete mode 100644 libs/sipcc/core/includes/phone_types.h delete mode 100644 libs/sipcc/core/includes/platform_api.h delete mode 100644 libs/sipcc/core/includes/pres_sub_not_handler.h delete mode 100644 libs/sipcc/core/includes/publish_int.h delete mode 100755 libs/sipcc/core/includes/rcc_int_types.h delete mode 100644 libs/sipcc/core/includes/regexp.h delete mode 100755 libs/sipcc/core/includes/ringlist.h delete mode 100644 libs/sipcc/core/includes/rtp_defs.h delete mode 100755 libs/sipcc/core/includes/scSession.h delete mode 100755 libs/sipcc/core/includes/session.h delete mode 100755 libs/sipcc/core/includes/sessionConstants.h delete mode 100755 libs/sipcc/core/includes/sessionTypes.h delete mode 100644 libs/sipcc/core/includes/sessuri.h delete mode 100644 libs/sipcc/core/includes/singly_link_list.h delete mode 100755 libs/sipcc/core/includes/sip_socket_api.h delete mode 100644 libs/sipcc/core/includes/sntp.h delete mode 100755 libs/sipcc/core/includes/string_lib.h delete mode 100755 libs/sipcc/core/includes/subapi.h delete mode 100755 libs/sipcc/core/includes/task.h delete mode 100644 libs/sipcc/core/includes/time2.h delete mode 100755 libs/sipcc/core/includes/timer.h delete mode 100644 libs/sipcc/core/includes/tnpphone.h delete mode 100755 libs/sipcc/core/includes/uart.h delete mode 100644 libs/sipcc/core/includes/uiapi.h delete mode 100644 libs/sipcc/core/includes/upgrade.h delete mode 100644 libs/sipcc/core/includes/util_ios_queue.h delete mode 100644 libs/sipcc/core/includes/util_parse.h delete mode 100644 libs/sipcc/core/includes/util_string.h delete mode 100644 libs/sipcc/core/includes/www.h delete mode 100644 libs/sipcc/core/includes/xml_defs.h delete mode 100644 libs/sipcc/core/sdp/ccsdp.c delete mode 100644 libs/sipcc/core/sdp/sdp.h delete mode 100644 libs/sipcc/core/sdp/sdp_access.c delete mode 100644 libs/sipcc/core/sdp/sdp_attr.c delete mode 100644 libs/sipcc/core/sdp/sdp_attr_access.c delete mode 100644 libs/sipcc/core/sdp/sdp_base64.c delete mode 100644 libs/sipcc/core/sdp/sdp_base64.h delete mode 100644 libs/sipcc/core/sdp/sdp_config.c delete mode 100644 libs/sipcc/core/sdp/sdp_main.c delete mode 100644 libs/sipcc/core/sdp/sdp_os_defs.h delete mode 100644 libs/sipcc/core/sdp/sdp_private.h delete mode 100755 libs/sipcc/core/sdp/sdp_services_unix.c delete mode 100755 libs/sipcc/core/sdp/sdp_services_win32.c delete mode 100644 libs/sipcc/core/sdp/sdp_token.c delete mode 100644 libs/sipcc/core/sdp/sdp_utils.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_callinfo.c delete mode 100755 libs/sipcc/core/sipstack/ccsip_cc.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_common_util.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_core.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_debug.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_info.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_messaging.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_platform.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_platform_tcp.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_platform_timers.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_platform_tls.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_platform_udp.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_pmh.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_publish.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_register.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_reldev.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_sdp.c delete mode 100755 libs/sipcc/core/sipstack/ccsip_spi_utils.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_subsmanager.c delete mode 100644 libs/sipcc/core/sipstack/ccsip_task.c delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_callinfo.h delete mode 100755 libs/sipcc/core/sipstack/h/ccsip_cc.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_common_cb.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_core.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_credentials.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_macros.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_messaging.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_platform.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_platform_tcp.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_platform_timers.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_platform_tls.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_platform_udp.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_pmh.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_protocol.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_publish.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_register.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_reldev.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_sdp.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_sim.h delete mode 100755 libs/sipcc/core/sipstack/h/ccsip_spi_utils.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_subsmanager.h delete mode 100644 libs/sipcc/core/sipstack/h/ccsip_task.h delete mode 100644 libs/sipcc/core/sipstack/h/httpish.h delete mode 100644 libs/sipcc/core/sipstack/h/httpish_protocol.h delete mode 100644 libs/sipcc/core/sipstack/h/pmhdefs.h delete mode 100644 libs/sipcc/core/sipstack/h/pmhutils.h delete mode 100755 libs/sipcc/core/sipstack/h/regmgrapi.h delete mode 100644 libs/sipcc/core/sipstack/h/sip_ccm_transport.h delete mode 100644 libs/sipcc/core/sipstack/h/sip_common_regmgr.h delete mode 100644 libs/sipcc/core/sipstack/h/sip_common_transport.h delete mode 100644 libs/sipcc/core/sipstack/h/sip_csps_transport.h delete mode 100644 libs/sipcc/core/sipstack/h/sip_interface_regmgr.h delete mode 100644 libs/sipcc/core/sipstack/h/sip_platform_task.h delete mode 100644 libs/sipcc/core/sipstack/httpish.c delete mode 100644 libs/sipcc/core/sipstack/pmhutils.c delete mode 100644 libs/sipcc/core/sipstack/sip_common_regmgr.c delete mode 100644 libs/sipcc/core/sipstack/sip_common_transport.c delete mode 100644 libs/sipcc/core/sipstack/sip_csps_transport.c delete mode 100644 libs/sipcc/core/sipstack/sip_interface_regmgr.c delete mode 100644 libs/sipcc/core/sipstack/sip_platform_task.c delete mode 100755 libs/sipcc/core/sipstack/sip_platform_win32_task.c delete mode 100644 libs/sipcc/core/src-common/configapp.c delete mode 100755 libs/sipcc/core/src-common/dialplan.c delete mode 100755 libs/sipcc/core/src-common/dialplanint.c delete mode 100644 libs/sipcc/core/src-common/digcalc.c delete mode 100755 libs/sipcc/core/src-common/kpml_common_util.c delete mode 100755 libs/sipcc/core/src-common/kpmlmap.c delete mode 100644 libs/sipcc/core/src-common/md5.c delete mode 100755 libs/sipcc/core/src-common/misc_apps_task.c delete mode 100755 libs/sipcc/core/src-common/pres_sub_not_handler.c delete mode 100644 libs/sipcc/core/src-common/publish_int.c delete mode 100644 libs/sipcc/core/src-common/singly_link_list.c delete mode 100644 libs/sipcc/core/src-common/sll_lite.c delete mode 100755 libs/sipcc/core/src-common/string_lib.c delete mode 100644 libs/sipcc/core/src-common/util_ios_queue.c delete mode 100644 libs/sipcc/core/src-common/util_parse.c delete mode 100644 libs/sipcc/core/src-common/util_string.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_align.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_assert.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_errno.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_errno.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_in.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_init.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_ipc.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_ipc.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_locks.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_locks.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_private.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_rand.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_socket.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_socket.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_stdio.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_stdio.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_string.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_string.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_strings.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_threads.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_time.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_timers.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_timers_using_select.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_tst.c delete mode 100644 libs/sipcc/cpr/android/cpr_android_tst.h delete mode 100644 libs/sipcc/cpr/android/cpr_android_types.h delete mode 100644 libs/sipcc/cpr/common/cpr_string.c delete mode 100644 libs/sipcc/cpr/common/strtok.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_align.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_assert.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_errno.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_errno.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_in.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_init.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_ipc.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_ipc.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_locks.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_locks.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_private.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_rand.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_socket.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_socket.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_stdio.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_stdio.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_string.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_string.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_strings.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_threads.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_time.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_timers.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_timers_using_select.c delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_tst.h delete mode 100644 libs/sipcc/cpr/darwin/cpr_darwin_types.h delete mode 100644 libs/sipcc/cpr/include/cpr.h delete mode 100644 libs/sipcc/cpr/include/cpr_assert.h delete mode 100644 libs/sipcc/cpr/include/cpr_debug.h delete mode 100644 libs/sipcc/cpr/include/cpr_errno.h delete mode 100644 libs/sipcc/cpr/include/cpr_in.h delete mode 100644 libs/sipcc/cpr/include/cpr_ipc.h delete mode 100644 libs/sipcc/cpr/include/cpr_locks.h delete mode 100644 libs/sipcc/cpr/include/cpr_memory.h delete mode 100644 libs/sipcc/cpr/include/cpr_rand.h delete mode 100644 libs/sipcc/cpr/include/cpr_socket.h delete mode 100644 libs/sipcc/cpr/include/cpr_stddef.h delete mode 100644 libs/sipcc/cpr/include/cpr_stdio.h delete mode 100644 libs/sipcc/cpr/include/cpr_stdlib.h delete mode 100644 libs/sipcc/cpr/include/cpr_string.h delete mode 100755 libs/sipcc/cpr/include/cpr_strings.h delete mode 100644 libs/sipcc/cpr/include/cpr_threads.h delete mode 100644 libs/sipcc/cpr/include/cpr_time.h delete mode 100644 libs/sipcc/cpr/include/cpr_timers.h delete mode 100644 libs/sipcc/cpr/include/cpr_types.h delete mode 100644 libs/sipcc/cpr/include/plstr.h delete mode 100755 libs/sipcc/cpr/linux/cpr_linux_align.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_assert.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_errno.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_errno.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_in.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_init.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_ipc.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_ipc.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_locks.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_locks.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_private.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_rand.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_socket.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_socket.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_stdio.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_stdio.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_string.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_string.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_strings.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_threads.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_time.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_timers.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_timers_using_select.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_tst.c delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_tst.h delete mode 100644 libs/sipcc/cpr/linux/cpr_linux_types.h delete mode 100644 libs/sipcc/include/cc_blf.h delete mode 100644 libs/sipcc/include/cc_blf_listener.h delete mode 100644 libs/sipcc/include/cc_call_feature.h delete mode 100644 libs/sipcc/include/cc_call_listener.h delete mode 100644 libs/sipcc/include/cc_config.h delete mode 100644 libs/sipcc/include/cc_constants.h delete mode 100644 libs/sipcc/include/cc_debug.h delete mode 100644 libs/sipcc/include/cc_device_feature.h delete mode 100644 libs/sipcc/include/cc_device_listener.h delete mode 100644 libs/sipcc/include/cc_info.h delete mode 100644 libs/sipcc/include/cc_info_listener.h delete mode 100644 libs/sipcc/include/cc_service.h delete mode 100644 libs/sipcc/include/cc_service_listener.h delete mode 100644 libs/sipcc/include/cc_types.h delete mode 100644 libs/sipcc/include/ccapi_call.h delete mode 100644 libs/sipcc/include/ccapi_call_info.h delete mode 100644 libs/sipcc/include/ccapi_call_listener.h delete mode 100644 libs/sipcc/include/ccapi_calllog.h delete mode 100644 libs/sipcc/include/ccapi_conf_roster.h delete mode 100644 libs/sipcc/include/ccapi_device.h delete mode 100644 libs/sipcc/include/ccapi_device_info.h delete mode 100644 libs/sipcc/include/ccapi_device_listener.h delete mode 100644 libs/sipcc/include/ccapi_feature_info.h delete mode 100644 libs/sipcc/include/ccapi_line.h delete mode 100644 libs/sipcc/include/ccapi_line_info.h delete mode 100644 libs/sipcc/include/ccapi_line_listener.h delete mode 100644 libs/sipcc/include/ccapi_service.h delete mode 100644 libs/sipcc/include/ccapi_types.h delete mode 100644 libs/sipcc/include/ccsdp.h delete mode 100644 libs/sipcc/include/config_api.h delete mode 100644 libs/sipcc/include/dns_util.h delete mode 100644 libs/sipcc/include/peer_connection_types.h delete mode 100644 libs/sipcc/include/plat_api.h delete mode 100644 libs/sipcc/include/reset_api.h delete mode 100644 libs/sipcc/include/sll_lite.h delete mode 100755 libs/sipcc/include/vcm.h delete mode 100644 libs/sipcc/include/xml_parser_defines.h delete mode 100644 libs/sipcc/plat/common/dns_utils.c delete mode 100644 libs/sipcc/plat/common/plat_debug.h delete mode 100755 libs/sipcc/plat/common/tnp_blf.h delete mode 100644 libs/sipcc/plat/csf2g/model.c delete mode 100644 libs/sipcc/plat/csf2g/reset_api.c delete mode 100644 libs/sipcc/plat/darwin/netif.c delete mode 100755 libs/sipcc/plat/darwin/plat_api_stub.c delete mode 100644 libs/sipcc/plat/unix-common/random.c delete mode 100755 libs/sipcc/stub/cc_blf_stub.c delete mode 100755 libs/sipcc/stub/vcm_stub.c diff --git a/libs/sipcc/Makefile.am b/libs/sipcc/Makefile.am deleted file mode 100644 index 6b19ad46c1..0000000000 --- a/libs/sipcc/Makefile.am +++ /dev/null @@ -1,419 +0,0 @@ -AM_CFLAGS = -Iinclude -Icore/includes -Icpr/include -Icore/common -Icore/sipstack/h -I core/ccapp -Icore/sdp -Icore/gsm/h -Iplat/common -AUTOMAKE_OPTIONS = gnu - -AM_CPPFLAGS = $(AM_CFLAGS) - -lib_LTLIBRARIES = libsipcc.la - -CORE_CCAPP_SRC = \ -core/ccapp/call_logger.c \ -core/ccapp/capability_set.c \ -core/ccapp/cc_blf.c \ -core/ccapp/cc_call_feature.c \ -core/ccapp/cc_config.c \ -core/ccapp/cc_device_feature.c \ -core/ccapp/cc_device_manager.c \ -core/ccapp/cc_info.c \ -core/ccapp/cc_service.c \ -core/ccapp/ccapi_call.c \ -core/ccapp/ccapi_call_info.c \ -core/ccapp/ccapi_config.c \ -core/ccapp/ccapi_device.c \ -core/ccapp/ccapi_device_info.c \ -core/ccapp/ccapi_feature_info.c \ -core/ccapp/ccapi_line.c \ -core/ccapp/ccapi_line_info.c \ -core/ccapp/ccapi_service.c \ -core/ccapp/ccapi_snapshot.c \ -core/ccapp/ccapp_task.c \ -core/ccapp/ccprovider.c \ -core/ccapp/conf_roster.c \ -core/ccapp/sessionHash.c - -CORE_COMMON_SRC = \ -core/common/cfgfile_utils.c \ -core/common/config_api.c \ -core/common/config_parser.c \ -core/common/init.c \ -core/common/logger.c \ -core/common/misc.c \ -core/common/plat.c \ -core/common/platform_api.c \ -core/common/prot_configmgr.c \ -core/common/resource_manager.c \ -core/common/sip_socket_api.c \ -core/common/subscription_handler.c \ -core/common/text_strings.c \ -core/common/ui.c - -GSM_SRC = \ -core/gsm/ccapi.c \ -core/gsm/ccapi_strings.c \ -core/gsm/dcsm.c \ -core/gsm/fim.c \ -core/gsm/fsm.c \ -core/gsm/fsmb2bcnf.c \ -core/gsm/fsmcac.c \ -core/gsm/fsmcnf.c \ -core/gsm/fsmdef.c \ -core/gsm/fsmxfr.c \ -core/gsm/gsm.c \ -core/gsm/gsm_sdp.c \ -core/gsm/gsm_sdp_crypto.c \ -core/gsm/lsm.c \ -core/gsm/media_cap_tbl.c \ -core/gsm/sm.c \ -core/gsm/subapi.c - -CORE_SDP_SRC = \ -core/sdp/ccsdp.c \ -core/sdp/sdp_access.c \ -core/sdp/sdp_attr.c \ -core/sdp/sdp_attr_access.c \ -core/sdp/sdp_base64.c \ -core/sdp/sdp_config.c \ -core/sdp/sdp_main.c \ -core/sdp/sdp_services_unix.c \ -core/sdp/sdp_token.c \ -core/sdp/sdp_utils.c - -CORE_SIPSTACK_SRC = \ -core/sipstack/ccsip_callinfo.c \ -core/sipstack/ccsip_cc.c \ -core/sipstack/ccsip_common_util.c \ -core/sipstack/ccsip_core.c \ -core/sipstack/ccsip_debug.c \ -core/sipstack/ccsip_info.c \ -core/sipstack/ccsip_messaging.c \ -core/sipstack/ccsip_platform.c \ -core/sipstack/ccsip_platform_tcp.c \ -core/sipstack/ccsip_platform_timers.c \ -core/sipstack/ccsip_platform_tls.c \ -core/sipstack/ccsip_platform_udp.c \ -core/sipstack/ccsip_pmh.c \ -core/sipstack/ccsip_publish.c \ -core/sipstack/ccsip_register.c \ -core/sipstack/ccsip_reldev.c \ -core/sipstack/ccsip_sdp.c \ -core/sipstack/ccsip_spi_utils.c \ -core/sipstack/ccsip_subsmanager.c \ -core/sipstack/ccsip_task.c \ -core/sipstack/httpish.c \ -core/sipstack/pmhutils.c \ -core/sipstack/sip_common_regmgr.c \ -core/sipstack/sip_common_transport.c \ -core/sipstack/sip_csps_transport.c \ -core/sipstack/sip_interface_regmgr.c - -CORE_SIPSTACK_UNIX_SRC = core/sipstack/sip_platform_task.c - -CORE_SRCCOMMON_SRC = \ -core/src-common/configapp.c \ -core/src-common/dialplan.c \ -core/src-common/dialplanint.c \ -core/src-common/digcalc.c \ -core/src-common/kpml_common_util.c \ -core/src-common/kpmlmap.c \ -core/src-common/md5.c \ -core/src-common/misc_apps_task.c \ -core/src-common/pres_sub_not_handler.c \ -core/src-common/publish_int.c \ -core/src-common/singly_link_list.c \ -core/src-common/sll_lite.c \ -core/src-common/string_lib.c \ -core/src-common/util_ios_queue.c \ -core/src-common/util_parse.c \ -core/src-common/util_string.c - -CPR_COMMON_SRC = cpr/common/cpr_string.c cpr/common/strtok.c - -CPR_DARWIN_SRC = \ -cpr/darwin/cpr_darwin_errno.c \ -cpr/darwin/cpr_darwin_init.c \ -cpr/darwin/cpr_darwin_ipc.c \ -cpr/darwin/cpr_darwin_locks.c \ -cpr/darwin/cpr_darwin_socket.c \ -cpr/darwin/cpr_darwin_stdio.c \ -cpr/darwin/cpr_darwin_string.c \ -cpr/darwin/cpr_darwin_threads.c \ -cpr/darwin/cpr_darwin_timers_using_select.c - -CPR_LINUX_SRC = \ -cpr/linux/cpr_linux_errno.c \ -cpr/linux/cpr_linux_init.c \ -cpr/linux/cpr_linux_ipc.c \ -cpr/linux/cpr_linux_locks.c \ -cpr/linux/cpr_linux_socket.c \ -cpr/linux/cpr_linux_stdio.c \ -cpr/linux/cpr_linux_string.c \ -cpr/linux/cpr_linux_threads.c \ -cpr/linux/cpr_linux_timers_using_select.c \ -cpr/linux/cpr_linux_tst.c - -CPR_WIN32_SRC = \ -cpr/win32/cpr_win_debug.c \ -cpr/win32/cpr_win_errno.c \ -cpr/win32/cpr_win_init.c \ -cpr/win32/cpr_win_ipc.c \ -cpr/win32/cpr_win_locks.c \ -cpr/win32/cpr_win_rand.c \ -cpr/win32/cpr_win_socket.c \ -cpr/win32/cpr_win_stdio.c \ -cpr/win32/cpr_win_string.c \ -cpr/win32/cpr_win_threads.c \ -cpr/win32/cpr_win_timers.c - -PLAT_COMMON_SRC = plat/common/dns_utils.c - -PLAT_CSF2G_SRC = \ -plat/csf2g/model.c \ -plat/csf2g/reset_api.c - -PLAT_DARWIN_SRC = plat/darwin/plat_api_stub.c -#plat/darwin/netif.c - -libsipcc_la_CFLAGS = $(AM_CFLAGS) $(SWITCH_AM_CFLAGS) -libsipcc_la_LDFLAGS = $(LIBS) $(PLATFORM_CORE_LDFLAGS) - -libsipcc_la_SOURCES = $(CORE_CCAPP_SRC) $(CORE_COMMON_SRC) $(GSM_SRC) $(CORE_SDP_SRC) $(CORE_SIPSTACK_SRC) $(CORE_SRCCOMMON_SRC) $(CPR_COMMON_SRC) $(PLAT_CSF2G_SRC) - -if ISMAC -libsipcc_la_SOURCES += $(CPR_DARWIN_SRC) $(PLAT_DARWIN_SRC) -libsipcc_la_CFLAGS += -DSIP_OS_OSX -D_POSIX_SOURCE -DCPR_MEMORY_LITTLE_ENDIAN -DNO_SOCKET_POLLING -DUSE_TIMER_SELECT_BASED -DFULL_BUILD -DSTUBBED_OUT -DUSE_PRINTF -D_DARWIN_C_SOURCE -DNO_NSPR_10_SUPPORT -endif - -#if not win32 -libsipcc_la_SOURCES += $(PLAT_COMMON_SRC) $(CORE_SIPSTACK_UNIX_SRC) -if !ISMAC -libsipcc_la_CFLAGS += -DSIP_OS_LINUX -D_GNU_SOURCE -DCPR_MEMORY_LITTLE_ENDIAN -DNO_SOCKET_POLLING -DUSE_TIMER_SELECT_BASED -DFULL_BUILD -DSTUBBED_OUT -DUSE_PRINTF -DLINUX -libsipcc_la_SOURCES += $(CPR_LINUX_SRC) -endif -#endif - -library_includedir = $(prefix)/include - -library_include_HEADERS = \ -core/ccapp/call_logger.h \ -core/ccapp/capability_set.h \ -core/ccapp/cc_device_manager.h \ -core/ccapp/ccapi_snapshot.h \ -core/ccapp/ccapp_task.h \ -core/ccapp/CCProvider.h \ -core/ccapp/conf_roster.h \ -core/ccapp/sessionHash.h \ -core/common/cfgfile_utils.h \ -core/common/config_parser.h \ -core/common/logger.h \ -core/common/logmsg.h \ -core/common/prot_cfgmgr_private.h \ -core/common/prot_configmgr.h \ -core/common/resource_manager.h \ -core/common/subscription_handler.h \ -core/common/text_strings.h \ -core/gsm/h/fim.h \ -core/gsm/h/fsm.h \ -core/gsm/h/gsm.h \ -core/gsm/h/gsm_sdp.h \ -core/gsm/h/lsm.h \ -core/gsm/h/lsm_private.h \ -core/gsm/h/sm.h \ -core/includes/ccapi.h \ -core/includes/ccSession.h \ -core/includes/check_sync.h \ -core/includes/ci.h \ -core/includes/config.h \ -core/includes/configapp.h \ -core/includes/configmgr.h \ -core/includes/debug.h \ -core/includes/dialplan.h \ -core/includes/dialplanint.h \ -core/includes/digcalc.h \ -core/includes/dns_utils.h \ -core/includes/dtmf.h \ -core/includes/embedded.h \ -core/includes/intelpentiumtypes.h \ -core/includes/kpml_common_util.h \ -core/includes/kpmlmap.h \ -core/includes/md5.h \ -core/includes/memory.h \ -core/includes/misc_apps_task.h \ -core/includes/misc_util.h \ -core/includes/phntask.h \ -core/includes/phone.h \ -core/includes/phone_debug.h \ -core/includes/phone_platform_constants.h \ -core/includes/phone_types.h \ -core/includes/platform_api.h \ -core/includes/pres_sub_not_handler.h \ -core/includes/publish_int.h \ -core/includes/rcc_int_types.h \ -core/includes/regexp.h \ -core/includes/ringlist.h \ -core/includes/rtp_defs.h \ -core/includes/scSession.h \ -core/includes/session.h \ -core/includes/sessionConstants.h \ -core/includes/sessionTypes.h \ -core/includes/sessuri.h \ -core/includes/singly_link_list.h \ -core/includes/sip_socket_api.h \ -core/includes/sntp.h \ -core/includes/string_lib.h \ -core/includes/subapi.h \ -core/includes/task.h \ -core/includes/time2.h \ -core/includes/timer.h \ -core/includes/tnpphone.h \ -core/includes/uart.h \ -core/includes/uiapi.h \ -core/includes/upgrade.h \ -core/includes/util_ios_queue.h \ -core/includes/util_parse.h \ -core/includes/util_string.h \ -core/includes/www.h \ -core/includes/xml_defs.h \ -core/sdp/sdp.h \ -core/sdp/sdp_base64.h \ -core/sdp/sdp_os_defs.h \ -core/sdp/sdp_private.h \ -core/sipstack/h/ccsip_callinfo.h \ -core/sipstack/h/ccsip_cc.h \ -core/sipstack/h/ccsip_common_cb.h \ -core/sipstack/h/ccsip_core.h \ -core/sipstack/h/ccsip_credentials.h \ -core/sipstack/h/ccsip_macros.h \ -core/sipstack/h/ccsip_messaging.h \ -core/sipstack/h/ccsip_platform.h \ -core/sipstack/h/ccsip_platform_tcp.h \ -core/sipstack/h/ccsip_platform_timers.h \ -core/sipstack/h/ccsip_platform_tls.h \ -core/sipstack/h/ccsip_platform_udp.h \ -core/sipstack/h/ccsip_pmh.h \ -core/sipstack/h/ccsip_protocol.h \ -core/sipstack/h/ccsip_publish.h \ -core/sipstack/h/ccsip_register.h \ -core/sipstack/h/ccsip_reldev.h \ -core/sipstack/h/ccsip_sdp.h \ -core/sipstack/h/ccsip_sim.h \ -core/sipstack/h/ccsip_spi_utils.h \ -core/sipstack/h/ccsip_subsmanager.h \ -core/sipstack/h/ccsip_task.h \ -core/sipstack/h/httpish.h \ -core/sipstack/h/httpish_protocol.h \ -core/sipstack/h/pmhdefs.h \ -core/sipstack/h/pmhutils.h \ -core/sipstack/h/regmgrapi.h \ -core/sipstack/h/sip_ccm_transport.h \ -core/sipstack/h/sip_common_regmgr.h \ -core/sipstack/h/sip_common_transport.h \ -core/sipstack/h/sip_csps_transport.h \ -core/sipstack/h/sip_interface_regmgr.h \ -core/sipstack/h/sip_platform_task.h \ -cpr/android/cpr_android_align.h \ -cpr/android/cpr_android_assert.h \ -cpr/android/cpr_android_errno.h \ -cpr/android/cpr_android_in.h \ -cpr/android/cpr_android_ipc.h \ -cpr/android/cpr_android_locks.h \ -cpr/android/cpr_android_private.h \ -cpr/android/cpr_android_rand.h \ -cpr/android/cpr_android_socket.h \ -cpr/android/cpr_android_stdio.h \ -cpr/android/cpr_android_string.h \ -cpr/android/cpr_android_strings.h \ -cpr/android/cpr_android_time.h \ -cpr/android/cpr_android_timers.h \ -cpr/android/cpr_android_tst.h \ -cpr/android/cpr_android_types.h \ -cpr/darwin/cpr_darwin_align.h \ -cpr/darwin/cpr_darwin_assert.h \ -cpr/darwin/cpr_darwin_errno.h \ -cpr/darwin/cpr_darwin_in.h \ -cpr/darwin/cpr_darwin_ipc.h \ -cpr/darwin/cpr_darwin_locks.h \ -cpr/darwin/cpr_darwin_private.h \ -cpr/darwin/cpr_darwin_rand.h \ -cpr/darwin/cpr_darwin_socket.h \ -cpr/darwin/cpr_darwin_stdio.h \ -cpr/darwin/cpr_darwin_string.h \ -cpr/darwin/cpr_darwin_strings.h \ -cpr/darwin/cpr_darwin_time.h \ -cpr/darwin/cpr_darwin_timers.h \ -cpr/darwin/cpr_darwin_tst.h \ -cpr/darwin/cpr_darwin_types.h \ -cpr/include/cpr.h \ -cpr/include/plstr.h \ -cpr/include/cpr_assert.h \ -cpr/include/cpr_debug.h \ -cpr/include/cpr_errno.h \ -cpr/include/cpr_in.h \ -cpr/include/cpr_ipc.h \ -cpr/include/cpr_locks.h \ -cpr/include/cpr_memory.h \ -cpr/include/cpr_rand.h \ -cpr/include/cpr_socket.h \ -cpr/include/cpr_stddef.h \ -cpr/include/cpr_stdio.h \ -cpr/include/cpr_stdlib.h \ -cpr/include/cpr_string.h \ -cpr/include/cpr_strings.h \ -cpr/include/cpr_threads.h \ -cpr/include/cpr_time.h \ -cpr/include/cpr_timers.h \ -cpr/include/cpr_types.h \ -cpr/linux/cpr_linux_align.h \ -cpr/linux/cpr_linux_assert.h \ -cpr/linux/cpr_linux_errno.h \ -cpr/linux/cpr_linux_in.h \ -cpr/linux/cpr_linux_ipc.h \ -cpr/linux/cpr_linux_locks.h \ -cpr/linux/cpr_linux_private.h \ -cpr/linux/cpr_linux_rand.h \ -cpr/linux/cpr_linux_socket.h \ -cpr/linux/cpr_linux_stdio.h \ -cpr/linux/cpr_linux_string.h \ -cpr/linux/cpr_linux_strings.h \ -cpr/linux/cpr_linux_time.h \ -cpr/linux/cpr_linux_timers.h \ -cpr/linux/cpr_linux_tst.h \ -cpr/linux/cpr_linux_types.h \ -include/cc_blf.h \ -include/cc_blf_listener.h \ -include/cc_call_feature.h \ -include/cc_call_listener.h \ -include/cc_config.h \ -include/cc_constants.h \ -include/cc_debug.h \ -include/cc_device_feature.h \ -include/cc_device_listener.h \ -include/cc_info.h \ -include/cc_info_listener.h \ -include/cc_service.h \ -include/cc_service_listener.h \ -include/cc_types.h \ -include/ccapi_call.h \ -include/ccapi_call_info.h \ -include/ccapi_call_listener.h \ -include/ccapi_calllog.h \ -include/ccapi_conf_roster.h \ -include/ccapi_device.h \ -include/ccapi_device_info.h \ -include/ccapi_device_listener.h \ -include/ccapi_feature_info.h \ -include/ccapi_line.h \ -include/ccapi_line_info.h \ -include/ccapi_line_listener.h \ -include/ccapi_service.h \ -include/ccapi_types.h \ -include/ccsdp.h \ -include/config_api.h \ -include/dns_util.h \ -include/peer_connection_types.h \ -include/plat_api.h \ -include/reset_api.h \ -include/sll_lite.h \ -include/vcm.h \ -include/xml_parser_defines.h \ -plat/common/plat_debug.h \ -plat/common/tnp_blf.h - diff --git a/libs/sipcc/core/ccapp/CCProvider.h b/libs/sipcc/core/ccapp/CCProvider.h deleted file mode 100755 index 1053719eba..0000000000 --- a/libs/sipcc/core/ccapp/CCProvider.h +++ /dev/null @@ -1,144 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CCPROVIDER_H__ -#define __CCPROVIDER_H__ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_socket.h" -#include "cpr_memory.h" -#include "cpr_errno.h" -#include "cpr_in.h" -#include "cpr_rand.h" -#include "cpr_string.h" -#include "cpr_threads.h" -#include "phone_types.h" -#include "session.h" - -#include "cc_constants.h" -#include "ccapi_types.h" -#include "conf_roster.h" - -#define CC_DEVICE_ID 0 -#include "ccapi_service.h" - -typedef enum { - FAILOVER, - FALLBACK, - NO_CUCM_SRST_AVAILABLE, - NONE_AVAIL, -} Cucm_mode_t; - -typedef struct -{ - cc_reg_state_t state; - Cucm_mode_t cucm_mode; - cc_boolean inPreservation; - session_id_t preservID; - unsigned int mode; - unsigned int cause; -} CCAppGlobal_t; - -typedef struct cc_call_log_t_ { - string_t localPartyName; - string_t localPartyNumber; - string_t remotePartyName[2]; - string_t remotePartyNumber[2]; - string_t altPartyNumber[2]; - cc_log_disposition_t logDisp; - cc_call_state_t callState; - time_t startTime; - cc_uint32_t duration; -} cc_call_log_t; - -typedef struct cc_call_info_t_{ - uint32_t ref_count; - session_id_t sess_id; - line_t line; - callid_t id; - uint16_t inst; - cc_call_state_t state; - cc_call_attr_t attr; - cc_call_type_t type; - cc_call_security_t security; - cc_call_policy_t policy; - unsigned int callref; - int isSelected; - unsigned int log_disp; - string_t clg_name; - string_t clg_number; - string_t alt_number; - string_t cld_name; - string_t cld_number; - string_t orig_called_name; - string_t orig_called_number; - string_t last_redir_name; - string_t last_redir_number; - string_t plcd_name; - string_t plcd_number; - string_t status; - char gci[CC_MAX_GCID]; - cc_int32_t cause; - cc_int32_t vid_dir; - cc_int32_t vid_offer; - cc_boolean is_conf; - cc_boolean ringer_start; - cc_boolean ringer_once; - cc_int32_t ringer_mode; - cc_boolean allowed_features[CCAPI_CALL_CAP_MAX]; - cc_string_t info_package; - cc_string_t info_type; - cc_string_t info_body; - cc_call_log_t call_log; - cc_boolean audio_mute; - cc_boolean video_mute; - cc_call_conference_Info_t call_conference; - cc_string_t sdp; - unsigned int media_stream_track_id; - unsigned int media_stream_id; - const cc_media_constraints_t* cc_constraints; -} session_data_t; - -typedef enum { - NO_ACTION=0, - RESET_ACTION, - RESTART_ACTION, - RE_REGISTER_ACTION, - STOP_ACTION, - DESTROY_ACTION -} cc_action_t; - -#define CCAPP_SERVICE_CMD 1 -#define CCAPP_CREATE_SESSION 2 -#define CCAPP_CLOSE_SESSION 3 -#define CCAPP_INVOKE_FEATURE 4 -#define CCAPP_SESSION_UPDATE 5 -#define CCAPP_FEATURE_UPDATE 6 -#define CCAPP_UPDATELINES 7 -#define CCAPP_FAILOVER_IND 8 -#define CCAPP_FALLBACK_IND 9 -#define CCAPP_MODE_NOTIFY 10 -#define CCAPP_SHUTDOWN_ACK 11 -#define CCAPP_REG_ALL_FAIL 12 -#define CCAPP_INVOKEPROVIDER_FEATURE 13 -#define CCAPP_SEND_INFO 14 -#define CCAPP_RCVD_INFO 15 -#define CCAPP_LOGOUT_RESET 16 -#define CCAPP_THREAD_UNLOAD 17 -#define CCAPP_SESSION_MGMT 18 - -extern cpr_status_e ccappTaskPostMsg(unsigned int msgId, void * data, uint16_t len, int appId); -extern void ccappSyncSessionMgmt(session_mgmt_t *sessMgmt); -extern void CCApp_task(void * arg); -extern void *findhash(unsigned int key); -extern session_id_t createSessionId(line_t line, callid_t call); -extern void getLineIdAndCallId (line_t *line_id, callid_t *call_id); -extern void ccp_handler(void* msg, int type); -extern session_data_t * getDeepCopyOfSessionData(session_data_t *data); -extern void cleanSessionData(session_data_t *data); -extern cc_call_handle_t ccappGetConnectedCall(); - -#endif - diff --git a/libs/sipcc/core/ccapp/call_logger.c b/libs/sipcc/core/ccapp/call_logger.c deleted file mode 100644 index e3ec264bf8..0000000000 --- a/libs/sipcc/core/ccapp/call_logger.c +++ /dev/null @@ -1,303 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdio.h" -#include -#include "sessionHash.h" -#include "CCProvider.h" -#include "call_logger.h" - - - -void calllogger_init_call_log (cc_call_log_t *log) -{ - log->localPartyName = strlib_empty(); - log->localPartyNumber = strlib_empty(); - log->remotePartyName[0] = strlib_empty(); - log->remotePartyName[1] = strlib_empty(); - log->remotePartyNumber[0] = strlib_empty(); - log->remotePartyNumber[1] = strlib_empty(); - log->altPartyNumber[0] = strlib_empty(); - log->altPartyNumber[1] = strlib_empty(); - log->startTime = 0; - log->duration = 0; - - log->logDisp = CC_LOGD_UNKNWN; - log->callState = MAX_CALL_STATES; -} - -void calllogger_copy_call_log (cc_call_log_t *dest, cc_call_log_t * src) -{ - dest->localPartyName = strlib_copy(src->localPartyName); - dest->localPartyNumber = strlib_copy(src->localPartyNumber); - dest->remotePartyName[0] = strlib_copy(src->remotePartyName[0]); - dest->remotePartyName[1] = strlib_copy(src->remotePartyName[1]); - dest->remotePartyNumber[0] = strlib_copy(src->remotePartyNumber[0]); - dest->remotePartyNumber[1] = strlib_copy(src->remotePartyNumber[1]); - dest->altPartyNumber[0] = strlib_copy(src->altPartyNumber[0]); - dest->altPartyNumber[1] = strlib_copy(src->altPartyNumber[1]); - dest->startTime = src->startTime; - dest->duration = src->duration; - - dest->logDisp = src->logDisp; - dest->callState = src->callState; -} - -void calllogger_free_call_log (cc_call_log_t *log) -{ - strlib_free(log->localPartyName); - strlib_free(log->localPartyNumber); - strlib_free(log->remotePartyName[0]); - strlib_free(log->remotePartyName[1]); - strlib_free(log->remotePartyNumber[0]); - strlib_free(log->remotePartyNumber[1]); - strlib_free(log->altPartyNumber[0]); - strlib_free(log->altPartyNumber[1]); - - calllogger_init_call_log(log); -} - -void calllogger_print_call_log(cc_call_log_t *log) -{ - static const char *fname = "calllogger_print_call_log"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - CCLOG_DEBUG("Remote ID %s:%s %s:%s\n LocalID %s:%s \n alt %s:%s\n", - log->remotePartyName[0], log->remotePartyNumber[0], - log->remotePartyName[1], log->remotePartyNumber[1], - log->localPartyName, log->localPartyNumber, - log->altPartyNumber[0], log->altPartyNumber[1] ); - CCLOG_DEBUG("state %d \n Disp %d\n", log->callState, log->logDisp); -} - -/** - * Call logger update to be called placed call num update - */ -void calllogger_setPlacedCallInfo (session_data_t *data) -{ - static const char *fname = "calllogger_setPlacedCallInfo"; - - CCLOG_DEBUG(DEB_F_PREFIX"updating placed number for session %x to %s:%s\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->sess_id, - data->cld_name, data->cld_number); - if ( data->call_log.logDisp == CC_LOGD_RCVD ) { return;} - data->call_log.remotePartyName[0] = strlib_copy(data->plcd_name); - data->call_log.remotePartyNumber[0] = strlib_copy(data->plcd_number); - data->call_log.logDisp = CC_LOGD_SENT; - data->call_log.startTime = time(NULL); -} - -/** - * call logger api to be called for log disp update - */ -void calllogger_updateLogDisp (session_data_t *data) -{ - static const char *fname = "calllogger_updateLogDisp"; - - CCLOG_DEBUG(DEB_F_PREFIX"updating log disposition for session %x to %d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->sess_id, data->log_disp); - data->call_log.logDisp = data->log_disp; -} - -cc_boolean partyInfoPassedTheNumberFilter (cc_string_t partyString) -{ - static const char *fname = "partyInfoPassedTheNumberFilter"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - // check if partyString is something we should not be logging at this point - // Uris: CfwdALL 105 - // Conference 152 - if (partyString && strlen(partyString) > 1 && - (partyString[1] == 17 || - partyString[1] == 91 || - partyString[1] == 05 || - partyString[1] == 18 || - partyString[1] == 16 || - partyString[1] == 52 )) { - - CCLOG_DEBUG(DEB_F_PREFIX"Filtering out the partyName=%s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), partyString); - return FALSE; - } - return TRUE; -} - -/** - * partyInfoPassedTheNameFilter - * - * @param partyString String - * @return boolean - */ -cc_boolean partyInfoPassedTheNameFilter(cc_string_t partyString) { - static const char *fname = "partyInfoPassedTheNameFilter"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - // If the name String has Conference, filter it out - if (partyString && strlen(partyString) > 1 && - (partyString[1] == 52 || partyString[1] == 53)) { - CCLOG_DEBUG(DEB_F_PREFIX"Filtering out the partyName=%s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), partyString); - return FALSE; - } - return TRUE; -} - -static cc_string_t missedCallMask=NULL; -void calllogger_setMissedCallLoggingConfig(cc_string_t mask) { - static const char *fname = "calllogger_setMissedCallLoggingConfig"; - - - CCLOG_DEBUG(DEB_F_PREFIX"Entering... mask=%s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), mask); - if ( missedCallMask == NULL) { - missedCallMask = strlib_empty(); - } - missedCallMask = strlib_update(missedCallMask, mask); -} - -cc_boolean isMissedCallLoggingEnabled (unsigned int line) -{ - static const char *fname = "isMissedCallLoggingEnabled"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering... mask=%s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), missedCallMask); - if (missedCallMask == NULL) { - return TRUE; - } - - if ((line > 0) && strlen(missedCallMask) > (line-1)) { - if ( missedCallMask[line-1] == '0' ) { - return FALSE; - } - } - return TRUE; -} - - -void handlePlacedCall (session_data_t *data) -{ - static const char *fname = "handlePlacedCall"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...\n",DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - //populate calling party if not already populated - if ( data->call_log.localPartyNumber == strlib_empty() ) { - data->call_log.localPartyNumber = strlib_update(data->call_log.localPartyNumber, data->clg_number); - data->call_log.localPartyName = strlib_update(data->call_log.localPartyName, data->clg_name); - } - - // first update or update with the same number we update name and number - if ( data->call_log.remotePartyNumber[0] == strlib_empty() || - (data->cld_number[0] != 0 && strncmp(data->call_log.remotePartyNumber[0], - data->cld_number, strlen(data->cld_number)) == 0 )) { - if ( partyInfoPassedTheNameFilter(data->cld_name) && - partyInfoPassedTheNumberFilter(data->cld_number) ) - data->call_log.remotePartyNumber[0] = strlib_update(data->call_log.remotePartyNumber[0], data->cld_number); - data->call_log.remotePartyName[0] = strlib_update(data->call_log.remotePartyName[0], data->cld_name); - } - - // Start the duration count once the call reaches connected state. - if ( data->state == CONNECTED && - data->call_log.startTime == 0 ) { - data->call_log.startTime = time(NULL); - } - - if (data->state == ONHOOK ) { - // only set the duration if the call entered the connected state - if ( data->call_log.startTime != 0 ) { - data->call_log.duration = (cc_uint32_t) (time(NULL) - data->call_log.startTime); - } else { - data->call_log.startTime = time(NULL); - } - } - - data->call_log.callState = data->state; -} - - -void handleMissedOrReceviedCall ( session_data_t *data ) -{ - static const char *fname = "handleMissedOrReceviedCall"; - int line = GET_LINE_ID(data->sess_id); - cc_string_t localName = strlib_empty(), localNumber = strlib_empty(); - cc_string_t remoteName = strlib_empty(), remoteNumber = strlib_empty(); - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (data->type == CC_CALL_TYPE_INCOMING || data->type == CC_CALL_TYPE_FORWARDED ) { - localName = data->cld_name; - localNumber = data->cld_number; - remoteName = data->clg_name; - remoteNumber = data->clg_number; - } else { - localName = data->clg_name; - localNumber = data->clg_number; - remoteName = data->cld_name; - remoteNumber = data->cld_number; - } - - if ( data->call_log.localPartyNumber == strlib_empty() ) { - data->call_log.localPartyNumber = strlib_update(data->call_log.localPartyNumber, localNumber); - data->call_log.localPartyName = strlib_update(data->call_log.localPartyName, localName); - } - - // first update or update with the same number we update name and number - if ( data->call_log.remotePartyNumber[0] == strlib_empty() || - (remoteNumber[0] != 0 && strncmp(data->call_log.remotePartyNumber[0], - remoteNumber, strlen(remoteNumber)) == 0 )) { - data->call_log.remotePartyNumber[0] = strlib_update(data->call_log.remotePartyNumber[0], remoteNumber); - data->call_log.altPartyNumber[0] = strlib_update(data->call_log.altPartyNumber[0], data->alt_number); - if (data->call_log.remotePartyName[0] == strlib_empty() ) { - data->call_log.remotePartyName[0] = strlib_update(data->call_log.remotePartyName[0], remoteName); - } - } else { - // since number doesn't match this is a new leg - data->call_log.remotePartyName[1] = strlib_update(data->call_log.remotePartyName[1], remoteName); - data->call_log.remotePartyNumber[1] = strlib_update(data->call_log.remotePartyNumber[1], remoteNumber); - data->call_log.altPartyNumber[1] = strlib_update(data->call_log.altPartyNumber[1], data->alt_number); - } - - if ( data->state == ONHOOK ) { - if ( data->call_log.callState == RINGIN ) { - data->call_log.startTime = time(NULL); - if (isMissedCallLoggingEnabled(line)) { - data->call_log.logDisp = CC_LOGD_MISSED; - } else { - data->call_log.logDisp = CC_LOGD_DELETE; - } - data->call_log.startTime = time(NULL); - data->call_log.duration = 0; //missed call duration is 0 - } else if ( data->call_log.startTime != 0 ){ - //connected call going onhook update duration - data->call_log.duration = (cc_uint32_t) (time(NULL) - data->call_log.startTime); - } - } - - if ( data->state == CONNECTED && data->call_log.startTime == 0 ) { - data->call_log.logDisp = CC_LOGD_RCVD; - data->call_log.startTime = time(NULL); - } - - data->call_log.callState = data->state; -} - - -/** - * Call logger update to be called on attr or callinfo or state events - */ -void calllogger_update (session_data_t *data) -{ - static const char *fname = "calllogger_update"; - - CCLOG_DEBUG(DEB_F_PREFIX"Entering...\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - if (data->call_log.logDisp == CC_LOGD_DELETE) { - CCLOG_DEBUG(DEB_F_PREFIX"log disposition set to delete. Ignoring call logging for sess_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->sess_id); - } - - if (data->call_log.logDisp == CC_LOGD_RCVD || data->call_log.logDisp == CC_LOGD_MISSED || - data->type == CC_CALL_TYPE_INCOMING || data->type == CC_CALL_TYPE_FORWARDED ) { - handleMissedOrReceviedCall(data); - } else if ( data->call_log.logDisp == CC_LOGD_SENT || - data->type == CC_CALL_TYPE_OUTGOING ) { - handlePlacedCall (data); - } - -} diff --git a/libs/sipcc/core/ccapp/call_logger.h b/libs/sipcc/core/ccapp/call_logger.h deleted file mode 100644 index 6ccec2e274..0000000000 --- a/libs/sipcc/core/ccapp/call_logger.h +++ /dev/null @@ -1,20 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CALL_LOGGER_H__ -#define __CALL_LOGGER_H__ - -#include "cc_types.h" -#include "CCProvider.h" - -void calllogger_init_call_log(cc_call_log_t *log); -void calllogger_copy_call_log(cc_call_log_t *dest, cc_call_log_t * src); -void calllogger_free_call_log(cc_call_log_t *log); -void calllogger_print_call_log(cc_call_log_t *log); -void calllogger_setPlacedCallInfo(session_data_t *data); -void calllogger_updateLogDisp(session_data_t *data); -void calllogger_setMissedCallLoggingConfig(cc_string_t mask); -void calllogger_update(session_data_t *data); - -#endif diff --git a/libs/sipcc/core/ccapp/capability_set.c b/libs/sipcc/core/ccapp/capability_set.c deleted file mode 100644 index 71471fb60d..0000000000 --- a/libs/sipcc/core/ccapp/capability_set.c +++ /dev/null @@ -1,281 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "capability_set.h" -#include "CCProvider.h" - -// -------------------------------------------------------------------------------- -// Data Structures Used to Store the Capability Set Information -// Settings on kept on a per call state, per feature basis. -// Includes all general endpoint capabilities, plus fcp-controlled ones -// -------------------------------------------------------------------------------- -static cc_boolean capability_set[MAX_CALL_STATES][CCAPI_CALL_CAP_MAX]; -static cc_boolean capability_idleset[CCAPI_CALL_CAP_MAX]; - - -// -------------------------------------------------------------------------------- -// Data Structures Used to Store the Parsed FCP information from UCM/FCP file -// (after parse will be used to selectively set capabilities in the above also) -// -------------------------------------------------------------------------------- - -// maximum number of features -#define FCP_FEATURE_MAX 9 - -char g_fp_version_stamp[MAX_FP_VERSION_STAMP_LEN]; -static cc_feature_control_policy_info_t cc_feat_control_policy[FCP_FEATURE_MAX]; -static ccapi_call_capability_e cc_fcp_id_to_capability_map[FCP_FEATURE_MAX+1]; // 0th entry of map is not used/null entry - - -static const unsigned int CALL_FORWARD_ALL_FCP_INDEX = 1; -static const unsigned int CONFERENCE_LIST_FCP_INDEX = 4; -static const unsigned int SPEED_DIAL_FCP_INDEX = 5; -static const unsigned int CALL_BACK_FCP_INDEX = 6; -static const unsigned int REDIAL_FCP_INDEX = 7; - -static int fcp_index = -1; - -// -------------------------------------------------------------------------------- - - -/* - * capset_set_fcp_forwardall - sets the fcp-controlled call forward all feature - * - */ -static void capset_set_fcp_forwardall (cc_boolean state) -{ - CONFIG_DEBUG(DEB_F_PREFIX"FCP Setting CALLFWD Capability to [%d]\n", DEB_F_PREFIX_ARGS(JNI, "capset_set_fcp_forwardall"), (unsigned int)state); - - capability_idleset[CCAPI_CALL_CAP_CALLFWD] = state; - capability_set[OFFHOOK][CCAPI_CALL_CAP_CALLFWD] = state; -} - -/* - * capset_set_fcp_redial - sets the fcp-controlled redial feature - * - */ -static void capset_set_fcp_redial (cc_boolean state) -{ - CONFIG_DEBUG(DEB_F_PREFIX"FCP Setting REDIAL capability to [%d]\n", DEB_F_PREFIX_ARGS(JNI, "capset_set_fcp_redial"), (unsigned int)state); - - capability_idleset[CCAPI_CALL_CAP_REDIAL] = state; - capability_set[OFFHOOK][CCAPI_CALL_CAP_REDIAL] = state; - capability_set[ONHOOK][CCAPI_CALL_CAP_REDIAL] = state; -} - -// -------------------------------------------------------------------------------- - - -/* - * fcp_set_index - sets a given feture index number (from fcp xml file), maps it to the internal - * call capability, and sets the appropriate state-based capability for the feature index - * - */ -static void fcp_set_index (unsigned int fcpCapabilityId, cc_boolean state) -{ - ccapi_call_capability_e capabilityId = CCAPI_CALL_CAP_MAX; - - // range check the capability index - if ((fcpCapabilityId <= 0) || (fcpCapabilityId > FCP_FEATURE_MAX)) - { - CONFIG_ERROR(CFG_F_PREFIX "Unable to set capability of unknown feature [%d] in FCP \n", "fcp_set_index", fcpCapabilityId); - return; - } - - // convert the fcp index to an fcp capability id - capabilityId = cc_fcp_id_to_capability_map[fcpCapabilityId]; - - - // based on the capability id, invoke the appropate method specific to that capability - switch (capabilityId) - { - case CCAPI_CALL_CAP_CALLFWD : capset_set_fcp_forwardall (state); break; - case CCAPI_CALL_CAP_REDIAL : capset_set_fcp_redial (state); break; - default : - { - CONFIG_ERROR(CFG_F_PREFIX "Unable to update settings for capability [%d]\n", "fcp_set_index", (int)capabilityId); - break; - } - } -} - -/* - * capset_init - initialize the internal capability data structures to defaults - * - */ -static void capset_init () -{ - // initialize the 4 tables related to capability set to false - memset(capability_idleset, 0, sizeof(capability_idleset)); - memset(capability_set, 0, sizeof(capability_set)); - - // ---------------------------------------------------------------------- - // FCP based capabilities - // ---------------------------------------------------------------------- - - CONFIG_DEBUG(DEB_F_PREFIX"FCP Initializing Capabilities to default\n", DEB_F_PREFIX_ARGS(JNI, "capset_init")); - - // ---------------------------------------------------------------------- - // Non-FCP-based Capabilities - // ---------------------------------------------------------------------- - - // Now, set all the non-FCP based capabilities to appropriate default settings - // (some of which may be enabled by default) - - capability_idleset[CCAPI_CALL_CAP_NEWCALL] = TRUE; - - // call-state based settings - // offhook - capability_set[OFFHOOK][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // onhook - capability_set[ONHOOK][CCAPI_CALL_CAP_NEWCALL] = TRUE; - - // ringout - capability_set[RINGOUT][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // ringing - capability_set[RINGIN][CCAPI_CALL_CAP_ANSWER] = TRUE; - - // proceed - capability_set[PROCEED][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // connected - capability_set[CONNECTED][CCAPI_CALL_CAP_ENDCALL] = TRUE; - capability_set[CONNECTED][CCAPI_CALL_CAP_HOLD] = TRUE; - capability_set[CONNECTED][CCAPI_CALL_CAP_TRANSFER] = TRUE; - capability_set[CONNECTED][CCAPI_CALL_CAP_CONFERENCE] = TRUE; - capability_set[CONNECTED][CCAPI_CALL_CAP_SELECT] = TRUE; - - // hold - capability_set[HOLD][CCAPI_CALL_CAP_RESUME] = TRUE; - capability_set[REMHOLD][CCAPI_CALL_CAP_RESUME] = TRUE; - - // busy - capability_set[BUSY][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // reorder - capability_set[REORDER][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // dialing - capability_set[DIALING][CCAPI_CALL_CAP_ENDCALL] = TRUE; - capability_set[DIALING][CCAPI_CALL_CAP_DIAL] = TRUE; - capability_set[DIALING][CCAPI_CALL_CAP_SENDDIGIT] = TRUE; - capability_set[DIALING][CCAPI_CALL_CAP_BACKSPACE] = TRUE; - - // holdrevert - capability_set[HOLDREVERT][CCAPI_CALL_CAP_ANSWER] = TRUE; - - // preservation - capability_set[PRESERVATION][CCAPI_CALL_CAP_ENDCALL] = TRUE; - - // waiting for digits - capability_set[WAITINGFORDIGITS][CCAPI_CALL_CAP_SENDDIGIT] = TRUE; - capability_set[WAITINGFORDIGITS][CCAPI_CALL_CAP_BACKSPACE] = TRUE; -} - - -/* - * capset_get_idleset - get the set of features associated with idle state - * - */ -void capset_get_idleset ( cc_cucm_mode_t mode, cc_boolean features[]) -{ - static const char fname[] = "capset_get_idleset"; - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"updating idleset", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - for (i=0;i < CCAPI_CALL_CAP_MAX; i++) { - CCAPP_DEBUG(DEB_F_PREFIX"updating line features %d=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), i, capability_idleset[i]); - features[i] = capability_idleset[i]; - } - -} - -/* - * capset_get_allowed_features - get the set of features - * - */ -void capset_get_allowed_features ( cc_cucm_mode_t mode, cc_call_state_t state, cc_boolean features[]) -{ - static const char fname[] = "capset_get_allowed_features"; - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"updating idleset", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - for (i=0;i < CCAPI_CALL_CAP_MAX; i++) { - features[i] = capability_set[state][i]; - } - -} - -// -------------------------------------------------------------------------------------------------------- -// ---------------------------- XML Parse Logic for Feature Control Policy -------------------------------- -// -------------------------------------------------------------------------------------------------------- - -/* - * fcp_set_capabilities - updates the capabilities structure, based on the now parsed information - * from fcp xml file - * - */ - -static void fcp_set_capabilities() -{ - int my_fcp_index = 0; - - if ( (fcp_index+1) >= FCP_FEATURE_MAX) { - fcp_index = (FCP_FEATURE_MAX -1); - CONFIG_ERROR(CFG_F_PREFIX "Received more than the maximum supported features [%d] in FCP \n", "fcp_set_capabilities", FCP_FEATURE_MAX); - - } - // loop over all the FCP features parsed, and for each one, based on ID, and enabled settings, - // update the corresponding call capability flags - for (my_fcp_index = 0; my_fcp_index <= fcp_index; my_fcp_index++) - { // set the capability if fcp file has it marked as 'enabled' - fcp_set_index(cc_feat_control_policy[my_fcp_index].featureId, (cc_feat_control_policy[my_fcp_index].featureEnabled == TRUE)); - } -} - -/* - * fcp_init - initialize the data structure used to store the fcp parse info - * - */ -static void fcp_init() -{ - // master index; set to null - fcp_index = -1; - - // initialize the map of fcp xml feature indexes to internal call capabilities - cc_fcp_id_to_capability_map[CALL_FORWARD_ALL_FCP_INDEX] = CCAPI_CALL_CAP_CALLFWD; - cc_fcp_id_to_capability_map[REDIAL_FCP_INDEX] = CCAPI_CALL_CAP_REDIAL; - - // initialize the capability set data structures - capset_init(); - - // initialize the version - g_fp_version_stamp[0] = '\0'; -} - -/* - * capset_set_fcp_forwardall - sets the fcp-controlled call forward all feature - * - */ -int fcp_init_template (const char* fcp_plan_string) -{ - fcp_init(); - - if (fcp_plan_string == NULL) - { // set up the default fcp - return (0); - } - - // update the fcp capabilities structure, based on the parsed feature information - fcp_set_capabilities(); - - return (0); -} -// ---------------------------- End Of XML Parse Logic for Feature Control Policy -------------------------- diff --git a/libs/sipcc/core/ccapp/capability_set.h b/libs/sipcc/core/ccapp/capability_set.h deleted file mode 100644 index bad517a70a..0000000000 --- a/libs/sipcc/core/ccapp/capability_set.h +++ /dev/null @@ -1,33 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CC_CAPABILITY_SET_H_ -#define _CC_CAPABILITY_SET_H_ - -#include "ccapi_types.h" - -extern void capset_get_idleset( cc_cucm_mode_t mode, cc_boolean features[]); -extern void capset_get_allowed_features( cc_cucm_mode_t mode, cc_call_state_t state, cc_boolean features[]); - -// FCP (feature control policy) methods -int fcp_init_template (const char* fcp_plan_string); - -// FCP Definitions -#define FCP_MAX_SIZE 0x5000 -#define FCP_FEATURE_NAME_MAX 24 -#define MAX_FP_VERSION_STAMP_LEN (64+1) - -extern char g_fp_version_stamp[MAX_FP_VERSION_STAMP_LEN]; - - -// for each feature in the XML FCP file, we'll receive the -// feature name, featureId, and whether or not it is enabled -typedef struct cc_feature_control_policy_info_t_ -{ - char featureName[FCP_FEATURE_NAME_MAX]; - unsigned int featureId; - cc_boolean featureEnabled; -} cc_feature_control_policy_info_t; - -#endif /* _CC_CAPABILITY_SET_H_ */ diff --git a/libs/sipcc/core/ccapp/cc_blf.c b/libs/sipcc/core/ccapp/cc_blf.c deleted file mode 100644 index 49c500248a..0000000000 --- a/libs/sipcc/core/ccapp/cc_blf.c +++ /dev/null @@ -1,50 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_blf.h" -#include "pres_sub_not_handler.h" - -/** - * Initialize the BLF stack - * @return - */ -int CC_BLF_init() { - pres_sub_handler_initialized(); - return CC_SUCCESS; -} -/** - * Start BLF subscription - * @param request_id the request id - * @param duration the subscription duration - * @param watcher the name of subscription watcher - * @param presentity - * @param app_id the application id for the BLF - * @param feature_mask - * @return void - */ -void CC_BLF_subscribe(int request_id, - int duration, - const char *watcher, - const char *presentity, - int app_id, - cc_blf_feature_mask_t feature_mask) { - pres_get_state(request_id, duration, watcher, presentity, app_id, feature_mask); -} -/** - * Unsubscribe the BLF subscription - * @param request_id the request id - * @return void - */ -void CC_BLF_unsubscribe(int request_id) { - pres_terminate_req(request_id); -} - -/** - * Unsubscribe all BLF subscription - * @return void - */ -void CC_BLF_unsubscribe_All() { - pres_terminate_req_all(); -} - diff --git a/libs/sipcc/core/ccapp/cc_call_feature.c b/libs/sipcc/core/ccapp/cc_call_feature.c deleted file mode 100644 index 529affa072..0000000000 --- a/libs/sipcc/core/ccapp/cc_call_feature.c +++ /dev/null @@ -1,681 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_call_feature.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "sessionTypes.h" -#include "lsm.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "ccapi.h" -#include "ccapp_task.h" -#include "sessionHash.h" -#include "cpr_rand.h" - -extern cpr_status_e ccappTaskPostMsg(unsigned int msgId, void * data, uint16_t len, int appId); - -/** - * Internal method: create call handle - * @param line - * @paran call_id - */ -cc_call_handle_t cc_createCallHandle(cc_lineid_t line, cc_callid_t call_id) -{ - return (CREATE_CALL_HANDLE(line, call_id)); -} - -/** - * Internal method: assign a valid call id. - * @param line_id line number - * @param call_id call id - * @return void - */ -void cc_getLineIdAndCallId (cc_lineid_t *line_id, cc_callid_t *call_id) -{ - // assign proper line_id and call_id if not already there - if ((*line_id) == 0 || (*line_id) == CC_ALL_LINES) { - /* - * If the filter is the All Calls Complex Filter and the primary line - * is at its configured call capacity, the next available line should - * be used. In this scenario, sessionUI/Mgr send the line_id as zero. - */ - (*line_id) = lsm_get_available_line(FALSE); - } - - if ((*call_id) == 0) { - (*call_id) = cc_get_new_call_id(); - } -} - -/** - * Invoke a call feature. - */ -cc_return_t cc_invokeFeature(cc_call_handle_t call_handle, group_cc_feature_t featureId, cc_sdp_direction_t video_pref, string_t data) { - session_feature_t callFeature; - callFeature.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + call_handle; - callFeature.featureID = featureId; - callFeature.featData.ccData.state = video_pref; - - CCAPP_DEBUG(DEB_F_PREFIX"cc_invokeFeature:sid=%d, line=%d, cid=%d, fid=%d, video_pref=%s data=%s\n", - DEB_F_PREFIX_ARGS("cc_call_feature", "cc_invokeFeature"), - callFeature.session_id, - GET_LINE_ID(call_handle), - GET_CALL_ID(call_handle), - featureId, SDP_DIRECTION_PRINT(video_pref), - ((featureId == CC_FEATURE_KEYPRESS) ? "...": data)); - - switch (featureId) { - case CC_FEATURE_KEYPRESS: - case CC_FEATURE_DIALSTR: - case CC_FEATURE_SPEEDDIAL: - case CC_FEATURE_BLIND_XFER_WITH_DIALSTRING: - case CC_FEATURE_END_CALL: - case CC_FEATURE_B2BCONF: - case CC_FEATURE_CONF: - case CC_FEATURE_XFER: - case CC_FEATURE_HOLD: - callFeature.featData.ccData.info = strlib_malloc(data, strlen(data)); - callFeature.featData.ccData.info1 = NULL; - break; - - default: - callFeature.featData.ccData.info = NULL; - callFeature.featData.ccData.info1 = NULL; - break; - } - - if (ccappTaskPostMsg(CCAPP_INVOKE_FEATURE, &callFeature, sizeof(session_feature_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG(DEB_F_PREFIX"ccappTaskSendMsg failed\n", - DEB_F_PREFIX_ARGS("cc_call_feature", "cc_invokeFeature")); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/** - * Invoke a call feature. - */ -cc_return_t cc_invokeFeatureSDPMode(cc_call_handle_t call_handle, group_cc_feature_t featureId, cc_jsep_action_t action, - cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type, - uint16_t level, const cc_media_constraints_t *constraints, string_t data, string_t data1) { - session_feature_t callFeature; - session_data_t * sessionData; - unsigned int session_id = 0; - callFeature.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + call_handle; - callFeature.featureID = featureId; - callFeature.featData.ccData.action = action; - callFeature.featData.ccData.media_type = media_type; - callFeature.featData.ccData.stream_id = stream_id; - callFeature.featData.ccData.track_id = track_id; - callFeature.featData.ccData.level = level; - callFeature.featData.ccData.has_constraints = FALSE; - - /* If constraints exist add to session hash */ - if (constraints) { - if (constraints->constraint_count > 0 && - (CC_FEATURE_CREATEOFFER == featureId || CC_FEATURE_CREATEANSWER == featureId )) { - /* A random number of 5 digits will not conflict with any - * other usage of the hash table */ - session_id = abs(cpr_rand()) % 60000; - sessionData = (session_data_t *)findhash(session_id); - sessionData = cpr_malloc(sizeof(session_data_t)); - memset(sessionData, 0, sizeof(session_data_t)); - sessionData->cc_constraints = constraints; - (void) addhash(session_id, sessionData); - callFeature.featData.ccData.sessionid = session_id; - callFeature.featData.ccData.has_constraints = TRUE; - } - } - - CCAPP_DEBUG(DEB_F_PREFIX"cc_invokeFeatureSDPMode:sid=%d, line=%d, cid=%d, fid=%d, video_pref=%s data=%s\n", - DEB_F_PREFIX_ARGS("cc_call_feature", "cc_invokeFeatureSDPMode"), - callFeature.session_id, - GET_LINE_ID(call_handle), - GET_CALL_ID(call_handle), - featureId, - ((featureId == CC_FEATURE_KEYPRESS) ? "...": data)); - - switch (featureId) { - case CC_FEATURE_KEYPRESS: - case CC_FEATURE_DIALSTR: - case CC_FEATURE_SPEEDDIAL: - case CC_FEATURE_BLIND_XFER_WITH_DIALSTRING: - case CC_FEATURE_END_CALL: - case CC_FEATURE_B2BCONF: - case CC_FEATURE_CONF: - case CC_FEATURE_XFER: - case CC_FEATURE_HOLD: - case CC_FEATURE_SETLOCALDESC: - case CC_FEATURE_SETREMOTEDESC: - case CC_FEATURE_SETPEERCONNECTION: - callFeature.featData.ccData.info = strlib_malloc(data, strlen(data)); - callFeature.featData.ccData.info1 = NULL; - break; - case CC_FEATURE_ADDICECANDIDATE: - callFeature.featData.ccData.info = strlib_malloc(data, strlen(data)); - callFeature.featData.ccData.info1 = strlib_malloc(data1, strlen(data1)); - break; - - default: - callFeature.featData.ccData.info = NULL; - callFeature.featData.ccData.info1 = NULL; - break; - } - - if (ccappTaskPostMsg(CCAPP_INVOKE_FEATURE, &callFeature, sizeof(session_feature_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG(DEB_F_PREFIX"ccappTaskSendMsg failed\n", - DEB_F_PREFIX_ARGS("cc_call_feature", "cc_invokeFeatureSDPMode")); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/***********************************Basic Call Feature Control Methods************************************ - * This section defines all the call related methods that an upper layer can use to control - * a call in progress. - */ - -/** - * Used to create any outgoing call regular call. The incoming/reverting/consultation call will be - * created by the stack. It creates a call place holder and initialize the memory for a call. An user needs - * other methods to start the call, such as the method OriginateCall, etc - * @param line line number that is invoked and is assigned - * @return call handle wich includes the assigned line and call id - */ -cc_call_handle_t CC_createCall(cc_lineid_t line) { - static const char fname[] = "CC_CreateCall"; - //Create call handle to initialize the memory. - cc_call_handle_t call_handle = CC_EMPTY_CALL_HANDLE; - cc_lineid_t lineid = line; - cc_callid_t callid = CC_NO_CALL_ID; - - - //Assign line and call id. - cc_getLineIdAndCallId(&lineid, &callid); - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, callid, lineid, fname)); - - if (lineid == CC_NO_LINE) { - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return call_handle; - } - - call_handle = cc_createCallHandle(lineid, callid); - - return call_handle; -} - -/** - * Start the call that was created. - * @param the call handle - * @return SUCCESS or FAILURE - */ - /*move it up...*/ -cc_return_t CC_CallFeature_originateCall(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_originateCall:"; - //CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - // GET_LINE_ID(call_handle), fname)); - CCAPP_DEBUG(DEB_F_PREFIX"CC_CallFeature_originateCall:cHandle=%d\n", - DEB_F_PREFIX_ARGS("cc_call_feature", fname), - call_handle); - return cc_invokeFeature(call_handle, CC_FEATURE_OFFHOOK, video_pref, NULL); -} - -/** - * Terminate or end a normal call. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_terminateCall(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_TerminateCall"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_ONHOOK, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Answer an incoming or reverting call. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_answerCall(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_AnswerCall"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_ANSWER, video_pref, NULL); -} - -/** - * Send a keypress to a call, it could be a single digit. - * @param call handle - * @param cc_digit digit pressed - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_sendDigit(cc_call_handle_t call_handle, cc_digit_t cc_digit) { - static const char fname[] = "CC_CallFeature_SendDigit"; - char digit; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - //Demote to eliminate the endian issue - digit = cc_digit; - return cc_invokeFeature(call_handle, CC_FEATURE_KEYPRESS, CC_SDP_MAX_QOS_DIRECTIONS, (string_t)&digit); -} - -/** - * Send a backspace action. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_backSpace(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_BackSpace"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_BKSPACE, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Send a dial digit string on an active call, e.g."9191234567". - * @param call handle - * @param numbers dialed string - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_dial(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref, const string_t numbers) { - static const char fname[] = "CC_CallFeature_Dial"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - if (cpr_strcasecmp(numbers, "DIAL") == 0) { - return cc_invokeFeature(call_handle, CC_FEATURE_DIAL, video_pref, numbers); - } - - return cc_invokeFeature(call_handle, CC_FEATURE_DIALSTR, video_pref, numbers); -} - -cc_return_t CC_CallFeature_CreateOffer(cc_call_handle_t call_handle, const cc_media_constraints_t *constraints) { - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), __FUNCTION__)); - - return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_CREATEOFFER, JSEP_NO_ACTION, - 0, 0, NO_STREAM, 0, constraints, NULL, NULL); -} - -cc_return_t CC_CallFeature_CreateAnswer(cc_call_handle_t call_handle, const cc_media_constraints_t *constraints) { - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), __FUNCTION__)); - - return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_CREATEANSWER, JSEP_NO_ACTION, - 0, 0, NO_STREAM, 0, constraints, NULL, NULL); -} - -cc_return_t CC_CallFeature_SetLocalDescription(cc_call_handle_t call_handle, cc_jsep_action_t action, string_t sdp) { - const cc_media_constraints_t *constraints = NULL; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), __FUNCTION__)); - - return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_SETLOCALDESC, action, - 0, 0, NO_STREAM, 0, constraints, sdp, NULL); -} - -cc_return_t CC_CallFeature_SetRemoteDescription(cc_call_handle_t call_handle, cc_jsep_action_t action, string_t sdp) { - const cc_media_constraints_t *constraints = NULL; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), __FUNCTION__)); - - return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_SETREMOTEDESC, action, - 0, 0, NO_STREAM, 0, constraints, sdp, NULL); -} - -cc_return_t CC_CallFeature_SetPeerConnection(cc_call_handle_t call_handle, cc_peerconnection_t pc) { - const cc_media_constraints_t *constraints = NULL; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), __FUNCTION__)); - - return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_SETPEERCONNECTION, JSEP_NO_ACTION, - 0, 0, NO_STREAM, 0, constraints, pc, NULL); -} - -cc_return_t CC_CallFeature_AddStream(cc_call_handle_t call_handle, cc_media_stream_id_t stream_id, - cc_media_track_id_t track_id, cc_media_type_t media_type) { - const cc_media_constraints_t *constraints = NULL; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), __FUNCTION__)); - - return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_ADDSTREAM, JSEP_NO_ACTION, - stream_id, track_id, media_type, 0, constraints, NULL, NULL); -} - -cc_return_t CC_CallFeature_RemoveStream(cc_call_handle_t call_handle, cc_media_stream_id_t stream_id, - cc_media_track_id_t track_id, cc_media_type_t media_type) { - - const cc_media_constraints_t *constraints = NULL; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), __FUNCTION__)); - - return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_REMOVESTREAM, JSEP_NO_ACTION, - stream_id, track_id, media_type, 0, constraints, NULL, NULL); -} - -cc_return_t CC_CallFeature_AddICECandidate(cc_call_handle_t call_handle, const char* candidate, const char *mid, cc_level_t level) { - const cc_media_constraints_t *constraints = NULL; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), __FUNCTION__)); - - return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_ADDICECANDIDATE, JSEP_NO_ACTION, - 0, 0, NO_STREAM, (uint16_t)level, constraints, candidate, mid); -} - -/** - * Initiate a speed dial. - * @param call handle - * @param callid call id - * @param speed dial numbers. - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_speedDial(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref, const string_t speed_dial_number) { - static const char fname[] = "CC_CallFeature_SpeedDial"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_SPEEDDIAL, video_pref, speed_dial_number); -} - -/** - * Initiate a BLF call pickup. - * @param call handle - * @param speed dial number configured. - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_blfCallPickup(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref, const string_t speed_dial_number) { - static const char fname[] = "CC_CallFeature_BLFCallPickup"; - cc_return_t ret = CC_SUCCESS; - string_t blf_sd = strlib_malloc(CISCO_BLFPICKUP_STRING, sizeof(CISCO_BLFPICKUP_STRING)); - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - blf_sd = strlib_append(blf_sd, "-"); - blf_sd = strlib_append(blf_sd, speed_dial_number); - - ret = cc_invokeFeature(call_handle, CC_FEATURE_SPEEDDIAL, video_pref, blf_sd); - //free memory - strlib_free(blf_sd); - return ret; -} - -/** - * Redial the last dial numbers. - * @param call handle - * @param video_pref the sdp direction - * @return SUCCESS or FAILURE - * @Notice: if there is no active dial made, this method should not be called. - */ -cc_return_t CC_CallFeature_redial(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_Redial"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_REDIAL, video_pref, NULL); -} - -/** - * Update a media capability for a call. - * @param call_handle - * @param video_pref the sdp direction - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_updateCallMediaCapability(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_updateCallMediaCapability"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_UPD_SESSION_MEDIA_CAP, video_pref, NULL); -} - -/** - * Make a call forward all on particular line - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_callForwardAll(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_CallForwardAll"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_CFWD_ALL, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Resume a held call. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_resume(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_Resume"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_RESUME, video_pref, NULL); -} - -/** - * End a consultation call. - * @param call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_endConsultativeCall(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_EndConsultativeCall"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_END_CALL, CC_SDP_MAX_QOS_DIRECTIONS, "ACTIVECALLS"); -} - -/** - * Initiate a conference. Steps to make a conference or transfer: - * 1. Create a call handle, e.g. chandle1. - * 2. Start the call on this call handle. - * 3. When the call is answered, invoke: - * CC_CallFeature_Conference(chandle1, FALSE, CC_EMPTY_CALL_HANDLE) to start a conference operation. - * 4. Upon receiving the consultative call (cHandle2) created from pSipcc system, - * invoke: - * CC_CallFeature_Dial(cHandle2) - * to dial the consultative call. - * 5. When the consultative call is in ringout or connected state, invoke: - * CC_CallFeature_Conference(cHandle2, FALSE, CC_EMPTY_CALL_HANDLE) to - * finish the conference. - * Note: 1. in the step 4, a user could kill the consultative call and pickup a hold call (not the parent call that - * initiated the conference). In this scenario, a parent call handle should be supplied. - * For instance, - * CC_CallFeature_Conference(cHandle2, FALSE, cHandle1) - * 2. If it's a B2bConf, substitute the "FALSE" with "TRUE" - * - * @param call_handle the call handle for - * 1. the original connected call. - * 2. the consultative call or a held call besides the parent call initiated the transfer. This is used - * on the second time to finish the transfer. - * @param is locall conference or not. If it's a local conference, it's a b2bconf. - * @param parent_call_handle if supplied, it will be the targeted parent call handle, which initiated the conference. - * @param video_pref the sdp direction - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_conference(cc_call_handle_t call_handle, - boolean is_local, - cc_call_handle_t parent_call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_Conference"; - char call_handle_str[10]; - cc_return_t ret = CC_SUCCESS; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - if (parent_call_handle == CC_EMPTY_CALL_HANDLE) { - if (is_local == FALSE) { - return cc_invokeFeature(call_handle, CC_FEATURE_B2BCONF, video_pref, ""); - } else { - return cc_invokeFeature(call_handle, CC_FEATURE_CONF, video_pref, ""); - } - } else { - cc_call_handle_t parent = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + parent_call_handle; - string_t parent_call_handle_str; - snprintf(call_handle_str, sizeof(call_handle_str), "%d", parent); - parent_call_handle_str = strlib_malloc(call_handle_str, strlen(call_handle_str)); - - if (is_local == FALSE) { - ret = cc_invokeFeature(call_handle, CC_FEATURE_B2BCONF, video_pref, parent_call_handle_str); - } else { - ret = cc_invokeFeature(call_handle, CC_FEATURE_CONF, video_pref, parent_call_handle_str); - } - strlib_free(parent_call_handle_str); - return ret; - } -} - -/** - * Initiate a call transfer. Please refer to Conference feature. - * @param call_handle the call handle for - * 1. the original connected call. - * 2. the consultative call or a held call besides the parent call initiated the transfer. This is used - * on the second time to finish the transfer. - * @param parent_call_handle if supplied, it will be the parent call handle, which initiated the transfer. - * @param video_pref the sdp direction - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_transfer(cc_call_handle_t call_handle, cc_call_handle_t parent_call_handle, cc_sdp_direction_t video_pref) { - static const char fname[] = "CC_CallFeature_transfer"; - char call_handle_str[10]; - cc_return_t ret = CC_SUCCESS; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - if (parent_call_handle == CC_EMPTY_CALL_HANDLE) { - return cc_invokeFeature(call_handle, CC_FEATURE_XFER, video_pref, ""); - } else { - cc_call_handle_t parent = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + parent_call_handle; - string_t parent_call_handle_str; - snprintf(call_handle_str, sizeof(call_handle_str), "%d", parent); - parent_call_handle_str = strlib_malloc(call_handle_str, strlen(call_handle_str)); - - ret = cc_invokeFeature(call_handle, CC_FEATURE_XFER, video_pref, parent_call_handle_str); - strlib_free(parent_call_handle_str); - return ret; - } -} - -/** - * Put a connected call on hold. - * @param call handle - * @param reason the reason to hold. The following values should be used. - * CC_HOLD_REASON_NONE, - * CC_HOLD_REASON_XFER, //Hold for transfer - * CC_HOLD_REASON_CONF, //Hold for conference - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_holdCall(cc_call_handle_t call_handle, cc_hold_reason_t reason) { - static const char fname[] = "CC_CallFeature_HoldCall"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - switch (reason) { - case CC_HOLD_REASON_XFER: - return cc_invokeFeature(call_handle, CC_FEATURE_HOLD, CC_SDP_MAX_QOS_DIRECTIONS, "TRANSFER"); - case CC_HOLD_REASON_CONF: - return cc_invokeFeature(call_handle, CC_FEATURE_HOLD, CC_SDP_MAX_QOS_DIRECTIONS, "CONFERENCE"); - case CC_HOLD_REASON_SWAP: - return cc_invokeFeature(call_handle, CC_FEATURE_HOLD, CC_SDP_MAX_QOS_DIRECTIONS, "SWAP"); - default: - break; - } - - return cc_invokeFeature(call_handle, CC_FEATURE_HOLD, CC_SDP_MAX_QOS_DIRECTIONS, ""); -} - -/********************************End of basic call feature methods******************************************/ - -/*************************************Additional call feature methods*************************************** - * - */ - -/** - * Join a call. - * @param call_handle call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_b2bJoin(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_b2bJoin"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_B2B_JOIN, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Initiate a direct transfer - * @param call_handle the call handle for the call to initialize a transfer - * @param target_call_handle the call handle for the target transfer call. - * @retrun SUCCESS or FAILURE. If the target call handle is empty, a FAILURE will be returned. - */ -cc_return_t CC_CallFeature_directTransfer(cc_call_handle_t call_handle, - cc_call_handle_t target_call_handle) { - static const char fname[] = "CC_CallFeature_directTransfer"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - if (target_call_handle == CC_EMPTY_CALL_HANDLE) { - CCAPP_DEBUG(DEB_L_C_F_PREFIX"target call handle is empty.\n", DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - return CC_FAILURE; - } - return CC_CallFeature_transfer(call_handle, target_call_handle, CC_SDP_MAX_QOS_DIRECTIONS); -} - -/** - * Initiate a join across line - * @param call_handle the call handle for the call that initializes a join across line (conference). - * @param target_call_handle the call handle for the call will be joined. - */ -cc_return_t CC_CallFeature_joinAcrossLine(cc_call_handle_t call_handle, cc_call_handle_t target_call_handle) { - static const char fname[] = "CC_CallFeature_joinAcrossLine"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - if (target_call_handle == CC_EMPTY_CALL_HANDLE) { - CCAPP_DEBUG(DEB_L_C_F_PREFIX"target call handle is empty.\n", DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - return CC_FAILURE; - } - return CC_CallFeature_conference(call_handle, TRUE, target_call_handle, CC_SDP_MAX_QOS_DIRECTIONS); -} - -/** - * Select or locked a call. - * @param call_handle call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_select(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_select"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_SELECT, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -/** - * Cancel a call feature, e.g. when the consultative call is connected and the - * user wishes not to make the conference, thie method can be invoked. - * @param call_handle call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CC_CallFeature_cancelXfrerCnf(cc_call_handle_t call_handle) { - static const char fname[] = "CC_CallFeature_cancelXfrerCnf"; - CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle), - GET_LINE_ID(call_handle), fname)); - - return cc_invokeFeature(call_handle, CC_FEATURE_CANCEL, CC_SDP_MAX_QOS_DIRECTIONS, NULL); -} - -void CC_CallFeature_mute(boolean mute) { -} - -void CC_CallFeature_speaker(boolean mute) { -} - -cc_call_handle_t CC_CallFeature_getConnectedCall() { - return ccappGetConnectedCall(); -} diff --git a/libs/sipcc/core/ccapp/cc_config.c b/libs/sipcc/core/ccapp/cc_config.c deleted file mode 100644 index d990051af8..0000000000 --- a/libs/sipcc/core/ccapp/cc_config.c +++ /dev/null @@ -1,154 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_config.h" -#include "CCProvider.h" -#include "phone_debug.h" -#include "cpr_types.h" -#include "dialplan.h" -#include "capability_set.h" -#include "configmgr.h" -#include "dialplanint.h" -#include "ccapp_task.h" -#include "cc_device_manager.h" -#include "config_api.h" - -extern int config_parser_main( char *config, int complete_config); -/** - * Set the maximum line available for registration - * @param lines the maximum line could be configured. - * @return - */ -int CC_Config_SetAvailableLines(cc_lineid_t lines) { - ccappTaskPostMsg(CCAPP_UPDATELINES, &lines, sizeof(unsigned short), CCAPP_CCPROVIER); - return CC_SUCCESS; -} - -/** - * The following section defines the configuration methods. - */ -/** - * Defines the CFGID parameter setting methods. - * see cfgid.h for all possible configuration parameters - * @todo - */ -void CC_Config_setIntValue(int cfgid, int value) { - config_set_value(cfgid, &value, sizeof(int)); - return; -} - -void CC_Config_setBooleanValue(int cfgid, cc_boolean value) { - int temp = (int) value; - - // For Now, convert all numeric parameters to Integer. This simplifies - // the required SIP and GSM code changes. We will go to the right size - // when we implement the "full" JNI. - - // config_set_value(cfg_id, &bool_value, sizeof(boolean)); - config_set_value(cfgid, &temp, sizeof(int)); - return; -} - -void CC_Config_setStringValue(int cfgid, const char* value) { - config_set_string(cfgid, (char *) value); - return; -} - -void CC_Config_setByteValue(int cfgid, unsigned char value) { - int temp = (int) value; - -// For Now, convert all numeric parameters to Integer. This simplifies -// the required SIP and GSM code changes. We will go to the right size -// when we implement the "full" JNI. - -// config_set_value(cfg_id, &byte_value, sizeof(unsigned char)); - config_set_value(cfgid, &temp, sizeof(int)); - return; -} - -void CC_Config_setArrayValue(int cfgid, char *byte_array, int length) { - unsigned char *byte_ptr; - int i; - - byte_ptr = cpr_malloc(length); - if (byte_ptr == NULL) { - TNP_DEBUG(DEB_F_PREFIX"setPropertyCacheByteArray():malloc failed.\n", DEB_F_PREFIX_ARGS(JNI, "nSetPropertyCacheByteArray")); - return; - } - - for (i = 0; i < length; i++) { - byte_ptr[i] = (unsigned char) byte_array[i]; - } - config_set_value(cfgid, byte_ptr, length); - cpr_free(byte_ptr); - - return; -} - -/** - * Set the dialplan file - * @param dial_plan_string the dial plan content string - * @param length the length of dial plan string, the maximum size will be 0x2000. - * @return string dial plan version stamp - */ -char* CC_Config_setDialPlan(const char *dial_plan_string, int length) { - const char fname[] = "CC_Config_setDialPlan"; - int ret; - - /** - * If the string is null, empty or oversized, we will reset the dial - * plan by setting the length to 0. - */ - if (dial_plan_string == NULL || length == 0 || length >= DIALPLAN_MAX_SIZE) { - TNP_DEBUG(DEB_F_PREFIX"Setting NULL dialplan string (length [%d] is 0, or length is larger than maximum [%d])\n", - DEB_F_PREFIX_ARGS(JNI, fname), length, DIALPLAN_MAX_SIZE); - - dp_init_template (NULL, 0); - return (NULL); - } - - ret = dp_init_template(dial_plan_string, length); - TNP_DEBUG(DEB_F_PREFIX"Parsed dial_plan_string. Version=[%s], Length=[%d]\n", DEB_F_PREFIX_ARGS(JNI, fname), g_dp_version_stamp, length); - if (ret != 0) - { - return (NULL); - } - - return (g_dp_version_stamp); -} - -/** - * Set the feature control plan - * @param fcp plan string - * @param length the length of fcp string - * @return string feature version stamp - */ - -char* CC_Config_setFcp(const char *fcp_plan_string, int len) { - const char fname[] = "CC_Config_setFcp"; - int ret = 0; - - /** - * If the string is null, return null (version) - */ - - TNP_DEBUG(DEB_F_PREFIX"FCP Parsing FCP doc\n", DEB_F_PREFIX_ARGS(JNI, fname)); - if (fcp_plan_string == NULL) - { - TNP_DEBUG(DEB_F_PREFIX"Null FCP xml document\n", - DEB_F_PREFIX_ARGS(JNI, fname)); - - fcp_init_template (NULL); - return (NULL); - } - - ret = fcp_init_template (fcp_plan_string); - TNP_DEBUG(DEB_F_PREFIX"Parsed FCP xml. Version=[%s]\n", DEB_F_PREFIX_ARGS(JNI, fname), g_fp_version_stamp); - if (ret != 0) - { - return (NULL); - } - - return (g_fp_version_stamp); -} diff --git a/libs/sipcc/core/ccapp/cc_device_feature.c b/libs/sipcc/core/ccapp/cc_device_feature.c deleted file mode 100644 index 930119f4ef..0000000000 --- a/libs/sipcc/core/ccapp/cc_device_feature.c +++ /dev/null @@ -1,62 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_device_feature.h" -#include "sessionConstants.h" -#include "sessionTypes.h" -#include "CCProvider.h" -#include "phone_debug.h" -#include "ccapp_task.h" - -/** - * Internal method - */ -void cc_invokeDeviceFeature(session_feature_t *feature) { - - if (ccappTaskPostMsg(CCAPP_INVOKEPROVIDER_FEATURE, feature, - sizeof(session_feature_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG(DEB_F_PREFIX"cc_invokeDeviceFeature failed\n", - DEB_F_PREFIX_ARGS("cc_device_feature", "cc_invokeDeviceFeature")); - } - -} - -void CC_DeviceFeature_supportsVideo(boolean enable) { - session_feature_t feat; - - feat.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT); - feat.featureID = DEVICE_SUPPORTS_NATIVE_VIDEO; - feat.featData.ccData.info = NULL; - feat.featData.ccData.info1 = NULL; - feat.featData.ccData.state = enable; - cc_invokeDeviceFeature(&feat); -} - -/** - * Enable video/camera. - * @param enable true or false - * @return void - */ -void CC_DeviceFeature_enableVideo(boolean enable) { - session_feature_t feat; - - feat.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT); - feat.featureID = DEVICE_ENABLE_VIDEO; - feat.featData.ccData.info = NULL; - feat.featData.ccData.info1 = NULL; - feat.featData.ccData.state = enable; - cc_invokeDeviceFeature(&feat); -} - -void CC_DeviceFeature_enableCamera(boolean enable) { - session_feature_t feat; - - feat.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT); - feat.featureID = DEVICE_ENABLE_CAMERA; - feat.featData.ccData.info = NULL; - feat.featData.ccData.info1 = NULL; - feat.featData.ccData.state = enable; - cc_invokeDeviceFeature(&feat); -} - diff --git a/libs/sipcc/core/ccapp/cc_device_manager.c b/libs/sipcc/core/ccapp/cc_device_manager.c deleted file mode 100644 index 5a8c8d93a8..0000000000 --- a/libs/sipcc/core/ccapp/cc_device_manager.c +++ /dev/null @@ -1,593 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_constants.h" -#include "session.h" -#include "ccSession.h" -#include "scSession.h" -#include "cpr_types.h" -#include "cpr_string.h" -#include "phone_debug.h" -#include "sessuri.h" -#include "config_api.h" -#include "CCProvider.h" -#include "ccapp_task.h" -#include "cc_device_manager.h" -#include "ccapi_service.h" -#include "cc_service.h" -#include "subscription_handler.h" -#include "ccapi_snapshot.h" -#include "util_string.h" - - -#define STARTUP_NORMAL 0 -#define STARTUP_UNSPECIFIED 1 -#define SHUTDOWN_NORMAL 2 -#define SHUTDOWN_UNSPECIFIED 3 -#define SHUTDOWN_VERMISMATHC 4 -#define RSP_TYPE_COMPLETE 5 - - -mgmt_state_t mgmtState = MGMT_STATE_IDLE; -//int parse_config_properties (int device_handle, const char *device_name, const char *cfg, int from_memory); -static boolean isStartRequestPending = FALSE; -static boolean isServiceStopped = TRUE; - -extern cc_boolean is_action_to_be_deferred(cc_action_t action); - - -char *mgmt_event_to_str (int evt) { - - switch (evt) { - case EV_CC_CREATE: - return "EV_CC_CREATE"; - case EV_CC_START: - return "EV_CC_START"; - case EV_CC_CONFIG_RECEIVED: - return "EV_CC_CONFIG_RECEIVED"; - case EV_CC_DO_SOFT_RESET: - return "EV_CC_DO_SOFT_RESET"; - case EV_CC_INSERVICE: - return "EV_CC_INSERVICE"; - case EV_CC_OOS_FAILOVER: - return "EV_CC_OOS_FAILOVER"; - case EV_CC_OOS_FALLBACK: - return "EV_CC_OOS_FALLBACK"; - case EV_CC_OOS_REG_ALL_FAILED: - return "EV_CC_OOS_REG_ALL_FAILED"; - case EV_CC_OOS_SHUTDOWN_ACK: - return "EV_CC_OOS_SHUTDOWN_ACK"; - case EV_CC_RE_REGISTER: - return "EV_CC_RE_REGISTER"; - case EV_CC_STOP: - return "EV_CC_STOP"; - case EV_CC_DESTROY: - return "EV_CC_DESTROY"; - case EV_CC_IP_VALID: - return "EV_CC_IP_VALID"; - case EV_CC_IP_INVALID: - return "EV_CC_IP_INVALID"; - } - - return "EV_INVALID"; -} - -char *mgmt_state_to_str (int state) { - - switch (state) { - case MGMT_STATE_IDLE: - return "MGMT_STATE_IDLE"; - case MGMT_STATE_CREATED: - return "MGMT_STATE_CREATED"; - case MGMT_STATE_REGISTERING: - return "MGMT_STATE_REGISTERING"; - case MGMT_STATE_REGISTERED: - return "MGMT_STATE_REGISTERED"; - case MGMT_STATE_OOS: - return "MGMT_STATE_OOS"; - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - return "MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK"; - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - return "MGMT_STATE_WAITING_FOR_CONFIG_FILE"; - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - return "MGMT_STATE_OOS_AWAIT_UN_REG_ACK"; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - return "MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK"; - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - return "MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK"; - } - - return "MGMT_STATE_INVALID"; -} - -void updateMediaConfigProperties( void ) -{ - //TODO: check Java code - - -} - -void updateVideoConfigProperties( void ) -{ - //TODO: check Java code - -} - -/* - * action for handled events for device manager - */ -int action(int cmd) -{ - int retVal = 0; - sessionProvider_cmd_t proCmd; - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; - proCmd.cmd = cmd; - - if (cmd == CMD_INSERVICE ) { - CCAPP_DEBUG("CC_device_manager_action: CMD_INSERVICE \n"); - updateMediaConfigProperties(); - updateVideoConfigProperties(); - proCmd.cmdData.ccData.reason = STARTUP_NORMAL; - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed\n"); - } - } else if (cmd == CMD_INIT) { - - CCAPP_DEBUG("CC_device_manager_action: CMD_INIT \n"); - proCmd.cmdData.ccData.reason = STARTUP_NORMAL; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed\n"); - } - } else if (cmd == CMD_RESTART) { - - CCAPP_DEBUG("CC_device_manager_action: CMD_RESTART \n"); - updateMediaConfigProperties(); - proCmd.cmdData.ccData.reason = STARTUP_NORMAL; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed\n"); - } - - } else if (cmd == CMD_SHUTDOWN) { - - CCAPP_DEBUG("CC_device_manager_action: CMD_SHUTDOWN \n"); - proCmd.cmdData.ccData.reason = CC_CAUSE_REG_ALL_FAILED; - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed\n"); - } - } else { - - proCmd.cmdData.ccData.reason = STARTUP_NORMAL; - CCAPP_DEBUG("CC_device_manager_action: Default \n"); - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("ccInvokeFeature: ccappTaskSendMsg failed\n"); - } - - } - - return retVal; - -} - - -cc_boolean is_phone_registered() { - if (mgmtState == MGMT_STATE_REGISTERED) { - return TRUE; - } else { - return FALSE; - } -} -/* - * Wrapper function for settting state for handled events for device manager - */ -void setState(int st) { - DEF_DEBUG("setState: new registration state= %s\n", mgmt_state_to_str(st)); - mgmtState = st; -} - -void processInsToOos (void ) -{ - //CCAPP_DEBUG("CC_device_manager: processInsToOoS \n"); - DEF_DEBUG("CC_device_manager: processInsToOoS \n"); - sub_hndlr_stop(); -} - -void prepareForSoftReset() -{ - CCAPP_DEBUG("CC_device_manager: prepareForSoftReset\n"); - -} - - -void processInserviceEvent( void) -{ - CCAPP_DEBUG("CC_device_manager: process Inservice Event\n"); - if (g_deviceInfo.cucm_mode == CC_MODE_CCM ) { - if (sub_hndlr_isAvailable() == FALSE) { - sub_hndlr_start(); - } - } - setState(MGMT_STATE_REGISTERED); - //TODO: check Java code -} - - -/* - * Event handler for device manager - */ -void registration_processEvent(int event) { - - boolean ignored=0; - - DEF_DEBUG("registration_processEvent: Event %s, current State %s \n", - mgmt_event_to_str(event) , mgmt_state_to_str(mgmtState)); - - switch (event) { - case EV_CC_CREATE: - switch ( mgmtState) { - case MGMT_STATE_IDLE: - setState(MGMT_STATE_CREATED); - init_empty_str(g_cfg_p); - CC_Service_create(); - CC_Service_init(); - break; - case MGMT_STATE_REGISTERED: - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_START: - isServiceStopped = FALSE; - switch ( mgmtState) { - case MGMT_STATE_CREATED: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - configFetchReq(0); - break; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - DEF_DEBUG("registration_processEvent: delaying start until SHUTDOWN_ACK is received."); - isStartRequestPending = TRUE; - break; - case MGMT_STATE_IDLE: - case MGMT_STATE_REGISTERED: - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_IP_INVALID: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - setState(MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK); - action(CMD_UNREGISTER_ALL_LINES); - break; - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - setState(MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK); - break; - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_CREATED: - case MGMT_STATE_IDLE: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - - break; - - case EV_CC_IP_VALID: - if (isServiceStopped == TRUE) { - ignored = 1; - DEF_DEBUG("registration_processEvent: "\ - "Ignoring IP_VALID as service was not Started "); - break; - } - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - if (is_action_to_be_deferred(RE_REGISTER_ACTION) - == FALSE) { - processInsToOos(); - prepareForSoftReset(); - setState(MGMT_STATE_OOS_AWAIT_UN_REG_ACK); - action(CMD_SHUTDOWN); - } - break; - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - if (is_action_to_be_deferred(RE_REGISTER_ACTION) - == FALSE) { - prepareForSoftReset(); - setState(MGMT_STATE_OOS_AWAIT_UN_REG_ACK); - action(CMD_SHUTDOWN); - } - break; - case MGMT_STATE_IDLE: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_CREATED: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_DO_SOFT_RESET: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); /* FALL THROUGH */ - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - prepareForSoftReset(); - setState(MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK); - action(CMD_SHUTDOWN); - break; - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_CONFIG_RECEIVED: - switch ( mgmtState) { - case MGMT_STATE_CREATED: // This state is only at init - // needs handler to be added on receiving message - setState(MGMT_STATE_REGISTERING); - action(CMD_INSERVICE); - break; - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - setState(MGMT_STATE_REGISTERING); - action(CMD_RESTART); - break; - case MGMT_STATE_REGISTERING: - case MGMT_STATE_REGISTERED: - case MGMT_STATE_OOS: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_INSERVICE: - switch (mgmtState) { - case MGMT_STATE_OOS: - case MGMT_STATE_REGISTERING: - setState(MGMT_STATE_REGISTERED); - case MGMT_STATE_REGISTERED: - processInserviceEvent(); - break; - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_OOS_FAILOVER: - case EV_CC_OOS_FALLBACK: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); - case MGMT_STATE_REGISTERING: - setState(MGMT_STATE_OOS); - break; - case MGMT_STATE_OOS: - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - case EV_CC_OOS_REG_ALL_FAILED: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); /* FALL THROUGH */ - case MGMT_STATE_OOS: - case MGMT_STATE_REGISTERING: - setState(MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK); - action(CMD_SHUTDOWN); - break; - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - /* - *This event shutdown sip stack to facilitate re-registration of - * all lines. - */ - case EV_CC_RE_REGISTER: - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); - setState(MGMT_STATE_OOS_AWAIT_UN_REG_ACK); - action(CMD_UNREGISTER_ALL_LINES); - break; - case MGMT_STATE_OOS: - case MGMT_STATE_REGISTERING: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_CREATED: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - case MGMT_STATE_IDLE: - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - default: - ignored = 1; - break; - } - break; - - case EV_CC_DESTROY: - isStartRequestPending = FALSE; - isServiceStopped = TRUE; - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - CC_Service_destroy(); - processInsToOos(); - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - setState(MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK); - action(CMD_UNREGISTER_ALL_LINES); - break; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - //setState(MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK); - setState(MGMT_STATE_IDLE); - CC_Service_destroy(); - break; - case MGMT_STATE_CREATED: - CC_Service_destroy(); - break; - case MGMT_STATE_IDLE: - CC_Service_destroy(); - break; - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - setState(MGMT_STATE_IDLE); - - default: - ignored = 1; - break; - } - - break; - case EV_CC_STOP: - isStartRequestPending = FALSE; - isServiceStopped = TRUE; - switch ( mgmtState) { - case MGMT_STATE_REGISTERED: - processInsToOos(); - case MGMT_STATE_REGISTERING: - case MGMT_STATE_OOS: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - setState(MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK); - action(CMD_UNREGISTER_ALL_LINES); - break; - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - setState(MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK); - break; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - case MGMT_STATE_CREATED: - case MGMT_STATE_IDLE: - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - setState(MGMT_STATE_IDLE); - //action(CMD_SHUTDOWN); - CC_Service_destroy(); - - default: - ignored = 1; - break; - } - break; - case EV_CC_OOS_SHUTDOWN_ACK: - switch ( mgmtState) { - case MGMT_STATE_OOS_AWAIT_UN_REG_ACK: - setState(MGMT_STATE_REGISTERING); - action(CMD_RESTART); - break; - case MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK: - setState(MGMT_STATE_WAITING_FOR_CONFIG_FILE); - configFetchReq(0); - setState(MGMT_STATE_IDLE); - break; - case MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK: - setState(MGMT_STATE_WAITING_FOR_CONFIG_FILE); - if (isStartRequestPending == TRUE) { - isStartRequestPending = FALSE; - configFetchReq(0); - } - setState(MGMT_STATE_IDLE); - break; - case MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK: - CC_Service_destroy(); - break; - case MGMT_STATE_REGISTERED: - case MGMT_STATE_WAITING_FOR_CONFIG_FILE: - case MGMT_STATE_OOS: - case MGMT_STATE_REGISTERING: - case MGMT_STATE_CREATED: - case MGMT_STATE_IDLE: - default: - ignored = 1; - break; - } - break; - default: - break; - } - - if (ignored) { - DEF_DEBUG("registration_processEvent: IGNORED Event %s in State %s \n", - mgmt_event_to_str(event) , mgmt_state_to_str(mgmtState)); - } - -} - - - diff --git a/libs/sipcc/core/ccapp/cc_device_manager.h b/libs/sipcc/core/ccapp/cc_device_manager.h deleted file mode 100644 index ed0dbec7d2..0000000000 --- a/libs/sipcc/core/ccapp/cc_device_manager.h +++ /dev/null @@ -1,43 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Management Events - */ - typedef enum { - EV_CC_CREATE=0, - EV_CC_START, - EV_CC_CONFIG_RECEIVED , - EV_CC_DO_SOFT_RESET , - EV_CC_INSERVICE, - EV_CC_OOS_FAILOVER, - EV_CC_OOS_FALLBACK, - EV_CC_OOS_REG_ALL_FAILED, - EV_CC_OOS_SHUTDOWN_ACK, - EV_CC_RE_REGISTER, - EV_CC_STOP, - EV_CC_DESTROY, - EV_CC_IP_VALID, - EV_CC_IP_INVALID -} mgmt_event_t; - - -/** - * Management states - */ -typedef enum { -MGMT_STATE_CREATED=0, -MGMT_STATE_IDLE, -MGMT_STATE_REGISTERING, -MGMT_STATE_REGISTERED, -MGMT_STATE_OOS, -MGMT_STATE_OOS_AWAIT_SHUTDOWN_ACK, -MGMT_STATE_WAITING_FOR_CONFIG_FILE, -MGMT_STATE_OOS_AWAIT_UN_REG_ACK, -MGMT_STATE_STOP_AWAIT_SHUTDOWN_ACK, -MGMT_STATE_DESTROY_AWAIT_SHUTDOWN_ACK -} mgmt_state_t; - -extern void registration_processEvent(int event); -cc_boolean is_phone_registered(); diff --git a/libs/sipcc/core/ccapp/cc_info.c b/libs/sipcc/core/ccapp/cc_info.c deleted file mode 100644 index d6117100a5..0000000000 --- a/libs/sipcc/core/ccapp/cc_info.c +++ /dev/null @@ -1,43 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_info.h" -#include "sessionTypes.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "ccapp_task.h" - -/** - * Send call information. - * @param call_handle call handle - * @param info_package the Info-Package header of the Info Package - * @param info_type the Content-Type header of the Info Package - * @param info_body the message body of the Info Package - * @return void - */ -void CC_Info_sendInfo(cc_call_handle_t call_handle, - string_t info_package, - string_t info_type, - string_t info_body) { - static const char *fname = "CC_Info_sendInfo"; - session_send_info_t send_info; - - CCAPP_DEBUG(DEB_F_PREFIX"entry... call_handle=0x%x\n", - DEB_F_PREFIX_ARGS(SIP_CC_SES, fname), call_handle); - - send_info.sessionID= (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + call_handle;; - send_info.generic_raw.info_package = strlib_malloc(info_package, strlen(info_package)); - send_info.generic_raw.content_type = strlib_malloc(info_type, strlen(info_type)); - send_info.generic_raw.message_body = strlib_malloc(info_body, strlen(info_body)); - - /* Once the msg is posted to ccapp_msgq, ccapp 'owns' these strings */ - // ccappTaskPostMsg does a shallow copy of *send_info - if (ccappTaskPostMsg(CCAPP_SEND_INFO, &send_info, - sizeof(session_send_info_t), CCAPP_CCPROVIER) != CPR_SUCCESS) { - CCAPP_ERROR(DEB_F_PREFIX"ccappTaskPostMsg failed\n", - DEB_F_PREFIX_ARGS(SIP_CC_SES, fname)); - } - -} diff --git a/libs/sipcc/core/ccapp/cc_service.c b/libs/sipcc/core/ccapp/cc_service.c deleted file mode 100644 index dd3dc3cd48..0000000000 --- a/libs/sipcc/core/ccapp/cc_service.c +++ /dev/null @@ -1,229 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cc_service.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "ccsip_messaging.h" -#include "ccapp_task.h" - -/** - * External init.c methods - */ -extern int ccPreInit (); -extern int ccInit (); -extern int ccUnload (); -extern void protCfgTblInit(); - -extern cc_int32_t SipDebugMessage; -extern cc_int32_t SipDebugState; -extern cc_int32_t SipDebugTask; -extern cc_int32_t SipDebugRegState; -extern cc_int32_t GSMDebug; -extern cc_int32_t FIMDebug; -extern cc_int32_t LSMDebug; -extern cc_int32_t FSMDebugSM; -extern int32_t CSMDebugSM; -extern cc_int32_t CCDebug; -extern cc_int32_t CCDebugMsg; -extern cc_int32_t AuthDebug; -extern cc_int32_t ConfigDebug; -extern cc_int32_t DpintDebug; -extern cc_int32_t KpmlDebug; -extern cc_int32_t VCMDebug; -extern cc_int32_t PLATDebug; -extern cc_int32_t CCEVENTDebug; -extern cc_int32_t g_CCAppDebug; -extern cc_int32_t g_CCLogDebug; -extern cc_int32_t TNPDebug; - -/** - * Initialize all the debug variables - */ -void dbg_init(void) -{ - /* This is for the RT/TNP products */ - SipDebugMessage = 1; - SipDebugState = 1; - SipDebugTask = 1; - SipDebugRegState = 1; - GSMDebug = 1; - FIMDebug = 1; - LSMDebug = 1; - FSMDebugSM = 1; - CSMDebugSM = 0; - VCMDebug = 1; - PLATDebug = 1; - CCEVENTDebug = 0; - CCDebug = 0; - CCDebugMsg = 0; - AuthDebug = 1; - TNPDebug = 1; - ConfigDebug = 1; - DpintDebug = 0; - KpmlDebug = 0; - g_CCAppDebug = 1; - g_CCLogDebug = 1; - TNPDebug = 1; - g_NotifyCallDebug = 0; - g_NotifyLineDebug = 0; -} -/** - * Defines the management methods. - */ -/** - * The following methods are defined to bring up the pSipcc stack - */ -/** - * Initialize the pSipcc stack. - * @return - */ -cc_return_t CC_Service_init() { - //Initialize stack - return ccInit(); -} - -/** - * Pre-initialize the pSipcc stack. - * @return - */ -cc_return_t CC_Service_create() { - //Preinitialize memory - ccPreInit(); - - //Initialize debug settings - dbg_init(); - - //Prepopulate the Configuration data table - protCfgTblInit(); - - return CC_SUCCESS; -} - -/** - * Gracefully unload the pSipcc stack - * @return - */ -cc_return_t CC_Service_destroy() { - ccUnload(); - return CC_SUCCESS; -} - -/** - * Bring up the pSipcc stack in service - * @return - */ -cc_return_t CC_Service_start() { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_start \n"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_INSERVICE; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_start: ccappTaskSendMsg failed\n"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/** - * Shutdown pSipcc stack for restarting - * @param mgmt_reason the reason to shutdown pSipcc stack - * @param reason_string literal string for shutdown - * @return - */ -cc_return_t CC_Service_shutdown(cc_shutdown_reason_t mgmt_reason, string_t reason_string) { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_shutdown \n"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_SHUTDOWN; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_shutdown: ccappTaskSendMsg failed\n"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/** - * Unregister all lines of a phone - * @param mgmt_reason the reason to bring down the registration - * @param reason_string the literal string for unregistration - * @return - */ -cc_return_t CC_Service_unregisterAllLines(cc_shutdown_reason_t mgmt_reason, string_t reason_string) { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_shutdown \n"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_SHUTDOWN; - proCmd.cmdData.ccData.reason = mgmt_reason; - proCmd.cmdData.ccData.reason_info = reason_string; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_shutdown: ccappTaskSendMsg failed\n"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/** - * Register all lines for a phone. - * @param mgmt_reason the reason of registration - * @param reason_string the literal string of the registration - * @return - */ -cc_return_t CC_Service_registerAllLines(cc_shutdown_reason_t mgmt_reason, string_t reason_string) { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_registerAllLines \n"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_REGISTER_ALL_LINES; - proCmd.cmdData.ccData.reason = mgmt_reason; - proCmd.cmdData.ccData.reason_info = reason_string; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_registerAllLines: ccappTaskSendMsg failed\n"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - -/** - * Restart pSipcc stack - * @return - */ -cc_return_t CC_Service_restart() { - sessionProvider_cmd_t proCmd; - - CCAPP_DEBUG("CC_Service_restart \n"); - - memset ( &proCmd, 0, sizeof(sessionProvider_cmd_t)); - proCmd.sessionType = SESSIONTYPE_CALLCONTROL; //Not used - proCmd.cmd = CMD_RESTART; - - if (ccappTaskPostMsg(CCAPP_SERVICE_CMD, (cprBuffer_t)&proCmd, - sizeof(sessionProvider_cmd_t), CCAPP_CCPROVIER) == CPR_FAILURE) { - CCAPP_DEBUG("CC_Service_restart: ccappTaskSendMsg failed\n"); - return CC_FAILURE; - } - return CC_SUCCESS; -} - - diff --git a/libs/sipcc/core/ccapp/ccapi_call.c b/libs/sipcc/core/ccapp/ccapi_call.c deleted file mode 100644 index 8af7198033..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_call.c +++ /dev/null @@ -1,375 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdio.h" -#include "ccapi_call.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "cc_call_feature.h" -#include "cc_info.h" -#include "lsm.h" -#include "prot_configmgr.h" -#include "ccapi_call_info.h" -#include "util_string.h" - -/** - * Get call info snapshot - * @param [in] handle - call handle - * @return cc_call_info_snap_t - */ -cc_callinfo_ref_t CCAPI_Call_getCallInfo(cc_call_handle_t handle) { - unsigned int session_id = ccpro_get_sessionId_by_callid(GET_CALL_ID(handle)); - cc_callinfo_ref_t snapshot=NULL; - session_data_t * data; - - if ( session_id != 0 ) { - data = findhash(session_id); - if ( data != NULL ) { - snapshot = getDeepCopyOfSessionData(data); - if (snapshot == NULL) { - return NULL; - } - snapshot->ref_count = 1; - } - } - return snapshot; -} -/** - * Retain the snapshot - * @param cc_callinfo_ref_t - refrence to the block to be retained - * @return void - */ -void CCAPI_Call_retainCallInfo(cc_callinfo_ref_t ref) { - if (ref != NULL ) { - ref->ref_count++; - } -} -/** - * Free the snapshot - * @param cc_callinfo_ref_t - refrence to the block to be freed - * @return void - */ -void CCAPI_Call_releaseCallInfo(cc_callinfo_ref_t ref) { - if (ref != NULL ) { - DEF_DEBUG(DEB_F_PREFIX"ref=0x%x: count=%d", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_releaseCallInfo"), ref, ref->ref_count); - ref->ref_count--; - if ( ref->ref_count == 0 ) { - cleanSessionData(ref); - cpr_free(ref); - } - } -} - -/** - * get the line associated with this call - * @param [in] handle - call handle - * @return cc_lineid_t - */ -cc_lineid_t CCAPI_Call_getLine(cc_call_handle_t call_handle){ - static const char *fname="CCAPI_Call_getLine"; - - if ( call_handle != 0 ) { - cc_lineid_t lineid = GET_LINE_ID(call_handle); - CCAPP_DEBUG(DEB_F_PREFIX"returned %u\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), lineid); - return lineid; - } - return 0; -} - -/** - * Originate call - * Goes offhook and dials digits if specified - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @param [in] digits - digits to be dialed - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_originateCall(cc_call_handle_t handle, cc_sdp_direction_t video_pref, cc_string_t digits){ - return CC_CallFeature_dial(handle, video_pref, digits); -} - -cc_return_t CCAPI_CreateOffer(cc_call_handle_t handle, const cc_media_constraints_t *constraints) { - return CC_CallFeature_CreateOffer(handle, constraints); -} - -cc_return_t CCAPI_CreateAnswer(cc_call_handle_t handle, const cc_media_constraints_t *constraints) { - return CC_CallFeature_CreateAnswer(handle, constraints); -} - -cc_return_t CCAPI_SetLocalDescription(cc_call_handle_t handle, cc_jsep_action_t action, cc_string_t sdp) { - return CC_CallFeature_SetLocalDescription(handle, action, sdp); -} - -cc_return_t CCAPI_SetRemoteDescription(cc_call_handle_t handle, cc_jsep_action_t action, cc_string_t sdp) { - return CC_CallFeature_SetRemoteDescription(handle, action, sdp); -} - -cc_return_t CCAPI_SetPeerConnection(cc_call_handle_t handle, cc_peerconnection_t pc) { - return CC_CallFeature_SetPeerConnection(handle, pc); -} - -cc_return_t CCAPI_AddStream(cc_call_handle_t handle, cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type) { - return CC_CallFeature_AddStream(handle, stream_id, track_id, media_type); -} - -cc_return_t CCAPI_RemoveStream(cc_call_handle_t handle, cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type) { - return CC_CallFeature_RemoveStream(handle, stream_id, track_id, media_type); -} - -cc_return_t CCAPI_AddICECandidate(cc_call_handle_t handle, cc_string_t candidate, cc_string_t mid, cc_level_t level) { - return CC_CallFeature_AddICECandidate(handle, candidate, mid, level); -} - -/** - * Dial digits on the call - * @param [in] handle - call handle - * @paraqm [in] digits - digits to be dialed - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_sendDigit(cc_call_handle_t handle, cc_digit_t digit){ - return CC_CallFeature_sendDigit(handle, digit); -} - -/** - * Send Backspace - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_backspace(cc_call_handle_t handle){ - return CC_CallFeature_backSpace(handle); -} - -/** - * Answer Call - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_answerCall(cc_call_handle_t handle, cc_sdp_direction_t video_pref) { - return CC_CallFeature_answerCall(handle, video_pref); -} - -/** - * Redial - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_redial(cc_call_handle_t handle, cc_sdp_direction_t video_pref){ - return CC_CallFeature_redial(handle, video_pref); -} - -/** - * Initiate Call Forward All - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_initiateCallForwardAll(cc_call_handle_t handle){ - return CC_CallFeature_callForwardAll(handle); -} -/** - * Hold - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_hold(cc_call_handle_t handle, cc_hold_reason_t reason){ - return CC_CallFeature_holdCall(handle, reason); -} - -/** - * Resume - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_resume(cc_call_handle_t handle, cc_sdp_direction_t video_pref) { - return CC_CallFeature_resume(handle, video_pref); -} - -/** - * end Consult leg - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_endConsultativeCall(cc_call_handle_t handle){ - cc_callinfo_ref_t info_handle = CCAPI_Call_getCallInfo(handle); - cc_call_attr_t attr = CCAPI_CallInfo_getCallAttr(info_handle); - if (attr != CC_ATTR_CONF_CONSULT && - attr != CC_ATTR_XFR_CONSULT && - attr != CC_ATTR_LOCAL_CONF_CONSULT && - attr != CC_ATTR_LOCAL_XFER_CONSULT) { - DEF_DEBUG(DEB_F_PREFIX"This method only calls on a consultative call", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_endConsultativeCall"), handle); - return CC_FAILURE; - } - - return CC_CallFeature_endConsultativeCall(handle); -} - -/** - * end Call - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_endCall(cc_call_handle_t handle){ - return CC_CallFeature_terminateCall(handle); -} - -/** - * Initiate a conference - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on consult call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_conferenceStart(cc_call_handle_t handle, cc_sdp_direction_t video_pref){ - return CC_CallFeature_conference(handle, TRUE,//not used - CC_EMPTY_CALL_HANDLE, video_pref); -} - -/** - * complete conference - * @param [in] handle - call handle - * @param [in] phandle - call handle of the other leg - * @param [in] video_pref - video direction desired on consult call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_conferenceComplete(cc_call_handle_t handle, cc_call_handle_t phandle, - cc_sdp_direction_t video_pref){ - return CC_CallFeature_conference(handle, TRUE,//not used - phandle, video_pref); - -} - -/** - * start transfer - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on consult call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_transferStart(cc_call_handle_t handle, cc_sdp_direction_t video_pref){ - return CC_CallFeature_transfer(handle, CC_EMPTY_CALL_HANDLE, video_pref); -} - -/** - * complete transfer - * @param [in] handle - call handle - * @param [in] phandle - call handle of the other leg - * @param [in] video_pref - video direction desired on consult call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_transferComplete(cc_call_handle_t handle, cc_call_handle_t phandle, - cc_sdp_direction_t video_pref){ - return CC_CallFeature_transfer(handle, phandle, video_pref); -} - -/** - * cancel conference or transfer - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_cancelTransferOrConferenceFeature(cc_call_handle_t handle){ - return CC_CallFeature_cancelXfrerCnf(handle); -} - -/** - * direct Transfer - * @param [in] handle - call handle - * @param [in] handle - transfer target call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_directTransfer(cc_call_handle_t handle, cc_call_handle_t target){ - return CC_CallFeature_directTransfer(handle, target); -} - -/** - * Join Across line - * @param [in] handle - call handle - * @param [in] handle - join target - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_joinAcrossLine(cc_call_handle_t handle, cc_call_handle_t target){ - return CC_CallFeature_joinAcrossLine(handle, target); -} - -/** - * BLF Call Pickup - * @param [in] handle - call handle - * @param [in] speed - speedDial Number - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_blfCallPickup(cc_call_handle_t handle, - cc_sdp_direction_t video_pref, cc_string_t speed){ - return CC_CallFeature_blfCallPickup(handle, video_pref, speed); -} - -/** - * Select a call - * @param [in] handle - call handle - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_select(cc_call_handle_t handle){ - return CC_CallFeature_select(handle); -} - -/** - * Update Video Media Cap for the call - * @param [in] handle - call handle - * @param [in] video_pref - video direction desired on call - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_updateVideoMediaCap (cc_call_handle_t handle, cc_sdp_direction_t video_pref) { - return CC_CallFeature_updateCallMediaCapability(handle, video_pref); -} - -/** - * send INFO method for the call - * @param [in] handle - call handle - * @param [in] infopackage - Info-Package header value - * @param [in] infotype - Content-Type header val - * @param [in] infobody - Body of the INFO message - * @return SUCCESS or FAILURE - */ -cc_return_t CCAPI_Call_sendInfo (cc_call_handle_t handle, cc_string_t infopackage, cc_string_t infotype, cc_string_t infobody) -{ - CC_Info_sendInfo(handle, infopackage, infotype, infobody); - return CC_SUCCESS; -} - -/** - * API to mute/unmute audio - * @param [in] val - TRUE=> mute FALSE => unmute - * @return SUCCESS or FAILURE - * NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume. - * This API doesn't perform the mute operation but simply caches the mute state of the session. - */ -cc_return_t CCAPI_Call_setAudioMute (cc_call_handle_t handle, cc_boolean val) { - unsigned int session_id = ccpro_get_sessionId_by_callid(GET_CALL_ID(handle)); - session_data_t * sess_data_p = (session_data_t *)findhash(session_id); - DEF_DEBUG(DEB_F_PREFIX": val=%d, handle=%d datap=%x", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_setAudioMute"), val, handle, sess_data_p); - if ( sess_data_p != NULL ) { - sess_data_p->audio_mute = val; - } - return CC_SUCCESS; -} - -/** - * API to mute/unmute Video - * @param [in] val - TRUE=> mute FALSE => unmute - * @return SUCCESS or FAILURE - * NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume - * This API doesn't perform the mute operation but simply caches the mute state of the session. - */ -cc_return_t CCAPI_Call_setVideoMute (cc_call_handle_t handle, cc_boolean val){ - unsigned int session_id = ccpro_get_sessionId_by_callid(GET_CALL_ID(handle)); - session_data_t * sess_data_p = (session_data_t *)findhash(session_id); - DEF_DEBUG(DEB_F_PREFIX": val=%d, handle=%d datap=%x", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Call_setVideoMute"), val, handle, sess_data_p); - if ( sess_data_p != NULL ) { - sess_data_p->video_mute = val; - lsm_set_video_mute(GET_CALL_ID(handle), val); - } - return CC_SUCCESS; -} diff --git a/libs/sipcc/core/ccapp/ccapi_call_info.c b/libs/sipcc/core/ccapp/ccapi_call_info.c deleted file mode 100644 index 20b3793410..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_call_info.c +++ /dev/null @@ -1,784 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdio.h" -#include "ccapi_call.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "text_strings.h" -#include "phone_debug.h" -#include "peer_connection_types.h" - -/** - * get Line on which this call is - * @param [in] handle - call handle - * @return cc_line_id_t - line ID - */ -cc_lineid_t CCAPI_CallInfo_getLine(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getLine"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %u\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), GET_LINE_ID(CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id))); - return GET_LINE_ID(CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id)); - } - - return 0; -} - -/** - * get Call state - * @param handle - call handle - * @return call state - */ -cc_call_state_t CCAPI_CallInfo_getCallState(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallState"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->state); - return data->state; - } - - return ONHOOK; -} - -/** - * get call attributes - * @param handle - call handle - * @return call attributes - */ -cc_call_attr_t CCAPI_CallInfo_getCallAttr(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallAttr"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->attr); - return data->attr; - } - - return 0; -} - -/** - * get Call Type - * @param handle - call handle - * @return call type - */ -cc_call_type_t CCAPI_CallInfo_getCallType(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallType"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->type); - return data->type; - } - - return 0; -} - -/** - * get Called party name - * @param handle - call handle - * @return called party name - */ -cc_string_t CCAPI_CallInfo_getCalledPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCalledPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->cld_name); - return data->cld_name; - } - - return strlib_empty(); -} - -/** - * get Called party number - * @param handle - call handle - * @return called party number - */ -cc_string_t CCAPI_CallInfo_getCalledPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCalledPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->cld_number); - return data->cld_number; - } - - return strlib_empty(); -} - -/** - * get Calling party name - * @param handle - call handle - * @return calling party name - */ -cc_string_t CCAPI_CallInfo_getCallingPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallingPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->clg_name); - return data->clg_name; - } - - return strlib_empty(); -} - -/** - * get Calling party number - * @param handle - call handle - * @return calling party number - */ -cc_string_t CCAPI_CallInfo_getCallingPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallingPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->clg_number); - return data->clg_number; - } - - return strlib_empty(); -} - -/** - * get alternate number - * @param handle - call handle - * @return calling party number - */ -cc_string_t CCAPI_CallInfo_getAlternateNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getAlternateNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->alt_number); - return data->alt_number; - } - - return strlib_empty(); -} - -/** - * get Original Called party name - * @param handle - call handle - * @return original called party name - */ -cc_string_t CCAPI_CallInfo_getOriginalCalledPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getOriginalCalledPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->orig_called_name); - return data->orig_called_name; - } - - return strlib_empty(); -} - -/** - * get Original Called party number - * @param handle - call handle - * @return original called party number - */ -cc_string_t CCAPI_CallInfo_getOriginalCalledPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getOriginalCalledPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->orig_called_number); - return data->orig_called_number; - } - - return strlib_empty(); -} - -/** - * get last redirecting party name - * @param handle - call handle - * @return last redirecting party name - */ -cc_string_t CCAPI_CallInfo_getLastRedirectingPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getLastRedirectingPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->last_redir_name); - return data->last_redir_name; - } - - return strlib_empty(); -} - -/** - * get past redirecting party number - * @param handle - call handle - * @return last redirecting party number - */ -cc_string_t CCAPI_CallInfo_getLastRedirectingPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getLastRedirectingPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->last_redir_number); - return data->last_redir_number; - } - - return strlib_empty(); -} - -/** - * get placed call party name - * @param handle - call handle - * @return placed party name - */ -cc_string_t CCAPI_CallInfo_getPlacedCallPartyName(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getPlacedCallPartyName"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->plcd_name); - return data->plcd_name; - } - - return strlib_empty(); -} - -/** - * get placed call party number - * @param handle - call handle - * @return placed party number - */ -cc_string_t CCAPI_CallInfo_getPlacedCallPartyNumber(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getPlacedCallPartyNumber"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->plcd_number); - return data->plcd_number; - } - - return strlib_empty(); -} - - -/** - * get call instance number - * @param handle - call handle - * @return - */ -cc_int32_t CCAPI_CallInfo_getCallInstance(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getCallInstance"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->inst); - return data->inst; - } - - return 0; -} - -/** - * get call status prompt - * @param handle - call handle - * @return call status - */ -cc_string_t CCAPI_CallInfo_getStatus(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getStatus"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->status); - return data->status; - } - - return strlib_empty(); - -} - -/** - * get call security - * @param handle - call handle - * @return call security status - */ -cc_call_security_t CCAPI_CallInfo_getSecurity(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getSecurity"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->security); - return data->security; - } - - return CC_SECURITY_NONE; -} - -/** - * * get Call Selection Status - * * @param [in] handle - call info handle - * * @return cc_boolean - TRUE => selected - * */ -cc_boolean CCAPI_CallInfo_getSelectionStatus(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getSelectionStatus"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->isSelected); - return data->isSelected; - } - - return FALSE; -} - -/** - * get call policy - * @param handle - call handle - * @return call policy - */ -cc_call_policy_t CCAPI_CallInfo_getPolicy(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getPolicy"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->policy); - return data->policy; - } - - return CC_POLICY_NONE; -} - -/** - * get GCID - * @param handle - call handle - * @return GCID - */ -cc_string_t CCAPI_CallInfo_getGCID(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getGCID"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->gci); - return data->gci; - } - - return strlib_empty(); -} - -/** - * get ringer state. - * @param handle - call handle - * @return ringer state - */ -cc_boolean CCAPI_CallInfo_getRingerState(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getRingerState"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->ringer_start); - return data->ringer_start; - } - - return FALSE; -} - -/** - * get ringer mode - * @param handle - call handle - * @return ringer mode - */ -int CCAPI_CallInfo_getRingerMode(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getRingerMode"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->ringer_mode); - return (int)(data->ringer_mode); - } - - return -1; -} - -/** - * get ringer loop count - * @param handle - call handle - * @return once Vs continuous - */ -cc_boolean CCAPI_CallInfo_getIsRingOnce(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getIsRingOnce"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->ringer_once); - return (int)(data->ringer_once); - } - - return TRUE; -} - -/** - * get onhook reason - * @param handle - call handle - * @return onhook reason - */ -cc_int32_t CCAPI_CallInfo_getOnhookReason(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getOnhookReason"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->cause); - return data->cause; - } - - return CC_CAUSE_NORMAL; -} - -/** - * is Conference Call? - * @param handle - call handle - * @return boolean - is Conference - */ -cc_boolean CCAPI_CallInfo_getIsConference(cc_callinfo_ref_t handle){ - session_data_t *data = (session_data_t *)handle; - char isConf[32]; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__)); - - memset(isConf, 0, sizeof(isConf)); - - if(platGetPhraseText(CONFERENCE_LOCALE_CODE, isConf, sizeof(isConf)) == CC_FAILURE){ - return FALSE; - } - - if( data != NULL){ - if( (strcasecmp(data->cld_name, isConf) == 0 && strcasecmp(data->cld_number, "") == 0) || - (strcasecmp(data->clg_name, isConf) == 0 && strcasecmp(data->clg_number, "") == 0) ) - { - return TRUE; - } - } - - return FALSE; -} - -/** - * getStream Statistics - * @param handle - call handle - * @return stream stats - */ -cc_return_t CCAPI_CallInfo_getStreamStatistics(cc_callinfo_ref_t handle, cc_int32_t stats[], cc_int32_t *count) -{ - static const char *fname="CCAPI_CallInfo_getStreamStatistics"; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - CCAPP_DEBUG(DEB_F_PREFIX"returned CC_SUCCESS (default)\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - // todo - return CC_SUCCESS; -} - - -/** - * has capability - is the feature allowed - * @param handle - call handle - * @param feat_id - feature id - * @return boolean - is Allowed - */ -cc_boolean CCAPI_CallInfo_hasCapability(cc_callinfo_ref_t handle, cc_int32_t feat_id){ - static const char *fname="CCAPI_CallInfo_hasCapability"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"feature id: %d , value returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),feat_id, data->allowed_features[feat_id]); - return data->allowed_features[feat_id]; - } - - return FALSE; -} - -/** - * get Allowed Feature set - * @param handle - call handle - * @return boolean array that can be indexed using CCAPI_CALL_CAP_XXXX to check if feature is enabled - */ -cc_boolean CCAPI_CallInfo_getCapabilitySet(cc_callinfo_ref_t handle, cc_int32_t feat_set[]){ - static const char *fname="CCAPI_CallInfo_getCapabilitySet"; - session_data_t *data = (session_data_t *)handle; - int feat_id; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - for (feat_id = 0; feat_id < CCAPI_CALL_CAP_MAX; feat_id++) { - feat_set[feat_id] = data->allowed_features[feat_id]; - CCAPP_DEBUG(DEB_F_PREFIX"feature id: %d , value %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),feat_id, feat_set[feat_id]); - } - - CCAPP_DEBUG(DEB_F_PREFIX"returned CC_SUCCESS\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return CC_SUCCESS; - } - - return CC_FAILURE; -} - -/** - * Call selection status - * @param [in] handle - call handle - * @return cc_boolean - selection status - */ -cc_boolean CCAPI_CallInfo_isCallSelected(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_isCallSelected"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->isSelected); - return data->isSelected; - } - - return FALSE; -} - -/** - * Call negotiated video direction - * @param [in] handle - call handle - * @return cc_sdp_direction_t - video direction - */ -cc_sdp_direction_t CCAPI_CallInfo_getVideoDirection(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getVideoDirection"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->vid_dir); - return (data->vid_dir); - } - - return CC_SDP_DIRECTION_INACTIVE; -} - -/** - * INFO Package for RECEIVED_INFO event - * @param [in] handle - call info handle - * @return cc_string_t - Info package header - */ -cc_string_t CCAPI_CallInfo_getINFOPack (cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getINFOPackage"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->info_package); - return data->info_package; - } - - return strlib_empty(); -} - -/** - * INFO type for RECEIVED_INFO event - * @param [in] handle - call info handle - * @return cc_string_t - content-type header - */ -cc_string_t CCAPI_CallInfo_getINFOType (cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getINFOType"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->info_type); - return data->info_type; - } - - return strlib_empty(); -} - -/** - * INFO body for RECEIVED_INFO event - * @param [in] handle - call info handle - * @return cc_string_t - INFO body - */ -cc_string_t CCAPI_CallInfo_getINFOBody (cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getINFOBody"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->info_body); - return data->info_body; - } - - return strlib_empty(); -} - -/** - * Get the call log reference - * @param [in] handle - call info handle - * @return cc_string_t - INFO body - * NOTE: Memory associated with the call log is tied to the cc_callinfo_ref_t handle - * this would be freed when the callinfo ref is freed. - */ -cc_calllog_ref_t CCAPI_CallInfo_getCallLogRef(cc_callinfo_ref_t handle) -{ - static const char *fname="CCAPI_CallInfo_getCallLogRef"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %x\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), &data->call_log); - return &data->call_log; - } - - return NULL; -} - - -/** - * Returns the Audio mute state for this call - * @return boolean true=muted false=not muted - */ -cc_boolean CCAPI_CallInfo_isAudioMuted (cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_isAudioMuted"; - session_data_t *data = (session_data_t *)handle; - session_data_t * sess_data_p; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - if ( data != NULL){ - sess_data_p = (session_data_t *)findhash(data->sess_id); - if ( sess_data_p != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sess_data_p->audio_mute); - return sess_data_p->audio_mute; - } - } - - return FALSE; -} - -/** - * Returns the Video mute state for this call - * @return boolean true=muted false=not muted - */ -cc_boolean CCAPI_CallInfo_isVideoMuted (cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_isVideoMuted"; - session_data_t *data = (session_data_t *)handle; - session_data_t * sess_data_p; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - if ( data != NULL){ - sess_data_p = (session_data_t *)findhash(data->sess_id); - if ( sess_data_p != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sess_data_p->video_mute); - return sess_data_p->video_mute; - } - } - - return FALSE; -} - -/** - * get SDP for CreateOffer\Create answer success callback - * @param handle - call handle - * @return sdp - */ -cc_string_t CCAPI_CallInfo_getSDP(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getSDP"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->sdp); - return data->sdp; - } - - return strlib_empty(); -} - -/** - * get status code from internal JSEP functions - * @param handle - call handle - * @return status code - */ -cc_int32_t CCAPI_CallInfo_getStatusCode(cc_callinfo_ref_t handle){ - static const char *fname="CCAPI_CallInfo_getStatusCode"; - session_data_t *data = (session_data_t *)handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( data != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->cause); - return data->cause; - } - - return CC_CAUSE_NORMAL; -} - - -/** - * get media stream table - * @param handle - call handle - * @return status MediaStreamTable - */ -MediaStreamTable* CCAPI_CallInfo_getMediaStreams(cc_callinfo_ref_t handle) { - static const char *fname="CCAPI_CallInfo_getMediaStreams"; - session_data_t *data = (session_data_t *)handle; - MediaTrack track; - MediaStreamTable* table = cpr_malloc(sizeof(MediaStreamTable)); - if (!table) - return NULL; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (data != NULL) { - table->media_stream_id = data->media_stream_id; - table->num_tracks = 1; /* this will change when we have multiple tracks per stream */ - track.media_stream_track_id = data->media_stream_track_id; - track.video = FALSE; - table->track[0] = track; - - /* - * Partly implemented multi-track handling - cc_table = data->media_tracks; - table->stream_id = (unsigned int)cc_table->stream_id; - table->num_tracks = (unsigned int)cc_table->num_tracks; - track.track_id = cc_table->track[0].ref_id; - table->track[0] = track; - */ - return table; - } - - return table; -} diff --git a/libs/sipcc/core/ccapp/ccapi_config.c b/libs/sipcc/core/ccapp/ccapi_config.c deleted file mode 100644 index e542901191..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_config.c +++ /dev/null @@ -1,108 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "phone_debug.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "prot_configmgr.h" -#include "cc_types.h" -#include "config_parser.h" -#include "config_api.h" -#include "ccapi_snapshot.h" -#include "ccapi_device.h" -#include "ccapi_device_info.h" -#include "cc_device_manager.h" -#include "ccapi_service.h" -#include "util_string.h" - -extern boolean apply_config; -extern cc_apply_config_result_t apply_config_result; -cc_boolean parse_setup_properties (int device_handle, const char *device_name, const char *sipUser, const char *sipPassword, const char *sipDomain); - -/** - * - * @return - */ - -void CCAPI_Start_response(int device_handle, const char *device_name, const char *sipUser, const char *sipPassword, const char *sipDomain) { - static const char fname[] = "CCAPI_Start_response"; - - if (is_empty_str((char*)sipUser) || is_empty_str((char*)sipDomain)) { - CCAPP_ERROR(DEB_F_PREFIX" invalid registration details user=%x, domain=%x\n", DEB_F_PREFIX_ARGS(CC_API, fname), sipUser, sipDomain); - return; - } - - g_dev_hdl = device_handle; - sstrncpy(g_dev_name, device_name, sizeof(g_dev_name)); - - if (is_phone_registered() == FALSE) { - - if (parse_setup_properties(device_handle, device_name, sipUser, sipPassword, sipDomain)) { - registration_processEvent(EV_CC_CONFIG_RECEIVED); - } - return; - } - - } - -/* New Function - Register without using config file downloaded from cucm - */ -cc_boolean parse_setup_properties (int device_handle, const char *device_name, const char *sipUser, const char *sipPassword, const char *sipDomain) { - CC_Config_setStringValue(CFGID_DEVICE_NAME, device_name); - - config_setup_main(sipUser, sipPassword, sipDomain); - - ccsnap_device_init(); - ccsnap_line_init(); - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_CONFIG_CHANGED, CC_DEVICE_ID); - return TRUE; -} - -cc_boolean CCAPI_Config_set_server_address(const char *ip_address) { - config_setup_server_address(ip_address); - return TRUE; -} - -cc_boolean CCAPI_Config_set_transport_udp(const cc_boolean is_udp) { - config_setup_transport_udp(is_udp); - return TRUE; -} - -cc_boolean CCAPI_Config_set_local_voip_port(const int port) { - config_setup_local_voip_control_port(port); - return TRUE; -} - -cc_boolean CCAPI_Config_set_remote_voip_port(const int port) { - config_setup_remote_voip_control_port(port); - return TRUE; -} - -int CCAPI_Config_get_local_voip_port() { - return config_get_local_voip_control_port(); -} - -int CCAPI_Config_get_remote_voip_port() { - return config_get_remote_voip_control_port(); -} - -const char* CCAPI_Config_get_version() { - return config_get_version(); -} - -cc_boolean CCAPI_Config_set_p2p_mode(const cc_boolean is_p2p) { - config_setup_p2p_mode(is_p2p); - return TRUE; -} - -cc_boolean CCAPI_Config_set_sdp_mode(const cc_boolean is_sdp) { - config_setup_sdp_mode(is_sdp); - return TRUE; -} - -cc_boolean CCAPI_Config_set_avp_mode(const cc_boolean is_rtpsavpf) { - config_setup_avp_mode(is_rtpsavpf); - return TRUE; -} diff --git a/libs/sipcc/core/ccapp/ccapi_device.c b/libs/sipcc/core/ccapp/ccapi_device.c deleted file mode 100644 index 79a919410f..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_device.c +++ /dev/null @@ -1,290 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdlib.h" -#include "string_lib.h" -#include "ccapi_snapshot.h" -#include "ccapi_device.h" -#include "CCProvider.h" -#include "cc_config.h" -#include "cc_call_feature.h" -#include "cc_device_feature.h" -#include "ccsip_messaging.h" -#include "ccapi_call_info.h" -#include "cc_device_manager.h" -#include "cc_service_listener.h" -#include "platform_api.h" -#include "util_string.h" -#include "ccapi_service.h" -#include "ccapi_device_info.h" - -char g_new_signaling_ip[MAX_IPADDR_STR_LEN]; - -dock_undock_event_t g_dock_undock_event = MEDIA_INTERFACE_UPDATE_NOT_REQUIRED; -extern accessory_cfg_info_t g_accessoryCfgInfo; - -extern void escalateDeescalate(); - -int signaling_interface_type; - -/** - * Get device reference handle - * @return cc_deviceinfo_ref_t - reference handle of the device - */ -cc_device_handle_t CCAPI_Device_getDeviceID() -{ - return CC_DEVICE_ID; -} - -/** - * Get device reference handle - * @param handle - device handle - * @return cc_deviceinfo_ref_t - reference handle of the device - */ -cc_deviceinfo_ref_t CCAPI_Device_getDeviceInfo(cc_device_handle_t handle) -{ - cc_device_info_t *device_info = (cc_device_info_t*)cpr_malloc(sizeof(cc_device_info_t)); - - if (device_info) { - *device_info = g_deviceInfo; - device_info->name = strlib_copy(g_deviceInfo.name); - if (device_info->name == NULL) { - device_info->name = strlib_empty(); - } - device_info->not_prompt = strlib_copy(g_deviceInfo.not_prompt); - if (device_info->not_prompt == NULL) { - device_info->not_prompt = strlib_empty(); - } - device_info->ref_count = 1; - } - return device_info; -} - -/** - * Retain the deviceInfo snapshot - * @param handle - device handle - * @param cc_deviceinfo_ref_t - refrence to the block to be retained - * @return void - */ -void CCAPI_Device_retainDeviceInfo(cc_deviceinfo_ref_t ref){ - cc_device_info_t *device_info = ref; - if (device_info) { - device_info->ref_count++; - } -} - -/** - * Set device configuration file location - * @param [in] ref - refrence to the block to be freed - * @param [in] file_path - device config file full path - * @return void - */ -void CCAPI_Device_configUpdate(cc_device_handle_t handle, file_path_t file_path) { - CC_Config_setStringValue(CFGID_CONFIG_FILE, file_path); -} - -/** - * Release the deviceInfo snapshot - * @param handle - device handle - * @param cc_deviceinfo_ref_t - refrence to the block to be released - * @return void - */ -void CCAPI_Device_releaseDeviceInfo(cc_deviceinfo_ref_t ref){ - cc_device_info_t *device_info = ref; - - if (device_info) { - device_info->ref_count--; - if ( device_info->ref_count == 0 ) { - strlib_free(device_info->name); - strlib_free(device_info->not_prompt); - cpr_free(device_info); - } - } -} - - -/** - * Create a call on the device - * @param handle - device handle - * @return cc_call_handle_t - handle of the call created - */ -cc_call_handle_t CCAPI_Device_CreateCall(cc_device_handle_t handle) -{ - return CC_createCall(0); -} - -/** - * Enable or disable video capability of the device. - * @param handle - device handle - * @param enable - a flag to indicate that application wants to enable of - * disable video capability of the device. - * @return void - */ -void CCAPI_Device_enableVideo(cc_device_handle_t handle, cc_boolean enable) -{ - CC_DeviceFeature_enableVideo(enable); - g_accessoryCfgInfo.video = ACCSRY_CFGD_APK; -} - -/** - * Enable or disable camera capability of the device. - * @param handle - device handle - * @param enable - a flag to indicate that application wants to enable of - * disable camera capability of the device. - * @return void - */ -void CCAPI_Device_enableCamera(cc_device_handle_t handle, cc_boolean enable) -{ - CC_DeviceFeature_enableCamera(enable); - g_accessoryCfgInfo.camera = ACCSRY_CFGD_APK; -} - -/** - * CCAPI_Device_setDigestNamePasswd - * - * @param handle - device handle - * @param name - The Digest auth name - * @param passwd - The password for that name for the line - * @return void - */ -void CCAPI_Device_setDigestNamePasswd (cc_device_handle_t handle, - char *name, char *pw) -{ - int line; - - for(line = 0; line < MAX_CONFIG_LINES; line++) { - CC_Config_setStringValue(CFGID_LINE_AUTHNAME + line, name); - CC_Config_setStringValue(CFGID_LINE_PASSWORD + line, pw); - } -} - -/** - * CCAPI_Device_IP_Update - * - * There is a change in the IP address and the values of new set - * of signaling and media IP addresses are provided. - * These value are compared with the current IP address values - * and depending on what changed, restart and/or re-invite - * action is taken. - * - * The case being addressed. - * 1) If the signaling IP change happens during a call, - * the change is deferred till phone is idle. - * 2)If media IP change happens during a call, it is applied immediately. - * 3) If both change, and call is active, that is treated same - * combination of case 1) and 2). - * 4) If no call is present, and signaling IP change, - * sipcc will re-register with new IP. - * - * @param handle - device handle - * @param signaling_ip - IP address that Must be used for signalling - * @param signaling_interface - Interface Name associaed with signaling IP - * @param signaling_int_type - Interface type associaed with signaling IP - * @param media_ip - IP address that Must be used for media - * @param media_interface - Interface nmae associaed with media IP - * @param media_interface - Interface Type associaed with media IP - * @return void - */ -void CCAPI_Device_IP_Update (cc_device_handle_t handle, - const char *signaling_ip, - const char *signaling_interface, - int signaling_int_type, - const char *media_ip, - const char *media_interface, - int media_int_type) -{ - static const char fname[] = "CCAPI_Device_IP_Update"; - char curr_signaling_ip[MAX_IPADDR_STR_LEN]; - char curr_media_ip[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t sig_ip; - - signaling_interface_type = signaling_int_type; - - // init the ip addr string to empty string - init_empty_str(curr_signaling_ip); - init_empty_str(curr_media_ip); - init_empty_str(g_new_signaling_ip); - - config_get_value(CFGID_MY_IP_ADDR, &sig_ip, sizeof(cpr_ip_addr_t)); - sig_ip.type = CPR_IP_ADDR_IPV4; - util_ntohl(&sig_ip, &sig_ip); - ipaddr2dotted(curr_signaling_ip, &sig_ip); - - config_get_string(CFGID_MEDIA_IP_ADDR, curr_media_ip, - MAX_IPADDR_STR_LEN); - - DEF_DEBUG(DEB_F_PREFIX"New sig_ip=%s media_ip=%s Current: sig_ip: %s,"\ - "media_ip: %s \n", - DEB_F_PREFIX_ARGS(CC_API, fname), - signaling_ip, - media_ip, - curr_signaling_ip, - curr_media_ip); - - /* - * If signaling and media IP are empty, stop the - * SIP service and return; - */ - if ((is_empty_str((char *)signaling_ip) || - (strncmp(signaling_ip, "0.0.0.0", MAX_IPADDR_STR_LEN) == 0)) - && (is_empty_str((char *)media_ip) || - (strncmp(media_ip, "0.0.0.0", MAX_IPADDR_STR_LEN) == 0))) { - CC_Config_setStringValue(CFGID_MY_IP_ADDR, "0.0.0.0"); - CC_Config_setStringValue(CFGID_MEDIA_IP_ADDR, EMPTY_STR); - DEF_DEBUG(DEB_F_PREFIX"Media and Signaling IP Not provided."\ - "Shutdown sip stack", DEB_F_PREFIX_ARGS(CC_API, fname)); - if ((strncmp(curr_signaling_ip, signaling_ip, - MAX_IPADDR_STR_LEN) != 0)) { - registration_processEvent(EV_CC_IP_INVALID); - return; - } - } - - /* - * There is a change in the signaling IP, set the - * new IP as the platform signaling IP and re-register - */ - if ((signaling_ip != NULL) && - (strncmp(curr_signaling_ip, signaling_ip, MAX_IPADDR_STR_LEN) != 0)) { - CC_Config_setStringValue(CFGID_MY_IP_ADDR, signaling_ip); - DEF_DEBUG(DEB_F_PREFIX"Signaling IP changed. Re-register, if needed.", - DEB_F_PREFIX_ARGS(CC_API, fname)); - registration_processEvent(EV_CC_IP_VALID); - - } - - /* - * There is a change in the media IP, set the - * new IP as the platform media IP and post the call to GSM - * to initiate re-inivite for all relevane calls - */ - if ((media_ip != NULL) && - (strncmp(curr_media_ip, media_ip, MAX_IPADDR_STR_LEN) != 0)) { - CC_Config_setStringValue(CFGID_MEDIA_IP_ADDR, media_ip); - if (g_dock_undock_event != MEDIA_INTERFACE_UPDATE_IN_PROCESS) { - g_dock_undock_event = MEDIA_INTERFACE_UPDATE_STARTED; - DEF_DEBUG(DEB_F_PREFIX" MEDIA_INTERFACE_UPDATE received. escalateDeescalate.", - DEB_F_PREFIX_ARGS(CC_API, fname)); - escalateDeescalate(); - }else { - DEF_DEBUG(DEB_F_PREFIX"MEDIA_INTERFACE_UPDATE received but escalateDeescalate already in progress:%d", - DEB_F_PREFIX_ARGS(CC_API, fname), g_dock_undock_event); - } - } -} - -/** - * CCAPI_Device_setVideoAutoTxPreference - * - * @param handle - device handle - * @param txPref - TRUE=> auto Tx Video prefered - * @return void - */ -void CCAPI_Device_setVideoAutoTxPreference (cc_device_handle_t handle, cc_boolean txPref) -{ - CCAPP_DEBUG("CCAPI_Device_setVideoAutoTxPreference: updated to %d\n", txPref); - cc_media_setVideoAutoTxPref(txPref); -} - - diff --git a/libs/sipcc/core/ccapp/ccapi_device_info.c b/libs/sipcc/core/ccapp/ccapi_device_info.c deleted file mode 100644 index c6671915b0..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_device_info.c +++ /dev/null @@ -1,475 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "string_lib.h" -#include "cc_constants.h" -#include "ccapi_snapshot.h" -#include "ccapi_device_info.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "phone_debug.h" -#include "ccapi_snapshot.h" -#include "ccapi_device_info.h" -#include "util_string.h" - - -/** - * gets the device name - * @returns - a pointer to the device name - */ -cc_deviceinfo_ref_t CCAPI_DeviceInfo_getDeviceHandle () -{ - static const char *fname="CCAPI_DeviceInfo_getDeviceHandle"; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - CCAPP_DEBUG(DEB_F_PREFIX"returned 0 (default)\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return 0; -} - -/** - * gets the device name - * @returns - a pointer to the device name - */ -cc_string_t CCAPI_DeviceInfo_getDeviceName (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getDeviceName"; - cc_device_info_t *device = handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( device != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device->name); - return device->name; - } - - return strlib_empty(); -} - -/** - * gets the device idle status - * @param [in] handle - reference to device info - * @returns boolean - idle status - */ -cc_boolean CCAPI_DeviceInfo_isPhoneIdle(cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_isPhoneIdle"; - boolean ret = TRUE; - hashItr_t itr; - session_data_t * session_data; - cc_call_state_t call_state; - - hashItrInit(&itr); - - while ((session_data = hashItrNext(&itr)) != NULL) { - call_state = session_data->state; - if (call_state != ONHOOK && - call_state != REMINUSE) { - ret = FALSE; - break; - } - } - CCAPP_DEBUG(DEB_F_PREFIX"idle state=%d session_id=0x%x call-state=%d handle=%x\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ret, - (session_data != NULL)? session_data->sess_id: 0, - (session_data != NULL)? session_data->state: 0, - (handle)? handle:0); - return ret; - -} - -/** - * gets the service state - * @param [in] handle - reference to device info - * @returns cc_service_state_t - INS/OOS - */ -cc_service_state_t CCAPI_DeviceInfo_getServiceState (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getServiceState"; - cc_device_info_t *device = handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( device != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device->ins_state); - return device->ins_state; - } - - return CC_STATE_IDLE; -} - -/** - * gets the service cause - * @param [in] handle - reference to device info - * @returns cc_service_cause_t - reason for service state - */ -cc_service_cause_t CCAPI_DeviceInfo_getServiceCause (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getServiceCause"; - cc_device_info_t *device = handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( device != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device->ins_cause); - return device->ins_cause; - } - - return CC_CAUSE_NONE; - -} - -/** - * gets the cucm mode - * @returns cc_cucm_mode_t - CUCM mode - */ -cc_cucm_mode_t CCAPI_DeviceInfo_getCUCMMode (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getCUCMMode"; - cc_device_info_t *device = handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( device != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device->cucm_mode); - return device->cucm_mode; - } - - return CC_MODE_INVALID; -} - -/** - * gets list of handles to calls on the device - * @param handle - device handle - * @param handles - array of call handle to be returned - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getCalls (cc_deviceinfo_ref_t handle, cc_call_handle_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getCalls"; - hashItr_t itr; - session_data_t *data; - int i=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL && - i<*count ) { - handles[i++] = CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - *count=i; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return) \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * gets list of handles to calls on the device by State - * @param handle - device handle - * @param state - state for whcih calls are requested - * @param handles - array of call handle to be returned - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getCallsByState (cc_deviceinfo_ref_t handle, cc_call_state_t state, - cc_call_handle_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getCallsByState"; - hashItr_t itr; - session_data_t *data; - int i=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL && - i<*count ) { - if ( data->state == state ) { - handles[i++] = CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - } - *count=i; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return) \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * gets list of handles to lines on the device - * @param handles[in,out] - array of line handle to be returned - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getLines (cc_deviceinfo_ref_t handle, cc_lineid_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getLines"; - cc_line_info_t *line; - int i=1, j=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - CCAPP_DEBUG(" LINES Start "); - - while ( (line = ccsnap_getLineInfo(i++)) != NULL && - j<*count ) { - CCAPP_DEBUG(" LINE handle[%d]=%d", j, line->button ); - /* We will use button as line handles */ - handles[j++] = line->button; - } - *count=j; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return) \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * gets list of handles to features on the device - * @param handles[in,out] - array of feature handle to be returned - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getFeatures (cc_deviceinfo_ref_t handle, cc_featureinfo_ref_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getFeatures"; - cc_featureinfo_ref_t feature; - int i=0, j=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - for (i=1;i<=MAX_CONFIG_LINES && j<*count;i++) { - feature = (cc_featureinfo_ref_t) ccsnap_getFeatureInfo(i); - if(feature != NULL){ - handles[j++] = feature; - } - } - *count=j; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return) \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * gets handles of call agent servers - * @param handles - array of handles to call agent servers - * @param count[in/out] number allocated in array/elements returned - * @returns - */ -void CCAPI_DeviceInfo_getCallServers (cc_deviceinfo_ref_t handle, cc_callserver_ref_t handles[], cc_uint16_t *count) -{ - static const char *fname="CCAPI_DeviceInfo_getCallServers"; - int i, j=0; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - for (i=0;iname != 0) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ref->name); - return ref->name; - } - return strlib_empty(); -} - -/** - * gets call server mode - * @param handle - handle of call server - * @returns - mode of the call server - */ -cc_cucm_mode_t CCAPI_DeviceInfo_getCallServerMode (cc_callserver_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getCallServerMode"; - cc_call_server_t *ref = (cc_call_server_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ref->type); - return ref->type; - } - - return CC_MODE_INVALID; -} - -/** - * gets calls erver name - * @param handle - handle of call server - * @returns status of the call server - */ -cc_ccm_status_t CCAPI_DeviceInfo_getCallServerStatus (cc_callserver_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getCallServerStatus"; - cc_call_server_t *ref = (cc_call_server_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), (ref->status)); - return ref->status; - } - - return CC_CCM_STATUS_NONE; -} - -/** - * get the NOTIFICATION PROMPT - * @param [in] handle - reference to device info - * @returns - */ -cc_string_t CCAPI_DeviceInfo_getNotifyPrompt (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getNotifyPrompt"; - cc_device_info_t *ref = (cc_device_info_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), (ref->not_prompt)); - return ref->not_prompt; - } - - return strlib_empty(); -} - -/** - * get the NOTIFICATION PROMPT PRIORITY - * @param [in] handle - reference to device info - * @returns - */ -cc_uint32_t CCAPI_DeviceInfo_getNotifyPromptPriority (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getNotifyPromptPriority"; - cc_device_info_t *ref = (cc_device_info_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), (ref->not_prompt_prio)); - return ref->not_prompt_prio; - } - - return 0; -} - -/** - * get the NOTIFICATION PROMPT PROGRESS - * @param [in] handle - reference to device info - * @returns - */ -cc_uint32_t CCAPI_DeviceInfo_getNotifyPromptProgress (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getNotifyPromptProgress"; - cc_device_info_t *ref = (cc_device_info_t *) handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if (ref != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %02X\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), (ref->not_prompt_prog)); - return ref->not_prompt_prog; - } - - return 0; -} - -/** - * gets provisioing for missed call logging - * @param [in] handle - reference to device info - * @returns boolean - false => disabled true => enabled - */ -cc_boolean CCAPI_DeviceInfo_isMissedCallLoggingEnabled (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_isMissedCallLoggingEnabled"; - - CCAPP_DEBUG(DEB_F_PREFIX" return val %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ccsnap_isMissedCallLoggingEnabled()); - return ccsnap_isMissedCallLoggingEnabled(); -} - -/** - * gets provisioing for placed call logging - * @param [in] handle - reference to device info - * @returns boolean - false => disabled true => enabled - */ -cc_boolean CCAPI_DeviceInfo_isPlacedCallLoggingEnabled (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_isPlacedCallLoggingEnabled"; - - CCAPP_DEBUG(DEB_F_PREFIX" return val %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ccsnap_isPlacedCallLoggingEnabled()); - return ccsnap_isPlacedCallLoggingEnabled(); -} - - -/** - * gets provisioing for received call logging - * @param [in] handle - reference to device info - * @returns boolean - false => disabled true => enabled - */ -cc_boolean CCAPI_DeviceInfo_isReceivedCallLoggingEnabled (cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_isReceivedCallLoggingEnabled"; - - CCAPP_DEBUG(DEB_F_PREFIX" return val %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ccsnap_isReceivedCallLoggingEnabled()); - return ccsnap_isReceivedCallLoggingEnabled(); -} - -/** - * gets time registration completed successfully - * @param [in] handle - reference to device info - * @returns long - the time registration completed successfully - */ -long long CCAPI_DeviceInfo_getRegTime (cc_deviceinfo_ref_t handle) -{ - return (g_deviceInfo.reg_time); -} - -/** - * Returns dot notation IP address phone used for registration purpose. If phone is not - * registered, then "0.0.0.0" is returned. - * @return char IP address used to register phone. - */ -cc_string_t CCAPI_DeviceInfo_getSignalingIPAddress(cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getSignalingIPAddress"; - cpr_ip_addr_t ip_addr = {0,{0}}; - - sip_config_get_net_device_ipaddr(&ip_addr); - ipaddr2dotted(g_deviceInfo.registration_ip_addr, &ip_addr); - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), g_deviceInfo.registration_ip_addr); - return g_deviceInfo.registration_ip_addr; -} - -/** - * Returns camera admin enable/disable status - * @param [in] handle - reference to device info - * @return cc_boolean - TRUE => enabled - */ -cc_boolean CCAPI_DeviceInfo_isCameraEnabled(cc_deviceinfo_ref_t handle) { - // returns the current status not the snapshot status - return cc_media_isTxCapEnabled(); -} - -/** - * Returns Video Capability admin enable/disable status - * @param [in] handle - reference to device info - * @return cc_boolean - TRUE => enabled - */ -cc_boolean CCAPI_DeviceInfo_isVideoCapEnabled(cc_deviceinfo_ref_t handle) { - // returns the current status not the snapshot status - return cc_media_isVideoCapEnabled(); -} - -/** - * gets the device mwi_lamp state - * @param [in] handle - reference to device info - * @returns boolean - mwi_lamp state - */ -cc_boolean CCAPI_DeviceInfo_getMWILampState(cc_deviceinfo_ref_t handle) -{ - static const char *fname="CCAPI_DeviceInfo_getMWILampState"; - cc_device_info_t *device = handle; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( device != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device->mwi_lamp); - return device->mwi_lamp; - } - - return FALSE; -} - diff --git a/libs/sipcc/core/ccapp/ccapi_feature_info.c b/libs/sipcc/core/ccapp/ccapi_feature_info.c deleted file mode 100644 index cc40589d5b..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_feature_info.c +++ /dev/null @@ -1,154 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccapi_snapshot.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "phone_debug.h" - -/** - * Get the physical button number on which this feature is configured - * @param feature - feature reference handle - * @return cc_int32_t - button assigned to the feature - */ -cc_int32_t CCAPI_featureInfo_getButton(cc_featureinfo_ref_t feature) -{ - static const char *fname="CCAPI_featureInfo_getButton"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->button); - return info->button; - } - return -1; -} - -/** - * Get the featureID - * @param feature - feature reference handle - * @return cc_int32_t - type of to the feature - */ -cc_int32_t CCAPI_featureInfo_getFeatureID(cc_featureinfo_ref_t feature) -{ - static const char *fname="CCAPI_featureInfo_getFeatureID"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->feature_id); - return info->feature_id; - } - return -1; -} - -/** - * Get the feature Label Name - * @param feature - feature reference handle - * @return cc_string_t - name of the feature created - */ -cc_string_t CCAPI_featureInfo_getDisplayName(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getDisplayName"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->name); - return ccsnap_get_line_label(info->button); - } - return NULL; -} - -/** - * Get the speeddial Number - * @param feature - feature reference handle - * @return cc_string_t - speeddial number of the feature created - */ -cc_string_t CCAPI_featureInfo_getSpeedDialNumber(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getSpeedDialNumber"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->speedDialNumber); - return info->speedDialNumber; - } - return NULL; -} - -/** - * Get the contact - * @param feature - feature reference handle - * @return cc_string_t - contact of the feature created - */ -cc_string_t CCAPI_featureInfo_getContact(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getContact"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->contact); - return info->contact; - } - return NULL; -} - -/** - * Get the retrieval prefix - * @param feature - feature reference handle - * @return cc_string_t - retrieval prefix of the feature created - */ -cc_string_t CCAPI_featureInfo_getRetrievalPrefix(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getRetrievalPrefix"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->retrievalPrefix); - return info->retrievalPrefix; - } - return NULL; -} - -/** - * Get BLF state - * @param feature - feature reference handle - * @return cc_string_t - handle of the feature created - */ -cc_blf_state_t CCAPI_featureInfo_getBLFState(cc_featureinfo_ref_t feature) { - static const char *fname="CCAPI_featureInfo_getBLFState"; - cc_feature_info_t *info = (cc_feature_info_t *)feature; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->blf_state); - return info->blf_state; - } - return CC_SIP_BLF_UNKNOWN; -} - -/** - * Get the feature option mask - * @param feature - feature reference handle - * @return cc_int32_t - feature option mask for the feature - */ -cc_int32_t CCAPI_featureInfo_getFeatureOptionMask(cc_featureinfo_ref_t feature) -{ - static const char *fname="CCAPI_featureInfo_getFeatureOptionMask"; - cc_feature_info_t *info; - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - info = (cc_feature_info_t *) feature; - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->featureOptionMask); - return info->featureOptionMask; - } - return -1; -} diff --git a/libs/sipcc/core/ccapp/ccapi_line.c b/libs/sipcc/core/ccapp/ccapi_line.c deleted file mode 100644 index 0931e11432..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_line.c +++ /dev/null @@ -1,81 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdlib.h" -#include "string_lib.h" -#include "cc_call_feature.h" -#include "ccapi_snapshot.h" -#include "ccapi_line.h" - -extern cc_line_info_t lineInfo[MAX_CONFIG_LINES+1]; - -/** - * Get reference handle for the line - * @return cc_call_handle_t - handle of the call created - */ -cc_lineinfo_ref_t CCAPI_Line_getLineInfo(cc_uint32_t lineID) -{ - cc_line_info_t *line_info = NULL; - int i; - - for (i=1;i<=MAX_CONFIG_LINES;i++) { - if ( (cc_uint32_t)lineInfo[i].button == lineID ) { - line_info = (cc_line_info_t*)cpr_malloc(sizeof(cc_line_info_t)); - - if (line_info) { - *line_info = lineInfo[i]; - line_info->ref_count = 1; - line_info->name = strlib_copy(lineInfo[i].name); - line_info->dn = strlib_copy(lineInfo[i].dn); - line_info->cfwd_dest = strlib_copy(lineInfo[i].cfwd_dest); - line_info->externalNumber = - strlib_copy(lineInfo[i].externalNumber); - } - } - } - return line_info; -} - -/** - * Create a call on the line - * @param [in] line - lineID - * @return cc_call_handle_t - handle of the call created - */ -cc_call_handle_t CCAPI_Line_CreateCall(cc_lineid_t line) -{ - // do we need to check the line on which this gets created? - return CC_createCall(line); -} - -/** - * Reatin the lineInfo snapshot - * @param cc_callinfo_ref_t - refrence to the block to be retained - * @return void - */ -void CCAPI_Line_retainLineInfo(cc_lineinfo_ref_t ref){ - cc_line_info_t *line_info = ref; - - line_info->ref_count++; -} -/** - * Free the lineInfo snapshot - * @param cc_callinfo_ref_t - refrence to the block to be freed - * @return void - */ -void CCAPI_Line_releaseLineInfo(cc_lineinfo_ref_t ref){ - cc_line_info_t *line_info = ref; - - if (line_info) { - line_info->ref_count--; - if ( line_info->ref_count == 0) { - strlib_free(line_info->name); - strlib_free(line_info->dn); - strlib_free(line_info->cfwd_dest); - strlib_free(line_info->externalNumber); - cpr_free(line_info); - } - } -} - - diff --git a/libs/sipcc/core/ccapp/ccapi_line_info.c b/libs/sipcc/core/ccapp/ccapi_line_info.c deleted file mode 100644 index dda2969e27..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_line_info.c +++ /dev/null @@ -1,425 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccapi_snapshot.h" -#include "ccapi_line.h" -#include "sessionHash.h" -#include "CCProvider.h" -#include "phone_debug.h" - -/** - * Get the line ID - * @param line - line reference handle - * @return line ID - */ -cc_int32_t CCAPI_lineInfo_getID(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getID"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - /* We will use button as line ID */ - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->button); - return info->button; - } - return -1; -} - -/** - * Get the line Name - * @param line - line reference handle - * @return cc_string_t - handle of the call created - */ -cc_string_t CCAPI_lineInfo_getName(cc_lineinfo_ref_t line) { - static const char *fname="CCAPI_lineInfo_getName"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->dn); - return info->dn; - } - return NULL; -} - -/** - * Get the line Label - * @param [in] line - line reference handle - * @return cc_string_t - line Label - * NOTE: The memory for return string doesn't need to be freed it will be freed when the info reference is freed - */ -cc_string_t CCAPI_lineInfo_getLabel(cc_lineinfo_ref_t line) { - static const char *fname="CCAPI_lineInfo_getLabel"; - cc_line_info_t *info = (cc_line_info_t *) line; - cc_string_t label = strlib_empty(); - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - label = ccsnap_get_line_label(info->button); - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), label); - } - return label; -} - -/** - * Get the line DN Number - * @param line - line reference handle - * @return cc_string_t - handle of the call created - */ -cc_string_t CCAPI_lineInfo_getNumber(cc_lineinfo_ref_t line) { - static const char *fname="CCAPI_lineInfo_getNumber"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->name); - return info->name; - } - return NULL; -} - -/** - * Get the line External Number - * @param line - line reference handle - * @return cc_string_t - handle of the call created - */ -cc_string_t CCAPI_lineInfo_getExternalNumber(cc_lineinfo_ref_t line) { - static const char *fname="CCAPI_lineInfo_getExternalNumber"; - cc_line_info_t *info = (cc_line_info_t *) line; - char externalNumberMask[MAX_EXTERNAL_NUMBER_MASK_SIZE]; - memset(externalNumberMask, 0, sizeof(externalNumberMask)); - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - config_get_string(CFGID_CCM_EXTERNAL_NUMBER_MASK, externalNumberMask, MAX_EXTERNAL_NUMBER_MASK_SIZE); - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->name); - if (strlen(externalNumberMask) > 0) { - CCAPP_DEBUG(DEB_F_PREFIX"number with mask applied == %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->externalNumber); - return info->externalNumber; - } else { - CCAPP_DEBUG(DEB_F_PREFIX"number without mask == %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->name); - return info->name; - } - } - return NULL; -} - -/** - * Get the physical button number on which this line is configured - * @param line - line reference handle - * @return cc_uint32_t - button number - */ -cc_uint32_t CCAPI_lineInfo_getButton(cc_lineinfo_ref_t line){ - static const char *fname="CCAPI_lineInfo_getButton"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->button); - return info->button; - } - return 0; - -} - -/** - * Get the Line Type - * @param [in] line - line reference handle - * @return cc_uint32_t - line featureID ( Line ) - */ -cc_line_feature_t CCAPI_lineInfo_getLineType(cc_lineinfo_ref_t line){ - static const char *fname="CCAPI_lineInfo_getLineType"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->line_type); - return info->line_type; - } - return 0; -} - - - -/** - * Get the CFWDAll status for the line - * @param line - line reference handle - * @return cc_boolean - isForwarded - */ -cc_boolean CCAPI_lineInfo_isCFWDActive(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_isCFWDActive"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->isCFWD); - return info->isCFWD; - } - return FALSE; -} - -/** - * Get the CFWDAll destination - * @param line - line reference handle - * @return cc_string_t - cfwd target - */ -cc_string_t CCAPI_lineInfo_getCFWDName(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getCFWDName"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cfwd_dest); - return info->cfwd_dest; - } - return NULL; -} - -/** - * Get the MWI Status - * @param line - line reference handle - * @return cc_uint32_t - MWI status (boolean 0 => no MWI) - */ -cc_uint32_t CCAPI_lineInfo_getMWIStatus(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIStatus"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d, status %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi, info->mwi.status); - return info->mwi.status; - } - return 0; -} - -/** - * Get the MWI Type - * @param line - line reference handle - * @return cc_uint32_t - MWI Type - */ -cc_uint32_t CCAPI_lineInfo_getMWIType(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIType"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d, type %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi, info->mwi.type); - return info->mwi.type; - } - return 0; -} - -/** - * Get the MWI new msg count - * @param line - line reference handle - * @return cc_uint32_t - MWI new msg count - */ -cc_uint32_t CCAPI_lineInfo_getMWINewMsgCount(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWINewMsgCount"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d, new count %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi, info->mwi.new_count); - return info->mwi.new_count; - } - return 0; -} -/** - * Get the MWI old msg count - * @param line - line reference handle - * @return cc_uint32_t - MWI old msg count - */ -cc_uint32_t CCAPI_lineInfo_getMWIOldMsgCount(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIOldMsgCount"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d, old_count %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi, info->mwi.old_count); - return info->mwi.old_count; - } - return 0; -} - -/** - * Get the MWI high priority new msg count - * @param line - line reference handle - * @return cc_uint32_t - MWI new msg count - */ -cc_uint32_t CCAPI_lineInfo_getMWIPrioNewMsgCount(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIPrioNewMsgCount"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d , pri_new count %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi, info->mwi.pri_new_count); - return info->mwi.pri_new_count; - } - return 0; -} -/** - * Get the MWI high priority old msg count - * @param line - line reference handle - * @return cc_uint32_t - MWI old msg count - */ -cc_uint32_t CCAPI_lineInfo_getMWIPrioOldMsgCount(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getMWIPrioOldMsgCount"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d, pri old_count %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->mwi, info->mwi.pri_old_count); - return info->mwi.pri_old_count; - } - return 0; -} - -/** - * Get calls on line - * @param [in] line - lineID - * @param [out] callref[] - Array of callinfo references - * @param [in/out] count - count of call references populated - * @return void - */ - -void CCAPI_LineInfo_getCalls(cc_lineid_t line, cc_call_handle_t handles[], int *count) -{ - static const char *fname="CCAPI_Line_getCalls"; - hashItr_t itr; - session_data_t *data; - int i=0; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL && - i<*count ) { - if ( GET_LINE_ID(data->sess_id) == line ){ - handles[i++] = CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - } - *count=i; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return) \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * Get calls on line - * @param [in] line - lineID - * @param [out] callref[] - Array of callinfo references - * @param [in/out] count - count of call references populated - * @return void - */ -void CCAPI_LineInfo_getCallsByState(cc_lineid_t line, cc_call_state_t state, - cc_call_handle_t handles[], int *count) -{ - static const char *fname="CCAPI_Line_getCallsByState"; - hashItr_t itr; - session_data_t *data; - int i=0; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL && - i<*count ) { - if ( GET_LINE_ID(data->sess_id) == line && data->state ==state ){ - handles[i++] = CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - } - *count=i; - CCAPP_DEBUG(DEB_F_PREFIX"Finished (no return) \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); -} - -/** - * Get the physical button number on which this line is configured - * @param [in] line - line reference handle - * @return cc_uint32_t - button number - */ -cc_boolean CCAPI_lineInfo_getRegState(cc_lineinfo_ref_t line) -{ - static const char *fname="CCAPI_lineInfo_getRegState"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->reg_state); - return info->reg_state; - } - return 0; -} - -/** - * has capability - is the feature allowed - * @param [in] line - line reference handle - * @param [in] feat_id - feature id - * @return boolean - is Allowed - */ -cc_boolean CCAPI_LineInfo_hasCapability (cc_lineinfo_ref_t line, cc_int32_t feat_id){ - static const char *fname="CCAPI_LineInfo_hasCapability"; - cc_line_info_t *info = (cc_line_info_t *) line; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"feature id: %d , value returned %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),feat_id, info->allowed_features[feat_id]); - return info->allowed_features[feat_id]; - } - - return FALSE; -} - - -/** - * get Allowed Feature set - * @param [in] line - line reference handle - * @param [in,out] feat_set - array of len CC_CALL_CAP_MAX - * @return cc_return_t - CC_SUCCESS or CC_FAILURE - */ -cc_return_t CCAPI_LineInfo_getCapabilitySet (cc_lineinfo_ref_t line, cc_int32_t feat_set[]){ - static const char *fname="CCAPI_LineInfo_getCapabilitySet"; - cc_line_info_t *info = (cc_line_info_t *) line; - int feat_id; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( info != NULL){ - for (feat_id = 0; feat_id < CCAPI_CALL_CAP_MAX; feat_id++) { - feat_set[feat_id] = info->allowed_features[feat_id]; - CCAPP_DEBUG(DEB_F_PREFIX"feature id: %d , value %d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),feat_id, feat_set[feat_id]); - } - - CCAPP_DEBUG(DEB_F_PREFIX"returned CC_SUCCESS\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return CC_SUCCESS; - } - - return CC_FAILURE; -} - - diff --git a/libs/sipcc/core/ccapp/ccapi_service.c b/libs/sipcc/core/ccapp/ccapi_service.c deleted file mode 100644 index bd6cafe066..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_service.c +++ /dev/null @@ -1,166 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccapi_service.h" -#include "cc_device_manager.h" -#include "cc_service.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "sessionConstants.h" -#include "ccsip_messaging.h" -#include "ccapp_task.h" -#include "config_api.h" -#include "ccapi_device.h" -#include "ccapi_device_info.h" -#include "cc_device_listener.h" -#include "cc_service_listener.h" -#include "plat_api.h" -#include "util_string.h" - -int sendResetUpdates = 0; // default is not to send updates - -// Global Variables -int g_dev_hdl; -char g_dev_name[G_DEV_NAME_SIZE]; -char g_cfg_p[G_CFG_P_SIZE]; -int g_compl_cfg; - -// Externs -extern void setState(); -extern void resetReady(); -extern void resetNotReady(); -extern void ccpro_handleserviceControlNotify(); - - -extern cc_srv_ctrl_cmd_t reset_type; -boolean isServiceStartRequestPending = FALSE; -cc_boolean is_action_to_be_deferred(cc_action_t action); -extern cc_action_t pending_action_type; -//cc_boolean parse_config_properties (int device_handle, const char *device_name, const char *cfg, int from_memory); - - - -/** - * Defines the management methods. - */ - -/** - * Pre-initialize the Sipcc stack. - * @return - */ -cc_return_t CCAPI_Service_create() { - CCAPP_ERROR("CCAPI_Service_create - calling CC_Service_create \n"); - - registration_processEvent(EV_CC_CREATE); - return (CC_SUCCESS); - //return (service_processEvent(EV_SRVC_CREATE)); -} - -/** - * Gracefully unload the Sipcc stack - * @return - */ -cc_return_t CCAPI_Service_destroy() { - CCAPP_ERROR("CCAPI_Service_destroy - calling CC_Service_destroy \n"); - - // if (is_action_to_be_deferred(STOP_ACTION) == TRUE) { - // return CC_SUCCESS; - // } - // initialize the config to empty - init_empty_str(g_cfg_p); - isServiceStartRequestPending = FALSE; - registration_processEvent(EV_CC_DESTROY); - return (CC_SUCCESS); -} - -/** - * Bring up the Sipcc stack in service - * @return - */ -cc_return_t CCAPI_Service_start() { - - if (isServiceStartRequestPending == TRUE) { - DEF_DEBUG("CCAPI_Service_start request is already pending. Ignoring this.\n"); - return CC_SUCCESS; - } - - DEF_DEBUG("CCAPI_Service_start - \n"); - isServiceStartRequestPending = TRUE; - - registration_processEvent(EV_CC_START); - - return (CC_SUCCESS); -} - -/** - * Stop Sipcc stack service - * @return - */ -cc_return_t CCAPI_Service_stop() { - - int sdpmode = 0; - - CCAPP_ERROR("CCAPI_Service_stop - calling registration stop \n"); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - if (is_action_to_be_deferred(STOP_ACTION) == TRUE) { - return CC_SUCCESS; - } - } - sendResetUpdates = 0; // reset to default is not to send updates - isServiceStartRequestPending = FALSE; - registration_processEvent(EV_CC_STOP); - return CC_SUCCESS; -} - - -/** - * reregister the Sipcc stack service, without downloading the config file - * - */ -cc_return_t CCAPI_Service_reregister(int device_handle, const char *device_name, - const char *cfg, - int complete_config) -{ - CCAPP_ERROR("CCAPI_Service_reregister - initiate reregister \n"); - - if (is_action_to_be_deferred(RE_REGISTER_ACTION) == TRUE) { - return CC_SUCCESS; - } - if (pending_action_type != NO_ACTION) { - CCAPP_ERROR("Reset/Restart is pending, reregister Ignored! \n"); - return CC_FAILURE; - } - - if (is_empty_str((char*)cfg)) { - CCAPP_ERROR("Reregister request with empty config. Exiting.\n"); - return CC_FAILURE; - } - - g_dev_hdl = device_handle; - sstrncpy(g_dev_name, device_name, sizeof(g_dev_name)); - sstrncpy(g_cfg_p, cfg, sizeof(g_cfg_p)); - CCAPP_DEBUG("CCAPI_Service_reregister - devce name [%s], cfg [%s] \n", g_dev_name, g_cfg_p); - g_compl_cfg = complete_config; - - registration_processEvent(EV_CC_RE_REGISTER); - - return (CC_SUCCESS); -} - -/** - * Reset Manager has request a reset, send the current state and - * start sending updates. - */ -void CCAPI_Service_reset_request() { - cc_deviceinfo_ref_t handle = 0; - sendResetUpdates = 1; - if (CCAPI_DeviceInfo_isPhoneIdle(handle) == TRUE) { - resetReady(); - } else { - resetNotReady(); - } - -} diff --git a/libs/sipcc/core/ccapp/ccapi_snapshot.c b/libs/sipcc/core/ccapp/ccapi_snapshot.c deleted file mode 100644 index b2e15b44b0..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_snapshot.c +++ /dev/null @@ -1,715 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "string.h" -#include "string_lib.h" -#include "text_strings.h" -#include "ccapi_snapshot.h" -#include "ccapi_device.h" -#include "ccapi_device_listener.h" -#include "ccapi_line.h" -#include "ccapi_line_listener.h" -#include "ccapi_line_info.h" -#include "ccapi_call.h" -#include "ccapi_call_listener.h" -#include "CCProvider.h" -#include "capability_set.h" -#include "phone_debug.h" - -cc_device_info_t g_deviceInfo; -accessory_cfg_info_t g_accessoryCfgInfo; -cc_line_info_t lineInfo[MAX_CONFIG_LINES+1]; -cc_feature_info_t featureInfo[MAX_CONFIG_LINES+1]; - -static void printCallInfo(cc_callinfo_ref_t info, const char* fname); -static void printFeatureInfo (ccapi_device_event_e type, cc_featureinfo_ref_t feature_info, const char* fname); - -cc_string_t lineLabels[MAX_CONFIG_LINES+1] = {0}; - - -void ccsnap_set_line_label(int btn, cc_string_t label) { - - CCAPP_ERROR(DEB_F_PREFIX"btn=%d label=%s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_set_line_label"), btn, label); - if ( btn > 0 && btn <= MAX_CONFIG_LINES+1 ) { - if ( label == NULL ) { - label = strlib_empty(); - } - if ( lineLabels[btn] == NULL ) { - lineLabels[btn] = strlib_empty(); - } - lineLabels[btn] = strlib_update(lineLabels[btn], label); - } -} - -cc_string_t ccsnap_get_line_label(int btn) { - if ( btn > 0 && btn <= MAX_CONFIG_LINES+1 ) { - return lineLabels[btn]; - } - return strlib_empty(); -} - -/* - * The below two functions are borrowed from CUCM/CUP as they both perform - * identical functions. That is, taking a DN 1555 and - * a mask 919476XXXX to build a true external number 9194761555. - */ -static void stringInsert(char *string, int num, char ch) -{ - - int len = strlen(string); - int k, j; - char tempString[100]; - sstrncpy(tempString, string, 100); - - for (k = 0; k < num; k++) - string[k] = ch; - - for (j = 0; j < len; j++) - string[k++] = tempString[j]; - - string[k] = 0; - -} - -/* - * Taken from CUCM/CUP code as they have done this already. - */ -cc_string_t CCAPI_ApplyTranslationMask (const char *ext, const char *mask) -{ - - char translationMask[100] = {'\0'}; - char dn[100] = {'\0'}; - char translatedString[100] = {'\0'}; - cc_string_t result; - unsigned int maskLen, - dnLen, - i, j = 0; - - if ((ext == NULL) || (mask == NULL)) { - return NULL; - } - - maskLen = strlen(mask); - dnLen = strlen(ext); - - if ((dnLen == 0) || (maskLen == 0)) { - CCAPP_DEBUG(DEB_F_PREFIX"CCAPI_ApplyTranslationMask DN or mask has len=0\n", -DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_ApplyTranslationMask")); - return NULL; - } - - /* make sure there's enough space in the buffer to - * hold the translated string. - */ - if (dnLen + maskLen > 99) { - CCAPP_DEBUG(DEB_F_PREFIX"CCAPI_ApplyTranslationMask length overflow\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_ApplyTranslationMask")); - return NULL; - } - - sstrncpy(translationMask, mask, 100); - sstrncpy(dn, ext, 100); - - /* make sure DN is numeric only */ - for (i=0; i< dnLen; i++) { - if (isalpha(dn[i])) { - return 0; - } - } - - if (maskLen > dnLen) { - stringInsert(dn, maskLen - dnLen, '?'); - } - - /* if the digit string is longer than the translation mask - * prepad the translation mask with '%'. - */ - if (dnLen > maskLen) { - stringInsert(translationMask, dnLen - maskLen, '%'); - } - - dnLen = strlen(dn); - - for (i=0; i < dnLen; i++) { - if (translationMask[i] == '%') - continue; - else if (translationMask[i] == 'X') - translatedString[j++] = dn[i]; - else - translatedString[j++] = translationMask[i]; - } - - translatedString[j] = 0; - result = strlib_malloc(translatedString, strlen(translatedString)); - return result; -} - -/** - * Before initing the line_info release any memory which has been used - * so we do not leak any here. - */ -void ccsnap_line_pre_init () { - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering line_pre_init to clear it out to avoid mem leaks\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_line_pre_init")); - - for (i=1;i 0)) { - strlib_free(lineInfo[i].name); - } - if ((lineInfo[i].dn) && (strlen(lineInfo[i].dn) > 0)) { - strlib_free(lineInfo[i].dn); - } - if ((lineInfo[i].cfwd_dest) && (strlen(lineInfo[i].cfwd_dest) > 0)) { - strlib_free(lineInfo[i].cfwd_dest); - } - if ((lineInfo[i].externalNumber) && - (strlen(lineInfo[i].externalNumber) > 0)) { - strlib_free(lineInfo[i].externalNumber); - } - if ((featureInfo[i].speedDialNumber) && - (strlen(featureInfo[i].speedDialNumber) > 0)) { - strlib_free(featureInfo[i].speedDialNumber); - } - if ((featureInfo[i].contact) && (strlen(featureInfo[i].contact) > 0)) { - strlib_free(featureInfo[i].contact); - } - if ((featureInfo[i].name) && (strlen(featureInfo[i].name) > 0)) { - strlib_free(featureInfo[i].name); - } - if ((featureInfo[i].retrievalPrefix) && - (strlen(featureInfo[i].retrievalPrefix) > 0)) { - strlib_free(featureInfo[i].retrievalPrefix); - } - } -} - -/** - * Initialize lineinfo and featureinfo arrays - */ -void ccsnap_line_init() { - int i; - cc_uint32_t tmpInt; - char tempStr[MAX_URL_LENGTH]; - char maskStr[MAX_EXTERNAL_NUMBER_MASK_SIZE]; - - /* clean up structure if need be */ - ccsnap_line_pre_init(); - - memset(lineInfo, 0, MAX_CONFIG_LINES*sizeof(cc_line_info_t)); - memset(featureInfo, 0, MAX_CONFIG_LINES*sizeof(cc_feature_info_t)); - for (i=1;i<=MAX_CONFIG_LINES;i++) { - config_get_line_value(CFGID_LINE_FEATURE, &tmpInt, sizeof(tmpInt), i); - if ( tmpInt == cfgLineFeatureDN ) { - lineInfo[i].button = i; - lineInfo[i].line_type = tmpInt; - config_get_line_value(CFGID_LINE_INDEX, &tmpInt, sizeof(tmpInt), i); - lineInfo[i].line_id = tmpInt; - config_get_line_value(CFGID_LINE_DISPLAYNAME_STRING, tempStr, - MAX_URL_LENGTH, i); - lineInfo[i].dn = strlib_malloc(tempStr, strlen(tempStr)); - config_get_line_value(CFGID_LINE_NAME_STRING, tempStr, - MAX_URL_LENGTH, i); - lineInfo[i].name = strlib_malloc(tempStr, strlen(tempStr)); - config_get_line_value(CFGID_LINE_CFWDALL, tempStr, - MAX_URL_LENGTH, i); - lineInfo[i].cfwd_dest = strlib_malloc(tempStr, strlen(tempStr)); - config_get_line_value(CFGID_LINE_SPEEDDIAL_NUMBER_STRING, tempStr, - MAX_URL_LENGTH, i); - memset(maskStr, 0, sizeof(maskStr)); - config_get_string(CFGID_CCM_EXTERNAL_NUMBER_MASK, maskStr, MAX_EXTERNAL_NUMBER_MASK_SIZE); - if (strlen(maskStr) > 0) { - lineInfo[i].externalNumber = CCAPI_ApplyTranslationMask(lineInfo[i].name, maskStr); - CCAPP_DEBUG("Setting lineInfo[i].externalNumber to %s\n", lineInfo[i].externalNumber); - } else { - lineInfo[i].externalNumber = strlib_empty(); - } - } else { - lineInfo[i].line_id = MAX_CONFIG_LINES+1; // invalid line id - lineInfo[i].button = i; - lineInfo[i].dn = strlib_empty(); - lineInfo[i].name = strlib_empty(); - lineInfo[i].cfwd_dest = strlib_empty(); - lineInfo[i].externalNumber = strlib_empty(); - } - capset_get_idleset(CC_MODE_CCM, lineInfo[i].allowed_features); - - // get feature again because it might have been changed if it is a DN - // and the tmpInt might have a different value - config_get_line_value(CFGID_LINE_FEATURE, &tmpInt, sizeof(tmpInt), i); - - // features which have no properties - if ( tmpInt == cfgLineFeatureAllCalls || - tmpInt == cfgLineFeatureMaliciousCallID || - tmpInt == cfgLineFeatureRedial || tmpInt == cfgLineFeatureAnswerOldest || tmpInt == cfgLineFeatureServices ) { - featureInfo[i].feature_id = tmpInt; - featureInfo[i].button = i; - featureInfo[i].speedDialNumber = strlib_empty(); - featureInfo[i].contact = strlib_empty(); - featureInfo[i].name = strlib_empty(); - featureInfo[i].retrievalPrefix = strlib_empty(); - featureInfo[i].featureOptionMask = 0; - } else if ( tmpInt == cfgLineFeatureSpeedDialBLF || tmpInt == cfgLineFeatureSpeedDial){ - featureInfo[i].feature_id = tmpInt; - featureInfo[i].button = i; - config_get_line_value(CFGID_LINE_SPEEDDIAL_NUMBER_STRING, tempStr, - MAX_URL_LENGTH, i); - featureInfo[i].speedDialNumber = strlib_malloc(tempStr, strlen(tempStr)); - featureInfo[i].contact = strlib_empty(); - config_get_line_value(CFGID_LINE_NAME_STRING, tempStr, - MAX_URL_LENGTH, i); - featureInfo[i].name = strlib_malloc(tempStr, strlen(tempStr)); - featureInfo[i].retrievalPrefix = strlib_empty(); - config_get_line_value(CFGID_LINE_FEATURE_OPTION_MASK, &tmpInt, sizeof(tmpInt), i); - featureInfo[i].featureOptionMask = tmpInt; - featureInfo[i].blf_state = CC_SIP_BLF_UNKNOWN; - } else { - featureInfo[i].feature_id = 0; - featureInfo[i].button = MAX_CONFIG_LINES+1; // invalid button value - featureInfo[i].speedDialNumber = strlib_empty(); - featureInfo[i].contact = strlib_empty(); - featureInfo[i].name = strlib_empty(); - featureInfo[i].retrievalPrefix = strlib_empty(); - featureInfo[i].featureOptionMask = 0; - } - } -} - -cc_line_info_t* ccsnap_getLineInfo(int lineID) -{ - int i; - cc_lineid_t line = (cc_lineid_t)lineID; - - for (i=1;i<=MAX_CONFIG_LINES;i++) { - if ( lineInfo[i].line_id == line ) { - return &lineInfo[i]; - } - } - - return NULL; -} - -cc_line_info_t* ccsnap_getLineInfoFromBtn(int btnID) -{ - int i; - - for (i=1;i<=MAX_CONFIG_LINES;i++) { - if ( lineInfo[i].button == btnID ) { - return &lineInfo[i]; - } - } - - return NULL; -} - -cc_boolean allowedFeature(int fid){ - return TRUE; -} - -cc_feature_info_t* ccsnap_getFeatureInfo(int featureIndex) -{ - if ( ( featureIndex<=MAX_CONFIG_LINES ) && - ( featureIndex>= 1 ) && - ( featureInfo[featureIndex].button == featureIndex ) ) { - if ( allowedFeature(featureInfo[featureIndex].feature_id) ){ - return &featureInfo[featureIndex]; - } - } - - return NULL; -} - -/** - * Release any used mem to avoid a leak. - */ -void ccsnap_device_pre_init () { - int i = 0; - - CCAPP_DEBUG(DEB_F_PREFIX"Entering device_pre_init to clear it out to avoid mem leaks\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_device_pre_init")); - if ((g_deviceInfo.name) && (strlen(g_deviceInfo.name) > 0)) { - strlib_free(g_deviceInfo.name); - } - if ((g_deviceInfo.not_prompt) && (strlen(g_deviceInfo.not_prompt) > 0)) { - strlib_free(g_deviceInfo.not_prompt); - } - - i = 0; - while (i < CCAPI_MAX_SERVERS) { - if ((g_deviceInfo.ucm[i].name) && - (strlen(g_deviceInfo.ucm[i].name) > 0)) { - strlib_free(g_deviceInfo.ucm[i].name); - } - i++; - } -} - -void ccsnap_device_init() { - char temp[MAX_SIP_URL_LENGTH]; - - /* clean up structure if need be */ - ccsnap_device_pre_init(); - - memset (&g_deviceInfo, 0, sizeof(g_deviceInfo)); - g_deviceInfo.name =strlib_empty(); - g_deviceInfo.not_prompt =strlib_empty(); - - g_deviceInfo.not_prompt_prio = 0; - g_deviceInfo.not_prompt_prog = 0; - g_deviceInfo.mwi_lamp = FALSE; - g_deviceInfo.cucm_mode = CC_MODE_CCM; - g_deviceInfo.ins_state = CC_STATE_IDLE; - g_deviceInfo.ins_cause = CC_CAUSE_NONE; - g_deviceInfo.reg_time = 0; - - config_get_string(CFGID_CCM1_ADDRESS, temp, MAX_SIP_URL_LENGTH); - g_deviceInfo.ucm[0].name = strlib_malloc(temp, strlen(temp)); - g_deviceInfo.ucm[0].type = CC_MODE_CCM; - g_deviceInfo.ucm[0].status = CC_CCM_STATUS_NONE; - - config_get_string(CFGID_CCM2_ADDRESS, temp, MAX_SIP_URL_LENGTH); - g_deviceInfo.ucm[1].name = strlib_malloc(temp, strlen(temp)); - g_deviceInfo.ucm[1].type = CC_MODE_CCM; - g_deviceInfo.ucm[1].status = CC_CCM_STATUS_NONE; - - config_get_string(CFGID_CCM3_ADDRESS, temp, MAX_SIP_URL_LENGTH); - g_deviceInfo.ucm[2].name = strlib_malloc(temp, strlen(temp)); - g_deviceInfo.ucm[2].type = CC_MODE_CCM; - g_deviceInfo.ucm[2].status = CC_CCM_STATUS_NONE; - - config_get_string(CFGID_CCM_TFTP_IP_ADDR, temp, MAX_SIP_URL_LENGTH); - g_deviceInfo.ucm[3].name = strlib_malloc(temp, strlen(temp)); - g_deviceInfo.ucm[3].type = CC_MODE_CCM; - g_deviceInfo.ucm[3].status = CC_CCM_STATUS_NONE; - - g_accessoryCfgInfo.camera = ACCSRY_CFGD_CFG; - g_accessoryCfgInfo.video = ACCSRY_CFGD_CFG; -} - -void ccsnap_gen_deviceEvent(ccapi_device_event_e event, cc_device_handle_t handle){ - const char* fname = "ccsnap_gen_deviceEvent"; - - cc_device_info_t *device_info = CCAPI_Device_getDeviceInfo(handle); - if ( device_info != NULL ) { - CCAPP_DEBUG(DEB_F_PREFIX"data->ref_count=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->ref_count); - - switch (event) { - case CCAPI_DEVICE_EV_NOTIFYPROMPT: - CCAPP_DEBUG(DEB_F_PREFIX"data->not_prompt=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->not_prompt); - CCAPP_DEBUG(DEB_F_PREFIX"data->not_prompt_prio=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->not_prompt_prio); - CCAPP_DEBUG(DEB_F_PREFIX"data->not_prompt_prog=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->not_prompt_prog); - break; - case CCAPI_DEVICE_EV_STATE: - CCAPP_DEBUG(DEB_F_PREFIX"setting property %s to %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), "FullyRegistered", ((device_info->ins_state == CC_STATE_INS) ? "1" : "0")); - //intentional follow through to let the debugs get printed. - default: - CCAPP_DEBUG(DEB_F_PREFIX"data->name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->name); - CCAPP_DEBUG(DEB_F_PREFIX"data->mwi_lamp=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->mwi_lamp); - CCAPP_DEBUG(DEB_F_PREFIX"data->ins_state=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->ins_state); - CCAPP_DEBUG(DEB_F_PREFIX"data->cucm_mode=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->cucm_mode); - CCAPP_DEBUG(DEB_F_PREFIX"data->ins_cause=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->ins_cause); - break; - - } - - CCAPI_DeviceListener_onDeviceEvent(event, handle, device_info); - } - CCAPI_Device_releaseDeviceInfo(device_info); -} - -void ccsnap_gen_lineEvent(ccapi_line_event_e event, cc_lineid_t handle){ - const char* fname = "ccsnap_gen_lineEvent"; - cc_line_info_t *line_info = CCAPI_Line_getLineInfo(handle); - - if ( line_info != NULL ) { - if (g_CCAppDebug) { - CCAPP_DEBUG(DEB_F_PREFIX"data->ref_count=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->ref_count); - CCAPP_DEBUG(DEB_F_PREFIX"data->line_id=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->line_id); - CCAPP_DEBUG(DEB_F_PREFIX"data->button=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->button); - CCAPP_DEBUG(DEB_F_PREFIX"data->reg_state=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->reg_state); - CCAPP_DEBUG(DEB_F_PREFIX"data->isCFWD=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->isCFWD); - CCAPP_DEBUG(DEB_F_PREFIX"data->isLocalCFWD=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->isLocalCFWD); - CCAPP_DEBUG(DEB_F_PREFIX"data->mwi=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->mwi); - CCAPP_DEBUG(DEB_F_PREFIX"data->name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->name); - CCAPP_DEBUG(DEB_F_PREFIX"data->dn=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->dn); - CCAPP_DEBUG(DEB_F_PREFIX"data->cfwd_dest=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->cfwd_dest); - } - CCAPI_LineListener_onLineEvent(event, handle, line_info); - } - CCAPI_Line_releaseLineInfo(line_info); -} - -void ccsnap_gen_callEvent(ccapi_call_event_e event, cc_call_handle_t handle){ - - session_data_t *call_info = CCAPI_Call_getCallInfo(handle); - - if ( call_info == NULL ) { - call_info = getDeepCopyOfSessionData(NULL); - } - - //print all info - if (g_CCAppDebug) { - printCallInfo(call_info, "ccsnap_gen_callEvent"); - } - - CCAPI_CallListener_onCallEvent(event, handle, call_info); - CCAPI_Call_releaseCallInfo(call_info); -} - -void ccsnap_update_ccm_status(cc_string_t addr, cc_ccm_status_t status) -{ - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"entry ccm %s status=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_update_ccm_status"), addr, status); - - for (i=0;i< CCAPI_MAX_SERVERS;i++) { - if ( g_deviceInfo.ucm[i].status == status ) { - //move the status to the new addr - g_deviceInfo.ucm[i].status = CC_CCM_STATUS_NONE; - } - if ( !strcmp(addr, g_deviceInfo.ucm[i].name) ) { - g_deviceInfo.ucm[i].status = status; - CCAPP_DEBUG(DEB_F_PREFIX"server %s is now status=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_update_ccm_status"), - g_deviceInfo.ucm[i].name, status); - } - } -} - -void ccsnap_handle_mnc_reached (cc_line_info_t *line_info, cc_boolean mnc_reached, cc_cucm_mode_t mode) -{ - cc_call_handle_t handles[MAX_CALLS]; - int count = MAX_CALLS, i; - session_data_t *cinfo; - - if (mnc_reached) { - line_info->allowed_features[CCAPI_CALL_CAP_NEWCALL] = FALSE; - line_info->allowed_features[CCAPI_CALL_CAP_REDIAL] = FALSE; - line_info->allowed_features[CCAPI_CALL_CAP_CALLFWD] = FALSE; - } else { - capset_get_idleset(mode, line_info->allowed_features); - } - - // update connected calls caps on this line - CCAPI_LineInfo_getCallsByState(line_info->line_id, CONNECTED, handles, &count); - for ( i=0; iattr == (cc_call_attr_t) CONF_CONSULT || - cinfo->attr == (cc_call_attr_t) XFR_CONSULT ) { - CCAPI_Call_releaseCallInfo(cinfo); - continue; - } - cinfo->allowed_features[CCAPI_CALL_CAP_TRANSFER] = mnc_reached?FALSE:TRUE; - cinfo->allowed_features[CCAPI_CALL_CAP_CONFERENCE] = mnc_reached?FALSE:TRUE; - //print call info - if (g_CCAppDebug) { - printCallInfo(cinfo, "ccsnap_handle_mnc_reached"); - } - CCAPI_CallListener_onCallEvent(CCAPI_CALL_EV_CAPABILITY, handles[i], cinfo); - } - } - // update RIU call caps on this line - CCAPI_LineInfo_getCallsByState(line_info->line_id, REMINUSE, handles, &count); - for ( i=0; iallowed_features[CCAPI_CALL_CAP_BARGE] = mnc_reached?FALSE:TRUE; - //print call info - if (g_CCAppDebug) { - printCallInfo(cinfo, "ccsnap_handle_mnc_reached"); - } - CCAPI_CallListener_onCallEvent(CCAPI_CALL_EV_CAPABILITY, handles[i], cinfo); - } - } -} - -void ccsnap_gen_blfFeatureEvent(cc_blf_state_t state, int appId) -{ - cc_feature_info_t *feature_info = NULL; - - feature_info = ccsnap_getFeatureInfo(appId); - - // if the feature exists - if (feature_info != NULL) { - feature_info->blf_state = state; - printFeatureInfo(CCAPI_DEVICE_EV_BLF, feature_info, "ccsnap_gen_blfFeatureEvent"); - CCAPI_DeviceListener_onFeatureEvent(CCAPI_DEVICE_EV_BLF, CC_DEVICE_ID, feature_info); - } -} - -/** - * Inserts localized strings into existing strings with escape characters. - * @param destination the return phrase holder - * @param source the phrase with escape characters. - * @param len the input length to cap the maximum value - * @return pointer to the new string - */ -cc_string_t ccsnap_EscapeStrToLocaleStr(cc_string_t destination, cc_string_t source, int len) -{ - static const char *fname="ccsnap_EscapeStrToLocaleStr"; - char phrase_collector[MAX_LOCALE_STRING_LEN] = { '\0' }; - char* phrase_collector_ptr = phrase_collector; - char* esc_string_itr = (char*)source; - int remaining_length = 0; - cc_string_t ret_str = strlib_empty(); - - if(destination == NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"Error: destination is NULL\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return NULL; - } - - if(source == NULL){ - CCAPP_DEBUG(DEB_F_PREFIX"Error: source is NULL\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - strlib_free(destination); - return strlib_empty(); - } - - if(source[0] == '\0'){ - strlib_free(destination); - return strlib_empty(); - } - - if (len == LEN_UNKNOWN) { - len = strlen(source) + MAX_LOCALE_PHRASE_LEN; - } - - if (len <= 0){ - CCAPP_DEBUG(DEB_F_PREFIX"Error: cannot write string of length <= 0\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - strlib_free(destination); - return strlib_empty(); - } - - if (len > MAX_LOCALE_STRING_LEN){ - len = MAX_LOCALE_STRING_LEN; - } - - remaining_length = len; - while( *esc_string_itr != NUL && - remaining_length > 0 && - strlen(phrase_collector_ptr) < (size_t)(len-1)) - { - int rtn = CC_SUCCESS; - int phrase_index = 0; - char* phrase_bucket_ptr = (char*)cpr_malloc(remaining_length * sizeof(char)); - - if (phrase_bucket_ptr == NULL) { - CCAPP_ERROR(DEB_F_PREFIX"Error: phrase_bucket_ptr is NULL\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - strlib_free(destination); - return NULL; - } - phrase_bucket_ptr[0] = '\0'; - switch(*esc_string_itr){ - case OLD_CUCM_DICTIONARY_ESCAPE_TAG: - phrase_index += CALL_CONTROL_PHRASE_OFFSET; - // Do not set break to combine common code - case NEW_CUCM_DICTIONARY_ESCAPE_TAG: - esc_string_itr++; - phrase_index += (int)(*esc_string_itr); - rtn = platGetPhraseText(phrase_index, phrase_bucket_ptr, remaining_length-1); - if(rtn == CC_FAILURE) break; - sstrncat(phrase_collector_ptr, (cc_string_t)phrase_bucket_ptr, remaining_length); - remaining_length--; - break; - default: - // We need length 2 to concat 1 char and a terminating char - sstrncat(phrase_collector_ptr, esc_string_itr, 1 + sizeof(char)); - remaining_length--; - break; - } - esc_string_itr++; - cpr_free(phrase_bucket_ptr); - } - - ret_str = strlib_malloc(phrase_collector_ptr, len); - - if (!ret_str) { - /* - * If a malloc error occurred, give them back what they had. - * It's not right, but it's better than nothing. - */ - ret_str = destination; - } else { - strlib_free(destination); - } - - CCAPP_DEBUG(DEB_F_PREFIX"Localization String returning %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ret_str); - return (ret_str); -} - -static boolean missed, placed, received; -void ccsnap_set_phone_services_provisioning(boolean misd, boolean plcd, boolean rcvd) { - CCAPP_ERROR(DEB_F_PREFIX"missed=%d placed=%d received=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_set_phone_services_provisioning"), misd, plcd, rcvd); - missed = misd; - placed = plcd; - received = rcvd; -} - -boolean ccsnap_isMissedCallLoggingEnabled() -{ - return missed; -} - -boolean ccsnap_isReceivedCallLoggingEnabled() -{ - return received; -} - -boolean ccsnap_isPlacedCallLoggingEnabled() -{ - return placed; -} - -/** - * Helper method - */ - -static void printCallInfo(cc_callinfo_ref_t info, const char* fname) { - CCAPP_DEBUG(DEB_F_PREFIX"data->ref_count=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ref_count); - CCAPP_DEBUG(DEB_F_PREFIX"data->sess_id=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->sess_id); - CCAPP_DEBUG(DEB_F_PREFIX"data->line=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->line); - CCAPP_DEBUG(DEB_F_PREFIX"data->id=%u \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->id); - CCAPP_DEBUG(DEB_F_PREFIX"data->inst=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->inst); - CCAPP_DEBUG(DEB_F_PREFIX"data->state=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->state); - CCAPP_DEBUG(DEB_F_PREFIX"data->attr=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->attr); - CCAPP_DEBUG(DEB_F_PREFIX"data->type=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->type); - CCAPP_DEBUG(DEB_F_PREFIX"data->security=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->security); - CCAPP_DEBUG(DEB_F_PREFIX"data->policy=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->policy); - CCAPP_DEBUG(DEB_F_PREFIX"data->isSelected=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->isSelected); - CCAPP_DEBUG(DEB_F_PREFIX"data->log_disp=%u \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->log_disp); - CCAPP_DEBUG(DEB_F_PREFIX"data->clg_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->clg_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->clg_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->clg_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->alt_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->alt_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->cld_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cld_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->cld_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cld_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->orig_called_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->orig_called_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->orig_called_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->orig_called_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->last_redir_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->last_redir_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->last_redir_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->last_redir_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->plcd_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->plcd_name); - CCAPP_DEBUG(DEB_F_PREFIX"data->plcd_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->plcd_number); - CCAPP_DEBUG(DEB_F_PREFIX"data->status=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->status); - CCAPP_DEBUG(DEB_F_PREFIX"data->gci=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->gci); - CCAPP_DEBUG(DEB_F_PREFIX"data->cause=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cause); - CCAPP_DEBUG(DEB_F_PREFIX"data->vid_dir=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->vid_dir); - CCAPP_DEBUG(DEB_F_PREFIX"data->vid_offer=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->vid_offer); - CCAPP_DEBUG(DEB_F_PREFIX"data->is_conf=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->is_conf); - CCAPP_DEBUG(DEB_F_PREFIX"data->ringer_start=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ringer_start); - CCAPP_DEBUG(DEB_F_PREFIX"data->ringer_mode=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ringer_mode); - CCAPP_DEBUG(DEB_F_PREFIX"data->ringer_once=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ringer_once); -} - -static void printFeatureInfo (ccapi_device_event_e type, cc_featureinfo_ref_t feature_info, const char* fname) { - CCAPP_DEBUG(DEB_F_PREFIX"data->button=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->button); - CCAPP_DEBUG(DEB_F_PREFIX"data->contact=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->contact); - CCAPP_DEBUG(DEB_F_PREFIX"data->featureOptionMask=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->featureOptionMask); - CCAPP_DEBUG(DEB_F_PREFIX"data->feature_id=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->feature_id); - CCAPP_DEBUG(DEB_F_PREFIX"data->name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->name); - CCAPP_DEBUG(DEB_F_PREFIX"data->retrievalPrefix=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->retrievalPrefix); - CCAPP_DEBUG(DEB_F_PREFIX"data->speedDialNumber=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->speedDialNumber); - if (type == CCAPI_DEVICE_EV_BLF) { - CCAPP_DEBUG(DEB_F_PREFIX"data->blf_state=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->blf_state); - } - -} diff --git a/libs/sipcc/core/ccapp/ccapi_snapshot.h b/libs/sipcc/core/ccapp/ccapi_snapshot.h deleted file mode 100644 index 087513fea0..0000000000 --- a/libs/sipcc/core/ccapp/ccapi_snapshot.h +++ /dev/null @@ -1,114 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCAPI_SNAPSHOT_H_ -#define _CCAPI_SNAPSHOT_H_ - -#include "ccsip_platform.h" -#include "prot_configmgr.h" -#include "ccapi_line.h" - -/* - * MWI info - */ -typedef struct cc_mwi_info_t_ { - cc_uint32_t status; - cc_uint32_t type; - cc_uint32_t new_count; - cc_uint32_t old_count; - cc_uint32_t pri_new_count; - cc_uint32_t pri_old_count; -} cc_mwi_info_t; - -/* - * line reference data structure - */ -typedef struct cc_line_info_t_ { - cc_uint32_t ref_count; - cc_uint32_t line_id; - cc_uint32_t line_type; - cc_int32_t button; - cc_boolean reg_state; - cc_boolean isCFWD; - cc_boolean isLocalCFWD; - cc_mwi_info_t mwi; - cc_string_t name; - cc_string_t dn; - cc_string_t cfwd_dest; - cc_boolean allowed_features[CCAPI_CALL_CAP_MAX]; - cc_string_t externalNumber; - cc_boolean fwd_caller_name_display; - cc_boolean fwd_caller_number_display; - cc_boolean fwd_redirected_number_display; - cc_boolean fwd_dialed_number_display; -} cc_line_info_t; - -typedef struct cc_feature_info_t_ { - cc_int32_t feature_id; - cc_int32_t button; - cc_string_t speedDialNumber; - cc_string_t contact; - cc_string_t name; - cc_string_t retrievalPrefix; - cc_uint32_t featureOptionMask; - cc_blf_state_t blf_state; -} cc_feature_info_t; - -typedef struct cc_call_server_t_ { - cc_string_t name; - cc_ccm_status_t status; - cc_int32_t type; -} cc_call_server_t; - -typedef struct cc_device_info_t_ { - cc_uint32_t ref_count; - cc_string_t name; - cc_string_t not_prompt; - char registration_ip_addr[MAX_IPADDR_STR_LEN]; - cc_int32_t not_prompt_prio; - cc_boolean not_prompt_prog; - cc_boolean mwi_lamp; - cc_cucm_mode_t cucm_mode; - cc_service_state_t ins_state; - cc_service_cause_t ins_cause; - long long reg_time; - cc_call_server_t ucm[CCAPI_MAX_SERVERS]; -} cc_device_info_t; - -typedef enum { - ACCSRY_CFGD_CFG, //accessory last configured by configuration file. - ACCSRY_CFGD_APK, //accessory last configured by another application. -} accsry_cfgd_by_t; - -typedef struct accessory_cfg_info_t_ { - accsry_cfgd_by_t camera; - accsry_cfgd_by_t video; -} accessory_cfg_info_t; - -extern accessory_cfg_info_t g_accessoryCfgInfo; -extern cc_device_info_t g_deviceInfo; -extern cc_line_info_t lineInfo[MAX_CONFIG_LINES+1]; - -cc_line_info_t* ccsnap_getLineInfo(int lineID); -cc_line_info_t* ccsnap_getLineInfoFromBtn(int btnID); -void ccsnap_line_init(); -void ccsnap_device_init(); -void ccsnap_gen_deviceEvent(ccapi_device_event_e event, cc_device_handle_t handle); -void ccsnap_gen_lineEvent(ccapi_line_event_e event, cc_lineid_t handle); -void ccsnap_gen_callEvent(ccapi_call_event_e event, cc_call_handle_t handle); -void ccsnap_update_ccm_status(cc_string_t addr, cc_ccm_status_t status); -void ccsnap_handle_mnc_reached (cc_line_info_t *line_info, - cc_boolean mnc_reached, cc_cucm_mode_t mode); -cc_feature_info_t* ccsnap_getFeatureInfo(int featureIndex); -void ccsnap_gen_blfFeatureEvent(cc_blf_state_t state, int appId); -cc_string_t ccsnap_EscapeStrToLocaleStr(cc_string_t destination, cc_string_t source, int len); -void ccsnap_set_phone_services_provisioning(boolean misd, boolean plcd, boolean rcvd); -boolean ccsnap_isMissedCallLoggingEnabled(); -boolean ccsnap_isReceivedCallLoggingEnabled(); -boolean ccsnap_isPlacedCallLoggingEnabled(); -void ccsnap_set_line_label(int btn, cc_string_t label); -cc_string_t ccsnap_get_line_label(int btn); - -#endif - diff --git a/libs/sipcc/core/ccapp/ccapp_task.c b/libs/sipcc/core/ccapp/ccapp_task.c deleted file mode 100644 index 0b6ff6639c..0000000000 --- a/libs/sipcc/core/ccapp/ccapp_task.c +++ /dev/null @@ -1,177 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccapp_task.h" -#include "phone.h" -#include "CCProvider.h" -#include "platform_api.h" - -extern cprMsgQueue_t ccapp_msgq; -extern void CCAppInit(); -static sll_lite_list_t sll_list; - -/** - * Add/Get ccapp task listener - */ -void addCcappListener(appListener* listener, int type) { - - listener_t *alistener = NULL; - - CCAPP_DEBUG(DEB_F_PREFIX"Entered: listenr=0x%x, type=%d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener"), - listener, type); - - if (listener == NULL) - { - CCAPP_ERROR(DEB_F_PREFIX"listener is NULL, returning\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener")); - return; - } - - alistener = cpr_malloc(sizeof(listener_t)); - if (alistener == NULL) { - CCAPP_ERROR(DEB_F_PREFIX"alistener is NULL, returning\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener")); - return; - } - - alistener->type = type; - alistener->listener_p = listener; - - sll_lite_link_tail(&sll_list, (sll_lite_node_t *)alistener); - CCAPP_DEBUG(DEB_F_PREFIX"Added: listenr=0x%x, type=%d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener"), - alistener->listener_p, alistener->type); -} - -appListener *getCcappListener(int type) { - static const char fname[] ="getCcappListener"; - listener_t *temp_info; - sll_lite_node_t *iterator; - - CCAPP_DEBUG(DEB_F_PREFIX"entered: for app[%d]\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - type); - - iterator = sll_list.head_p; - while (iterator) { - temp_info = (listener_t *)iterator; - CCAPP_DEBUG(DEB_F_PREFIX"appid=%d, listener=0x%x\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), temp_info->type, temp_info->listener_p); - if (temp_info->type == type) { - { - return temp_info->listener_p; - } - } - iterator = iterator->next_p; - } - return NULL; -} - -/** - * - * CC Provider wrapper for posting msg to CCAPP - * - * @param msgId - message ID - * @param data - ptr to data - * @param len - len of data - * - * @return CPR_SUCCESS/CPR_FAILURE - * - * @pre None - */ - -cpr_status_e ccappTaskPostMsg(unsigned int msgId, void * data, uint16_t len, int appId) -{ - cprBuffer_t *msg; - static const char fname[] = "ccappPostMsg"; - cpr_status_e retval = CPR_SUCCESS; - - msg = (cprBuffer_t *) cpr_malloc(len); - if (msg == NULL) { - CCAPP_ERROR(DEB_F_PREFIX"failed to allocate message.\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - return CPR_FAILURE; - } - - memcpy(msg, data, len); - - if ((retval=ccappTaskSendMsg(msgId, msg, len, appId)) == CPR_FAILURE) { - cpr_free(msg); - } - - return retval; -} - -/** - * - * CC Provider wrapper for cprSendMessage - * - * @param cmd - Command - * @param msg - msg ptr - * @param len - len of msg - * @param usr - - * - * @return CPR_SUCCESS/CPR_FAILURE - * - * @pre msg is a malloc mem ptr - */ -cpr_status_e -ccappTaskSendMsg (uint32_t cmd, void *msg, uint16_t len, uint32_t UsrInfo) -{ - phn_syshdr_t *syshdr; - - syshdr = (phn_syshdr_t *) cprGetSysHeader(msg); - if (!syshdr) { - return CPR_FAILURE; - } - syshdr->Cmd = cmd; - syshdr->Len = len; - syshdr->Usr.UsrInfo = UsrInfo; - - if (cprSendMessage(ccapp_msgq , (cprBuffer_t*)msg, (void **)&syshdr) == CPR_FAILURE) { - cprReleaseSysHeader(syshdr); - return CPR_FAILURE; - } - return CPR_SUCCESS; -} - -/** - * - * CCApp Provider main routine. - * - * @param arg - CCApp msg queue - * - * @return void - * - * @pre None - */ -void CCApp_task(void * arg) -{ - static const char fname[] = "CCApp_task"; - phn_syshdr_t *syshdr = NULL; - appListener *listener = NULL; - void * msg; - - //initialize the listener list - sll_lite_init(&sll_list); - - CCAppInit(); - - while (1) { - msg = cprGetMessage(ccapp_msgq, TRUE, (void **) &syshdr); - if ( msg) { - CCAPP_DEBUG(DEB_F_PREFIX"Received Cmd[%d] for app[%d]\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - syshdr->Cmd, syshdr->Usr.UsrInfo); - - listener = getCcappListener(syshdr->Usr.UsrInfo); - if (listener != NULL) { - (* ((listener)))(msg, syshdr->Cmd); - } else { - CCAPP_DEBUG(DEB_F_PREFIX"Event[%d] doesn't have a dedicated listener.\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - syshdr->Usr.UsrInfo); - } - cprReleaseSysHeader(syshdr); - cpr_free(msg); - } - } -} - - - diff --git a/libs/sipcc/core/ccapp/ccapp_task.h b/libs/sipcc/core/ccapp/ccapp_task.h deleted file mode 100644 index e2792a3b0d..0000000000 --- a/libs/sipcc/core/ccapp/ccapp_task.h +++ /dev/null @@ -1,20 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "sll_lite.h" - -//Define app id for ccapp task -#define CCAPP_CCPROVIER 1 -#define CCAPP_MSPROVIDER 2 - -typedef void(* appListener) (void *message, int type); -typedef struct { - sll_lite_node_t node; - int type; - appListener *listener_p; -} listener_t; - -extern void addCcappListener(appListener* listener, int type); -appListener *getCcappListener(int type); -cpr_status_e ccappTaskSendMsg (uint32_t cmd, void *msg, uint16_t len, uint32_t usrInfo); diff --git a/libs/sipcc/core/ccapp/ccprovider.c b/libs/sipcc/core/ccapp/ccprovider.c deleted file mode 100755 index 2e5548bc38..0000000000 --- a/libs/sipcc/core/ccapp/ccprovider.c +++ /dev/null @@ -1,2241 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "CCProvider.h" -#include "ccSession.h" -#include "ccsip_task.h" -#include "cpr.h" -#include "cpr_stdlib.h" -#include "cpr_ipc.h" -#include "phone.h" -#include "phntask.h" -#include "ccapi.h" -#include "debug.h" -#include "phone_debug.h" -#include "dialplanint.h" -#include "configmgr.h" -#include "prot_configmgr.h" -#include "lsm.h" -#include "sip_common_regmgr.h" -#include "sessionHash.h" -#include "pres_sub_not_handler.h" -#include "cc_call_listener.h" -#include "cc_service_listener.h" -#include "cc_config.h" -#include "cc_device_listener.h" -#include "cc_service_listener.h" -#include "plat_api.h" -#include "cc_info_listener.h" -#include "cc_blf_listener.h" -#include "platform_api.h" -#include "ccapp_task.h" -#include "ccapi.h" -#include "capability_set.h" -#include "plat_debug.h" - -#include "config_api.h" -#include "ccapi_call_info.h" -#include "ccapi_call_listener.h" -#include "ccapi_snapshot.h" -#include "ccapi_device.h" -#include "ccapi_line_listener.h" -#include "ccapi_device_listener.h" -#include "cc_device_manager.h" -#include "call_logger.h" -#include "subscription_handler.h" -#include "ccapi_device_info.h" -#include "conf_roster.h" -#include "reset_api.h" -//#include "prlog.h" - -/*--------------------------------------------------------- - * - * Definitions - * - */ -#define NOTIFY_CALL_STATUS (data->state == OFFHOOK? "OFFHOOK" : \ - data->state == ONHOOK? "ONHOOK" : \ - data->state == RINGOUT? "RINGOUT" : \ - data->state == RINGIN? "RINGIN" : \ - data->state == PROCEED ? "PROCEED" : \ - data->state == CONNECTED ? "CONNECTED" : \ - data->state == HOLD ? "HOLD" : \ - data->state == REMHOLD ? "REMHOLD" : \ - data->state == RESUME ? "RESUME" : \ - data->state == BUSY ? "BUSY" : \ - data->state == REORDER ? "REORDER" : \ - data->state == CONFERENCE ? "CONFERENCE" : \ - data->state == DIALING ? "DIALING" : \ - data->state == REMINUSE ? "REMINUSE" : \ - data->state == HOLDREVERT ? "HOLDREVERT" :\ - data->state == WHISPER ? "WHISPER" : \ - data->state == PRESERVATION ? "PRESERVATION" : \ - data->state == WAITINGFORDIGITS ? "WAITINGFORDIGITS" : \ - "Unknown state") - -#define CCAPP_TASK_CMD_PRINT(arg) ((arg) == CCAPP_SERVICE_CMD ? "CCAPP_SERVICE_CMD" : \ - (arg) == CCAPP_CREATE_SESSION ? "CCAPP_CREATE_SESSION" : \ - (arg) == CCAPP_CLOSE_SESSION ? "CCAPP_CLOSE_SESSION" : \ - (arg) == CCAPP_INVOKE_FEATURE ? "CCAPP_INVOKE_FEATURE" : \ - (arg) == CCAPP_SESSION_UPDATE ? "CCAPP_SESSION_UPDATE" : \ - (arg) == CCAPP_FEATURE_UPDATE ? "CCAPP_FEATURE_UPDATE" : \ - (arg) == CCAPP_UPDATELINES ? "CCAPP_UPDATELINES" : \ - (arg) == CCAPP_FAILOVER_IND ? "CCAPP_FAILOVER_IND" : \ - (arg) == CCAPP_FALLBACK_IND ? "CCAPP_FALLBACK_IND" : \ - (arg) == CCAPP_MODE_NOTIFY ? "CCAPP_MODE_NOTIFY" : \ - (arg) == CCAPP_SHUTDOWN_ACK ? "CCAPP_SHUTDOWN_ACK" : \ - (arg) == CCAPP_REG_ALL_FAIL ? "CCAPP_REG_ALL_FAIL" : \ - (arg) == CCAPP_INVOKEPROVIDER_FEATURE ? "CCAPP_INVOKEPROVIDER_FEATURE" : \ - (arg) == CCAPP_SEND_INFO ? "CCAPP_SEND_INFO" : \ - (arg) == CCAPP_RCVD_INFO ? "CCAPP_RCVD_INFO" : \ - (arg) == CCAPP_LOGOUT_RESET ? "CCAPP_LOGOUT_RESET" : \ - (arg) == CCAPP_SESSION_MGMT ? "CCAPP_SESSION_MGMT" : \ - (arg) == CCAPP_THREAD_UNLOAD ? "CCAPP_THREAD_UNLOAD" : \ - (arg) == CCAPP_SESSION_MGMT ? "CCAPP_SESSION_MGMT" : \ - "Unknown Cmd") - -#define APP_ERR_MSG err_msg - -#define MAX_REASON_LENGTH MAX_SIP_REASON_LENGTH -#define MAX_SESSION_PARAM_LEN 128 - -/* UNKNOWN_PHRASE_STR should equal the value returned - * if the phrase code is not found in the dictionary. - * For CIUS, this is found in LocalizedStrings.java */ -#define UNKNOWN_PHRASE_STR "???" -#define UNKNOWN_PHRASE_STR_SIZE 3 - -/*--------------------------------------------------------- - * - * Local Variables - * - */ - -/*--------------------------------------------------------- - * - * Global Variables - * - */ -static CCAppGlobal_t gCCApp; -cc_int32_t g_CCAppDebug=TRUE; -cc_int32_t g_CCLogDebug=TRUE; -cc_int32_t g_NotifyCallDebug=TRUE; -cc_int32_t g_NotifyLineDebug=TRUE; - -cc_srv_ctrl_req_t reset_type; - -extern cprMsgQueue_t ccapp_msgq; -extern cprThread_t ccapp_thread; -extern boolean platform_initialized; -extern void resetReady(); -extern void resetNotReady(); -extern int sendResetUpdates; - -extern boolean apply_config; - -extern char g_new_signaling_ip[]; - -extern int configFileDownloadNeeded; -cc_action_t pending_action_type = NO_ACTION; - - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ -extern void send_protocol_config_msg(void); -extern void gsm_shutdown(void); -extern void sip_shutdown(void); -extern void dp_shutdown(void); -extern void MiscAppTaskShutdown(void); -extern void lsm_init(void); -extern void fsm_init(void); -extern void fim_init(void); -extern void SIPTaskPostRestart(boolean restart); -extern void ccsip_register_cancel(boolean cancel_reg, boolean backup_proxy); -extern void notify_register_update(int last_available_line); -extern void getLineIdAndCallId (line_t *line_id, callid_t *call_id); -extern void set_default_video_pref(int pref); -extern void set_next_sess_video_pref(int pref); -extern void cc_media_update_native_video_support(boolean val); -extern void cc_media_update_video_cap(boolean val); -extern void cc_media_update_video_txcap(boolean val); - -session_data_t * getDeepCopyOfSessionData(session_data_t *data); -static void ccappUpdateSessionData(session_update_t *sessUpd); -static void ccappFeatureUpdated (feature_update_t *featUpd); -void destroy_ccapp_thread(); -void ccpro_handleserviceControlNotify(); - -/*--------------------------------------------------------- - * - * Function declarations - * - */ - -cc_service_state_t mapProviderState(cc_reg_state_t state) -{ - switch(state) { - case CC_INSERVICE: - return CC_STATE_INS; - case CC_CREATED_IDLE: - return CC_STATE_IDLE; - case CC_OOS_REGISTERING: - case CC_OOS_FAILOVER: - case CC_OOS_IDLE: - default: - return CC_STATE_OOS; - - } -} - -static void ccapp_hlapi_update_device_reg_state() { - g_deviceInfo.ins_state = mapProviderState(gCCApp.state); - g_deviceInfo.ins_cause = gCCApp.cause; - g_deviceInfo.cucm_mode = gCCApp.mode; - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_STATE, CC_DEVICE_ID); -} - -void ccpro_handleINS() { - registration_processEvent(EV_CC_INSERVICE); -} - -void ccpro_handleOOS() { - switch(gCCApp.cause){ - case CC_CAUSE_REG_ALL_FAILED: - registration_processEvent(EV_CC_OOS_REG_ALL_FAILED); - break; - case CC_CAUSE_FAILOVER: - registration_processEvent(EV_CC_OOS_FAILOVER); - break; - case CC_CAUSE_FALLBACK: - registration_processEvent(EV_CC_OOS_FALLBACK); - break; - case CC_CAUSE_SHUTDOWN: - registration_processEvent(EV_CC_OOS_SHUTDOWN_ACK); - break; - } -} - -cc_boolean is_action_to_be_deferred(cc_action_t action) { - if (CCAPI_DeviceInfo_isPhoneIdle(CC_DEVICE_ID) == FALSE) { - pending_action_type = action; - DEF_DEBUG("Action deferred=%d", action); - return TRUE; - } else { - return FALSE; - } -} - -void perform_deferred_action() { - cc_action_t temp_action = pending_action_type; - - if (is_action_to_be_deferred(pending_action_type) == TRUE) { - return; - } - - pending_action_type = NO_ACTION; - DEF_DEBUG("Perform deferred action=%d", temp_action); - - if (temp_action == RESET_ACTION || temp_action == RESTART_ACTION) { - ccpro_handleserviceControlNotify(); - } else if (temp_action == RE_REGISTER_ACTION) { - CCAPI_Service_reregister(g_dev_hdl, g_dev_name, g_cfg_p, g_compl_cfg); - } else if (temp_action == STOP_ACTION) { - CCAPI_Service_stop(); - } else if (temp_action == DESTROY_ACTION) { - CCAPI_Service_destroy(); - } -} - -void ccpro_handleserviceControlNotify() { - cc_action_t temp_action = NO_ACTION; - if (reset_type == CC_DEVICE_RESET) { - temp_action = RESET_ACTION; - } else if (reset_type == CC_DEVICE_RESTART) { - temp_action = RESTART_ACTION; - } - - if ((reset_type != CC_DEVICE_ICMP_UNREACHABLE) && - is_action_to_be_deferred(temp_action) == TRUE) { - return; - } - - - if (reset_type == CC_DEVICE_RESET) { - resetRequest(); - } else if (reset_type == CC_DEVICE_RESTART) { - registration_processEvent(EV_CC_DO_SOFT_RESET); - } -} - -/** - * Returns the registration state - */ -cc_reg_state_t ccapp_get_state() { - return gCCApp.state; -} - -void ccp_handler(void* msg, int type); - -/** - * - * CCApp Provider init routine. - * - * @param none - * - * @return void - * - * @pre None - */ -void CCAppInit() -{ - ccProvider_state_t srvcState; - appListener handler = ccp_handler; - - gCCApp.state = CC_CREATED_IDLE; - gCCApp.cause = CC_CAUSE_NONE; - gCCApp.mode = CC_MODE_INVALID; - gCCApp.cucm_mode = NONE_AVAIL; - if (platThreadInit("CCApp_Task") != 0) { - return; - } - - /* - * Adjust relative priority of CCApp thread. - */ - (void) cprAdjustRelativeThreadPriority(CCPROVIDER_THREAD_RELATIVE_PRIORITY); - - debug_bind_keyword("cclog", &g_CCLogDebug); - srvcState.cause = gCCApp.cause; // XXX set but not used - srvcState.mode = gCCApp.mode; // XXX set but not used - (void) srvcState; - - //Add listeners - //CCProvider lister - DEF_DEBUG(DEB_F_PREFIX"Add ccp listener: type%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAppInit"), - CCAPP_CCPROVIER); - - addCcappListener(&handler, CCAPP_CCPROVIER); - -} - -/* - * Function: processProviderEvent - * - * Description: inform session events to CCApp - * - * Parameters: - * call_id - call identifier - * line_id - line identifier - * - * Returns: none - */ -void -processProviderEvent (line_t line_id, unsigned int event, int data) -{ - static const char fname[] = "processProviderEvent"; - callid_t call_id = 0; - - DEF_DEBUG(DEB_F_PREFIX"line=%d event=%d data=%d", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - line_id, event, data); - switch(event) { - case DEVICE_FEATURE_CFWD: - getLineIdAndCallId(&line_id, &call_id); - if (lsm_is_line_available(line_id, FALSE) == FALSE) { - //Send onhook to indicate session closure. - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATE, CREATE_CALL_HANDLE(line_id, call_id)); - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - break; - } - - cc_feature(CC_SRC_UI, call_id, line_id, CC_FEATURE_CFWD_ALL, NULL); - - break; - case DEVICE_SUPPORTS_NATIVE_VIDEO: - cc_media_update_native_video_support(data); - break; - case DEVICE_ENABLE_VIDEO: - cc_media_update_video_cap(data); - break; - case DEVICE_ENABLE_CAMERA: - cc_media_update_native_video_txcap(data); - break; - } -} - - -/* - * Function: CheckAndGetAvailableLine - * - * Parameters: - * line - line identifier - * call - call identifier - * - * Returns: TRUE if a line is available. - */ -static boolean CheckAndGetAvailableLine(line_t *line, callid_t *call) -{ - /* - * case 1: line>0 & call>0: invoking this in an offhook session. - * case 2: line>0 & call=0: invoking this onhook with simple filter active - * case 3: line=0 & call=0: invoking this in onhook with all calls filter active - */ - if ((*line > 0) && (*call == 0)) { - if (lsm_is_line_available(*line, FALSE) == FALSE) { - // since the session is not created yet, no need to close the session. - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return FALSE; - } - } - else if ((*line == 0) && (*call == 0)) { - *line = lsm_get_available_line(FALSE); - if (*line == 0 ) { - // since the session is not created yet, no need to close the session. - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return FALSE; - } - } - *call = (*call == 0) ? cc_get_new_call_id() : *call; - return TRUE; -} - -/* - * Function: getVideoPref - * - * Description: get video direction if specified - * - * Parameters: - * data - urn param - * - * Returns: sdp_direction_e - requested video direction - */ -sdp_direction_e getVideoPref( string_t data) -{ - if ( data == NULL ) { - return SDP_MAX_QOS_DIRECTIONS; - } - - if ( strstr(data, "video=sendrecv")) { - return SDP_DIRECTION_SENDRECV; - } else if (strstr(data, "video=sendonly")) { - return SDP_DIRECTION_SENDONLY; - } else if (strstr(data, "video=recvonly")){ - return SDP_DIRECTION_RECVONLY; - } else if (strstr(data, "video=none")){ - return SDP_DIRECTION_INACTIVE; - } else { - return SDP_MAX_QOS_DIRECTIONS; - } -} - -/* - * Function: updateSessionVideoPref - * - * Description: update video direction for the session only - * - * Parameters: - * line_id - line at which the session needs the video pref updated - * call_id - callid for which the session needs the video pref updated - * dir - video pref - * - * Returns: - */ -static void updateSessionVideoPref( line_t line_id, callid_t call_id, sdp_direction_e video_pref) -{ - static const char fname[] = "updateSessionVideoPref"; - cc_feature_data_t featdata; - - DEF_DEBUG(DEB_L_C_F_PREFIX"updating to %d video capapbility %s", - DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, call_id, line_id, fname), video_pref, - (video_pref == SDP_DIRECTION_INACTIVE ? "disabled" : "enabled")); - featdata.caps.support_direction = video_pref; - cc_feature(CC_SRC_UI, call_id, line_id, CC_FEATURE_UPD_SESSION_MEDIA_CAP, &featdata); -} - -/* - * Function: updateVideoPref - * - * Description: update video direction if specified - * - * Parameters: - * line_id - line at which the session needs the video pref updated - * call_id - callid for which the session needs the video pref updated - * data - urn param - * - * Returns: - */ - -static void updateVideoPref( unsigned int event, line_t line_id, callid_t call_id, sdp_direction_e video_pref/*string_t data*/) -{ - static const char fname[] = "updateVideoPref"; - - if ( video_pref == SDP_MAX_QOS_DIRECTIONS ) { - // we are done no updates needed - return; - } - - switch (event) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - if ( call_id == CC_NO_CALL_ID ) { - // This is the only means to update the default behavior - set_default_video_pref(video_pref); - } else { - updateSessionVideoPref(line_id, call_id, video_pref); - } - break; - case CC_FEATURE_DIALSTR: - case CC_FEATURE_DIAL: - case CC_FEATURE_SPEEDDIAL: - case CC_FEATURE_REDIAL: - if ( call_id == CC_NO_CALL_ID ) { - set_next_sess_video_pref(video_pref); - } else { - updateSessionVideoPref(line_id, call_id, video_pref); - } - break; - case CC_FEATURE_NEW_CALL: - case CC_FEATURE_OFFHOOK: - case CC_FEATURE_CONF: - case CC_FEATURE_B2BCONF: - case CC_FEATURE_XFER: - set_next_sess_video_pref(video_pref); - break; - case CC_FEATURE_RESUME: - case CC_FEATURE_ANSWER: - updateSessionVideoPref(line_id, call_id, video_pref); - break; - default: - CCAPP_DEBUG(DEB_L_C_F_PREFIX"event=%d. update to %d not supported", - DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, call_id, line_id, fname), event, video_pref); - - } -} - -/* - * Function: getDigits - * - * Description: returns the first param before the ; - * - * Parameters: - * data - urn param - * digits - memory to return the first param - * Returns: - */ -void getDigits(string_t data, char *digits) { - char *endptr; - int len=0; - - digits[0]=0; - - if ( data !=NULL ) { - endptr = strchr(data,';'); - if ( endptr ) { - len = endptr - data; - } else { - len = strlen(data); - } - - if ( len) { - memcpy(digits, data, len); - digits[len] = 0; - } - } -} - -/* - * Function: processSessionEvent - * - * Description: inform session events to CCApp - * - * Parameters: - * call_id - call identifier - * line_id - line identifier - * - * Returns: none - */ -void -processSessionEvent (line_t line_id, callid_t call_id, unsigned int event, sdp_direction_e video_pref, ccSession_feature_t ccData) -{ - static const char fname[] = "processSessionEvent"; - cc_feature_data_t featdata; - int instance = line_id; - boolean incoming = FALSE; - session_data_t * sess_data_p; - char digits[CC_MAX_DIALSTRING_LEN]; - char* data = (char*)ccData.info; - char* data1 =(char*)ccData.info1; - long strtol_result; - char *strtol_end; - - CCAPP_DEBUG(DEB_L_C_F_PREFIX"event=%d data=%s", - DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, call_id, line_id, fname), event, - ((event == CC_FEATURE_KEYPRESS) ? "..." : data)); - - memset(&featdata, 0, sizeof(cc_feature_data_t)); - updateVideoPref(event, line_id, call_id, video_pref); - switch(event) { - case CC_FEATURE_ONHOOK: - getLineIdAndCallId(&line_id, &call_id); - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_ONHOOK = %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data); - cc_onhook_ext(CC_SRC_UI, call_id, line_id, FALSE, - (data && (strncasecmp(data, "ACTIVECALLS", sizeof("ACTIVECALLS")) == 0))? - CC_REASON_ACTIVECALL_LIST: CC_REASON_NULL ); - break; - case CC_FEATURE_KEYPRESS: - dp_int_update_keypress(line_id, call_id, (unsigned char)*data); - break; - case CC_FEATURE_BKSPACE: - dp_int_update_keypress(line_id, call_id, BKSP_KEY); - break; - case CC_FEATURE_CREATEOFFER: - featdata.session.sessionid = ccData.sessionid; - featdata.session.has_constraints = ccData.has_constraints; - cc_createoffer (CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_CREATEOFFER, &featdata); - break; - case CC_FEATURE_CREATEANSWER: - featdata.session.sessionid = ccData.sessionid; - featdata.session.has_constraints = ccData.has_constraints; - cc_createanswer (CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_CREATEANSWER, data, &featdata); - break; - case CC_FEATURE_SETLOCALDESC: - cc_setlocaldesc (CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_SETLOCALDESC, ccData.action, data, &featdata); - break; - case CC_FEATURE_SETREMOTEDESC: - cc_setremotedesc (CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_SETREMOTEDESC, ccData.action, data, &featdata); - break; - case CC_FEATURE_SETPEERCONNECTION: - PR_ASSERT(strlen(data) < PC_HANDLE_SIZE); - if (strlen(data) >= PC_HANDLE_SIZE) - return; - - sstrncpy(featdata.pc.pc_handle, data, sizeof(featdata.pc.pc_handle)); - - cc_int_feature2(CC_MSG_SETPEERCONNECTION, CC_SRC_UI, CC_SRC_GSM, - call_id, (line_t)instance, - CC_FEATURE_SETPEERCONNECTION, &featdata); - break; - case CC_FEATURE_ADDSTREAM: - featdata.track.stream_id = ccData.stream_id; - featdata.track.track_id = ccData.track_id; - featdata.track.media_type = ccData.media_type; - cc_int_feature2(CC_MSG_ADDSTREAM, CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_ADDSTREAM, &featdata); - break; - case CC_FEATURE_REMOVESTREAM: - featdata.track.stream_id = ccData.stream_id; - featdata.track.track_id = ccData.track_id; - featdata.track.media_type = ccData.media_type; - cc_int_feature2(CC_MSG_REMOVESTREAM, CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_REMOVESTREAM, &featdata); - break; - case CC_FEATURE_ADDICECANDIDATE: - featdata.candidate.level = ccData.level; - sstrncpy(featdata.candidate.candidate, data, sizeof(featdata.candidate.candidate)-1); - sstrncpy(featdata.candidate.mid, data1, sizeof(featdata.candidate.mid)-1); - cc_int_feature2(CC_MSG_ADDCANDIDATE, CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_ADDICECANDIDATE, &featdata); - break; - case CC_FEATURE_DIALSTR: - if (CheckAndGetAvailableLine(&line_id, &call_id) == TRUE) { - getDigits(data, digits); - if (strlen(digits) == 0) { - //if dial string is empty then go offhook - cc_offhook(CC_SRC_UI, call_id, line_id); - } else { - dp_int_init_dialing_data(line_id, call_id); - dp_int_dial_immediate(line_id, call_id, TRUE, - (char *)digits, NULL, CC_MONITOR_NONE); - } - } - break; - - case CC_FEATURE_DIAL: - dp_int_dial_immediate(line_id, call_id, FALSE, NULL, NULL, CC_MONITOR_NONE); - break; - case CC_FEATURE_SPEEDDIAL: - /* - * BLF Pickup Line Selection: - * ------------------------- - * - * case 1: line_id>0 & call_id>0 : BLF key press after going offhook on a given line. - * Check if the given line has available call capacity. If not, end the session - * and display STR_INDEX_NO_LINE_FOR_PICKUP toast. - * - * case 2: line_id>0 & call_id=0 : BLF key press w/o offhook when a simple filter is active. - * Check if the given line has available call capacity. If not, find the next available line. - * If no available line is found, display STR_INDEX_NO_LINE_FOR_PICKUP toast. - * - * case 3: line_id=0 & call_id=0 : BLF key press w/o offhook when a AllCalls filter is active. - * Find an available line. If no available line is found, - * display STR_INDEX_NO_LINE_FOR_PICKUP toast. - */ - if (strncmp(data, CISCO_BLFPICKUP_STRING, (sizeof(CISCO_BLFPICKUP_STRING) - 1)) == 0) { - if ((instance > 0) && (call_id > 0)) { - if (lsm_is_line_available(instance, incoming) == FALSE) { - session_update_t sessUpd; - sessUpd.eventID = CALL_STATE; - sessUpd.sessionID = createSessionId(line_id, call_id); - sessUpd.sessType = SESSIONTYPE_CALLCONTROL; - sessUpd.update.ccSessionUpd.data.state_data.state = evOnHook; - sessUpd.update.ccSessionUpd.data.state_data.line_id = line_id; - sessUpd.update.ccSessionUpd.data.state_data.cause = CC_CAUSE_NORMAL; - ccappUpdateSessionData(&sessUpd); - // Pass this update to Session Manager - lsm_ui_display_notify_str_index(STR_INDEX_NO_LINE_FOR_PICKUP); - break; - } - } - else if ((instance > 0) && (call_id == 0)) { - if (lsm_is_line_available(instance, incoming) == FALSE) { - line_id = lsm_get_available_line(incoming); - if (line_id == 0 ) { - // since the session is not created yet, no need to close the session. - lsm_ui_display_notify_str_index(STR_INDEX_NO_LINE_FOR_PICKUP); - break; - } - } - } - else if ((instance == 0) && (call_id == 0)) { - line_id = lsm_get_available_line(incoming); - if (line_id == 0 ) { - // since the session is not created yet, no need to close the session. - lsm_ui_display_notify_str_index(STR_INDEX_NO_LINE_FOR_PICKUP); - break; - } - } - call_id = (call_id == 0) ? cc_get_new_call_id() : call_id; - } - /* - * SpeedDial Line Selection: - * ------------------------ - * - * case 1: line_id>0 & call_id>0 : speeddial key press after going offhook on a given line. - * Simply use this line to make an outgoing call. - * - * case 2: line_id>0 & call_id=0 : SD key press w/o offhook when a simple filter is active. - * Check if the given line has available call capacity. If not, - * display STR_INDEX_ERROR_PASS_LIMIT toast. - * - * case 3: line_id=0 & call_id=0 : SD key press w/o offhook when a AllCalls filter is active. - * Find an available line. If no available line is found, - * display STR_INDEX_ERROR_PASS_LIMIT toast. - */ - else if (CheckAndGetAvailableLine(&line_id, &call_id) == FALSE) { - break; - } - - getDigits(data,digits); - - dp_int_init_dialing_data(line_id, call_id); - dp_int_dial_immediate(line_id, call_id, TRUE, - digits, NULL, CC_MONITOR_NONE); - break; - case CC_FEATURE_BLIND_XFER_WITH_DIALSTRING: - featdata.xfer.cause = CC_CAUSE_XFER_LOCAL_WITH_DIALSTRING; - sstrncpy(featdata.xfer.dialstring, (char *)data, CC_MAX_DIALSTRING_LEN); - cc_feature(CC_SRC_UI, call_id, (line_t)instance, CC_FEATURE_BLIND_XFER, - &featdata); - break; - case CC_FEATURE_REDIAL: - if (line_id == 0) { - /* - * If line_id is zero, get the last dialed line. - */ - line_id = dp_get_redial_line(); - if (line_id == 0) { - break; - } - } - - /* if not an existing call, check capacity on the line */ - if (call_id == CC_NO_CALL_ID) { - if (lsm_is_line_available(line_id, FALSE) == FALSE) { - /* - * since the session is not created yet, no - * need to close the session. - */ - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - break; - } else { - /* we have capacity and call does not exist */ - call_id = cc_get_new_call_id(); - } - } - dp_int_do_redial(line_id, call_id); - break; - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - /* handled in updateVideoPref() just outside of the switch */ - break; - - case CC_FEATURE_NEW_CALL: - case CC_FEATURE_OFFHOOK: - if (lsm_is_line_available(line_id, FALSE) == FALSE) { - //close the session - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_OFFHOOK: no available line.\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATE, CREATE_CALL_HANDLE(line_id, call_id)); - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - break; - } - - if (call_id == 0) { - call_id = cc_get_new_call_id(); - } else { - if (event == CC_FEATURE_NEW_CALL) { - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_NEW_CALL called with callid=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), call_id); - } else { - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_OFFHOOK called with callid=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), call_id); - } - } - cc_offhook(CC_SRC_UI, call_id, line_id); - break; - - case CC_FEATURE_CFWD_ALL: - getLineIdAndCallId(&line_id, &call_id); - - cc_feature(CC_SRC_UI, call_id, line_id, CC_FEATURE_CFWD_ALL, NULL); - - break; - - case CC_FEATURE_RESUME: - case CC_FEATURE_ANSWER: - - sess_data_p = (session_data_t *)findhash(createSessionId(line_id, call_id)); - if ( sess_data_p == NULL ) { - break; - } - if (sess_data_p->state == HOLD || sess_data_p->state == HOLDREVERT) { - cc_feature(CC_SRC_UI, call_id, line_id, CC_FEATURE_RESUME, NULL); - } else { - cc_feature(CC_SRC_UI, call_id, line_id, event, NULL); - } - break; - - case CC_FEATURE_END_CALL: - CCAPP_DEBUG(DEB_F_PREFIX"CC_FEATURE_ONHOOK = %s\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data); - if (data && (strcmp(data, "ACTIVECALLS") == 0)) { - getLineIdAndCallId(&line_id, &call_id); - cc_onhook_ext(CC_SRC_UI, call_id, line_id, TRUE, CC_REASON_ACTIVECALL_LIST); - } else { - cc_feature(CC_SRC_UI, call_id, line_id, event, NULL); - } - break; - - case CC_FEATURE_CONF: - // for CUCM mode we will translate CONF to B2BCONF - if ( gCCApp.mode == CC_MODE_CCM ) { - if ( gCCApp.mode == CC_MODE_CCM && platGetFeatureAllowed(CC_SIS_B2B_CONF) ) { - //CUCME can't support B2BCONF currently. - event = CC_FEATURE_B2BCONF; - } - }// DON'T ADD BREAK HERE. EVENT IS PASSED BELOW - case CC_FEATURE_B2BCONF: - case CC_FEATURE_XFER: - getDigits(data,digits); - if ( strlen(digits)) { - cc_feature_data_t ftr_data; - CCAPP_DEBUG(DEB_F_PREFIX"conf: sid=%s.\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),data); - // if data is received we need to extract the call id - // and send target_call_id in feature_data - // Post the event on the original call ( received call id as string in data). - if ( event == CC_FEATURE_B2BCONF ) { - ftr_data.b2bconf.target_call_id = call_id; - } else if ( event == CC_FEATURE_XFER ) { - ftr_data.xfer.target_call_id = call_id; - } else if ( event == CC_FEATURE_CONF) { - //Legacy local conference. - ftr_data.cnf.target_call_id = call_id; - } - - errno = 0; - strtol_result = strtol(digits, &strtol_end, 10); - - if (errno || digits == strtol_end || strtol_result < INT_MIN || strtol_result > INT_MAX) { - CCAPP_ERROR(DEB_F_PREFIX"digits parse error %s.\n",DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__), digits); - } else { - cc_feature(CC_SRC_UI, GET_CALLID((int) strtol_result), line_id, event, &ftr_data); - } - break; - } else { - CCAPP_DEBUG(DEB_F_PREFIX"conf: no sid.\n",DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - }// DON'T ADD BREAK HERE. EVENT IS PASSED BELOW - - case CC_FEATURE_B2B_JOIN: - case CC_FEATURE_DIRTRXFR: - case CC_FEATURE_SELECT: - case CC_FEATURE_CANCEL: - cc_feature(CC_SRC_UI, call_id, line_id, event, NULL); - break; - - case CC_FEATURE_HOLD: - if (data && ((strcmp(data, "TRANSFER") == 0) || - (strcmp(data, "CONFERENCE") == 0) || (strcmp(data, "SWAP") == 0))) { - featdata.hold.call_info.data.hold_resume_reason = CC_REASON_SWAP; - } else { - - featdata.hold.call_info.data.hold_resume_reason = CC_REASON_NONE; - } - featdata.hold.call_info.type = CC_FEAT_HOLD; - featdata.hold.msg_body.num_parts = 0; - cc_feature(CC_SRC_UI, call_id, line_id, event, &featdata); - break; - - default: - break; - } -} - -void CCAppShutdown() -{ -} - - -static char * ccapp_cmd_to_str(unsigned int cmd) { - switch (cmd) { - case CMD_INSERVICE: - return "CMD_INSERVICE"; - case CMD_SHUTDOWN: - return "CMD_SHUTDOWN"; - case CMD_RESTART: - return "CMD_RESTART"; - case CMD_UNREGISTER_ALL_LINES: - return "CMD_UNREGISTER_ALL_LINES"; - case CMD_REGISTER_ALL_LINES: - return "CMD_REGISTER_ALL_LINES"; - default: - return "CMD_UNKNOWN"; - } -} -/** - * - * CC Provider process service Cmds - * - * @param cmd - Command - * @param reason - reason - * @param reasonStr - reason string - * - * @return void - * - * @pre None - */ -void CCApp_processCmds(unsigned int cmd, unsigned int reason, string_t reasonStr) -{ - static const char fname[] = "CCApp_processCmds"; - CCAPP_DEBUG(DEB_F_PREFIX" Received Cmd %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, - fname), ccapp_cmd_to_str(cmd)); - switch (cmd) { - case CMD_INSERVICE: - ccsnap_device_init(); - ccsnap_line_init(); - gCCApp.state = CC_OOS_REGISTERING; - send_protocol_config_msg(); - break; - case CMD_SHUTDOWN: - case CMD_UNREGISTER_ALL_LINES: - /* send a shutdown message to the SIP Task */ - SIPTaskPostShutdown(SIP_EXTERNAL, reason, reasonStr); - break; - case CMD_RESTART: - SIPTaskPostRestart(TRUE); - break; - case CMD_BLF_INIT: - pres_sub_handler_initialized(); - break; - default: - APP_ERR_MSG("CCApp_processCmds: Error: Unknown message %d\n", cmd); - break; - } -} - -boolean isNoCallExist() -{ - hashItr_t itr; - - hashItrInit(&itr); - - return (hashItrNext(&itr)?FALSE:TRUE); -} - -/** - * Make deep copy of session_data_t - */ -session_data_t * getDeepCopyOfSessionData(session_data_t *data) -{ - session_data_t *newData = (session_data_t *) cpr_malloc(sizeof(session_data_t)); - - if ( newData != NULL ) { - memset(newData, 0, sizeof(session_data_t)); - - if ( data != NULL ) { - *newData = *data; - newData->ref_count = 1; - newData->clg_name = strlib_copy(data->clg_name); - newData->clg_number = strlib_copy(data->clg_number); - newData->cld_name = strlib_copy(data->cld_name); - newData->cld_number = strlib_copy(data->cld_number); - newData->alt_number = strlib_copy(data->alt_number); - newData->orig_called_name = strlib_copy(data->orig_called_name); - newData->orig_called_number = strlib_copy(data->orig_called_number); - newData->last_redir_name = strlib_copy(data->last_redir_name); - newData->last_redir_number = strlib_copy(data->last_redir_number); - newData->plcd_name = strlib_copy(data->plcd_name); - newData->plcd_number = strlib_copy(data->plcd_number); - newData->status = strlib_copy(data->status); - calllogger_copy_call_log(&newData->call_log, &data->call_log); - } else { - newData->ref_count = 1; - newData->state = ONHOOK; - newData->security = CC_SECURITY_NONE; - newData->policy = CC_POLICY_NONE; - newData->clg_name = strlib_empty(); - newData->clg_number = strlib_empty(); - newData->cld_name = strlib_empty(); - newData->cld_number = strlib_empty(); - newData->alt_number = strlib_empty(); - newData->orig_called_name = strlib_empty(); - newData->orig_called_number = strlib_empty(); - newData->last_redir_name = strlib_empty(); - newData->last_redir_number = strlib_empty(); - newData->plcd_name = strlib_empty(); - newData->plcd_number = strlib_empty(); - newData->status = strlib_empty(); - calllogger_init_call_log(&newData->call_log); - } - - } - return newData; -} - - -/** - * - * CCApp Provider search for session and deepfree data - * - * @return ptr to session data - * - * @pre None - */ - -void cleanSessionData(session_data_t *data) -{ - if ( data != NULL ) { - strlib_free(data->clg_name); - data->clg_name = strlib_empty(); - strlib_free(data->clg_number); - data->clg_number = strlib_empty(); - strlib_free(data->alt_number); - data->alt_number = strlib_empty(); - strlib_free(data->cld_name); - data->cld_name = strlib_empty(); - strlib_free(data->cld_number); - data->cld_number = strlib_empty(); - strlib_free(data->orig_called_name); - data->orig_called_name = strlib_empty(); - strlib_free(data->orig_called_number); - data->orig_called_number = strlib_empty(); - strlib_free(data->last_redir_name); - data->last_redir_name = strlib_empty(); - strlib_free(data->last_redir_number); - data->last_redir_number = strlib_empty(); - strlib_free(data->plcd_name); - data->plcd_name = strlib_empty(); - strlib_free(data->plcd_number); - data->plcd_number = strlib_empty(); - strlib_free(data->status); - data->status = strlib_empty(); - calllogger_free_call_log(&data->call_log); - } -} - -/** - * - * CCApp Provider check for CONNECTED calls for preservation - * - * @return boolean - do we need to move in call preservation phase - * - * @pre None - */ - -boolean ccappPreserveCall() -{ - static const char fname[] = "ccappPreserveCall"; - hashItr_t itr; - session_data_t *data; - boolean retVal = FALSE; - - CCAPP_DEBUG(DEB_F_PREFIX"called\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL ) { - if ( data->state == CONNECTED || data->state == PRESERVATION ) { - // need to wait for this call to end. - CCAPP_DEBUG(DEB_F_PREFIX"inPreservation = true\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - gCCApp.inPreservation = TRUE; - gCCApp.preservID = data->sess_id; - capset_get_allowed_features(gCCApp.mode, PRESERVATION, data->allowed_features); - ccsnap_gen_callEvent(CCAPI_CALL_EV_PRESERVATION, CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id)); - retVal = TRUE; - } else { - // End this call now - CCAPP_DEBUG(DEB_F_PREFIX"ending call %x\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->sess_id); - /* - * Note that for calls in state such as RIU, HOLD etc. - * we must send ON hook event (cc_onhook) instead of - * CC_FEATURE_END_CALL because corrsponding state machines - * handle only onhook event to clean up calls. - */ - cc_onhook(CC_SRC_UI, GET_CALLID(data->sess_id), - GET_LINEID(data->sess_id), TRUE); - - } - } - - return retVal; -} - -/** - * - * CCApp Provider check if its safe to proceed with failover/fallback - * - * @return void - do we need to move in call preservation phase - * - * @pre None - */ - -void proceedWithFOFB() -{ - static const char fname[] = "proceedWithFOFB"; - - CCAPP_DEBUG(DEB_F_PREFIX"called. preservation=%d in cucm mode=%s \n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - gCCApp.inPreservation, - gCCApp.cucm_mode == FAILOVER ? "FAILOVER": - gCCApp.cucm_mode == FALLBACK ? "FALLBACK": - gCCApp.cucm_mode == NO_CUCM_SRST_AVAILABLE ? - "NO_CUCM_SRST_AVAILABLE": "NONE"); - gCCApp.state = CC_OOS_REGISTERING; - - switch(gCCApp.cucm_mode) - { - case FAILOVER: - cc_fail_fallback_sip(CC_SRC_UI, RSP_START, CC_REG_FAILOVER_RSP, TRUE); - gCCApp.cause = CC_CAUSE_FAILOVER; - break; - - case FALLBACK: - cc_fail_fallback_sip(CC_SRC_UI, RSP_START, CC_REG_FALLBACK_RSP, TRUE); - gCCApp.cause = CC_CAUSE_FALLBACK; - break; - - case NO_CUCM_SRST_AVAILABLE: - gCCApp.cause = CC_CAUSE_REG_ALL_FAILED; - gCCApp.state = CC_OOS_IDLE; - break; - - default: - break; - } - - // Notify OOS state to Session Manager - switch (mapProviderState(gCCApp.state)) { - case CC_STATE_OOS: - ccpro_handleOOS(); - break; - default: - break; - } - ccapp_hlapi_update_device_reg_state(); -} -/** - * - * ccappHandleRegUpdates handles reg state changes. - * - * @param featUpd - feature update with reg state msg - * - * @return void - * - * @pre None - */ -void ccappHandleRegStateUpdates(feature_update_t *featUpd) -{ - static const char fname[] = "ccappHandleRegStateUpdates"; - - CCAPP_DEBUG(DEB_F_PREFIX"called. feature=%d=%s, state=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), featUpd->featureID, CCAPP_TASK_CMD_PRINT(featUpd->featureID), gCCApp.state); - gCCApp.cause = CC_CAUSE_NONE; - - // Update state varaibles to track state - switch (featUpd->featureID) - { - case CCAPP_MODE_NOTIFY: - gCCApp.mode = featUpd->update.ccFeatUpd.data.line_info.info; - CCAPP_DEBUG(DEB_F_PREFIX"called. gCCApp.mode= %d gCCApp.state=%d. Returning\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), gCCApp.mode, gCCApp.state); - return; - - case CCAPP_FAILOVER_IND: - gCCApp.state = CC_OOS_FAILOVER; - gCCApp.cucm_mode = FAILOVER; - gCCApp.cause = CC_CAUSE_FAILOVER; - if ( featUpd->update.ccFeatUpd.data.line_info.info == CC_TYPE_CCM ){ - gCCApp.mode = CC_MODE_CCM; - } - - else if (featUpd->update.ccFeatUpd.data.line_info.info == 3) { - gCCApp.mode = CC_MODE_NONCCM; - } - - if ( ccappPreserveCall() == FALSE) { - gCCApp.state = CC_OOS_REGISTERING; - cc_fail_fallback_sip(CC_SRC_UI, RSP_START, CC_REG_FAILOVER_RSP, FALSE); - } - break; - - case CCAPP_FALLBACK_IND: - gCCApp.cucm_mode = FALLBACK; - if ( featUpd->update.ccFeatUpd.data.line_info.info == CC_TYPE_CCM ){ - gCCApp.mode = CC_MODE_CCM; - } - if ( isNoCallExist() ) { - gCCApp.state = CC_OOS_REGISTERING; - gCCApp.cause = CC_CAUSE_FALLBACK; - cc_fail_fallback_sip(CC_SRC_UI, RSP_START, CC_REG_FALLBACK_RSP, FALSE); - } - break; - - case CCAPP_SHUTDOWN_ACK: - gCCApp.state = CC_OOS_IDLE; - gCCApp.cucm_mode = NONE_AVAIL; - gCCApp.inPreservation = FALSE; - gCCApp.cause = CC_CAUSE_SHUTDOWN; - - break; - case CCAPP_REG_ALL_FAIL: - gCCApp.state = CC_OOS_IDLE; - gCCApp.cucm_mode = NO_CUCM_SRST_AVAILABLE; - gCCApp.inPreservation = FALSE; - if (ccappPreserveCall() == FALSE) { - gCCApp.cause = CC_CAUSE_REG_ALL_FAILED; - } else { - gCCApp.cause = CC_CAUSE_FAILOVER; - } - break; - - case CCAPP_LOGOUT_RESET: - gCCApp.state = CC_OOS_IDLE; - gCCApp.cucm_mode = NONE_AVAIL; - /*gCCApp.inFailover = FALSE; - gCCApp.inFallback = FALSE;*/ - gCCApp.inPreservation = FALSE; - gCCApp.cause = CC_CAUSE_LOGOUT_RESET; - break; - } - // Notify INS/OOS state to Session Manager if required - CCAPP_DEBUG(DEB_F_PREFIX"called. service_state=%d, mode=%d, cause=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - mapProviderState(gCCApp.state), - gCCApp.mode, - gCCApp.cause); - switch (mapProviderState(gCCApp.state)) { - case CC_STATE_INS: - ccpro_handleINS(); - break; - case CC_STATE_OOS: - ccpro_handleOOS(); - break; - default: - break; - } - ccapp_hlapi_update_device_reg_state(); -} - -/* - * this function determine if the called number (i.e., dialed number) contains - * string x-cisco-serviceuri-cfwdall. - */ -static boolean ccappCldNumIsCfwdallString(string_t cld_number) { - static char cfwdAllString[STATUS_LINE_MAX_LEN] = "x-cisco-serviceuri-cfwdall"; - - if (strncmp(cld_number, cfwdAllString, strlen(cfwdAllString)) == 0) { - /* The Called Party number is the Call Forward all URI */ - return ((int) TRUE); - } - return ((int) FALSE); -} - -/** - * Api to update mute state of connected call - */ -cc_call_handle_t ccappGetConnectedCall(){ - session_data_t * data; - hashItr_t itr; - - hashItrInit(&itr); - while ( (data = (session_data_t*)hashItrNext(&itr)) != NULL ) { - if( data->state == CONNECTED ) { - return CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id); - } - } - return 0; -} - -/** - * - * CCApp Provider cache session data to hashTable routine - * - * @param sessUpd - Session update from CC - * - * @return void - * - * @pre None - */ - -static void ccappUpdateSessionData (session_update_t *sessUpd) -{ - static const char fname[] = "ccappUpdateSessionData"; - session_data_t * data = (session_data_t *)findhash(sessUpd->sessionID), *sess_data_p; - boolean createdSessionData = TRUE; - cc_deviceinfo_ref_t handle = 0; - boolean previouslyInConference = FALSE; - - if ( data == NULL ) { - cc_call_state_t call_state = sessUpd->update.ccSessionUpd.data.state_data.state; - - if ( ( sessUpd->eventID == CALL_INFORMATION ) || - ( sessUpd->eventID == CALL_STATE || sessUpd->eventID == CALL_NEWCALL - || sessUpd->eventID == CREATE_OFFER || sessUpd->eventID == CREATE_ANSWER - || sessUpd->eventID == SET_LOCAL_DESC || sessUpd->eventID == SET_REMOTE_DESC - || sessUpd->eventID == REMOTE_STREAM_ADD)) { - - CCAPP_DEBUG(DEB_F_PREFIX"CALL_SESSION_CREATED for session id 0x%x event is 0x%x \n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->sessionID, - sessUpd->eventID); - - if (sessUpd->eventID == CALL_INFORMATION ) { - call_state = RINGIN; - - } else { - if ( sessUpd->update.ccSessionUpd.data.state_data.state == ONHOOK ) { - CCAPP_DEBUG(DEB_F_PREFIX"NOT CREATING Session Ignoring event %d sessid %x as state is ONHOOK\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->eventID, sessUpd->sessionID ); - //Even session data is not created, we need to send ONHOOK to application to terminate call. - createdSessionData = FALSE; - } - call_state = sessUpd->update.ccSessionUpd.data.state_data.state; - } - //Create a new call. - if (createdSessionData == TRUE) { - cc_call_handle_t callHandle = CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID); - // - NOTIFY_CALL_DEBUG(DEB_NOTIFY_PREFIX"[line=%d][call.ref=%d]\n", - "CallBegin", GET_LINE_ID(callHandle), GET_CALL_ID(callHandle)); - //> - data = cpr_malloc(sizeof(session_data_t)); - if ( data == NULL ) { - APP_ERR_MSG("ccappUpdateSessionData Error: cpr_malloc failed for session data\n"); - return; - } - //Populate the session hash data the first time. - memset(data, 0, sizeof(session_data_t)); - data->sess_id = sessUpd->sessionID; - data->state = call_state; - data->line = sessUpd->update.ccSessionUpd.data.state_data.line_id; - if (sessUpd->eventID == CALL_NEWCALL || sessUpd->eventID == CREATE_OFFER || - sessUpd->eventID == CREATE_ANSWER || sessUpd->eventID == SET_LOCAL_DESC || - sessUpd->eventID == SET_REMOTE_DESC || sessUpd->eventID == REMOTE_STREAM_ADD ) { - data->attr = sessUpd->update.ccSessionUpd.data.state_data.attr; - data->inst = sessUpd->update.ccSessionUpd.data.state_data.inst; - } - data->cause = sessUpd->update.ccSessionUpd.data.state_data.cause; - data->clg_name = strlib_empty(); - data->clg_number = strlib_empty(); - data->alt_number = strlib_empty(); - data->cld_name = strlib_empty(); - data->cld_number = strlib_empty(); - data->orig_called_name = strlib_empty(); - data->orig_called_number = strlib_empty(); - data->last_redir_name = strlib_empty(); - data->last_redir_number = strlib_empty(); - data->plcd_name = strlib_empty(); - data->plcd_number = strlib_empty(); - data->status = strlib_empty(); - data->gci[0] = 0; - data->vid_dir = SDP_DIRECTION_INACTIVE; - data->callref = 0; - calllogger_init_call_log(&data->call_log); - - if ( sessUpd->eventID == CREATE_OFFER || sessUpd->eventID == CREATE_ANSWER - || sessUpd->eventID == SET_LOCAL_DESC || sessUpd->eventID == SET_REMOTE_DESC - || sessUpd->eventID == REMOTE_STREAM_ADD) { - data->sdp = sessUpd->update.ccSessionUpd.data.state_data.sdp; - data->cause = sessUpd->update.ccSessionUpd.data.state_data.cause; - data->media_stream_track_id = sessUpd->update.ccSessionUpd.data.state_data.media_stream_track_id; - data->media_stream_id = sessUpd->update.ccSessionUpd.data.state_data.media_stream_id; - } - - /* - * If phone was idle, we not going to active state - * send notification to resetmanager that we - * are no longer resetReady. - */ - if ((CCAPI_DeviceInfo_isPhoneIdle(handle) == TRUE) && (sendResetUpdates)) { - resetNotReady(); - } - (void) addhash(data->sess_id, data); - } - - //The update accordingly - switch (sessUpd->eventID) { - case CALL_INFORMATION: - data->clg_name = ccsnap_EscapeStrToLocaleStr(data->clg_name, sessUpd->update.ccSessionUpd.data.call_info.clgName, LEN_UNKNOWN); - data->cld_name = ccsnap_EscapeStrToLocaleStr(data->cld_name, sessUpd->update.ccSessionUpd.data.call_info.cldName, LEN_UNKNOWN); - data->orig_called_name = ccsnap_EscapeStrToLocaleStr(data->orig_called_name, sessUpd->update.ccSessionUpd.data.call_info.origCalledName, LEN_UNKNOWN); - data->last_redir_name = ccsnap_EscapeStrToLocaleStr(data->last_redir_name, sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingName, LEN_UNKNOWN); - - data->clg_number = strlib_update(data->clg_number, sessUpd->update.ccSessionUpd.data.call_info.clgNumber); - data->cld_number = strlib_update(data->cld_number, sessUpd->update.ccSessionUpd.data.call_info.cldNumber); - data->alt_number = strlib_update(data->alt_number, sessUpd->update.ccSessionUpd.data.call_info.altClgNumber); - data->orig_called_number = strlib_update(data->orig_called_number, sessUpd->update.ccSessionUpd.data.call_info.origCalledNumber); - data->last_redir_number = strlib_update(data->last_redir_number, sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingNumber); - data->type = sessUpd->update.ccSessionUpd.data.call_info.call_type; - data->inst = sessUpd->update.ccSessionUpd.data.call_info.instance_id; - data->security = sessUpd->update.ccSessionUpd.data.call_info.security; - data->policy = sessUpd->update.ccSessionUpd.data.call_info.policy; - break; - case CALL_STATE: - if (createdSessionData == FALSE) { - return; - } - data->state = sessUpd->update.ccSessionUpd.data.state_data.state; - data->line = sessUpd->update.ccSessionUpd.data.state_data.line_id; - break; - default: - break; - } - } else if (sessUpd->eventID == CALL_DELETE_LAST_DIGIT) { - CCAPP_DEBUG(DEB_F_PREFIX"CALL_DELETE_LAST_DIGIT: event %d sessid %x.\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->eventID, sessUpd->sessionID ); - return; - } else { - CCAPP_DEBUG(DEB_F_PREFIX"NOT CREATING Session Ignoring event %d sessid %x \n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->eventID, sessUpd->sessionID ); - return; - } - - // send event to csf2g API - if (data != NULL) { - capset_get_allowed_features(gCCApp.mode, data->state, data->allowed_features); - ccsnap_gen_callEvent(CCAPI_CALL_EV_CREATED, CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id)); - } - return; - - } - - CCAPP_DEBUG(DEB_F_PREFIX"Found data for sessid %x event %d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->sessionID, sessUpd->eventID); - switch(sessUpd->eventID) { - case CALL_SESSION_CLOSED: - // find and deep free then delete - sess_data_p = (session_data_t *)findhash(sessUpd->sessionID); - if ( sess_data_p != NULL ){ - cleanSessionData(sess_data_p); - if ( 0 > delhash(sessUpd->sessionID) ) { - APP_ERR_MSG (DEB_F_PREFIX"failed to delete hash sessid=0x%08x\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),sessUpd->sessionID); - } - cpr_free(sess_data_p); - } - if ( (gCCApp.inPreservation || (gCCApp.cucm_mode == FALLBACK)) && isNoCallExist()) { - /* The phone is now Idle. Clear the inPreservation Flag */ - gCCApp.inPreservation = FALSE; - proceedWithFOFB(); - } - if ((CCAPI_DeviceInfo_isPhoneIdle(handle) == TRUE) && (sendResetUpdates)) { - resetReady(); - } - if (pending_action_type != NO_ACTION) { - perform_deferred_action(); - } - break; - - case CALL_STATE: - DEF_DEBUG(DEB_F_PREFIX"Call_STATE:. state=%d, attr=%d, cause=%d, instance=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - sessUpd->update.ccSessionUpd.data.state_data.state, - data->attr, - sessUpd->update.ccSessionUpd.data.state_data.cause, - data->inst); - if ( sessUpd->update.ccSessionUpd.data.state_data.state == HOLD && - (data->state == REMHOLD || data->state == REMINUSE)){ - data->state = REMHOLD; - } else { - data->state = sessUpd->update.ccSessionUpd.data.state_data.state; - } - data->line = sessUpd->update.ccSessionUpd.data.state_data.line_id; - sessUpd->update.ccSessionUpd.data.state_data.attr = data->attr; - sessUpd->update.ccSessionUpd.data.state_data.inst = data->inst; - - data->cause = sessUpd->update.ccSessionUpd.data.state_data.cause; - - //Update call state - if ( data != NULL ){ - capset_get_allowed_features(gCCApp.mode, data->state, data->allowed_features); - } - calllogger_update(data); - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATE, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - - // - if (data->state == ONHOOK) { - NOTIFY_CALL_DEBUG(DEB_NOTIFY_PREFIX"[line=%d][call.ref=%d]\n", - "CallEND", data->line, data->id); - } - //> - - if (data->state == ONHOOK) { - // find and deep free then delete - sess_data_p = (session_data_t *)findhash(sessUpd->sessionID); - if ( sess_data_p != NULL ){ - cleanSessionData(sess_data_p); - if ( 0 > delhash(sessUpd->sessionID) ) { - APP_ERR_MSG (DEB_F_PREFIX"failed to delete hash sessid=0x%08x\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),sessUpd->sessionID); - } - cpr_free(sess_data_p); - data = NULL; - } - if ((gCCApp.inPreservation || (gCCApp.cucm_mode == FALLBACK)) && isNoCallExist()) { - /* The phone is now Idle. Clear the inPreservation Flag */ - gCCApp.inPreservation = FALSE; - proceedWithFOFB(); - } - if ((CCAPI_DeviceInfo_isPhoneIdle(handle) == TRUE) && (sendResetUpdates)) { - resetReady(); - } - if (pending_action_type != NO_ACTION) { - perform_deferred_action(); - } - } - break; - - case CALL_CALLREF: - data->callref = sessUpd->update.ccSessionUpd.data.callref; - break; - case CALL_GCID: - if ( ! strncasecmp(data->gci, sessUpd->update.ccSessionUpd.data.gcid, CC_MAX_GCID)) { - // No change in gci we can ignore the update - return; - } - sstrncpy(data->gci, sessUpd->update.ccSessionUpd.data.gcid, CC_MAX_GCID); - ccsnap_gen_callEvent(CCAPI_CALL_EV_GCID, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_NEWCALL: - data->state = sessUpd->update.ccSessionUpd.data.state_data.state; - data->line = sessUpd->update.ccSessionUpd.data.state_data.line_id; - data->attr = sessUpd->update.ccSessionUpd.data.state_data.attr; - data->inst = sessUpd->update.ccSessionUpd.data.state_data.inst; - return; - break; - - case CALL_ATTR: - data->attr = sessUpd->update.ccSessionUpd.data.state_data.attr; - calllogger_update(data); - ccsnap_gen_callEvent(CCAPI_CALL_EV_ATTR, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case CALL_INFORMATION: - // check conference state, if it changes, we'll send a conference event notification - previouslyInConference = CCAPI_CallInfo_getIsConference(data); - - data->clg_name = ccsnap_EscapeStrToLocaleStr(data->clg_name, sessUpd->update.ccSessionUpd.data.call_info.clgName, LEN_UNKNOWN); - data->cld_name = ccsnap_EscapeStrToLocaleStr(data->cld_name, sessUpd->update.ccSessionUpd.data.call_info.cldName, LEN_UNKNOWN); - data->orig_called_name = ccsnap_EscapeStrToLocaleStr(data->orig_called_name, sessUpd->update.ccSessionUpd.data.call_info.origCalledName, LEN_UNKNOWN); - data->last_redir_name = ccsnap_EscapeStrToLocaleStr(data->last_redir_name, sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingName, LEN_UNKNOWN); - data->clg_number = strlib_update(data->clg_number, sessUpd->update.ccSessionUpd.data.call_info.clgNumber); - data->cld_number = strlib_update(data->cld_number, sessUpd->update.ccSessionUpd.data.call_info.cldNumber); - data->alt_number = strlib_update(data->alt_number, sessUpd->update.ccSessionUpd.data.call_info.altClgNumber); - data->orig_called_number = strlib_update(data->orig_called_number, sessUpd->update.ccSessionUpd.data.call_info.origCalledNumber); - data->last_redir_number = strlib_update(data->last_redir_number, sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingNumber); - data->type = sessUpd->update.ccSessionUpd.data.call_info.call_type; - data->inst = sessUpd->update.ccSessionUpd.data.call_info.instance_id; - data->security = sessUpd->update.ccSessionUpd.data.call_info.security; - data->policy = sessUpd->update.ccSessionUpd.data.call_info.policy; - if ((data->cld_number[0]) && ccappCldNumIsCfwdallString(data->cld_number)) { - DEF_DEBUG(DEB_F_PREFIX"Not updating the UI. Called Number = %s\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), data->cld_number); - return; - } - /* - * For 3rd Gen and 4th Gen phones... Use sessUpd->update structure to pass call information - * For 5th Gen phones, the information will be localized by a 5th Gen Application, and the - * dictionaries might not be equivalent. - */ - calllogger_update(data); - - ccsnap_gen_callEvent(CCAPI_CALL_EV_CALLINFO, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - - // if we're entering a conference, then indicate conference participant info (in case the info came earlier, app - // will receive the notification now. If info comes later, then app will receive an additional subsequent info notice - // at that time. - if ((!previouslyInConference) && (CCAPI_CallInfo_getIsConference(data))) { - ccsnap_gen_callEvent(CCAPI_CALL_EV_CONF_PARTICIPANT_INFO, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - } - - break; - - case CALL_PLACED_INFO: - data->plcd_number = strlib_update(data->plcd_number, sessUpd->update.ccSessionUpd.data.plcd_info.cldNum); - data->plcd_name = ccsnap_EscapeStrToLocaleStr(data->plcd_name, sessUpd->update.ccSessionUpd.data.plcd_info.cldName, LEN_UNKNOWN); - calllogger_setPlacedCallInfo(data); - - break; - - case CALL_SELECTED: - data->isSelected = sessUpd->update.ccSessionUpd.data.action; - ccsnap_gen_callEvent(CCAPI_CALL_EV_SELECT, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case CALL_SELECT_FEATURE_SET: - // Not quite perfect but should do for now - if ( strcmp("CONNECTEDNOFEAT", sessUpd->update.ccSessionUpd.data.feat_set.featSet ) ) { - data->allowed_features[CCAPI_CALL_CAP_HOLD] = FALSE; - data->allowed_features[CCAPI_CALL_CAP_CONFERENCE] = FALSE; - data->allowed_features[CCAPI_CALL_CAP_TRANSFER] = FALSE; - } else if ( sessUpd->update.ccSessionUpd.data.feat_set.featMask[0] == skConfrn ) { - data->allowed_features[CCAPI_CALL_CAP_CONFERENCE] = FALSE; - } - ccsnap_gen_callEvent(CCAPI_CALL_EV_CAPABILITY, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case CALL_STATUS: - /* - * For 5th Gen Phones, data->status is localized. - * 3rd Gen and 4th Gen phones should use sessUpd->update struct to pass the status to the application. - */ - data->status = ccsnap_EscapeStrToLocaleStr(data->status, sessUpd->update.ccSessionUpd.data.status.status, LEN_UNKNOWN); - if (data->status != NULL) { - if(strncmp(data->status, UNKNOWN_PHRASE_STR, UNKNOWN_PHRASE_STR_SIZE) == 0){ - data->status = strlib_empty(); - } - if(strcmp(data->status, strlib_empty()) != 0){ - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATUS, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - } - } - // - NOTIFY_CALL_DEBUG(DEB_NOTIFY_PREFIX"[line=%d][call.ref=%d][status=%s]\n", - "callStatusChange", data->line, data->id, - NOTIFY_CALL_STATUS); - //> - - break; - if(strcmp(data->status, strlib_empty()) != 0){ - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATUS, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - } - - case CALL_PRESERVATION_ACTIVE: - data->state = PRESERVATION; - ccsnap_gen_callEvent(CCAPI_CALL_EV_PRESERVATION, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case RINGER_STATE: - data->ringer_start = sessUpd->update.ccSessionUpd.data.ringer.start; - data->ringer_mode = sessUpd->update.ccSessionUpd.data.ringer.mode; - data->ringer_once = sessUpd->update.ccSessionUpd.data.ringer.once; - ccsnap_gen_callEvent(CCAPI_CALL_EV_RINGER_STATE, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - - case VIDEO_AVAIL: - if ( data->vid_dir == sessUpd->update.ccSessionUpd.data.action ) { - // no change don't update - return; - } - data->vid_dir = sessUpd->update.ccSessionUpd.data.action; - ccsnap_gen_callEvent(CCAPI_CALL_EV_VIDEO_AVAIL, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case VIDEO_OFFERED: - data->vid_offer = sessUpd->update.ccSessionUpd.data.action; - ccsnap_gen_callEvent(CCAPI_CALL_EV_VIDEO_OFFERED, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_ENABLE_BKSP: - data->allowed_features[CCAPI_CALL_CAP_BACKSPACE] = TRUE; - ccsnap_gen_callEvent(CCAPI_CALL_EV_CAPABILITY, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_SECURITY: - data->security = sessUpd->update.ccSessionUpd.data.security; - ccsnap_gen_callEvent(CCAPI_CALL_EV_SECURITY, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_LOGDISP: - data->log_disp = sessUpd->update.ccSessionUpd.data.action; - calllogger_updateLogDisp(data); - // No need to generate this event anymore - // ccsnap_gen_callEvent(CCAPI_CALL_EV_LOG_DISP, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_DELETE_LAST_DIGIT: - ccsnap_gen_callEvent(CCAPI_CALL_EV_LAST_DIGIT_DELETED, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_FEATURE_CANCEL: - ccsnap_gen_callEvent(CCAPI_CALL_EV_XFR_OR_CNF_CANCELLED, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CALL_RECV_INFO_LIST: - //Should not come here. It's dealed in CCAPP_RCVD_INFO. - break; - case MEDIA_INTERFACE_UPDATE_BEGIN: - ccsnap_gen_callEvent(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_BEGIN, - CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case MEDIA_INTERFACE_UPDATE_SUCCESSFUL: - ccsnap_gen_callEvent(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_SUCCESSFUL, - CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case MEDIA_INTERFACE_UPDATE_FAIL: - ccsnap_gen_callEvent(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_FAIL, - CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID)); - break; - case CREATE_OFFER: - case CREATE_ANSWER: - case SET_LOCAL_DESC: - case SET_REMOTE_DESC: - case REMOTE_STREAM_ADD: - data->sdp = sessUpd->update.ccSessionUpd.data.state_data.sdp; - data->cause = sessUpd->update.ccSessionUpd.data.state_data.cause; - data->state = sessUpd->update.ccSessionUpd.data.state_data.state; - data->media_stream_track_id = sessUpd->update.ccSessionUpd.data.state_data.media_stream_track_id; - data->media_stream_id = sessUpd->update.ccSessionUpd.data.state_data.media_stream_id; - capset_get_allowed_features(gCCApp.mode, data->state, data->allowed_features); - ccsnap_gen_callEvent(CCAPI_CALL_EV_STATE, CREATE_CALL_HANDLE_FROM_SESSION_ID(data->sess_id)); - break; - default: - DEF_DEBUG(DEB_F_PREFIX"Unknown event, id = %d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->eventID); - break; - } - return; -} - -static void freeSessionData(session_update_t *sessUpd) -{ - switch(sessUpd->eventID) { - case CALL_INFORMATION: - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.clgName); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.clgNumber); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.cldName); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.cldNumber); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.altClgNumber); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.origCalledName); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.origCalledNumber); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingName); - strlib_free(sessUpd->update.ccSessionUpd.data.call_info.lastRedirectingNumber); - break; - case CALL_PLACED_INFO: - strlib_free(sessUpd->update.ccSessionUpd.data.plcd_info.cldName); - strlib_free(sessUpd->update.ccSessionUpd.data.plcd_info.cldNum); - break; - case CALL_SELECT_FEATURE_SET: - strlib_free(sessUpd->update.ccSessionUpd.data.feat_set.featSet); - break; - case CALL_STATUS: - strlib_free(sessUpd->update.ccSessionUpd.data.status.status); - break; - case CALL_RECV_INFO_LIST: - strlib_free(sessUpd->update.ccSessionUpd.data.recv_info_list); - break; - } -} - -static void freeSessionMgmtData(session_mgmt_t *sessMgmt) -{ - switch(sessMgmt->func_id) { - case SESSION_MGMT_APPLY_CONFIG: - strlib_free(sessMgmt->data.config.log_server); - strlib_free(sessMgmt->data.config.load_server); - strlib_free(sessMgmt->data.config.load_id); - strlib_free(sessMgmt->data.config.inactive_load_id); - strlib_free(sessMgmt->data.config.cucm_result); - strlib_free(sessMgmt->data.config.fcp_version_stamp); - strlib_free(sessMgmt->data.config.dialplan_version_stamp); - strlib_free(sessMgmt->data.config.config_version_stamp); - break; - case SESSION_MGMT_EXECUTE_URI: - strlib_free(sessMgmt->data.uri.uri); - break; - default: - break; - } -} - -static void freeRcvdInfo(session_rcvd_info_t *rcvdInfo) -{ - switch(rcvdInfo->packageID) { - case INFO_PKG_ID_GENERIC_RAW: - strlib_free(rcvdInfo->info.generic_raw.info_package); - strlib_free(rcvdInfo->info.generic_raw.content_type); - strlib_free(rcvdInfo->info.generic_raw.message_body); - break; - } -} - -void dump_msg(char * name, unsigned int *msg, int len, unsigned int cmd) { -int i,j; - CCAPP_DEBUG(DEB_F_PREFIX"\n%s %x %d cmd=%d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "dump_msg"), name, msg, len, cmd); - for ( j=0;j<10;j++) { - for(i=0;i<16;i++) { - CCAPP_DEBUG(DEB_F_PREFIX"%08X ", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "dump_msg"), msg[i+j]); - if ( (i+j+1)*4 >= len ) return; - } - CCAPP_DEBUG(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "dump_msg")); - } -} - - -/** - * A ccapp task listener - */ -void ccp_handler(void* msg, int type) { - static const char fname[] = "ccp_handler"; - sessionProvider_cmd_t *cmdMsg; - session_feature_t *featMsg; - session_update_t *sessUpd; - feature_update_t *featUpd; - session_mgmt_t *sessMgmt; - session_send_info_t *sendInfo; - session_rcvd_info_t *rcvdInfo; - session_id_t sess_id; - session_data_t *data; - int length; - - CCAPP_DEBUG(DEB_F_PREFIX"Received Cmd %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - CCAPP_TASK_CMD_PRINT(type) ); - - - switch (type) { - case CCAPP_SERVICE_CMD: - cmdMsg = (sessionProvider_cmd_t *) msg; - CCApp_processCmds (cmdMsg->cmd, cmdMsg->cmdData.ccData.reason, - cmdMsg->cmdData.ccData.reason_info); - break; - - case CCAPP_INVOKEPROVIDER_FEATURE: - featMsg = (session_feature_t *) msg; - processProviderEvent(GET_LINEID(featMsg->session_id), featMsg->featureID, - featMsg->featData.ccData.state); - if (featMsg->featData.ccData.info != NULL) { - strlib_free(featMsg->featData.ccData.info); - } - if (featMsg->featData.ccData.info1 != NULL) { - strlib_free(featMsg->featData.ccData.info1); - } - break; - case CCAPP_INVOKE_FEATURE: - featMsg = (session_feature_t *) msg; - CCAPP_DEBUG(DEB_F_PREFIX"CCAPP_INVOKE_FEATURE:sid=%d, fid=%d, line=%d, cid=%d, info=%s info1=%s\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - featMsg->session_id, - featMsg->featureID, - GET_LINEID(featMsg->session_id), - GET_CALLID(featMsg->session_id), - ((featMsg->featureID == CC_FEATURE_KEYPRESS) ? "..." : featMsg->featData.ccData.info), - ((featMsg->featureID == CC_FEATURE_KEYPRESS) ? "..." : featMsg->featData.ccData.info1)); - processSessionEvent(GET_LINEID(featMsg->session_id), GET_CALLID(featMsg->session_id), - featMsg->featureID, featMsg->featData.ccData.state, - featMsg->featData.ccData); - if (featMsg->featData.ccData.info != NULL) { - strlib_free(featMsg->featData.ccData.info); - } - if (featMsg->featData.ccData.info1 != NULL) { - strlib_free(featMsg->featData.ccData.info1); - } - break; - - case CCAPP_CLOSE_SESSION: - sess_id = *(session_id_t*)msg; - cc_feature(CC_SRC_UI, GET_CALLID(sess_id), - GET_LINEID(sess_id), CC_FEATURE_END_CALL, NULL); - break; - - case CCAPP_SESSION_UPDATE: - sessUpd = (session_update_t *) msg; - // Udpate the local cache - CCAPP_DEBUG(DEB_F_PREFIX"CCAPP_SESSION_UPDATE:type:%d.\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), GET_SESS_TYPE(sessUpd->sessionID)); - // XXX Why do this when sessType is in session_update_t already? - if (GET_SESS_TYPE(sessUpd->sessionID) == SESSIONTYPE_CALLCONTROL) { - ccappUpdateSessionData(sessUpd); - } - else { - CCAPP_DEBUG(DEB_F_PREFIX"Unknown type:%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), sessUpd->sessType); - } - freeSessionData(sessUpd); - break; - - case CCAPP_FEATURE_UPDATE: - - featUpd = (feature_update_t *) msg; - // Update Registration state - if (featUpd->featureID == DEVICE_REG_STATE) - CCAPP_DEBUG(DEB_F_PREFIX"DEVICE_REG_STATE\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if(featUpd->update.ccFeatUpd.data.line_info.info == CC_REGISTERED) - CCAPP_DEBUG(DEB_F_PREFIX"CC_REGISTERED\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if(gCCApp.state == (int) CC_INSERVICE) - CCAPP_DEBUG(DEB_F_PREFIX"CC_INSERVICE\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - if ( featUpd->featureID == DEVICE_REG_STATE && - featUpd->update.ccFeatUpd.data.line_info.info == CC_REGISTERED && - gCCApp.state != (int) CC_INSERVICE ) - { - cc_uint32_t major_ver=0, minor_ver=0,addtnl_ver=0; - char name[CC_MAX_LEN_REQ_SUPP_PARAM_CISCO_SISTAG]={0}; - platGetSISProtocolVer( &major_ver, &minor_ver, &addtnl_ver, name); - CCAPP_DEBUG(DEB_F_PREFIX"The SIS verion is: %s, sis ver: %d.%d.%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), name, major_ver, minor_ver, addtnl_ver); - if(!strncmp(name, REQ_SUPP_PARAM_CISCO_CME_SISTAG, strlen(REQ_SUPP_PARAM_CISCO_CME_SISTAG))){ - CCAPP_DEBUG(DEB_F_PREFIX"This is CUCME mode.\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - } else if(!strncmp(name, REQ_SUPP_PARAM_CISCO_SISTAG, strlen(REQ_SUPP_PARAM_CISCO_SISTAG))){ - CCAPP_DEBUG(DEB_F_PREFIX"This is CUCM mode.\n",DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - } else { - CCAPP_DEBUG(DEB_F_PREFIX"This is unknown mode.\n",DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - } - - gCCApp.state = CC_INSERVICE; - gCCApp.cause = CC_CAUSE_NONE; - - // Notify INS/OOS state to Session Manager if required - ccapp_hlapi_update_device_reg_state(); - ccpro_handleINS(); - - if (gCCApp.cucm_mode == FAILOVER) { - cc_fail_fallback_sip(CC_SRC_UI, RSP_COMPLETE, CC_REG_FAILOVER_RSP, FALSE); - } - if (gCCApp.cucm_mode == FALLBACK) { - cc_fail_fallback_sip(CC_SRC_UI, RSP_COMPLETE, CC_REG_FALLBACK_RSP, FALSE); - } - gCCApp.cucm_mode = NONE_AVAIL; - } - - ccappFeatureUpdated(featUpd); - break; - - case CCAPP_SESSION_MGMT: - sessMgmt = (session_mgmt_t *) msg; - ccappSyncSessionMgmt(sessMgmt); - break; - - case CCAPP_SEND_INFO: - sendInfo = (session_send_info_t *) msg; - data = (session_data_t *)findhash(sendInfo->sessionID); - - if ( data != NULL && data->state == CONNECTED ) { - cc_int_info(CC_SRC_UI, CC_SRC_SIP, - GET_CALLID(sendInfo->sessionID), - GET_LINEID(sendInfo->sessionID), - sendInfo->generic_raw.info_package, - sendInfo->generic_raw.content_type, - sendInfo->generic_raw.message_body); - } - strlib_free(sendInfo->generic_raw.message_body); - strlib_free(sendInfo->generic_raw.content_type); - strlib_free(sendInfo->generic_raw.info_package); - break; - - case CCAPP_RCVD_INFO: - sendInfo = (session_send_info_t *) msg; - data = (session_data_t *)findhash(sendInfo->sessionID); - rcvdInfo = (session_rcvd_info_t *) msg; - - length = strlen((const char*)rcvdInfo->info.generic_raw.message_body); - if (data != NULL) { - CCAPP_DEBUG(DEB_F_PREFIX"rcvdInfo: addr=%x length=%d, xml=%s\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE"), - &data->call_conference, length, rcvdInfo->info.generic_raw.message_body); - - data->info_package = rcvdInfo->info.generic_raw.info_package; - data->info_type = rcvdInfo->info.generic_raw.content_type; - data->info_body = rcvdInfo->info.generic_raw.message_body; - - ccsnap_gen_callEvent(CCAPI_CALL_EV_RECEIVED_INFO, CREATE_CALL_HANDLE_FROM_SESSION_ID(rcvdInfo->sessionID)); - - // most of the time isConference will be true at this point, we can notify the app of - // the updated participant info. However, if we're transitioning from non conference into - // conference, then we'll delay this notification until we're fully in conference state - if (CCAPI_CallInfo_getIsConference(data)) - { // in conference - send the info - ccsnap_gen_callEvent(CCAPI_CALL_EV_CONF_PARTICIPANT_INFO, CREATE_CALL_HANDLE_FROM_SESSION_ID(rcvdInfo->sessionID)); - } - - // one shot notify cleanup after event generation - data->info_package = strlib_empty(); - data->info_type = strlib_empty(); - data->info_body = strlib_empty(); - } - freeRcvdInfo(rcvdInfo); - break; - - case CCAPP_UPDATELINES: - notify_register_update(*(int *)msg); - break; - - case CCAPP_MODE_NOTIFY: - case CCAPP_FAILOVER_IND: - case CCAPP_SHUTDOWN_ACK: - case CCAPP_FALLBACK_IND: - case CCAPP_REG_ALL_FAIL: - featUpd = (feature_update_t *) msg; - ccappHandleRegStateUpdates(featUpd); - break; - - case CCAPP_THREAD_UNLOAD: - destroy_ccapp_thread(); - break; - default: - APP_ERR_MSG("CCApp_Task: Error: Unknown message %d msg =0x%x\n", type, msg); - break; - } -} - -/* - * Function: destroy_ccapp_thread - * Description: shutdown and kill ccapp thread - * Parameters: none - * Returns: none - */ -void destroy_ccapp_thread() -{ - static const char fname[] = "destroy_ccapp_thread"; - TNP_DEBUG(DEB_F_PREFIX"Unloading ccapp and destroying ccapp thread\n", - DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - platform_initialized = FALSE; - CCAppShutdown(); - (void)cprDestroyThread(ccapp_thread); -} - -/** - * CCAPP wrapper to update device features. - * @param featUpd - feature_update_t - * @return void - */ -static -void ccappFeatureUpdated (feature_update_t *featUpd) { - cc_line_info_t *line_info; - - switch(featUpd->featureID) { - case DEVICE_FEATURE_CFWD: - line_info = ccsnap_getLineInfoFromBtn(featUpd->update.ccFeatUpd.data.cfwd.line); - if ( line_info != NULL ) { - line_info->isCFWD = featUpd->update.ccFeatUpd.data.cfwd.isFwd; - line_info->isLocalCFWD = featUpd->update.ccFeatUpd.data.cfwd.isLocal; - line_info->cfwd_dest = strlib_update(line_info->cfwd_dest, featUpd->update.ccFeatUpd.data.cfwd.cfa_num); - ccsnap_gen_lineEvent(CCAPI_LINE_EV_CFWDALL, line_info->button); - } - CC_Config_setStringValue(CFGID_LINE_CFWDALL+featUpd->update.ccFeatUpd.data.cfwd.line-1, featUpd->update.ccFeatUpd.data.cfwd.cfa_num); - - break; - case DEVICE_FEATURE_MWI: - line_info = ccsnap_getLineInfoFromBtn(featUpd->update.ccFeatUpd.data.mwi_status.line); - if ( line_info != NULL ) { - line_info->mwi.status = featUpd->update.ccFeatUpd.data.mwi_status.status; - line_info->mwi.type = featUpd->update.ccFeatUpd.data.mwi_status.type; - line_info->mwi.new_count = featUpd->update.ccFeatUpd.data.mwi_status.newCount; - line_info->mwi.old_count = featUpd->update.ccFeatUpd.data.mwi_status.oldCount; - line_info->mwi.pri_new_count = featUpd->update.ccFeatUpd.data.mwi_status.hpNewCount; - line_info->mwi.pri_old_count = featUpd->update.ccFeatUpd.data.mwi_status.hpOldCount; - ccsnap_gen_lineEvent(CCAPI_LINE_EV_MWI, line_info->button); - } - //Added for automation test - NOTIFY_LINE_DEBUG(DEB_NOTIFY_PREFIX"[line=%d][state=%s]", - "MWIChanged", featUpd->update.ccFeatUpd.data.mwi_status.line, - (featUpd->update.ccFeatUpd.data.mwi_status.status)?"ON":"OFF"); - - break; - case DEVICE_FEATURE_MWILAMP: - g_deviceInfo.mwi_lamp = featUpd->update.ccFeatUpd.data.state_data.state; - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_MWI_LAMP, CC_DEVICE_ID); - break; - case DEVICE_FEATURE_BLF: - sub_hndlr_NotifyBLFStatus(featUpd->update.ccFeatUpd.data.blf_data.request_id, - featUpd->update.ccFeatUpd.data.blf_data.state, - featUpd->update.ccFeatUpd.data.blf_data.app_id); - break; - case DEVICE_FEATURE_MNC_REACHED: - line_info = ccsnap_getLineInfoFromBtn(featUpd->update.ccFeatUpd.data.line_info.line); - if ( line_info != NULL ) { - ccsnap_handle_mnc_reached(line_info, - featUpd->update.ccFeatUpd.data.line_info.info, gCCApp.mode); - ccsnap_gen_lineEvent(CCAPI_LINE_EV_CAPSET_CHANGED, line_info->button); - } - break; - case DEVICE_SERVICE_CONTROL_REQ: - reset_type = (cc_srv_ctrl_req_t) featUpd->update.ccFeatUpd.data.reset_type; - ccpro_handleserviceControlNotify(); - break; - case DEVICE_NOTIFICATION: - g_deviceInfo.not_prompt = ccsnap_EscapeStrToLocaleStr(g_deviceInfo.not_prompt, featUpd->update.ccFeatUpd.data.notification.prompt, LEN_UNKNOWN); - g_deviceInfo.not_prompt_prio = featUpd->update.ccFeatUpd.data.notification.priority; - g_deviceInfo.not_prompt_prog = featUpd->update.ccFeatUpd.data.notification.notifyProgress; - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_NOTIFYPROMPT, CC_DEVICE_ID); - break; - case DEVICE_LABEL_N_SPEED: - // todo - break; - case DEVICE_REG_STATE: - line_info = ccsnap_getLineInfoFromBtn(featUpd->update.ccFeatUpd.data.line_info.line); - if ( line_info != NULL ) { - line_info->reg_state = featUpd->update.ccFeatUpd.data.line_info.info; - ccsnap_gen_lineEvent(CCAPI_LINE_EV_REG_STATE, line_info->button); - } - break; - case DEVICE_CCM_CONN_STATUS: - ccsnap_update_ccm_status(featUpd->update.ccFeatUpd.data.ccm_conn.addr, - featUpd->update.ccFeatUpd.data.ccm_conn.status); - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_SERVER_STATUS, CC_DEVICE_ID); - break; - default: - DEF_DEBUG(DEB_F_PREFIX"Unknown event: id= %d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccappFeatureUpdated"), featUpd->featureID); - break; - - } - if ( featUpd->featureID == DEVICE_NOTIFICATION) { - strlib_free(featUpd->update.ccFeatUpd.data.notification.prompt); - } - - if ( featUpd->featureID == DEVICE_CCM_CONN_STATUS) { - strlib_free(featUpd->update.ccFeatUpd.data.ccm_conn.addr); - } - - if ( featUpd->featureID == DEVICE_FEATURE_CFWD) { - strlib_free(featUpd->update.ccFeatUpd.data.cfwd.cfa_num); - } - - if (featUpd->featureID == DEVICE_SYNC_CONFIG_VERSION) { - strlib_free(featUpd->update.ccFeatUpd.data.cfg_ver_data.cfg_ver); - strlib_free(featUpd->update.ccFeatUpd.data.cfg_ver_data.dp_ver); - strlib_free(featUpd->update.ccFeatUpd.data.cfg_ver_data.softkey_ver); - } - - if (featUpd->featureID == DEVICE_LABEL_N_SPEED) { - strlib_free(featUpd->update.ccFeatUpd.data.cfg_lbl_n_spd.speed); - strlib_free(featUpd->update.ccFeatUpd.data.cfg_lbl_n_spd.label); - } - -} - -/** - * - * CCApp Provider wrapper for synchronous calls. - * - * @param sessMgmt - session management message - * - * @return void - * - * @pre None - */ -void ccappSyncSessionMgmt(session_mgmt_t *sessMgmt) -{ - cc_line_info_t *line_info; - CCAPP_DEBUG(DEB_F_PREFIX"ccappSyncSessionMgmt: func_id=%d \n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccappSyncSessionMgmt"), - sessMgmt->func_id); - - //sessionMgmt(sessMgmt); - switch (sessMgmt->func_id) { - case SESSION_MGMT_SET_TIME: - g_deviceInfo.reg_time = sessMgmt->data.time.gmt_time; - CCAPP_DEBUG(DEB_F_PREFIX"Setting reg_time to == %lld\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, - "ccappSyncSessionMgmt"), g_deviceInfo.reg_time); - platSetCucmRegTime(); - break; - case SESSION_MGMT_GET_PHRASE_TEXT: - sessMgmt->data.phrase_text.ret_val = - platGetPhraseText(sessMgmt->data.phrase_text.ndx, - sessMgmt->data.phrase_text.outstr, - sessMgmt->data.phrase_text.len); - break; - case SESSION_MGMT_GET_UNREG_REASON: - sessMgmt->data.unreg_reason.unreg_reason = platGetUnregReason(); - break; - case SESSION_MGMT_UPDATE_KPMLCONFIG: - platSetKPMLConfig(sessMgmt->data.kpmlconfig.kpml_val); - break; - case SESSION_MGMT_GET_AUDIO_DEVICE_STATUS: - //Noop - break; - case SESSION_MGMT_CHECK_SPEAKER_HEADSET_MODE: - //Noop - break; - case SESSION_MGMT_LINE_HAS_MWI_ACTIVE: - line_info = ccsnap_getLineInfoFromBtn(sessMgmt->data.line_mwi_active.line); - if (line_info != NULL) { - sessMgmt->data.line_mwi_active.ret_val = line_info->mwi.status; - } - break; - case SESSION_MGMT_APPLY_CONFIG: - // save the proposed versions of fcp and dialplan to apply. Will check against - // current versions and redownload if necessary - - if (pending_action_type == NO_ACTION) { - configApplyConfigNotify(sessMgmt->data.config.config_version_stamp, - sessMgmt->data.config.dialplan_version_stamp, - sessMgmt->data.config.fcp_version_stamp, - sessMgmt->data.config.cucm_result, - sessMgmt->data.config.load_id, - sessMgmt->data.config.inactive_load_id, - sessMgmt->data.config.load_server, - sessMgmt->data.config.log_server, - sessMgmt->data.config.ppid); - } - break; - default: - break; - } - freeSessionMgmtData(sessMgmt); - -} - -/** - * ccCreateSession - * - * Called to create a CC session - * - * @param param - ccSession_create_param_t - * Contains the type of session and specific data - * - * @return ccSession_id_t - id of the session created - */ -session_id_t createSessionId(line_t line, callid_t call) -{ - return ( SESSIONTYPE_CALLCONTROL << SID_TYPE_SHIFT ) + - (line << SID_LINE_SHIFT ) + call; -} - -/** - * getLineIdAndCallId - * - * get Line and call_id - * - * @param *line_id - * @param *call_id - * - */ -void getLineIdAndCallId (line_t *line_id, callid_t *call_id) -{ - // assign proper line_id and call_id if not already there - if ((*line_id) == 0 || (*line_id) == CC_ALL_LINES) { - /* - * If the filter is the All Calls Complex Filter and the primary line - * is at its configured call capacity, the next available line should - * be used. In this scenario, sessionUI/Mgr send the line_id as zero. - */ - (*line_id) = lsm_get_available_line(FALSE); - } - - if ((*call_id) == 0) { - (*call_id) = cc_get_new_call_id(); - } -} diff --git a/libs/sipcc/core/ccapp/conf_roster.c b/libs/sipcc/core/ccapp/conf_roster.c deleted file mode 100644 index 2cb1f268d9..0000000000 --- a/libs/sipcc/core/ccapp/conf_roster.c +++ /dev/null @@ -1,401 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "sll_lite.h" -#include "cc_constants.h" -#include "cc_types.h" -#include "cc_config.h" -#include "phone_debug.h" -#include "debug.h" -#include "CCProvider.h" -#include "ccapi_call_info.h" -#include "conf_roster.h" -#include "ccapi.h" -#include "ccapp_task.h" - -cc_conf_participant_status_t -convertStringToParticipantStatus(const char *data) -{ - if (strcmp(data, "connected") == 0) { - return CCAPI_CONFPARTICIPANT_CONNECTED; - } else if (strcmp(data, "alerting") == 0) { - return CCAPI_CONFPARTICIPANT_ALERTING; - } else if (strcmp(data, "dialing-out") == 0) { - return CCAPI_CONFPARTICIPANT_DIALING_OUT; - } else if (strcmp(data, "on-hold") == 0) { - return CCAPI_CONFPARTICIPANT_ON_HOLD; - } else if (strcmp(data, "disconnected") == 0) { - return CCAPI_CONFPARTICIPANT_DISCONNECTED; - } else { - return CCAPI_CONFPARTICIPANT_UNKNOWN; - } -} - -cc_call_security_t -convertStringToParticipantSecurity(const char *data) -{ - - if (strcmp(data, "NotAuthenticated") == 0) { - return CC_SECURITY_NOT_AUTHENTICATED; - } else if (strcmp(data, "Authenticated") == 0) { - return CC_SECURITY_AUTHENTICATED; - } else if (strcmp(data, "Encrypted") == 0) { - return CC_SECURITY_ENCRYPTED; - } else if (strcmp(data, "Unknown") == 0) { - return CC_SECURITY_UNKNOWN; - } else { - return CC_SECURITY_NONE; - } -} - - -void conf_roster_init_call_conference (cc_call_conference_Info_t *info) -{ - CCAPP_DEBUG(DEB_F_PREFIX"in init_call_conference \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - - info->participantMax = 0; - info->participantCount = 0; - info->myParticipantId = strlib_empty(); - - sll_lite_init(&info->currentParticipantsList); -} - -void conf_roster_free_call_conference (cc_call_conference_Info_t *confInfo) -{ - cc_call_conferenceParticipant_Info_t *participant; - - CCAPP_DEBUG(DEB_F_PREFIX"in free_call_confrerence \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - - while((participant=(cc_call_conferenceParticipant_Info_t *) - sll_lite_unlink_head(&confInfo->currentParticipantsList)) != NULL) - { - strlib_free(participant->participantName); - strlib_free(participant->endpointUri); - strlib_free(participant->callid); - strlib_free(participant->participantNumber); - - participant->participantSecurity = CC_SECURITY_NONE; - participant->participantStatus = CCAPI_CONFPARTICIPANT_UNKNOWN; - participant->canRemoveOtherParticipants = FALSE; - - cpr_free(participant); - participant = NULL; - } - - strlib_free(confInfo->myParticipantId); - conf_roster_init_call_conference(confInfo); -} - -void conf_roster_copy_call_conferance (cc_call_conference_Info_t *dest, cc_call_conference_Info_t * src) -{ - cc_call_conferenceParticipant_Info_t *destParticipant; - cc_call_conferenceParticipant_Info_t *srcParticipant; - sll_lite_node_t *iterator; - sll_lite_return_e sll_ret_val; - - CCAPP_DEBUG(DEB_F_PREFIX"in copy_call_confrerence \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - - iterator = src->currentParticipantsList.head_p; - conf_roster_init_call_conference(dest); - - dest->participantMax = src->participantMax; - dest->participantCount = src->participantCount; - dest->myParticipantId = strlib_copy(src->myParticipantId); - - while (iterator) { - srcParticipant = (cc_call_conferenceParticipant_Info_t *)iterator; - - destParticipant = cpr_malloc(sizeof(cc_call_conferenceParticipant_Info_t)); - if (destParticipant == NULL) { - CCAPP_ERROR(DEB_F_PREFIX" Malloc failure for participant\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - return; - } else { - destParticipant->participantName = strlib_copy(srcParticipant->participantName); - destParticipant->endpointUri = strlib_copy(srcParticipant->endpointUri); - destParticipant->callid = strlib_copy(srcParticipant->callid); - - destParticipant->participantNumber = strlib_copy(srcParticipant->participantNumber); - destParticipant->participantSecurity = srcParticipant->participantSecurity; - destParticipant->participantStatus = srcParticipant->participantStatus; - destParticipant->canRemoveOtherParticipants = srcParticipant->canRemoveOtherParticipants; - } - - sll_ret_val = sll_lite_link_tail(&dest->currentParticipantsList, (sll_lite_node_t *)destParticipant); - if (sll_ret_val != SLL_LITE_RET_SUCCESS) { - CCAPP_ERROR(DEB_F_PREFIX" Error while trying to insert in the linked list\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE")); - cpr_free(destParticipant); - return; - } - - iterator = iterator->next_p; - } -} - -// ------------------- -// API Implementation -// ------------------- - -/** -* Get Conference Participants -* @param [in] handle - call handle -* @param [in/out] participantHandles - array of participant handles to be returned -* @param [in/out] count - in: size of array provided in participantHandles; out: number of entries populated (up to original value provided) -* @return void -*/ -void CCAPI_CallInfo_getConfParticipants (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandles[], int* count) -{ - cc_call_conference_ref_t callConference = NULL; // conference reference (from call info) - cc_call_conference_participant_ref_t participant = NULL; // participant reference - cc_uint16_t participantIndex = 0; // participant index - cc_uint16_t nodeCount = 0; // linked list node count - - CCAPP_DEBUG(DEB_F_PREFIX"Entering: CCAPI_CallInfo_getConfParticipants\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference handle\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - *count = 0; - return; - } - - nodeCount = SLL_LITE_NODE_COUNT(&(callConference->currentParticipantsList)); - CCAPP_DEBUG(DEB_F_PREFIX"SLL NODE COUNT = [%d]\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF"), nodeCount); - if (nodeCount <= 0) - { - *count = 0; - return; - } - - participant = (cc_call_conference_participant_ref_t)SLL_LITE_LINK_HEAD(&callConference->currentParticipantsList); - while (participant != NULL) - { - if (participantIndex >= *count) - { - CCAPP_ERROR(DEB_F_PREFIX"Not Enough Room Provided To List All Participants. Listed [%d] of [%d]\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF"), count, nodeCount); - return; - } - - // add this participant to our list of particpiants - participantHandles[participantIndex] = (participant->callid); - - // step to the next stored participant in the list - participant = (cc_call_conference_participant_ref_t)SLL_LITE_LINK_NEXT_NODE(participant); - participantIndex++; - } - - // sanity check - if (participantIndex != nodeCount) - { // did not find the expected number of participants! - CCAPP_ERROR(DEB_F_PREFIX"Detected mismatch between counted participants [%d] and SLL returned nodecount [%d]\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF"), - participantIndex, nodeCount); - *count = 0; - return; - } - - // return number of participants - *count = nodeCount; - return; -} - -/** -* Get Maximum Number of Conference Participants ( in case gui wants to show %full conference info ) -* @param [in] handle - call handle -* @return maximum number of conference participants -*/ -cc_uint16_t CCAPI_CallInfo_getConfParticipantMax (cc_callinfo_ref_t handle) -{ // - cc_call_conference_ref_t callConference; // conference reference (from call info) - - CCAPP_DEBUG(DEB_F_PREFIX"Entering: CCAPI_CallInfo_getConfParticipantMax\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - // no conference reference available - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference reference\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (0); - } - - // return the max - return (callConference->participantMax); -} - -/** -* Get Participant Name -* @param [in] handle - call info handle -* @param [in] participantHandle - specific handle for conference participant -* @return display name of the conference participant -*/ -cc_string_t CCAPI_CallInfo_getConfParticipantName (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_participant_ref_t participant = getConferenceParticipantRef (handle, participantHandle); - if (participant == NULL) - { - return strlib_empty(); - } - - return (participant->participantName); -} - -/** -* Get Participant Number -* @param [in] handle - handle of call -* @param [in] participantHandle - handle of conference participant -* @return display number of the conference participant -*/ -cc_string_t CCAPI_CallInfo_getConfParticipantNumber (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_participant_ref_t participant = getConferenceParticipantRef (handle, participantHandle); - if (participant == NULL) - { - return strlib_empty(); - } - - return (participant->participantNumber); -} - -/** -* Get Conference Participant Status -* @param [in] handle - call handle -* @param [in] participantHandle - handle of conference participant -* @return conference participant status -*/ -cc_conf_participant_status_t CCAPI_CallInfo_getConfParticipantStatus (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_participant_ref_t participant = getConferenceParticipantRef (handle, participantHandle); - if (participant == NULL) - { - return (CCAPI_CONFPARTICIPANT_UNKNOWN); - } - - return (participant->participantStatus); -} - -/** -* Get Participant Security -* @param [in] handle - call handle -* @param [in] participantHandle - handle of conference participant -* @return security setting of the specific conference participant -*/ -cc_call_security_t CCAPI_CallInfo_getConfParticipantSecurity (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_participant_ref_t participant = getConferenceParticipantRef (handle, participantHandle); - if (participant == NULL) - { - return (CC_SECURITY_NONE); - } - - return (participant->participantSecurity); -} - -/** -*/ -cc_boolean CCAPI_CallInfo_isConfSelfParticipant (cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_ref_t callConference; // conference reference (from call info) - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - // error - log - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference reference\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (FALSE); - } - - return (strcmp((callConference->myParticipantId), participantHandle) == 0); -} - -/** -*/ -cc_participant_ref_t CCAPI_CallInfo_getConfSelfParticipant (cc_callinfo_ref_t handle) -{ - cc_call_conference_ref_t callConference; // conference reference (from call info) - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - // unexpected error - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference reference\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return strlib_empty(); - } - - return (callConference->myParticipantId); -} - -// ----- -/** - * Get the call conference reference - * @param [in] handle - call info handle - * @return cc_call_conference_Info_t - */ -cc_call_conference_ref_t getCallConferenceRef(cc_callinfo_ref_t handle) -{ - session_data_t *data = (session_data_t *)handle; - - if (!CCAPI_CallInfo_getIsConference(handle)) - { - CCAPP_ERROR(DEB_F_PREFIX"Conference API Invoked, but Not In Conference Call\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); - }; - - if (data == NULL) - { - return (NULL); - } - - return (&data->call_conference); -} - -// ------------------------------------------------------------------------------------------------------------------ -// getConferenceParticipantRef: returns participant ref (pointer) to a specific participant handle -// ------------------------------------------------------------------------------------------------------------------ -cc_call_conference_participant_ref_t getConferenceParticipantRef(cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle) -{ - cc_call_conference_ref_t callConference; // conference reference (from call info) - cc_call_conference_participant_ref_t participant; - - // get conference reference from the call info - callConference = getCallConferenceRef(handle); - if (callConference == NULL) - { - // no conference reference available - CCAPP_ERROR(DEB_F_PREFIX"Unable to get conference reference\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); - } - - // see if participantHandle is legit... - if (participantHandle == NULL) - { - CCAPP_DEBUG(DEB_F_PREFIX"Received query for null participant\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); - } - - if (SLL_LITE_NODE_COUNT(&(callConference->currentParticipantsList)) <= 0) - { - CCAPP_ERROR(DEB_F_PREFIX"Participant list node count is 0, returning NULL\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); - } - - participant = (cc_call_conference_participant_ref_t)SLL_LITE_LINK_HEAD(&callConference->currentParticipantsList); - while (participant != NULL) - { - // see if we've found the participant we're looking for - if (strcmp(participant->callid, participantHandle) == 0) - { - return (participant); - } - - // no match so far, so look at the next item in the list... - participant = (cc_call_conference_participant_ref_t)SLL_LITE_LINK_NEXT_NODE(participant); - } - - CCAPP_ERROR(DEB_F_PREFIX" Did Not Find participant!\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONF")); - return (NULL); -} diff --git a/libs/sipcc/core/ccapp/conf_roster.h b/libs/sipcc/core/ccapp/conf_roster.h deleted file mode 100644 index 4eda1bca14..0000000000 --- a/libs/sipcc/core/ccapp/conf_roster.h +++ /dev/null @@ -1,49 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CONFROSTER_H__ -#define __CONFROSTER_H__ - -#include "sll_lite.h" -#include "cpr_string.h" -#include "cc_constants.h" -#include "cpr_stdio.h" -#include "ccapi_conf_roster.h" - -// structure for individual participant/user info -typedef struct cc_call_conferenceParticipant_Info_t_ { - sll_lite_node_t node; - cc_participant_ref_t callid; - string_t participantName; - string_t participantNumber; - cc_conf_participant_status_t participantStatus; - cc_call_security_t participantSecurity; - string_t endpointUri; - cc_boolean canRemoveOtherParticipants; -} cc_call_conferenceParticipant_Info_t; - -// reference to above structure -typedef struct cc_call_conferenceParticipant_Info_t_* cc_call_conference_participant_ref_t; - -// main structure (one instance kept per conference (per call)) -typedef struct cc_call_conference_Info_t_ { - int32_t participantMax; - int32_t participantCount; - cc_participant_ref_t myParticipantId; - sll_lite_list_t currentParticipantsList; -} cc_call_conference_Info_t; - -// reference to above structure -typedef struct cc_call_conference_Info_t_* cc_call_conference_ref_t; - -void conf_roster_init_call_conference (cc_call_conference_Info_t *info); -cc_call_conference_ref_t getCallConferenceRef(cc_callinfo_ref_t handle); -cc_call_conference_participant_ref_t getConferenceParticipantRef(cc_callinfo_ref_t handle, cc_participant_ref_t participantHandle); -void conf_roster_free_call_conference (cc_call_conference_Info_t *confInfo); -void conf_roster_copy_call_conferance (cc_call_conference_Info_t *dest, cc_call_conference_Info_t * src); - -#endif - - - diff --git a/libs/sipcc/core/ccapp/sessionHash.c b/libs/sipcc/core/ccapp/sessionHash.c deleted file mode 100755 index 972a5cd385..0000000000 --- a/libs/sipcc/core/ccapp/sessionHash.c +++ /dev/null @@ -1,305 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef UNIT_TEST -#define cpr_malloc malloc -#define cpr_free free -#define CCAPP_DEBUG printf -#else -#include "cpr_stdlib.h" -#endif - -#include "sessionHash.h" - -#define HASHBUCKETS 67 - -hash_table_t *hashtable[HASHBUCKETS]={0}; - -void hashItrInit(hashItr_t *itr) -{ - itr->bucket = 0; - itr->node = NULL; -} - -void * hashItrNext(hashItr_t *itr) -{ - int i; - - if ( itr->node != NULL ) { - if ( itr->node->next != NULL ) { - itr->node = itr->node->next; - return itr->node->data; - } - // We just iterated to the end of the list. - // Increment the bucket to search next - itr->bucket++; - } - - for(i=itr->bucket; i< HASHBUCKETS; i++) { - if (hashtable[i] != NULL) { - itr->bucket = i; - itr->node = hashtable[i]; - return itr->node->data; - } - } - return NULL; -} - - -/** - * sessionHash - * function to add generate hash given the key - * - * @param key - - * - * @return the hash index - */ -unsigned int sessionHash (unsigned int key) -{ - // since the key is session_id create the hashval to be line_id + call_id - unsigned int hashval = key + ((key & 0xFFFF0000)>>16); - - return hashval%67; -} - -/** - * addhash - * function to add data for a given key in the table - * - * @param key - * @param data - pointer to data stored - * - * @return - 0 for success - */ - -int addhash (unsigned int key, void *data) -{ - hash_table_t *newhash; - hash_table_t *cur_hash; - unsigned int hashval; - - newhash = (hash_table_t *)(cpr_malloc(sizeof(hash_table_t))); - if (newhash == NULL) { - return -1; - } - - newhash->key = key; - - newhash->data = data; - - hashval = sessionHash(key); - - if (hashtable[hashval] == NULL) { - hashtable[hashval] = newhash; - hashtable[hashval]->prev = NULL; - hashtable[hashval]->next = NULL; - } - else { - cur_hash=hashtable[hashval]; - while(cur_hash->next != NULL) { - cur_hash=cur_hash->next; - } - cur_hash->next = newhash; - newhash->next = NULL; - newhash->prev = cur_hash; - } - - return 0; -} - -/** - * returns the session id given a callid - * @param call_id - * @return sessionID or 0 - */ - -unsigned int ccpro_get_sessionId_by_callid(unsigned short call_id) { - int i; - hash_table_t *cur_hash; - - for ( i=0; ikey & 0xffff) == call_id ) { - return cur_hash->key; - } - cur_hash = cur_hash->next; - } - } - return 0; -} - - -/** - * findhash - * function retrieve the data for the given key - * - * @param key - * - * @return the data ptr or NULL - */ - -void *findhash(unsigned int key) -{ - unsigned int hashval; - hash_table_t *cur_hash; - - hashval = 0; - - hashval = sessionHash(key); - - - cur_hash = hashtable[hashval]; - while ( cur_hash != NULL ) { - if ( cur_hash->key == key) { - return cur_hash->data; - } - cur_hash = cur_hash->next; - } - - return NULL; -} - -/** - * delhash - * function to remove the hash entry for a given key - * - * @param key - * - * @return - 0 for success - */ - -int delhash(unsigned int key) -{ - unsigned int hashval; - hash_table_t *cur_hash; - - hashval = 0; - - hashval = sessionHash(key); - - - if (hashtable[hashval] == NULL) { - return -1; - } - - if (hashtable[hashval]->key == key) { - cur_hash = hashtable[hashval]; - hashtable[hashval] = cur_hash->next; - if ( hashtable[hashval] != NULL ) { - hashtable[hashval]->prev = NULL; - } - cpr_free(cur_hash); - return 0; - } - else { - - cur_hash = hashtable[hashval]->next; - - while (cur_hash != NULL) { - if (cur_hash->key == key) { - cur_hash->prev->next = cur_hash->next; - if (cur_hash->next != NULL) { - cur_hash->next->prev = cur_hash->prev; - } - cpr_free(cur_hash); - return 0; - } - cur_hash = cur_hash->next; - } - } - return -1; -} - -#ifdef UNIT_TEST - -void hashstats(int detail) -{ - static const char *fname="hashstats"; - int max, total, i, nodes, used; - double avg; - hash_table_t *cur_hash; - - max = total = i = nodes = used = 0; - avg = 0; - - if (detail > 0) { - for (i = 0; i < HASHBUCKETS; i++) { - if (hashtable[i] != NULL) { - used++; - nodes = 0; - cur_hash = hashtable[i]; - while(cur_hash != NULL) { - nodes++; - if (detail > 3) { - CCAPPDEBUG(DEB_F_PREFIX"%lx -> %lx: (%lx) (%lx) -> %lx\n", - DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), - cur_hash->prev, cur_hash, cur_hash->key, cur_hash->data, cur_hash->next); - } - cur_hash = cur_hash->next; - } - if (nodes != 0) total += nodes; - if (nodes > max) { - max = nodes; - } - if (detail > 1) { - CCAPPDEBUG(DEB_F_PREFIX"i: %d\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), i); - } - } - } - avg = (double)(total) / (double)(used); - CCAPPDEBUG(DEB_F_PREFIX"total: %d\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), total); - CCAPPDEBUG(DEB_F_PREFIX"max: %d\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), max); - CCAPPDEBUG(DEB_F_PREFIX"used: %lf\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), 100 * ((double)(used) / (double)(HASHBUCKETS))); - CCAPPDEBUG(DEB_F_PREFIX"average: %lf\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), avg); - } -} - -int main() -{ - static const char *fname="main"; - hashItr_t itr; - void * data; - - addhash(0x01010001,0x1234); - addhash(0x01060001,0x4567); - addhash(0x01060002,0x9324); - addhash(0x01070002,0x4321); - addhash(0x01070004,0x2134); - addhash(0x01080005,0x1324); - addhash(0x01030001,0x1243); - hashstats(7); - - hashItrInit(&itr); - while ( data = hashItrNext(&itr) ) { - CCAPPDEBUG(DEB_F_PREFIX"Itr found %lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), data); - } - - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01010001)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060001)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060002)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070002)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070004)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01080005)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01030001)); - - delhash(0x01030001); - delhash(0x01060001); - hashstats(7); - - hashItrInit(&itr); - while ( data = hashItrNext(&itr) ) { - CCAPPDEBUG(DEB_F_PREFIX"Itr found %lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HAS, fname), data); - } - - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01010001)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060001)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060002)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070002)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070004)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01080005)); - CCAPPDEBUG(DEB_F_PREFIX"%lx\n", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01030001)); -} -#endif - diff --git a/libs/sipcc/core/ccapp/sessionHash.h b/libs/sipcc/core/ccapp/sessionHash.h deleted file mode 100755 index 4722bb4de5..0000000000 --- a/libs/sipcc/core/ccapp/sessionHash.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -typedef struct hash_table { - struct hash_table *next; - struct hash_table *prev; - unsigned int key; - void *data; -} hash_table_t; - -typedef struct { - unsigned int bucket; - hash_table_t *node; -} hashItr_t; - - -extern void hashItrInit(hashItr_t *itr) ; -extern void * hashItrNext(hashItr_t *itr); -extern int addhash (unsigned int key, void *data) ; -extern int delhash(unsigned int key); -extern void *findhash(unsigned int key); -extern unsigned int ccpro_get_sessionId_by_callid(unsigned short call_id); diff --git a/libs/sipcc/core/common/cfgfile_utils.c b/libs/sipcc/core/common/cfgfile_utils.c deleted file mode 100755 index a31f80235b..0000000000 --- a/libs/sipcc/core/common/cfgfile_utils.c +++ /dev/null @@ -1,415 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include -#include -#include -#include -#include "util_string.h" - -#define IN6ADDRSZ 16 -#define INT16SZ 2 -#define INADDRSZ 4 -#define IS_DIGIT(ch) ((ch >= '0') && (ch <= '9')) - -/* - * Parse ascii dotted ip address notation into binary representation - * only parses and makes sure the address is in the form: - * digits.digits.digits.digits - * Requires minimum of 1 digit per each section and digits cannot - * exceed 255. It does NOT attempt to validate if the end result - * is a valid ip address or not (eg. 0.0.0.0) is accepted. - * The parsed address is returned in the Telecaster "byte reversed" - * order. Eg. 0xf8332ca1 = 161.44.51.248 - */ -int -str2ip (const char *str, cpr_ip_addr_t *cpr_addr) -{ - uint32_t ip_addr; - unsigned int num; - int dot_cnt; - char ch; - int digit_flag; - uint32_t *addr = (uint32_t *)&(cpr_addr->u.ip4); - - dot_cnt = 0; - num = 0; - ip_addr = 0; - digit_flag = 0; - cpr_addr->type = CPR_IP_ADDR_INVALID; - - while (1) { - ch = *str++; - if (!ch) - break; /* end of string */ - /* - * Check for digits 0 through 9 - */ - if (IS_DIGIT(ch)) { - digit_flag = 1; - num = num * 10 + (ch - '0'); - if (num > 255) { - return (1); - } - continue; - } else if (ch == ':') { - //must be ipv6 address - cpr_addr->type = CPR_IP_ADDR_IPV6; - return(cpr_inet_pton(AF_INET6, str, addr)); - } - - /* - * Check for DOT. Must also have seen at least 1 digit prior - */ - if ((ch == '.') && (digit_flag)) { - dot_cnt++; - ip_addr = ((ip_addr << 8) | num); - num = 0; - digit_flag = 0; - continue; - } - - /* if get here invalid dotted IP character or missing digit */ - return (1); - } - - /* - * Must have seen 3 dots exactly and at least 1 trailing digit - */ - if ((dot_cnt != 3) || (!digit_flag)) { - return (1); - } - - ip_addr = ((ip_addr << 8) | num); - - ip_addr = ntohl(ip_addr); /* convert to Telecaster format */ - cpr_addr->type = CPR_IP_ADDR_IPV4; - *addr = ip_addr; - return (0); -} - - -/* - * Parse an IP address. - * If the IP address value is set to "" or to "UNPROVISIONED" it - * is set to its' default value. - */ -int -cfgfile_parse_ip (const var_t *entry, const char *value) -{ -// RAC - Defaults will need to be handled on the Java Side. -// if ((*value == NUL) || (cpr_strcasecmp(value, "UNPROVISIONED") == 0)) { -// cfgfile_set_default(entry); -// return (0); -// } else { - return (str2ip(value, (cpr_ip_addr_t *) entry->addr)); -// } -} - -/* - * Print (format) an IP address. - * The IP address to be printed is in the Telecaster "byte reversed" - * order. Eg. 0xf8332ca1 = 248.51.44.161 - */ -int -cfgfile_print_ip (const var_t *entry, char *buf, int len) -{ - // RT phones receive the IP address in this order: 0xf8332ca1 = 161.44.51.248 - cpr_ip_addr_t *cprIpAddrPtr = (cpr_ip_addr_t *)entry->addr; - - if (cprIpAddrPtr->type == CPR_IP_ADDR_IPV4) { - sprint_ip(buf, cprIpAddrPtr->u.ip4); - return 1; - } - - return 0; -} - -/* - * Print (format) an IP address. - * The IP address to be printed is in the non-Telecaster "byte reversed" - * order - which is really network order. Eg. 0xa12c33f8 = 161.44.51.248 - */ -int -cfgfile_print_ip_ntohl (const var_t *entry, char *buf, int len) -{ - uint32_t ip; - - ip = *(uint32_t *) entry->addr; - return (snprintf(buf, len, get_debug_string(DEBUG_IP_PRINT), - ((ip >> 24) & (0xff)), ((ip >> 16) & (0xff)), - ((ip >> 8) & (0xff)), ((ip >> 0) & (0xff)))); -} - -/* - * parse (copy) an ascii string - */ -int -cfgfile_parse_str (const var_t *entry, const char *value) -{ - int str_len; - - /* fixme: this could use malloc, or offer a different */ - /* fixme: parser routine that does like parse_str_ptr */ - /* fixme: in that case, free the old string and */ - /* fixme: strdup the new string */ - - str_len = strlen(value); - if (str_len + 1 > entry->length) { - err_msg(get_debug_string(DEBUG_PARSER_STRING_TOO_LARGE), - entry->length, str_len); - return (1); - } - - /* - * Copy string into config block - */ - sstrncpy((char *)entry->addr, value, entry->length); - return (0); - - -} - -/* - * Print (format) at string - */ -int -cfgfile_print_str (const var_t *entry, char *buf, int len) -{ - return (snprintf(buf, len, "%s", (char *)entry->addr)); -} - -/* - * Parse an ascii integer into binary - */ -int -cfgfile_parse_int (const var_t *entry, const char *value) -{ - unsigned int num; - char ch; - - num = 0; - - if (strcmp(value, "UNPROVISIONED") == 0) { - num = 0; - } else { - while (1) { - ch = *value++; - if (!ch) - break; /* end of string */ - /* - * Check for digits 0 through 9 - */ - if (IS_DIGIT(ch)) { - num = num * 10 + (ch - '0'); - continue; - } - - /* if get here invalid decimal character */ - return (1); - } - } - switch (entry->length) { - case 1: - *(uint8_t *) entry->addr = (uint8_t) num; - break; - case 2: - *(uint16_t *) entry->addr = (uint16_t) num; - break; - case 4: - *(uint32_t *) entry->addr = num; - break; - default: - *(unsigned int *) entry->addr = num; - break; - } - - return (0); -} - -/* - * print (format) an Integer - */ -int -cfgfile_print_int (const var_t *entry, char *buf, int len) -{ - unsigned int value; - - switch (entry->length) { - case 1: - value = *(uint8_t *) entry->addr; - break; - case 2: - value = *(uint16_t *) entry->addr; - break; - case 4: - value = *(uint32_t *) entry->addr; - break; - default: - value = *(unsigned int *) entry->addr; - break; - } - return (snprintf(buf, len, "%u", value)); -} - -/* - * Parse a keytable. A key table is a list of keywords. For each - * keyword there is an associated enum value (key value). - * search the keyword table for a matching keyword, and if found - * set the variable to the matching emum value. - */ -int -cfgfile_parse_key (const var_t *entry, const char *value) -{ - const key_table_entry_t *keytable; - - keytable = entry->key_table; - - if (keytable == NULL) { - err_msg(get_debug_string(DEBUG_PARSER_NULL_KEY_TABLE)); - return (1); - } - -// RAC - This (If Needed) Will need to be moved to the Java Side. -// /* check for nulled out keys and set to the default value */ -// if ((cpr_strcasecmp(value,"UNPROVISIONED") == 0) || -// (value[0] == 0)) { -// err_msg(get_debug_string(DEBUG_PARSER_SET_DEFAULT), -// entry->name, entry->default_value); -// cfgfile_set_default(entry); -// return(0); -// } - - while (keytable->name) { - if (cpr_strcasecmp(value, keytable->name) == 0) { - *(unsigned int *) entry->addr = keytable->value; - return (0); - } - keytable++; - } - - err_msg(get_debug_string(DEBUG_PARSER_UNKNOWN_KEY), value); - return (1); -} - -/* - * print (format) a key value. Search the table for the matching - * enum type, then format as output the keyname associated with it. - */ -int -cfgfile_print_key (const var_t *entry, char *buf, int len) -{ - const key_table_entry_t *keytable; - int value; - - keytable = entry->key_table; - value = *(int *) entry->addr; - - while (keytable->name) { - if (value == keytable->value) { - return (snprintf(buf, len, "%s", keytable->name)); - } - keytable++; - } - - err_msg(get_debug_string(DEBUG_PARSER_UNKNOWN_KEY_ENUM), value); - return (0); -} - -/* - * Sprintf an IP address in dotted notation. - */ -int -sprint_ip (char *buf, uint32_t ip) -{ - return (sprintf(buf, get_debug_string(DEBUG_IP_PRINT), - ((ip >> 0) & (0xff)), ((ip >> 8) & (0xff)), - ((ip >> 16) & (0xff)), ((ip >> 24) & (0xff)))); -} - -/* - * print (format) a MAC address - */ -int -cfgfile_print_mac (const var_t *entry, char *buf, int len) -{ - return (snprintf(buf, len, get_debug_string(DEBUG_MAC_PRINT), - ((uint8_t *) entry->addr)[0] * 256 + - ((uint8_t *) entry->addr)[1], - ((uint8_t *) entry->addr)[2] * 256 + - ((uint8_t *) entry->addr)[3], - ((uint8_t *) entry->addr)[4] * 256 + - ((uint8_t *) entry->addr)[5])); -} - -/** - * Parse a keytable. A key table is a list of keywords. For each - * keyword there is an associated enum value (key value). - * search the keyword table for a matching keyword, and if found - * save the entire key etnry into the table. - * - * @param[in] entry - pointer ot var_t. - * @param[in] value - pointer to const. string of configuration value. - * - * @return 1 - failed to parsed the configuration. - * 0 - succesfull parsed the configuration value. - * - * @pre (entry != NULL) - * @pre (value != NULL) - */ -int -cfgfile_parse_key_entry (const var_t *entry, const char *value) -{ - const key_table_entry_t *keytable; - - keytable = entry->key_table; - - if (keytable == NULL) { - err_msg(get_debug_string(DEBUG_PARSER_NULL_KEY_TABLE)); - return (1); - } - - while (keytable->name) { - if (cpr_strcasecmp(value, keytable->name) == 0) { - /* keep the entire entry */ - *(key_table_entry_t *)entry->addr = *keytable; - return (0); - } - keytable++; - } - - err_msg(get_debug_string(DEBUG_PARSER_UNKNOWN_KEY), value); - return (1); -} - -/** - * print (format) a key value. Print the name of the key out. - * - * @param[in] entry - pointer ot var_t. - * @param[in] value - pointer to const. string of configuration value. - * - * @return always return 0. - * - * @pre (entry != NULL) - * @pre (value != NULL) - */ -int -cfgfile_print_key_entry (const var_t *entry, char *buf, int len) -{ - key_table_entry_t *key; - - key = (key_table_entry_t *) entry->addr; - if (key->name != NULL) { - return (snprintf(buf, len, "%s", key->name)); - } else { - /* the entry is not even configured */ - return (0); - } -} diff --git a/libs/sipcc/core/common/cfgfile_utils.h b/libs/sipcc/core/common/cfgfile_utils.h deleted file mode 100755 index 63e5465326..0000000000 --- a/libs/sipcc/core/common/cfgfile_utils.h +++ /dev/null @@ -1,96 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CFGFILE_UTILS_H_ -#define _CFGFILE_UTILS_H_ - -#include "cpr_types.h" - -//============================================================================= -// -// Structure/Type definitions -// -//----------------------------------------------------------------------------- - -struct var_struct; - -typedef int (*parse_func_t)(const struct var_struct *, const char *); -typedef int (*print_func_t)(const struct var_struct *, char *, int); - -typedef struct { - const char *name; - int value; -} key_table_entry_t; - -#define NULL_KEY (-1) - -typedef struct var_struct { - const char *name; - void *addr; - int length; - parse_func_t parse_func; - print_func_t print_func; - const key_table_entry_t *key_table; -} var_t; - -/********************************************************* - * - * Config Table "Helper" Routines - * - * These #defines are routines that are called from the - * config table entries to parse (PA), print (PR), - * and export (XP), different config entries. These are the - * "common" helper routines. Protocol-specific routines - * are located in prot_configmgr_private.h - * - *********************************************************/ -#define PA_IP cfgfile_parse_ip -#define PR_IP cfgfile_print_ip -#define PR_IPN cfgfile_print_ip_ntohl -#define PA_STR cfgfile_parse_str -#define PR_STR cfgfile_print_str -#define PA_INT cfgfile_parse_int -#define PR_INT cfgfile_print_int -#define PA_KEY cfgfile_parse_key -#define PA_KEYE cfgfile_parse_key_entry -#define PR_KEY cfgfile_print_key -#define PR_KEYE cfgfile_print_key_entry -#define PR_MAC cfgfile_print_mac -#define XP_NONE 0 - -/********************************************************* - * - * Config Table "Helper" Macros - * - * These macros are used to help build the actual config - * table. They provide the address and length of the - * entries. They also tell which table the entry is - * stored in. - * - *********************************************************/ -#define CFGADDR(field) ((void*)&(prot_cfg_block.field)) -#define CFGLEN(field) (sizeof(prot_cfg_block.field)) -#define CFGVAR(field) CFGADDR(field),CFGLEN(field) - -/* generic config file parsing functions */ -int cfgfile_parse_ip(const var_t *, const char *value); -int cfgfile_parse_str(const var_t *, const char *value); -int cfgfile_parse_int(const var_t *, const char *value); -int cfgfile_parse_key(const var_t *, const char *value); -int cfgfile_parse_key_entry(const var_t *, const char *value); - -/* generic config file printing functions */ -int cfgfile_print_ip(const var_t *, char *buf, int); -int cfgfile_print_ip_ntohl(const var_t *, char *buf, int); -int cfgfile_print_str(const var_t *, char *buf, int); -int cfgfile_print_int(const var_t *, char *buf, int); -int cfgfile_print_key(const var_t *, char *buf, int); -int cfgfile_print_key_entry(const var_t *, char *buf, int); - -/* generic config file export (print) functions */ -int sprint_ip(char *, uint32_t ip); -int sprint_mac(char *, const unsigned char *ptr); -int cfgfile_print_mac(const var_t *entry, char *buf, int); - -#endif /* _CFGFILE_UTILS_H_ */ diff --git a/libs/sipcc/core/common/config_api.c b/libs/sipcc/core/common/config_api.c deleted file mode 100755 index 7007ddd61e..0000000000 --- a/libs/sipcc/core/common/config_api.c +++ /dev/null @@ -1,498 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "config.h" -#include "dns_utils.h" -#include "phone_debug.h" -#include "ccapi.h" -#include "debug.h" - -cc_int32_t ConfigDebug; - -/* - * This file contains the API routines that are used to - * access the config table. - * - * Avoid writing more of these routines. - * Try and reuse these routines as much as possible. - * - * We should be able to set and retrieve any type of value - * using one of these routines. - */ - - -/* - * Function: config_get_string() - * - * Description: Get any arbitrary config entry as a string - * - * Parameters: id - The id of the config string to get - * buffer - Empty buffer where string will be copied - * buffer_len - length of the buffer where string will be copied - * - * Returns: None - */ -void -config_get_string (int id, char *buffer, int buffer_len) -{ - const var_t *entry; - char *buf_start; - - /* - * Set the result to be empty in case we can't find anything - */ - buffer[0] = 0; - if ((id >= 0) && (id < CFGID_PROTOCOL_MAX)) { - entry = &prot_cfg_table[id]; - if (entry->length > buffer_len) { - CONFIG_ERROR(CFG_F_PREFIX"insufficient buffer: %d\n", "config_get_string", - id); - } else { - buf_start = buffer; - entry->print_func(entry, buffer, buffer_len); - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: get str: %s = %s\n", DEB_F_PREFIX_ARGS(CONFIG_API, "config_get_string"), id, entry->name, - buf_start); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"Invalid ID: %d\n", "config_get_string", id); - } -} - - -/* - * Function: config_set_string() - * - * Parameters: id - The id of the config string to set - * buffer - The new value for the string - * - * Description: Set any arbitrary config entry as a string - * - * Returns: None - */ -void -config_set_string (int id, char *buffer) -{ - const var_t *entry; - - if ((id >= 0) && (id < CFGID_PROTOCOL_MAX)) { - entry = &prot_cfg_table[id]; - if (entry->parse_func(entry, buffer)) { - /* Parse function returned an error */ - CONFIG_ERROR(CFG_F_PREFIX"Parse function failed. ID: %d %s:%s\n", "config_set_string", id, entry->name, buffer); - } else { - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s set str to %s\n", DEB_F_PREFIX_ARGS(CONFIG_API, "config_set_string"), id, entry->name, - buffer); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"Invalid ID: %d\n", "config_set_string", id); - } -} - -#define MAX_CONFIG_VAL_PRINT_LEN 256 -/* - * Function: print_config_value() - * - * Description: If debug is enabled then print value contained in - * the buffer. Cast and dereference the buffer ptr - * according to length. If no match to char, short, - * int or long then just print each byte (ex: MacAddr). - * Called by config_set/get_value() function. - * - * Parameters: id - the id of the config value to get - * get_set - config action (get val or set val) - * entry_name - config id name - * buffer - buffer containing the value - * length - number of bytes in the buffer - * - * Returns: none - */ -/* - * Some logical upper limit to avoid long print out in case - * of large length value - */ -void -print_config_value (int id, char *get_set, const char *entry_name, - void *buffer, int length) -{ - long long_val = 0; - int int_val = 0; - short short_val = 0; - char char_val = 0; - char str[MAX_CONFIG_VAL_PRINT_LEN]; - char *in_ptr; - char *str_ptr; - - if (length == sizeof(char)) { - char_val = *(char *) buffer; - long_val = (long) char_val; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %ld\n", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, - long_val); - } else if (length == sizeof(short)) { - short_val = *(short *) buffer; - long_val = (long) short_val; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %ld\n", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, - long_val); - } else if (length == sizeof(int)) { - int_val = *(int *) buffer; - long_val = (long) int_val; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %ld\n", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, - long_val); - } else if (length == sizeof(long)) { - long_val = *(long *) buffer; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %ld\n", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, - long_val); - } else if (length < MAX_CONFIG_VAL_PRINT_LEN / 2) { - - in_ptr = (char *) buffer; - str_ptr = &str[0]; - while (length--) { - sprintf(str_ptr++, "%02x", *in_ptr++); - str_ptr++; - } - *str_ptr = '\0'; - CONFIG_DEBUG(DEB_F_PREFIX"CFGID %d: %s: %s = %s\n", DEB_F_PREFIX_ARGS(CONFIG_API, "print_config_value"), id, get_set, entry_name, str); - } else { - CONFIG_ERROR(CFG_F_PREFIX"cfg_id = %d length too long -> %d\n", "print_config_value", - id, length); - } -} - -/* - * Function: config_get_value() - * - * Description: Get any arbitrary config entry as a raw data value. - * If the length doesn't match the actual length of the field, - * nothing will be copied. - * - * Parameters: id - The id of the config value to get - * buffer - Empty buffer where value will be copied - * length - The number of bytes to get - * - * Returns: None - */ -void -config_get_value (int id, void *buffer, int length) -{ - const var_t *entry; - - /* - * Retrieve raw entry from table..... - */ - if ((id >= 0) && (id < CFGID_PROTOCOL_MAX)) { - entry = &prot_cfg_table[id]; - if (length == entry->length) { - memcpy(buffer, entry->addr, entry->length); - - if (ConfigDebug) { - print_config_value(id, "Get Val", entry->name, buffer, length); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"%s size error\n", "config_get_value", - entry->name); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"Invalid ID: %d\n", "config_get_value", id); - } -} - - -/* - * Function: config_set_value() - * - * Description: Set arbitrary config entry as a raw data value. - * If the length doesn't match the actual length of the field, - * nothing will be copied. - * - * Parameters: id - The id of the config value to set - * buffer - The new value to be set - * length - The number of bytes to set - * - * Returns: None - */ -void -config_set_value (int id, void *buffer, int length) -{ - const var_t *entry; - - /* - * Retrieve entry from table..... - */ - if ((id >= 0) && (id < CFGID_PROTOCOL_MAX)) { - entry = &prot_cfg_table[id]; - if (entry->length != length) { - CONFIG_ERROR(CFG_F_PREFIX" %s size error entry size=%d, len=%d\n", - "config_set_value", entry->name, entry->length, length); - return; - } - memcpy(entry->addr, buffer, entry->length); - if (ConfigDebug) { - print_config_value(id, "Set Val", entry->name, buffer, length); - } - } else { - CONFIG_ERROR(CFG_F_PREFIX"Invalid ID: %d\n", "config_set_value", id); - } -} - -/* Function: get_printable_cfg() - * - * Description: prints the config value in the buf - * - * Parameters: indx, buf, len - * - * Returns: buf - */ -char * -get_printable_cfg(unsigned int indx, char *buf, unsigned int len) -{ - const var_t *table; - buf[0]=0; - - table = &prot_cfg_table[indx]; - // If this field has a password, print the param name, but NOT the - // real password - if (indx>=CFGID_LINE_PASSWORD && indx < CFGID_LINE_PASSWORD+MAX_CONFIG_LINES) { - // and add an invisible one - sstrncpy(buf, "**********", MAX_CONFIG_VAL_PRINT_LEN); - } else if ( table->print_func ) { - table->print_func(table, buf, len); - } - - if ( buf[0] == 0 ) { - sstrncpy(buf,"EMPTY", len); - } - return buf; -} - -/* - * Function: show_config_cmd() - * - * Description: Callback passed in the config init routine for show config - * - * Parameters: argc, argv - * - * Returns: zero(0) - */ - -cc_int32_t -show_config_cmd (cc_int32_t argc, const char *argv[]) -{ - const var_t *table; - char buf[MAX_CONFIG_VAL_PRINT_LEN]; - int i, feat; - - debugif_printf("\n%s\n", "------ Current *Cache* Configuration ------"); - table = prot_cfg_table; - - for ( i=0; i < CFGID_LINE_FEATURE; i++ ) { - if (table->print_func) { - table->print_func(table, buf, sizeof(buf)); - - // If this field has a password, print the param name, but NOT the - // real password - if (strstr(table->name, "Password") != 0) { - // and add an invisible one - sstrncpy(buf, "**********", sizeof(buf)); - } - debugif_printf("%s : %s\n", table->name, buf); - } - table++; - } - - debugif_printf("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", - prot_cfg_table[CFGID_LINE_INDEX].name, - prot_cfg_table[CFGID_LINE_FEATURE].name, - prot_cfg_table[CFGID_LINE_MAXNUMCALLS].name, - prot_cfg_table[CFGID_LINE_BUSY_TRIGGER].name, - prot_cfg_table[CFGID_PROXY_ADDRESS].name, - prot_cfg_table[CFGID_PROXY_PORT].name, - prot_cfg_table[CFGID_LINE_CALL_WAITING].name, - prot_cfg_table[CFGID_LINE_MSG_WAITING_LAMP].name, - prot_cfg_table[CFGID_LINE_MESSAGE_WAITING_AMWI].name, - prot_cfg_table[CFGID_LINE_RING_SETTING_IDLE].name, - prot_cfg_table[CFGID_LINE_RING_SETTING_ACTIVE].name, - prot_cfg_table[CFGID_LINE_NAME].name, - prot_cfg_table[CFGID_LINE_AUTOANSWER_ENABLED].name, - prot_cfg_table[CFGID_LINE_AUTOANSWER_MODE].name, - prot_cfg_table[CFGID_LINE_AUTHNAME].name, - prot_cfg_table[CFGID_LINE_PASSWORD].name, - prot_cfg_table[CFGID_LINE_DISPLAYNAME].name, - prot_cfg_table[CFGID_LINE_CONTACT].name); - - for (i=0; i< MAX_CONFIG_LINES; i++) { - config_get_value(CFGID_LINE_FEATURE+i, &feat, sizeof(feat)); - if ( feat != CC_FEATURE_NONE ){ - debugif_printf("%3s ", get_printable_cfg(CFGID_LINE_INDEX+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%4s ", get_printable_cfg(CFGID_LINE_FEATURE+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%3s ", get_printable_cfg(CFGID_LINE_MAXNUMCALLS+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%3s ", get_printable_cfg(CFGID_LINE_BUSY_TRIGGER+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%12s ", get_printable_cfg(CFGID_PROXY_ADDRESS+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_PROXY_PORT+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%3s ", get_printable_cfg(CFGID_LINE_CALL_WAITING+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%6s ", get_printable_cfg(CFGID_LINE_MSG_WAITING_LAMP+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%6s ", get_printable_cfg(CFGID_LINE_MESSAGE_WAITING_AMWI+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%6s ", get_printable_cfg(CFGID_LINE_RING_SETTING_IDLE+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%6s ", get_printable_cfg(CFGID_LINE_RING_SETTING_ACTIVE+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf(" %s ", get_printable_cfg(CFGID_LINE_NAME+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_AUTOANSWER_ENABLED+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_AUTOANSWER_MODE+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_AUTHNAME+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_PASSWORD+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s ", get_printable_cfg(CFGID_LINE_DISPLAYNAME+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - debugif_printf("%s\n", get_printable_cfg(CFGID_LINE_CONTACT+i, buf, MAX_CONFIG_VAL_PRINT_LEN)); - } - } - - return (0); -} - - -/********************************************** - * Line-Based Config API - **********************************************/ - -/* - * Function: config_get_line_id() - * - * Description: Given the line and the line-specific ID, this function - * will return the actual ID used to access the value in the - * config table. - * - * Parameters: id - The id config value to get - * line - The line that the ID is associated with - * - * Returns: TRUE if the entry is found - * FALSE otherwise. - */ -static int -config_get_line_id (int id, int line) -{ - int line_id = 0; - const var_t *entry; - - if ((line == 0) || (line > MAX_REG_LINES)) { - entry = &prot_cfg_table[id]; // XXX set but not used - (void) entry; - CONFIG_ERROR(CFG_F_PREFIX"ID=%d- line %d out of range\n", "config_get_line_id", id, line); - return (0); - } - line_id = id + line - 1; - - return (line_id); -} - - -/* - * Function: config_get_line_string() - * - * Description: Get any arbitrary line config entry as a string - * - * Parameters: id - The id of the config string to get - * buffer - Empty buffer where string will be copied - * line - The line that the ID is associated with - * buffer_len - length of the output buffer - * - * Returns: None - */ -void -config_get_line_string (int id, char *buffer, int line, int buffer_len) -{ - int line_id = 0; - - line_id = config_get_line_id(id, line); - if (line_id) { - config_get_string(line_id, buffer, buffer_len); - } -} - - -/* - * Function: config_set_line_string() - * - * Description: Set any arbitrary line config entry as a string - * - * Parameters: id - The id of the config string to set - * buffer - The new value for the string - * line - The line that the ID is associated with - * - * Returns: None - */ -void -config_set_line_string (int id, char *buffer, int line) -{ - int line_id = 0; - - line_id = config_get_line_id(id, line); - if (line_id) { - config_set_string(line_id, buffer); - } -} - -/* - * Function: config_get_line_value() - * - * Parameters: id - The id of the config value to get - * *buffer - Empty buffer where value will be copied - * length - The number of bytes to get - * line - The line that the ID is associated with - * - * Description: Get any arbitrary line config entry as a raw data value. - * If the length doesn't match the actual length of the field, - * nothing will be copied. - * - * Returns: None - */ -void -config_get_line_value (int id, void *buffer, int length, int line) -{ - int line_id = 0; - - line_id = config_get_line_id(id, line); - if (line_id) { - config_get_value(line_id, buffer, length); - } -} - -/* - * Function: config_set_line_value() - * - * Description: Set arbitrary config entry as a raw data value. - * If the length doesn't match the actual length of the field, - * nothing will be copied. - * - * Parameters: id - The id of the config value to set - * buffer - The new value to be set - * length - The number of bytes to set - * line - The line that the ID is associated with - * - * Returns: None - */ -void -config_set_line_value (int id, void *buffer, int length, int line) -{ - int line_id = 0; - - line_id = config_get_line_id(id, line); - if (line_id) { - config_set_value(line_id, buffer, length); - } -} - -/* - * Function: config_init() - * - * Description: Initialize the Config Debug command - * - * Parameters: none - * - * Returns: none - * - */ -void -config_init (void) -{ - /* Place holder for future init related actions */ -} diff --git a/libs/sipcc/core/common/config_parser.c b/libs/sipcc/core/common/config_parser.c deleted file mode 100644 index 2637268b26..0000000000 --- a/libs/sipcc/core/common/config_parser.c +++ /dev/null @@ -1,641 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "cc_constants.h" -#include "cc_types.h" -#include "cc_config.h" -#include "phone_debug.h" -#include "debug.h" -#include "ccapi.h" -#include "prot_configmgr.h" -#include "call_logger.h" -#include "sip_common_transport.h" -#include "sip_ccm_transport.h" -#include "config_parser.h" -#include "cc_device_feature.h" -#include "ccapi_snapshot.h" -#include "config_api.h" -#include "capability_set.h" -#include "util_string.h" - -#define MAC_ADDR_SIZE 6 -#define FILE_PATH 256 -#define MAX_MULTI_LEVEL_CONFIG 2 - -#define MLCFG_VIDEO_CAPABILITY 0 -#define MLCFG_CISCO_CAMERA 1 -#define MLCFG_CAPABILITY_MAX 2 -#define MLCFG_NOT_SET -1 - -#define VERSION_LENGTH_MAX 100 - -#define ID_BLOCK_PREF1 1 -#define ID_BLOCK_PREF3 3 -/* - * File location is hardcoded for getting mac and IP addr - */ -#define IP_ADDR_FILE "/sdcard/myip.txt" -static char autoreg_name[MAX_LINE_NAME_SIZE]; - -static char fcpTemplateFile[FILE_PATH] = ""; - -char g_cfg_version_stamp[MAX_CFG_VERSION_STAMP_LEN + 1] = {0}; -int line = -1; //initialize line to -1, as 0 is valid line -boolean apply_config = FALSE; -cc_apply_config_result_t apply_config_result = APPLY_CONFIG_NONE; -extern var_t prot_cfg_table[]; -void print_config_value (int id, char *get_set, const char *entry_name, void *buffer, int length); - -static int sip_port[MAX_CCM]; -static int secured_sip_port[MAX_CCM]; -static int security_mode = 3; /*SECURE*/ -extern accessory_cfg_info_t g_accessoryCfgInfo; - -// Configurable settings -static int gTransportLayerProtocol = 4; // 4 = tcp, 2 = udp -static boolean gP2PSIP = FALSE; -static boolean gSDPMODE = FALSE; -static boolean gRTPSAVPF = TRUE; /* TRUE = RTP/SAVPF , FALSE = RTP/SAVP */ -static int gVoipControlPort = 5060; -static int gCcm1_sip_port = 5060; - -/* - * This function determine whether the passed config parameter should be used - * in comparing the new and old config value for apply-config purpose. Only - * those config ids on whose change phone needs to restart are part of this - * function. For remaining parameters, it is assumed that any change can be - * applied dynamically. - * - */ -boolean is_cfgid_in_restart_list(int cfgid) { - - if ((cfgid >= CFGID_LINE_FEATURE && cfgid < (CFGID_LINE_FEATURE + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_INDEX && cfgid < (CFGID_LINE_INDEX + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_PROXY_ADDRESS && cfgid < (CFGID_PROXY_ADDRESS + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_PROXY_PORT && cfgid < (CFGID_PROXY_PORT + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_NAME && cfgid < (CFGID_LINE_NAME + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_DISPLAYNAME && cfgid < (CFGID_LINE_DISPLAYNAME + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_SPEEDDIAL_NUMBER && cfgid < (CFGID_LINE_SPEEDDIAL_NUMBER + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_MESSAGES_NUMBER && cfgid < (CFGID_LINE_MESSAGES_NUMBER + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FWD_CALLER_NAME_DIPLAY && cfgid < (CFGID_LINE_FWD_CALLER_NAME_DIPLAY + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY && cfgid < (CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY && cfgid < (CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY && cfgid < (CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_CALL_WAITING && cfgid < (CFGID_LINE_CALL_WAITING + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_AUTHNAME && cfgid < (CFGID_LINE_AUTHNAME + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_PASSWORD && cfgid < (CFGID_LINE_PASSWORD + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_FEATURE_OPTION_MASK && cfgid < (CFGID_LINE_FEATURE_OPTION_MASK + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_MSG_WAITING_LAMP && cfgid < (CFGID_LINE_MSG_WAITING_LAMP + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_MESSAGE_WAITING_AMWI && cfgid < (CFGID_LINE_MESSAGE_WAITING_AMWI + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_RING_SETTING_IDLE && cfgid < (CFGID_LINE_RING_SETTING_IDLE + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_RING_SETTING_ACTIVE && cfgid < (CFGID_LINE_RING_SETTING_ACTIVE + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_CONTACT && cfgid < (CFGID_LINE_CONTACT + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_MAXNUMCALLS && cfgid < (CFGID_LINE_MAXNUMCALLS + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_BUSY_TRIGGER && cfgid < (CFGID_LINE_BUSY_TRIGGER + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_AUTOANSWER_ENABLED && cfgid < (CFGID_LINE_AUTOANSWER_ENABLED + MAX_CONFIG_LINES)) || - (cfgid >= CFGID_LINE_AUTOANSWER_MODE && cfgid < (CFGID_LINE_AUTOANSWER_MODE + MAX_CONFIG_LINES)) - ) - { - return TRUE; - } - switch (cfgid) { - case CFGID_CCM1_ADDRESS: - case CFGID_CCM2_ADDRESS: - case CFGID_CCM3_ADDRESS: - case CFGID_CCM1_SIP_PORT: - case CFGID_CCM2_SIP_PORT: - case CFGID_CCM3_SIP_PORT: - - case CFGID_PROXY_BACKUP: - case CFGID_PROXY_BACKUP_PORT: - case CFGID_PROXY_EMERGENCY: - case CFGID_PROXY_EMERGENCY_PORT: - case CFGID_OUTBOUND_PROXY: - case CFGID_OUTBOUND_PROXY_PORT: - - case CFGID_PROXY_REGISTER: - case CFGID_REMOTE_CC_ENABLED: - - case CFGID_SIP_INVITE_RETX: - case CFGID_SIP_RETX: - case CFGID_TIMER_INVITE_EXPIRES: - case CFGID_TIMER_KEEPALIVE_EXPIRES: - case CFGID_TIMER_SUBSCRIBE_EXPIRES: - case CFGID_TIMER_SUBSCRIBE_DELTA: - case CFGID_TIMER_T1: - case CFGID_TIMER_T2: - - case CFGID_SIP_MAX_FORWARDS: - case CFGID_REMOTE_PARTY_ID: - case CFGID_REG_USER_INFO: - - case CFGID_PREFERRED_CODEC: - case CFGID_VOIP_CONTROL_PORT: - case CFGID_NAT_ENABLE: - case CFGID_NAT_ADDRESS: - case CFGID_NAT_RECEIVED_PROCESSING: - - case CFGID_DTMF_AVT_PAYLOAD: - case CFGID_DTMF_DB_LEVEL: - case CFGID_DTMF_OUTOFBAND: - - case CFGID_KPML_ENABLED: - case CFGID_MEDIA_PORT_RANGE_START: - case CFGID_TRANSPORT_LAYER_PROT: - - case CFGID_TIMER_REGISTER_EXPIRES: - case CFGID_TIMER_REGISTER_DELTA: - case CFGID_DSCP_FOR_CALL_CONTROL: - return TRUE; - default: - return FALSE; - } -} - - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_byte_value(int cfgid, unsigned char value, const unsigned char * config_name) { - int temp_value ; - const var_t *entry; - if (apply_config == TRUE) { - if (is_cfgid_in_restart_list(cfgid) == TRUE) { - config_get_value(cfgid, &temp_value, sizeof(temp_value)); - if (((int)value) != temp_value) { - apply_config_result = RESTART_NEEDED; - entry = &prot_cfg_table[cfgid]; - print_config_value(cfgid, "changed Get Val", entry->name, &temp_value, sizeof(temp_value)); - DEF_DEBUG(CFG_F_PREFIX "config %s[%d] changed. Old value=%d new value=%d\n", "compare_or_set_byte_value", config_name, cfgid, temp_value, value); - } - } - } else { - CC_Config_setByteValue(cfgid, value); - } -} - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_boolean_value(int cfgid, cc_boolean value, const unsigned char * config_name) { - int temp_value ; - const var_t *entry; - if (apply_config == TRUE) { - if (is_cfgid_in_restart_list(cfgid) == TRUE) { - config_get_value(cfgid, &temp_value, sizeof(temp_value)); - if (((int)value) != temp_value) { - apply_config_result = RESTART_NEEDED; - entry = &prot_cfg_table[cfgid]; - print_config_value(cfgid, "changed Get Val", entry->name, &temp_value, sizeof(temp_value)); - DEF_DEBUG(CFG_F_PREFIX "config %s[%d] changed. Old value=%d new value=%d\n", "compare_or_set_boolean_value", config_name, cfgid, temp_value, value); - } - } - } else { - CC_Config_setBooleanValue(cfgid, value); - } -} - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_int_value(int cfgid, int value, const unsigned char * config_name) { - int temp_value; - const var_t *entry; - if (apply_config == TRUE) { - if (is_cfgid_in_restart_list(cfgid) == TRUE) { - config_get_value(cfgid, &temp_value, sizeof(temp_value)); - if (value != temp_value) { - apply_config_result = RESTART_NEEDED; - entry = &prot_cfg_table[cfgid]; - print_config_value(cfgid, "changed Get Val", entry->name, &temp_value, sizeof(temp_value)); - - DEF_DEBUG(CFG_F_PREFIX "config %s[%d] changed. new value=%d Old value=%d\n", "compare_or_set_int_value", config_name, cfgid, value, temp_value); - } - } - } else { - CC_Config_setIntValue(cfgid, value); - } -} - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_string_value (int cfgid, const char* value, const unsigned char * config_name) { - static char temp_value[MAX_SIP_URL_LENGTH]; - const var_t *entry; - if (apply_config == TRUE ) { - if (is_cfgid_in_restart_list(cfgid) == TRUE) { - config_get_string(cfgid, temp_value, MAX_SIP_URL_LENGTH); - if (strcmp(value, temp_value) != 0) { - apply_config_result = RESTART_NEEDED; - entry = &prot_cfg_table[cfgid]; - print_config_value(cfgid, "changed Get Val", entry->name, &temp_value, sizeof(temp_value)); - DEF_DEBUG(CFG_F_PREFIX "config %s[%d] changed. new value=%s Old value=%s\n", "compare_or_set_string_value", config_name, cfgid, value, temp_value); - } - } - } else { - CC_Config_setStringValue(cfgid, value); - } -} - -int lineConfig = 0; -int portConfig = 0; -int proxyConfig = 0; - -/* - * config_set_autoreg_properties - * - */ -void config_set_autoreg_properties () -{ - CC_Config_setIntValue(CFGID_LINE_INDEX + 0, 1); - CC_Config_setIntValue(CFGID_LINE_FEATURE + 0, 9); - CC_Config_setStringValue(CFGID_PROXY_ADDRESS + 0, "USECALLMANAGER"); - CC_Config_setIntValue(CFGID_PROXY_PORT + 0, 5060); - CC_Config_setStringValue(CFGID_LINE_NAME + 0, autoreg_name); - CC_Config_setBooleanValue(CFGID_PROXY_REGISTER, 1); - CC_Config_setIntValue(CFGID_TRANSPORT_LAYER_PROT, 2); - - /* timerRegisterExpires = 3600 */ - CC_Config_setIntValue(CFGID_TIMER_REGISTER_EXPIRES, 3600); - /* sipRetx = 10 */ - CC_Config_setIntValue(CFGID_SIP_RETX, 10); - /* sipInviteRetx = 6 */ - CC_Config_setIntValue(CFGID_SIP_INVITE_RETX, 6); - /* timerRegisterDelta = 5 */ - CC_Config_setIntValue(CFGID_TIMER_REGISTER_DELTA, 5); - /* MaxRedirects = 70 */ - CC_Config_setIntValue(CFGID_SIP_MAX_FORWARDS, 70); - /* timerInviteExpires = 180 */ - CC_Config_setIntValue(CFGID_TIMER_INVITE_EXPIRES, 180); - /* timerSubscribeDelta = 5 */ - CC_Config_setIntValue(CFGID_TIMER_SUBSCRIBE_DELTA, 5); - /* timerSubscribeExpires = 120 */ - CC_Config_setIntValue(CFGID_TIMER_SUBSCRIBE_EXPIRES, 120); - - CC_Config_setIntValue(CFGID_REMOTE_CC_ENABLED, 1); - CC_Config_setIntValue(CFGID_VOIP_CONTROL_PORT, 5060); -} - -/* - * update_security_mode_and_ports - * - */ -void update_security_mode_and_ports(void) { - sec_level_t sec_level = NON_SECURE; - - // convert security mode (from UCM xml) into internal enum - switch (security_mode) - { - case 1: sec_level = NON_SECURE; break; - case 2: sec_level = AUTHENTICATED; break; - case 3: sec_level = ENCRYPTED; break; - default: - CONFIG_ERROR(CFG_F_PREFIX "unable to translate securite mode [%d]\n", "update_security_mode_and_ports", (int)security_mode); - break; - } - - compare_or_set_int_value(CFGID_CCM1_SEC_LEVEL, sec_level, - (const unsigned char *)"deviceSecurityMode"); - compare_or_set_int_value(CFGID_CCM2_SEC_LEVEL, sec_level, - (const unsigned char *)"deviceSecurityMode"); - compare_or_set_int_value(CFGID_CCM3_SEC_LEVEL, sec_level, - (const unsigned char *)"deviceSecurityMode"); - - if (sec_level == NON_SECURE) { - compare_or_set_int_value(CFGID_CCM1_SIP_PORT, sip_port[0], - (const unsigned char *)"ccm1_sip_port"); - compare_or_set_int_value(CFGID_CCM2_SIP_PORT, sip_port[1], - (const unsigned char *)"ccm2_sip_port"); - compare_or_set_int_value(CFGID_CCM3_SIP_PORT, sip_port[2], - (const unsigned char *)"ccm3_sip_port"); - } else { - compare_or_set_int_value(CFGID_CCM1_SIP_PORT, secured_sip_port[0], - (const unsigned char *)"ccm1_secured_sip_port"); - compare_or_set_int_value(CFGID_CCM2_SIP_PORT, secured_sip_port[1], - (const unsigned char *)"ccm2_secured_sip_port"); - compare_or_set_int_value(CFGID_CCM3_SIP_PORT, secured_sip_port[2], - (const unsigned char *)"ccm3_secured_sip_port"); - } -} - - -#define MISSEDCALLS "Application:Cisco/MissedCalls" -#define PLACEDCALLS "Application:Cisco/PlacedCalls" -#define RECEIVEDCALLS "Application:Cisco/ReceivedCalls" - -/* - * config_get_mac_addr - * - * Get the filename that has the mac address and parse the string - * convert it into an mac address stored in the bytearray maddr -*/ -void config_get_mac_addr (char *maddr) -{ - platGetMacAddr(maddr); - -} - -/* - * Set the MAC address in the config table - */ -void config_set_ccm_ip_mac () -{ - - char macaddr[MAC_ADDR_SIZE]; - - compare_or_set_int_value(CFGID_DSCP_FOR_CALL_CONTROL , 1, (const unsigned char *) "DscpCallControl"); - compare_or_set_int_value(CFGID_SPEAKER_ENABLED, 1, (const unsigned char *) "speakerEnabled"); - - if (apply_config == FALSE) { - config_get_mac_addr(macaddr); - - CONFIG_DEBUG(CFG_F_PREFIX ": MAC Address IS: %x:%x:%x:%x:%x:%x \n", - "config_get_mac_addr", macaddr[0], macaddr[1], - macaddr[2], macaddr[3], macaddr[4], macaddr[5]); - - CC_Config_setArrayValue(CFGID_MY_MAC_ADDR, macaddr, MAC_ADDR_SIZE); - CC_Config_setArrayValue(CFGID_MY_ACTIVE_MAC_ADDR, macaddr, MAC_ADDR_SIZE); - } -} - -/* - * config_setup_element - * Setup elements that once were downloaded from CUCM in an XML file. - * Settings are stored in config.h - */ -void config_setup_elements (const char *sipUser, const char *sipPassword, const char *sipDomain) -{ - unsigned int i; - // char buf[MAX_SIP_URL_LENGTH] = {'\0'}; - char ip[MAX_SIP_URL_LENGTH] = {'\0'}; - char option[MAX_SIP_URL_LENGTH] = {'\0'}; - int line = 0; - cc_boolean isSecure = FALSE, isValid = TRUE; - char macaddr[MAC_ADDR_SIZE]; - - compare_or_set_int_value(CFGID_MEDIA_PORT_RANGE_START, gStartMediaPort, (const unsigned char *) "startMediaPort"); - compare_or_set_int_value(CFGID_MEDIA_PORT_RANGE_END, gStopMediaPort, (const unsigned char *) "stopMediaPort"); - compare_or_set_boolean_value(CFGID_CALLERID_BLOCKING, gCallerIdBlocking, (const unsigned char *) "callerIdBlocking"); - compare_or_set_boolean_value(CFGID_ANONYMOUS_CALL_BLOCK, gAnonblock, (const unsigned char *) "anonymousCallBlock"); - compare_or_set_string_value(CFGID_PREFERRED_CODEC, gPreferredCodec, (const unsigned char *) "preferredCodec"); - compare_or_set_string_value(CFGID_DTMF_OUTOFBAND, gDtmfOutOfBand, (const unsigned char *) "dtmfOutofBand"); - compare_or_set_int_value(CFGID_DTMF_AVT_PAYLOAD, gDtmfAvtPayload, (const unsigned char *) "dtmfAvtPayload"); - compare_or_set_int_value(CFGID_DTMF_DB_LEVEL, gDtmfDbLevel, (const unsigned char *) "dtmfDbLevel"); - compare_or_set_int_value(CFGID_SIP_RETX, gSipRetx, (const unsigned char *) "sipRetx"); - compare_or_set_int_value(CFGID_SIP_INVITE_RETX, gSipInviteRetx, (const unsigned char *) "sipInviteRetx"); - compare_or_set_int_value(CFGID_TIMER_T1, gTimerT1, (const unsigned char *) "timerT1"); - compare_or_set_int_value(CFGID_TIMER_T2, gTimerT2, (const unsigned char *) "timerT2"); - compare_or_set_int_value(CFGID_TIMER_INVITE_EXPIRES, gTimerInviteExpires, (const unsigned char *) "timerInviteExpires"); - compare_or_set_int_value(CFGID_TIMER_REGISTER_EXPIRES, gTimerRegisterExpires, (const unsigned char *) "timerRegisterExpires"); - compare_or_set_boolean_value(CFGID_PROXY_REGISTER, gRegisterWithProxy, (const unsigned char *) "registerWithProxy"); - compare_or_set_string_value(CFGID_PROXY_BACKUP, gBackupProxy, (const unsigned char *) "backupProxy"); - compare_or_set_int_value(CFGID_PROXY_BACKUP_PORT, gBackupProxyPort, (const unsigned char *) "backupProxyPort"); - compare_or_set_string_value(CFGID_PROXY_EMERGENCY, gEmergencyProxy, (const unsigned char *) "emergencyProxy"); - compare_or_set_int_value(CFGID_PROXY_EMERGENCY_PORT, gEmergencyProxyPort, (const unsigned char *) "emergencyProxyPort"); - compare_or_set_string_value(CFGID_OUTBOUND_PROXY, gOutboundProxy, (const unsigned char *) "outboundProxy"); - compare_or_set_int_value(CFGID_OUTBOUND_PROXY_PORT, gOutboundProxyPort, (const unsigned char *) "outboundProxyPort"); - compare_or_set_boolean_value(CFGID_NAT_RECEIVED_PROCESSING, gNatRecievedProcessing, (const unsigned char *) "natRecievedProcessing"); - compare_or_set_string_value(CFGID_REG_USER_INFO, gUserInfo, (const unsigned char *) "userInfo"); - compare_or_set_boolean_value(CFGID_REMOTE_PARTY_ID, gRemotePartyID, (const unsigned char *) "remotePartyID"); - compare_or_set_boolean_value (CFGID_SEMI_XFER, gSemiAttendedTransfer, (const unsigned char *) "semiAttendedTransfer"); - compare_or_set_int_value(CFGID_CALL_HOLD_RINGBACK, gCallHoldRingback, (const unsigned char *) "callHoldRingback"); - compare_or_set_boolean_value(CFGID_STUTTER_MSG_WAITING, gStutterMsgWaiting, (const unsigned char *) "stutterMsgWaiting"); - compare_or_set_string_value(CFGID_CALL_FORWARD_URI, gCallForwardURI, (const unsigned char *) "callForwardURI"); - compare_or_set_boolean_value(CFGID_CALL_STATS, gCallStats, (const unsigned char *) "callStats"); - compare_or_set_int_value(CFGID_TIMER_REGISTER_DELTA, gTimerRegisterDelta, (const unsigned char *) "timerRegisterDelta"); - compare_or_set_int_value(CFGID_SIP_MAX_FORWARDS, gMaxRedirects, (const unsigned char *) "maxRedirects"); - compare_or_set_boolean_value(CFGID_2543_HOLD, gRfc2543Hold, (const unsigned char *) "rfc2543Hold"); - compare_or_set_boolean_value(CFGID_LOCAL_CFWD_ENABLE, gLocalCfwdEnable, (const unsigned char *) "localCfwdEnable"); - compare_or_set_int_value(CFGID_CONN_MONITOR_DURATION, gConnectionMonitorDuration, (const unsigned char *) "connectionMonitorDuration"); - compare_or_set_int_value(CFGID_CALL_LOG_BLF_ENABLED, gCallLogBlfEnabled, (const unsigned char *) "callLogBlfEnabled"); - compare_or_set_boolean_value(CFGID_RETAIN_FORWARD_INFORMATION, gRetainForwardInformation, (const unsigned char *) "retainForwardInformation"); - compare_or_set_int_value(CFGID_REMOTE_CC_ENABLED, gRemoteCcEnable, (const unsigned char *) "remoteCcEnable"); - compare_or_set_int_value(CFGID_TIMER_KEEPALIVE_EXPIRES, gTimerKeepAliveExpires, (const unsigned char *) "timerKeepAliveExpires"); - compare_or_set_int_value(CFGID_TIMER_SUBSCRIBE_EXPIRES, gTimerSubscribeExpires, (const unsigned char *) "timerSubscribeExpires"); - compare_or_set_int_value(CFGID_TIMER_SUBSCRIBE_DELTA, gTimerSubscribeDelta, (const unsigned char *) "timerSubscribeDelta"); - compare_or_set_int_value(CFGID_TRANSPORT_LAYER_PROT, gTransportLayerProtocol, (const unsigned char *) "transportLayerProtocol"); - compare_or_set_int_value(CFGID_KPML_ENABLED, gKpml, (const unsigned char *) "kpml"); - compare_or_set_boolean_value(CFGID_NAT_ENABLE, gNatEnabled, (const unsigned char *) "natEnabled"); - compare_or_set_string_value(CFGID_NAT_ADDRESS, gNatAddress, (const unsigned char *) "natAddress"); - compare_or_set_int_value(CFGID_VOIP_CONTROL_PORT, gVoipControlPort, (const unsigned char *) "voipControlPort"); - compare_or_set_boolean_value(CFGID_ENABLE_VAD, gAnableVad, (const unsigned char *) "enableVad"); - compare_or_set_boolean_value(CFGID_AUTOANSWER_IDLE_ALTERNATE, gAutoAnswerAltBehavior, (const unsigned char *) "autoAnswerAltBehavior"); - compare_or_set_int_value(CFGID_AUTOANSWER_TIMER, gAutoAnswerTimer, (const unsigned char *) "autoAnswerTimer"); - compare_or_set_boolean_value(CFGID_AUTOANSWER_OVERRIDE, gAutoAnswerOverride, (const unsigned char *) "autoAnswerOverride"); - compare_or_set_int_value(CFGID_OFFHOOK_TO_FIRST_DIGIT_TIMER, gOffhookToFirstDigitTimer, (const unsigned char *) "offhookToFirstDigitTimer"); - compare_or_set_int_value(CFGID_CALL_WAITING_SILENT_PERIOD, gSilentPeriodBetweenCallWaitingBursts, (const unsigned char *) "silentPeriodBetweenCallWaitingBursts"); - compare_or_set_int_value(CFGID_RING_SETTING_BUSY_POLICY, gRingSettingBusyStationPolicy, (const unsigned char *) "ringSettingBusyStationPolicy"); - compare_or_set_int_value (CFGID_BLF_ALERT_TONE_IDLE, gBlfAudibleAlertSettingOfIdleStation, (const unsigned char *) "blfAudibleAlertSettingOfIdleStation"); - compare_or_set_int_value (CFGID_BLF_ALERT_TONE_BUSY, gBlfAudibleAlertSettingOfBusyStation, (const unsigned char *) "blfAudibleAlertSettingOfBusyStation"); - compare_or_set_int_value (CFGID_JOIN_ACROSS_LINES, gJoinAcrossLines, (const unsigned char *) "joinAcrossLines"); - compare_or_set_boolean_value(CFGID_CNF_JOIN_ENABLE, gCnfJoinEnabled, (const unsigned char *) "cnfJoinEnabled"); - compare_or_set_int_value (CFGID_ROLLOVER, gRollover, (const unsigned char *) "rollover"); - compare_or_set_boolean_value(CFGID_XFR_ONHOOK_ENABLED, gTransferOnhookEnabled, (const unsigned char *) "transferOnhookEnabled"); - compare_or_set_int_value(CFGID_DSCP_AUDIO, gDscpForAudio, (const unsigned char *) "dscpForAudio"); - compare_or_set_int_value(CFGID_DSCP_VIDEO, gDscpVideo, (const unsigned char *) "dscpVideo"); - compare_or_set_int_value(CFGID_INTER_DIGIT_TIMER, gT302Timer, (const unsigned char *) "T302Timer"); - - // TODO(emannion): You had line=1; line<= .... - // Debugging suggests that alghouth *line* is 1-indexed, the config entries - // are 1-indexed. See. config_get_line_id(). - // You may want to rewrite this in terms of config_get_line_id(). - // Please check -- EKR - for(line = 0; line < MAX_REG_LINES; line++) { - - compare_or_set_int_value(CFGID_LINE_INDEX + line, gLineIndex, (const unsigned char *)"lineIndex"); - compare_or_set_int_value(CFGID_LINE_FEATURE + line, gFeatureID, (const unsigned char *) "featureID"); - compare_or_set_string_value(CFGID_PROXY_ADDRESS + line, gProxy, (const unsigned char *) "proxy"); - compare_or_set_int_value(CFGID_PROXY_PORT + line, gPort, (const unsigned char *) "port"); - - if ( apply_config == FALSE ) { - ccsnap_set_line_label(line+1, "LINELABEL"); - } - - compare_or_set_string_value(CFGID_LINE_NAME + line, sipUser, (const unsigned char *) "name"); - compare_or_set_string_value(CFGID_LINE_DISPLAYNAME + line, gDisplayName, (const unsigned char *) "displayName"); - compare_or_set_string_value(CFGID_LINE_MESSAGES_NUMBER + line, gMessagesNumber, (const unsigned char *) "messagesNumber"); - compare_or_set_boolean_value(CFGID_LINE_FWD_CALLER_NAME_DIPLAY + line, gCallerName, (const unsigned char *) "callerName"); - compare_or_set_boolean_value(CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY + line, gCallerNumber, (const unsigned char *) "callerNumber"); - compare_or_set_boolean_value(CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY + line, gRedirectedNumber, (const unsigned char *) "redirectedNumber"); - compare_or_set_boolean_value(CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY + line, gDialedNumber, (const unsigned char *) "dialedNumber"); - compare_or_set_byte_value(CFGID_LINE_MSG_WAITING_LAMP + line, gMessageWaitingLampPolicy, (const unsigned char *) "messageWaitingLampPolicy"); - compare_or_set_byte_value(CFGID_LINE_MESSAGE_WAITING_AMWI + line, gMessageWaitingAMWI, (const unsigned char *) "messageWaitingAMWI"); - compare_or_set_byte_value(CFGID_LINE_RING_SETTING_IDLE + line, gRingSettingIdle, (const unsigned char *) "ringSettingIdle"); - compare_or_set_byte_value(CFGID_LINE_RING_SETTING_ACTIVE + line, gRingSettingActive, (const unsigned char *) "ringSettingActive"); - compare_or_set_string_value(CFGID_LINE_CONTACT + line, sipUser, (const unsigned char *) "contact"); - compare_or_set_int_value(CFGID_LINE_MAXNUMCALLS + line, gMaxNumCalls, (const unsigned char *) "maxNumCalls"); - compare_or_set_int_value(CFGID_LINE_BUSY_TRIGGER + line, gBusyTrigger, (const unsigned char *) "busyTrigger"); - compare_or_set_byte_value(CFGID_LINE_AUTOANSWER_ENABLED + line, gAutoAnswerEnabled, (const unsigned char *) "autoAnswerEnabled"); - compare_or_set_byte_value(CFGID_LINE_CALL_WAITING + line, gCallWaiting, (const unsigned char *) "callWaiting"); - compare_or_set_string_value(CFGID_LINE_AUTHNAME + line, sipUser, (const unsigned char *)"authName"); - compare_or_set_string_value(CFGID_LINE_PASSWORD + line, sipPassword, (const unsigned char *)"authPassword"); - } - - compare_or_set_int_value(CFGID_CCM1_SEC_LEVEL, gDeviceSecurityMode,(const unsigned char *)"deviceSecurityMode"); - compare_or_set_int_value(CFGID_CCM1_SIP_PORT, gCcm1_sip_port,(const unsigned char *)"ccm1_sip_port"); - compare_or_set_int_value(CFGID_CCM2_SIP_PORT, gCcm2_sip_port,(const unsigned char *)"ccm2_sip_port"); - compare_or_set_int_value(CFGID_CCM3_SIP_PORT, gCcm3_sip_port, (const unsigned char *)"ccm3_sip_port"); - - - isSecure = FALSE; - sstrncpy(ip, "", MAX_SIP_URL_LENGTH); - sstrncpy(option, "User Specific", MAX_SIP_URL_LENGTH); - - compare_or_set_string_value(CFGID_CCM1_ADDRESS+0, sipDomain, (const unsigned char *) "ccm1_addr"); - compare_or_set_boolean_value(CFGID_CCM1_IS_VALID + 0, gCcm1_isvalid, (const unsigned char *)"ccm1_isvalid"); - compare_or_set_int_value(CFGID_DSCP_FOR_CALL_CONTROL , gDscpCallControl, (const unsigned char *) "DscpCallControl"); - compare_or_set_int_value(CFGID_SPEAKER_ENABLED, gSpeakerEnabled, (const unsigned char *) "speakerEnabled"); - - if (apply_config == FALSE) { - config_get_mac_addr(macaddr); - - CONFIG_DEBUG(CFG_F_PREFIX ": MAC Address IS: %x:%x:%x:%x:%x:%x \n", - "config_get_mac_addr", macaddr[0], macaddr[1], - macaddr[2], macaddr[3], macaddr[4], macaddr[5]); - - CC_Config_setArrayValue(CFGID_MY_MAC_ADDR, macaddr, MAC_ADDR_SIZE); - CC_Config_setArrayValue(CFGID_MY_ACTIVE_MAC_ADDR, macaddr, MAC_ADDR_SIZE); - } - - CONFIG_DEBUG(CFG_F_PREFIX "%s \n", "config_parse_element", "phoneServices"); - CONFIG_DEBUG(CFG_F_PREFIX "%s \n", "config_parse_element", "versionStamp"); - CONFIG_ERROR(CFG_F_PREFIX "%s new=%s old=%s \n", "config_parser_element", "versionStamp", - "1284570837-bbc096ed-7392-427d-9694-5ce49d5c3acb", g_cfg_version_stamp); - - if (apply_config == FALSE) { - memset(g_cfg_version_stamp, 0, sizeof(g_cfg_version_stamp)); - i = strlen("1284570837-bbc096ed-7392-427d-9694-5ce49d5c3acb"); - if (i > MAX_CFG_VERSION_STAMP_LEN) { - CONFIG_ERROR(CFG_F_PREFIX "config version %d, bigger than allocated space %d\n", "config_parser_element", i, MAX_CFG_VERSION_STAMP_LEN); - } - - sstrncpy(g_cfg_version_stamp, "1284570837-bbc096ed-7392-427d-9694-5ce49d5c3acb", sizeof(g_cfg_version_stamp)); - } - else { - CONFIG_ERROR(CFG_F_PREFIX "got NULL value for %s\n", "config_parser_element", "versionStamp"); - } - - CONFIG_DEBUG(CFG_F_PREFIX "%s \n", "config_parser_element", "externalNumberMask"); - compare_or_set_string_value(CFGID_CCM_EXTERNAL_NUMBER_MASK, gExternalNumberMask, (const unsigned char *) "externalNumberMask"); - - /* Set SIP P2P boolean */ - compare_or_set_boolean_value(CFGID_P2PSIP, gP2PSIP, (const unsigned char *) "p2psip"); - - /* Set product version */ - compare_or_set_string_value(CFGID_VERSION, gVersion, (const unsigned char *) "version"); - - /* Set rtcp-mux, right now to always true */ - compare_or_set_boolean_value(CFGID_RTCPMUX, gRTCPMUX, (const unsigned char *) "rtcpmux"); - - /* Set RTP/SAVPF, right now to always true */ - compare_or_set_boolean_value(CFGID_RTPSAVPF, gRTPSAVPF, (const unsigned char *) "rtpsavpf"); - - compare_or_set_boolean_value(CFGID_MAXAVBITRATE, gMAXAVBITRATE, (const unsigned char *) "maxavbitrate"); - - compare_or_set_boolean_value(CFGID_MAXCODEDAUDIOBW, gMAXCODEDAUDIOBW, (const unsigned char *) "maxcodedaudiobw"); - - compare_or_set_boolean_value(CFGID_USEDTX, gUSEDTX, (const unsigned char *) "usedtx"); - - compare_or_set_boolean_value(CFGID_STEREO, gSTEREO, (const unsigned char *) "stereo"); - - compare_or_set_boolean_value(CFGID_USEINBANDFEC, gUSEINBANDFEC, (const unsigned char *) "useinbandfec"); - - compare_or_set_boolean_value(CFGID_CBR, gCBR, (const unsigned char *) "cbr"); - - compare_or_set_boolean_value(CFGID_MAXPTIME, gMAXPTIME, (const unsigned char *) "maxptime"); - - compare_or_set_int_value(CFGID_SCTP_PORT, gSCTPPort, (const unsigned char *) "sctp_port"); - - compare_or_set_int_value(CFGID_NUM_DATA_STREAMS, gNumDataStreams, (const unsigned char *) "num_data_streams"); - - (void) isSecure; // XXX set but not used - (void) isValid; // XXX set but not used -} - -void config_setup_server_address (const char *sipDomain) { - compare_or_set_string_value(CFGID_CCM1_ADDRESS+0, sipDomain, (const unsigned char *) "ccm1_addr"); -} - -void config_setup_transport_udp(const cc_boolean is_udp) { - gTransportLayerProtocol = is_udp ? 2 : 4; - compare_or_set_int_value(CFGID_TRANSPORT_LAYER_PROT, gTransportLayerProtocol, (const unsigned char *) "transportLayerProtocol"); -} - -void config_setup_local_voip_control_port(const int voipControlPort) { - gVoipControlPort = voipControlPort; - compare_or_set_int_value(CFGID_VOIP_CONTROL_PORT, voipControlPort, (const unsigned char *) "voipControlPort"); -} - -void config_setup_remote_voip_control_port(const int voipControlPort) { - gCcm1_sip_port = voipControlPort; - compare_or_set_int_value(CFGID_CCM1_SIP_PORT, voipControlPort,(const unsigned char *)"ccm1_sip_port"); -} - -int config_get_local_voip_control_port() { - return gVoipControlPort; -} - -int config_get_remote_voip_control_port() { - return gCcm1_sip_port; -} - -const char* config_get_version() { - return gVersion; -} - -void config_setup_p2p_mode(const cc_boolean is_p2p) { - gP2PSIP = is_p2p; - compare_or_set_boolean_value(CFGID_P2PSIP, is_p2p, (const unsigned char *) "p2psip"); -} - -void config_setup_sdp_mode(const cc_boolean is_sdp) { - gSDPMODE = is_sdp; - compare_or_set_boolean_value(CFGID_SDPMODE, is_sdp, (const unsigned char *) "sdpsip"); -} - -void config_setup_avp_mode(const cc_boolean is_rtpsavpf) { - gRTPSAVPF = is_rtpsavpf; - compare_or_set_boolean_value(CFGID_RTPSAVPF, is_rtpsavpf, (const unsigned char *) "rtpsavpf"); -} - -/** - * Process/Parse the FCP file if specified in the master config file. -*/ -void config_parser_handle_fcp_file (char* fcpTemplateFile) -{ - - // if no fcp file specified in master config file, then set the default dialplan - if (strcmp (fcpTemplateFile, "") == 0) - { - CC_Config_setFcp(NULL, 0); - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_CONFIG_CHANGED, CC_DEVICE_ID); - - return; - } - - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_CONFIG_CHANGED, CC_DEVICE_ID); -} - - -/** - * Function called as part of registration without using cnf device file download. - */ -int config_setup_main( const char *sipUser, const char *sipPassword, const char *sipDomain) -{ - config_setup_elements(sipUser, sipPassword, sipDomain); - update_security_mode_and_ports(); - - // Take care of Fetch and apply of FCP and DialPlan if configured and necessary - if (apply_config == FALSE) { - config_parser_handle_fcp_file (fcpTemplateFile); - } - - return 0; -} diff --git a/libs/sipcc/core/common/config_parser.h b/libs/sipcc/core/common/config_parser.h deleted file mode 100644 index 35730eaaf8..0000000000 --- a/libs/sipcc/core/common/config_parser.h +++ /dev/null @@ -1,173 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CONFIG_PARSER_H_ -#define CONFIG_PARSER_H_ - -#include "cc_constants.h" -#include "cc_types.h" -#include "cc_config.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "debug.h" -#include "prot_configmgr.h" -#include "call_logger.h" -#include "sip_common_transport.h" -#include "sip_ccm_transport.h" - -#define MAX_CFG_VERSION_STAMP_LEN 80 - -/* - * This function determine whether the passed config parameter should be used - * in comparing the new and old config value for apply-config purpose. Only - * those config ids on whose change phone needs to restart are part of this - * function. For remaining parameters, it is assumed that any change can be - * applied dynamically. - * - */ -boolean is_cfgid_in_restart_list(int cfgid); - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_byte_value(int cfgid, unsigned char value, const unsigned char * config_name); - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_boolean_value(int cfgid, cc_boolean value, const unsigned char * config_name); - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_int_value(int cfgid, int value, const unsigned char * config_name); - -/* - * This function either compare the new and old config value or set the value - * for the config_id passed depending upon whether apply-config is true or not. - */ -void compare_or_set_string_value (int cfgid, const char* value, const unsigned char * config_name); - -/* - * config_fetch_dialplan() called to retrieve the dialplan - * - */ -void config_fetch_dialplan(char *filename); - -/* - * config_fetch_fcp() called to retrieve the fcp - * - */ -void config_fetch_fcp(char *filename); - -/* - * config_set_autoreg_properties - * - */ -void config_set_autoreg_properties (); - -/* - * update_security_mode_and_ports - * - */ -void update_security_mode_and_ports(void); - -/* - * config_get_mac_addr - * - * Get the filename that has the mac address and parse the string - * convert it into an mac address stored in the bytearray maddr -*/ -void config_get_mac_addr (char *maddr); - -/* - * Set the IP and MAC address in the config table - */ -void config_set_ccm_ip_mac (); - - -/* - * Set up configuration without XML config file. - */ -void config_setup_elements ( const char *sipUser, const char *sipPassword, const char *sipDomain); - -/* - * Set server ip address into config - * Same ip address is also used to make a P2P call - */ -void config_setup_server_address (const char *sipDomain); - -/* - * set transport protocol, limited to udp or tcp for now - */ -void config_setup_transport_udp(const cc_boolean is_udp); - -/* - * set local voip port defaults to 5060 - */ -void config_setup_local_voip_control_port(const int voipControlPort); - -/* - * set remote voip port defaults to 5060 - */ -void config_setup_remote_voip_control_port(const int voipControlPort); - -/* - * get local voip port defaults to 5060 - */ -int config_get_local_voip_control_port(); - -/* - * get remote voip port defaults to 5060 - */ -int config_get_remote_voip_control_port(); - -/* - * get ikran version - */ -const char* config_get_version(); - -/* - * set p2p mode on or off - */ -void config_setup_p2p_mode(const cc_boolean is_p2p); - -/* - * set sdp mode on or off - */ -void config_setup_sdp_mode(const cc_boolean is_sdp); - -/* - * set avp mode (true == RTP/SAVPF, false = RTP/SAVP) - */ -void config_setup_avp_mode(const cc_boolean is_rtpsavpf); - -/** -* config_minimum_check: -* -* @a_node: the initial xml node to consider. -* @doc: The DOM tree of the xml file -* -* Check if minimum set of elements are present in the config file and -* have values that can be used by sipstack -* -*/ - -/** - * Parse the file that is passed in, - * walk down the DOM that is created , and get the - * xml elements nodes. - */ -int config_parser_main( char *config, int complete_config); - -/* - * Set up configuration without XML config file. - */ -int config_setup_main( const char *sipUser, const char *sipPassword, const char *sipDomain); - - -#endif /* CONFIG_PARSER_H_ */ diff --git a/libs/sipcc/core/common/init.c b/libs/sipcc/core/common/init.c deleted file mode 100755 index 87770c6c07..0000000000 --- a/libs/sipcc/core/common/init.c +++ /dev/null @@ -1,576 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr.h" -#include "cpr_in.h" -#include "cpr_stdlib.h" -#include "cpr_ipc.h" -#include "phntask.h" -#include -#include "configmgr.h" -#include "debug.h" -#include "config.h" -#include "vcm.h" -#include "dialplan.h" -#include "debug.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "ccsip_task.h" -#include "gsm.h" -#include "misc_apps_task.h" -#include "plat_api.h" -#include "ccapp_task.h" - -#include "phone_platform_constants.h" -/** The following defines are used to tune the total memory that pSIPCC - * allocates and uses. */ -/** Block size for emulated heap space, i.e. 1kB */ -#define BLK_SZ 1024 - -/** 5 MB Heap Based on 0.5 MB initial use + 4 MB for calls (20K * 200) + 0.5 MB misc */ -/** The number of supported blocks for the emulated heap space */ -#define MEM_BASE_BLK 500 //500 blocks, ~ 0.5M -#define MEM_MISC_BLK 500 //500 blocks, ~ 0.5M -/** Size of the emulated heap space. This is the value passed to the memory - * management pre-init procedure. The total memory allocated is - * "PRIVATE_SYS_MEM_SIZE + 2*64" where the additional numbers are for a gaurd - * band. */ -#define MEM_PER_CALL_BLK 20 //20 block, ~20k -#define PRIVATE_SYS_MEM_SIZE ((MEM_BASE_BLK + MEM_MISC_BLK + (MEM_PER_CALL_BLK) * MAX_CALLS) * BLK_SZ) - -// used in early init code where config has not been setup -const boolean gHardCodeSDPMode = TRUE; -boolean gStopTickTask = FALSE; - - -/*-------------------------------------------------------------------------- - * Local definitions - *-------------------------------------------------------------------------- - */ -#define GSMSTKSZ 61440 - -/* - * CNU thread queue sizes. - * - * On CNU, the message queue size can hold up to 31 entries only. - * This is too small for a phone that can support the MAX_CALLS that - * is close to or higher than 31 calls simultaneously. In a scenario when - * the number of active calls on the phone reaches its MAC_CALLS then - * there can be a potential MAX_CALLS that is great ther than 31 events on - * a queue to GSM or SIP thread. - * - * One known scenario is a 7970 phone having 50 held calls where all - * calls are not from the same CCM that this phone registers with but - * still within the same cluster. If that CCM is restarted, the CCM that - * this phone registers with will terminate these calls on the phone by - * sending BYEs, SUBSCRIBE (to terminate) DTMF digi collection and etc. to - * all these calls very quickly together. Handling these SIP messages - * can generate many internal events between SIP and GSM threads including - * events that are sent to self (such as GSM which includes applications - * that runs as part of GSM). The amount of the events posted on the queues - * during this time can be far exceeding than 31 and MAX_CALLS entries. - * - * The followings define queue sizes for GSM, SIP and the other threads. - * The GSM's queue size is defined to be larger than SIP's queue size to - * account for self sending event. The formular below is based on the - * testing with the above scenario and with 8-3-x phone load. The maximum - * queue depth observed for GSM under - * this condition is 129 entries and the maximum queue depth of - * SIP under the same condition is about 67 entries. Therefore, the queue - * depth of GSM thread is given to 3 times MAX_CALLS (or 153) and - * 2 times (or 102) for SIP thread for 7970 case. - * - */ -#define GSMQSZ (MAX_CALLS*3) /* GSM message queue size */ -#define SIPQSZ (MAX_CALLS*2) /* SIP message queue size */ -#define DEFQSZ 0 /* default message queue size */ -#define DEFAPPQSZ MAX_REG_LINES - -/*-------------------------------------------------------------------------- - * Global data - *-------------------------------------------------------------------------- - */ - -cprMsgQueue_t ccapp_msgq; -cprThread_t ccapp_thread; - -cprMsgQueue_t sip_msgq; -cprThread_t sip_thread; -#ifdef NO_SOCKET_POLLING -cprThread_t sip_msgqwait_thread; -#endif - -cprMsgQueue_t gsm_msgq; -cprThread_t gsm_thread; - -cprMsgQueue_t misc_app_msgq; -cprThread_t misc_app_thread; - -#ifdef JINDO_DEBUG_SUPPORTED -cprMsgQueue_t debug_msgq; -cprThread_t debug_thread; -#endif - -#ifdef EXTERNAL_TICK_REQUIRED -cprMsgQueue_t ticker_msgq; -cprThread_t ticker_thread; -#endif - -/* Platform initialized flag */ -boolean platform_initialized = FALSE; - -static int thread_init(void); - -/*-------------------------------------------------------------------------- - * External data references - * ------------------------------------------------------------------------- - */ - - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ -extern void gsm_set_initialized(void); -extern void vcm_init(void); -extern void dp_init(void *); -extern cprBuffer_t SIPTaskGetBuffer(uint16_t size); - -extern void sip_platform_task_loop(void *arg); -#ifdef NO_SOCKET_POLLING -extern void sip_platform_task_msgqwait(void *arg); -#endif -extern void GSMTask(void *); -#ifndef VENDOR_BUILD -extern void debug_task(void *); -#endif -extern void MiscAppTask(void *); -extern void cpr_timer_tick(void); - -extern void cprTimerSystemInit(void); -extern int32_t ui_clear_mwi(int32_t argc, const char *argv[]); -void gsm_shutdown(void); -void dp_shutdown(void); -void MiscAppTaskShutdown(void); -void CCAppShutdown(void); -cprBuffer_t gsm_get_buffer (uint16_t size); - - - - -/*-------------------------------------------------------------------------- - * Local scope function prototypes - *-------------------------------------------------------------------------- - */ -#ifdef EXTERNAL_TICK_REQUIRED -int TickerTask(void *); -#endif - -void send_protocol_config_msg(void); - -/** - * ccMemInit() - */ -extern -int ccMemInit(size_t size) { - return CPR_SUCCESS; -} - -/** - * ccPreInit - * - * Initialization routine to call before any application level - * code initializes. - * - * Parameters: None - * - * Return Value: CPR_SUCCESS or CPR_FAILURE - */ - -int -ccPreInit () -{ - static boolean ccPreInit_called = FALSE; - - if (ccPreInit_called == FALSE) { - ccPreInit_called = TRUE; - //Initializes the memory first - ccMemInit(PRIVATE_SYS_MEM_SIZE); - cprPreInit(); - } - - return CPR_SUCCESS; -} - -int -ccInit () -{ - - TNP_DEBUG(DEB_F_PREFIX"started init of SIP call control\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, "ccInit")); - - platInit(); - - strlib_init(); - - /* - * below should move to cprPreInit. keep it here until then - */ -#ifdef _WIN32 - cprTimerSystemInit(); -#endif - - /* Initialize threads, queues etc. */ - (void) thread_init(); - - platform_initialized = TRUE; - - return 0; -} - -static int -thread_init () -{ - gStopTickTask = FALSE; - /* - * This will have already been called for CPR CNU code, - * but may be called here for Windows emulation. - */ - (void) cprPreInit(); - - - PHNChangeState(STATE_FILE_CFG); - - /* initialize message queues */ - sip_msgq = cprCreateMessageQueue("SIPQ", SIPQSZ); - gsm_msgq = cprCreateMessageQueue("GSMQ", GSMQSZ); - - if (FALSE == gHardCodeSDPMode) { - misc_app_msgq = cprCreateMessageQueue("MISCAPPQ", DEFQSZ); - } - ccapp_msgq = cprCreateMessageQueue("CCAPPQ", DEFQSZ); -#ifdef JINDO_DEBUG_SUPPORTED - debug_msgq = cprCreateMessageQueue("DEBUGAPPQ", DEFQSZ); -#endif -#ifdef EXTERNAL_TICK_REQUIRED - ticker_msgq = cprCreateMessageQueue("Ticker", DEFQSZ); -#endif - - - /* - * Initialize the command parser and debug infrastructure - */ - debugInit(); - - /* create threads */ - ccapp_thread = cprCreateThread("CCAPP Task", - (cprThreadStartRoutine) CCApp_task, - GSMSTKSZ, CCPROVIDER_THREAD_RELATIVE_PRIORITY /* pri */, ccapp_msgq); - if (ccapp_thread == NULL) { - err_msg("failed to create CCAPP task \n"); - } - -#ifdef JINDO_DEBUG_SUPPORTED -#ifndef VENDOR_BUILD - debug_thread = cprCreateThread("Debug Task", - (cprThreadStartRoutine) debug_task, STKSZ, - 0 /*pri */ , debug_msgq); - - if (debug_thread == NULL) { - err_msg("failed to create debug task\n"); - } -#endif -#endif - - /* SIP main thread */ - sip_thread = cprCreateThread("SIPStack task", - (cprThreadStartRoutine) sip_platform_task_loop, - STKSZ, SIP_THREAD_RELATIVE_PRIORITY /* pri */, sip_msgq); - if (sip_thread == NULL) { - err_msg("failed to create sip task \n"); - } - -#ifdef NO_SOCKET_POLLING - /* SIP message wait queue task */ - sip_msgqwait_thread = cprCreateThread("SIP MsgQueueWait task", - (cprThreadStartRoutine) - sip_platform_task_msgqwait, - STKSZ, SIP_THREAD_RELATIVE_PRIORITY /* pri */, sip_msgq); - if (sip_msgqwait_thread == NULL) { - err_msg("failed to create sip message queue wait task\n"); - } -#endif - - gsm_thread = cprCreateThread("GSM Task", - (cprThreadStartRoutine) GSMTask, - GSMSTKSZ, GSM_THREAD_RELATIVE_PRIORITY /* pri */, gsm_msgq); - if (gsm_thread == NULL) { - err_msg("failed to create gsm task \n"); - } - - if (FALSE == gHardCodeSDPMode) { - misc_app_thread = cprCreateThread("MiscApp Task", - (cprThreadStartRoutine) MiscAppTask, - STKSZ, 0 /* pri */, misc_app_msgq); - if (misc_app_thread == NULL) { - err_msg("failed to create MiscApp task \n"); - } - } - -#ifdef EXTERNAL_TICK_REQUIRED - ticker_thread = cprCreateThread("Ticker task", - (cprThreadStartRoutine) TickerTask, - STKSZ, 0, ticker_msgq); - if (ticker_thread == NULL) { - err_msg("failed to create ticker task \n"); - } -#endif - - /* Associate the threads with the message queues */ - (void) cprSetMessageQueueThread(sip_msgq, sip_thread); - (void) cprSetMessageQueueThread(gsm_msgq, gsm_thread); - - if (FALSE == gHardCodeSDPMode) { - (void) cprSetMessageQueueThread(misc_app_msgq, misc_app_thread); - } - - (void) cprSetMessageQueueThread(ccapp_msgq, ccapp_thread); -#ifdef JINDO_DEBUG_SUPPORTED - (void) cprSetMessageQueueThread(debug_msgq, debug_thread); -#endif -#ifdef EXTERNAL_TICK_REQUIRED - (void) cprSetMessageQueueThread(ticker_msgq, ticker_thread); -#endif - - /* - * initialize debugs of other modules. - * - * dp_init needs the gsm_msgq id. This - * is set in a global variable by the - * GSM task running. However due to timing - * issues dp_init is sometimes run before - * the GSM task has set this variable resulting - * in a NULL msgqueue ptr being passed to CPR - * which returns an error and does not create - * the dialplan timer. Thus pass is the same - * data to dp_init that is passed into the - * cprCreateThread call for GSM above. - */ - config_init(); - vcmInit(); - dp_init(gsm_msgq); - - if (sip_minimum_config_check() != 0) { - PHNChangeState(STATE_UNPROVISIONED); - } else { - PHNChangeState(STATE_CONNECTED); - } - - (void) cprPostInit(); - - if ( vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX) ) { - cc_media_update_native_video_support(TRUE); - } - - return (0); -} - - -#ifdef EXTERNAL_TICK_REQUIRED - -uint16_t SecTimer = 50; - -unsigned long timeofday_in_seconds = 0; - -void -MAIN0Timer (void) -{ - if (SecTimer-- == 0) { - SecTimer = 50; - timeofday_in_seconds++; - } - //gtick +=2; - cpr_timer_tick(); -} - -int -TickerTask (void *a) -{ - TNP_DEBUG(DEB_F_PREFIX"Ticker Task initialized..\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, "TickerTask")); - while (FALSE == gStopTickTask) { - cprSleep(20); - MAIN0Timer(); - } - return 0; -} -#endif - -void -send_protocol_config_msg (void) -{ - const char *fname = "send_protocol_config_msg"; - char *msg; - - TNP_DEBUG(DEB_F_PREFIX"send TCP_DONE message to sip thread..\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - - msg = (char *) SIPTaskGetBuffer(4); - if (msg == NULL) { - TNP_DEBUG(DEB_F_PREFIX"failed to allocate message..\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - return; - } - /* send a config done message to the SIP Task */ - if (SIPTaskSendMsg(TCP_PHN_CFG_TCP_DONE, msg, 0, NULL) == CPR_FAILURE) { - err_msg("%s: notify SIP stack ready failed", fname); - cpr_free(msg); - } - gsm_set_initialized(); - PHNChangeState(STATE_CONNECTED); -} - - - - - -/* - * Function: send_task_unload_msg - * - * Description: - * - send shutdown and thread destroy msg to sip, gsm, ccapp, misc - * threads - * Parameters: destination thread - * - * Returns: none - * - */ -void -send_task_unload_msg(cc_srcs_t dest_id) -{ - const char *fname = "send_task_unload_msg"; - uint16_t len = 4; - cprBuffer_t msg = gsm_get_buffer(len); - int sdpmode = 0; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (msg == NULL) { - err_msg("%s: failed to allocate msg cprBuffer_t\n", fname); - return; - } - - DEF_DEBUG(DEB_F_PREFIX"send Unload message to %s task ..\n", - DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname), - dest_id == CC_SRC_SIP ? "SIP" : - dest_id == CC_SRC_GSM ? "GSM" : - dest_id == CC_SRC_MISC_APP ? "Misc App" : - dest_id == CC_SRC_CCAPP ? "CCApp" : "Unknown"); - - switch(dest_id) { - case CC_SRC_SIP: - { - /* send this msg so phone can send unRegister msg */ - SIPTaskPostShutdown(SIP_EXTERNAL, CC_CAUSE_SHUTDOWN, ""); - /* allow unRegister msg to sent out and shutdown to complete */ - - if (!sdpmode) { - cprSleep(2000); - } - /* send a unload message to the SIP Task to kill sip thread*/ - msg = SIPTaskGetBuffer(len); - if (msg == NULL) { - err_msg("%s:%d: failed to allocate sip msg buffer\n", fname); - return; - } - - if (SIPTaskSendMsg(THREAD_UNLOAD, (cprBuffer_t)msg, len, NULL) == CPR_FAILURE) - { - cpr_free(msg); - err_msg("%s: Unable to send THREAD_UNLOAD msg to sip thread", fname); - } - } - break; - case CC_SRC_GSM: - { - msg = gsm_get_buffer(len); - if (msg == NULL) { - err_msg("%s: failed to allocate gsm msg cprBuffer_t\n", fname); - return; - } - if (CPR_FAILURE == gsm_send_msg(THREAD_UNLOAD, msg, len)) { - err_msg("%s: Unable to send THREAD_UNLOAD msg to gsm thread", fname); - } - } - break; - case CC_SRC_MISC_APP: - { - msg = cpr_malloc(len); - if (msg == NULL) { - err_msg("%s: failed to allocate misc msg cprBuffer_t\n", fname); - return; - } - if (CPR_FAILURE == MiscAppTaskSendMsg(THREAD_UNLOAD, msg, len)) { - err_msg("%s: Unable to send THREAD_UNLOAD msg to Misc App thread", fname); - } - } - break; - case CC_SRC_CCAPP: - { - msg = cpr_malloc(len); - if (msg == NULL) { - err_msg("%s: failed to allocate ccapp msg cprBuffer_t\n", fname); - return; - } - if (ccappTaskPostMsg(CCAPP_THREAD_UNLOAD, msg, len, CCAPP_CCPROVIER) == CPR_FAILURE ) - { - err_msg("%s: Unable to send THREAD_UNLOAD msg to CCapp thread", fname); - } - err_msg("%s: send UNLOAD msg to CCapp thread good", fname); - } - break; - - default: - err_msg("%s: Unknown destination task passed=%d.", fname, dest_id); - break; - } -} - -/* - * Function: ccUnload - * - * Description: - * - deinit portable runtime. - * - Cleanup call control modules, GSM and SIp Stack - * - * Parameters: none - * - * Returns: none - * - */ -void -ccUnload (void) -{ - static const char fname[] = "ccUnload"; - - DEF_DEBUG(DEB_F_PREFIX"ccUnload called..\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - if (platform_initialized == FALSE) - { - TNP_DEBUG(DEB_F_PREFIX"system is not loaded, ignore unload\n", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - return; - } - /* - * We are going to send an unload msg to each of the thread, which on - * receiving the msg, will kill itself. - */ - send_task_unload_msg(CC_SRC_SIP); - send_task_unload_msg(CC_SRC_GSM); - - if (FALSE == gHardCodeSDPMode) { - send_task_unload_msg(CC_SRC_MISC_APP); - } - - send_task_unload_msg(CC_SRC_CCAPP); - - cprSleep(200); - - gStopTickTask = TRUE; -} - diff --git a/libs/sipcc/core/common/logger.c b/libs/sipcc/core/common/logger.c deleted file mode 100755 index 6715c62ab6..0000000000 --- a/libs/sipcc/core/common/logger.c +++ /dev/null @@ -1,87 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_string.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "stdarg.h" -#include "logger.h" -#include "logmsg.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "uiapi.h" -#include "platform_api.h" -#include "prot_configmgr.h" - -#define MAX_LOG_CACHE_ENTRIES 20 - -/* - * Log a message. - * Cause the message to be printed to the console port - * as well, the log is stored in a local data area for - * later viewing - */ -void -log_msg (int phrase_index, ...) -{ - char phrase_buf[LOG_MAX_LEN * 4]; - char status_msg[LOG_MAX_LEN * 4]; - va_list ap; - - /* - * Make sure that the phrase index is valid. - */ - if (phrase_index == 0) { - return; - } - - /* - * Get the translated phrase index from the Java code. - */ - if (platGetPhraseText(phrase_index, phrase_buf, (LOG_MAX_LEN * 4)) == CPR_FAILURE) { - return; - } - - /* - * If extra data is required, sprintf this into the status message buffer - */ - va_start(ap, phrase_index); - vsprintf(status_msg, phrase_buf, ap); - va_end(ap); - - err_msg("%%%s\n", status_msg); - - /* - * For now, do not send the Registration messages over to the Java Status - * Logs. They come out too fast and will overwhelm the existing logging - * mechanism. We will need to implement a new mechanism in order to put - * these in the phone's status menu. - */ - switch (phrase_index) { - case LOG_REG_MSG: - case LOG_REG_RED_MSG: - case LOG_REG_AUTH_MSG: - case LOG_REG_AUTH_HDR_MSG: - case LOG_REG_AUTH_SCH_MSG: - case LOG_REG_CANCEL_MSG: - case LOG_REG_AUTH: - case LOG_REG_AUTH_ACK_TMR: - case LOG_REG_AUTH_NO_CRED: - case LOG_REG_AUTH_UNREG_TMR: - case LOG_REG_RETRY: - case LOG_REG_UNSUPPORTED: - case LOG_REG_AUTH_SERVER_ERR: - case LOG_REG_AUTH_GLOBAL_ERR: - case LOG_REG_AUTH_UNKN_ERR: - return; - - default: - break; - } - - ui_log_status_msg(status_msg); -} - - diff --git a/libs/sipcc/core/common/logger.h b/libs/sipcc/core/common/logger.h deleted file mode 100644 index 3a1465b1a1..0000000000 --- a/libs/sipcc/core/common/logger.h +++ /dev/null @@ -1,17 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _LOGGER_INCLUDED_H -#define _LOGGER_INCLUDED_H - -#define LOG_MAX_LEN 64 - -/* - * short form helper macros - */ -void log_msg(int log, ...); -void log_clear(int msg); -char *get_device_name(); - -#endif /* _LOGGER_INCLUDED_H */ diff --git a/libs/sipcc/core/common/logmsg.h b/libs/sipcc/core/common/logmsg.h deleted file mode 100644 index 29ee709b21..0000000000 --- a/libs/sipcc/core/common/logmsg.h +++ /dev/null @@ -1,42 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _LOGMSG_INCLUDED_H -#define _LOGMSG_INCLUDED_H - -#include "logger.h" - -/* - * Config messages - * The number denotes the string location in the Phone dictionary file - */ -#define LOG_CFG_PARSE_DIAL 1074 //"%d Error(s) Parsing: %s" - -/* - * SIP messages - * The number denotes the string location in the Phone dictionary file - */ -#define LOG_REG_MSG 1058 //"REG send failure: REGISTER" -#define LOG_REG_RED_MSG 1059 //"REG send failure: REGISTER Redirected" -#define LOG_REG_AUTH_MSG 1060 //"REG send failure: REGISTER auth" -#define LOG_REG_AUTH_HDR_MSG 1061 //"REG send failure: REGISTER auth hdr" -#define LOG_REG_AUTH_SCH_MSG 1062 //"REG send failure: REGISTER auth scheme" -#define LOG_REG_CANCEL_MSG 1063 //"REG send failure: CANCEL REGISTER" - -#define LOG_REG_AUTH 1064 //"REG auth failed: %s" -#define LOG_REG_AUTH_ACK_TMR 1065 //"REG auth failed: ack timer" -#define LOG_REG_AUTH_NO_CRED 1066 //"REG auth failed: no more credentials" -#define LOG_REG_AUTH_UNREG_TMR 1067 //"REG auth failed: unreg ack timer" -#define LOG_REG_RETRY 1068 //"REG retries exceeded" -#define LOG_REG_UNSUPPORTED 1069 //"REG msg unsupported: %s" - -#define LOG_REG_AUTH_SERVER_ERR 1070 //"REG auth failed: in %d, server error" -#define LOG_REG_AUTH_GLOBAL_ERR 1071 //"REG auth failed: in %d, global error" -#define LOG_REG_AUTH_UNKN_ERR 1072 //"REG auth failed: in %d, ??? error" - -#define LOG_REG_BACKUP 1073 //"REG Not Registered to Backup Proxy" - -#define LOG_REG_EXPIRE 1076 //"REG Expires time too small" - -#endif /* _LOGMSG_INCLUDED_H */ diff --git a/libs/sipcc/core/common/misc.c b/libs/sipcc/core/common/misc.c deleted file mode 100644 index fa264d5397..0000000000 --- a/libs/sipcc/core/common/misc.c +++ /dev/null @@ -1,391 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include -#include -#include - -#include "cpr.h" -#include "phone_debug.h" -#include "cc_debug.h" -#include "phone.h" -#include "cpr_socket.h" -#include "prot_configmgr.h" -#include "debug.h" -#include "cpr_string.h" -#include "cpr_stdlib.h" - -/*-------------------------------------------------------------------------- - * Local definitions - *-------------------------------------------------------------------------- - */ - -/* NTP related local data */ -#define MAX_NTP_MONTH_STR_LEN 4 -#define MAX_NTP_MONTH_ARRAY_SIZE 12 -#define MAX_NTP_DATE_HDR_STR_LEN 128 -#define MAX_NTP_TOKEN_BUF_LEN 16 - -/* The number of arguments (argc) used in the show command */ -#define NUM_OF_SHOW_ARGUMENTS 2 - -#if 0 -static int last_month = 99; -static char last_month_str[MAX_NTP_MONTH_STR_LEN] = ""; -static const char *month_ar[MAX_NTP_MONTH_ARRAY_SIZE] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; -#endif - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ - -extern void platform_set_time(int32_t gmt_time); -void SipNtpUpdateClockFromCCM(void); - - -/*-------------------------------------------------------------------------- - * Local scope function prototypes - *-------------------------------------------------------------------------- - */ - -#if 0 -/* - * This function finds month (0 to 11) from month name - * listed above in month_ar[]. This is used to convert the - * date header from CCM to derive time/date. - */ -static boolean -set_month_from_str (char *month_str) -{ - boolean ret_val = FALSE; - const char * fname = "set_month_from_str"; - int i; - - if (month_str) { - if (strncmp(month_str, last_month_str, 3) != 0) { - for (i = 0; i < 12; i++) { - if (strncmp(month_str, month_ar[i], 3) == 0) { - sstrncpy(last_month_str, month_str, sizeof(last_month_str)); - last_month = i; - ret_val = TRUE; - break; - } - } - } else { - ret_val = TRUE; - } - } else { - TNP_DEBUG(DEB_F_PREFIX "Input month_str is NULL!!!! \n", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } - return (ret_val); -} -#endif - - -/* - * MISC platform stubs - * These stubs are mostly NOPs for TNP but they are referred from common code - * and this avoids ifdefs in the code. - * - */ -static uint16_t PHNState = STATE_CONNECTED; - -/* ccsip_core.o */ -uint16_t -PHNGetState (void) -{ - return (PHNState); -} - -void -PHNChangeState (uint16_t state) -{ - PHNState = state; -} - -/* ccsip_platform.o */ -void -phone_reset (DeviceResetType resetType) -{ - return; -} - - -/* - * Methods below should be moved to plat as they are exported as an external API. - * For now keeping all miscellaneous methods here. - */ -extern void config_get_value (int id, void *buffer, int length); - -/*logger.c */ - -/* - * Clear an entry or multiple entries in the - * log table. The passed in log message is used - * for partial matching, in order to figure out - * what logs need to be cleared. - * - * The TNP Status Message screen does not have any - * facility to "clear" log messages. - */ -void -log_clear (int msg) -{ -} - - -/** - * - * Indicates if the (preferred) network interface has changed (e.g., dock/undock) - * - * @param none - * - * - * @return true if the (preferred) network interface has changed since last query - * @return false if the (preferred) network interface has not changed - */ -boolean plat_is_network_interface_changed (void) -{ - return(FALSE); -} - - -/** - * give the platform IPV6 IP address. - * - * @param[in/out] ip_addr - pointer to the cpr_ip_addr_t. The - * result IP address will be populated in this - * structure. - * - * @return None. - */ -void -platform_get_ipv6_address (cpr_ip_addr_t *ip_addr) -{ - //config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); - //Todo IPv6: Hack to get the IPV6 address - //if (ip_mode == CPR_IP_MODE_IPV6 || ip_mode == CPR_IP_MODE_DUAL) { - //} - ip_addr->type = CPR_IP_ADDR_IPV6; - ip_addr->u.ip6.addr.base8[15] = 0x65; - ip_addr->u.ip6.addr.base8[14] = 0xfb; - ip_addr->u.ip6.addr.base8[13] = 0xb1; - ip_addr->u.ip6.addr.base8[12] = 0xfe; - ip_addr->u.ip6.addr.base8[11] = 0xff; - ip_addr->u.ip6.addr.base8[10] = 0x11; - ip_addr->u.ip6.addr.base8[9] = 0x11; - ip_addr->u.ip6.addr.base8[8] = 0x02; - ip_addr->u.ip6.addr.base8[7] = 0x01; - ip_addr->u.ip6.addr.base8[6] = 0x00; - ip_addr->u.ip6.addr.base8[5] = 0x18; - ip_addr->u.ip6.addr.base8[4] = 0x0c; - ip_addr->u.ip6.addr.base8[3] = 0xb8; - ip_addr->u.ip6.addr.base8[2] = 0x0d; - ip_addr->u.ip6.addr.base8[1] = 0x01; - ip_addr->u.ip6.addr.base8[0] = 0x20; - - return; -} - -/** - * give the mac address string - * - * @param addr - mac address string (OUTPUT) - * - * @return none - */ -void -platform_get_wired_mac_address (unsigned char *addr) -{ - config_get_value(CFGID_MY_MAC_ADDR, addr, 6); - TNP_DEBUG(DEB_F_PREFIX"Wired MacAddr:from Get Val: %04x:%04x:%04x", - DEB_F_PREFIX_ARGS(PLAT_API, "platform_get_wired_mac_address"), - addr[0] * 256 + addr[1], addr[2] * 256 + addr[3], - addr[4] * 256 + addr[5]); -} - -/** - * Get active mac address if required - * - * @param addr - mac address string (OUTPUT) - * - * @return none - */ -void -platform_get_active_mac_address (unsigned char *addr) -{ - config_get_value(CFGID_MY_ACTIVE_MAC_ADDR, addr, 6); - TNP_DEBUG(DEB_F_PREFIX"ActiveMacAddr:from Get Val: %04x:%04x:%04x", - DEB_F_PREFIX_ARGS(PLAT_API, "platform_get_mac_address"), - addr[0] * 256 + addr[1], addr[2] * 256 + addr[3], - addr[4] * 256 + addr[5]); -} - -/** - * give the platform IPV4 IP address. - * - * @param[in/out] ip_addr - pointer to the cpr_ip_addr_t. The - * result IP address will be populated in this - * structure. - * - * @return None. - */ -void -platform_get_ipv4_address (cpr_ip_addr_t *ip_addr) -{ - config_get_value(CFGID_MY_IP_ADDR, ip_addr, sizeof(cpr_ip_addr_t)); - ip_addr->type = CPR_IP_ADDR_IPV4; - - return; -} - -uint32_t -IPNameCk (char *name, char *addr_error) -{ - char *namePtr = name; - char string[4] = { 0, 0, 0, 0 }; - int x = 0; - int i = 0; - uint32_t temp, ip_addr = 0; - char ip_addr_out[MAX_IPADDR_STR_LEN]; - unsigned long strtoul_result; - char *strtoul_end; - - /* Check if valid IPv6 address */ - if (cpr_inet_pton(AF_INET6, name, ip_addr_out)) { - *addr_error = FALSE; - return TRUE; - } - *addr_error = TRUE; - while (*namePtr != 0) { - if ((*namePtr >= 0x30) && (*namePtr <= 0x39)) { - if (x > 2) - return (0); - string[x++] = *namePtr++; - } else { - if (*namePtr == 0x2e) { - if (i > 3) - return (0); - namePtr++; - x = 0; - - errno = 0; - strtoul_result = strtoul(string, &strtoul_end, 10); - - if (errno || string == strtoul_end || strtoul_result > 255) { - return 0; - } - - temp = (uint32_t) strtoul_result; - - ip_addr |= temp << (24 - (i * 8)); - string[0] = 0; - string[1] = 0; - string[2] = 0; - i++; - } else - return (0); // not an IP address - } - } - - if (i == 3) { - errno = 0; - strtoul_result = strtoul(string, &strtoul_end, 10); - - if (errno || string == strtoul_end || strtoul_result > 255) { - return 0; - } - - temp = (uint32_t) strtoul_result; - - ip_addr |= temp; - *addr_error = FALSE; - return (ntohl(ip_addr)); - } else { - return 0; - } -} - -/** - * @brief Given a msg buffer, returns a pointer to the buffer's header - * - * The cprGetSysHeader function retrieves the system header buffer for the - * passed in message buffer. - * - * @param[in] buffer pointer to the buffer whose sysHdr to return - * - * @return Abstract pointer to the msg buffer's system header - * or #NULL if failure - */ -void * -cprGetSysHeader (void *buffer) -{ - phn_syshdr_t *syshdr; - - /* - * Stinks that an external structure is necessary, - * but this is a side-effect of porting from IRX. - */ - syshdr = cpr_calloc(1, sizeof(phn_syshdr_t)); - if (syshdr) { - syshdr->Data = buffer; - } - return (void *)syshdr; -} - -/** - * @brief Called when the application is done with this system header - * - * The cprReleaseSysHeader function returns the system header buffer to the - * system. - * @param[in] syshdr pointer to the sysHdr to be released - * - * @return none - */ -void -cprReleaseSysHeader (void *syshdr) -{ - if (syshdr == NULL) { - CPR_ERROR("cprReleaseSysHeader: Sys header pointer is NULL\n"); - return; - } - - cpr_free(syshdr); -} - -/** - * @brief An internal function to update the system header - * - * A CPR-only function. Given a sysHeader and data, this function fills - * in the data. The purpose for this function is to help prevent CPR - * code from having to know about the phn_syshdr_t layout. - * - * @param[in] buffer pointer to a syshdr from a successful call to - * cprGetSysHeader - * @param[in] cmd command to place in the syshdr buffer - * @param[in] len length to place in the syshdr buffer - * @param[in] timerMsg msg being sent to the calling thread - * - * @return none - * - * @pre (buffer != NULL) - */ -void -fillInSysHeader (void *buffer, uint16_t cmd, uint16_t len, void *timerMsg) -{ - phn_syshdr_t *syshdr; - - syshdr = (phn_syshdr_t *) buffer; - syshdr->Cmd = cmd; - syshdr->Len = len; - syshdr->Usr.UsrPtr = timerMsg; - return; -} - diff --git a/libs/sipcc/core/common/plat.c b/libs/sipcc/core/common/plat.c deleted file mode 100644 index bbbcf6144c..0000000000 --- a/libs/sipcc/core/common/plat.c +++ /dev/null @@ -1,89 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "cpr.h" -#include "phone_debug.h" -#include "CCProvider.h" -#include "ccsip_pmh.h" -#include "sessionTypes.h" -#include "ccapp_task.h" - -// Why don't we modify strlib_malloc to handle NULL? -#define STRLIB_CREATE(str) (str)?strlib_malloc((str), strlen((str))):strlib_empty() - -void -platform_apply_config (char * configVersionStamp, - char * dialplanVersionStamp, - char * fcpVersionStamp, - char * cucmResult, - char * loadId, - char * inactiveLoadId, - char * loadServer, - char * logServer, - boolean ppid); -/** - * This function calls the JNI function to sends the information received - * in apply-config NOTIFY message to Java side. - * - * @param configVersionStamp - version stamp for config file - * @param dialplanVersionStamp - version stamp for the dialplan file - * @param fcpVersionStamp - version stamp for the softkey file (?) - * @param cucmResult - CUCM result after applying config by CUCM - * @param loadId - loadId to upgrade as requested by CUCM - * @param inactiveLoadId - inactive loadId for inactive partition as requested by CUCM - * @param loadServer - load server form where to pick loadId - * @param logServer - log server for logging output of peer to peer upgrade. - * @param ppid - specify whether peer to peer upgrade is enabled/disabled. - * - * @return none - */ -void -platform_apply_config (char * configVersionStamp, - char * dialplanVersionStamp, - char * fcpVersionStamp, - char * cucmResult, - char * loadId, - char * inactiveLoadId, - char * loadServer, - char * logServer, - boolean ppid) -{ - static const char fname[] = "platform_apply_config"; - session_mgmt_t msg; - - fcpVersionStamp = (fcpVersionStamp != NULL) ? fcpVersionStamp : ""; - - /// Print the arguments - CCAPP_DEBUG(DEB_F_PREFIX" configVersionStamp=%s \ndialplanVersionStamp=%s" - "\nfcpVersionStamp=%s \ncucmResult=%s " - "\nloadId=%s \ninactiveLoadId=%s \nloadServer=%s \nlogServer=%s " - "\nppid=%s\n", DEB_F_PREFIX_ARGS(PLAT_API, fname), - (configVersionStamp != NULL) ? configVersionStamp : "", - (dialplanVersionStamp != NULL) ? dialplanVersionStamp:"", - fcpVersionStamp, - cucmResult != NULL ? cucmResult: "", - (loadId != NULL) ? loadId : "", - (inactiveLoadId != NULL) ? inactiveLoadId : "", - (loadServer != NULL) ? loadServer : "", - (logServer != NULL) ? logServer : "", - ppid == TRUE? "True": "False"); - - - // following data is freed in function freeSessionMgmtData() - msg.func_id = SESSION_MGMT_APPLY_CONFIG; - msg.data.config.config_version_stamp = STRLIB_CREATE(configVersionStamp); - msg.data.config.dialplan_version_stamp = STRLIB_CREATE(dialplanVersionStamp); - msg.data.config.fcp_version_stamp = STRLIB_CREATE(fcpVersionStamp); - msg.data.config.cucm_result = STRLIB_CREATE(cucmResult); - msg.data.config.load_id = STRLIB_CREATE(loadId); - msg.data.config.inactive_load_id = STRLIB_CREATE(inactiveLoadId); - msg.data.config.load_server = STRLIB_CREATE(loadServer); - msg.data.config.log_server = STRLIB_CREATE(logServer); - msg.data.config.ppid = ppid; - - if ( ccappTaskPostMsg(CCAPP_SESSION_MGMT, &msg, sizeof(session_mgmt_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send platform_apply_config msg\n", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } -} diff --git a/libs/sipcc/core/common/platform_api.c b/libs/sipcc/core/common/platform_api.c deleted file mode 100755 index 233ce10be6..0000000000 --- a/libs/sipcc/core/common/platform_api.c +++ /dev/null @@ -1,396 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include "cpr.h" -#include "cpr_string.h" -#include "phone_debug.h" -#include "prot_configmgr.h" -#include "phone.h" -#include "CCProvider.h" -#include "cpr_stdlib.h" -#include "ccsip_pmh.h" -#include "platform_api.h" -#include -#include "ccapp_task.h" - -/*-------------------------------------------------------------------------- - * Local definitions - *-------------------------------------------------------------------------- - */ -#define PLT_F_PREFIX "PLT : %s : " // requires 1 arg: fname -// Why don't we modify strlib_malloc to handle NULL? -#define STRLIB_CREATE(str) (str)?strlib_malloc((str), strlen((str))):strlib_empty() - -/*-------------------------------------------------------------------------- - * Global data - *-------------------------------------------------------------------------- - */ - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ - -void platform_sync_cfg_vers(char *cfg_ver, char *dp_ver, char *softkey_ver); -void platform_reg_fallback_ind(int fallback_to); -void platform_reg_failover_ind(int failover_to); - - -/*-------------------------------------------------------------------------- - * Local scope function prototypes - *-------------------------------------------------------------------------- - */ - - -/** - * give the platform IP address mode. This is a temporary function - * until config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)) - * is fully implemented (P2). - * - * @param none - * - * @return CPR_IP_MODE_IPV4, - * CPR_IP_MODE_IPV6, - * CPR_IP_MODE_DUAL - */ -cpr_ip_mode_e -platform_get_ip_address_mode (void) -{ - cpr_ip_mode_e ip_mode; - - //config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); - - /* fake mode to what ever mode under test here */ - ip_mode = CPR_IP_MODE_IPV4; - - return (ip_mode); -} - - -/** - * Send a reset or restart request to the adapter - * - * @param action - reset or restart - * @return none - * - */ -void -platform_reset_req (DeviceResetType action) -{ - static const char fname[] = "platform_reset_req"; - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"***********%s, requested***********\n", - DEB_F_PREFIX_ARGS(PLAT_API, fname), - (action==1)? "RESET":"RESTART"); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_SERVICE_CONTROL_REQ; - msg.update.ccFeatUpd.data.reset_type = action; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send platform_reset_req(%d) msg \n", DEB_F_PREFIX_ARGS(PLAT_API, fname), action); - } -} - -/** - * Ask the platform to sync with versions got from call control - * or outside entity. As part of the sync, platform downloads - * the files if required. - * - * @param cfg_ver - version stamp for config file - * @param dp_ver - version stamp for the dialplan file - * @param softkey_ver - version stamp for the softkey file. - * - * @return none - */ -void -platform_sync_cfg_vers (char *cfg_ver, char *dp_ver, char *softkey_ver) -{ - static const char fname[] = "platform_sync_cfg_vers"; - char empty_string[] = ""; - feature_update_t msg; - - if (cfg_ver == NULL) { - cfg_ver = empty_string; - } - if (dp_ver == NULL) { - dp_ver = empty_string; - } - if (softkey_ver == NULL) { - softkey_ver = empty_string; - } - - CCAPP_DEBUG(DEB_F_PREFIX"cfg_ver=%s dp_ver=%s sk_ver=%s\n", DEB_F_PREFIX_ARGS(PLAT_API, fname), - cfg_ver, dp_ver, softkey_ver); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_SYNC_CONFIG_VERSION; - msg.update.ccFeatUpd.data.cfg_ver_data.cfg_ver = strlib_malloc(cfg_ver, strlen(cfg_ver)); - msg.update.ccFeatUpd.data.cfg_ver_data.dp_ver = strlib_malloc(dp_ver, strlen(dp_ver)); - msg.update.ccFeatUpd.data.cfg_ver_data.softkey_ver = strlib_malloc(softkey_ver, strlen(softkey_ver)); - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send platform_sync_cfg_vers msg \n", - DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } -} - - -/** - * - * Tell platform to adjust the time to the gmt_time received from outside - * For sip the "outside" is from the "Date" header coming from a CCM or - * any other Server - * - * @param gmt_time - GMT time in seconds - * - * @return none - */ -void -platform_set_time (long gmt_time) -{ - static const char fname[] = "platform_set_time"; - session_mgmt_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX"setting time to=%ld", DEB_F_PREFIX_ARGS(PLAT_API, fname), gmt_time); - - msg.func_id = SESSION_MGMT_SET_TIME; - msg.data.time.gmt_time = gmt_time; - - if ( ccappTaskPostMsg(CCAPP_SESSION_MGMT, &msg, sizeof(session_mgmt_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send platform_set_time msg\n", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } -} - - -/** - * - * Indicate to the platform that reg manager wants to failover to a Call - * control indicated in failover_to. A corresponding ccRegFailoverRsp() - * will be issued by the platform once the failover indication is processed. - * - * @param failover_to - type of call control, - * e.g. cip_sipcc_CcMgmtConst_CC_TYPE_CCM - * @return none - */ -void -platform_reg_failover_ind (int failover_to) -{ - static const char fname[] = "platform_reg_failover_ind"; - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"***********Failover to %s=%d ***********\n", - DEB_F_PREFIX_ARGS(PLAT_API, fname), - failover_to == CC_TYPE_CCM ? "CC_TYPE_CCM" : - "Other", failover_to); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_FAILOVER_IND; - msg.update.ccFeatUpd.data.line_info.info = failover_to; - - if ( ccappTaskPostMsg(CCAPP_FAILOVER_IND, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send platform_reg_failover_ind(%d) msg \n", fname, failover_to); - } - -} - - -/** - * Indicate to the platform that reg manager intends to fallback to - * primary CCM. Currently the fallback_to is always to CC_TYPE_CCM. - * - * @param fallback_to - type of call control, - * e.g. cip_sipcc_CcMgmtConst_CC_TYPE_CCM - * - * @return none - */ -void -platform_reg_fallback_ind (int fallback_to) -{ - static const char fname[] = "platform_reg_fallback_ind"; - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"***********Fallback to %d CUCM.***********\n", - DEB_F_PREFIX_ARGS(PLAT_API, fname), - fallback_to); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_FALLBACK_IND; - msg.update.ccFeatUpd.data.line_info.info = fallback_to; - - if ( ccappTaskPostMsg(CCAPP_FALLBACK_IND, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send platform_reg_fallback_ind(%d) msg \n", fname, fallback_to); - } -} - -/** - * - * Indicate to the platform that current fallback activity - * is complete i.e. either success or encountered an error - * and that the platform should put the User interaction back - * in service. - * - * @param none - * - * @return none - */ -void -platform_reg_fallback_cfm (void) -{ - static const char fname[] = "platform_reg_fallback_cfm"; - - DEF_DEBUG(DEB_F_PREFIX"***********Fallback completed.***********\n", - DEB_F_PREFIX_ARGS(PLAT_API, fname)); -} - -/** - * - * Indicate to the platform that current failover activity - * is complete i.e. either success or encountered an error - * and that the platform should put the User interaction back - * in service. - * - * @param none - * - * @return none - */ -void -platform_reg_failover_cfm (void) -{ - static const char fname[] = "platform_reg_failover_cfm"; - - DEF_DEBUG(DEB_F_PREFIX"***********Failover completed.***********\n", - DEB_F_PREFIX_ARGS(PLAT_API, fname)); -} - - -/** - * - * Notify the platform that call control has shut down. - * - * @param none - * - * @return none - */ -void -shutdownCCAck (void) -{ - static const char fname[] = "shutdownCCAck"; - feature_update_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_SHUTDOWN_ACK; - - if ( ccappTaskPostMsg(CCAPP_SHUTDOWN_ACK, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send shutdownCCAck(%d) msg \n", fname); - } -} - -/** - * Notify the platform about the change in call control mode. - * - * @param mode - the call control mode. - * cip_sipcc_CcMgmtConst_CC_TYPE_CCM - * or cip_sipcc_CcMgmtConst_CC_TYPE_OTHER - * - * @return none - */ -void -platform_cc_mode_notify (int mode) -{ - static const char fname[] = "platform_cc_mode_notify"; - feature_update_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX"mode =%d\n", DEB_F_PREFIX_ARGS(PLAT_API, fname), mode); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_MODE_NOTIFY; - msg.update.ccFeatUpd.data.line_info.info = mode; - - if ( ccappTaskPostMsg(CCAPP_MODE_NOTIFY, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send platform_cc_mode_notify(%d) msg \n", fname, mode); - } -} - - -int -platform_get_phrase_text (int ndx, char *outstr, uint32_t len) -{ - static const char fname[] = "platform_get_phrase_text"; - session_mgmt_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX "index=%d\n", DEB_F_PREFIX_ARGS(PLAT_API, fname), ndx); - - msg.func_id = SESSION_MGMT_GET_PHRASE_TEXT; - msg.data.phrase_text.ndx = ndx; - msg.data.phrase_text.outstr = outstr; - msg.data.phrase_text.len = len; - - ccappSyncSessionMgmt(&msg); - - return msg.data.phrase_text.ret_val; -} - - -/*called from configapp.c. This routine will set the kpml - value on the java side and trigger it down to c-side. - Also, it will reinitialize the dialplan. */ -void -update_kpmlconfig(int kpmlVal) -{ - static const char fname[] = "update_kpmlconfig"; - session_mgmt_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX "kpml=%d\n", DEB_F_PREFIX_ARGS(PLAT_API, fname), kpmlVal); - - msg.func_id = SESSION_MGMT_UPDATE_KPMLCONFIG; - msg.data.kpmlconfig.kpml_val = kpmlVal; - - if ( ccappTaskPostMsg(CCAPP_SESSION_MGMT, &msg, sizeof(session_mgmt_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_DEBUG(DEB_F_PREFIX"failed to send update_kpmlconfig msg\n", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - } -} - - -boolean -check_speaker_headset_mode() -{ - static const char fname[] = "check_speaker_headset_mode"; - - CCAPP_DEBUG(DEB_F_PREFIX "checking SPEAKER and HEADSET active or not\n", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - - return platGetSpeakerHeadsetMode(); -} - - -/** - * - * Notify the platform to logout and reset. - * - * @param none - * - * @return none - */ - -void -platform_logout_reset_req(void){ - static const char fname[] = "platform_logout_reset_req"; - feature_update_t msg; - - CCAPP_DEBUG(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(PLAT_API, fname)); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_LOGOUT_RESET; - - if ( ccappTaskPostMsg(CCAPP_FALLBACK_IND, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(PLT_F_PREFIX"failed to send Logout_Reset(%d) msg \n", fname); - } - return; -} - diff --git a/libs/sipcc/core/common/prot_cfgmgr_private.h b/libs/sipcc/core/common/prot_cfgmgr_private.h deleted file mode 100755 index ddf609e629..0000000000 --- a/libs/sipcc/core/common/prot_cfgmgr_private.h +++ /dev/null @@ -1,431 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _PROT_CFGMGR_PRIVATE_H_ -#define _PROT_CFGMGR_PRIVATE_H_ - -#include "cpr_types.h" -#include "ccapi.h" -#include "ccsip_protocol.h" -//TEMPORARY REMOVAL #include "sntp.h" -#include "configmgr.h" -#include "dtmf.h" -#include "phone_platform_constants.h" - -#ifdef SAPP_SAPP_GSM -#define DEFAULT_PROTOCOL "sip" -#define SCCP_WELL_KNOWN_PORT_STR "2000" -#endif - -#define SIP_PLATFORM_CONFIG_DATE_TEMPLATE_24HOUR "M/D/Y" -#define SIP_PLATFORM_CONFIG_DATE_TEMPLATE_12HOUR "M/D/YA" - -#define DYNAMIC_DTMF_PAYLOAD_MIN 96 -#define DYNAMIC_DTMF_PAYLOAD_MAX 127 - -// Includes 3 CCMS -#define MAX_CCMS 4 - -#define MAX_CODEC_ENTRIES 10 -// updated MAX_LOAD_FILE_NAME to be in sync with XmlDefaultConfigParmObject -#define MAX_LOAD_FILE_NAME 65 - -/********************************************************* - * - * Config Block Definition - * This structure holds all of the parsed configuration - * information obtained from the TFTP config file - * - * To add new entries to the config table, please see - * the instructions in configmgr.h and prot_configmgr.h - * - * note: IP addresses are internally stored in the - * Telecaster "Byte Reversed" order. - * Eg. 0xf8332ca1 = 161.44.51.248 - * - ********************************************************/ -typedef struct -{ - int feature; - int index; - int maxnumcalls; - int busy_trigger; - char name[MAX_LINE_NAME_SIZE]; - char authname[AUTH_NAME_SIZE]; - char password[MAX_LINE_PASSWORD_SIZE]; - char displayname[MAX_LINE_NAME_SIZE]; // Actually we allow upto 32 UTF-8 chars which typically needs 32*3 octets. - char contact[MAX_LINE_CONTACT_SIZE]; - int autoanswer; - char autoanswer_mode[MAX_LINE_AUTO_ANS_MODE_SIZE]; - int call_waiting; - int msg_waiting_lamp; - int msg_waiting_amwi; - int ring_setting_idle; - int ring_setting_active; - char proxy_address[MAX_IPADDR_STR_LEN]; - int proxy_port; - char cfwdall[MAX_URL_LENGTH]; - char speeddial_number[MAX_LINE_NAME_SIZE]; - char retrieval_prefix[MAX_LINE_NAME_SIZE]; - char messages_number[MAX_LINE_NAME_SIZE]; - int fwd_caller_name_display; - int fwd_caller_number_display; - int fwd_redirected_number_display; - int fwd_dialed_number_display; - int feature_option_mask; -} line_cfg_t; - -typedef struct -{ - char address[MAX_IPADDR_STR_LEN]; - char ipv6address[MAX_IPADDR_STR_LEN]; - int sip_port; - int sec_level; - int is_valid; -} ccm_cfg_t; - -typedef struct -{ - cpr_ip_addr_t my_ip_addr; - uint8_t my_mac_addr[6]; - - line_cfg_t line[MAX_CONFIG_LINES]; - ccm_cfg_t ccm[MAX_CCMS]; - int proxy_register; - int sip_retx; /* SIP retransmission count */ - int sip_invite_retx; /* SIP INVITE request retransmission count */ - int timer_t1; /* SIP T1 timer value */ - int timer_t2; /* SIP T2 timer value */ - int timer_invite_expires; /* SIP Expires timer value */ - int timer_register_expires; - /* - * preferred codec is kept as key_table_entry structure. The - * name field of the key is a primary indication whether the - * parameter is configured or not. This is because the - * zero value is a designated value for G711 and the -1 is - * for no codec. The -1 is not natural value of uninitialized - * variable therefore keep the codec as name and value pair. - * The missing of the name indiates there the parameter is not - * configured. - */ - key_table_entry_t preferred_codec; - int dtmf_db_level; - DtmfOutOfBandTransport_t dtmf_outofband; - int dtmf_avt_payload; - int callerid_blocking; - int dnd_call_alert; - int dnd_reminder_timer; - int blf_alert_tone_idle; - int blf_alert_tone_busy; - int auto_pickup_enabled; - int call_hold_ringback; - int stutter_msg_waiting; - int call_stats; - int auto_answer; - int anonymous_call_block; - int nat_enable; - char nat_address[MAX_IPADDR_STR_LEN]; - int voip_control_port; - unsigned int media_port_start; - unsigned int media_port_end; - char sync[MAX_SYNC_LEN]; - char proxy_backup[MAX_IPADDR_STR_LEN]; - char proxy_emergency[MAX_IPADDR_STR_LEN]; - int proxy_backup_port; - int proxy_emergency_port; - int nat_received_processing; - - char proxy_outbound[MAX_IPADDR_STR_LEN]; - int proxy_outbound_port; - char reg_user_info[MAX_REG_USER_INFO_LEN]; - int cnf_join_enable; - int remote_party_id; - int semi_xfer; - char cfwd_uri[MAX_URL_LENGTH]; - int local_cfwd_enable; - int timer_register_delta; - int rfc_2543_hold; - int sip_max_forwards; - int conn_monitor_duration; - char call_pickup_uri[MAX_URL_LENGTH]; - char call_pickup_list_uri[MAX_URL_LENGTH]; - char call_pickup_group_uri[MAX_URL_LENGTH]; - char meet_me_service_uri[MAX_URL_LENGTH]; - char call_forward_uri[MAX_URL_LENGTH]; - char abbreviated_dial_uri[MAX_URL_LENGTH]; - int call_log_blf_enabled; - int remote_cc_enabled; - int timer_keepalive_expires; - int timer_subscribe_expires; - int timer_subscribe_delta; - int transport_layer_prot; - int kpml; - int enable_vad; - int autoanswer_idle_alt; - int autoanswer_timer; - int autoanswer_override; - int offhook_to_first_digit; - int call_waiting_period; - int ring_setting_busy_pol; - int dscp_for_call_control; - int speaker_enabled; - int xfr_onhook_enabled; - int retain_forward_information; - int rollover; - int join_across_lines; - int emcc_mode; - int visiting_em_port; - char visiting_em_ip[MAX_IPADDR_STR_LEN]; - int ip_addr_mode; - char load_file[MAX_LOAD_FILE_NAME]; - int inter_digit_timer; - int dscp_audio; - int dscp_video; - char deviceName[MAX_REG_USER_INFO_LEN]; - uint8_t my_active_mac_addr[6]; - char userAgent[MAX_REG_USER_INFO_LEN]; - char modelNumber[MAX_REG_USER_INFO_LEN]; - int srst_is_secure; - char join_dxfer_policy[MAX_JOIN_DXFER_POLICY_SIZE]; - char external_number_mask[MAX_EXTERNAL_NUMBER_MASK_SIZE]; - char media_ip_addr[MAX_IPADDR_STR_LEN]; - int p2psip; - int sdpmode; - char version[4]; - int rtcpmux; - int rtpsavpf; - int maxavbitrate; - int maxcodedaudiobw; - int usedtx; - int stereo; - int useinbandfec; - int cbr; - int maxptime; - int sctp_port; - int num_data_streams; -} prot_cfg_t; - -static prot_cfg_t prot_cfg_block; - - -/********************************************************* - * return (1); - * Config Table Keytable Structures - * - * Some config table entries can only contain special return (1); - * values. Those entries must specify a key table - * that contains valid values for the entry. - * - *********************************************************/ -/* - * codec_table table is used for parsing configured preferred - * codec, J-side caches string and it is converted to the enumerated - * value during reset/restart. The "none" value is currently used - * by CUCM' TFTP when there is no preferred codec configured and - * therefore the "none" is included in the table. - */ -static const key_table_entry_t codec_table[] = { - {"g711ulaw", RTP_PCMU}, - {"g711alaw", RTP_PCMA}, - {"g729a", RTP_G729}, - {"L16", RTP_L16}, -#ifdef CISCOWB_SUPPORTED - {"CiscoWb", RTP_CISCOWB}, -#endif - {"g722", RTP_G722}, - {"iLBC", RTP_ILBC}, - {"iSAC", RTP_ISAC}, - {"opus", RTP_OPUS}, - {"none", RTP_NONE}, - {0, RTP_NONE} -}; - -static const key_table_entry_t dtmf_outofband_table[] = { - {"none", DTMF_OUTOFBAND_NONE}, - {"avt", DTMF_OUTOFBAND_AVT}, - {"avt_always", DTMF_OUTOFBAND_AVT_ALWAYS}, - {0, 0} -}; - -static const key_table_entry_t user_info_table[] = { - {"none", 0,}, - {"phone", 1,}, - {"ip", 2,}, - {0, 0,} -}; - -/********************************************************* - *!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * SIP Protocol Config table Variable Name and Type Definitions - * - * This table defines all the possible variables that can - * be set in the TFTP config file (if used). - * var: Is the name as it is defined in the ascii - * configuration file. - * addr: Is the address of where the parsed variable - * is stored into memory - * len: Is the length of the item in kazoo memory. - * (Important for things like strings) - * parser: Is a function pointer to a routine that is - * used to parse (convert) this particular - * variable from ascii form to internal form. - * print: Is a function pointer to a routine that is - * used to print (convert) this particular - * variable from internal form to ascii form. - * keytable: Defines the table of values that this entry - * can have. - * - *!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Before changing any these, please read the following: - * - * This table MUST be kept in sync with the configuration - * ID enums located in the prot_configmgr.h - * file. There is a one-to-one correspondence between those - * enums and this table. - * - * To add or remove config properties, please refer to the - * file prot_configmgr.h. - * - *!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - *********************************************************/ - /********************************************************* - * - * Platform-Specific Configuration Section - * (Common across all IP Phone protocols.) - * - ********************************************************/ - -/* name {addr & len} parser print */ -/* ------------------------ ----------------- ------ ------ */ -var_t prot_cfg_table[CFGID_PROTOCOL_MAX+1] = { - /* 0 */{"startMediaPort",CFGVAR(media_port_start), PA_INT, PR_INT, 0}, - {"endMediaPort", CFGVAR(media_port_end), PA_INT, PR_INT, 0}, - {"callerIdBlocking", CFGVAR(callerid_blocking), PA_INT, PR_INT, 0}, - {"anonymousCallBlock", CFGVAR(anonymous_call_block), PA_INT, PR_INT, 0}, - {"dndCallAlert", CFGVAR(dnd_call_alert), PA_INT, PR_INT, 0}, - {"dndReminderTimer", CFGVAR(dnd_reminder_timer), PA_INT, PR_INT, 0}, - {"preferredCode", CFGVAR(preferred_codec), PA_KEYE, PR_KEYE, codec_table}, - {"dtmfOutofBand",CFGVAR(dtmf_outofband), PA_KEY, PR_KEY, dtmf_outofband_table}, - {"dtmfAvtPayload", CFGVAR(dtmf_avt_payload), PA_INT, PR_INT, 0}, - {"dtmfDbLevel", CFGVAR(dtmf_db_level), PA_INT, PR_INT, 0}, - {"sipRetx", CFGVAR(sip_retx), PA_INT, PR_INT, 0}, - /*11*/ {"sipInviteRetx", CFGVAR(sip_invite_retx), PA_INT, PR_INT, 0}, - {"timerT1", CFGVAR(timer_t1), PA_INT, PR_INT, 0}, - {"timerT2", CFGVAR(timer_t2), PA_INT, PR_INT, 0}, - {"timerInviteExpires", CFGVAR(timer_invite_expires), PA_INT, PR_INT, 0}, - {"timerRegisterExpires", CFGVAR(timer_register_expires), PA_INT, PR_INT, 0}, - {"registerWithProxy", CFGVAR(proxy_register), PA_INT, PR_INT, 0}, - {"backupProxy", CFGVAR(proxy_backup), PA_STR, PR_STR, 0}, - {"backupProxyPort", CFGVAR(proxy_backup_port), PA_INT, PR_INT, 0}, - {"emergencyProxy", CFGVAR(proxy_emergency), PA_STR, PR_STR, 0}, - {"emergencyProxyPort", CFGVAR(proxy_emergency_port), PA_INT, PR_INT, 0}, - {"outboundProxy", CFGVAR(proxy_outbound), PA_STR, PR_STR, 0}, - {"outboundProxyPort", CFGVAR(proxy_outbound_port), PA_INT, PR_INT, 0}, - {"natReceivedProcessing", CFGVAR(nat_received_processing),PA_INT, PR_INT, 0}, - {"userInfo", CFGVAR(reg_user_info), PA_KEY, PR_KEY, user_info_table}, - {"cnfJoinEnable", CFGVAR(cnf_join_enable), PA_INT, PR_INT, 0}, - {"remotePartyID", CFGVAR(remote_party_id), PA_INT, PR_INT, 0}, - {"semiAttendedTransfer", CFGVAR(semi_xfer), PA_INT, PR_INT, 0}, - {"callHoldRingback", CFGVAR(call_hold_ringback), PA_INT, PR_INT, 0}, - {"stutterMsgWaiting", CFGVAR(stutter_msg_waiting), PA_INT, PR_INT, 0}, - {"callForwardUri", CFGVAR(cfwd_uri), PA_STR, PR_STR, 0}, - /*31*/ {"callStats", CFGVAR(call_stats), PA_INT, PR_INT, 0}, - {"autoAnswer", CFGVAR(auto_answer), PA_INT, PR_INT, 0}, - {"localCfwdEnable", CFGVAR(local_cfwd_enable), PA_INT, PR_INT, 0}, - {"timerRegisterDelta", CFGVAR(timer_register_delta), PA_INT, PR_INT, 0}, - {"MaxRedirects", CFGVAR(sip_max_forwards), PA_INT, PR_INT, 0}, - {"rfc2543Hold", CFGVAR(rfc_2543_hold), PA_INT, PR_INT, 0}, - {"ccm1_address", CFGVAR(ccm[0].address), PA_STR, PR_STR, 0}, - {"ccm2_address", CFGVAR(ccm[1].address), PA_STR, PR_STR, 0}, - {"ccm3_address", CFGVAR(ccm[2].address), PA_STR, PR_STR, 0}, - {"ccm1_ipv6address", CFGVAR(ccm[0].ipv6address), PA_STR, PR_STR, 0}, - {"ccm2_ipv6address", CFGVAR(ccm[1].ipv6address), PA_STR, PR_STR, 0}, - {"ccm3_ipv6address", CFGVAR(ccm[2].ipv6address), PA_STR, PR_STR, 0}, - {"ccm1_sipPort", CFGVAR(ccm[0].sip_port), PA_INT, PR_INT, 0}, - {"ccm2_sipPort", CFGVAR(ccm[1].sip_port), PA_INT, PR_INT, 0}, - {"ccm3_sipPort", CFGVAR(ccm[2].sip_port), PA_INT, PR_INT, 0}, - {"ccm1_securityLevel", CFGVAR(ccm[0].sec_level), PA_INT, PR_INT, 0}, - {"ccm2_securityLevel", CFGVAR(ccm[1].sec_level), PA_INT, PR_INT, 0}, - {"ccm3_securityLevel", CFGVAR(ccm[2].sec_level), PA_INT, PR_INT, 0}, - {"ccm1_isValid", CFGVAR(ccm[0].is_valid), PA_INT, PR_INT, 0}, - /*50*/ {"ccm2_isValid", CFGVAR(ccm[1].is_valid), PA_INT, PR_INT, 0}, - {"ccm3_isValid", CFGVAR(ccm[2].is_valid), PA_INT, PR_INT, 0}, - {"ccmTftp_ipAddr", CFGVAR(ccm[3].address), PA_STR, PR_STR, 0}, - {"ccmTftp_port", CFGVAR(ccm[3].sip_port), PA_INT, PR_INT, 0}, - {"ccmTftp_isValid", CFGVAR(ccm[3].is_valid), PA_INT, PR_INT, 0}, - {"ccmTftp_securityLevel", CFGVAR(ccm[3].sec_level), PA_INT, PR_INT, 0}, - {"ccmSrstIpAddr", CFGVAR(ccm[4].address), PA_STR, PR_STR, 0}, - {"ccmSrst_sipPort", CFGVAR(ccm[4].sip_port), PA_INT, PR_INT, 0}, - {"ccmSrst_isValid", CFGVAR(ccm[4].is_valid), PA_INT, PR_INT, 0}, - {"ccmSrst_securityLevel", CFGVAR(ccm[4].sec_level), PA_INT, PR_INT, 0}, - {"connectionMonitorDuration", CFGVAR(conn_monitor_duration), PA_INT, PR_INT, 0}, - {"callPickupURI", CFGVAR(call_pickup_uri), PA_STR, PR_STR, 0}, - {"callPickupListURI", CFGVAR(call_pickup_list_uri), PA_STR, PR_STR, 0}, - {"callPickupGroupURI", CFGVAR(call_pickup_group_uri), PA_STR, PR_STR, 0}, - {"meetMeServiceURI", CFGVAR(meet_me_service_uri), PA_STR, PR_STR, 0}, - {"callForwardURI", CFGVAR(call_forward_uri), PA_STR, PR_STR, 0}, - {"abbreviatedDialURI", CFGVAR(abbreviated_dial_uri), PA_STR, PR_STR, 0}, - {"callLogBlfEnabled", CFGVAR(call_log_blf_enabled), PA_INT, PR_INT, 0}, - {"remoteCcEnabled", CFGVAR(remote_cc_enabled), PA_INT, PR_INT, 0}, - {"retainForwardInformation", CFGVAR(retain_forward_information), PA_INT, PR_INT, 0}, - /*70*/ {"timerKeepaliveExpires", CFGVAR(timer_keepalive_expires),PA_INT, PR_INT, 0}, - {"timerSubscribeExpires", CFGVAR(timer_subscribe_expires),PA_INT, PR_INT, 0}, - {"timerSubscribeDelta", CFGVAR(timer_subscribe_delta), PA_INT, PR_INT, 0}, - {"transportLayerProtocol", CFGVAR(transport_layer_prot), PA_INT, PR_INT, 0}, - {"kpml", CFGVAR(kpml), PA_INT, PR_INT, 0}, - {"natEnable", CFGVAR(nat_enable), PA_INT, PR_INT, 0}, - {"natAddress", CFGVAR(nat_address), PA_STR, PR_STR, 0}, - {"voipControlPort", CFGVAR(voip_control_port), PA_INT, PR_INT, 0}, - {"myIpAddr", CFGVAR(my_ip_addr), PA_IP, PR_IP, 0}, - {"myMacAddr", CFGVAR(my_mac_addr), PA_STR, PR_MAC, 0}, - {"enableVad", CFGVAR(enable_vad), PA_INT, PR_INT, 0}, - {"autoAnswerAltBehavior", CFGVAR(autoanswer_idle_alt), PA_INT, PR_INT, 0}, - {"autoAnswerTimer", CFGVAR(autoanswer_timer), PA_INT, PR_INT, 0}, - {"autoAnswerOverride", CFGVAR(autoanswer_override), PA_INT, PR_INT, 0}, - {"offhookToFirstDigitTimer", CFGVAR(offhook_to_first_digit), PA_INT, PR_INT, 0}, - {"silentPeriodBetweenCallWaitingBursts", CFGVAR(call_waiting_period), PA_INT, PR_INT, 0}, - {"ringSettingBusyStationPolicy", CFGVAR(ring_setting_busy_pol), PA_INT, PR_INT, 0}, - {"DscpForCm2Dvce", CFGVAR(dscp_for_call_control), PA_INT, PR_INT, 0}, - {"speakerEnabled", CFGVAR(speaker_enabled), PA_INT, PR_INT, 0}, - {"transferOnhookEnable", CFGVAR(xfr_onhook_enabled), PA_INT, PR_INT, 0}, - /*90*/ {"rollover", CFGVAR(rollover), PA_INT, PR_INT, 0}, - {"loadFileName", CFGVAR(load_file), PA_STR, PR_STR, 0}, - {"blfAlertToneIdle", CFGVAR(blf_alert_tone_idle),PA_INT, PR_INT, 0}, - {"blfAlertToneBusy", CFGVAR(blf_alert_tone_busy),PA_INT, PR_INT, 0}, - {"autoPickupEnable", CFGVAR(auto_pickup_enabled),PA_INT, PR_INT, 0}, - {"joinAcrossLines", CFGVAR(join_across_lines), PA_INT, PR_INT, 0}, - /*96*/ {"myActiveMacAddr", CFGVAR(my_active_mac_addr), PA_STR, PR_MAC, 0}, - /*97*/ {"DscpAudio", CFGVAR(dscp_audio), PA_INT, PR_INT, 0}, - {"deviceName", CFGVAR(deviceName), PA_STR, PR_STR, 0}, - {"userAgent", CFGVAR(userAgent), PA_STR, PR_STR, 0}, - {"modelNumber", CFGVAR(modelNumber), PA_STR, PR_STR, 0}, - {"DscpVideo", CFGVAR(dscp_video), PA_INT, PR_INT, 0}, - {"IPAddrMode", CFGVAR(ip_addr_mode), PA_INT, PR_INT, 0}, - {"interDigitTimer", CFGVAR(inter_digit_timer), PA_INT, PR_INT, 0}, - {"emccMode", CFGVAR(emcc_mode), PA_INT, PR_INT, 0}, - {"visitingEMPort", CFGVAR(visiting_em_port), PA_INT, PR_INT, 0}, - {"visitingEMIpAddress", CFGVAR(visiting_em_ip), PA_STR, PR_STR, 0}, - {"isSRSTSecure", CFGVAR(srst_is_secure), PA_INT, PR_INT, 0}, -/*108*/ {"joinDxferPolicy", CFGVAR(join_dxfer_policy), PA_STR, PR_STR, 0}, - {"externalNumberMask", CFGVAR(external_number_mask), PA_STR, PR_STR, 0}, - {"mediaIpAddr", CFGVAR(media_ip_addr), PA_STR, PR_STR, 0}, - {"p2psip", CFGVAR(p2psip), PA_INT, PR_INT, 0}, - {"version", CFGVAR(version), PA_STR, PR_STR, 0}, - {"sdpmode", CFGVAR(sdpmode), PA_INT, PR_INT, 0}, - {"rtcpmux", CFGVAR(rtcpmux), PA_INT, PR_INT, 0}, - {"rtpsavpf", CFGVAR(rtpsavpf), PA_INT, PR_INT, 0}, - {"maxavbitrate", CFGVAR(maxavbitrate), PA_INT, PR_INT, 0}, - {"maxcodedaudiobw", CFGVAR(maxcodedaudiobw), PA_INT, PR_INT, 0}, - {"usedtx", CFGVAR(usedtx), PA_INT, PR_INT, 0}, - {"stereo", CFGVAR(stereo), PA_INT, PR_INT, 0}, - {"useinbandfec", CFGVAR(useinbandfec), PA_INT, PR_INT, 0}, - {"cbr", CFGVAR(cbr), PA_INT, PR_INT, 0}, - {"maxptime", CFGVAR(maxptime), PA_INT, PR_INT, 0}, - {"sctp_port", CFGVAR(sctp_port), PA_INT, PR_INT, 0}, - {"num_data_streams", CFGVAR(num_data_streams), PA_INT, PR_INT, 0}, - {0, 0, 0, 0, 0, 0} - }; - -#endif /* _PROT_CFGMGR_PRIVATE_H_ */ diff --git a/libs/sipcc/core/common/prot_configmgr.c b/libs/sipcc/core/common/prot_configmgr.c deleted file mode 100755 index 93da2d5c3d..0000000000 --- a/libs/sipcc/core/common/prot_configmgr.c +++ /dev/null @@ -1,890 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_in.h" -#include "util_string.h" -#include "task.h" -#include "upgrade.h" -#include "ccsip_task.h" -#include "config.h" -#include "ccsip_core.h" -#include "prot_configmgr.h" -#include "prot_cfgmgr_private.h" -#include "sip_common_transport.h" -#include "phone_debug.h" -#include "regmgrapi.h" -#include "rtp_defs.h" -#include "vcm.h" -#include "plat_api.h" - -#define MAX_TOS_VALUE 5 -#define MIN_VOIP_PORT_RANGE 1024 -#define MAX_VOIP_PORT_RANGE 65535 -#define MAX_AUTO_ANSWER_7960 63 -#define MIN_KEEPALIVE_EXPIRES 120 -#define MAX_KEEPALIVE_EXPIRES 7200 - -extern void platform_get_ipv4_address(cpr_ip_addr_t *ip_addr); -extern void platform_get_ipv6_address(cpr_ip_addr_t *ip_addr); -extern boolean Is794x; - -static cpr_ip_addr_t redirected_nat_ipaddr = {0,{0}}; -static void config_set_current_codec_table(int codec_mask, - rtp_ptype *codec_table); - -/********************************************************* - * - * Network Configuration Settings - * Look at making these generic and moving them to the - * network library... - * - *********************************************************/ - -static void initCfgTblEntry(int index, const char * name, void *addr, int length, - parse_func_t parse, print_func_t print, - const key_table_entry_t *key) -{ - var_t *table; - table = &prot_cfg_table[index]; - - table->name = name; - table->addr = addr; - table->length = length; - table->parse_func = parse; - table->print_func = print; - table->key_table = key; - -} - -/* Function: protCfgTblInit() - * - * Description: Initializes line specific params in prot_cfg_table - * - * Parameters: - * - * Returns: - */ -void protCfgTblInit() -{ -int i; - memset(&prot_cfg_block, 0, sizeof(prot_cfg_block)); - for (i=0; i< MAX_CONFIG_LINES; i++) { - initCfgTblEntry(CFGID_LINE_INDEX+i, "Index", CFGVAR(line[i].index), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FEATURE+i, "Feat", CFGVAR(line[i].feature), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_MAXNUMCALLS+i, "MNC", CFGVAR(line[i].maxnumcalls), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_BUSY_TRIGGER+i, "BT", CFGVAR(line[i].busy_trigger), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_PROXY_ADDRESS+i, "ProxyAddr", CFGVAR(line[i].proxy_address), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_PROXY_PORT+i, "ProxyPort", CFGVAR(line[i].proxy_port), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_CALL_WAITING+i, "CWait", CFGVAR(line[i].call_waiting), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_AUTOANSWER_ENABLED+i, "AAns", CFGVAR(line[i].autoanswer), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_AUTOANSWER_MODE+i, "AAnsMode", CFGVAR(line[i].autoanswer_mode), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_MSG_WAITING_LAMP+i, "MWILamp", CFGVAR(line[i].msg_waiting_lamp), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_MESSAGE_WAITING_AMWI+i, "AMWI", CFGVAR(line[i].msg_waiting_amwi), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_RING_SETTING_IDLE+i, "RingIdle", CFGVAR(line[i].ring_setting_idle), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_RING_SETTING_ACTIVE+i, "RingActive", CFGVAR(line[i].ring_setting_active), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_NAME+i, "Name", CFGVAR(line[i].name), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_AUTHNAME+i, "AuthName", CFGVAR(line[i].authname), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_PASSWORD+i, "Passwd", CFGVAR(line[i].password), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_DISPLAYNAME+i, "DisplayName", CFGVAR(line[i].displayname), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_CONTACT+i, "Contact", CFGVAR(line[i].contact), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_CFWDALL+i, "CfwdAll", CFGVAR(line[i].cfwdall), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_SPEEDDIAL_NUMBER+i, "speedDialNumber", CFGVAR(line[i].speeddial_number), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_RETRIEVAL_PREFIX+i, "retrievalPrefix", CFGVAR(line[i].retrieval_prefix), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_MESSAGES_NUMBER+i, "messagesNumber", CFGVAR(line[i].messages_number), PA_STR, PR_STR, 0); - initCfgTblEntry(CFGID_LINE_FWD_CALLER_NAME_DIPLAY+i, "callerName", CFGVAR(line[i].fwd_caller_name_display), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY+i, "callerName", CFGVAR(line[i].fwd_caller_number_display), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY+i, "redirectedNumber", CFGVAR(line[i].fwd_redirected_number_display), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY+i, "dialedNumber", CFGVAR(line[i].fwd_dialed_number_display), PA_INT, PR_INT, 0); - initCfgTblEntry(CFGID_LINE_FEATURE_OPTION_MASK+i, "featureOptionMask", CFGVAR(line[i].feature_option_mask), PA_INT, PR_INT, 0); - } - - initCfgTblEntry(CFGID_PROTOCOL_MAX, 0, 0, 0, 0, 0, 0); -} - -/* - * sip_config_get_net_device_ipaddr() - * - * Get the device IP address. - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * Eg. 0xac2c33f8 = 161.44.51.248 - */ -void -sip_config_get_net_device_ipaddr (cpr_ip_addr_t *ip_addr) -{ - cpr_ip_addr_t ip_addr1 = {0,{0}}; - - platform_get_ipv4_address(&ip_addr1); - util_ntohl(ip_addr, &ip_addr1); -} - -/* - * sip_config_get_net_device_ipaddr() - * - * Get the device IP address. - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * - */ -void -sip_config_get_net_ipv6_device_ipaddr (cpr_ip_addr_t *ip_addr) -{ - cpr_ip_addr_t ip_addr1 = {0,{0}}; - - platform_get_ipv6_address(&ip_addr1); - util_ntohl(ip_addr, &ip_addr1); -} - - -/* - * sip_config_get_nat_ipaddr() - * - * Get the nat IP address. - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * Eg. 0xac2c33f8 = 161.44.51.248 - */ -void -sip_config_get_nat_ipaddr (cpr_ip_addr_t *ip_addr) -{ - cpr_ip_addr_t IPAddress; - char address[MAX_IPADDR_STR_LEN]; - int dnsErrorCode = 1; - - if (redirected_nat_ipaddr.type == CPR_IP_ADDR_INVALID) { - config_get_string(CFGID_NAT_ADDRESS, address, sizeof(address)); - if ((cpr_strcasecmp(address, UNPROVISIONED) != 0) && (address[0] != 0)) { - dnsErrorCode = dnsGetHostByName(address, &IPAddress, 100, 1); - } - - if (dnsErrorCode == 0) { - util_ntohl(ip_addr, &IPAddress); - return ; - } else { - /* - * If the NAT address is not provisioned or - * unavailable, return the local address instead. - */ - sip_config_get_net_device_ipaddr(ip_addr); - return; - } - } else { - *ip_addr = redirected_nat_ipaddr; - return ; - } - -} - -/* - * sip_config_set_nat_ipaddr() - * - * Set the device NAT IP address. - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * Eg. 0xac2c33f8 = 161.44.51.248 - */ -void -sip_config_set_nat_ipaddr (cpr_ip_addr_t *ip_address) -{ - redirected_nat_ipaddr = *ip_address; -} - -/********************************************************* - * - * SIP Configuration Settings - * These should probably be turned into generic config - * table "gets/sets" or should be moved to a SIP platform - * file. Maybe ccsip_platform_ui.c since that's where we - * have the other SIP Platform code. In the long run, we - * should rename ccsip_platform_ui.c to ccsip_platform.c - * - *********************************************************/ - -/* - * sip_config_get_line_from_button() - * Some cases CCM sends down line number instead of button number - * that has to be mapped to correct button number. This function is - * called to get actual line number for a given button number - * - * Returns: actual line number from given button number - * - */ -line_t -sip_config_get_line_from_button (line_t button) -{ - line_t max_lines_allowed; - uint32_t line = 0; - line_t button_no = 0; - - if (Is794x) { - max_lines_allowed = MAX_REG_LINES_794X; - } else { - max_lines_allowed = MAX_REG_LINES; - } - - if ((button < 1) || (button > max_lines_allowed)) { - return (button); - } - - config_get_line_value(CFGID_LINE_INDEX, &line, - sizeof(line), button); - - /* Look for the line number through the configuration - * max_lines_allowed)) { - if (line != 0) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"Invalid Line: %d\n", fname, line); - } - return FALSE; - } - - config_get_line_string(CFGID_LINE_NAME, temp, line, sizeof(temp)); - if (temp[0] == '\0') { - return FALSE; - } - - config_get_line_value(CFGID_LINE_FEATURE, &line_feature, - sizeof(line_feature), line); - - if (line_feature != cfgLineFeatureDN) { - return FALSE; - } - - return TRUE; -} -/* - * sip_config_local_line_get() - * - * Get the Line setting. - * Note: The UI has serious problems if there are gaps in the - * line names. Therefore, lines must be sequential. In - * other words, if lines 1, 2, and 4 have names, this routine - * will return that two lines are active. Once Line three is - * found to be unprovisioned, line 4 will be ignored. - */ -line_t -sip_config_local_line_get (void) -{ - if (Is794x) { - return (MAX_REG_LINES_794X); - } - return (MAX_REG_LINES); -} -/* - * sip_config_get_keepalive_expires() - * - * Returns the keepalive expires configured. - * The minimum allowed value is returned if - * configured value is less than the minimum - * allowed value.If the configured value is - * greater than the maximum allowed then the - * maximum allowed value is returned. - * - */ -int -sip_config_get_keepalive_expires() -{ - int keepalive_interval = 0; - - config_get_value(CFGID_TIMER_KEEPALIVE_EXPIRES, &keepalive_interval, - sizeof(keepalive_interval)); - - if (keepalive_interval < MIN_KEEPALIVE_EXPIRES) { - keepalive_interval = MIN_KEEPALIVE_EXPIRES; - TNP_DEBUG(DEB_F_PREFIX"Keepalive interval less than minimum acceptable.Resetting it to %d\n", - DEB_F_PREFIX_ARGS(SIP_KA, "sip_config_get_keepalive_expires"), - keepalive_interval); - } else if (keepalive_interval > MAX_KEEPALIVE_EXPIRES) { - keepalive_interval = MAX_KEEPALIVE_EXPIRES; - TNP_DEBUG(DEB_F_PREFIX"Keepalive interval more than maximum acceptable.Resetting it to %d\n", - DEB_F_PREFIX_ARGS(SIP_KA, "sip_config_get_keepalive_expires"), - keepalive_interval); - } - - return keepalive_interval; -} -/* - * sip_config_get_display_name() - * - * Get the display name - */ -void -sip_config_get_display_name (line_t line, char *buffer, int buffer_len) -{ - - config_get_line_string(CFGID_LINE_DISPLAYNAME, buffer, line, buffer_len); - - if ((strcmp(buffer, UNPROVISIONED) == 0) || (buffer[0] == '\0')) { - config_get_line_string(CFGID_LINE_NAME, buffer, line, buffer_len); - } -} - -/** - * Returns the configured value of preferred codec. The codec may - * or may not be available by the platform. - * - * @param[in] none. - * - * @return rtp_ptype of the codec. - */ -rtp_ptype -sip_config_preferred_codec (void) -{ - key_table_entry_t cfg_preferred_codec; - - config_get_value(CFGID_PREFERRED_CODEC, &cfg_preferred_codec, - sizeof(cfg_preferred_codec)); - if ((cfg_preferred_codec.name != NULL) && - (cfg_preferred_codec.name[0] != '\0')) { - /* The configuration has preferred codec configured */ - return (cfg_preferred_codec.value); - } - /* No preferred codec configured */ - return (RTP_NONE); -} - -/** - * sip_config_local_supported_codecs_get() - * Get the locally supported codec list. The returned list - * of codecs will be in the ordered of preference. If there is - * preferred condec configured and it is available, the - * preferred codec will be put on the first entry of the - * returned list. - * - * @param[in,out] aSupportedCodecs - pointer to arrary fo the - * rtp_ptype to store the result of - * currenlty available codecs. - * @param[in] supportedCodecsLen - indicates the number of entry - * of the aSupportedCodecs. - * - * @return number of current codecs available. - * - * @pre (aSupportedCodecs != NULL) - * @pre (supportedCodecsLen != 0) - */ -uint16_t -sip_config_local_supported_codecs_get (rtp_ptype aSupportedCodecs[], - uint16_t supportedCodecsLen) -{ - rtp_ptype current_codec_table[MAX_CODEC_ENTRIES+1]; - rtp_ptype *codec; - rtp_ptype pref_codec; - uint16_t count = 0; - int codec_mask; - boolean preferred_codec_available = FALSE; - - codec_mask = vcmGetAudioCodecList(VCM_DSP_FULLDUPLEX); - - if (!codec_mask) { - codec_mask = VCM_CODEC_RESOURCE_G711 | VCM_CODEC_RESOURCE_OPUS; - } - - /* - * convert the current available codec into the enumerated - * preferred list. - */ - current_codec_table[0] = RTP_NONE; - current_codec_table[MAX_CODEC_ENTRIES] = RTP_NONE; - config_set_current_codec_table(codec_mask, ¤t_codec_table[0]); - - /* - * Get the configured preferred codec. If one is configured, - * check it to see if currently it can be supported by the - * platform. If it is configured and is availble to support, - * put the preferred codec in the first one of the list. - */ - pref_codec = sip_config_preferred_codec(); - if (pref_codec != RTP_NONE) { - /* - * There is a configured preferred codec, check to see if - * the codec is currently avaible or not. - */ - codec = ¤t_codec_table[0]; - while (*codec != RTP_NONE) { - if (pref_codec == *codec) { - preferred_codec_available = TRUE; - break; - } - codec++; - } - } - - if (preferred_codec_available) { - /* - * The preferred codec is configured and the platform - * currently can support the preferred codec, put it in - * the first entry. - */ - aSupportedCodecs[count] = pref_codec; - count++; - } else { - /* - * Must init or comparison will be made to uninitialized memory. - * Do not increment count here since we are not adding RTP_NONE - * as a supported codec. We are only initializing memory to a - * known value. - */ - aSupportedCodecs[count] = RTP_NONE; - } - - codec = ¤t_codec_table[0]; - while (*codec != RTP_NONE) { - if (count < supportedCodecsLen) { - if (*codec != aSupportedCodecs[0]) { - aSupportedCodecs[count] = *codec; - count++; - } - } - codec++; - } - return count; -} - -/* - * sip_config_local_supported_codecs_get() - * - * Get the locally supported codec list. - */ -uint16_t -sip_config_video_supported_codecs_get (rtp_ptype aSupportedCodecs[], - uint16_t supportedCodecsLen, boolean isOffer) -{ - uint16_t count = 0; - int codec_mask; - cc_uint32_t major_ver, minor_ver; - - if ( isOffer ) { - codec_mask = vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX); - } else { - /* we are trying to match the answer then we - already have the rx stream open */ - //codec_mask = vcmGetVideoCodecList(DSP_ENCODEONLY); - codec_mask = vcmGetVideoCodecList(VCM_DSP_IGNORE); - } - if ( codec_mask & VCM_CODEC_RESOURCE_VP8) { - aSupportedCodecs[count] = RTP_VP8; - count++; - } - if ( codec_mask & VCM_CODEC_RESOURCE_H264) { - /* - * include payload type for packetization mode 1 only if ucm sis version - * is equal to or greater than 5.1.0 (AngelFire). - */ - platGetSISProtocolVer(&major_ver, &minor_ver, NULL, NULL); - if ((major_ver > SIS_PROTOCOL_MAJOR_VERSION_ANGELFIRE) || - (major_ver == SIS_PROTOCOL_MAJOR_VERSION_ANGELFIRE && - minor_ver >= SIS_PROTOCOL_MINOR_VERSION_ANGELFIRE)) { - if (vcmGetVideoMaxSupportedPacketizationMode() == 1) { - aSupportedCodecs[count] = RTP_H264_P1; - count++; - } - } - aSupportedCodecs[count] = RTP_H264_P0; - count++; - } - if ( codec_mask & VCM_CODEC_RESOURCE_H263) { - aSupportedCodecs[count] = RTP_H263; - count++; - } - - return count; -} - -/** - * The function fills in the given codec array based on the - * platform bit mask of codecs. Note, that the enumerated list - * produced is also in the preferred order. - * - * @param[in] codec_mask - platform bit mask corresponding to the - * codecs. - * @param[in/out] codecs - pointer to array of for storing the - * output of the enumerated codec based on - * bit set in the codec_mask. - * - * @return None. - * - * @pre (codec_table != NULL) - * @pre storge of codec_table must be last enough to holds - * supported codec in the bit mask. - */ -static void -config_set_current_codec_table (int codec_mask, rtp_ptype *codecs) -{ - int idx = 0; - - if (codec_mask & VCM_CODEC_RESOURCE_OPUS) { - codecs[idx] = RTP_OPUS; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_G711) { - codecs[idx] = RTP_PCMU; - idx++; - codecs[idx] = RTP_PCMA; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_G729A) { - codecs[idx] = RTP_G729; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_LINEAR) { - codecs[idx] = RTP_L16; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_G722) { - codecs[idx] = RTP_G722; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_iLBC) { - codecs[idx] = RTP_ILBC; - idx++; - } - - if (codec_mask & VCM_CODEC_RESOURCE_iSAC) { - codecs[idx] = RTP_ISAC; - idx++; - } - - codecs[idx] = RTP_NONE; - - return; -} - -/* - * sip_config_local_dtmf_dblevels_get() - * - * Get the DTMF DB levels - */ -uint32_t -sip_config_local_dtmf_dblevels_get (void) -{ - int value; - - config_get_value(CFGID_DTMF_DB_LEVEL, &value, sizeof(value)); - switch (value) { - case 0: - return 0; // Mute - case 1: - return 2900; // 6 dB down - case 2: - return 4096; // 3 dB down - case 3: - return 5786; // Nominal amplitude - // (-8.83 dBm0 to network, -11.83 dBm0 local) - case 4: - return 8173; // 3 dB up - case 5: - return 11544; // 6 dB up - default: - return 5786; // Nominal amplitude - } -} - -/* - * sip_config_get_line_by_called_number - * - * Return the line by the given called_number - */ -line_t sip_config_get_line_by_called_number (line_t start_line, const char *called_number) -{ - int i; - line_t max_lines; - line_t line = 0; - char line_name[MAX_LINE_NAME_SIZE]; - char contact[MAX_LINE_CONTACT_SIZE]; - char *name; - - max_lines = sip_config_local_line_get(); - - /* - * Check the called number for the E.164 "+" - * and ignore it if present. - */ - if (called_number[0] == '+') { - called_number++; - } - - for (i = start_line; i <= max_lines; i++) { - if (sip_config_check_line((line_t)i)) { - config_get_line_string(CFGID_LINE_NAME, line_name, i, - sizeof(line_name)); - /* - * Check the configured line name for the E.164 "+" - * and ignore it if present. - */ - name = &line_name[0]; - if (line_name[0] == '+') { - name++; - } - - if (cpr_strcasecmp(called_number, name) == 0) { - line = (line_t)i; - break; - } - } - } - - // If line not found - check with contact list - if (line == 0) { - for (i = start_line; i <= max_lines; i++) { - if (sip_config_check_line((line_t)i)) { - config_get_line_string(CFGID_LINE_CONTACT, contact, i, - sizeof(contact)); - if (cpr_strcasecmp(called_number, contact) == 0) { - line = (line_t)i; - break; - } - } - } - } - - return (line); -} - -/********************************************************* - * - * SIP Config API - * The routines below with the "prot" prefix are called - * by the config system. The calls that start with "sip" - * are helper functions for the SIP implementation of the - * "prot" API. - * - *********************************************************/ - -/* - * sip_minimum_config_check() - * - * Return indication if the SIP minimum configuration - * requirements have been met. - * Returns 0 if minimum config is met - * Returns non-zero if minimum config has not been met - * (eg. missing at least 1 required parameter) - */ -int -sip_minimum_config_check (void) -{ - char str_val[MAX_IPADDR_STR_LEN]; - char line_name[MAX_LINE_NAME_SIZE]; - int value; - - /* - * Make sure that line 1 is configured - */ - config_get_line_string(CFGID_LINE_NAME, line_name, 1, sizeof(line_name)); - if ((strcmp(line_name, UNPROVISIONED) == 0) || (line_name[0] == '\0')) { - return -1; - } - - config_get_line_string(CFGID_PROXY_ADDRESS, str_val, 1, MAX_IPADDR_STR_LEN); - if ((strcmp(str_val, UNPROVISIONED) == 0) || (str_val[0] == '\0')) { - return -1; - } - - config_get_line_value(CFGID_PROXY_PORT, &value, sizeof(value), 1); - if (value == 0) { - return -1; - } - - return 0; -} - -/* - * prot_config_change_notify() - * Let the SIP stack know that a config change has occurred. - * - */ -int -prot_config_change_notify (int notify_type) -{ - if (SIPTaskProcessConfigChangeNotify(notify_type) < 0) { -//CPR TODO: need reference for - CCSIP_DEBUG_ERROR(PLAT_COMMON_F_PREFIX"SIPTaskProcessConfigChangeNotify() " - "returned error.\n", "prot_config_change_notify"); - } - - return (TRUE); -} - -/* - * prot_config_check_line_name() - * Makes sure that there are no spaces in the SIP Line Names - * - * Returns: TRUE if the Name is Valid - * FALSE if the Name is Invalid - * - */ -boolean -prot_config_check_line_name (char *line_name) -{ - while ((*line_name != ' ') && (*line_name != NUL)) { - line_name++; - } - - if (*line_name == ' ') { - return (FALSE); - } - return (TRUE); -} - -/* - * prot_sanity_check_config_settings() - * - , Louis* Checks the sanity of the protocol config block values - * and sets them to defaults if they are incorrect. - */ -int -prot_sanity_check_config_settings (void) -{ - int retval = 0; - return retval; -} - - -/* - * prot_shutdown() - * - * Shut down the protocol stack. - */ - -void -prot_shutdown (void) -{ - sip_shutdown(); -} diff --git a/libs/sipcc/core/common/prot_configmgr.h b/libs/sipcc/core/common/prot_configmgr.h deleted file mode 100755 index 204c3b6005..0000000000 --- a/libs/sipcc/core/common/prot_configmgr.h +++ /dev/null @@ -1,298 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _PROT_CONFIGMGR_H_ -#define _PROT_CONFIGMGR_H_ - -#include "cpr_types.h" -#include "phone_types.h" -#include "rtp_defs.h" -#include "ccsip_platform.h" -#include "configmgr.h" -#include "cfgfile_utils.h" -#include "phone_platform_constants.h" -#include "cc_config.h" -#include "cc_constants.h" -#include "ccsdp.h" - -#define UNPROVISIONED "UNPROVISIONED" - -/********************************************************* - * - * The following parameters set Config system settings - * for SIP - * - *********************************************************/ -#define HWTYPE "SIP" -#define MAX_LINE_NAME_SIZE 128 -#define AUTH_NAME_SIZE 129 -#define MAX_LINE_PASSWORD_SIZE 32 -#define MAX_LINE_DISPLAY_SIZE 32 -#define MAX_LINE_CONTACT_SIZE 128 -#define MAX_LINE_AUTO_ANS_MODE_SIZE 32 -#define MAX_REG_USER_INFO_LEN 32 -#define MAX_JOIN_DXFER_POLICY_SIZE 40 -#define MAX_EXTERNAL_NUMBER_MASK_SIZE 40 - -/********************************************************* - *!!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * TNP SIP Phone Configuration IDs - * - *!!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - * The following macro definitions are defined in cc_config.h. - * Change should be made in the cc_config.h and add reference here. - * - * <------ Original notes ------> - * Before changing this code, please read the following: - * - * The Configuration system for the TNP phones is simply a cache - * that exists for the GSM/SIP DLL to use. The property values are - * sent from Java across the JNI to the cache. This prevents - * the SIP and GSM code from having to suffer through a JNI call - * every time they wish to retrieve a configuration parameter. - * - * These ID's need to match the definitions in JplatConfigConstants.java - * - * To add a new value to the table, - * In general, you will have to: - * - * 1) Create an index for the new CFG param below - * 2) Update prot_cfg_table either in prot_cfgmgr_private.h - * or in prot_configmgr.c (for line specific params) - * 3) Update JPlatConfigConstants.h with the new ID - * 4) Create a property on JAVA side and update it from XML config - * 5) Update show_cfg_cmd if adding a new line param - * - *!!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!! - *********************************************************/ - -/* Keep non line specific params here */ - -#define CFGID_MEDIA_PORT_RANGE_START CFGID_MEDIA_PORT_RANGE_START_INT -#define CFGID_MEDIA_PORT_RANGE_END CFGID_MEDIA_PORT_RANGE_END_INT -#define CFGID_CALLERID_BLOCKING CFGID_CALLERID_BLOCKING_BOOL -#define CFGID_ANONYMOUS_CALL_BLOCK CFGID_ANONYMOUS_CALL_BLOCK_BOOL -#define CFGID_DND_CALL_ALERT CFGID_DND_CALL_ALERT_BYTE -#define CFGID_DND_REMINDER_TIMER CFGID_DND_REMINDER_TIMER_INT -#define CFGID_PREFERRED_CODEC CFGID_PREFERRED_CODEC_STRING -#define CFGID_DTMF_OUTOFBAND CFGID_DTMF_OUTOFBAND_STRING -#define CFGID_DTMF_AVT_PAYLOAD CFGID_DTMF_AVT_PAYLOAD_INT -#define CFGID_DTMF_DB_LEVEL CFGID_DTMF_DB_LEVEL_INT - -#define CFGID_SIP_RETX CFGID_SIP_RETX_INT -#define CFGID_SIP_INVITE_RETX CFGID_SIP_INVITE_RETX_INT -#define CFGID_TIMER_T1 CFGID_TIMER_T1_INT -#define CFGID_TIMER_T2 CFGID_TIMER_T2_INT -#define CFGID_TIMER_INVITE_EXPIRES CFGID_TIMER_INVITE_EXPIRES_INT -#define CFGID_TIMER_REGISTER_EXPIRES CFGID_TIMER_REGISTER_EXPIRES_INT - -#define CFGID_PROXY_REGISTER CFGID_PROXY_REGISTER_BOOL -#define CFGID_PROXY_BACKUP CFGID_PROXY_BACKUP_STRING -#define CFGID_PROXY_BACKUP_PORT CFGID_PROXY_BACKUP_PORT_INT -#define CFGID_PROXY_EMERGENCY CFGID_PROXY_EMERGENCY_STRING -#define CFGID_PROXY_EMERGENCY_PORT CFGID_PROXY_EMERGENCY_PORT_INT -#define CFGID_OUTBOUND_PROXY CFGID_OUTBOUND_PROXY_STRING -#define CFGID_OUTBOUND_PROXY_PORT CFGID_OUTBOUND_PROXY_PORT_INT - -#define CFGID_NAT_RECEIVED_PROCESSING CFGID_NAT_RECEIVED_PROCESSING_BOOL -#define CFGID_REG_USER_INFO CFGID_REG_USER_INFO_STRING -#define CFGID_CNF_JOIN_ENABLE CFGID_CNF_JOIN_ENABLE_BOOL -#define CFGID_REMOTE_PARTY_ID CFGID_REMOTE_PARTY_ID_BOOL -#define CFGID_SEMI_XFER CFGID_SEMI_XFER_BOOL -#define CFGID_CALL_HOLD_RINGBACK CFGID_CALL_HOLD_RINGBACK_BOOL -#define CFGID_STUTTER_MSG_WAITING CFGID_STUTTER_MSG_WAITING_BOOL -/** - * The CFGID_CFWD_URL was consolidated for RT and CIUS and should be for TNP as well. - */ -#define CFGID_CFWD_URL CFGID_CFWD_URL_STRING - -#define CFGID_CALL_STATS CFGID_CALL_STATS_BOOL -#define CFGID_LOCAL_CFWD_ENABLE CFGID_LOCAL_CFWD_ENABLE_BOOL -#define CFGID_TIMER_REGISTER_DELTA CFGID_TIMER_REGISTER_DELTA_INT -#define CFGID_SIP_MAX_FORWARDS CFGID_SIP_MAX_FORWARDS_INT -#define CFGID_2543_HOLD CFGID_2543_HOLD_BOOL - -#define CFGID_CCM1_ADDRESS CFGID_CCM1_ADDRESS_STRING -#define CFGID_CCM2_ADDRESS CFGID_CCM2_ADDRESS_STRING -#define CFGID_CCM3_ADDRESS CFGID_CCM3_ADDRESS_STRING - -// Note: IPv6 Not currently supported on Cius -#define CFGID_CCM1_IPV6_ADDRESS CFGID_CCM1_IPV6_ADDRESS_STRING -#define CFGID_CCM2_IPV6_ADDRESS CFGID_CCM2_IPV6_ADDRESS_STRING -#define CFGID_CCM3_IPV6_ADDRESS CFGID_CCM3_IPV6_ADDRESS_STRING - -#define CFGID_CCM1_SIP_PORT CFGID_CCM1_SIP_PORT_INT -#define CFGID_CCM2_SIP_PORT CFGID_CCM2_SIP_PORT_INT -#define CFGID_CCM3_SIP_PORT CFGID_CCM3_SIP_PORT_INT - -#define CFGID_CCM1_SEC_LEVEL CFGID_CCM1_SEC_LEVEL_INT -#define CFGID_CCM2_SEC_LEVEL CFGID_CCM2_SEC_LEVEL_INT -#define CFGID_CCM3_SEC_LEVEL CFGID_CCM3_SEC_LEVEL_INT - -#define CFGID_CCM1_IS_VALID CFGID_CCM1_IS_VALID_BOOL -#define CFGID_CCM2_IS_VALID CFGID_CCM2_IS_VALID_BOOL -#define CFGID_CCM3_IS_VALID CFGID_CCM3_IS_VALID_BOOL - -#define CFGID_CCM_TFTP_IP_ADDR CFGID_CCM_TFTP_IP_ADDR_STRING -#define CFGID_CCM_TFTP_PORT CFGID_CCM_TFTP_PORT_INT -#define CFGID_CCM_TFTP_IS_VALID CFGID_CCM_TFTP_IS_VALID_BOOL -#define CFGID_CCM_TFTP_SEC_LEVEL CFGID_CCM_TFTP_SEC_LEVEL_INT - -#define CFGID_CONN_MONITOR_DURATION CFGID_CONN_MONITOR_DURATION_INT -#define CFGID_CALL_PICKUP_URI CFGID_CALL_PICKUP_URI_STRING -#define CFGID_CALL_PICKUP_LIST_URI CFGID_CALL_PICKUP_LIST_URI_STRING -#define CFGID_CALL_PICKUP_GROUP_URI CFGID_CALL_PICKUP_GROUP_URI_STRING -#define CFGID_MEET_ME_SERVICE_URI CFGID_MEET_ME_SERVICE_URI_STRING -#define CFGID_CALL_FORWARD_URI CFGID_CALL_FORWARD_URI_STRING -#define CFGID_ABBREVIATED_DIAL_URI CFGID_ABBREVIATED_DIAL_URI_STRING -#define CFGID_CALL_LOG_BLF_ENABLED CFGID_CALL_LOG_BLF_ENABLED_BOOL -#define CFGID_REMOTE_CC_ENABLED CFGID_REMOTE_CC_ENABLED_BOOL -#define CFGID_RETAIN_FORWARD_INFORMATION CFGID_RETAIN_FORWARD_INFORMATION_BOOL - -#define CFGID_TIMER_KEEPALIVE_EXPIRES CFGID_TIMER_KEEPALIVE_EXPIRES_INT -#define CFGID_TIMER_SUBSCRIBE_EXPIRES CFGID_TIMER_SUBSCRIBE_EXPIRES_INT -#define CFGID_TIMER_SUBSCRIBE_DELTA CFGID_TIMER_SUBSCRIBE_DELTA_INT -#define CFGID_TRANSPORT_LAYER_PROT CFGID_TRANSPORT_LAYER_PROT_INT -#define CFGID_KPML_ENABLED CFGID_KPML_ENABLED_INT - -#define CFGID_NAT_ENABLE CFGID_NAT_ENABLE_BOOL -#define CFGID_NAT_ADDRESS CFGID_NAT_ADDRESS_STRING -#define CFGID_VOIP_CONTROL_PORT CFGID_VOIP_CONTROL_PORT_INT -#define CFGID_MY_IP_ADDR CFGID_MY_IP_ADDR_STRING -#define CFGID_MY_MAC_ADDR CFGID_MY_MAC_ADDR_STRING -#define CFGID_ENABLE_VAD CFGID_ENABLE_VAD_BOOL - -#define CFGID_AUTOANSWER_IDLE_ALTERNATE CFGID_AUTOANSWER_IDLE_ALTERNATE_BOOL -#define CFGID_AUTOANSWER_TIMER CFGID_AUTOANSWER_TIMER_INT -#define CFGID_AUTOANSWER_OVERRIDE CFGID_AUTOANSWER_OVERRIDE_BOOL - -#define CFGID_OFFHOOK_TO_FIRST_DIGIT_TIMER CFGID_OFFHOOK_TO_FIRST_DIGIT_TIMER_INT -#define CFGID_CALL_WAITING_SILENT_PERIOD CFGID_CALL_WAITING_SILENT_PERIOD_INT -#define CFGID_RING_SETTING_BUSY_POLICY CFGID_RING_SETTING_BUSY_POLICY_INT -#define CFGID_DSCP_FOR_CALL_CONTROL CFGID_DSCP_FOR_CALL_CONTROL_INT -#define CFGID_SPEAKER_ENABLED CFGID_SPEAKER_ENABLED_BOOL -#define CFGID_XFR_ONHOOK_ENABLED CFGID_XFR_ONHOOK_ENABLED_BOOL -#define CFGID_ROLLOVER CFGID_ROLLOVER_INT -#define CFGID_LOAD_FILE CFGID_LOAD_FILE_STRING - -#define CFGID_BLF_ALERT_TONE_IDLE CFGID_BLF_ALERT_TONE_IDLE_INT -#define CFGID_BLF_ALERT_TONE_BUSY CFGID_BLF_ALERT_TONE_BUSY_INT -#define CFGID_AUTO_PICKUP_ENABLED CFGID_AUTO_PICKUP_ENABLED_BOOL - -#define CFGID_JOIN_ACROSS_LINES CFGID_JOIN_ACROSS_LINES_INT - -#define CFGID_MY_ACTIVE_MAC_ADDR CFGID_MY_ACTIVE_MAC_ADDR_STRING -#define CFGID_DSCP_AUDIO CFGID_DSCP_AUDIO_INT -#define CFGID_DEVICE_NAME CFGID_DEVICE_NAME_STRING -#define CFGID_USER_AGENT CFGID_USER_AGENT_STRING -#define CFGID_MODEL_NUMBER CFGID_MODEL_NUMBER_STRING -#define CFGID_DSCP_VIDEO CFGID_DSCP_VIDEO_INT - -#define CFGID_IP_ADDR_MODE CFGID_IP_ADDR_MODE_INT -#define CFGID_INTER_DIGIT_TIMER CFGID_INTER_DIGIT_TIMER_INT - -// Note - EMCC not currently supported on CIUS -#define CFGID_EMCC_MODE CFGID_EMCC_MODE_BOOL -#define CFGID_VISITING_EM_PORT CFGID_VISITING_EM_PORT_INT -#define CFGID_VISITING_EM_IP CFGID_VISITING_EM_IP_STRING - -#define CFGID_CCM_EXTERNAL_NUMBER_MASK CFGID_CCM_EXTERNAL_NUMBER_MASK_STRING -#define CFGID_MEDIA_IP_ADDR CFGID_MEDIA_IP_ADDR_STRING - -/* All non Line specific params should be added above */ -/* All Line specific params should be added below */ - -#define CFGID_LINE_FEATURE CFGID_LINE_FEATURE_INT -#define CFGID_LINE_INDEX CFGID_LINE_INDEX_INT -#define CFGID_LINE_MAXNUMCALLS CFGID_LINE_MAXNUMCALLS_INT -#define CFGID_LINE_NAME CFGID_LINE_NAME_STRING -#define CFGID_LINE_AUTHNAME CFGID_LINE_AUTHNAME_STRING -#define CFGID_LINE_PASSWORD CFGID_LINE_PASSWORD_STRING -#define CFGID_LINE_DISPLAYNAME CFGID_LINE_DISPLAYNAME_STRING -#define CFGID_LINE_CONTACT CFGID_LINE_CONTACT_STRING -#define CFGID_PROXY_ADDRESS CFGID_PROXY_ADDRESS_STRING -#define CFGID_PROXY_PORT CFGID_PROXY_PORT_INT -#define CFGID_LINE_AUTOANSWER_ENABLED CFGID_LINE_AUTOANSWER_ENABLED_BYTE -#define CFGID_LINE_AUTOANSWER_MODE CFGID_LINE_AUTOANSWER_MODE_STRING -#define CFGID_LINE_CALL_WAITING CFGID_LINE_CALL_WAITING_BYTE -#define CFGID_LINE_MSG_WAITING_LAMP CFGID_LINE_MSG_WAITING_LAMP_BYTE -#define CFGID_LINE_MESSAGE_WAITING_AMWI CFGID_LINE_MESSAGE_WAITING_AMWI_BYTE -#define CFGID_LINE_RING_SETTING_IDLE CFGID_LINE_RING_SETTING_IDLE_BYTE -#define CFGID_LINE_RING_SETTING_ACTIVE CFGID_LINE_RING_SETTING_ACTIVE_BYTE -#define CFGID_LINE_BUSY_TRIGGER CFGID_LINE_BUSY_TRIGGER_INT -#define CFGID_LINE_CFWDALL CFGID_LINE_CFWDALL_STRING - -#define CFGID_LINE_SPEEDDIAL_NUMBER CFGID_LINE_SPEEDDIAL_NUMBER_STRING -#define CFGID_LINE_RETRIEVAL_PREFIX CFGID_LINE_RETRIEVAL_PREFIX_STRING -#define CFGID_LINE_MESSAGES_NUMBER CFGID_LINE_MESSAGES_NUMBER_STRING -#define CFGID_LINE_FWD_CALLER_NAME_DIPLAY CFGID_LINE_FWD_CALLER_NAME_DIPLAY_BOOL -#define CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY CFGID_LINE_FWD_CALLER_NUMBER_DIPLAY_BOOL -#define CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY CFGID_LINE_FWD_REDIRECTED_NUMBER_DIPLAY_BOOL -#define CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY CFGID_LINE_FWD_DIALED_NUMBER_DIPLAY_BOOL -#define CFGID_LINE_FEATURE_OPTION_MASK CFGID_LINE_FEATURE_OPTION_MASK_INT -#define CFGID_P2PSIP CFGID_P2PSIP_BOOL -#define CFGID_VERSION CFGID_VERSION_STRING -#define CFGID_SDPMODE CFGID_SDPMODE_BOOL -#define CFGID_RTCPMUX CFGID_RTCPMUX_BOOL -#define CFGID_RTPSAVPF CFGID_RTPSAVPF_BOOL -#define CFGID_MAXAVBITRATE CFGID_MAXAVBITRATE_BOOL -#define CFGID_MAXCODEDAUDIOBW CFGID_MAXCODEDAUDIOBW_BOOL -#define CFGID_USEDTX CFGID_USEDTX_BOOL -#define CFGID_STEREO CFGID_STEREO_BOOL -#define CFGID_USEINBANDFEC CFGID_USEINBANDFEC_BOOL -#define CFGID_CBR CFGID_CBR_BOOL -#define CFGID_MAXPTIME CFGID_MAXPTIME_BOOL -#define CFGID_SCTP_PORT CFGID_SCTP_PORT_INT -#define CFGID_NUM_DATA_STREAMS CFGID_NUM_DATA_STREAMS_INT - -/********************************************************* - * - * Value Definitions - * - *********************************************************/ -// Line feature -typedef enum { - cfgLineFeatureNone = CC_LINE_FEATURE_NONE, - cfgLineFeatureRedial = CC_LINE_FEATURE_REDIAL, - cfgLineFeatureSpeedDial = CC_LINE_FEATURE_SPEEDDIAL, - cfgLineFeatureDN = CC_LINE_FEATURE_DN, - cfgLineFeatureService = CC_LINE_FEATURE_SERVICE, - cfgLineFeatureSpeedDialBLF = CC_LINE_FEATURE_SPEEDDIALBLF, - cfgLineFeatureMaliciousCallID = CC_LINE_FEATURE_MALICIOUSCALLID, - cfgLineFeatureAllCalls = CC_LINE_FEATURE_ALLCALLS, - cfgLineFeatureAnswerOldest = CC_LINE_FEATURE_ANSWEROLDEST, - cfgLineFeatureServices = CC_LINE_FEATURE_SERVICES, - cfgLineFeatureBLF = CC_LINE_FEATURE_BLF -} cfgLineFeatureType_e; - -/********************************************************* - * - * Function Prototypes - * - *********************************************************/ -void protocol_cfg_init(void); -void sip_config_get_net_device_ipaddr(cpr_ip_addr_t *ip_addr); -void sip_config_get_net_ipv6_device_ipaddr(cpr_ip_addr_t *ip_addr); -void sip_config_get_nat_ipaddr(cpr_ip_addr_t *ip_addr); -void sip_config_set_nat_ipaddr(cpr_ip_addr_t *ip_address); -uint16_t sip_config_local_supported_codecs_get(rtp_ptype aSupportedCodecs[], - uint16_t supportedCodecsLen); -uint16_t sip_config_video_supported_codecs_get(rtp_ptype aSupportedCodecs[], - uint16_t supportedCodecsLen, boolean isOffer); - -boolean prot_config_check_line_name(char *line_name); -//const key_table_entry_t * sip_config_local_codec_entry_find(const rtp_ptype codec); -line_t sip_config_get_button_from_line(line_t line); -line_t sip_config_get_line_from_button(line_t button); -boolean sip_config_check_line(line_t line); -line_t sip_config_local_line_get(void); -void sip_config_get_display_name(line_t line, char *buffer, int buffer_len); -line_t sip_config_get_line_by_called_number(line_t start_line, const char *called_number); -int sip_minimum_config_check(void); -void config_set_codec_table(int codec_mask); -int sip_config_get_keepalive_expires(); -rtp_ptype sip_config_preferred_codec(void); - -#endif /* PROT_CONFIGMGR_H_ */ diff --git a/libs/sipcc/core/common/resource_manager.c b/libs/sipcc/core/common/resource_manager.c deleted file mode 100644 index 6e969a1ecf..0000000000 --- a/libs/sipcc/core/common/resource_manager.c +++ /dev/null @@ -1,300 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "resource_manager.h" -#include "phone_debug.h" - -#define RM_NUM_ELEMENTS_PER_MAP 32 -#define rm_get_table_index(a) (a / RM_NUM_ELEMENTS_PER_MAP) -#define rm_get_map_offset(a) (a % RM_NUM_ELEMENTS_PER_MAP) - -/* - * rm_clear_all_elements - * - * Description: - * This function clears all members of the specified resource manager - * - * Parameters: - * rm_p - pointer to the resource manager to be cleared - * - * Returns: - * None - */ -void -rm_clear_all_elements (resource_manager_t *rm_p) -{ - static const char fname[] = "rm_clear_all_elements"; - uint16_t i; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.\n", fname); - return; - } - - for (i = 0; i < rm_p->max_index; i++) { - rm_p->table[i] = 0; - } -} - -/* - * rm_clear_element - * - * Description: - * This function clears a single element from the specified resource manager - * - * Parameters: - * rm_p - pointer to the resource manager to be cleared - * element - element id of element to be cleared - * - * Returns: - * None - */ -void -rm_clear_element (resource_manager_t * rm_p, int16_t element) -{ - static const char fname[] = "rm_clear_elements"; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.\n", fname); - return; - } - - if (element < 0 || element >= rm_p->max_element) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"element value %d invalid. Max value is %d.\n", - fname, element, rm_p->max_element - 1); - return; - } - - rm_p->table[rm_get_table_index(element)] &= - (~(1 << rm_get_map_offset(element))); -} - -/* - * rm_set_element - * - * Description: - * This function sets the bit representing the specified element - * in the specified resource manager. - * - * Parameters: - * rm_p - pointer to the resource manager - * element - element id of element to be set - * - * Returns: - * None - */ -void -rm_set_element (resource_manager_t *rm_p, int16_t element) -{ - static const char fname[] = "rm_set_element"; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.\n", fname); - return; - } - - if (element < 0 || element >= rm_p->max_element) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"element value %d invalid. Max value %d.\n", - fname, element, rm_p->max_element - 1); - return; - } - - rm_p->table[rm_get_table_index(element)] |= - (1 << rm_get_map_offset(element)); -} - -/* - * rm_is_element_set - * - * Description: - * This function checks if the specified element in the specified - * resource manager is set. - * - * Parameters: - * rm_p - pointer to the resource manager. - * element - element id of element to be checked. - * - * Returns: - * TRUE if element is set, else FALSE - */ -boolean -rm_is_element_set (resource_manager_t *rm_p, int16_t element) -{ - static const char fname[] = "rm_is_element_set"; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.\n", fname); - return FALSE; - } - - if (element < 0 || element >= rm_p->max_element) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"element value %d invalid. Max value %d.\n", - fname, element, rm_p->max_element - 1); - return FALSE; - } - - if (rm_p->table[rm_get_table_index(element)] & - (1 << rm_get_map_offset(element))) { - return TRUE; - } - - return FALSE; -} - -/* - * rm_get_free_element - * - * Description: - * This function walks through the members of the resource manager and - * attempts to locate a free element. If a free element is found, the - * element's associated bit is set in the resource manager and the - * element id is returned. - * - * Parameters: - * rm_p - pointer to the resource manager. - * - * Returns: - * If an element is available, a element id (from zero to max element) - * If no element is available, -1 is returned. - */ -int16_t -rm_get_free_element (resource_manager_t *rm_p) -{ - static const char fname[] = "rm_get_free_element"; - int16_t element = -1; - uint16_t i, j; - uint32_t max_map = 0; - - max_map = ~max_map; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.\n", fname); - return -1; - } - - for (i = 0; i < rm_p->max_index && element == -1; i++) { - if (rm_p->table[i] != max_map) { - for (j = 0; j < RM_NUM_ELEMENTS_PER_MAP && element == -1; j++) { - if (!(rm_p->table[i] & (1 << j))) { - element = i * RM_NUM_ELEMENTS_PER_MAP + j; - if (element < rm_p->max_element) { - rm_set_element(rm_p, element); - } - } - } - } - } - - if (element >= rm_p->max_element) { - element = -1; - } - return (element); -} - -/* - * rm_show - * - * Description: - * Utility function used to dump the contents of the resource manager. - * - * Parameters: - * rm_p - pointer to the resource manager. - * - * Returns: - * none - */ -void -rm_show (resource_manager_t *rm_p) -{ - static const char fname[] = "rm_show"; - int16_t element = 0; - uint16_t i, j; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.\n", fname); - return; - } - - for (i = 0; i < rm_p->max_index; i++) { - for (j = 0; j < RM_NUM_ELEMENTS_PER_MAP; j++) { - if (rm_p->table[i] & (1 << j)) { - element = (i * RM_NUM_ELEMENTS_PER_MAP) + j; - TNP_DEBUG(DEB_F_PREFIX"rm map: %d\n", DEB_F_PREFIX_ARGS(RM, fname), element); - } - } - } -} - -/* - * rm_create - * - * Description: - * Allocates and initializes a new resource manager - * - * Parameters: - * max_element - Maximum number of elements the resource manager - * is required to track - * - * Returns: - * If successful, pointer to the newly allocated resource manager - * If not successful, NULL - */ -resource_manager_t * -rm_create (int16_t max_element) -{ - static const char fname[] = "rm_create"; - resource_manager_t *rm_p; - - if (max_element < 0) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"invalid max element %d received.\n", fname, - max_element); - return NULL; - } - - rm_p = (resource_manager_t *) cpr_malloc(sizeof(resource_manager_t)); - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"unable to allocate resource manager.\n", fname); - return NULL; - } - - rm_p->max_element = max_element; - rm_p->max_index = max_element / RM_NUM_ELEMENTS_PER_MAP + 1; - - rm_p->table = (uint32_t *) - cpr_malloc(rm_p->max_index * RM_NUM_ELEMENTS_PER_MAP); - if (!rm_p->table) { - free(rm_p); - return NULL; - } - rm_clear_all_elements(rm_p); - return rm_p; -} - -/* - * rm_free - * - * Description: - * This function frees the memory allocated for the specified resource manager. - * - * Parameters: - * rm_p - pointer to the resource manager. - * - * Returns: - * none - */ -void -rm_destroy (resource_manager_t *rm_p) -{ - static const char fname[] = "rm_destroy"; - - if (!rm_p) { - PLAT_ERROR(PLAT_COMMON_F_PREFIX"null resource manager received.\n", fname); - return; - } - - cpr_free(rm_p->table); - cpr_free(rm_p); -} diff --git a/libs/sipcc/core/common/resource_manager.h b/libs/sipcc/core/common/resource_manager.h deleted file mode 100644 index 4d34be59dc..0000000000 --- a/libs/sipcc/core/common/resource_manager.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _RM_MGR_H__ -#define _RM_MGR_H_ - -typedef struct resource_manager { - int16_t max_element; - int16_t max_index; - uint32_t *table; -} resource_manager_t; - -void rm_clear_all_elements(resource_manager_t *rm); -void rm_clear_element(resource_manager_t *rm, int16_t element); -void rm_set_element(resource_manager_t *rm, int16_t element); -boolean rm_is_element_set(resource_manager_t *rm, int16_t element); -int16_t rm_get_free_element(resource_manager_t *rm); -void rm_show(resource_manager_t *rm); -resource_manager_t *rm_create(int16_t max_element); -void rm_destroy(resource_manager_t *rm); - -#endif diff --git a/libs/sipcc/core/common/sip_socket_api.c b/libs/sipcc/core/common/sip_socket_api.c deleted file mode 100755 index 15952840f1..0000000000 --- a/libs/sipcc/core/common/sip_socket_api.c +++ /dev/null @@ -1,100 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr.h" -#include "cpr_socket.h" -#include "errno.h" -#include "plat_api.h" - -/** - * sipSocketSend - * - * @brief The sipSocketSend() function is a wrapper used by the sipstack to send - * data over a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc Specifies the socket created with cprSocket() to send - * @param[in] buf A pointer to the buffer of the message to send. - * @param[in] len Specifies the length in bytes of the message pointed to by the buffer argument. - * @param[in] flags - The options used for the send. - * - * - */ -ssize_t -sipSocketSend (cpr_socket_t soc, - CONST void *buf, - size_t len, - int32_t flags, - boolean secure) -{ -// if (secure) { -// return platSecSocSend (soc, buf, len); -// } else { - return cprSend(soc, buf, len, flags); -// } -} - -/** - * sipSocketRecv - * - * @brief The sipSocketRecv() function is a wrapper used by the sipstack to send - * data over a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc Specifies the socket created with cprSocket() to send - * @param[in] buf A pointer to the buffer of the message to send. - * @param[in] len Specifies the length in bytes of the message pointed to by the buffer argument. - * @param[in] flags - The options used for the recv. - */ -ssize_t -sipSocketRecv (cpr_socket_t soc, - void * RESTRICT buf, - size_t len, - int32_t flags, - boolean secure) -{ -// if (secure) { -// return platSecSocRecv (soc, buf, len); -// } else { - return cprRecv(soc, buf, len, flags); -// } -} - -/** - * sipSocketClose - * - * @brief The sipSocketClose() function is a wrapper used by the sipstack to - * close a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc - The socket that needs to be destroyed - * - * @return CPR_SUCCESS on success otherwise, CPR_FAILURE. cpr_errno needs to be set in this case. - * - * @note The possible error values this function should return are - * @li [CPR_EBADF] socket is not a valid socket descriptor. - */ -cpr_status_e -sipSocketClose (cpr_socket_t soc, - boolean secure) -{ -// if (secure) { -// return platSecSocClose (soc); -// } else { - return cprCloseSocket(soc); -// } -} - diff --git a/libs/sipcc/core/common/subscription_handler.c b/libs/sipcc/core/common/subscription_handler.c deleted file mode 100755 index f587379ccb..0000000000 --- a/libs/sipcc/core/common/subscription_handler.c +++ /dev/null @@ -1,342 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cc_types.h" -#include "phone_platform_constants.h" -#include "cc_constants.h" -#include "phone_debug.h" -#include "prot_configmgr.h" -#include "cc_blf.h" -#include "ccapi_snapshot.h" - -#define SPEEDDIAL_START_BUTTON_NUMBER 2 - -static unsigned char transactionIds[MAX_REG_LINES]; -static boolean displayBLFState = TRUE; -static cc_blf_state_t blfStates[MAX_REG_LINES]; -static boolean isBLFHandlerRunning = FALSE; -static boolean isAvailable = FALSE; - -#ifndef INT_MAX -#define INT_MAX 2147483647 -#endif - -static void ccBLFHandlerInitialized(); - -/* - * Function: sub_hndlr_isAlertingBLFState - * - * Description: returns if the BLF state is "alerting" - * - * Parameters: - * inst - line button number. - * - * Returns: TRUE/FALSE - */ -boolean sub_hndlr_isAlertingBLFState(int inst) -{ - static const char fname[] = "sub_hndlr_isAlertingBLFState"; - - if ((displayBLFState == TRUE) && (blfStates[inst - 1] == CC_SIP_BLF_ALERTING)) { - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, isAlerting=TRUE\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - inst); - - return TRUE; - } - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, isAlerting=FALSE\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - inst); - return FALSE; -} - -/* - * Function: sub_hndlr_isInUseBLFState - * - * Description: returns if the BLF state is "in use" - * - * Parameters: - * inst - line button number. - * - * Returns: TRUE/FALSE - */ -boolean sub_hndlr_isInUseBLFState(int inst) -{ - static const char fname[] = "sub_hndlr_isInUseBLFState"; - - if ((displayBLFState == TRUE) && (blfStates[inst - 1] == CC_SIP_BLF_INUSE)) { - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, isInUse=TRUE\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - inst); - return TRUE; - } - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, isInUse=FALSE\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - inst); - return FALSE; -} - -/* - * Function: sub_hndlr_isAvailable - * - * Description: returns if the subscription handler is available. - * - * Parameters: none. - * - * Returns: TRUE/FALSE - */ -boolean sub_hndlr_isAvailable() -{ - static const char fname[] = "sub_hndlr_isAvailable"; - - CCAPP_DEBUG(DEB_F_PREFIX"isAvailable=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - isAvailable); - return isAvailable; -} - -static unsigned short get_new_trans_id() -{ - static unsigned short curr_trans_id = 0; - - if (++curr_trans_id == 0) { - curr_trans_id = 1; - } - - return curr_trans_id; -} - -/* - * Function: sub_hndlr_start - * - * Description: does blf subscriptions upon registration. - * - * Parameters: none. - * - * Returns: void - */ -void sub_hndlr_start() -{ - static const char fname[] = "sub_hndlr_start"; - int i; - cc_uint32_t lineFeature = 0; - cc_uint32_t featureOptionMask = 0; - char speedDialNumber[MAX_LINE_NAME_SIZE] = {0}; - char primaryLine[MAX_LINE_NAME_SIZE] = {0}; - int transId; - - CCAPP_DEBUG(DEB_F_PREFIX"entering\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - /* let the system know that subscription handler is available. */ - isAvailable = TRUE; - - /* get primary DN */ - config_get_line_string(CFGID_LINE_NAME, primaryLine, 1, sizeof(primaryLine)); - - /* - * for speeddial/BLF buttons, make presence subscriptions. - */ - for (i = SPEEDDIAL_START_BUTTON_NUMBER; i <= MAX_REG_LINES; i++) { - // first line must always be a calling line. - config_get_line_value(CFGID_LINE_FEATURE, &lineFeature, sizeof(lineFeature), i); - - - CCAPP_DEBUG(DEB_F_PREFIX"inst=%d, lineFeature=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - i, lineFeature); - switch (lineFeature) { - case cfgLineFeatureSpeedDialBLF: - config_get_line_string(CFGID_LINE_SPEEDDIAL_NUMBER, speedDialNumber, i, sizeof(speedDialNumber)); - if (speedDialNumber[0] == 0) { - break; - } - config_get_line_value(CFGID_LINE_FEATURE, &featureOptionMask, sizeof(featureOptionMask), i); - - transId = get_new_trans_id(); - transactionIds[i - 1] = transId; - CC_BLF_subscribe(transId, - INT_MAX, - primaryLine, - speedDialNumber, - i, - featureOptionMask ); - break; - default: - break; - } - - //Initializes native BLF handler - ccBLFHandlerInitialized(); - } -} - -static void ccBLFHandlerInitialized() -{ - if (!isBLFHandlerRunning) { - CC_BLF_init(); - isBLFHandlerRunning = TRUE; - } -} - -/* - * Function: sub_hndlr_stop - * - * Description: terminates blf subscriptions upon unregistration. - * - * Parameters: none. - * - * Returns: void - */ -void sub_hndlr_stop() -{ - static const char fname[] = "sub_hndlr_stop"; - int i; - - CCAPP_DEBUG(DEB_F_PREFIX"entering\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - isAvailable = FALSE; - isBLFHandlerRunning = FALSE; - - // should clean up blf susbcription list. - for (i = SPEEDDIAL_START_BUTTON_NUMBER; i <= MAX_REG_LINES; i++) { - //first, reset the transaction ids - transactionIds[i - 1] = 0; - //reset blf states. - blfStates[i - 1] = CC_SIP_BLF_UNKNOWN; - } - CC_BLF_unsubscribe_All(); -} - - -/* - * Function: hideBLFButtonsDisplay - * - * Description: hides BLF states - * - * Parameters: none. - * - * Returns: void - */ -static void hideBLFButtonsDisplay() -{ - static const char fname[] = "hideBLFButtonsDisplay"; - int i; - cc_uint32_t lineFeature = 0; - - CCAPP_DEBUG(DEB_F_PREFIX"entering\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - displayBLFState = FALSE; - for (i = SPEEDDIAL_START_BUTTON_NUMBER; i <= MAX_REG_LINES; i++) { - // first line must always be a calling line. - config_get_line_value(CFGID_LINE_FEATURE, &lineFeature, sizeof(lineFeature), i); - - switch (lineFeature) { - case cfgLineFeatureSpeedDialBLF: - ccsnap_gen_blfFeatureEvent(CC_SIP_BLF_UNKNOWN, i); - break; - default: - break; - } - } -} - -/* - * Function: unhideBLFButtonsDisplay - * - * Description: unhides BLF states. - * - * Parameters: none. - * - * Returns: void - */ -static void unhideBLFButtonsDisplay() -{ - static const char fname[] = "unhideBLFButtonsDisplay"; - int i; - cc_uint32_t lineFeature = 0; - char speedDialNumber[MAX_LINE_NAME_SIZE] = {0}; - - CCAPP_DEBUG(DEB_F_PREFIX"entering\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - - displayBLFState = TRUE; - - for (i = SPEEDDIAL_START_BUTTON_NUMBER; i <= MAX_REG_LINES; i++) { - // first line must always be a calling line. - config_get_line_value(CFGID_LINE_FEATURE, &lineFeature, sizeof(lineFeature), i); - config_get_line_string(CFGID_LINE_SPEEDDIAL_NUMBER, speedDialNumber, i, sizeof(speedDialNumber)); - - switch (lineFeature) { - case cfgLineFeatureSpeedDialBLF: - ccsnap_gen_blfFeatureEvent(blfStates[i - 1], i); - break; - default: - break; - } - } -} - -/* - * Function: sub_hndlr_controlBLFButtons - * - * Description: hides/unhides BLF states. - * - * Parameters: none. - * - * Returns: void - */ -void sub_hndlr_controlBLFButtons(boolean state) -{ - static const char fname[] = "sub_hndlr_controlBLFButtons"; - - if (state == TRUE) { - CCAPP_DEBUG(DEB_F_PREFIX"going to hide\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - hideBLFButtonsDisplay(); - } else { - CCAPP_DEBUG(DEB_F_PREFIX"going to unhide\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname)); - unhideBLFButtonsDisplay(); - } -} - -/* - * Function: sub_hndlr_NotifyBLFStatus - * - * Description: notifies the app of BLF state. - * - * Parameters: - * requestId - requestId of the subscription - * status - BLF status - * appId - button number of the BLF feature key. - * - * Returns: void - */ -void sub_hndlr_NotifyBLFStatus(int requestId, cc_blf_state_t status, int appId) -{ - static const char fname[] = "sub_hndlr_NotifyBLFStatus"; - cc_uint32_t lineFeature = 0; - char speedDialNumber[MAX_LINE_NAME_SIZE] = {0}; - - - CCAPP_DEBUG(DEB_F_PREFIX"requestId=%d, status=%d, appId=%d\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), - requestId, status, appId); - if (appId == 0) { - // call list BLF. - } else { - config_get_line_value(CFGID_LINE_FEATURE, &lineFeature, sizeof(lineFeature), appId); - config_get_line_string(CFGID_LINE_SPEEDDIAL_NUMBER, speedDialNumber, appId, sizeof(speedDialNumber)); - - blfStates[appId - 1] = status; - if (displayBLFState == FALSE) { - return; // ignore the notify - } - if (lineFeature == cfgLineFeatureSpeedDialBLF) { - ccsnap_gen_blfFeatureEvent(status, appId); - } - } -} - diff --git a/libs/sipcc/core/common/subscription_handler.h b/libs/sipcc/core/common/subscription_handler.h deleted file mode 100755 index 3bcf7317d2..0000000000 --- a/libs/sipcc/core/common/subscription_handler.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SUB_HANDLER_H__ -#define __SUB_HANDLER_H__ - -boolean sub_hndlr_isAlertingBLFState(int inst); - -boolean sub_hndlr_isInUseBLFState(int inst); - -boolean sub_hndlr_isAvailable(); - -void sub_hndlr_start(); - -void sub_hndlr_stop(); - -void sub_hndlr_controlBLFButtons(boolean state); - -void sub_hndlr_NotifyBLFStatus(int requestId, int status, int appId); - -#endif - diff --git a/libs/sipcc/core/common/text_strings.c b/libs/sipcc/core/common/text_strings.c deleted file mode 100755 index b8576c9c7d..0000000000 --- a/libs/sipcc/core/common/text_strings.c +++ /dev/null @@ -1,361 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "text_strings.h" - - -#define dcl_str(x,p) char str_##x[] = p -#define use_str(x) str_##x - - -/* - * Debug strings. No localization needed. Keep it separate. - */ - -dcl_str(DEBUG_START, "SIPCC-START:\0"); -dcl_str(DEBUG_SEPARATOR_BAR, "===============\n"); -dcl_str(DEBUG_CONSOLE_PASSWORD, "CONSOLE-PWD:cisco"); -dcl_str(DEBUG_CONSOLE_KEYWORD_CONSOLE_STALL, "CONSOLE-STALL"); -dcl_str(DEBUG_CONSOLE_KEYWORD_MEMORYMAP, "CONSOLE-MEMORYMAP"); -dcl_str(DEBUG_CONSOLE_KEYWORD_MALLOCTABLE, "CONSOLE-MALLOCTABLE"); -dcl_str(DEBUG_CONSOLE_KEYWORD_MEMORYDUMP, "CONSOLE-DUMP"); -dcl_str(DEBUG_CONSOLE_KEYWORD_DNS, "CONSOLE-DNS"); -dcl_str(DEBUG_CONSOLE_KEYWORD_DSPSTATE, "CONSOLE-DSPSTATE"); -dcl_str(DEBUG_CONSOLE_USAGE_MEMORYDUMP, "CONSOLE-MEMORYDUMP: addr bytes [cnt blk [1/0 char output]]\n"); -dcl_str(DEBUG_CONSOLE_BREAK, "CONSOLE-BREAK\r\n"); - -dcl_str(DEBUG_FUNCTION_ENTRY, "SIPCC-FUNC_ENTRY: LINE %d/%d: %-35s: %s <- %s\n"); -dcl_str(DEBUG_FUNCTION_ENTRY2, "SIPCC-FUNC_ENTRY: LINE %d/%d: %-35s: %s <- %s(%d)\n"); -dcl_str(DEBUG_SIP_ENTRY, "SIPCC-ENTRY: LINE %d/%d: %-35s: %s\n"); -dcl_str(DEBUG_SIP_URL_ERROR, "SIPCC-%s: Error: URL is not SIP.\n"); -dcl_str(DEBUG_LINE_NUMBER_INVALID, "SIPCC-LINE_NUM: %s: Error: Line number (%d) is invalid\n"); -dcl_str(DEBUG_SIP_SPI_SEND_ERROR, "SIPCC-SPI_SEND_ERR: %s: Error: sipSPISendErrorResponse(%d) failed.\n"); -dcl_str(DEBUG_SIP_SDP_CREATE_BUF_ERROR, "SIPCC-SDP_BUF: %s: Error: sipsdp_src_dest_create() returned null\n"); -dcl_str(DEBUG_SIP_PARSE_SDP_ERROR, "SIPCC-SDP_PARSE: %s: Error: sdp_parse()\n"); -dcl_str(DEBUG_SIP_FEATURE_UNSUPPORTED, "SIPCC-FEATURE: LINE %d/%d: %-35s: This feature is unsupported in the current state.\n"); -dcl_str(DEBUG_SIP_DEST_SDP, "SIPCC-SDP_DEST: LINE %d/%d: %-35s: Process SDP: Dest=<%s>:<%d>\n"); -dcl_str(DEBUG_SIP_MSG_SENDING_REQUEST, "SIPCC-MSG_SEND_REQ: %s: Sending %s...\n"); -dcl_str(DEBUG_SIP_MSG_SENDING_RESPONSE, "SIPCC-MSG_SEND_RESP: %s: Sending response %d...\n"); -dcl_str(DEBUG_SIP_MSG_RECV, "SIPCC-MSG_RECV: %s: Received SIP message %s.\n"); -dcl_str(DEBUG_SIP_STATE_UNCHANGED, "SIPCC-SIP_STATE: LINE %d/%d: %-35s: State unchanged -> %s\n"); -dcl_str(DEBUG_SIP_FUNCTIONCALL_FAILED, "SIPCC-FUNC_CALL: LINE %d/%d: %-35s: Error: %s returned error.\n"); -dcl_str(DEBUG_SIP_BUILDFLAG_ERROR, "SIPCC-BUILD_FLAG: %s: Error: Build flag is not successful. Will not send message.\n"); -dcl_str(DEBUG_GENERAL_FUNCTIONCALL_FAILED, "SIPCC-FUNC_CALL: %s: Error: %s returned error.\n"); -dcl_str(DEBUG_GENERAL_SYSTEMCALL_FAILED, "SIPCC-SYS_CALL: %s: Error: %s failed: errno = %d\n"); -dcl_str(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT, "SIPCC-FUNC_CALL: %s: Error: invalid argument: %s\n"); -dcl_str(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM, "SIPCC-FUNC_NAME: sippmh_parse_from_or_to(FROM)"); -dcl_str(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO, "SIPCC-FUNC_NAME: sippmh_parse_from_or_to(TO)"); -dcl_str(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE, "SIPCC-SM_REQ: sip_sm_request_check_and_store()"); -dcl_str(DEBUG_SNTP_LI_ERROR, "SIPCC-SNTP: Leap indicator == 3\n"); -dcl_str(DEBUG_SNTP_MODE_ERROR, "SIPCC-SNTP: Mode is not server (4/5) in response\n"); -dcl_str(DEBUG_SNTP_STRATUM_ERROR, "SIPCC-SNTP: Invalid stratum > 15\n"); -dcl_str(DEBUG_SNTP_TIMESTAMP_ERROR, "SIPCC-SNTP: Server did not echo our transmit timestamp\n"); -dcl_str(DEBUG_SNTP_TIMESTAMP1, "SIPCC-SNTP: %-15s: 0x%08x %08x, "); -dcl_str(DEBUG_SNTP_TIMESTAMP2, "SIPCC-SNTP: (%+03d:%02d) %s"); -dcl_str(DEBUG_SNTP_TIME_UPDATE, "SIPCC-SNTP: Updating date and time to:\n%s %lu %02lu:%02lu:%02lu " - "%04lu, %s, week %lu and day %lu. " - "Daylight saving is: %d\n\n"); -dcl_str(DEBUG_SNTP_TS_HEADER, "SIPCC-SNTP: Settings:\nMode : %lu\nTimezone " - ": %d\nServer Addr : %s\nTimeStruct : TZ/Offset: %d/%lu," - " AutoAdjust: %d\nMo Day DoW WoM Time\n"); -dcl_str(DEBUG_SNTP_TS_PRINT, "SIPCC-SNTP: %3lu %3lu %3lu %3lu %4lu\n"); -dcl_str(DEBUG_SNTP_SOCKET_REOPEN, "SIPCC-SNTP: Re-opening listening port due to IP change\n"); -dcl_str(DEBUG_SNTP_DISABLED, "SIPCC-SNTP: Unicast w/server addr 0.0.0.0, SNTP disabled\n"); -dcl_str(DEBUG_SNTP_REQUEST, "SIPCC-SNTP: Sending NTP request packet [%s]\n"); -dcl_str(DEBUG_SNTP_RESPONSE, "SIPCC-SNTP: Receiving NTP response packet\n"); -dcl_str(DEBUG_SNTP_RETRANSMIT, "SIPCC-SNTP: Waiting %d msec to retransmit\n"); -dcl_str(DEBUG_SNTP_UNICAST_MODE, "SIPCC-SNTP: Unicast mode [%s]\n"); -dcl_str(DEBUG_SNTP_MULTICAST_MODE, "SIPCC-SNTP: Multicast/Directed broadcast mode [%s]\n"); -dcl_str(DEBUG_SNTP_ANYCAST_MODE, "SIPCC-SNTP: Anycast mode [%s]\n"); -dcl_str(DEBUG_SNTP_VALIDATION, "SIPCC-SNTP: Dropping unauthorized SNTP response: %s\n"); -dcl_str(DEBUG_SNTP_VALIDATION_PACKET, "SIPCC-SNTP: Semantic check failed for NTP packet\n"); -dcl_str(DEBUG_SNTP_WRONG_SERVER, "SIPCC-SNTP: Unauthorized server"); -dcl_str(DEBUG_SNTP_NO_REQUEST, "SIPCC-SNTP: No request sent"); -dcl_str(DEBUG_SNTP_ANYCAST_RESET, "SIPCC-SNTP: Reset to Unicast to server: %s\n"); -dcl_str(DEBUG_SOCKET_UDP_RTP, "SIPCC-SOC_TASK: UDP_RTP event received.\n"); -dcl_str(DEBUG_MAC_PRINT, "SIPCC-MAC_PRINT: %04x:%04x:%04x"); -dcl_str(DEBUG_IP_PRINT, "SIPCC-IP_PRINT: %u.%u.%u.%u"); -dcl_str(DEBUG_SYSBUF_UNAVAILABLE, "SIPCC-SYS_BUF: %s: Error: IRXLstGet() failed\n"); -dcl_str(DEBUG_MSG_BUFFER_TOO_BIG, "SIPCC-MSG_BUF: %s: Error: Args Check: message buffer length (%d) too big.\n"); -dcl_str(DEBUG_UNKNOWN_TIMER_BLOCK, "SIPCC-TIMER: %s: Error: Unknown timer block\n"); -dcl_str(DEBUG_CREDENTIALS_BAG_CORRUPTED, "SIPCC-CRED: %-35s: Error: credentials bags corrupted"); -dcl_str(DEBUG_INPUT_NULL, "SIPCC-INPUT: %s: Error: Input is null\n"); -dcl_str(DEBUG_INPUT_EMPTY, "SIPCC-INPUT: %s: Error: Input is empty\n"); -dcl_str(DEBUG_STRING_DUP_FAILED, "SIPCC-STR_DUP: %s: Unable to duplicate string.\n"); -dcl_str(DEBUG_PARSER_STRING_TOO_LARGE, "SIPCC-PARSE: Parse error: string too big (%d,%d)\n"); -dcl_str(DEBUG_PARSER_NULL_KEY_TABLE, "SIPCC-PARSE: Parse error: NULL key table passed into parser\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_KEY, "SIPCC-PARSE: Parse error: Unknown key name: %s\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_KEY_ENUM, "SIPCC-PARSE: Print error: Unknown key enum: %d\n"); -dcl_str(DEBUG_PARSER_INVALID_START_VAR, "SIPCC-PARSE: Parse error: Invalid start variable ch=0x%02x(%c)\n"); -dcl_str(DEBUG_PARSER_INVALID_VAR_CHAR, "SIPCC-PARSE: Parse error: Invalid variable ch=0x%02x(%c)\n"); -dcl_str(DEBUG_PARSER_MISSING_COLON, "SIPCC-PARSE: Parse error: Missing colon separator\n"); -dcl_str(DEBUG_PARSER_NO_VALUE, "SIPCC-PARSE: Parse error: no value for variable\n"); -dcl_str(DEBUG_PARSER_EARLY_EOL, "SIPCC-PARSE: Parse error: early EOL for value\n"); -dcl_str(DEBUG_PARSER_INVALID_VAR_NAME, "SIPCC-PARSE: Parse error: parse_var_name failed: %d\n"); -dcl_str(DEBUG_PARSER_INVALID_VAR_VALUE, "SIPCC-PARSE: Parse error: var: %s parse_var_value failed: %d\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_VAR, "SIPCC-PARSE: Parse error: var: %s not found in table\n"); -dcl_str(DEBUG_PARSER_NAME_VALUE, "SIPCC-PARSE: Name: [%s] Value: [%s]\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_NAME_VALUE, "SIPCC-PARSE: Parse error: Name: [%s] Value: [%s] rc:%d\n"); -dcl_str(DEBUG_PARSER_UNKNOWN_ERROR, "SIPCC-PARSE: Default error: Name: [%s] Value: [%s] rc:%d\n"); -dcl_str(DEBUG_PARSER_NUM_ERRORS, "SIPCC-PARSE: Parse error: %d Errors found\n"); -dcl_str(DEBUG_PARSER_SET_DEFAULT, "SIPCC-PARSE: Parser Info: Setting var: %s to default value: %s\n\n"); -dcl_str(DEBUG_SDP_ERROR_BODY_FIELD, "SIPCC-SDP: \n%s: Error in one of the SDP body fields \n"); -dcl_str(DEBUG_UDP_OPEN_FAIL, "SIPCC-UDP: %s: UdpOpen(R IP=%d, R Port=%d, L Port=%d) failed\n"); -dcl_str(DEBUG_UDP_PAYLOAD_TOO_LARGE, "SIPCC-UDP: %s: Error: payload size=<%d> > allowed size=<%d>\n"); -dcl_str(DEBUG_RTP_TRANSPORT, "SIPCC-RTP: %s: transport= %d\n"); -dcl_str(DEBUG_RTP_INVALID_VOIP_TYPE, "SIPCC-RTP: %s: Error: Unexpected voipCodec_t type: <%d>\n"); -dcl_str(DEBUG_RTP_INVALID_RTP_TYPE, "SIPCC-RTP: %s: Error: Unexpected rtp_ptype in SDP body: <%d>\n"); -dcl_str(DEBUG_MEMORY_ALLOC, "SIPCC-MEM: Malloc Addr:0x%lx, Size:%d\n"); -dcl_str(DEBUG_MEMORY_FREE, "SIPCC-MEM: Free Addr:0x%lx, Size:%d\n"); -dcl_str(DEBUG_MEMORY_MALLOC_ERROR, "SIPCC-MEM: 0x%lx:Malloc error for size %d\n"); -dcl_str(DEBUG_MEMORY_REALLOC_ERROR, "SIPCC-MEM: %s: Error: malloc_tagged() returned null.\n"); -dcl_str(DEBUG_MEMORY_OUT_OF_MEM, "SIPCC-MEM: %s: Error: malloc failed\n"); -dcl_str(DEBUG_MEMORY_ENTRY, "SIPCC-MEM: >> Used: %1d size: %6d addr:0x%08x\n"); -dcl_str(DEBUG_MEMORY_SUMMARY, "===== MEMORY MAP START =====\n" - "free blocks : %6d, free block space:%6d, largest free block: %6d\n" - "used blocks : %6d, used block space:%6d, largest used block: %6d\n" - "wasted block: %6d, str_lib space :%6d\n" - "used space excluding str_lib space :%6d\n \n" - "===== MEMORY MAP END =====\n"); -dcl_str(DEBUG_MEMORY_ADDRESS_HEADER, "SIPCC-MEM: 0x%08x: "); -dcl_str(DEBUG_MEMORY_DUMP, "SIPCC-MEM: DUMP: 0x%08x - 0x%08x\n"); -dcl_str(DEBUG_DNS_GETHOSTBYNAME, "SIPCC-DNS: gethostbyname('%s',%08x,%d,%d)\n"); -dcl_str(DEBUG_PMH_INCORRECT_SYNTAX, "SIPCC-PMH: INCORRECT SYNTAX"); -dcl_str(DEBUG_PMH_INVALID_FIELD_VALUE, "SIPCC-PMH: INVALID FIELD VALUE"); -dcl_str(DEBUG_PMH_INVALID_SCHEME, "SIPCC-PMH: INVALID SCHEME"); -dcl_str(DEBUG_PMH_UNKNOWN_SCHEME, "SIPCC-PMH: UNKNOWN SCHEME"); -dcl_str(DEBUG_PMH_NOT_ENOUGH_PARAMETERS, "SIPCC-PMH: NOT ENOUGH PARAMETERS"); -dcl_str(DEBUG_REG_DISABLED, "SIPCC-REG: LINE %d/%d: %-35s: registration disabled\n"); -dcl_str(DEBUG_REG_PROXY_EXPIRES, "SIPCC-REG: LINE %d/%d: %-35s: Using proxy expires value\n"); -dcl_str(DEBUG_REG_SIP_DATE, "SIPCC-REG: LINE %d/%d: %-35s: SIP-date= %s\n"); -dcl_str(DEBUG_REG_SIP_RESP_CODE, "SIPCC-REG: LINE %d/%d: %-35s: Error: SIP response code\n"); -dcl_str(DEBUG_REG_SIP_RESP_FAILURE, "SIPCC-REG: LINE %d/%d: %-35s: SIP failure %d resp\n"); -dcl_str(DEBUG_REG_INVALID_LINE, "SIPCC-REG: %-35s: Line %d: Invalid line\n"); -dcl_str(CC_NO_MSG_BUFFER, "SIPCC-MSG_BUF: %s : no msg buffer available\n"); -dcl_str(CC_SEND_FAILURE, "SIPCC-MSG_SEND: %s : unable to send msg\n"); -dcl_str(GSM_UNDEFINED, "SIPCC-GSM: UNDEFINED"); -dcl_str(GSM_DBG_PTR, "SIPCC-GSM_DBG_PTR: %s %-4d: %-35s: %s= %p\n"); -dcl_str(GSM_FUNC_ENTER, "SIPCC-GSM_FUNC_ENT: %s %-4d: %-35s\n"); -dcl_str(GSM_DBG1, "SIPCC-GSM: %s %-4d: %-35s: %s\n"); -dcl_str(FSM_DBG_SM_DEFAULT_EVENT, "SIPCC-FSM: default - ignoring.\n"); -dcl_str(FSM_DBG_SM_FTR_ENTRY, "SIPCC-FSM: feature= %s, src= %s\n"); -dcl_str(FSM_DBG_FAC_ERR, "SIPCC-FSM_FAC_ERR: %-4d: %-35s:\n %s, rc= %s\n"); -dcl_str(FSM_DBG_FAC_FOUND, "SIPCC-FSM: %-4d: %-35s: facility found(%d)\n"); -dcl_str(FSM_DBG_IGNORE_FTR, "SIPCC-FSM: %s %-4d: %8d: ignoring feature= %s\n"); -dcl_str(FSM_DBG_IGNORE_SRC, "SIPCC-FSM: %s %-4d: %8d: ignoring src= %s\n"); -dcl_str(FSM_DBG_CHANGE_STATE, "SIPCC-FSM: %s %-4d: %8d: %s -> %s\n"); -dcl_str(FSM_DBG_SDP_BUILD_ERR, "SIPCC-FSM: Unable to build SDP. \n"); -dcl_str(FSMDEF_DBG_PTR, "SIPCC-FSM: DEF %-4d/%d: %-35s: dcb= %p\n"); -dcl_str(FSMDEF_DBG1, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s\n"); -dcl_str(FSMDEF_DBG2, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s %d\n"); -dcl_str(FSMDEF_DBG_SDP, "SIPCC-FSM: DEF %-4d/%d: %-35s: addr= %s, port= %d,\n media_type(s)="); -dcl_str(FSMDEF_DBG_CLR_SPOOF_APPLD, "SIPCC-FSM: DEF %-4d/%d: %-35s: clearing spoof_ringout_applied.\n"); -dcl_str(FSMDEF_DBG_CLR_SPOOF_RQSTD, "SIPCC-FSM: DEF %-4d/%d: %-35s: clearing spoof_ringout_requested.\n"); -dcl_str(FSMDEF_DBG_INVALID_DCB, "SIPCC-FSM: DEF 0 : %-35s: invalid dcb\n"); -dcl_str(FSMDEF_DBG_FTR_REQ_ACT, "SIPCC-FSM: DEF %-4d/%d: feature requested %s but %s is active.\n"); -dcl_str(FSMDEF_DBG_TMR_CREATE_FAILED, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s:\n cprCreateTimer failed.\n"); -dcl_str(FSMDEF_DBG_TMR_START_FAILED, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s:\n cprStartTimer failed, errno= %d.\n"); -dcl_str(FSMDEF_DBG_TMR_CANCEL_FAILED, "SIPCC-FSM: DEF %-4d/%d: %-35s: %s:\n cprCancelTimer failed, errno= %d.\n"); -dcl_str(FSMXFR_DBG_XFR_INITIATED, "SIPCC-FSM: XFR %-4d/%d/%d: %8d: xfer initiated\n"); -dcl_str(FSMXFR_DBG_PTR, "SIPCC-FSM: XFR %-4d/%d/%d: %-35s: xcb= %p\n"); -dcl_str(FSMCNF_DBG_CNF_INITIATED, "SIPCC-FSM: CNF %-4d/%d/%d: %8d: conf initiated\n"); -dcl_str(FSMCNF_DBG_PTR, "SIPCC-FSM: CNF %-4d/%d/%d: %-35s: ncb= %p\n"); -dcl_str(FSMB2BCNF_DBG_CNF_INITIATED, "SIPCC-FSM: B2BCNF %-4d/%d/%d: %8d: b2bconf initiated\n"); -dcl_str(FSMB2BCNF_DBG_PTR, "SIPCC-FSM: B2BCNF %-4d/%d/%d: %-35s: ncb= %p\n"); -dcl_str(FSMSHR_DBG_BARGE_INITIATED, "SIPCC-FSM: SHR %-4d/%d/%d: %8d: Barge initiated\n"); -dcl_str(LSM_DBG_ENTRY, "SIPCC-LSM: %-4d/%d: %-35s\n"); -dcl_str(LSM_DBG_INT1, "SIPCC-LSM: %-4d/%d: %-35s: %s= %d\n"); -dcl_str(LSM_DBG_CC_ERROR, "SIPCC-LSM: %-4d/%d: %-35s: (%d:%p) failure\n"); -dcl_str(VCM_DEBUG_ENTRY, "SIPCC-VCM: %-4d: %-35s\n"); -dcl_str(SM_PROCESS_EVENT_ERROR, "SIPCC-SM: %s: Error: sip_sm_process_event() returned error processing %d\n"); -dcl_str(REG_SM_PROCESS_EVENT_ERROR, "SIPCC-SM: %s: Error: sip_reg_sm_process_event() returned error processing %d\n"); -dcl_str(DEBUG_END, "SIPCC-END: \0"); - -/* - * Debug string table NOT subject to localization - */ -debug_string_table_entry debug_string_table [] = { - {0}, // DEBUG_START - {use_str(DEBUG_SEPARATOR_BAR)}, // DEBUG_SEPARATOR_BAR - {use_str(DEBUG_CONSOLE_PASSWORD)}, // DEBUG_CONSOLE_PASSWORD - {use_str(DEBUG_CONSOLE_KEYWORD_CONSOLE_STALL)}, // DEBUG_CONSOLE_KEYWORD_CONSOLE_STALL - {use_str(DEBUG_CONSOLE_KEYWORD_MEMORYMAP)}, // DEBUG_CONSOLE_KEYWORD_MEMORYMAP - {use_str(DEBUG_CONSOLE_KEYWORD_MALLOCTABLE)}, // DEBUG_CONSOLE_KEYWORD_MALLOCTABLE - {use_str(DEBUG_CONSOLE_KEYWORD_MEMORYDUMP)}, // DEBUG_CONSOLE_KEYWORD_MEMORYDUMP - {use_str(DEBUG_CONSOLE_KEYWORD_DNS)}, // DEBUG_CONSOLE_KEYWORD_DNS - {use_str(DEBUG_CONSOLE_KEYWORD_DSPSTATE)}, // DEBUG_CONSOLE_KEYWORD_DSPSTATE - {use_str(DEBUG_CONSOLE_USAGE_MEMORYDUMP)}, // DEBUG_CONSOLE_USAGE_MEMORYDUMP - {use_str(DEBUG_CONSOLE_BREAK)}, // DEBUG_CONSOLE_BREAK - {use_str(DEBUG_FUNCTION_ENTRY)}, // DEBUG_FUNCTION_ENTRY - {use_str(DEBUG_FUNCTION_ENTRY2)}, // DEBUG_FUNCTION_ENTRY2 - {use_str(DEBUG_SIP_ENTRY)}, // DEBUG_SIP_ENTRY - {use_str(DEBUG_SIP_URL_ERROR)}, // DEBUG_SIP_URL_ERROR - {use_str(DEBUG_LINE_NUMBER_INVALID)}, // DEBUG_LINE_NUMBER_INVALID - {use_str(DEBUG_SIP_SPI_SEND_ERROR)}, // DEBUG_SIP_SPI_SEND_ERROR - {use_str(DEBUG_SIP_SDP_CREATE_BUF_ERROR)}, // DEBUG_SIP_SDP_CREATE_BUF_ERROR - {use_str(DEBUG_SIP_PARSE_SDP_ERROR)}, // DEBUG_SIP_PARSE_SDP_ERROR - {use_str(DEBUG_SIP_FEATURE_UNSUPPORTED)}, // DEBUG_SIP_FEATURE_UNSUPPORTED - {use_str(DEBUG_SIP_DEST_SDP)}, // DEBUG_SIP_DEST_SDP - {use_str(DEBUG_SIP_MSG_SENDING_REQUEST)}, // DEBUG_SIP_MSG_SENDING_REQUEST - {use_str(DEBUG_SIP_MSG_SENDING_RESPONSE)}, // DEBUG_SIP_MSG_SENDING_RESPONSE - {use_str(DEBUG_SIP_MSG_RECV)}, // DEBUG_SIP_MSG_RECV - {use_str(DEBUG_SIP_STATE_UNCHANGED)}, // DEBUG_SIP_STATE_UNCHANGED - {use_str(DEBUG_SIP_FUNCTIONCALL_FAILED)}, // DEBUG_SIP_FUNCTIONCALL_FAILED - {use_str(DEBUG_SIP_BUILDFLAG_ERROR)}, // DEBUG_SIP_BUILDFLAG_ERROR - {use_str(DEBUG_GENERAL_FUNCTIONCALL_FAILED)}, // DEBUG_GENERAL_FUNCTIONCALL_FAILED - {use_str(DEBUG_GENERAL_SYSTEMCALL_FAILED)}, // DEBUG_GENERAL_SYSTEMCALL_FAILED - {use_str(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT)}, // DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT - {use_str(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)},// DEBUG_FUNCTIONNAME_SIP_PARSE_FROM - {use_str(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)}, // DEBUG_FUNCTIONNAME_SIP_PARSE_TO - {use_str(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)}, // DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE - {use_str(DEBUG_SNTP_LI_ERROR)}, // DEBUG_SNTP_LI_ERROR - {use_str(DEBUG_SNTP_MODE_ERROR)}, // DEBUG_SNTP_MODE_ERROR - {use_str(DEBUG_SNTP_STRATUM_ERROR)}, // DEBUG_SNTP_STRATUM_ERROR - {use_str(DEBUG_SNTP_TIMESTAMP_ERROR)}, // DEBUG_SNTP_TIMESTAMP_ERROR - {use_str(DEBUG_SNTP_TIMESTAMP1)}, // DEBUG_SNTP_TIMESTAMP1 - {use_str(DEBUG_SNTP_TIMESTAMP2)}, // DEBUG_SNTP_TIMESTAMP2 - {use_str(DEBUG_SNTP_TIME_UPDATE)}, // DEBUG_SNTP_TIME_UPDATE - {use_str(DEBUG_SNTP_TS_HEADER)}, // DEBUG_SNTP_TS_HEADER - {use_str(DEBUG_SNTP_TS_PRINT)}, // DEBUG_SNTP_TS_PRINT - {use_str(DEBUG_SNTP_SOCKET_REOPEN)}, // DEBUG_SNTP_SOCKET_REOPEN - {use_str(DEBUG_SNTP_DISABLED)}, // DEBUG_SNTP_DISABLED - {use_str(DEBUG_SNTP_REQUEST)}, // DEBUG_SNTP_REQUEST - {use_str(DEBUG_SNTP_RESPONSE)}, // DEBUG_SNTP_RESPONSE - {use_str(DEBUG_SNTP_RETRANSMIT)}, // DEBUG_SNTP_RETRANSMIT - {use_str(DEBUG_SNTP_UNICAST_MODE)}, // DEBUG_SNTP_UNICAST_MODE - {use_str(DEBUG_SNTP_MULTICAST_MODE)}, // DEBUG_SNTP_MULTICAST_MODE - {use_str(DEBUG_SNTP_ANYCAST_MODE)}, // DEBUG_SNTP_ANYCAST_MODE - {use_str(DEBUG_SNTP_VALIDATION)}, // DEBUG_SNTP_VALIDATION - {use_str(DEBUG_SNTP_VALIDATION_PACKET)}, // DEBUG_SNTP_VALIDATION_PACKET - {use_str(DEBUG_SNTP_WRONG_SERVER)}, // DEBUG_SNTP_WRONG_SERVER - {use_str(DEBUG_SNTP_NO_REQUEST)}, // DEBUG_SNTP_NO_REQUEST - {use_str(DEBUG_SNTP_ANYCAST_RESET)}, // DEBUG_SNTP_ANYCAST_RESET - {use_str(DEBUG_SOCKET_UDP_RTP)}, // DEBUG_SOCKET_UDP_RTP - {use_str(DEBUG_MAC_PRINT)}, // DEBUG_MAC_PRINT - {use_str(DEBUG_IP_PRINT)}, // DEBUG_IP_PRINT - {use_str(DEBUG_SYSBUF_UNAVAILABLE)}, // DEBUG_SYSBUF_UNAVAILABLE - {use_str(DEBUG_MSG_BUFFER_TOO_BIG)}, // DEBUG_MSG_BUFFER_TOO_BIG - {use_str(DEBUG_UNKNOWN_TIMER_BLOCK)}, // DEBUG_UNKNOWN_TIMER_BLOCK - {use_str(DEBUG_CREDENTIALS_BAG_CORRUPTED)}, // DEBUG_CREDENTIALS_BAG_CORRUPTED - {use_str(DEBUG_INPUT_NULL)}, // DEBUG_INPUT_NULL - {use_str(DEBUG_INPUT_EMPTY)}, // DEBUG_INPUT_EMPTY - {use_str(DEBUG_STRING_DUP_FAILED)}, // DEBUG_STRING_DUP_FAILED - {use_str(DEBUG_PARSER_STRING_TOO_LARGE)}, // DEBUG_PARSER_STRING_TOO_LARGE - {use_str(DEBUG_PARSER_NULL_KEY_TABLE)}, // DEBUG_PARSER_NULL_KEY_TABLE - {use_str(DEBUG_PARSER_UNKNOWN_KEY)}, // DEBUG_PARSER_UNKNOWN_KEY - {use_str(DEBUG_PARSER_UNKNOWN_KEY_ENUM)}, // DEBUG_PARSER_UNKNOWN_KEY_ENUM - {use_str(DEBUG_PARSER_INVALID_START_VAR)}, // DEBUG_PARSER_INVALID_START_VAR - {use_str(DEBUG_PARSER_INVALID_VAR_CHAR)}, // DEBUG_PARSER_INVALID_VAR_CHAR - {use_str(DEBUG_PARSER_MISSING_COLON)}, // DEBUG_PARSER_MISSING_COLON - {use_str(DEBUG_PARSER_NO_VALUE)}, // DEBUG_PARSER_NO_VALUE - {use_str(DEBUG_PARSER_EARLY_EOL)}, // DEBUG_PARSER_EARLY_EOL - {use_str(DEBUG_PARSER_INVALID_VAR_NAME)}, // DEBUG_PARSER_INVALID_VAR_NAME - {use_str(DEBUG_PARSER_INVALID_VAR_VALUE)}, // DEBUG_PARSER_INVALID_VAR_VALUE - {use_str(DEBUG_PARSER_UNKNOWN_VAR)}, // DEBUG_PARSER_UNKNOWN_VAR - {use_str(DEBUG_PARSER_NAME_VALUE)}, // DEBUG_PARSER_NAME_VALUE - {use_str(DEBUG_PARSER_UNKNOWN_NAME_VALUE)}, // DEBUG_PARSER_UNKNOWN_NAME_VALUE - {use_str(DEBUG_PARSER_UNKNOWN_ERROR)}, // DEBUG_PARSER_UNKNOWN_ERROR - {use_str(DEBUG_PARSER_NUM_ERRORS)}, // DEBUG_PARSER_NUM_ERRORS - {use_str(DEBUG_PARSER_SET_DEFAULT)}, // DEBUG_PARSER_SET_DEFAULT - {use_str(DEBUG_SDP_ERROR_BODY_FIELD)}, // DEBUG_SDP_ERROR_BODY_FIELD - {use_str(DEBUG_UDP_OPEN_FAIL)}, // DEBUG_UDP_OPEN_FAIL - {use_str(DEBUG_UDP_PAYLOAD_TOO_LARGE)}, // DEBUG_UDP_PAYLOAD_TOO_LARGE - {use_str(DEBUG_RTP_TRANSPORT)}, // DEBUG_RTP_TRANSPORT - {use_str(DEBUG_RTP_INVALID_VOIP_TYPE)}, // DEBUG_RTP_INVALID_VOIP_TYPE - {use_str(DEBUG_RTP_INVALID_RTP_TYPE)}, // DEBUG_RTP_INVALID_RTP_TYPE - {use_str(DEBUG_MEMORY_ALLOC)}, // DEBUG_MEMORY_ALLOC - {use_str(DEBUG_MEMORY_FREE)}, // DEBUG_MEMORY_FREE - {use_str(DEBUG_MEMORY_MALLOC_ERROR)}, // DEBUG_MEMORY_MALLOC_ERROR - {use_str(DEBUG_MEMORY_REALLOC_ERROR)}, // DEBUG_MEMORY_REALLOC_ERROR - {use_str(DEBUG_MEMORY_OUT_OF_MEM)}, // DEBUG_MEMORY_OUT_OF_MEM - {use_str(DEBUG_MEMORY_ENTRY)}, // DEBUG_MEMORY_ENTRY - {use_str(DEBUG_MEMORY_SUMMARY)}, // DEBUG_MEMORY_SUMMARY - {use_str(DEBUG_MEMORY_ADDRESS_HEADER)}, // DEBUG_MEMORY_ADDRESS_HEADER - {use_str(DEBUG_MEMORY_DUMP)}, // DEBUG_MEMORY_DUMP - {use_str(DEBUG_DNS_GETHOSTBYNAME)}, // DEBUG_DNS_GETHOSTBYNAME - {use_str(DEBUG_PMH_INCORRECT_SYNTAX)}, // DEBUG_PMH_INCORRECT_SYNTAX - {use_str(DEBUG_PMH_INVALID_FIELD_VALUE)}, // DEBUG_PMH_INVALID_FIELD_VALUE - {use_str(DEBUG_PMH_INVALID_SCHEME)}, // DEBUG_PMH_INVALID_SCHEME - {use_str(DEBUG_PMH_UNKNOWN_SCHEME)}, // DEBUG_PMH_UNKNOWN_SCHEME - {use_str(DEBUG_PMH_NOT_ENOUGH_PARAMETERS)}, // DEBUG_PMH_NOT_ENOUGH_PARAMETERS - {use_str(DEBUG_REG_DISABLED)}, // DEBUG_REG_DISABLED - {use_str(DEBUG_REG_PROXY_EXPIRES)}, // DEBUG_REG_PROXY_EXPIRES - {use_str(DEBUG_REG_SIP_DATE)}, // DEBUG_REG_SIP_DATE - {use_str(DEBUG_REG_SIP_RESP_CODE)}, // DEBUG_REG_SIP_RESP_CODE - {use_str(DEBUG_REG_SIP_RESP_FAILURE)}, // DEBUG_REG_SIP_RESP_FAILURE - {use_str(DEBUG_REG_INVALID_LINE)}, // DEBUG_REG_INVALID_LINE - {use_str(CC_NO_MSG_BUFFER)}, // CC_NO_MSG_BUFFER^M - {use_str(CC_SEND_FAILURE)}, // CC_SEND_FAILURE^M - {use_str(GSM_UNDEFINED)}, // GSM_UNDEFINED - {use_str(GSM_DBG_PTR)}, // GSM_DBG_PTR - {use_str(GSM_FUNC_ENTER)}, // GSM_FUNC_ENTER - {use_str(GSM_DBG1)}, // GSM_DBG1 - {use_str(FSM_DBG_SM_DEFAULT_EVENT)}, // FSM_DBG_SM_DEFAULT_EVENT - {use_str(FSM_DBG_SM_FTR_ENTRY)}, // FSM_DBG_SM_FTR_ENTRY - {use_str(FSM_DBG_FAC_ERR)}, // FSM_DBG_FAC_ERR - {use_str(FSM_DBG_FAC_FOUND)}, // FSM_DBG_FAC_FOUND - {use_str(FSM_DBG_IGNORE_FTR)}, // FSM_DBG_IGNORE_FTR - {use_str(FSM_DBG_IGNORE_SRC)}, // FSM_DBG_IGNORE_SRC - {use_str(FSM_DBG_CHANGE_STATE)}, // FSM_DBG_CHANGE_STATE - {use_str(FSM_DBG_SDP_BUILD_ERR)}, // FSM_DBG_SDP_BUILD_ERR - {use_str(FSMDEF_DBG_PTR)}, // FSMDEF_DBG_PTR - {use_str(FSMDEF_DBG1)}, // FSMDEF_DBG1 - {use_str(FSMDEF_DBG2)}, // FSMDEF_DBG2 - {use_str(FSMDEF_DBG_SDP)}, // FSMDEF_DBG_SDP - {use_str(FSMDEF_DBG_CLR_SPOOF_APPLD)}, // FSMDEF_DBG_CLEAR_SPOOF - {use_str(FSMDEF_DBG_CLR_SPOOF_RQSTD)}, // FSMDEF_DBG_CLEAR_SPOOF - {use_str(FSMDEF_DBG_INVALID_DCB)}, // FSMDEF_DBG_INVALID_DCB - {use_str(FSMDEF_DBG_FTR_REQ_ACT)}, // FSMDEF_DBG_FTR_REQ_ACT - {use_str(FSMDEF_DBG_TMR_CREATE_FAILED)}, // FSMDEF_DBG_TMR_CREATE_FAILED - {use_str(FSMDEF_DBG_TMR_START_FAILED)}, // FSMDEF_DBG_TMR_START_FAILED - {use_str(FSMDEF_DBG_TMR_CANCEL_FAILED)}, // FSMDEF_DBG_TMR_CANCEL_FAILED - {use_str(FSMXFR_DBG_XFR_INITIATED)}, // FSMXFR_DBG_XFR_INITIATED - {use_str(FSMXFR_DBG_PTR)}, // FSMXFR_DBG_PTR - {use_str(FSMCNF_DBG_CNF_INITIATED)}, // FSMCNF_DBG_CNF_INITIATED - {use_str(FSMCNF_DBG_PTR)}, // FSMCNF_DBG_PTR - {use_str(FSMB2BCNF_DBG_CNF_INITIATED)}, // FSMB2BCNF_DBG_CNF_INITIATED - {use_str(FSMB2BCNF_DBG_PTR)}, // FSMB2BCNF_DBG_PTR - {use_str(FSMSHR_DBG_BARGE_INITIATED)}, // FSMSHR_DBG_BARGE_INITIATED - {use_str(LSM_DBG_ENTRY)}, // LSM_DBG_ENTRY - {use_str(LSM_DBG_INT1)}, // LSM_DBG_INT1 - {use_str(LSM_DBG_CC_ERROR)}, // LSM_DBG_CC_ERROR - {use_str(VCM_DEBUG_ENTRY)}, // VCM_DEBUG_ENTRY - {use_str(SM_PROCESS_EVENT_ERROR)}, // SM_PROCESS_EVENT_ERROR - {use_str(REG_SM_PROCESS_EVENT_ERROR)}, // REG_SM_PROCESS_EVENT_ERROR - {0}, -}; - - - -//************************************************************************ - -/* - * Phrase string table subject to localization - */ -tnp_phrase_index_str_table_entry tnp_phrase_index_str_table [] = { - {"\0"}, // LOCALE_START - {"\x80\x13"}, // IDLE_PROMPT sccp 119 - {"Anonymous"}, // ANONYMOUS - used for messaging; keep English - {"\x80\x1e"}, // CALL_PROCEEDING_IN - {"\x80\x1e"}, // CALL_PROCEEDING_OUT - {"\x80\x16"}, // CALL_ALERTING sccp 122 - {"\x80\x1b"}, // CALL_ALERTING_SECONDARY sccp 127 - {"\x80\x16"}, // CALL_ALERTING_LOCAL - {"\x80\x18"}, // CALL_CONNECTED sccp 124 - {"\x80\x03"}, // CALL_INITIATE_HOLD sccp 103 or phone 786? - {"\x80\x20"}, // PROMPT_DIAL sccp 132 - {"\x80\x19"}, // LINE_BUSY sccp 125 - {"\x80\x1b"}, // CALL_WAITING - {"\x80\x52"}, // TRANSFER_FAILED sccp 182 - {"\x80\x26"}, // Cannot complete the b2b conf - {"\x80\x34"}, // UI_CONFERENCE - {"\x80\x38"}, // UI_UNKNOWN - {"\x80\x1f"}, // REMOTE_IN_USE - {"\x80\x55"}, // NUM_NOT_CONFIGURED - {"\x80\x17"}, // UI_FROM - {"\x80\x29"}, // INVALID_CONF_PARTICIPANT - {"\x80\x36"}, // UI_PRIVATE - {"\0"} // LOCALE_END -}; diff --git a/libs/sipcc/core/common/text_strings.h b/libs/sipcc/core/common/text_strings.h deleted file mode 100755 index 0502a38e05..0000000000 --- a/libs/sipcc/core/common/text_strings.h +++ /dev/null @@ -1,302 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef TEXT_STRINGS_H -#define TEXT_STRINGS_H - -#include "cpr_types.h" -#include "phone_types.h" -#include "string_lib.h" - - -#define DEF_NOTIFY_PRI 20 -#define HR_NOTIFY_PRI 1 - -/* - * Define hard coded Anonymous string to be used in From header - * when call id blocking is enabled. This is also used to - * compare to when anonymous call block is enabled. We can - * can not use the localized version of Anonymous for these - * actions. - */ -#define SIP_HEADER_ANONYMOUS_STR "Anonymous" - -/* - * Define special strings that are not localized to be used for - * comparing special display names whether the names are special - * and not to display the number associated with the name. - */ -#define CONFERENCE_STR "conference" -#define CONFERENCE_STR_LEN (sizeof(CONFERENCE_STR)-1) -#define CONFERENCE_LOCALE_CODE 964 -/* - * Constants for dictionary index - */ - -// Hardcoding phrases that need to be dropped on floor for RT to 1 - -#define STR_INDEX_GRP_CALL_PICKUP 47 -#define STR_INDEX_LST_CALL_PICKUP 49 -#define STR_INDEX_FEAT_UNAVAIL 148 -#define STR_INDEX_CNFR_FAIL_NOCODEC 1054 -#define STR_INDEX_REORDER 1055 -#define STR_INDEX_ANONYMOUS_SPACE 1056 -#define STR_INDEX_NO_FREE_LINES 1057 -#define STR_INDEX_REGISTRATION_REJECTED 1058 -#define STR_INDEX_REGISTERING 1 -#define STR_INDEX_WHISPER 1 -#define STR_INDEX_PROXY_UNAVAIL 1 -#define STR_INDEX_CALL_REDIRECTED 1 -#define STR_INDEX_TRANSFERRING 1 -#define STR_INDEX_SESSION_PROGRESS 1 -#define STR_INDEX_CALLING 1 -#define STR_INDEX_USE_LINE_OR_JOIN_TO_COMPLETE 1 -#define STR_INDEX_CONF_LOCAL_MIXED 1 -#define STR_INDEX_NO_CALL_FOR_PICKUP 195 - -#define STR_INDEX_CALL_FORWARD 105 -#define STR_INDEX_CALL_PICKUP 117 -#define STR_INDEX_NO_LINE_FOR_PICKUP 198 - - -#define STR_INDEX_ERROR_PASS_LIMIT 149 -#define STR_INDEX_TRANS_COMPLETE 918 -#define STR_INDEX_END_CALL 877 -#define STR_INDEX_NO_BAND_WIDTH 1158 - -#define STR_INDEX_RESP_TIMEOUT 1160 - -#define CALL_BUBBLE_STR_MAX_LEN 32 - -#define STATUS_LINE_MAX_LEN 128 - -/* - * Escape codes definitions - */ -#define OLD_CUCM_DICTIONARY_ESCAPE_TAG '\x80' -#define NEW_CUCM_DICTIONARY_ESCAPE_TAG '\x1E' -#define CALL_CONTROL_PHRASE_OFFSET '\x64' // offset 100 -#define MAX_LOCALE_PHRASE_LEN 256 -#define MAX_LOCALE_STRING_LEN 1024 - -/* - * Escaped index string codes for Call Mgr dictionary phrases - */ -#define INDEX_STR_KEY_NOT_ACTIVE (char *) "\x80\x2D" -#define INDEX_STR_BARGE (char *) "\x80\x43" -#define INDEX_STR_PRIVATE (char *) "\x80\x36" -#define INDEX_STR_HOLD_REVERSION (char *) "\x1E\x23" -#define INDEX_STR_MONITORING (char *) "\x1E\x27" -#define INDEX_STR_COACHING (char *) "\x1E\x46" - - -/* - * Index value for phrase strings subject to localization - */ -enum PHRASE_STRINGS_ENUM { - LOCALE_START, - IDLE_PROMPT, - ANONYMOUS, /* fsmdef.o */ - CALL_PROCEEDING_IN, - CALL_PROCEEDING_OUT, - CALL_ALERTING, - CALL_ALERTING_SECONDARY, - CALL_ALERTING_LOCAL, - CALL_CONNECTED, - CALL_INITIATE_HOLD, - PROMPT_DIAL, - LINE_BUSY, - CALL_WAITING, - TRANSFER_FAILED, - CONF_CANNOT_COMPLETE, - UI_CONFERENCE, - UI_UNKNOWN, - REMOTE_IN_USE, - NUM_NOT_CONFIGURED, - UI_FROM, - INVALID_CONF_PARTICIPANT, - UI_PRIVATE, - LOCALE_END -}; - -/* - * Index value for Debug strings NOT subject to localization - */ -enum DEBUG_STRINGS_ENUM { - DEBUG_START, - DEBUG_SEPARATOR_BAR, - DEBUG_CONSOLE_PASSWORD, - DEBUG_CONSOLE_KEYWORD_CONSOLE_STALL, - DEBUG_CONSOLE_KEYWORD_MEMORYMAP, - DEBUG_CONSOLE_KEYWORD_MALLOCTABLE, - DEBUG_CONSOLE_KEYWORD_MEMORYDUMP, - DEBUG_CONSOLE_KEYWORD_DNS, - DEBUG_CONSOLE_KEYWORD_DSPSTATE, - DEBUG_CONSOLE_USAGE_MEMORYDUMP, - DEBUG_CONSOLE_BREAK, - - DEBUG_FUNCTION_ENTRY, - DEBUG_FUNCTION_ENTRY2, - DEBUG_SIP_ENTRY, - DEBUG_SIP_URL_ERROR, - DEBUG_LINE_NUMBER_INVALID, - DEBUG_SIP_SPI_SEND_ERROR, - DEBUG_SIP_SDP_CREATE_BUF_ERROR, - DEBUG_SIP_PARSE_SDP_ERROR, - DEBUG_SIP_FEATURE_UNSUPPORTED, - DEBUG_SIP_DEST_SDP, - DEBUG_SIP_MSG_SENDING_REQUEST, - DEBUG_SIP_MSG_SENDING_RESPONSE, - DEBUG_SIP_MSG_RECV, - DEBUG_SIP_STATE_UNCHANGED, - DEBUG_SIP_FUNCTIONCALL_FAILED, - DEBUG_SIP_BUILDFLAG_ERROR, - DEBUG_GENERAL_FUNCTIONCALL_FAILED, - DEBUG_GENERAL_SYSTEMCALL_FAILED, - DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT, - DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM, - DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO, - DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE, - - DEBUG_SNTP_LI_ERROR, - DEBUG_SNTP_MODE_ERROR, - DEBUG_SNTP_STRATUM_ERROR, - DEBUG_SNTP_TIMESTAMP_ERROR, - DEBUG_SNTP_TIMESTAMP1, - DEBUG_SNTP_TIMESTAMP2, - DEBUG_SNTP_TIME_UPDATE, - DEBUG_SNTP_TS_HEADER, - DEBUG_SNTP_TS_PRINT, - DEBUG_SNTP_SOCKET_REOPEN, - DEBUG_SNTP_DISABLED, - DEBUG_SNTP_REQUEST, - DEBUG_SNTP_RESPONSE, - DEBUG_SNTP_RETRANSMIT, - DEBUG_SNTP_UNICAST_MODE, - DEBUG_SNTP_MULTICAST_MODE, - DEBUG_SNTP_ANYCAST_MODE, - DEBUG_SNTP_VALIDATION, - DEBUG_SNTP_VALIDATION_PACKET, - DEBUG_SNTP_WRONG_SERVER, - DEBUG_SNTP_NO_REQUEST, - DEBUG_SNTP_ANYCAST_RESET, - DEBUG_SOCKET_UDP_RTP, - DEBUG_MAC_PRINT, - DEBUG_IP_PRINT, - DEBUG_SYSBUF_UNAVAILABLE, - DEBUG_MSG_BUFFER_TOO_BIG, - DEBUG_UNKNOWN_TIMER_BLOCK, - DEBUG_CREDENTIALS_BAG_CORRUPTED, - DEBUG_INPUT_EMPTY, - DEBUG_INPUT_NULL, - DEBUG_STRING_DUP_FAILED, - DEBUG_PARSER_STRING_TOO_LARGE, - DEBUG_PARSER_NULL_KEY_TABLE, - DEBUG_PARSER_UNKNOWN_KEY, - DEBUG_PARSER_UNKNOWN_KEY_ENUM, - DEBUG_PARSER_INVALID_START_VAR, - DEBUG_PARSER_INVALID_VAR_CHAR, - DEBUG_PARSER_MISSING_COLON, - DEBUG_PARSER_NO_VALUE, - DEBUG_PARSER_EARLY_EOL, - DEBUG_PARSER_INVALID_VAR_NAME, - DEBUG_PARSER_INVALID_VAR_VALUE, - DEBUG_PARSER_UNKNOWN_VAR, - DEBUG_PARSER_NAME_VALUE, - DEBUG_PARSER_UNKNOWN_NAME_VALUE, - DEBUG_PARSER_UNKNOWN_ERROR, - DEBUG_PARSER_NUM_ERRORS, - DEBUG_PARSER_SET_DEFAULT, - DEBUG_SDP_ERROR_BODY_FIELD, - DEBUG_UDP_OPEN_FAIL, - DEBUG_UDP_PAYLOAD_TOO_LARGE, - DEBUG_TCP_PAYLOAD_TOO_LARGE = DEBUG_UDP_PAYLOAD_TOO_LARGE, - DEBUG_RTP_TRANSPORT, - DEBUG_RTP_INVALID_VOIP_TYPE, - DEBUG_RTP_INVALID_RTP_TYPE, - DEBUG_MEMORY_ALLOC, - DEBUG_MEMORY_FREE, - DEBUG_MEMORY_MALLOC_ERROR, - DEBUG_MEMORY_REALLOC_ERROR, - DEBUG_MEMORY_OUT_OF_MEM, - DEBUG_MEMORY_ENTRY, - DEBUG_MEMORY_SUMMARY, - DEBUG_MEMORY_ADDRESS_HEADER, - DEBUG_MEMORY_DUMP, - DEBUG_DNS_GETHOSTBYNAME, - DEBUG_PMH_INCORRECT_SYNTAX, - DEBUG_PMH_INVALID_FIELD_VALUE, - DEBUG_PMH_INVALID_SCHEME, - DEBUG_PMH_UNKNOWN_SCHEME, - DEBUG_PMH_NOT_ENOUGH_PARAMETERS, - DEBUG_REG_DISABLED, - DEBUG_REG_PROXY_EXPIRES, - DEBUG_REG_SIP_DATE, - DEBUG_REG_SIP_RESP_CODE, - DEBUG_REG_SIP_RESP_FAILURE, - DEBUG_REG_INVALID_LINE, - CC_NO_MSG_BUFFER, - CC_SEND_FAILURE, - GSM_UNDEFINED, - GSM_DBG_PTR, - GSM_FUNC_ENTER, - GSM_DBG1, - FSM_DBG_SM_DEFAULT_EVENT, - FSM_DBG_SM_FTR_ENTRY, - FSM_DBG_FAC_ERR, - FSM_DBG_FAC_FOUND, - FSM_DBG_IGNORE_FTR, - FSM_DBG_IGNORE_SRC, - FSM_DBG_CHANGE_STATE, - FSM_DBG_SDP_BUILD_ERR, - FSMDEF_DBG_PTR, - FSMDEF_DBG1, - FSMDEF_DBG2, - FSMDEF_DBG_SDP, - FSMDEF_DBG_CLR_SPOOF_APPLD, - FSMDEF_DBG_CLR_SPOOF_RQSTD, - FSMDEF_DBG_INVALID_DCB, - FSMDEF_DBG_FTR_REQ_ACT, - FSMDEF_DBG_TMR_CREATE_FAILED, - FSMDEF_DBG_TMR_START_FAILED, - FSMDEF_DBG_TMR_CANCEL_FAILED, - FSMXFR_DBG_XFR_INITIATED, - FSMXFR_DBG_PTR, - FSMCNF_DBG_CNF_INITIATED, - FSMCNF_DBG_PTR, - FSMB2BCNF_DBG_CNF_INITIATED, - FSMB2BCNF_DBG_PTR, - FSMSHR_DBG_BARGE_INITIATED, - LSM_DBG_ENTRY, - LSM_DBG_INT1, - LSM_DBG_CC_ERROR, - VCM_DEBUG_ENTRY, - SM_PROCESS_EVENT_ERROR, - REG_SM_PROCESS_EVENT_ERROR, - DEBUG_END -}; - - -typedef struct { - const char *text; -} debug_string_table_entry; - -extern debug_string_table_entry debug_string_table[]; - -#define get_debug_string(index) ((char*)debug_string_table[(index)].text) - - - -typedef struct { - const char *index_str; -} tnp_phrase_index_str_table_entry; - - -extern tnp_phrase_index_str_table_entry tnp_phrase_index_str_table[]; - -#define platform_get_phrase_index_str(index) ((char*)tnp_phrase_index_str_table[(index)].index_str) -#define get_info_string(index) "NotImplemented" - - -#endif diff --git a/libs/sipcc/core/common/ui.c b/libs/sipcc/core/common/ui.c deleted file mode 100755 index 750a43539d..0000000000 --- a/libs/sipcc/core/common/ui.c +++ /dev/null @@ -1,1666 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** @file tnp_ui.c - * API provided by Platform to the Call Control for User Interface activities - */ - -#include "cpr.h" -#include "cpr_in.h" -#include "phone.h" -#include "time2.h" -#include "debug.h" -#include "phone_debug.h" -#include "dialplan.h" -#include "ccapi.h" -#include "cfgfile_utils.h" -#include "prot_configmgr.h" -#include "dns_utils.h" -#include "uiapi.h" -#include "lsm.h" -#include "fsm.h" -#include "CCProvider.h" -#include "ccSession.h" -#include "platform_api.h" -#include "vcm.h" -#include "ccapp_task.h" - -/* - * Note: Do not include "msprovider.h" here unless the dependencies on - * /vob/ip_phone/ip_g4/infra have been removed, as those dependencies - * break CSF builds. - */ - -/*-------------------------------------------------------------------------- - * Local definitions - *-------------------------------------------------------------------------- - */ -#define CCAPP_F_PREFIX "CCAPP : %s : " // requires 1 arg: __FUNCTION__ -// Why don't we modify strlib_malloc to handle NULL? -#define STRLIB_CREATE(str) (str)?strlib_malloc((str), strlen((str))):strlib_empty() -// Define default display timeout and priority -#define DEFAULT_DISPLAY_NOTIFY_TIMEOUT 0 -#define DEFAULT_DISPLAY_NOTIFY_PRIORITY 0 - - -/*-------------------------------------------------------------------------- - * Global data - *-------------------------------------------------------------------------- - */ - -/*-------------------------------------------------------------------------- - * External data references - * ------------------------------------------------------------------------- - */ - - -/*-------------------------------------------------------------------------- - * External function prototypes - *-------------------------------------------------------------------------- - */ - -extern int Basic_Get_Line_By_Name(char *name); -extern char *Basic_is_phone_forwarded(line_t line); -extern void dp_int_dial_immediate(line_t line, callid_t call_id, - boolean collect_more, char *digit_str, - char *g_call_id, - monitor_mode_t monitor_mode); -extern void dp_int_init_dialing_data(line_t line, callid_t call_id); -extern callid_t dp_get_dialing_call_id(void); -extern void dp_int_update_key_string(line_t line, callid_t call_id, - char *digits); -extern void platform_set_time(int32_t gmt_time); -extern session_id_t createSessionId(line_t line, callid_t call); -// XXX need to either make msprovider.h platform-independent and include that file instead, -// or move ui_keypad_button out of this file (ccmedia.c, perhaps?) - -/*-------------------------------------------------------------------------- - * Local scope function prototypes - *-------------------------------------------------------------------------- - */ - -/** - * wrapper to post Call State change to CCAPP - * - * @param event - new state change event - * @param nLine - line identifier for which call state change - * @param nCallID - call identifier - * - * - * @return none (Side effect: Call bubble changes accordingly) - * - */ -void -ui_call_state (call_events event, line_t nLine, callid_t nCallID, cc_causes_t cause) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"event=%d \n", DEB_L_C_F_PREFIX_ARGS(UI_API, nLine, nCallID, __FUNCTION__), - event); - - if (nCallID == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(nLine, nCallID); - msg.eventID = CALL_STATE; - msg.update.ccSessionUpd.data.state_data.state = event; - msg.update.ccSessionUpd.data.state_data.line_id = nLine; - msg.update.ccSessionUpd.data.state_data.cause = cause; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE(%d) msg \n", __FUNCTION__, event); - } -} - -/** - * wrapper to post presentation for new call to CCAPP - * Function: ui_new_call - * - * @param nLine line identifier - * @param nCallID - call identifier - * @param call_attr - call attribute(normal, transfer consult, conf consult) - * @param call_instance_id - call instance identifier - * - * @return none - */ -void -ui_new_call (call_events event, line_t nLine, callid_t nCallID, - int call_attr, uint16_t call_instance_id, boolean dialed_digits) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"state=%d attr=%d call_instance=%d, dialed_digits=%s\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, nLine, nCallID, __FUNCTION__), event, call_attr, call_instance_id, (dialed_digits)? "true" : "false"); - - if (nCallID == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID= createSessionId(nLine, nCallID); - - msg.eventID = CALL_NEWCALL; - msg.update.ccSessionUpd.data.state_data.state = event; - msg.update.ccSessionUpd.data.state_data.attr = call_attr; - msg.update.ccSessionUpd.data.state_data.inst = call_instance_id; - msg.update.ccSessionUpd.data.state_data.line_id = nLine; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE(%d) msg \n", __FUNCTION__, event); - } - - return; -} - -/** - * set or change the attribute on the call and reflect the changes - * to call plane (such as change in softkeys or other visual aspects). - * used to change the call attribute back to normal from consult - * - * Posts the update to CCAPP - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param attr - call attribute has to be one of call_attr_t - * - * @return none - */ -void -ui_set_call_attr (line_t line_id, callid_t call_id, call_attr_t attr) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"attr=%d\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__), attr); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_ATTR; - msg.update.ccSessionUpd.data.state_data.attr = attr; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_ATTR(%d) msg \n", __FUNCTION__, attr); - } -} - -/** - * Wrapper for ui_update_callref - * - * @param line - line for the session - * @param call_id - callid for the session - * @param callref - callref for the session - * - * @return none - */ -void -ui_update_callref (line_t line, callid_t call_id, unsigned int callref) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"callref = %d\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), callref); - - if ( callref == 0 ) return; - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_CALLREF; - msg.update.ccSessionUpd.data.callref = callref; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_REF() msg \n", __FUNCTION__); - } - - return; -} - - -/** - * Wrapper for ui_update_gcid - global_call_id - * - * @param line - line for the session - * @param call_id - callid for the session - * @param gcid - Global CallId for the session - * - * @return none - */ -void -ui_update_gcid (line_t line, callid_t call_id, char *gcid) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"gcid = %s\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), gcid); - - if ( *gcid == '\0' ) return; - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_GCID; - sstrncpy(msg.update.ccSessionUpd.data.gcid, gcid, CC_MAX_GCID); - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_GCID() msg \n", __FUNCTION__); - } - - return; -} - -/** - * Wrapper for ui_update_video_avail - * indicates video stream is avail for this session to UI - * @param line - line for the session - * @param call_id - callid for the session - * - * @return none - */ -void -ui_update_video_avail (line_t line, callid_t call_id, int avail) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = VIDEO_AVAIL; - msg.update.ccSessionUpd.data.action = avail; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send VIDEO_AVAIL() msg \n", __FUNCTION__); - } - - return; -} - -void ui_update_media_interface_change(line_t line, callid_t call_id, group_call_event_t event) { - session_update_t msg; - - if (event != MEDIA_INTERFACE_UPDATE_BEGIN && - event != MEDIA_INTERFACE_UPDATE_SUCCESSFUL && - event != MEDIA_INTERFACE_UPDATE_FAIL) { - // un-related event. ignore. - return; - } - - if (event != MEDIA_INTERFACE_UPDATE_BEGIN) { - /* we are sending final result */ - g_dock_undock_event = MEDIA_INTERFACE_UPDATE_NOT_REQUIRED; - } - - DEF_DEBUG(DEB_L_C_F_PREFIX "event=%s", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - event == MEDIA_INTERFACE_UPDATE_BEGIN ? "MEDIA_INTERFACE_UPDATE_BEGIN" : - event == MEDIA_INTERFACE_UPDATE_SUCCESSFUL ? "MEDIA_INTERFACE_UPDATE_SUCCESSFUL" : - event == MEDIA_INTERFACE_UPDATE_FAIL ? "MEDIA_INTERFACE_UPDATE_FAIL" : "unknown"); - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - msg.sessionID = createSessionId(line, call_id); - msg.eventID = event; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send media update () msg \n", __FUNCTION__); - } -} - -void -ui_call_stop_ringer (line_t line, callid_t call_id) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = RINGER_STATE; - msg.update.ccSessionUpd.data.ringer.start = FALSE; - msg.update.ccSessionUpd.data.ringer.mode = VCM_RING_OFF; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send RINGER_STATE() msg \n", __FUNCTION__); - } - - return; -} - -void -ui_call_start_ringer (vcm_ring_mode_t ringMode, short once, line_t line, callid_t call_id) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = RINGER_STATE; - msg.update.ccSessionUpd.data.ringer.start = TRUE; - msg.update.ccSessionUpd.data.ringer.mode = ringMode; - msg.update.ccSessionUpd.data.ringer.once = (cc_boolean) once; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send RINGER_STATE() msg \n", __FUNCTION__); - } - - return; -} - -/** - * Wrapper for ui_update_video_avail - * indicates video stream is avail for this session to UI - * @param line - line for the session - * @param call_id - callid for the session - * - * @return none - */ -void -ui_update_video_offered (line_t line, callid_t call_id, int avail) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = VIDEO_OFFERED; - msg.update.ccSessionUpd.data.action = avail; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send VIDEO_OFFERED() msg \n", __FUNCTION__); - } - - return; -} - - -/** - * Wrapper for ui call info post to CCAPP - * call bubble with appropriate party information - * - * @param pCallingPartyNameStr/NumberStr - Calling party information - * @param displayCallingNumber - * @param pCalledPartyNameStr/NumberStr - called party information - * @param displayCalledNumber - * @param pOrigCalledNameStr/NumberStr - * @param pLastRedirectingNameStr/NumberStr - * @param call_type - * @param line - line identifier - * @param call_id - call identifier - * @param call_instance_id - call instance displayed in call bubble - * @param cc_security - * - * @return none - */ -void -ui_call_info (string_t pCallingPartyNameStr, - string_t pCallingPartyNumberStr, - string_t pAltCallingPartyNumberStr, - boolean displayCallingNumber, - string_t pCalledPartyNameStr, - string_t pCalledPartyNumberStr, - boolean displayCalledNumber, - string_t pOrigCalledNameStr, - string_t pOrigCalledNumberStr, - string_t pLastRedirectingNameStr, - string_t pLastRedirectingNumberStr, - calltype_t call_type, - line_t line, - callid_t call_id, - uint16_t call_instance_id, - cc_security_e call_security, - cc_policy_e call_policy) -{ - session_update_t msg; - const char *uiCalledName; - const char *uiCalledNumber; - const char *uiCallingName; - const char *uiCallingNumber; - int inbound; - char lineName[MAX_LINE_NAME_SIZE]; - char lineNumber[MAX_LINE_NAME_SIZE]; - - - TNP_DEBUG(DEB_L_C_F_PREFIX"call instance=%d callednum=%s calledname=%s clngnum=%s clngname = %s\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), call_instance_id, pCalledPartyNumberStr, - pCalledPartyNameStr, pCallingPartyNumberStr, pCallingPartyNameStr); - - TNP_DEBUG(DEB_F_PREFIX"calltype=%d displayClng=%d displayCld=%d\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), call_type, - displayCallingNumber, displayCalledNumber); - - - inbound = (call_type == FSMDEF_CALL_TYPE_INCOMING) || (call_type == FSMDEF_CALL_TYPE_FORWARD); - uiCalledNumber = pCalledPartyNumberStr; - uiCalledName = pCalledPartyNameStr; - uiCallingNumber = pCallingPartyNumberStr; - uiCallingName = pCallingPartyNameStr; - - config_get_line_string(CFGID_LINE_DISPLAYNAME, lineName, line, sizeof(lineName)); - config_get_line_string(CFGID_LINE_NAME, lineNumber, line, sizeof(lineNumber)); - - if (inbound) { - uiCalledNumber = lineNumber; - uiCalledName = lineName; - } else { - uiCallingNumber = lineNumber; - uiCallingName = lineName; - } - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_INFORMATION; - msg.update.ccSessionUpd.data.call_info.clgName = uiCallingName?strlib_malloc(uiCallingName, strlen(uiCallingName)):strlib_empty(); - - if ( uiCallingNumber== NULL || (inbound && !displayCallingNumber)) { - msg.update.ccSessionUpd.data.call_info.clgNumber = strlib_empty(); - } else { - msg.update.ccSessionUpd.data.call_info.clgNumber = strlib_malloc(uiCallingNumber, strlen(uiCallingNumber)); - } - - if ( pAltCallingPartyNumberStr == NULL || (inbound && !displayCallingNumber)) { - msg.update.ccSessionUpd.data.call_info.altClgNumber = strlib_empty(); - } else { - msg.update.ccSessionUpd.data.call_info.altClgNumber = strlib_malloc(pAltCallingPartyNumberStr,strlen(pAltCallingPartyNumberStr)); - } - - msg.update.ccSessionUpd.data.call_info.cldName = uiCalledName?strlib_malloc(uiCalledName,strlen(uiCalledName)):strlib_empty(); - - if (uiCalledNumber == NULL || (!inbound && !displayCalledNumber)) { - msg.update.ccSessionUpd.data.call_info.cldNumber = strlib_empty(); - } else { - msg.update.ccSessionUpd.data.call_info.cldNumber = strlib_malloc(uiCalledNumber,strlen(uiCalledNumber)); - } - msg.update.ccSessionUpd.data.call_info.origCalledName = pOrigCalledNameStr?strlib_malloc(pOrigCalledNameStr, strlen(pOrigCalledNameStr)):strlib_empty(); - msg.update.ccSessionUpd.data.call_info.origCalledNumber = pOrigCalledNumberStr?strlib_malloc(pOrigCalledNumberStr,strlen(pOrigCalledNumberStr)):strlib_empty(); - msg.update.ccSessionUpd.data.call_info.lastRedirectingName = pLastRedirectingNameStr?strlib_malloc(pLastRedirectingNameStr,strlen(pLastRedirectingNameStr)):strlib_empty(); - msg.update.ccSessionUpd.data.call_info.lastRedirectingNumber = pLastRedirectingNumberStr?strlib_malloc(pLastRedirectingNumberStr, strlen(pLastRedirectingNumberStr)):strlib_empty(); - msg.update.ccSessionUpd.data.call_info.call_type = call_type; - msg.update.ccSessionUpd.data.call_info.instance_id = call_instance_id; - msg.update.ccSessionUpd.data.call_info.security = call_security; - msg.update.ccSessionUpd.data.call_info.policy = call_policy; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_INFO() msg \n", __FUNCTION__); - } - - return; -} - -/** - * Wrapper for ui cc capability post to CCAPP - * - * @param line - line identifier - * @param callID - call identifier - * @param capability - cc capability - * - * @return none - */ -void -ui_cc_capability (line_t line, callid_t call_id, string_t recv_info_list) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"recv_info_list:%s\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - recv_info_list); - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_RECV_INFO_LIST; - msg.update.ccSessionUpd.data.recv_info_list = strlib_copy(recv_info_list); - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_RECV_INFO_LIST msg \n", __FUNCTION__); - } -} - -/** - * Wrapper for ui info received post to CCAPP - * - * @param line - line identifier - * @param callID - call identifier - * @param info_package - the Info-Package header of the Info Package - * @param content_type - the Content-Type header of the Info Package - * @param message_body - the message body of the Info Package - * - * @return none - */ -void -ui_info_received (line_t line, callid_t call_id, const char *info_package, - const char *content_type, const char *message_body) -{ - session_rcvd_info_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"info_package:%s content_type:%s message_body:%s\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - info_package, content_type, message_body); - - msg.sessionID = createSessionId(line, call_id); - msg.packageID = INFO_PKG_ID_GENERIC_RAW; - msg.info.generic_raw.info_package = info_package?strlib_malloc(info_package, strlen(info_package)):strlib_empty(); - msg.info.generic_raw.content_type = content_type?strlib_malloc(content_type, strlen(content_type)):strlib_empty(); - msg.info.generic_raw.message_body = message_body?strlib_malloc(message_body, strlen(message_body)):strlib_empty(); - - if ( ccappTaskPostMsg(CCAPP_RCVD_INFO, &msg, sizeof(session_rcvd_info_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_INFO_RECEIVED msg \n", __FUNCTION__); - } -} - - -/** - * An internal wrapper for ui call status post to CCAPP - * - * @param pString - status string - * @param line - line identifier - * @param callID - call identifier - * @param timeout - timeout for the status line - * - * @return none - */ -static void -ui_set_call_status_display (string_t status, line_t line, callid_t callID, int timeout, char priority) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"the stat string =%s, timeout= %d, priority=%d\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line, callID, __FUNCTION__), - status, - timeout, - priority); - - if (callID == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line, callID); - msg.eventID = CALL_STATUS; - msg.update.ccSessionUpd.data.status.timeout = timeout; - msg.update.ccSessionUpd.data.status.priority = priority; - if ( status ) { - msg.update.ccSessionUpd.data.status.status = strlib_malloc(status, strlen(status)); - } else { - msg.update.ccSessionUpd.data.status.status = strlib_empty(); - } - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATUS(%s) msg \n", __FUNCTION__, status); - } -} - - -/** - * Wrapper for ui call status post to CCAPP - * - * @param pString - status string - * @param line - line identifier - * @param callID - call identifier - * @param timeout - timeout for the status line - * - * @return none - */ -void -ui_set_call_status (string_t status, line_t line, callid_t callID) -{ - - TNP_DEBUG(DEB_L_C_F_PREFIX"the stat string =%s\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line, callID, __FUNCTION__), - status); - - if (callID == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - ui_set_call_status_display(status, line, callID, DEFAULT_DISPLAY_NOTIFY_TIMEOUT, DEFAULT_DISPLAY_NOTIFY_PRIORITY); -} - - -/** - * Wrapper for sending notification CCAPP - * - * @param promptString - notification string - * @param timeout - timeout of this notify - * @param notifyProgress- the type of notification - * TRUE - Progress, FALSE- Normal - * @param priority - priority of this notification - * Pri 1..5 Low .. High - * - * @return none - */ -void -ui_set_notification (line_t line, callid_t call_id, char *promptString, int timeout, - boolean notifyProgress, char priority) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d callid=%d str=%s tout=%d notifyProgress=%d pri=%d\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - line, call_id, promptString, timeout, notifyProgress, priority); - - if (line > 0 && call_id > 0) { - ui_set_call_status_display(promptString, line, call_id, timeout, priority); - return; - } - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_NOTIFICATION; - msg.update.ccFeatUpd.data.notification.timeout = timeout; - msg.update.ccFeatUpd.data.notification.notifyProgress = notifyProgress; - msg.update.ccFeatUpd.data.notification.priority = priority; - if ( promptString != NULL ) { - msg.update.ccFeatUpd.data.notification.prompt = strlib_malloc(promptString, strlen(promptString)); - } else { - msg.update.ccFeatUpd.data.notification.prompt = strlib_empty(); - } - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_NOTIFICATION(%s) msg \n", __FUNCTION__, promptString); - } -} - -/** - * CCAPPPost to clear the previous notify of given priority - * - * @param priority - notification of the given pri - * - * @return none - */ -/* TBD: the API should have priority param */ -void -ui_clear_notification () -{ - TNP_DEBUG(DEB_F_PREFIX"called..\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__)); - - // A promptString of NULL shall act as a clear - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, NULL, 0, FALSE, 1); -} - -/** - * - * CCAPP Post to set the MWI lamp indication of the device - * - * @param 1 - on or else off - * - * @return none - */ -void -ui_change_mwi_lamp (int status) -{ - feature_update_t msg; - - - TNP_DEBUG(DEB_F_PREFIX"status=%d \n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), status); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_MWILAMP; - msg.update.ccFeatUpd.data.state_data.state = status; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_MWILAMP(%d) msg \n", __FUNCTION__, status); - } -} - -/** - * - * CCAPP post to set the MWI lamp indication for given line - * - * @param line - line identifier - * @param on - TRUE -> on, otherwise off - * - * @return none - */ -void -ui_set_mwi (line_t line, boolean status, int type, int newCount, int oldCount, int hpNewCount, int hpOldCount) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d count=%d \n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), line, status); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_MWI; - msg.update.ccFeatUpd.data.mwi_status.line = line; - msg.update.ccFeatUpd.data.mwi_status.status = status; - msg.update.ccFeatUpd.data.mwi_status.type = type; - msg.update.ccFeatUpd.data.mwi_status.newCount = newCount; - msg.update.ccFeatUpd.data.mwi_status.oldCount = oldCount; - msg.update.ccFeatUpd.data.mwi_status.hpNewCount = hpNewCount; - msg.update.ccFeatUpd.data.mwi_status.hpOldCount = hpOldCount; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_MWI(%d,%d) msg \n", __FUNCTION__, line, status); - } -} - -/* - * Function: ui_mnc_reached - * - * @param line - line number - * @param boolean - maximum number of calls reached on this line - * - * Description: - * post mnc_reached status to CCAPP - * - * @return none - * - */ -void ui_mnc_reached (line_t line, boolean mnc_reached) -{ - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"line %d: Max number of calls reached =%d \n", - DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - line, mnc_reached); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_MNC_REACHED; - msg.update.ccFeatUpd.data.line_info.line = line; - msg.update.ccFeatUpd.data.line_info.info = mnc_reached; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_MNC_REACHED(%d,%d) msg \n", __FUNCTION__, - line, mnc_reached); - } - -} - -/** - * - * Check if MWI is active on a given line - * - * @param line - line identifier - * - * @return true if active; false otherwise. - */ -boolean -ui_line_has_mwi_active (line_t line) -{ - session_mgmt_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), line); - - msg.func_id = SESSION_MGMT_LINE_HAS_MWI_ACTIVE; - msg.data.line_mwi_active.line = line; - - ccappSyncSessionMgmt(&msg); - - return msg.data.line_mwi_active.ret_val; -} - - -/** - * CCAPP msg post to Set linekey values - * - * @param line - line identifier - * @param SpeedDial - Speeddial string to be changed - * @param label - Feature lable to be changed - * - * @return none - */ -void -ui_update_label_n_speeddial (line_t line, line_t button_no, string_t speed_dial, string_t label) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d speeddial=%s displayname=%s\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), line, - speed_dial, label); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_LABEL_N_SPEED; - msg.update.ccFeatUpd.data.cfg_lbl_n_spd.line = line; - msg.update.ccFeatUpd.data.cfg_lbl_n_spd.button = (unsigned char) button_no; - msg.update.ccFeatUpd.data.cfg_lbl_n_spd.speed = strlib_malloc(speed_dial, sizeof(speed_dial)); - msg.update.ccFeatUpd.data.cfg_lbl_n_spd.label = strlib_malloc(label, sizeof(label)); - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_LABEL_N_SPEED(%d) msg \n", __FUNCTION__, button_no); - } -} - -/** - * Inform CCAPP of registration state of given line in Line Plane - * - * @param line - line identifier - * @param registered - whether the line was registered or not - * - * @return none - */ -void -ui_set_sip_registration_state (line_t line, boolean registered) -{ - feature_update_t msg; - int value; - - TNP_DEBUG(DEB_F_PREFIX"%s %d: %s\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - (line==CC_ALL_LINES) ? "ALL LINES":"LINE" ,line, - (registered)? "REGISTERED":"UN-REGISTERED"); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_REG_STATE; - msg.update.ccFeatUpd.data.line_info.line = line; - msg.update.ccFeatUpd.data.line_info.info = registered ? CC_REGISTERED : CC_UNREGISTERED; - config_get_value(CFGID_PROXY_REGISTER, &value, sizeof(value)); - if (value == 0) { - msg.update.ccFeatUpd.data.line_info.info = CC_REGISTERED; - } - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE(%d, %d) msg \n", __FUNCTION__, line, registered); - } -} - -/** - * Inform CCAPP of registration state of given line in Line Plane - * - * @param registered - line registered true/false - * - * @return none - */ -void -ui_update_registration_state_all_lines (boolean registered) -{ - DEF_DEBUG(DEB_F_PREFIX"***********ALL LINES %s****************\n", - DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - (registered)? "REGISTERED":"UN-REGISTERED"); - - ui_set_sip_registration_state(CC_ALL_LINES, registered); - -} - -/** - * Inform the CCAPP that all registration attempts with - * all call controls have failed. - * - * @param none - * - * @return none - */ -void -ui_reg_all_failed (void) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"***********Registration to all CUCMs failed.***********\n", - DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__)); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = CCAPP_REG_ALL_FAIL; - msg.update.ccFeatUpd.data.line_info.line = CC_ALL_LINES; - msg.update.ccFeatUpd.data.line_info.info = FALSE; - - if ( ccappTaskPostMsg(CCAPP_REG_ALL_FAIL, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE() msg \n", __FUNCTION__); - } -} - -/** - * - * inform CCAPP about the status of the CCMs - * - * @param ccm_addr - IP address string - * @param status - status (notconnected, active, standby, notavail) - * - * @return none - */ -void -ui_set_ccm_conn_status (char * ccm_addr, int status) -{ - feature_update_t msg; - - DEF_DEBUG(DEB_F_PREFIX"***********CUCM %s %s***********\n", - DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), ccm_addr, - ((status == 0) ?"Not connected":((status == 1)?"STAND BY": - ((status == 2)?"ACTIVE":"UNKNOWN")))); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_CCM_CONN_STATUS; - msg.update.ccFeatUpd.data.ccm_conn.addr = ccm_addr?strlib_malloc(ccm_addr, strlen(ccm_addr)):strlib_empty(); - msg.update.ccFeatUpd.data.ccm_conn.status = status; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_CCM_CONN_STATUS(%d) msg \n", __FUNCTION__, status); - } -} - -/** - * Treat given line and callid as being put on hold by user. - * - * @param line - line identifier - * @param call_id - call identifier - * - * @return none - */ -void -ui_set_local_hold (line_t line, callid_t call_id) -{ - /* THIS IS A NOP FOR TNP */ - TNP_DEBUG(DEB_L_C_F_PREFIX"called\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, "ui_set_local_hold")); - return; -} - -/** - * Sets the call forward status as a flashing arrow and status line - * accordingly. - * - * @param line - line identifier - * @param cfa - call forward all true/false - * @param cfa_number - string representing call forwarded to number - * - * @return none - */ -void -ui_cfwd_status (line_t line, boolean cfa, char *cfa_number, boolean lcl_fwd) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"line=%d cfa=%d cfa_number=%s lcl_fwd=%d", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), - line, cfa, cfa_number, lcl_fwd); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_CFWD; - msg.update.ccFeatUpd.data.cfwd.line = line; - msg.update.ccFeatUpd.data.cfwd.isFwd = cfa; - msg.update.ccFeatUpd.data.cfwd.isLocal = lcl_fwd; - msg.update.ccFeatUpd.data.cfwd.cfa_num = cfa_number?strlib_malloc(cfa_number, strlen(cfa_number)):strlib_empty(); - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_CFWD(%d) msg \n", __FUNCTION__, cfa); - } -} - -/** - * Get the Idle prompt string. - * - * @return the idle prompt phrase from locale - */ -char * -ui_get_idle_prompt_string (void) -{ - TNP_DEBUG(DEB_F_PREFIX"called\n", DEB_F_PREFIX_ARGS(UI_API, "ui_get_idle_prompt_string")); - return platform_get_phrase_index_str(IDLE_PROMPT); -} - -/** - * Set the Appropriate Idle prompt string. - * - * @param pString - New Idle Prompt String - * @param prompt - The Idle Prompt To Be Modified - * - * @return the idle prompt phrase from locale - */ -void -ui_set_idle_prompt_string (string_t pString, int prompt) -{ - TNP_DEBUG(DEB_F_PREFIX"Prompt=%d, Prompt string=%s NOP operation\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), prompt, pString); -} - -/** - * Updates placed call information for call history - * - * @param line - line identifier - * @param call_id - call identifier - * @param cldName - called name - * @param cldNumber - called number - * - * @return none - */ -void -ui_update_placed_call_info (line_t line, callid_t call_id, string_t cldName, - string_t cldNumber) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"calledName:calledNumber %s:%s\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), cldName, cldNumber); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - TNP_DEBUG(DEB_F_PREFIX"invalid callid\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__)); - return; - } - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_PLACED_INFO; - msg.update.ccSessionUpd.data.plcd_info.cldName = strlib_empty(); - msg.update.ccSessionUpd.data.plcd_info.cldNum = strlib_empty(); - - if ( cldName) { - msg.update.ccSessionUpd.data.plcd_info.cldName = strlib_update( - msg.update.ccSessionUpd.data.plcd_info.cldName, cldName); - } - if ( cldNumber) { - msg.update.ccSessionUpd.data.plcd_info.cldNum = strlib_update( - msg.update.ccSessionUpd.data.plcd_info.cldNum, cldNumber); - } - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_PLACED_INFO(%s) msg \n", __FUNCTION__, cldNumber); - } -} - - -/** - * Description: remove last digit from input box - * - * @param line - line identifier - * @param call_id - call identifier - * - * @return none - */ -void -ui_delete_last_digit (line_t line_id, callid_t call_id) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"called\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_DELETE_LAST_DIGIT; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_DELETE_LAST_DIGIT() msg \n", __FUNCTION__); - } -} - -/** - * Keep/Remove BackSpace key if presented - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param enable - TRUE -> enable backspace softkey - * - * @return none - */ -void -ui_control_featurekey_bksp (line_t line_id, callid_t call_id, boolean enable) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"enable=%d\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__), - enable); - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_ENABLE_BKSP; - msg.update.ccSessionUpd.data.action = enable; - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_ENABLE_BKSP(%d) msg \n", __FUNCTION__, enable); - } -} - - -/** - * Select(lock-down) the call specified. - * For tnp this visually places a check box on the bubble. - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param selected - TRUE -> call is locked-down in signaling, - * mark as such on UI - * - * @return none - */ -void -ui_call_selected (line_t line_id, callid_t call_id, int selected) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"selected=%d\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__), selected); - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_SELECTED; - msg.update.ccSessionUpd.data.action = selected; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_SELECTED(%d) msg \n", __FUNCTION__, selected); - } -} - -/** - * Send the BLF state to the UI apps. - * - * @param[in] state - TRUE/FALSE - * - * @return none - */ -void ui_BLF_notification (int request_id, cc_blf_state_t blf_state, int app_id) -{ - feature_update_t msg; - - TNP_DEBUG(DEB_F_PREFIX"state=%d app_id=%d\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), blf_state, app_id); - - msg.sessionType = SESSIONTYPE_CALLCONTROL; - msg.featureID = DEVICE_FEATURE_BLF; - msg.update.ccFeatUpd.data.blf_data.state = blf_state; - msg.update.ccFeatUpd.data.blf_data.request_id = request_id; - msg.update.ccFeatUpd.data.blf_data.app_id = app_id; - - if ( ccappTaskPostMsg(CCAPP_FEATURE_UPDATE, &msg, sizeof(feature_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send DEVICE_FEATURE_BLF(state=%d, app_id=%d) msg \n", - __FUNCTION__, blf_state, app_id); - } -} - -/** - * - * Change the softkey set to preservation key set (with just the EndCall key) - * From the platform perspective, this is strictly a softkey set change - * operation. There is no underlying state change in the call or its status. - * In other words, after this invocation, the clients can still issue - * ui_call_state() or any other call operation if they deem fit and - * the softkey set will adhere to that state. - * - * @param line_id - line identifier - * @param call_id - call identifier - * - * @return none - */ -void -ui_call_in_preservation (line_t line_id, callid_t call_id) -{ - TNP_DEBUG(DEB_L_C_F_PREFIX"called\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__)); - - /* simply update the state . A Preservation event from - CUCM is just for the session */ - ui_call_state (evCallPreservation , line_id, call_id, CC_CAUSE_NORMAL); -} - -/** - * request ui to present a named softkey set for given call. - * The softkey set passed(set_name param) must be known to the platform. - * enable_mask is a set of bits (starting from LSB) one for each softkey. - * (so least significant bit represents left most softkey and so on). - * This function is typically used to mask certain softkeys in a given set. - * Use of this API as general purpose mechanism to present softkeys is - * discouraged because it breaks encapsulation. This API is introduced - * for the tough cases where adapter can not determine which keys to - * mask based on its state alone. - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param set_name - name of the softkey set - * @param sk_mask_list - the softkey events that need to be masked - * @param len - length of the softkey list array - * - * @return none - */ -void -ui_select_feature_key_set (line_t line_id, callid_t call_id, char *set_name, - int sk_mask_list[], int len) -{ - int i; - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"called\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line_id, call_id, __FUNCTION__)); - - if (call_id == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - if (len <= 0 || len > MAX_SOFT_KEYS) { - TNP_DEBUG(DEB_F_PREFIX"Incorrect softkey array length passed in : %d\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), len); - return; - } - - memset( &msg, 0, sizeof(session_update_t)); - - msg.sessionID = createSessionId(line_id, call_id); - msg.eventID = CALL_SELECT_FEATURE_SET; - - if ( set_name == NULL ) { - // No point continuing here - return; - } - - msg.update.ccSessionUpd.data.feat_set.featSet = set_name?strlib_malloc(set_name, sizeof(set_name)):strlib_empty(); - for (i = 0; i < len; i++) { - msg.update.ccSessionUpd.data.feat_set.featMask[i] = sk_mask_list[i]; - } - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_SELECT_FEATURE_SET() msg \n", __FUNCTION__); - } -} - - -/* Test Interface Operations */ - -/** - * Inject a simulated keypress into the Java Infrastructure - * - * @param uri - string - * - * @return none - */ -void -ui_execute_uri (char *uri) -{ - session_mgmt_t msg; - - TNP_DEBUG(DEB_F_PREFIX"uri=%s\n", DEB_F_PREFIX_ARGS(UI_API, __FUNCTION__), uri); - - msg.func_id = SESSION_MGMT_EXECUTE_URI; - msg.data.uri.uri = STRLIB_CREATE(uri); - - if ( ccappTaskPostMsg(CCAPP_SESSION_MGMT, &msg, sizeof(session_mgmt_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(DEB_F_PREFIX"failed to send EXECUTE_URI() msg\n", DEB_F_PREFIX_ARGS(PLAT_API, __FUNCTION__)); - } -} - -/* Log Message Interface Operations */ - -/** - * - * Update Security (mainly lock) Icon on the call bubble. - * NOTE: Only used to indicate media security (ENCRYPTED or not). - * For updating the signaling security(shield icon), use uiCallInfo or - * uiUpdateCallInfo. - * - * @param line - line identifier - * @param call_id - call identifier - * @param call_security - follows the cc_security_e enum - * - * @return none - */ -void -ui_update_call_security (line_t line, callid_t call_id, - cc_security_e call_security) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"security=%d\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - call_security); - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_SECURITY; - msg.update.ccSessionUpd.data.security = call_security; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_SECURITY(%d) msg \n", __FUNCTION__, call_security); - } -} - -/* - *Just for TNP currently. - */ -void -ui_update_conf_invoked (line_t line, callid_t call_id, - boolean invoked) -{ - //Nothing to do here -} - - -/** - * - * Cancel the feature plane given by call_id. - * - * @param line - line identifier - * @param call_id - call identifier - * @param target_call_id - target call id - * - * @return none - */ -void -ui_terminate_feature (line_t line, callid_t call_id, - callid_t target_call_id) -{ - session_update_t msg; - - TNP_DEBUG(DEB_L_C_F_PREFIX"target_call_id=%d\n", DEB_L_C_F_PREFIX_ARGS(UI_API, line, call_id, __FUNCTION__), - target_call_id); - - msg.sessionID = createSessionId(line, call_id); - msg.eventID = CALL_FEATURE_CANCEL; - if (target_call_id != CC_NO_CALL_ID) { - msg.update.ccSessionUpd.data.target_sess_id = createSessionId(line, target_call_id); - } else { - msg.update.ccSessionUpd.data.target_sess_id = 0; - } - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_FEATURE_CANCEL(%d) msg \n", __FUNCTION__, target_call_id); - } -} - -/* APIs required for CTI operations */ - -/* NOP for TNP: the speaker mode is set by media manager. if call control - * need to set the mode explicitely use vcm_set_speaker_mode. - */ -void -ui_set_speaker_mode (boolean mode) -{ - return; -} - -void -ui_cfwdall_req (unsigned int line) -{ - lsm_clear_cfwd_all_ccm(line); - return; -} - - -/***********************************************************/ - -char * -Basic_is_phone_forwarded (line_t line) -{ - TNP_DEBUG(DEB_F_PREFIX"called for line %d\n", DEB_F_PREFIX_ARGS(UI_API, "Basic_is_phone_forwarded"), line); - return ((char *) lsm_is_phone_forwarded(line)); -} - -void -ui_sip_config_done (void) -{ -} - -/** - * convert to numeric dtmf tone code that ms - * understands from ascii code - */ -static int map_digit(char k) -{ - switch(k) { - case '1': - return 1; - case '2': - return 2; - case '3': - return 3; - case '4': - return 4; - case '5': - return 5; - case '6': - return 6; - case '7': - return 7; - case '8': - return 8; - case '9': - return 9; - case '0': - return 0; - case '*': - return 10; - case'#': - return 11; - case 'A': - return 12; - case 'B': - return 13; - case 'C': - return 14; - case 'D': - return 15; - default: - return -1; - } -} - - -/** - * Emulate keypad button press - * - * @param digitstr - one or more digits to be pressed - * @param direction - either VCM_PLAY_TONE_TO_EAR or VCM_PLAY_TONE_TO_NET - * or VCM_PLAY_TONE_TO_ALL - * - * @return none - */ -void -ui_keypad_button (char *digitstr, int direction) -{ - int digit; - unsigned int i; - - - for (i=0; iline, call_id, __FUNCTION__)); - - msg.sessionID = createSessionId(dcb->line, call_id); - msg.eventID = CALL_LOGDISP; - msg.update.ccSessionUpd.data.action = logdisp; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR("%s: failed to send CALL_PRESERVATION_ACTIVE(%d) msg \n", __FUNCTION__, call_id); - } -} - -/** - * Stub for ui_control_feature - * - * @param line_id - line identifier - * @param call_id - call identifier - * @param feature - name of the softkey set - * @param enable - enable/disable - * - * @return none - */ -void -ui_control_feature (line_t line_id, callid_t call_id, - int feat_list[], int len, int enable) -{ - // do nothing. -} - -/* - * Helper for the following four functions which all load up a - * session_update message and post it. - * - */ -static void post_message_helper( - group_call_event_t eventId, - call_events event, - line_t nLine, - callid_t nCallId, - uint16_t call_instance_id, - char *sdp, - cc_int32_t status) -{ - session_update_t msg; - - if (nCallId == CC_NO_CALL_ID) { - /* no operation when no call ID */ - return; - } - - msg.sessionID = createSessionId(nLine, nCallId); - - msg.eventID = eventId; - msg.update.ccSessionUpd.data.state_data.state = event; - msg.update.ccSessionUpd.data.state_data.inst = call_instance_id; - msg.update.ccSessionUpd.data.state_data.line_id = nLine; - msg.update.ccSessionUpd.data.state_data.sdp = sdp; - if (eventId == SET_LOCAL_DESC || eventId == SET_REMOTE_DESC) { - msg.update.ccSessionUpd.data.state_data.cause = status; - } - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE(%d) msg \n", __FUNCTION__, event); - } - - return; -} - -/** - * Send data from createOffer to the UI, can send success with SDP string - * or can send error - * - * @return none - */ -void ui_create_offer(call_events event, line_t nLine, callid_t nCallID, - uint16_t call_instance_id, char* sdp) -{ - TNP_DEBUG(DEB_L_C_F_PREFIX"state=%d attr=%d call_instance=%d\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, nLine, nCallID, __FUNCTION__), event, call_instance_id); - - post_message_helper(CREATE_OFFER, event, nLine, nCallID, call_instance_id, sdp, 0); - - return; -} - -/** - * Send data from createAnswer to the UI, can send success with SDP string - * or can send error - * - * @return none - */ -void ui_create_answer(call_events event, line_t nLine, callid_t nCallID, - uint16_t call_instance_id, char* sdp) -{ - TNP_DEBUG(DEB_L_C_F_PREFIX"state=%d call_instance=%d\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, nLine, nCallID, __FUNCTION__), event, call_instance_id); - - post_message_helper(CREATE_ANSWER, event, nLine, nCallID, call_instance_id, sdp, 0); - - return; -} - -/** - * Send data from setLocalDescription to the UI - * - * @return none - */ - -void ui_set_local_description(call_events event, line_t nLine, callid_t nCallID, - uint16_t call_instance_id, char* sdp, cc_int32_t status) -{ - TNP_DEBUG(DEB_L_C_F_PREFIX"state=%d call_instance=%d\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, nLine, nCallID, __FUNCTION__), event, call_instance_id); - - post_message_helper(SET_LOCAL_DESC, event, nLine, nCallID, call_instance_id, sdp, status); - - return; -} - -/** - * Send data from setRemoteDescription to the UI - * - * @return none - */ - -void ui_set_remote_description(call_events event, line_t nLine, callid_t nCallID, - uint16_t call_instance_id, char* sdp, cc_int32_t status) -{ - TNP_DEBUG(DEB_L_C_F_PREFIX"state=%d call_instance=%d\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, nLine, nCallID, __FUNCTION__), event, call_instance_id); - - post_message_helper(SET_REMOTE_DESC, event, nLine, nCallID, call_instance_id, sdp, status); - - return; -} - - -/** - * Send Remote Stream data to the UI - * - * @return none - */ - -void ui_on_remote_stream_added(call_events event, line_t nLine, callid_t nCallID, uint16_t call_instance_id, cc_media_remote_track_table_t media_track) -{ - session_update_t msg; - fsmdef_dcb_t *dcb = fsmdef_get_dcb_by_call_id(nCallID); - - if (nCallID == CC_NO_CALL_ID || dcb == NULL) { - /* no operation when no call ID */ - return; - } - - TNP_DEBUG(DEB_L_C_F_PREFIX"state=%d call_instance=%d\n", - DEB_L_C_F_PREFIX_ARGS(UI_API, nLine, nCallID, __FUNCTION__), event, call_instance_id); - - - msg.sessionID = createSessionId(nLine, nCallID); - - msg.eventID = REMOTE_STREAM_ADD; - msg.update.ccSessionUpd.data.state_data.state = event; - msg.update.ccSessionUpd.data.state_data.inst = call_instance_id; - msg.update.ccSessionUpd.data.state_data.line_id = nLine; - msg.update.ccSessionUpd.data.state_data.media_stream_track_id = media_track.track[0].media_stream_track_id; - msg.update.ccSessionUpd.data.state_data.media_stream_id = (unsigned int)media_track.media_stream_id; - - if ( ccappTaskPostMsg(CCAPP_SESSION_UPDATE, &msg, sizeof(session_update_t), CCAPP_CCPROVIER) != CPR_SUCCESS ) { - CCAPP_ERROR(CCAPP_F_PREFIX"failed to send CALL_STATE(%d) msg \n", __FUNCTION__, event); - } - - return; -} diff --git a/libs/sipcc/core/gsm/ccapi.c b/libs/sipcc/core/gsm/ccapi.c deleted file mode 100755 index 9f9a65800c..0000000000 --- a/libs/sipcc/core/gsm/ccapi.c +++ /dev/null @@ -1,1749 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "cpr_stdlib.h" -#include "ccapi.h" -#include "ccsip_task.h" -#include "debug.h" -#include "phone_debug.h" -#include "phntask.h" -#include "phone.h" -#include "text_strings.h" -#include "string_lib.h" -#include "gsm.h" -#include "vcm.h" -#include "sip_common_regmgr.h" -#include "util_string.h" - -static const char *cc_src_names[] = { - "GSM", - "UI", - "SIP", - "MISC_APP", - "CCAPP" -}; - -#define CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, msg) \ - DEF_DEBUG(DEB_L_C_F_PREFIX"%s -> %s: %-20s\n",\ - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__),\ - cc_src_name(src_id), cc_src_name(dst_id), msg) - - -callid_t cc_get_new_call_id (void) -{ - static callid_t call_id = CC_NO_CALL_ID; - - if (++call_id == 0) { - call_id = 1; - } - - return call_id; -} - - -const char * -cc_src_name (cc_srcs_t id) -{ - if ((id <= CC_SRC_MIN) || (id >= CC_SRC_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return cc_src_names[id]; -} - - -static void -cc_print_msg (char *pData, int len) -{ - int ix; - int msg_id = *((int *) pData); - - buginf("\n" CCA_F_PREFIX "cc_msg= %s, 0x=", __FUNCTION__, - cc_msg_name((cc_msgs_t) msg_id)); - for (ix = 0; ix < len; ix++) { - if ((ix % 8 == 0) && ix) { - buginf(" "); - } - if (ix % 24 == 0) { - buginf("\n"); - } - buginf("%02x ", *pData++); - } - buginf("\n"); -} - - -/* - * Return a SysBuf and initialize - * Parameters supplied by application: - * - MinSize: size of buffer requested - */ -cprBuffer_t -cc_get_msg_buf (int min_size) -{ - cprBuffer_t buf; - - if (min_size > CPR_MAX_MSG_SIZE) { - /* Size requested exceeds maximum ethernet buffer */ - GSM_ERR_MSG(get_debug_string(DEBUG_MSG_BUFFER_TOO_BIG), - __FUNCTION__, min_size); - return (cprBuffer_t)NULL; - } - - buf = gsm_get_buffer((uint16_t) min_size); - if (!buf) { - GSM_ERR_MSG(get_debug_string(DEBUG_SYSBUF_UNAVAILABLE), __FUNCTION__); - return (cprBuffer_t)NULL; - } - - /* Clean out the data region of the message */ - memset(buf, 0, min_size); - - CC_DEBUG(DEB_F_PREFIX "Msg id = 0x%0x\n", DEB_F_PREFIX_ARGS(CC_API, __FUNCTION__), buf); - - return buf; -} - -static cc_rcs_t -cc_send_cmd_msg (uint32_t cmd, cprBuffer_t buf, uint16_t len, cc_srcs_t dst_id) -{ - cpr_status_e rc; - - CC_DEBUG_MSG cc_print_msg((char *) buf, len); - - switch (dst_id) { - case CC_SRC_GSM: - rc = gsm_send_msg(cmd, buf, len); - if (rc == CPR_FAILURE) { - cc_free_msg_data((cc_msg_t *) buf); - cpr_free(buf); - } - break; - case CC_SRC_SIP: - rc = SIPTaskSendMsg(cmd, buf, len, NULL); - if (rc == CPR_FAILURE) { - cc_free_msg_data((cc_msg_t *) buf); - cpr_free(buf); - } - break; - default: - rc = CPR_FAILURE; - break; - } - - return (rc == CPR_SUCCESS) ? CC_RC_SUCCESS : CC_RC_ERROR; -} - -static cc_rcs_t -cc_send_msg (cprBuffer_t buf, uint16_t len, cc_srcs_t dst_id) -{ - cpr_status_e rc; - - CC_DEBUG_MSG cc_print_msg((char *) buf, len); - - switch (dst_id) { - case CC_SRC_GSM: - rc = gsm_send_msg(GSM_SIP, buf, len); - if (rc == CPR_FAILURE) { - cc_free_msg_data((cc_msg_t *) buf); - cpr_free(buf); - } - break; - case CC_SRC_SIP: - rc = SIPTaskSendMsg(SIP_GSM, buf, len, NULL); - if (rc == CPR_FAILURE) { - cc_free_msg_data((cc_msg_t *) buf); - cpr_free(buf); - } - break; - default: - rc = CPR_FAILURE; - break; - } - - return (rc == CPR_SUCCESS) ? CC_RC_SUCCESS : CC_RC_ERROR; -} - - -/* - * ROUTINE: cc_initialize_msg_body_parts_info - * - * DESCRIPTION: Initializes the msg body part. - * - * PARAMETERS: - * msg_body - pointer to cc_msgbody_info_t to be initialized. - * - * RETURNS: - * None. - * - * NOTES: None - */ -void -cc_initialize_msg_body_parts_info (cc_msgbody_info_t *msg_body) -{ - if (msg_body == NULL) { - return; - } - msg_body->num_parts = 0; - memset(&msg_body->parts[0], 0, sizeof(msg_body->parts)); -} - -/* - * ROUTINE: cc_mv_msg_body_parts - * - * DESCRIPTION: Move the body parts from source to destination. - * - * PARAMETERS: - * dst_msg - pointer to destination cc_msgbody_info_t - * src_msg - pointer to source cc_msgbody_info_t - * - * RETURNS: - * None - * - * NOTES: The function attempts to free the message bodies - * that might be in the destination to prevent - * memory leak from overridden the destination by - * moving the new message source. - * - * The dst_msg must be pointed to the initialized - * message block either with all zero or at least - * number of parts is set to zero to prevent - * freeing an invalid address. - */ -void -cc_mv_msg_body_parts (cc_msgbody_info_t *dst_msg, cc_msgbody_info_t *src_msg) -{ - if (dst_msg == NULL) { - GSM_ERR_MSG(CCA_F_PREFIX "dst is NULL\n", __FUNCTION__); - return; - } - - /* Free the msg. bodies that might be in the dest first */ - cc_free_msg_body_parts(dst_msg); - - if (src_msg != NULL) { - /* copy all of the parts */ - *dst_msg = *src_msg; - src_msg->num_parts = 0; - } -} - -/* - * ROUTINE: cc_free_msg_body_parts - * - * DESCRIPTION: Free elements in the msg body part structure. - * - * PARAMETERS: - * msg_body - pointer to cc_msgbody_info_t for freeing. - * - * RETURNS: - * None - * - * NOTES: None - */ -void -cc_free_msg_body_parts (cc_msgbody_info_t *msg_body) -{ - cc_msgbody_t *part; - - if ((msg_body == NULL) || (msg_body->num_parts == 0)) { - /* Nothing to be freed */ - return; - } - - /* Free all of the bodies and their contents */ - part = &msg_body->parts[0]; - for (; msg_body->num_parts; msg_body->num_parts--, part++) { - if (part->body != NULL) { - cpr_free(part->body); - part->body = NULL; - } - if (part->content_id != NULL) { - cpr_free(part->content_id); - part->content_id = NULL; - } - } -} - -/* - * ROUTINE: cc_get_msg_body_info_ptr_from_feature_data - * - * DESCRIPTION: The function gets msg pointer from a cc_feature_data_t - * structure if there is one. The msg body - * info does not aways attach to all features - * i.e. only certain feature IDs have msg body - * in the feature data. The function returns - * pointer to the msg body if the feature has - * valid data and for those features that contain - * msg body. - * - * PARAMETERS: - * id - cc_feature_t. - * data - pointer to cc_feature_data_t of the feature data to - * whose embedded resources need to be freed. - * - * RETURNS: - * msg_body - pointer to msg_body_info_t if there is - * a msg. - * - * NOTES: None - */ -static cc_msgbody_info_t * -cc_get_msg_body_info_ptr_from_feature_data (cc_features_t id, - cc_feature_data_t *data) -{ - cc_msgbody_info_t *msg_body = NULL; - - if (data == NULL) { - return (NULL); - } - - switch (id) { - case CC_FEATURE_HOLD: - msg_body = &data->hold.msg_body; - break; - case CC_FEATURE_RESUME: - case CC_FEATURE_MEDIA: - msg_body = &data->resume.msg_body; - break; - case CC_FEATURE_UPDATE: - msg_body = &data->update.msg_body; - break; - default: - /* - * Other ones do not have msg body info yet, add the handling here - * when adding feature that needs msg body info. - */ - break; - } - return (msg_body); -} - -/* - * ROUTINE: cc_cp_caller - * - * DESCRIPTION: Copy caller ID and other fields from source to destination. - * - * PARAMETERS: - * dst_caller - pointer to destination cc_caller_id_t - * src_caller - pointer to source cc_caller_id_t - * - * RETURNS: - * None - * - * Note: See also cc_mv_caller_id() cc_free_caller(). - */ -static void -cc_cp_caller (cc_caller_id_t *dst_caller, cc_caller_id_t *src_caller) -{ - if ((src_caller == NULL) || (dst_caller == NULL)) { - return; - } - - dst_caller->calling_name = strlib_empty(); - if (src_caller->calling_name != NULL) { - dst_caller->calling_name = strlib_update(dst_caller->calling_name, - src_caller->calling_name); - } - - dst_caller->calling_number = strlib_empty(); - if (src_caller->calling_number != NULL) { - dst_caller->calling_number = strlib_update(dst_caller->calling_number, - src_caller->calling_number); - } - - dst_caller->alt_calling_number = strlib_empty(); - if (src_caller->alt_calling_number != NULL) { - dst_caller->alt_calling_number = strlib_update(dst_caller->alt_calling_number, - src_caller->alt_calling_number); - } - - dst_caller->called_name = strlib_empty(); - if (src_caller->called_name != NULL) { - dst_caller->called_name = strlib_update(dst_caller->called_name, - src_caller->called_name); - } - - dst_caller->called_number = strlib_empty(); - if (src_caller->called_number != NULL) { - dst_caller->called_number = strlib_update(dst_caller->called_number, - src_caller->called_number); - } - - dst_caller->orig_called_name = strlib_empty(); - if (src_caller->orig_called_name != NULL) { - dst_caller->orig_called_name = - strlib_update(dst_caller->orig_called_name, - src_caller->orig_called_name); - } - - dst_caller->orig_called_number = strlib_empty(); - if (src_caller->orig_called_number != NULL) { - dst_caller->orig_called_number = - strlib_update(dst_caller->orig_called_number, - src_caller->orig_called_number); - } - - dst_caller->last_redirect_name = strlib_empty(); - if (src_caller->last_redirect_name != NULL) { - dst_caller->last_redirect_name = - strlib_update(dst_caller->last_redirect_name, - src_caller->last_redirect_name); - } - - dst_caller->last_redirect_number = strlib_empty(); - if (src_caller->last_redirect_number) { - dst_caller->last_redirect_number = - strlib_update(dst_caller->last_redirect_number, - src_caller->last_redirect_number); - } - - dst_caller->orig_rpid_number = strlib_empty(); - if (src_caller->orig_rpid_number != NULL) { - dst_caller->orig_rpid_number = - strlib_update(dst_caller->orig_rpid_number, - src_caller->orig_rpid_number); - } - dst_caller->display_calling_number = src_caller->display_calling_number; - dst_caller->display_called_number = src_caller->display_called_number; - dst_caller->call_type = src_caller->call_type; - dst_caller->call_instance_id = src_caller->call_instance_id; -} - -/* - * ROUTINE: cc_mv_caller_id - * - * DESCRIPTION: Move caller ID fields from source to destination. - * The caller ID fields from the destination will be - * freed if necessary prior to the move. This allows - * caller to replace the older IDs with the new IDs - * without data duplication. - * - * PARAMETERS: - * dst_caller - pointer to destination cc_caller_id_t - * src_caller - pointer to source cc_caller_id_t - * - * RETURNS: - * None - * - * Note: See also cc_cp_caller() cc_free_caller(). - */ -void -cc_mv_caller_id (cc_caller_id_t *dst_caller, cc_caller_id_t *src_caller) -{ - if ((src_caller == NULL) || (dst_caller == NULL)) { - return; - } - - /* - * Move the IDs from the source to the destination. - * After moved the IDs from the source to the destination then - * the source needs to be NULL. - */ - if (src_caller->calling_name != NULL) { - if (dst_caller->calling_name != NULL) { - strlib_free(dst_caller->calling_name); - } - dst_caller->calling_name = src_caller->calling_name; - src_caller->calling_name = NULL; - } - - if (src_caller->calling_number != NULL) { - if (dst_caller->calling_number != NULL) { - strlib_free(dst_caller->calling_number); - } - dst_caller->calling_number = src_caller->calling_number; - src_caller->calling_number = NULL; - } - - if (src_caller->alt_calling_number != NULL) { - if (dst_caller->alt_calling_number != NULL) { - strlib_free(dst_caller->alt_calling_number); - } - dst_caller->alt_calling_number = src_caller->alt_calling_number; - src_caller->alt_calling_number = NULL; - } - - if (src_caller->called_name != NULL) { - if (dst_caller->called_name != NULL) { - strlib_free(dst_caller->called_name); - } - dst_caller->called_name = src_caller->called_name; - src_caller->called_name = NULL; - } - - if (src_caller->called_number != NULL) { - if (dst_caller->called_number != NULL) { - strlib_free(dst_caller->called_number); - } - dst_caller->called_number = src_caller->called_number; - src_caller->called_number = NULL; - } - - if (src_caller->orig_called_name != NULL) { - if (dst_caller->orig_called_name != NULL) { - strlib_free(dst_caller->orig_called_name); - } - dst_caller->orig_called_name = src_caller->orig_called_name; - src_caller->orig_called_name = NULL; - } - - if (src_caller->orig_called_number != NULL) { - if (dst_caller->orig_called_number != NULL) { - strlib_free(dst_caller->orig_called_number); - } - dst_caller->orig_called_number = src_caller->orig_called_number; - src_caller->orig_called_number = NULL; - } - - if (src_caller->last_redirect_name != NULL) { - if (dst_caller->last_redirect_name != NULL) { - strlib_free(dst_caller->last_redirect_name); - } - dst_caller->last_redirect_name = src_caller->last_redirect_name; - src_caller->last_redirect_name = NULL; - } - - if (src_caller->last_redirect_number != NULL) { - if (dst_caller->last_redirect_number != NULL) { - strlib_free(dst_caller->last_redirect_number); - } - dst_caller->last_redirect_number = src_caller->last_redirect_number; - src_caller->last_redirect_number = NULL; - } - - if (src_caller->orig_rpid_number != NULL) { - if (dst_caller->orig_rpid_number != NULL) { - strlib_free(dst_caller->orig_rpid_number); - } - dst_caller->orig_rpid_number = src_caller->orig_rpid_number; - src_caller->orig_rpid_number = NULL; - } - dst_caller->display_calling_number = src_caller->display_calling_number; - dst_caller->display_called_number = src_caller->display_called_number; -} - -/* - * ROUTINE: cc_free_caller_id - * - * DESCRIPTION: Free caller ID fields. The IDs that are not NULL IDs will be - * freed because others might have been moved already. - * - * PARAMETERS: - * caller - pointer to destination cc_caller_id_t - * - * RETURNS: - * None - * - * Note: See also cc_cp_caller() cc_mv_caller(). - */ -static void -cc_free_caller_id (cc_caller_id_t *caller) -{ - if (caller == NULL) { - return; - } - - if (caller->calling_name != NULL) { - strlib_free(caller->calling_name); - } - - if (caller->calling_number != NULL) { - strlib_free(caller->calling_number); - } - - if (caller->alt_calling_number != NULL) { - strlib_free(caller->alt_calling_number); - } - - if (caller->called_name != NULL) { - strlib_free(caller->called_name); - } - - if (caller->called_number != NULL) { - strlib_free(caller->called_number); - } - - if (caller->orig_called_name != NULL) { - strlib_free(caller->orig_called_name); - } - - if (caller->orig_called_number != NULL) { - strlib_free(caller->orig_called_number); - } - - if (caller->last_redirect_name != NULL) { - strlib_free(caller->last_redirect_name); - } - - if (caller->last_redirect_number) { - strlib_free(caller->last_redirect_number); - } - - if (caller->orig_rpid_number != NULL) { - strlib_free(caller->orig_rpid_number); - } -} - -/* - * ROUTINE: cc_free_msg_data - * - * DESCRIPTION: Free resources embedded in CCAPI msg. data - * structure. - * - * PARAMETERS: - * data - pointer to cc_msg_t whose embedded resources - * need to be freed. - * - * RETURNS: - * None - */ -void -cc_free_msg_data (cc_msg_t *msg) -{ - cc_msgbody_info_t *msg_body = NULL; - cc_caller_id_t *caller_id = NULL; - - if (msg == NULL) { - return; - } - switch (msg->msg.setup.msg_id) { - case CC_MSG_SETUP: - msg_body = &msg->msg.setup.msg_body; - caller_id = &msg->msg.setup.caller_id; - strlib_free(msg->msg.setup.recv_info_list); - break; - case CC_MSG_SETUP_ACK: - msg_body = &msg->msg.setup_ack.msg_body; - caller_id = &msg->msg.setup_ack.caller_id; - break; - case CC_MSG_PROCEEDING: - caller_id = &msg->msg.proceeding.caller_id; - break; - case CC_MSG_ALERTING: - msg_body = &msg->msg.alerting.msg_body; - caller_id = &msg->msg.alerting.caller_id; - break; - case CC_MSG_CONNECTED: - msg_body = &msg->msg.connected.msg_body; - caller_id = &msg->msg.connected.caller_id; - strlib_free(msg->msg.connected.recv_info_list); - break; - case CC_MSG_CONNECTED_ACK: - msg_body = &msg->msg.connected_ack.msg_body; - caller_id = &msg->msg.connected_ack.caller_id; - break; - case CC_MSG_FEATURE: - if (msg->msg.feature.data_valid) { - msg_body = cc_get_msg_body_info_ptr_from_feature_data( - msg->msg.feature.feature_id, - &msg->msg.feature.data); - - if (msg->msg.feature.feature_id == CC_FEATURE_CALLINFO) { - caller_id = &msg->msg.feature.data.call_info.caller_id; - } - } - break; - case CC_MSG_FEATURE_ACK: - if (msg->msg.feature_ack.data_valid) { - msg_body = cc_get_msg_body_info_ptr_from_feature_data( - msg->msg.feature_ack.feature_id, - &msg->msg.feature_ack.data); - } - break; - case CC_MSG_OPTIONS_ACK: - msg_body = &msg->msg.options_ack.msg_body; - break; - case CC_MSG_AUDIT_ACK: - msg_body = &msg->msg.audit_ack.msg_body; - break; - case CC_MSG_INFO: - strlib_free(msg->msg.info.message_body); - strlib_free(msg->msg.info.content_type); - strlib_free(msg->msg.info.info_package); - break; - default: - return; - } - cc_free_msg_body_parts(msg_body); - cc_free_caller_id(caller_id); -} - -/* - * ROUTINE: cc_cp_msg_body_parts - * - * DESCRIPTION: Copy elements in the msg body part structure. - * - * PARAMETERS: - * dst_msg - pointer to destination cc_msgbody_info_t - * src_msg - pointer to source cc_msgbody_info_t - * - * RETURNS: - * CC_RC_ERROR - * CC_RC_SUCCESS - * - * NOTES: The function attempts to free the message bodies - * that might be in the destination to prevent - * memory leak from overridden the destination by - * moving the new message source. - * - * The dst_msg must be pointed to the initialized - * message block either with all zero or at least - * number of parts is set to zero to prevent - * freeing an invalid address. - */ -cc_rcs_t -cc_cp_msg_body_parts (cc_msgbody_info_t *dst_msg, cc_msgbody_info_t *src_msg) -{ - uint32_t i, body_length; - cc_msgbody_t *src_part, *dst_part; - cc_rcs_t status; - int len; - - if ((dst_msg == NULL) || (src_msg == NULL)) { - return CC_RC_ERROR; - } - /* Free the msg. bodies that might be in the dest first */ - cc_free_msg_body_parts(dst_msg); - - src_part = &src_msg->parts[0]; - dst_part = &dst_msg->parts[0]; - - /* Copy all of the fields of all body parts */ - status = CC_RC_SUCCESS; - for (i = 0; i < src_msg->num_parts; i++, src_part++, dst_part++) { - dst_part->content_type = src_part->content_type; - dst_part->content_disposition = src_part->content_disposition; - - /* Copy body */ - dst_part->body = NULL; - dst_part->body_length = 0; - if ((src_part->body != NULL) && (src_part->body_length > 0)) { - body_length = src_part->body_length; - dst_part->body = (char *) cpr_malloc(body_length); - - if (dst_part->body == NULL) { - /* Unable to allocate memory for body */ - status = CC_RC_ERROR; - break; - } else { - /* - * Copy body including NULL char but the length field - * does not include the extra NULL char. - */ - memcpy(dst_part->body, src_part->body, body_length); - dst_part->body_length = src_part->body_length; - } - } - - dst_part->content_id = NULL; - /* Copy content ID */ - if (src_part->content_id != NULL) { - len = strlen(src_part->content_id) + 1; - dst_part->content_id = (char *) cpr_malloc(len); - if (dst_part->content_id != NULL) { - memcpy(dst_part->content_id, src_part->content_id, len); - } else { - /* Unable to allocate memory for content ID */ - status = CC_RC_ERROR; - break; - } - } - } - dst_msg->num_parts = i; /* number of part copied */ - dst_msg->content_type = src_msg->content_type; - - if (status != CC_RC_SUCCESS) { - /* - * Unable to duplicate the body parts, free all of the allocated - * resources - */ - cc_free_msg_body_parts(dst_msg); - } - return status; -} - -void -cc_int_setup (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_alerting_type alert_info, vcm_ring_mode_t alerting_ring, - vcm_tones_t alerting_tone, cc_redirect_t *redirect, - cc_call_info_t *call_info_p, boolean replaces, - string_t recv_info_list, cc_msgbody_info_t *msg_body) -{ - cc_setup_t *pmsg; - - if (caller_id == NULL) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG("%s: caller id is NULL\n", __FUNCTION__); - return; - } - - CC_DEBUG(DEB_L_C_F_PREFIX " CGPD= %s, CGPN= %s,\n CDPD= %s, CDPN= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), - caller_id->calling_name, caller_id->calling_number, - caller_id->called_name, caller_id->called_number); - - pmsg = (cc_setup_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_SETUP; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->alert_info = alert_info; - pmsg->alerting_ring = alerting_ring; - pmsg->alerting_tone = alerting_tone; - cc_cp_caller(&pmsg->caller_id, caller_id); - - pmsg->call_info.type = CC_FEAT_NONE; - if (call_info_p) { - pmsg->call_info = *call_info_p; - } - - pmsg->replaces = replaces; - - if (redirect != NULL) { - pmsg->redirect = *redirect; - } - - /* Info Package */ - if (recv_info_list && (*recv_info_list != '\0')) { - pmsg->recv_info_list = strlib_copy(recv_info_list); - } else { - pmsg->recv_info_list = strlib_empty(); - } - - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_setup_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body) -{ - cc_setup_ack_t *pmsg; - - pmsg = (cc_setup_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_SETUP_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } -} - - -void -cc_int_proceeding (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id) -{ - cc_proceeding_t *pmsg; - - pmsg = (cc_proceeding_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_PROCEEDING; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg(pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_alerting (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body, boolean inband) -{ - cc_alerting_t *pmsg; - - - pmsg = (cc_alerting_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_ALERTING; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - pmsg->inband = inband; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " inband= %d\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), inband); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_connected (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - string_t recv_info_list, cc_msgbody_info_t *msg_body) -{ - cc_connected_t *pmsg; - - pmsg = (cc_connected_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_CONNECTED; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - - /* Info Package */ - if (recv_info_list && (*recv_info_list != '\0')) { - pmsg->recv_info_list = strlib_copy(recv_info_list); - } else { - pmsg->recv_info_list = strlib_empty(); - } - - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_connected_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body) -{ - cc_connected_ack_t *pmsg; - - pmsg = (cc_connected_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_CONNECTED_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (caller_id != NULL) { - cc_cp_caller(&pmsg->caller_id, caller_id); - } - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_release (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_causes_t cause, const char *dialstring, - cc_kfact_t *kfactor) -{ - cc_release_t *pmsg; - - if (dialstring == NULL) { - CC_DEBUG(DEB_L_C_F_PREFIX " cause= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_cause_name(cause)); - } else { - CC_DEBUG(DEB_L_C_F_PREFIX " cause= %s, dialstring= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_cause_name(cause), dialstring); - } - - pmsg = (cc_release_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_RELEASE; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->cause = cause; - - if (dialstring) { - sstrncpy(pmsg->dialstring, dialstring, CC_MAX_DIALSTRING_LEN); - } - if (kfactor != NULL) { - sstrncpy(pmsg->kfactor.rxstats, kfactor->rxstats, CC_KFACTOR_STAT_LEN); - sstrncpy(pmsg->kfactor.txstats, kfactor->txstats, CC_KFACTOR_STAT_LEN); - } - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_release_complete (cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, cc_causes_t cause, - cc_kfact_t *kfactor) -{ - cc_release_complete_t *pmsg; - - - pmsg = (cc_release_complete_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_RELEASE_COMPLETE; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->cause = cause; - if (kfactor != NULL) { - sstrncpy(pmsg->kfactor.rxstats, kfactor->rxstats, CC_KFACTOR_STAT_LEN); - sstrncpy(pmsg->kfactor.txstats, kfactor->txstats, CC_KFACTOR_STAT_LEN); - } - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " cause= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_cause_name(cause)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_feature2 (cc_msgs_t msg_id, cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, cc_features_t feature_id, - cc_feature_data_t *data) -{ - cc_feature_t *pmsg; - cc_msgbody_info_t *msg_body; - - pmsg = (cc_feature_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG("%s: no buffer available for feat=%s\n", __FUNCTION__, - cc_feature_name(feature_id)); - return; - } - - pmsg->msg_id = msg_id; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->feature_id = feature_id; - pmsg->data_valid = (data == NULL) ? (FALSE) : (TRUE); - - if (pmsg->data_valid == TRUE) { - pmsg->data = *data; - /* - * For call Info feature, need to copy the caller ID - */ - if (feature_id == CC_FEATURE_CALLINFO) { - /* Copy the caller ID */ - cc_cp_caller(&pmsg->data.call_info.caller_id, - &data->call_info.caller_id); - } - /* - * Clear the msg body from the source now since the msg. bodies - * has been transferred to to the CCAPI msg. - */ - msg_body = cc_get_msg_body_info_ptr_from_feature_data(feature_id, data); - cc_initialize_msg_body_parts_info(msg_body); - } - - if ((feature_id == CC_FEATURE_XFER) || - (feature_id == CC_FEATURE_BLIND_XFER)) { - if (data != NULL) { - CC_DEBUG(DEB_L_C_F_PREFIX - "method= %d, call_id= %d, cause= %s dialstring= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), - data->xfer.method, data->xfer.target_call_id, - cc_cause_name(data->xfer.cause), data->xfer.dialstring); - } - } - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_feature_name(feature_id)); - CC_DEBUG(DEB_L_C_F_PREFIX "feature= %s, data= %p\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_feature_name(feature_id), data); - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG("%s: unable to send msg for feat=%s\n", __FUNCTION__, - cc_feature_name(feature_id)); - } - return; -} - -/* - * Helper function for the next six functions that populates and sends - * a feature message - * - */ -static void send_message_helper( - cc_msgs_t msg_id, - cc_srcs_t src_id, - cc_srcs_t dst_id, - callid_t call_id, - line_t line, - cc_features_t feature_id, - cc_feature_data_t *data, - string_t sdp, - cc_jsep_action_t action) -{ - cc_feature_t *pmsg; - cc_msgbody_info_t *msg_body; - - pmsg = (cc_feature_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - GSM_ERR_MSG("%s: no buffer available for feat=%s\n", __FUNCTION__, - cc_feature_name(feature_id)); - return; - } - - pmsg->msg_id = msg_id; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->feature_id = feature_id; - pmsg->data_valid = (data == NULL) ? (FALSE) : (TRUE); - - if (msg_id == CC_MSG_SETLOCALDESC || msg_id == CC_MSG_SETREMOTEDESC) { - pmsg->action = action; - } - - if (msg_id == CC_MSG_CREATEANSWER || msg_id == CC_MSG_SETLOCALDESC || msg_id == CC_MSG_SETREMOTEDESC) { - sstrncpy(pmsg->sdp, sdp, sizeof(pmsg->sdp)); - } - - if (pmsg->data_valid == TRUE) { - pmsg->data = *data; - /* - * For call Info feature, need to copy the caller ID - */ - if (feature_id == CC_FEATURE_CALLINFO) { - /* Copy the caller ID */ - cc_cp_caller(&pmsg->data.call_info.caller_id, - &data->call_info.caller_id); - } - /* - * Clear the msg body from the source now since the msg. bodies - * has been transferred to to the CCAPI msg. - */ - msg_body = cc_get_msg_body_info_ptr_from_feature_data(feature_id, data); - cc_initialize_msg_body_parts_info(msg_body); - } - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_feature_name(feature_id)); - CC_DEBUG(DEB_L_C_F_PREFIX "feature= %s, data= %p\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_feature_name(feature_id), data); - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG("%s: unable to send msg for feat=%s\n", __FUNCTION__, - cc_feature_name(feature_id)); - } - - return; -} - -void -cc_createoffer (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_features_t feature_id, cc_feature_data_t *data) -{ - send_message_helper(CC_MSG_CREATEOFFER, src_id, dst_id, call_id, line, - feature_id, data, NULL, 0); - - return; -} - - -void -cc_createanswer (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_features_t feature_id, string_t sdp, cc_feature_data_t *data) -{ - send_message_helper(CC_MSG_CREATEANSWER, src_id, dst_id, call_id, line, - feature_id, data, sdp, 0); - - return; -} - - -void cc_setlocaldesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - cc_features_t feature_id, cc_jsep_action_t action, string_t sdp, cc_feature_data_t *data) -{ - send_message_helper(CC_MSG_SETLOCALDESC, src_id, dst_id, call_id, line, - feature_id, data, sdp, action); - - return; -} - -void cc_setremotedesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - cc_features_t feature_id, cc_jsep_action_t action, string_t sdp, cc_feature_data_t *data) -{ - send_message_helper(CC_MSG_SETREMOTEDESC, src_id, dst_id, call_id, line, - feature_id, data, sdp, action); - - return; -} - -void cc_localdesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - cc_features_t feature_id, cc_feature_data_t *data) -{ - send_message_helper(CC_MSG_LOCALDESC, src_id, dst_id, call_id, line, - feature_id, data, NULL, 0); - - return; -} - -void cc_remotedesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - cc_features_t feature_id, cc_feature_data_t *data) -{ - send_message_helper(CC_MSG_REMOTEDESC, src_id, dst_id, call_id, line, - feature_id, data, NULL, 0); - - return; -} - - -void -cc_int_feature_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_features_t feature_id, - cc_feature_data_t *data, cc_causes_t cause) -{ - cc_feature_ack_t *pmsg; - cc_msgbody_info_t *msg_body; - - pmsg = (cc_feature_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_FEATURE_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->feature_id = feature_id; - pmsg->data_valid = (data == NULL) ? (FALSE) : (TRUE); - - if (pmsg->data_valid == TRUE) { - pmsg->data = *data; - /* - * Clear the msg body from the source now since the msg. bodies - * has been transferred to to the CCAPI msg. - */ - msg_body = cc_get_msg_body_info_ptr_from_feature_data(feature_id, data); - cc_initialize_msg_body_parts_info(msg_body); - } - pmsg->cause = cause; - - if ((feature_id == CC_FEATURE_XFER) || - (feature_id == CC_FEATURE_BLIND_XFER)) { - if (data != NULL) { - CC_DEBUG(DEB_L_C_F_PREFIX - "method= %d, call_id= %d, cause= %s dialstring= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), - data->xfer.method, data->xfer.target_call_id, - cc_cause_name(data->xfer.cause), data->xfer.dialstring); - } - } - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX "feature= %s, data= %p, cause= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_feature_name(feature_id), data, - cc_cause_name(cause)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_offhook (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, callid_t call_id, - line_t line, char *global_call_id, monitor_mode_t monitor_mode, - cfwdall_mode_t cfwdall_mode) -{ - cc_offhook_t *pmsg; - - pmsg = (cc_offhook_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_OFFHOOK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - if (global_call_id != NULL) { - sstrncpy(pmsg->global_call_id, global_call_id, CC_GCID_LEN); - } - pmsg->prim_call_id = prim_call_id; - pmsg->hold_resume_reason = consult_reason; - pmsg->monitor_mode = monitor_mode; - pmsg->cfwdall_mode = cfwdall_mode; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_line (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line) -{ - cc_line_t *pmsg; - - pmsg = (cc_line_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_LINE; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_onhook (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, callid_t call_id, - line_t line, boolean softkey, cc_onhook_reason_e active_list) -{ - cc_onhook_t *pmsg; - - pmsg = (cc_onhook_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_ONHOOK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->softkey = softkey; - pmsg->prim_call_id = prim_call_id; - pmsg->hold_resume_reason = consult_reason; - pmsg->active_list = active_list; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_digit_begin (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, int digit) -{ - cc_digit_begin_t *pmsg; - - pmsg = (cc_digit_begin_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_DIGIT_BEGIN; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->digit = digit; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_dialstring (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, const char *dialstring, const char *g_call_id, - monitor_mode_t monitor_mode) -{ - cc_dialstring_t *pmsg; - - if (dialstring == NULL) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG("%s: no dialstring\n", __FUNCTION__); - return; - } - - CC_DEBUG(DEB_L_C_F_PREFIX "dialstring= %s\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__),dialstring); - - pmsg = (cc_dialstring_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_DIALSTRING; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - sstrncpy(pmsg->dialstring, dialstring, CC_MAX_DIALSTRING_LEN); - sstrncpy(pmsg->g_call_id, g_call_id, CC_GCID_LEN); - pmsg->monitor_mode = monitor_mode; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - - -void -cc_int_mwi (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - boolean on, int type, int newCount, int oldCount, int hpNewCount, int hpOldCount) -{ - cc_mwi_t *pmsg; - - pmsg = (cc_mwi_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_MWI; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->msgSummary.on = on; - pmsg->msgSummary.type = type; - pmsg->msgSummary.newCount = newCount; - pmsg->msgSummary.oldCount = oldCount; - pmsg->msgSummary.hpNewCount = hpNewCount; - pmsg->msgSummary.hpOldCount = hpOldCount; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " mwi status= %d\n new count= %d old count= %d", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), on, newCount, oldCount); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_options_sdp_req (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, void *pMessage) -{ - cc_options_sdp_req_t *pmsg; - - pmsg = (cc_options_sdp_req_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_OPTIONS; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->pMessage = pMessage; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " message ptr=%p\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), pMessage); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_options_sdp_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, void *pMessage, cc_msgbody_info_t *msg_body) -{ - cc_options_sdp_ack_t *pmsg; - - pmsg = (cc_options_sdp_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_OPTIONS_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->pMessage = pMessage; - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX " message ptr=%p\n", - DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), pMessage); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_audit_sdp_req (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, boolean apply_ringout) -{ - cc_audit_sdp_req_t *pmsg; - - pmsg = (cc_audit_sdp_req_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_AUDIT; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->apply_ringout = apply_ringout; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_L_C_F_PREFIX "\n", DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_audit_sdp_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_msgbody_info_t *msg_body) -{ - cc_audit_sdp_ack_t *pmsg; - - pmsg = (cc_audit_sdp_ack_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_AUDIT_ACK; - pmsg->src_id = src_id; - pmsg->call_id = call_id; - pmsg->line = line; - /* Move body parts if there are any */ - pmsg->msg_body.num_parts = 0; - cc_mv_msg_body_parts(&pmsg->msg_body, msg_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_fail_fallback (cc_srcs_t src_id, cc_srcs_t dst_id, int rsp_type, - cc_regmgr_rsp_e rsp_id, boolean waited) -{ - cc_regmgr_t *pmsg; - - - pmsg = (cc_regmgr_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_FAILOVER_FALLBACK; - pmsg->src_id = src_id; - pmsg->rsp_type = rsp_type; - pmsg->rsp_id = rsp_id; - pmsg->wait_flag = waited; - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, 0, 0, cc_msg_name(pmsg->msg_id)); - CC_DEBUG(DEB_F_PREFIX "rsp_type= %s rsp_id= %s waited = %d\n", - DEB_F_PREFIX_ARGS(CC_API, __FUNCTION__), - rsp_type == RSP_START ? "RSP_START" : "RSP_COMPLETE", - rsp_id == CC_REG_FAILOVER_RSP ? "REG_FAILOVER_RSP" : "REG_FALLBACK_RSP", - waited); - - if (cc_send_cmd_msg(REG_MGR_STATE_CHANGE, (cprBuffer_t) pmsg, - sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_int_info (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, string_t info_package, string_t content_type, - string_t message_body) -{ - cc_info_t *pmsg; - - - pmsg = (cc_info_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - // nobody checks, CC_RC_ERROR, so generate error message - GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__); - return; - } - - pmsg->msg_id = CC_MSG_INFO; - pmsg->call_id = call_id; - pmsg->line = line; - pmsg->info_package = strlib_copy(info_package); - pmsg->content_type = strlib_copy(content_type); - pmsg->message_body = strlib_copy(message_body); - - CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id)); - - if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) { - // nobody checks the return code, so generate error message - GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__); - } - return; -} - -void -cc_init (void) -{ - /* Placeholder function for any initialization tasks */ -} - diff --git a/libs/sipcc/core/gsm/ccapi_strings.c b/libs/sipcc/core/gsm/ccapi_strings.c deleted file mode 100644 index 23e6da7d59..0000000000 --- a/libs/sipcc/core/gsm/ccapi_strings.c +++ /dev/null @@ -1,60 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#define __CC_FEATURE_STRINGS__ // this is required to include feature strings. -#define __CC_MESSAGES_STRINGS__ // this is required to include message strings. -#define __CC_CAUSE_STRINGS__ // this is required to include cause strings. -#include "text_strings.h" -#include "ccapi.h" - -/** - * This function will be invoked by debug print functions. - * - * @param id - feature id - * - * @return feature name string. - */ -const char *cc_feature_name (cc_features_t id) -{ - if ((id <= CC_FEATURE_MIN) || (id >= CC_FEATURE_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return cc_feature_names[id - CC_FEATURE_NONE]; -} - - -/** - * This function will be invoked by debug print functions. - * - * @param id - cc msg id - * - * @return cc msg name string. - */ -const char *cc_msg_name (cc_msgs_t id) -{ - if ((id <= CC_MSG_MIN) || (id >= CC_MSG_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return cc_msg_names[id]; -} - -/** - * This function will be invoked by debug print functions. - * - * @param id - cc cause id - * - * @return cc cause name string. - */ -const char *cc_cause_name (cc_causes_t id) -{ - if ((id <= CC_CAUSE_MIN) || (id >= CC_CAUSE_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return cc_cause_names[id - CC_CAUSE_OK]; -} - diff --git a/libs/sipcc/core/gsm/dcsm.c b/libs/sipcc/core/gsm/dcsm.c deleted file mode 100755 index 0484ef2d3a..0000000000 --- a/libs/sipcc/core/gsm/dcsm.c +++ /dev/null @@ -1,723 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_errno.h" -#include "phone.h" -#include "phntask.h" -#include "lsm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "fim.h" -#include "sdp.h" -#include "debug.h" -#include "gsm_sdp.h" -#include "uiapi.h" -#include "gsm.h" -#include "prot_configmgr.h" -#include "singly_link_list.h" - -typedef enum dcsm_state { - DCSM_S_MIN = -1, - DCSM_S_READY, - DCSM_S_WAITING, - DCSM_S_MAX -} dcsm_state_e; - -#define DCSM_MAX_CALL_IDS (LSM_MAX_CALLS) - -static struct dcsm_icb_t { - callid_t call_ids[DCSM_MAX_CALL_IDS]; - line_t line; - int gsm_state; - sll_handle_t s_msg_list; - - dcsm_state_e state; -} dcsm_cb; - -static const char *dcsm_state_names[] = { - "DCSM_READY", - "DCSM_WAITING" -}; - -extern cc_int32_t g_dcsmDebug; - -static sm_rcs_t dcsm_wait_ev_feature_handling(void *event, int event_id); -static sm_rcs_t dcsm_wait_ev_offhook_handling(void *event, int event_id); -static sm_rcs_t dcsm_wait_ev_dialstring_handling(void *event, int event_id); - -typedef sm_rcs_t (*pdcsm_sm_evt_handler)(void *event, int event_id); - -typedef struct _dcsm_table_t { - int min_state; - int max_state; - int min_event; - int max_event; - pdcsm_sm_evt_handler *table; -} dcsm_table_t; - - -static pdcsm_sm_evt_handler dcsm_function_table[DCSM_S_MAX][CC_MSG_MAX] = -{ -/* DCSM_S_READY ------------------------------------------------------------ */ - { - /* DCSM_E_SETUP */ NULL, - /* DCSM_E_SETUP_ACK */ NULL, - /* DCSM_E_PROCEEDING */ NULL, - /* DCSM_E_ALERTING */ NULL, - /* DCSM_E_CONNECTED */ NULL, - /* DCSM_E_CONNECTED_ACK */ NULL, - /* DCSM_E_RELEASE */ NULL, - /* DCSM_E_RELEASE_COMPLETE */ NULL, - /* DCSM_E_FEATURE */ NULL, - /* DCSM_E_FEATURE_ACK */ NULL, - /* DCSM_E_OFFHOOK */ NULL, - /* DCSM_E_ONHOOK */ NULL, - /* DCSM_E_LINE */ NULL, - /* DCSM_E_DIGIT_BEGIN */ NULL, - /* DCSM_E_DIGIT_END */ NULL, - /* DCSM_E_DIALSTRING */ NULL, - /* DCSM_E_MWI */ NULL, - /* DCSM_E_SESSION_AUDIT */ NULL - }, - -/* DCSM_S_WAITING----------------------------------------------------- */ - { - /* DCSM_E_SETUP */ NULL, - /* DCSM_E_SETUP_ACK */ NULL, - /* DCSM_E_PROCEEDING */ NULL, - /* DCSM_E_ALERTING */ NULL, - /* DCSM_E_CONNECTED */ NULL, - /* DCSM_E_CONNECTED_ACK */ NULL, - /* DCSM_E_RELEASE */ NULL, - /* DCSM_E_RELEASE_COMPLETE */ NULL, - /* DCSM_E_FEATURE */ dcsm_wait_ev_feature_handling, - /* DCSM_E_FEATURE_ACK */ NULL, - /* DCSM_E_OFFHOOK */ dcsm_wait_ev_offhook_handling, - /* DCSM_E_ONHOOK */ NULL, - /* DCSM_E_LINE */ NULL, - /* DCSM_E_DIGIT_BEGIN */ NULL, - /* DCSM_E_DIGIT_END */ NULL, - /* DCSM_E_DIALSTRING */ dcsm_wait_ev_dialstring_handling, - /* DCSM_E_MWI */ NULL, - /* DCSM_E_SESSION_AUDIT */ NULL - }, -}; - -static dcsm_table_t dcsm_sm_table; -static dcsm_table_t *pdcsm_sm_table = &dcsm_sm_table; - -/* - * Adds event to the dcsm queue. - * - * @param event - Call control event to add - * - * @return TRUE if the event is added. - - * - */ -static boolean -dcsm_add_event_to_queue (void *event) -{ - (void) sll_append(dcsm_cb.s_msg_list, event); - - return TRUE; -} - -/* - * Get a event from the queue. - * - * @param none - * - * @return pointer to the event. - - * - */ -static void * -dcsm_get_first_event_from_queue (void) -{ - void *msg_ptr = NULL; - - msg_ptr = sll_next(dcsm_cb.s_msg_list, NULL); - - sll_remove(dcsm_cb.s_msg_list, msg_ptr); - - return(msg_ptr); -} - -/* - * Get dcsm state name. - * - * @param int - state id - * - * @return ponter to the state name either - * DCSM_READY or DCSM_WAITING. - * - */ -const char *dcsm_get_state_name (int state) -{ - if ((state <= DCSM_S_MIN) || - (state >= DCSM_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return dcsm_state_names[state]; -} - -/** - * Feed the event to FIM state machine a direct function call - * to process message retrieved from the queue. - * - * @param void * - pointer to the message to be processed - * - * @return none. - */ -static void dcsm_process_event_to_gsm (void *msg_ptr) -{ - if (fim_process_event(msg_ptr, FALSE) == TRUE) { - - fim_free_event(msg_ptr); - - /* Release buffer too */ - cpr_free(msg_ptr); - } -} - - -/** - * Process ready state events. - * - * @param none - * - * @return none. - */ - -static void dcsm_do_ready_state_job (void) -{ - static const char fname[] = "dcsm_do_ready_state_job"; - void *msg_ptr; - int event_id; - cc_feature_t *feat_msg = NULL; - callid_t call_id = CC_NO_CALL_ID; - - if (dcsm_cb.state != DCSM_S_READY) { - DEF_DEBUG(DEB_F_PREFIX": not in ready state.\n", - DEB_F_PREFIX_ARGS("DCSM", fname)); - return; - } - - msg_ptr = dcsm_get_first_event_from_queue(); - - /* Check if there is any msg available */ - if (msg_ptr != NULL) { - event_id = (int)(((cc_setup_t *)msg_ptr)->msg_id); - if (event_id == CC_MSG_FEATURE) { - feat_msg = (cc_feature_t *) msg_ptr; - if (feat_msg != NULL) { - call_id = feat_msg->call_id; - } - } - - DEF_DEBUG(DEB_F_PREFIX"%d: event (%s%s)\n", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - cc_msg_name((cc_msgs_t)(event_id)), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - dcsm_process_event_to_gsm(msg_ptr); - } -} - -/** - * Function process events based on the state of DCSM. - * - * @param none - * - * @return none. - */ -void dcsm_process_jobs (void) -{ - dcsm_do_ready_state_job(); -} - -/** - * Adds call_id to the list of call_id's which made DCSM to move - * to waiting state. - * - * @param callid_t - call id that has to be added to the list - * - * @return none. - */ -static void dcsm_add_call_id_to_list (callid_t call_id) -{ - static const char fname[] = "dcsm_add_call_id_to_list"; - int i, loc = -1; - - for (i=0; i< DCSM_MAX_CALL_IDS; i++) { - if (dcsm_cb.call_ids[i] == CC_NO_CALL_ID) { - loc = i; - } else if (dcsm_cb.call_ids[i] == call_id) { - //Call_id already present so do not try to add again - return; - } - } - - if (loc == -1) { - - /* Should never happen as there is a space to store call_id - * for each calls - */ - DCSM_ERROR(DCSM_F_PREFIX"DCSM No space to store call_id.\n", - DEB_F_PREFIX_ARGS("DCSM", fname)); - return; - } - - dcsm_cb.call_ids[loc] = call_id; -} - -/** - * Remove call_id from the list and see if the call_ids list is null. - * - * @param callid_t - call id that to be removed from the list. - * - * @return TRUE - if the call_ids list is empty. - * FALSE - call_ids list is not empty. - */ -static boolean dcsm_remove_check_for_empty_list (callid_t call_id) -{ - int i; - boolean call_id_present = FALSE; - - for (i=0; i< DCSM_MAX_CALL_IDS; i++) { - if (dcsm_cb.call_ids[i] == call_id) { - dcsm_cb.call_ids[i] = CC_NO_CALL_ID; - - /* Found out that other call_id exist by setting - * call_id_preset, so return true, don't have to - * continue - */ - if (call_id_present == TRUE) { - return FALSE; - } - - } else if (dcsm_cb.call_ids[i] != CC_NO_CALL_ID) { - call_id_present = TRUE; - } - } - - if (call_id_present == TRUE) { - return(FALSE); - } - - return(TRUE); -} - - -/* - * The function responsible for setting gsm state machine. - * - * @param callid_t - call id of the call - * state - current GSM state - * - * @return void - * - */ -void -dcsm_update_gsm_state (fsm_fcb_t *fcb, callid_t call_id, int state) -{ - int last_state; - static const char fname[] = "dcsm_update_gsm_state"; - fsmdef_dcb_t *dcb; - - if (fcb->fsm_type != FSM_TYPE_DEF) { - DEF_DEBUG(DEB_F_PREFIX"%d: Not handling for %s\n", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - fsm_type_name(fcb->fsm_type)); - return; - } - - last_state = dcsm_cb.state; - - switch (state) { - case FSMDEF_S_RELEASING: - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb && dcb->send_release == FALSE) { - /* This call is already released from SIP persepctive. so no need to wait */ - break; - } - case FSMDEF_S_CONNECTING: - case FSMDEF_S_HOLD_PENDING: - case FSMDEF_S_RESUME_PENDING: - dcsm_add_call_id_to_list(call_id); - - dcsm_cb.state = DCSM_S_WAITING; - break; - case FSMDEF_S_MIN: - case FSMDEF_S_IDLE: - case FSMDEF_S_COLLECT_INFO: - case FSMDEF_S_CALL_SENT: - case FSMDEF_S_OUTGOING_PROCEEDING: - case FSMDEF_S_KPML_COLLECT_INFO: - case FSMDEF_S_OUTGOING_ALERTING: - case FSMDEF_S_INCOMING_ALERTING: - case FSMDEF_S_JOINING: - case FSMDEF_S_CONNECTED: - case FSMDEF_S_CONNECTED_MEDIA_PEND: - case FSMDEF_S_HOLDING: - case FSMDEF_S_PRESERVED: - case FSMDEF_S_MAX: - /* If there are no other call_id then move it to - * ready state else, it will remain in waiting - * state - */ - if (dcsm_remove_check_for_empty_list(call_id) == TRUE) { - dcsm_cb.state = DCSM_S_READY; - /* Check if there are any pending events in the queue - * if so send a DCSM_EV_READY to the GSM so dcsm will - * get a chance to execute. - */ - if (sll_count(dcsm_cb.s_msg_list) > 0 ) { - if (gsm_send_msg(DCSM_EV_READY, NULL, 0) == CPR_FAILURE) { - DCSM_ERROR(DCSM_F_PREFIX"send DCSM_EV_READY ERROR.\n", - DEB_F_PREFIX_ARGS(DCSM, fname)); - } - } - } - - break; - default: - break; - } - - DEF_DEBUG(DEB_F_PREFIX"%d : %s --> %s\n", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - dcsm_get_state_name(last_state), - dcsm_get_state_name(dcsm_cb.state)); - return; -} - -/** - * - * Feature passed through when state machine is in waiting state - * - * @param sm_event_t - * - * @return sm_rcs_t - * - * @pre (none) - */ -static sm_rcs_t -dcsm_wait_ev_offhook_handling (void *event, int event_id) -{ - static const char fname[] = "dcsm_wait_ev_offhook_handling"; - - DEF_DEBUG(DEB_F_PREFIX": offhook\n", - DEB_F_PREFIX_ARGS("DCSM", fname)); - - dcsm_add_event_to_queue(event); - return (SM_RC_END); -} -/** - * - * Feature passed through when state machine is in waiting state - * - * @param sm_event_t - * - * @return sm_rcs_t - * - * @pre (none) - */ -static sm_rcs_t -dcsm_wait_ev_feature_handling (void *event, int event_id) -{ - static const char fname[] = "dcsm_wait_ev_feature_handling"; - cc_feature_t *feat_msg = (cc_feature_t *) event; - sm_rcs_t rc = SM_RC_END; - cc_features_t ftr_id = CC_FEATURE_UNDEFINED; - callid_t call_id = CC_NO_CALL_ID; - - if (feat_msg != NULL) { - ftr_id = feat_msg->feature_id; - call_id = feat_msg->call_id; - } - - DEF_DEBUG(DEB_F_PREFIX"%d: id= %s%s\n", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - cc_msg_name((cc_msgs_t)(event_id)), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - - switch (ftr_id) { - case CC_FEATURE_ANSWER: - case CC_FEATURE_NEW_CALL: - case CC_FEATURE_REDIAL: - case CC_FEATURE_RESUME: - case CC_FEATURE_JOIN: - dcsm_add_event_to_queue(event); - DEF_DEBUG(DEB_F_PREFIX"%d: Event queued\n", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id); - rc = SM_RC_END; - break; - default: - DEF_DEBUG(DEB_F_PREFIX"%d: Feature msg not handled\n", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id); - - rc = SM_RC_CONT; - break; - } - - - return (rc); - -} - -/** - * - * Feature passed through when state machine is in waiting state - * - * @param sm_event_t - * - * @return sm_rcs_t - * - * @pre (none) - */ -static sm_rcs_t -dcsm_wait_ev_dialstring_handling (void *event, int event_id) -{ - static const char fname[] = "dcsm_wait_ev_dialstring_handling"; - - DEF_DEBUG(DEB_F_PREFIX": dialstring\n", - DEB_F_PREFIX_ARGS("DCSM", fname)); - - dcsm_add_event_to_queue(event); - return (SM_RC_END); -} - -/** - * - * Feature passed through when state machine is in waiting state - * - * @param sm_event_t - * - * @return sm_rcs_t - * - * @pre (none) - */ -sm_rcs_t -dcsm_process_event (void *event, int event_id) -{ - static const char fname[] = "dcsm_process_event"; - callid_t call_id; - int state_id; - sm_rcs_t rc = SM_RC_CONT; - fsm_fcb_t *fcb = (fsm_fcb_t *) event; - cc_feature_t *feat_msg = NULL; - pdcsm_sm_evt_handler hdlr; /* cached handler in order to compute its addr once */ - - call_id = fcb->call_id; - - if (event_id == CC_MSG_FEATURE) { - feat_msg = (cc_feature_t *) event; - - if (feat_msg != NULL){ - call_id = feat_msg->call_id; - } - } - - DEF_DEBUG(DEB_F_PREFIX"DCSM %-4d:(%s:%s%s)\n", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - dcsm_get_state_name(dcsm_cb.state), - cc_msg_name((cc_msgs_t)(event_id)), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - - state_id = dcsm_cb.state; // Get current state; - - /* - * validate the state and event - * and that there is a valid function for this state-event pair. - */ - if ((state_id > pdcsm_sm_table->min_state) && - (state_id < pdcsm_sm_table->max_state) && - (event_id > pdcsm_sm_table->min_event) && - (event_id < pdcsm_sm_table->max_event)) { - - if ((hdlr = pdcsm_sm_table->table[pdcsm_sm_table->max_event * state_id + - event_id]) != NULL) { - DEF_DEBUG(DEB_F_PREFIX"%-4d: dcsm entry: (%s)\n", - DEB_F_PREFIX_ARGS("DCSM", fname), call_id, - cc_msg_name((cc_msgs_t)(event_id))); - - rc = hdlr(event, event_id); - } - - } - - return (rc); - -} - -/* - * Function responsible for searching the list. - * - * @param cac_data_t *key_p - pointer to the key. - * @param cac_data_t *cac_data - cac data. - * - * @return void - * - */ -static sll_match_e -dcsm_match_event (void *key_p, void *msg_data) -{ - return SLL_MATCH_FOUND; -} - -/** - * - * Show function for DCSM - * - * @param argc - number of parameter passed - * argv - argument passed - * - * @return 0 - if function successful - */ -cc_int32_t -dcsm_show_cmd (cc_int32_t argc, const char *argv[]) -{ - void *msg_ptr; - int i; - cc_setup_t *msg; - cc_msgs_t msg_id; - line_t line; - callid_t call_id; - cc_feature_t *feat_msg = NULL; - - - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("%s", "show dcsm\n"); - return (0); - } - - - if (dcsm_cb.s_msg_list == NULL) { - return(0); - } - - debugif_printf("%s", "\n-------------------------- DCSM Data --------------------------"); - debugif_printf("\nDCSM State = %s",dcsm_get_state_name(dcsm_cb.state)); - debugif_printf("%s", "\nDCSM waiting calls \n"); - - for (i=0; i< DCSM_MAX_CALL_IDS; i++) { - if (dcsm_cb.call_ids[i] != CC_NO_CALL_ID) { - debugif_printf("%d ", dcsm_cb.call_ids[i]); - } - } - debugif_printf("%s", "\n"); - - debugif_printf("%s", "\nDCSM waiting events \n"); - i = 0; - msg_ptr = sll_next(dcsm_cb.s_msg_list, NULL); - while (msg_ptr) { - msg_ptr = sll_next(dcsm_cb.s_msg_list, msg_ptr); - - if (msg_ptr) { - msg = (cc_setup_t *) msg_ptr; - msg_id = msg->msg_id; - call_id = msg->call_id; - line = msg->line; - if ((int)msg_id == CC_MSG_FEATURE) { - feat_msg = (cc_feature_t *) msg_ptr; - } - - debugif_printf("Event %d (%d/%d): (%s%s)\n", - i++, line, call_id, cc_msg_name(msg_id), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - } - } - debugif_printf("%s", "\n-------------------------- DCSM Data Done-----------------------"); - - return (0); -} - - -/** - * - * Initialize dcsm state machine. - * - * @param none - * - * @return none - * - * @pre none - */ -void -dcsm_init (void) -{ - static const char fname[] = "dcsm_init"; - int i; - - /* - * Initialize the state/event table. - */ - dcsm_sm_table.min_state = DCSM_S_MIN; - dcsm_sm_table.max_state = DCSM_S_MAX; - dcsm_sm_table.min_event = CC_MSG_MIN; - dcsm_sm_table.max_event = CC_MSG_MAX; - dcsm_sm_table.table = (&(dcsm_function_table[0][0])); - - dcsm_cb.state = DCSM_S_READY; - - for (i=0; i< DCSM_MAX_CALL_IDS; i++) { - dcsm_cb.call_ids[i] = CC_NO_CALL_ID; - } - - /* allocate and initialize cac list */ - dcsm_cb.s_msg_list = sll_create((sll_match_e(*)(void *, void *)) - dcsm_match_event); - - if (dcsm_cb.s_msg_list == NULL) { - DCSM_ERROR(DCSM_F_PREFIX"DCSM CB creation failed.\n", - DEB_F_PREFIX_ARGS("DCSM", fname)); - - } - -} - -/** - * - * Shut down routine for dcsm state machine. - * - * @param none - * - * @return none - * - * @pre none - */ -void -dcsm_shutdown (void) -{ - void *msg_ptr; - - if (dcsm_cb.s_msg_list == NULL) { - return; - } - - msg_ptr = sll_next(dcsm_cb.s_msg_list, NULL); - while (msg_ptr) { - msg_ptr = sll_next(dcsm_cb.s_msg_list, msg_ptr); - - if (msg_ptr) { - fim_free_event(msg_ptr); - - /* Release buffer too */ - cpr_free(msg_ptr); - } - } - - sll_destroy(dcsm_cb.s_msg_list); - dcsm_cb.s_msg_list = NULL; -} - diff --git a/libs/sipcc/core/gsm/fim.c b/libs/sipcc/core/gsm/fim.c deleted file mode 100755 index 4a176ed0eb..0000000000 --- a/libs/sipcc/core/gsm/fim.c +++ /dev/null @@ -1,761 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -//#include "mozilla/Assertions.h" -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "phone.h" -#include "fim.h" -#include "lsm.h" -#include "fsm.h" -#include "sm.h" -#include "ccapi.h" -#include "debug.h" -#include "phone_debug.h" -#include "util_string.h" -#include "sdp.h" -#include "gsm_sdp.h" -#include "ccsip_sdp.h" -#include "platform_api.h" - -extern void set_next_sess_video_pref(int pref); -extern sm_rcs_t dcsm_process_event(void *event, int event_id); - -#define FIM_MAX_CHNS (LSM_MAX_CALLS) -#define FIM_MAX_SCBS (FSM_TYPE_MAX) -#define FIM_MAX_ICBS (FSM_TYPE_MAX * FIM_MAX_CHNS) - -static fim_scb_t *fim_scbs; -static fim_icb_t *fim_icbs; - - -static void -fim_mwi (cc_mwi_t *msg) -{ - cc_action_data_t data; - - data.mwi.on = msg->msgSummary.on; - data.mwi.type = msg->msgSummary.type; - data.mwi.newCount = msg->msgSummary.newCount; - data.mwi.oldCount = msg->msgSummary.oldCount; - data.mwi.hpNewCount = msg->msgSummary.hpNewCount; - data.mwi.hpOldCount = msg->msgSummary.hpOldCount; - - (void)cc_call_action(msg->call_id, msg->line, CC_ACTION_MWI, &data); -} - - -static void -fim_init_call_chns (void) -{ - int chn; - fsm_types_t type; - fim_icb_t *icb = NULL; - static const char fname[] = "fim_init_call_chns"; - - fim_scbs = (fim_scb_t *) cpr_calloc(FIM_MAX_SCBS, sizeof(fim_scb_t)); - if (fim_scbs == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to allocate FIM SCBs.\n", fname); - return; - } - - fim_icbs = (fim_icb_t *) cpr_calloc(FIM_MAX_ICBS, sizeof(fim_icb_t)); - if (fim_icbs == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to allocate FIM ICBs.\n", fname); - cpr_free(fim_scbs); - fim_scbs = NULL; - return; - } - - /* - * Initialize the icbs (fim control blocks). - */ - icb = fim_icbs; - for (chn = 0; chn < FIM_MAX_CHNS; chn++) { - for (type = FSM_TYPE_HEAD; type < FSM_TYPE_MAX; type++, icb++) { - icb->call_id = CC_NO_CALL_ID; - icb->scb = &(fim_scbs[type]); - icb->cb = NULL; - - /* - * Set the next_chn pointers if this is the head of the chain, - * Set non-head icbs and the last head to NULL. - */ - if ((type == FSM_TYPE_HEAD) && (chn < (FIM_MAX_CHNS - 1))) { - icb->next_chn = icb + FSM_TYPE_MAX; - } else { - icb->next_chn = NULL; - } - - /* - * Set the next_icb pointers if this icb is not the last - * one on the chain. - */ - if (type < (FSM_TYPE_MAX - 1)) { - icb->next_icb = icb + 1; - } else { - icb->next_icb = NULL; - } - } /* for (jscb = FSM_TYPE_HEAD; i < FSM_TYPE_MAX; i++) { */ - } /* for (ichn = 0; ichn < FIM_MAX_CHNS; ichn++) { */ - - /* - * Initialize the scbs (state machine control blocks). - */ - icb = fim_icbs; - for (type = FSM_TYPE_HEAD; type < FSM_TYPE_MAX; type++, icb++) { - icb->scb->type = type; - fsm_init_scb(icb, CC_NO_CALL_ID); - } -} - -static void -fim_free_call_chn (fim_icb_t *call_chn, line_t line, boolean update_call_cnt) -{ - static const char fname[] = "fim_free_call_chn"; - fim_icb_t *icb = call_chn; - - FIM_DEBUG(get_debug_string(GSM_DBG_PTR), "FIM", call_chn->call_id, fname, - "call_chn", call_chn); - - /* - * Go through the chain and free each icb. - */ - for (icb = call_chn; icb != NULL; icb = icb->next_icb) { - if (icb->scb->free_cb != NULL) { - icb->scb->free_cb(icb, icb->call_id); - } - icb->call_id = CC_NO_CALL_ID; - icb->cb = NULL; - } - if (update_call_cnt == TRUE) { - lsm_decrement_call_chn_cnt(line); - } - else { - FIM_DEBUG(get_debug_string(GSM_DBG_PTR), "lsm not decremented", call_chn->call_id, fname, - "call_chn", call_chn); - } -} - - -static fim_icb_t * -fim_get_call_chn_by_call_id (callid_t call_id) -{ - static const char fname[] = "fim_get_call_chn_by_call_id"; - fim_icb_t *call_chn = NULL; - fim_icb_t *icb = NULL; - - for (icb = fim_icbs; icb != NULL; icb = icb->next_chn) { - if (icb->call_id == call_id) { - call_chn = icb; - break; - } - } - - FIM_DEBUG(get_debug_string(GSM_DBG_PTR), "FIM", call_id, fname, "chn", - call_chn); - - return call_chn; -} - -static fim_icb_t * -fim_get_new_call_chn (callid_t call_id) -{ - static const char fname[] = "fim_get_new_call_chn"; - fim_icb_t *call_chn = NULL; - fim_icb_t *icb = NULL; - - /* - * Verify that this call_id is not already used. - */ - call_chn = fim_get_call_chn_by_call_id(call_id); - if (call_chn != NULL) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "call_id in use"); - - return NULL; - } - - /* - * Construct a new call chain. - */ - call_chn = fim_get_call_chn_by_call_id(CC_NO_CALL_ID); - if (call_chn == NULL) { - /* - * No more free call_chns are available. - */ - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "no free call_chns"); - - return NULL; - } - - call_chn->call_id = call_id; - call_chn->ui_locked = FALSE; - - /* - * Set the control blocks for the icbs. - */ - for (icb = call_chn; icb != NULL; icb = icb->next_icb) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - fsm_type_name(icb->scb->type)); - - if (icb->scb->get_cb) { - icb->scb->get_cb(icb, call_id); - icb->call_id = call_id; - icb->ui_locked = FALSE; - } - } - - FIM_DEBUG(get_debug_string(GSM_DBG_PTR), "FIM", call_chn->call_id, fname, - "call_chn", call_chn); - - return call_chn; -} - -void -fim_free_event (void *data) -{ - cc_msg_t *msg = (cc_msg_t *) data; - - /* Free CCAPI msg. data that are not consumed */ - cc_free_msg_data(msg); -} - -static void -fim_process_options_msg (void *data) -{ - static const char fname[] = "fim_process_options_msg"; - cc_sdp_t *local_sdp_p = NULL; - cc_causes_t cause = CC_CAUSE_MIN; - cc_msgbody_info_t msg_body; - cc_options_sdp_req_t *options_msg = (cc_options_sdp_req_t *) data; - - gsmsdp_create_options_sdp(&local_sdp_p); - - cause = gsmsdp_encode_sdp(local_sdp_p, &msg_body); - if (cause != CC_CAUSE_OK) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", options_msg->call_id, - fname, "Unable to build SDP\n"); - } else { - cc_int_options_sdp_ack(CC_SRC_GSM, CC_SRC_SIP, - options_msg->call_id, - options_msg->line, - options_msg->pMessage, &msg_body); - } - sipsdp_src_dest_free(CCSIP_SRC_SDP_BIT, &local_sdp_p); -} - -void -fim_lock_ui (callid_t call_id) -{ - fim_icb_t *call_chn = fim_get_call_chn_by_call_id(call_id); - - if (call_chn == NULL) { - FIM_DEBUG(DEB_F_PREFIX"unknown call id\n", DEB_F_PREFIX_ARGS(FIM, "fim_lock_ui")); - return; - } - call_chn->ui_locked = TRUE; -} - -void -fim_unlock_ui (callid_t call_id) -{ - fim_icb_t *call_chn = fim_get_call_chn_by_call_id(call_id); - - if (call_chn == NULL) { - FIM_DEBUG(DEB_F_PREFIX"unknown call id\n", DEB_F_PREFIX_ARGS(FIM, "fim_unlock_ui")); - return; - } - call_chn->ui_locked = FALSE; -} - -static boolean -fsm_event_filtered_by_ui_lock (int event_id, cc_features_t feature_id) -{ - /* - * If UI has been locked by GSM due to pending states, we want - * to filter the events that come in from the UI. We will still - * allow all GSM and SIP stack originated events through to the - * GSM sm. - */ - if (event_id == CC_MSG_ONHOOK) { - return FALSE; - } - - if ((event_id == CC_MSG_FEATURE) && - (feature_id == CC_FEATURE_END_CALL || - feature_id == CC_FEATURE_REQ_PEND_TIMER_EXP || - feature_id == CC_FEATURE_RESUME || - feature_id == CC_FEATURE_HOLD)) { - return FALSE; - } - - return TRUE; -} - -/** - * - * Check if the feature event is generic feature - * - * @param cc_features_t feature_id - * - * @return TRUE if the feature is generic or else FALSE - * - * @pre None - */ -boolean fim_is_app_generic_features (cc_features_t feat_id) -{ - return(FALSE); -} - -/** - * - * Check if the message is the feature event that may requires a new - * call chain. - * - * @param msg - pointer to cc_setup_t. - * - * @return TRUE if the feature that may requires a new call chain. - * - * @pre (msg != NULL) - */ -static boolean -fim_check_feature_event (cc_setup_t *msg) -{ - - if ((((cc_feature_t *)msg)->feature_id == CC_FEATURE_SELECT) || - (((cc_feature_t *)msg)->feature_id == CC_FEATURE_DIRTRXFR) || - (((cc_feature_t *)msg)->feature_id == CC_FEATURE_B2BCONF) || - (((cc_feature_t *)msg)->feature_id == CC_FEATURE_CFWD_ALL)) { - return (TRUE); - } - return (FALSE); -} - -/* - * fim_feature_need_outgoing_call_context - * - * Description: - * This function determines whther a new feature invokation needs - * an early outgoing call context created in the FIM main module or not. - * - * Parameters: - msg - pointer to the cc_setup_t. - * - * Returns: - * TRUE - the feature requires outgoing call context to be created. - * FALSE - the feature does not requries outgoing call context to - * be created during initial FIM displacthing. - */ -static boolean -fim_feature_need_outgoing_call_context (cc_setup_t *msg) -{ - if (((cc_feature_t *)msg)->feature_id == CC_FEATURE_NOTIFY) { - /* - * these features do not need outgoing context to be created early - */ - return (FALSE); - } - return (TRUE); -} - -/** - * - * Process events received for GSM - * - * @param void event data - * cac_passed indicate if the event passed cac request. - * Usually set to true once the cac response is - * received so that it won't do another request. - * - * @return true if message memory has to be released by caller - * false if the message memory is not to be released by - * caller. - * - * @pre (data not_eq NULL) - * @pre (CC_MSG_MIN < msg->msg_id msg_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - int event_id = msg_id; - sm_event_t event; - fim_icb_t *call_chn = NULL; - fim_icb_t *icb = NULL; - boolean done = FALSE; - sm_rcs_t rc = SM_RC_ERROR; - fim_cb_hdr_t *cb_hdr = NULL; - fsm_fcb_t *fcb = NULL; - cc_feature_t *feat_msg = (cc_feature_t *) data; - cc_feature_data_t * feat_data = &(feat_msg->data); - boolean update_call_cnt = TRUE; - uint32_t no_of_session = 1; - callid_t bw_call_id; - - FIM_DEBUG(DEB_L_C_F_PREFIX"Msg name = %s\n", DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), - cc_msg_name(msg_id)); - - /* - * Validate the incoming event. - */ - if ((event_id <= CC_MSG_MIN) || (event_id >= CC_MSG_MAX)) { - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - return(TRUE); - } - - /* Make sure to process the device events - */ - - if (dcsm_process_event(data, event_id) == SM_RC_END) { - /* Keep the message in the dcsm state handler */ - return(FALSE); - } - - /* - * Grab non-call control events and hand them off to other functions that - * are not implemented by the fsms. - */ - if (msg_id == CC_MSG_MWI) { - fim_mwi((cc_mwi_t *) msg); - } - - if (event_id == CC_MSG_OPTIONS) { - fim_process_options_msg(data); - return(TRUE); - } - - - if (platWlanISActive() && cac_passed == FALSE) { - /* The WLAN will request for bandwidth only for the events received from - * UI or other external entity. For internal events there is allocated bandwidth - * and do not need to request again. - */ - - if ((msg->src_id != CC_SRC_GSM) && - ((event_id == CC_MSG_SETUP) || - (event_id == CC_MSG_OFFHOOK) || - (event_id == CC_MSG_DIALSTRING) || - (event_id == CC_MSG_LINE) || - ((event_id == CC_MSG_FEATURE) && - ((((cc_feature_t *) msg)->feature_id == CC_FEATURE_NEW_CALL))))) { - - bw_call_id = call_id; - - if ((event_id == CC_MSG_SETUP) && - ((((cc_setup_t *)msg)->call_info.type == CC_FEAT_MONITOR))) { - no_of_session = 2; - bw_call_id = msg->call_info.data.join.join_call_id; - } - - if (fsm_cac_call_bandwidth_req (bw_call_id, no_of_session, msg) != CC_CAUSE_OK) { - return(TRUE); - } - /* Do not release the msg once it returns from the call - */ - return(FALSE); - } - } - - if ((event_id == CC_MSG_FEATURE) && ((call_id == CC_NO_CALL_ID) || - fim_is_app_generic_features(((cc_feature_t *) msg)->feature_id))) { - if (((cc_feature_t *)msg)->feature_id == CC_FEATURE_BLF_ALERT_TONE) { - (void)cc_call_action(0, 0, CC_ACTION_PLAY_BLF_ALERTING_TONE, NULL); - } else if (((cc_feature_t *)msg)->feature_id == CC_FEATURE_UPD_MEDIA_CAP) { - fsmdef_update_media_cap_feature_event(feat_msg); - } - return(TRUE); - } - - /* - * Throw away any messages with call_id < 1 (which means they are invalid). - * - * The GSM will send messages back to itself with a call_id < 1 because - * it uses the NULL_DCB. The fsmxfr will use a NULL_DCB that has invalid - * data in it, but the DCB points to a valid DCB. This way, the fsmxfr does - * not have to keep checking for the NULL. - */ - if (call_id < 1) { - return(TRUE); - } - - - /* - * Get the call chain associated with this call_id. - */ - call_chn = fim_get_call_chn_by_call_id(call_id); - - if (call_chn == NULL) { - /* - * No call chain, so get a new call chain, - * but only if the event is a call establishment event. - */ - if ((event_id == CC_MSG_SETUP) || - (event_id == CC_MSG_OFFHOOK) || - (event_id == CC_MSG_DIALSTRING) || - (event_id == CC_MSG_LINE) || - (event_id == CC_MSG_CREATEOFFER) || - (event_id == CC_MSG_CREATEANSWER) || - (event_id == CC_MSG_SETLOCALDESC) || - (event_id == CC_MSG_SETREMOTEDESC) || - (event_id == CC_MSG_SETPEERCONNECTION) || - (event_id == CC_MSG_ADDSTREAM) || - (event_id == CC_MSG_REMOVESTREAM) || - (event_id == CC_MSG_ADDCANDIDATE) || - ((event_id == CC_MSG_FEATURE) && - ((((cc_feature_t *) msg)->feature_id == CC_FEATURE_NEW_CALL)))) { - call_chn = fim_get_new_call_chn(call_id); - - /* - * Make sure we got a new call chain. - */ - if (call_chn == NULL) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "no call_chn"); - - fsm_display_no_free_lines(); - - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - return(TRUE); - } - - } else if ((event_id == CC_MSG_FEATURE) && - (fim_check_feature_event(msg))) { - - call_chn = fim_get_new_call_chn(call_id); - - /* - * Make sure we got a new call chain. - */ - if (call_chn == NULL) { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "no call_chn"); - - fsm_display_no_free_lines(); - - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - return(TRUE); - } - - if (fim_feature_need_outgoing_call_context(msg)) { - /* Get new outgoing call context using DEF state m/c fsm */ - if (fsm_get_new_outgoing_call_context(call_id, line, - fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF), - FALSE) != CC_CAUSE_OK) { - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - return(TRUE); - } - } - - } else { - FIM_DEBUG(get_debug_string(GSM_DBG1), "FIM", call_id, fname, - "not a call establishment event\n"); - if( feat_msg->feature_id == CC_FEATURE_UPD_SESSION_MEDIA_CAP) { - FIM_DEBUG(DEB_L_C_F_PREFIX"set_next_sess_video_pref = %d\n", - DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), - feat_data->caps.support_direction); - set_next_sess_video_pref(feat_data->caps.support_direction); - } - return(TRUE); - } - if (event_id != CC_MSG_SETUP) { - /* - * Increment the call chain cnt for this line - * For incoming calls, we don't know the line number - * when SETUP msg is received, so it's an exception, it'll be - * added in fsmdef_idle_setup - */ - lsm_increment_call_chn_cnt(line); - } - } /* if (call_chn == NULL) */ - - - /* - * Pass the event to the call chain unless UI lock has been enabled. - */ - if (call_chn->ui_locked && ((cc_feature_t *) msg)->src_id == CC_SRC_UI) { - if (fsm_event_filtered_by_ui_lock(event_id, - ((cc_feature_t *)msg)->feature_id)) { - FIM_DEBUG(DEB_L_C_F_PREFIX" %s filtered by UI lock\n", - DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), - cc_feature_name(((cc_feature_t *)msg)->feature_id)); - return(TRUE); - } - } - - /* - * Skip the head. - */ - icb = call_chn->next_icb; - PR_ASSERT(icb); - while (icb && !done) { - /* - * Set the required event data so the entity can process the event. - */ - cb_hdr = (fim_cb_hdr_t *) (icb->cb); - - PR_ASSERT(cb_hdr); - if (!cb_hdr) { - done = TRUE; - break; - } - - event.data = cb_hdr; - event.state = cb_hdr->state; - event.event = event_id; - event.msg = data; - - fcb = (fsm_fcb_t *) icb->cb; - - /* - * For example, if we receive INVITE and CANCEL messages back to back, - * we may be decrementing the call count of wrong line because SIP stack did - * not get the correct value for line yet. - * so set the line value to correct value from DCB. - * For RIU calls, there will be no DCB. However, line value cames from SIP stack - * correctly. - */ - - if ((fcb->fsm_type == FSM_TYPE_DEF) && (event_id == CC_MSG_RELEASE)) { - if (fcb->dcb != NULL) { - line = fcb->dcb->line; - } - } - - /* - * This update_call_cnt is only used when RC_CLEANUP is returned. - */ - update_call_cnt = TRUE; // by default, always update call count - if (fcb->dcb != NULL) { - update_call_cnt = (fcb->dcb->call_not_counted_in_mnc_bt) ? FALSE: TRUE; - } - - FIM_DEBUG(DEB_L_C_F_PREFIX" %s(%s:%s)\n", - DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), fsm_type_name(icb->scb->type), - fsm_state_name(fcb->fsm_type, event.state), - cc_msg_name((cc_msgs_t) (event.event))); - - rc = sm_process_event(icb->scb->sm, &event); - - - switch (rc) { - case SM_RC_CONT: - case SM_RC_DEF_CONT: - icb = icb->next_icb; - break; - - case SM_RC_END: - done = TRUE; - break; - - case SM_RC_ERROR: - FIM_DEBUG(DEB_L_C_F_PREFIX" fsm sm error(%d:%d)\n", - DEB_L_C_F_PREFIX_ARGS(FIM, line, call_id, fname), event.state, event.event); - done = TRUE; - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - break; - - case SM_RC_CLEANUP: - done = TRUE; - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - break; - - default: - done = TRUE; - cc_call_state(call_id, line, CC_STATE_UNKNOWN, NULL); - break; - } /* switch (rc) */ - - if ((rc == SM_RC_END) && (fcb->fsm_type == FSM_TYPE_DEF) && - (event_id == CC_MSG_FEATURE)) - { - if ( ((cc_feature_t *) msg)->feature_id == CC_FEATURE_CFWD_ALL){ - lsm_decrement_call_chn_cnt(line); - } - } - - if (icb == NULL) { - done = TRUE; - FIM_DEBUG("icb is null and get here!"); - } - - } /* while (done != TRUE) { */ - - if (rc == SM_RC_CLEANUP) { - fim_free_call_chn(call_chn, line, update_call_cnt); - - } - - return(TRUE); -} - - -cc_int32_t -fim_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fim_icb_t *icb = NULL; - fim_scb_t *scb = NULL; - int i = 0; - - /* - * Check if need help. - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("%s", "show fim\n"); - } - - /* - * Print the icbs. - */ - debugif_printf("%s", "\n---------------------------------- FIM icbs -----------------------------------"); - debugif_printf("%s", "\ni call_id type icb next_chn next_icb cb scb"); - debugif_printf("%s", "\n-------------------------------------------------------------------------------\n"); - - FSM_FOR_ALL_CBS(icb, fim_icbs, FIM_MAX_ICBS) { - debugif_printf("%-3d %-7d %-6s 0x%8p 0x%8p 0x%8p 0x%8p 0x%8p\n", - i++, icb->call_id, fsm_type_name(icb->scb->type), - icb, icb->next_chn, icb->next_icb, icb->cb, icb->scb); - } - - /* - * Print the scbs. - */ - i = 0; - debugif_printf - ("%s", "\n------------------------ FIM scbs ------------------------"); - debugif_printf("%s", "\ni type scb sm get_cb free_cb"); - debugif_printf - ("%s", "\n----------------------------------------------------------\n"); - - FSM_FOR_ALL_CBS(scb, fim_scbs, FIM_MAX_SCBS) { - debugif_printf("%-2d %-6s 0x%8p 0x%8p 0x%8p 0x%8p\n", - i++, fsm_type_name(scb->type), scb, - scb->sm, scb->get_cb, scb->free_cb); - } - - return (0); -} - - -void -fim_init (void) -{ - - fim_init_call_chns(); -} - -void -fim_shutdown (void) -{ - cpr_free(fim_scbs); - cpr_free(fim_icbs); - fim_scbs = NULL; - fim_icbs = NULL; -} diff --git a/libs/sipcc/core/gsm/fsm.c b/libs/sipcc/core/gsm/fsm.c deleted file mode 100755 index c5f676a9ba..0000000000 --- a/libs/sipcc/core/gsm/fsm.c +++ /dev/null @@ -1,1385 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "fsm.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "gsm.h" /* for GSM_ERR_MSG */ -#include "ccapi.h" -#include "phone_debug.h" -#include "debug.h" -#include "text_strings.h" -#include "sip_interface_regmgr.h" -#include "resource_manager.h" -#include "platform_api.h" - -#define FSM_MAX_FCBS (LSM_MAX_CALLS * (FSM_TYPE_MAX - 1)) -#define FSM_S_IDLE 0 - -extern sm_table_t *pfsmcnf_sm_table; -extern sm_table_t *pfsmb2bcnf_sm_table; -extern sm_table_t *pfsmxfr_sm_table; -extern sm_table_t *pfsmdef_sm_table; - -static fsm_fcb_t *fsm_fcbs; -static fsmdef_dcb_t fsm_dcb; -extern uint16_t g_numofselected_calls; -extern void dcsm_update_gsm_state(fsm_fcb_t *fcb, callid_t call_id, int state); - - -static const char *fsm_type_names[] = { - "HEAD", - "CNF", - "B2BCNF", - "XFR", - "DEF" -}; - -static resource_manager_t *ci_map_p[MAX_REG_LINES + 1]; -static resource_manager_t *shown_calls_ci_map_p[MAX_REG_LINES + 1]; - -const char * -fsm_type_name (fsm_types_t type) -{ - if ((type <= FSM_TYPE_MIN) || (type >= FSM_TYPE_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsm_type_names[type]); -} - - -const char * -fsm_state_name (fsm_types_t type, int id) -{ - switch (type) { - case FSM_TYPE_DEF: - return (fsmdef_state_name(id)); - - case FSM_TYPE_XFR: - return (fsmxfr_state_name(id)); - - case FSM_TYPE_CNF: - return (fsmcnf_state_name(id)); - - case FSM_TYPE_B2BCNF: - return (fsmb2bcnf_state_name(id)); - - case FSM_TYPE_NONE: - return ("IDLE"); - - default: - return (get_debug_string(GSM_UNDEFINED)); - } -} - - -void -fsm_sm_ftr (cc_features_t ftr_id, cc_srcs_t src_id) -{ - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SM_FTR_ENTRY), - cc_feature_name(ftr_id), cc_src_name(src_id)); -} - - -void -fsm_sm_ignore_ftr (fsm_fcb_t *fcb, int fname, cc_features_t ftr_id) -{ - FSM_DEBUG_SM(get_debug_string(FSM_DBG_IGNORE_FTR), - fsm_type_name(fcb->fsm_type), fcb->call_id, fname, - cc_feature_name(ftr_id)); -} - - -void -fsm_sm_ignore_src (fsm_fcb_t *fcb, int fname, cc_srcs_t src_id) -{ - FSM_DEBUG_SM(get_debug_string(FSM_DBG_IGNORE_SRC), - fsm_type_name(fcb->fsm_type), fcb->call_id, fname, - cc_src_name(src_id)); -} - - -void -fsm_init_fcb (fsm_fcb_t *fcb, callid_t call_id, fsmdef_dcb_t *dcb, - fsm_types_t type) -{ - fcb->call_id = call_id; - - fcb->state = FSM_S_IDLE; - fcb->old_state = FSM_S_IDLE; - - fcb->fsm_type = type; - - fcb->dcb = dcb; - - fcb->xcb = NULL; - - fcb->ccb = NULL; - - fcb->b2bccb = NULL; -} - - -/* - * ROUTINE: fsm_get_fcb_by_call_id_and_type - * - * DESCRIPTION: return the fcb referenced by the given call_id and type - * - * PARAMETERS: fsm_id - * - * RETURNS: fcb - * !NULL: fcb found - * NULL: fcb not found - * - * NOTES: - */ -fsm_fcb_t * -fsm_get_fcb_by_call_id_and_type (callid_t call_id, fsm_types_t type) -{ - static const char fname[] = "fsm_get_fcb_by_call_id_and_type"; - fsm_fcb_t *fcb; - fsm_fcb_t *fcb_found = NULL; - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - if ((fcb->call_id == call_id) && (fcb->fsm_type == type)) { - fcb_found = fcb; - break; - } - } - - FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id, - fname, "fcb", fcb_found); - - return (fcb_found); -} - -/* - * DESCRIPTION: return the fcb referenced by the given call_id and type - * - * PARAMETERS: fsm_id - * - * @return void - * !NULL: fcb found - * NULL: fcb not found - * - */ -void -fsm_get_fcb_by_selected_or_connected_call_fcb (callid_t call_id, fsm_fcb_t **con_fcb_found, - fsm_fcb_t **sel_fcb_found) -{ - static const char fname[] = "fsm_get_fcb_by_selected_or_connected_call_fcb"; - fsm_fcb_t *fcb; - - *con_fcb_found = NULL; - *sel_fcb_found = NULL; - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - - if (fcb->call_id == call_id) { - /* Do not count current call_id */ - continue; - } - if (fcb->fsm_type == FSM_TYPE_DEF && - (fcb->state == FSMDEF_S_CONNECTED || - fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND || - fcb->state == FSMDEF_S_OUTGOING_ALERTING)) { - *con_fcb_found = fcb; - } else if (fcb->fsm_type == FSM_TYPE_DEF && fcb->dcb->selected) { - *sel_fcb_found = fcb; - break; - } - } - - FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id, - fname, "fcb", con_fcb_found); - -} - -/* - * ROUTINE: fsm_get_fcb_by_call_id - * - * DESCRIPTION: return the fcb referenced by the given call_id - * - * PARAMETERS: fsm_id - * - * RETURNS: fcb - * !NULL: fcb found - * NULL: fcb not found - * - * NOTES: - */ -fsm_fcb_t * -fsm_get_fcb_by_call_id (callid_t call_id) -{ - static const char fname[] = "fsm_get_fcb_by_call_id"; - fsm_fcb_t *fcb; - fsm_fcb_t *fcb_found = NULL; - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - if (fcb->call_id == call_id) { - fcb_found = fcb; - break; - } - } - - FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id, - fname, "fcb", fcb_found); - - return (fcb_found); -} - - -/* - * ROUTINE: fsm_get_new_fcb - * - * DESCRIPTION: return a new fcb initialized with the given data - * - * PARAMETERS: - * call_id: call_id - * type: feature type - * - * RETURNS: - * fcb: the new fcb - */ -fsm_fcb_t * -fsm_get_new_fcb (callid_t call_id, fsm_types_t fsm_type) -{ - static const char fname[] = "fsm_get_new_fcb"; - fsm_fcb_t *fcb; - - /* - * Get free fcb by using CC_NO_CALL_ID as the call_id because a free fcb - * will have a call_id of CC_NO_CALL_ID. - */ - fcb = fsm_get_fcb_by_call_id(CC_NO_CALL_ID); - if (fcb != NULL) { - fsm_init_fcb(fcb, call_id, FSMDEF_NO_DCB, fsm_type); - } - - FSM_DEBUG_SM(get_debug_string(GSM_DBG_PTR), "FSM", call_id, - fname, "fcb", fcb); - - return (fcb); -} - - -fsmdef_dcb_t * -fsm_get_dcb (callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - /* - * Return the fsm default dcb if a dcb was not found. - */ - if (dcb == NULL) { - dcb = &fsm_dcb; - } - - return (dcb); -} - - -void -fsm_get_fcb (fim_icb_t *icb, callid_t call_id) -{ - icb->cb = fsm_get_new_fcb(call_id, icb->scb->type); -} - - -void -fsm_init_scb (fim_icb_t *icb, callid_t call_id) -{ - icb->scb->get_cb = &fsm_get_fcb; - - switch (icb->scb->type) { - - case FSM_TYPE_B2BCNF: - icb->scb->sm = pfsmb2bcnf_sm_table; - icb->scb->free_cb = fsmb2bcnf_free_cb; - - break; - - case FSM_TYPE_CNF: - icb->scb->sm = pfsmcnf_sm_table; - icb->scb->free_cb = fsmcnf_free_cb; - - break; - case FSM_TYPE_XFR: - icb->scb->sm = pfsmxfr_sm_table; - icb->scb->free_cb = fsmxfr_free_cb; - - break; - - case FSM_TYPE_DEF: - icb->scb->sm = pfsmdef_sm_table; - icb->scb->free_cb = fsmdef_free_cb; - - break; - - case FSM_TYPE_HEAD: - default: - icb->scb->get_cb = NULL; - icb->scb->free_cb = NULL; - icb->scb->sm = NULL; - } - -} - - -void -fsm_change_state (fsm_fcb_t *fcb, int fname, int new_state) -{ - - DEF_DEBUG(DEB_L_C_F_PREFIX"%s: %s -> %s\n", - DEB_L_C_F_PREFIX_ARGS(FSM, ((fcb->dcb == NULL)? CC_NO_LINE: fcb->dcb->line), - fcb->call_id, "fsm_change_state"), - fsm_type_name(fcb->fsm_type), - fsm_state_name(fcb->fsm_type, fcb->state), - fsm_state_name(fcb->fsm_type, new_state)); - - fcb->old_state = fcb->state; - fcb->state = new_state; - NOTIFY_STATE_CHANGE(fcb, fcb->call_id, new_state); - -} - - -void -fsm_release (fsm_fcb_t *fcb, int fname, cc_causes_t cause) -{ - fsm_change_state(fcb, fname, FSM_S_IDLE); - - /* Cleanup any pending cac request for that call */ - fsm_cac_call_release_cleanup(fcb->call_id); - - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); -} - - -cc_int32_t -fsm_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsm_fcb_t *fcb; - int i = 0; - void *cb = NULL; - - PR_ASSERT(i == 0); - - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("%s", "show fsm\n"); - return 0; - } - - /* - * Print the fcbs - */ - debugif_printf("%s", "\n----------------------------- FSM fcbs -------------------------------"); - debugif_printf("%s", "\ni call_id fcb type state dcb cb "); - debugif_printf("%s", "\n----------------------------------------------------------------------\n"); - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - switch (fcb->fsm_type) { - case FSM_TYPE_CNF: - cb = fcb->ccb; - break; - - case FSM_TYPE_B2BCNF: - cb = fcb->ccb; - break; - - case FSM_TYPE_XFR: - cb = fcb->xcb; - break; - - case FSM_TYPE_DEF: - cb = fcb->dcb; - break; - - default: - cb = NULL; - } - - debugif_printf("%-3d %-7d 0x%8p %-9s %-9s 0x%8p 0x%8p\n", - i++, fcb->call_id, fcb, fsm_type_name(fcb->fsm_type), - fsm_state_name(fcb->fsm_type, fcb->state), - fcb->dcb, cb); - } - - return (0); -} - - -void -fsm_init (void) -{ - fsm_fcb_t *fcb; - - fsmdef_init_dcb(&fsm_dcb, 0, FSMDEF_CALL_TYPE_NONE, NULL, LSM_NO_LINE, - NULL); - - fsmdef_init(); - fsmb2bcnf_init(); - fsmcnf_init(); - fsmxfr_init(); - - fsm_cac_init(); - - /* - * Initialize the fcbs. - */ - fsm_fcbs = (fsm_fcb_t *) cpr_calloc(FSM_MAX_FCBS, sizeof(fsm_fcb_t)); - if (fsm_fcbs == NULL) { - GSM_ERR_MSG(GSM_F_PREFIX"Failed to allcoate FSM FCBs.\n", "fsm_init"); - return; - } - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - - /* - * Init call instance id map. - */ - fsmutil_init_ci_map(); -} - -void -fsm_shutdown (void) -{ - fsmdef_shutdown(); - - fsmb2bcnf_shutdown(); - - fsmcnf_shutdown(); - fsmxfr_shutdown(); - - fsm_cac_shutdown(); - - cpr_free(fsm_fcbs); - fsm_fcbs = NULL; - - /* - * Free call instance id map. - */ - fsmutil_free_ci_map(); -} - -/* - * ROUTINE: fsm_set_fcb_dcbs - * - * DESCRIPTION: Set the dcbs for the fsms. The fsm call chain is setup before - * the dcb is known, so this function is called after the dcb - * is known to set the dcb in the fcbs. - * - * PARAMETERS: - * dcb - * - * RETURNS: NONE - * - * NOTES: - */ -cc_causes_t -fsm_set_fcb_dcbs (fsmdef_dcb_t *dcb) -{ - callid_t call_id = dcb->call_id; - fsm_fcb_t *fcb; - fsm_types_t i; - - for (i = FSM_TYPE_CNF; i < FSM_TYPE_MAX; i++) { - fcb = fsm_get_fcb_by_call_id_and_type(call_id, i); - if (fcb == NULL) { - return CC_CAUSE_ERROR; - } - fcb->dcb = dcb; - } - - return CC_CAUSE_OK; -} - - -/* - * ROUTINE: fsm_get_new_outgoing_call_context - * - * DESCRIPTION: get a new outgoing call context - * - * PARAMETERS: - * fcb - * call_id - * line - * - * RETURNS: rc - * FSM_SUCCESS: context successfully created - * FSM_SUCCESS: context unsuccessfully created - * - * NOTES: - */ -cc_causes_t -fsm_get_new_outgoing_call_context (callid_t call_id, line_t line, - fsm_fcb_t *fcb, boolean expline) -{ - static const char fname[] = "fsm_get_new_outgoing_call_context"; - fsmdef_dcb_t *dcb; - cc_causes_t cause = CC_CAUSE_OK; - cc_causes_t lsm_rc; - - /* - * Get a dcb to handle the call. - */ - dcb = fsmdef_get_new_dcb(call_id); - if (dcb == NULL) { - return CC_CAUSE_NO_RESOURCE; - } - - /* - * Get a free facility associated with this line. - */ - lsm_rc = lsm_get_facility_by_line(call_id, line, expline, dcb); - if (lsm_rc != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_ERR), call_id, fname, - "lsm_get_facility_by_line failed", cc_cause_name(lsm_rc)); - } - - /* - * If no line was returned, then init the dcb with an invalid line to - * indicate that no line was returned. - */ - if (lsm_rc != CC_CAUSE_OK) { - line = LSM_NO_LINE; - } - fsmdef_init_dcb(dcb, call_id, FSMDEF_CALL_TYPE_OUTGOING, NULL, line, fcb); - - cause = fsm_set_fcb_dcbs(dcb); - if (cause == CC_CAUSE_OK) { - cause = lsm_rc; - } - - FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_FOUND), call_id, fname, - dcb->line); - - return cause; -} - - -/* - * ROUTINE: fsm_get_new_incoming_call_context - * - * DESCRIPTION: get a new incoming call context - * - * PARAMETERS: - * fcb - * call_id - * - * RETURNS: rc - * FSM_SUCCESS: context successfully created - * FSM_SUCCESS: context unsuccessfully created - * - * NOTES: - */ -cc_causes_t -fsm_get_new_incoming_call_context (callid_t call_id, fsm_fcb_t *fcb, - const char *called_number, boolean expline) -{ - static const char fname[] = "fsm_get_new_incoming_call_context"; - fsmdef_dcb_t *dcb; - line_t free_line; - cc_causes_t cause; - cc_causes_t lsm_rc; - - - /* - * Get a dcb to handle the call. - */ - dcb = fsmdef_get_new_dcb(call_id); - if (dcb == NULL) { - return CC_CAUSE_NO_RESOURCE; - } - - /* - * Get a free facility associated with this called_number. - */ - if ((lsm_rc = lsm_get_facility_by_called_number(call_id, called_number, - &free_line, expline, dcb)) - != CC_CAUSE_OK) { - /* - * Set a default free line (This should really be changed - * to a special invalid value and GSM modified to recognize it.) - * The dcb is needed in order for GSM to clean up the call correctly. - */ - free_line = 1; - FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_ERR), call_id, fname, - "lsm_get_facility_by_called_number", - cc_cause_name(lsm_rc)); - } - - fsmdef_init_dcb(dcb, call_id, FSMDEF_CALL_TYPE_INCOMING, called_number, - free_line, fcb); - - cause = fsm_set_fcb_dcbs(dcb); - if (cause == CC_CAUSE_OK) { - cause = lsm_rc; - } - - FSM_DEBUG_SM(get_debug_string(FSM_DBG_FAC_FOUND), call_id, fname, - dcb->line); - - return cause; -} - -/* - * fsmutil_is_cnf_leg - * - * Description: - * - * Returns TRUE if conferencing is active for the call_id - * - * - * Parameters: - * - * call_id - ccapi call identifier associated with the call. - * fsmxcb_ccbs - pointer to all conf ccbs - * max_ccbs - Max number of ccbs to check - * - * Returns TRUE if the conferencing is active for the call_id - */ -int -fsmutil_is_cnf_leg (callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs, - unsigned short max_ccbs) -{ - fsmcnf_ccb_t *ccb; - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, max_ccbs) { - if ((ccb->cnf_call_id == call_id) || (ccb->cns_call_id == call_id)) { - return TRUE; - } - } - return FALSE; -} - -/* - * fsmutil_is_xfr_leg - * - * Description: - * - * Returns transfer mode if the specified leg identified by call_id is - * participating in a xfer - * - * Parameters: - * - * call_id - ccapi call identifier associated with the call. - * fsmxfr_xcbs - pointer to all xfr ccbs - * max_xcbs - Max number of ccbs to check - * - * Returns: fsmxfr_modes_t - */ -int -fsmutil_is_xfr_leg (callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs, - unsigned short max_xcbs) -{ - fsmxfr_xcb_t *xcb; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, max_xcbs) { - if ((xcb->xfr_call_id == call_id) || (xcb->cns_call_id == call_id)) { - return xcb->mode; - } - } - return FSMXFR_MODE_MIN; -} - -void -fsm_display_no_free_lines (void) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(STR_INDEX_NO_FREE_LINES, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } -} - -/* - * Function: fsm_display_use_line_or_join_to_complete - * - * Description: - * The function is used to put up the status line - * "Use Line or Join to Complete" - * - * @param None - * - * @return None - */ -void -fsm_display_use_line_or_join_to_complete (void) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(STR_INDEX_USE_LINE_OR_JOIN_TO_COMPLETE, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } -} - -void -fsm_display_feature_unavailable (void) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(STR_INDEX_FEAT_UNAVAIL, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } -} - -void -fsm_set_call_status_feature_unavailable (callid_t call_id, line_t line) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(STR_INDEX_FEAT_UNAVAIL, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - ui_set_call_status(tmp_str, line, lsm_get_ui_id(call_id)); - } -} - -/** - * - * Get total number of selected calls. - * - * @param void - * - * @return uint16_t - * - * @pre (none) - */ -uint16_t fsmutil_get_num_selected_calls (void) -{ - return(g_numofselected_calls); -} - -/** - * This function will hide/unhide ringingin calls. - * - * @param[in] hide - indicates whether calls should be hidden or unhidden - * - * @return none - */ -void fsm_display_control_ringin_calls (boolean hide) -{ - fsm_fcb_t *fcb; - - FSM_FOR_ALL_CBS(fcb, fsm_fcbs, FSM_MAX_FCBS) { - if ((fcb->state == FSMDEF_S_INCOMING_ALERTING) && - (lsm_is_it_priority_call(fcb->call_id) == FALSE)) { /* priority call should not be hidden */ - lsm_display_control_ringin_call (fcb->call_id, fcb->dcb->line, hide); - if (hide == TRUE) { - fsmutil_clear_shown_calls_ci_element(fcb->dcb->caller_id.call_instance_id, fcb->dcb->line); - } else { - fsmutil_set_shown_calls_ci_element(fcb->dcb->caller_id.call_instance_id, fcb->dcb->line); - } - } - } -} - -/* - * fsmutil_init_groupid - * - * Description: - * - * Assign the group id to the default control block. - * - * Parameters: - * dcb - default control block - * call_id - ccapi call identifier associated with the call - * call_type - incoming or outgoing call - * - * Returns: None. groupid will be assigned in the dcb. - */ -void -fsmutil_init_groupid (fsmdef_dcb_t *dcb, callid_t call_id, - fsmdef_call_types_t call_type) -{ - fsmcnf_ccb_t *ccb = NULL; - - /* if this was a consult leg of a conference then there will be - * a ccb on the primary leg - */ - dcb->group_id = CC_NO_GROUP_ID; - if (call_type != FSMDEF_CALL_TYPE_NONE) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb) { - /* consult leg of a conference */ - fsmdef_dcb_t *other_dcb = NULL; - - other_dcb = - fsmdef_get_dcb_by_call_id(fsmcnf_get_other_call_id(ccb, call_id)); - if (other_dcb) { - dcb->group_id = other_dcb->group_id; - } - } else { - /* either a primary or some other leg; not part of any conference */ - - dcb->group_id = dcb->call_id; - } - } - return; -} - -/** - * - * Find out if the call pointed by call_id is a consult call - * of a conference, transfer. - * - * @param line line related to that call - * @param call_id call_id - * - * @return call attributes - * - * @pre none - */ -int -fsmutil_get_call_attr (fsmdef_dcb_t *dcb, - line_t line, callid_t call_id) -{ - int call_attr; - - if (fsmutil_is_cnf_consult_call(call_id) == TRUE) { - call_attr = LOCAL_CONF_CONSULT; - } else if (fsmutil_is_b2bcnf_consult_call(call_id) == TRUE) { - call_attr = CONF_CONSULT; - } else if (fsmutil_is_xfr_consult_call(call_id) == TRUE) { - call_attr = XFR_CONSULT; - } else { - if (dcb == NULL) { - return(NORMAL_CALL); - } - - switch (dcb->active_feature) { - case CC_FEATURE_CFWD_ALL: - call_attr = CC_ATTR_CFWD_ALL; - break; - default: - call_attr = NORMAL_CALL; - break; - } - } - return call_attr; -} - -/* - * fsmutil_is_cnf_consult_leg - * - * Description: - * Returns TRUE if the specified call_id is for a call that is - * the consultative call of a conference. - * - * Parameters: - * call_id - ccapi call identifier associated with the call. - * fsmxcb_ccbs - pointer to all conf ccbs - * max_ccbs - Max number of ccbs to check - * - * Returns: TRUE if consultative call; otherwise, FALSE. - */ -int -fsmutil_is_cnf_consult_leg (callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs, - uint16_t max_ccbs) -{ - fsmcnf_ccb_t *ccb; - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, max_ccbs) { - if (ccb->cns_call_id == call_id) { - return TRUE; - } - } - - return FALSE; -} - - -/* - * fsmutil_is_xfr_consult_leg - * - * Description: - * Returns TRUE if the specified call_id is for a call that is - * the consultative call of a transfer only when that consult - * was an initiated transfer. - * - * Parameters: - * call_id - ccapi call identifier associated with the call. - * fsmxfr_xcbs - pointer to all xfr ccbs - * max_xcbs - Max number of ccbs to check - * - * Returns: TRUE if consultative call; otherwise, FALSE. - */ -int -fsmutil_is_xfr_consult_leg (callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs, - uint16_t max_xcbs) -{ - fsmxfr_xcb_t *xcb; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, max_xcbs) { - if ((xcb->mode == FSMXFR_MODE_TRANSFEROR) && - (xcb->cns_call_id == call_id)) { - return TRUE; - } - } - return FALSE; -} - -/* - * fsmutil_clear_feature_invocation_state - * - * Description: - * This function clears the feature invocation state of the feature id - * supplied. This function is used by the code that would receive the - * feature ack (from SIP stack). - * - * Note: Code responsible for invoking features and receiving feature acks - * must call this function to clear the feature invocation state. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with the call - * cc_features_t feature_id - feature id in question - * - * Returns: None - */ -static void -fsmutil_clear_feature_invocation_state (fsmdef_dcb_t *dcb, - cc_features_t feature_id) -{ - if ((feature_id < CC_FEATURE_NONE) || (feature_id >= CC_FEATURE_MAX)) { - /* Log Error */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Invalid feature id -> %d\n", dcb->line, dcb->call_id, "fsmutil_clear_feature_invocation_state", feature_id); - return; - } - - rm_clear_element((resource_manager_t *) dcb->feature_invocation_state, - (int16_t) feature_id); -} - -/* - * fsmutil_process_feature_ack - * - * Description: - * This function implements the generic feature ack processing. - * Feature invocation state is Cleared when feature ack is received. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with the call - * cc_features_t feature_id - feature id in question - * - * Returns: None - */ -void -fsmutil_process_feature_ack (fsmdef_dcb_t *dcb, cc_features_t feature_id) -{ - /* clear the feature invocation state (was set when invoked) */ - fsmutil_clear_feature_invocation_state(dcb, feature_id); -} - -/* - * fsmutil_clear_all_feature_invocation_state - * - * Description: - * This function clears the feature invocation state of ALL features. - * - * This function may be used by the code that would initialize/reset - * the state machine. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with the call - * - * Returns: None - */ -void -fsmutil_clear_all_feature_invocation_state (fsmdef_dcb_t *dcb) -{ - rm_clear_all_elements((resource_manager_t *) dcb->feature_invocation_state); -} - -/* - * fsmutil_init_feature_invocation_state - * - * Description: - * Utility function to allocate and init a feature invocation state table. - * - * Parameters: - * dcb - dcb whose feature invocation state table is being created - * - * Returns: - * none - */ -void -fsmutil_init_feature_invocation_state (fsmdef_dcb_t *dcb) -{ - static const char fname[] = "fsmutil_init_feature_invocation_state"; - - dcb->feature_invocation_state = rm_create(CC_FEATURE_MAX); - - if (!dcb->feature_invocation_state) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"failed to allocate feature invocation state table\n", dcb->line, dcb->call_id, - fname); - } -} - - -/* - * fsmutil_free_feature_invocation_state - * - * Description: - * Utility function to free the feature invocation state table of the - * specified dcb. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_free_feature_invocation_state (fsmdef_dcb_t *dcb) -{ - rm_destroy((resource_manager_t *) dcb->feature_invocation_state); - dcb->feature_invocation_state = NULL; -} - -/* - * fsmutil_free_all_ci_id - * - * Description: - * This function clears the entire call instance map. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_free_all_ci_id (void) -{ - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - rm_clear_all_elements((resource_manager_t *) ci_map_p[line]); - } -} - -/* - * fsmutil_free_ci_id - * - * Description: - * This function clears a specified call instance id from - * the call instance map. - * - * Note that call instance ids are one based. The resource manager - * used to implement the call instance map is zero based so we have - * to adjust the call instance id when using the resource manager API. - * - * Parameters: - * id - the call instance id to be freed - * line - line from where to free the call instance id - * - * Returns: - * None - */ -void -fsmutil_free_ci_id (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_free_ci_id"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id); - return; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line); - return; - } - - rm_clear_element((resource_manager_t *) ci_map_p[line], (int16_t) --id); -} - -#ifdef LOCAL_UI_CALLINSTANCE_ID -/*This routine is not needed now as the local assignment - *of call instance id is no longer supported. - */ -/* - * fsmutil_get_ci_id - * - * Description: - * This function locates the next available call instance id in - * the call instance map. This function is utilized when operating in - * the peer to peer mode to assign call instance ids for inbound - * and outbound calls. - * - * Note that call instance ids are one based. The resource manager - * used to implement the call instance map is zero based so we have - * to adjust the call instance id when using the resource manager API. - * - * Parameters: - * line - line from where to retrieve the call instance id - * - * Returns: - * uint16_t - Non-zero call instance id. 0 if no call instance ids - * are available. - */ -uint16_t -fsmutil_get_ci_id (line_t line) -{ - static const char fname[] = "fsmutil_get_ci_id"; - int16_t id; - uint16_t return_id = 0; - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG("specified line %d is invalid\n", fname, line); - return 0; - } - - id = rm_get_free_element(ci_map_p[line]); - if (id >= 0) { - return_id = ++id; - } - return (return_id); -} -#endif - -/* - * fsmutil_set_ci_id - * - * Description: - * This function marks a specified call instance id as being in - * use in the call instance map. This function is used when in - * CCM mode to store the call instance id specified by the CCM - * for inbound and outbound calls. - * - * Note that call instance ids are one based. The resource manager - * used to implement the call instance map is zero based so we have - * to adjust the call instance id when using the resource manager API. - * Parameters: - * - * Parameters: - * id - The call instance id to set. - * line - Line being used for the call. - * - * Returns: - * None - */ -void -fsmutil_set_ci_id (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_set_ci_id"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id); - return; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line); - return; - } - - rm_set_element(ci_map_p[line], (int16_t) --id); -} - -/* - * fsmutil_init_ci_map - * - * Description: - * Utility function to allocate and init the call instance id map. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_init_ci_map (void) -{ - static const char fname[] = "fsmutil_init_ci_map"; - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - ci_map_p[line] = rm_create(MAX_CALLS); - - if (!ci_map_p[line]) { - GSM_ERR_MSG(GSM_F_PREFIX"failed to allocate call instance id map for line %d", - fname, line); - } - } -} - -/** - * This function will allocate and initialize the shown_calls_call_instnace map. - * - * @return none - */ -void fsmutil_init_shown_calls_ci_map (void) -{ - static const char fname[] = "fsmutil_init_shown_calls_ci_map"; - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - shown_calls_ci_map_p[line] = rm_create(MAX_CALLS); - - if (!shown_calls_ci_map_p[line]) { - GSM_ERR_MSG(GSM_F_PREFIX"failed to allocate shown calls call instance id map for line %d", - fname, line); - } - } -} - -/** - * This function will set the shown_calls_call_instnace map to zeros. - * - * @return none - */ -void fsmutil_free_all_shown_calls_ci_map (void) -{ - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - rm_clear_all_elements((resource_manager_t *) shown_calls_ci_map_p[line]); - } -} - -/** - * This function marks a given call to be hidden. - * - * @param[in] id - call instance id of the call to be hidden. - * @param[in] line - the line being used for the call. - * - * @return none - */ -void fsmutil_clear_shown_calls_ci_element (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_clear_shown_calls_ci_element"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id); - return; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line); - return; - } - - rm_clear_element((resource_manager_t *) shown_calls_ci_map_p[line], (int16_t)(id - 1)); -} - -/** - * This function marks a given call to be shown. - * - * @param[in] id - call instance id of the call to be shown. - * @param[in] line - the line being used for the call. - * - * @return none - */ -void fsmutil_set_shown_calls_ci_element (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_set_shown_calls_ci_element"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id); - return; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line); - return; - } - - rm_set_element(shown_calls_ci_map_p[line], (int16_t)(id - 1)); -} - -/** - * This function checks if a given call is to be shown. - * - * @param[in] id - call instance id of the call. - * @param[in] line - the line being used for the call. - * - * @return none - */ -boolean fsmutil_is_shown_calls_ci_element_set (uint16_t id, line_t line) -{ - static const char fname[] = "fsmutil_is_shown_calls_ci_element_set"; - - if (id < 1 || id > MAX_CALLS) { - GSM_ERR_MSG(GSM_F_PREFIX"specified id %d is invalid\n", fname, id); - return FALSE; - } - - if (line < 1 || line > MAX_REG_LINES) { - GSM_ERR_MSG(GSM_F_PREFIX"specified line %d is invalid\n", fname, line); - return FALSE; - } - - if (rm_is_element_set(shown_calls_ci_map_p[line], (int16_t)(id - 1))) { - return (TRUE); - } - - return (FALSE); -} - -/* - * fsmutil_free_ci_map - * - * Description: - * Utility function to free the call instance id map. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_free_ci_map (void) -{ - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - rm_destroy((resource_manager_t *) ci_map_p[line]); - ci_map_p[line] = NULL; - } -} - -/* - * fsmutil_show_ci_map - * - * Description: - * Utility function to display the current state of the call - * instance map. - * - * Parameters: - * None - * - * Returns: - * None - */ -void -fsmutil_show_ci_map (void) -{ - uint16_t line; - - for (line = 1; line <= MAX_REG_LINES; line++) { - rm_show(ci_map_p[line]); - } -} diff --git a/libs/sipcc/core/gsm/fsmb2bcnf.c b/libs/sipcc/core/gsm/fsmb2bcnf.c deleted file mode 100755 index aa8423ab28..0000000000 --- a/libs/sipcc/core/gsm/fsmb2bcnf.c +++ /dev/null @@ -1,1285 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "fsm.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "debug.h" -#include "config.h" -#include "uiapi.h" -#include "phntask.h" -#include "regmgrapi.h" -#include "subapi.h" -#include "rcc_int_types.h" - -static fsmcnf_ccb_t *fsmb2bcnf_ccbs; - -typedef enum { - FSMB2BCNF_S_MIN = -1, - FSMB2BCNF_S_IDLE, - FSMB2BCNF_S_ACTIVE, - FSMB2BCNF_S_MAX -} fsmb2bcnf_states_t; - -static const char *fsmb2bcnf_state_names[] = { - "IDLE", - "ACTIVE" -}; - - -static sm_rcs_t fsmb2bcnf_ev_idle_feature(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_release(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_release_complete(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_feature(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_feature_ack(sm_event_t *event); -static sm_rcs_t fsmb2bcnf_ev_active_onhook(sm_event_t *event); - -static sm_function_t fsmb2bcnf_function_table[FSMB2BCNF_S_MAX][CC_MSG_MAX] = -{ -/* FSMB2BCNF_S_IDLE ------------------------------------------------------------ */ - { - /* FSMB2BCNF_E_SETUP */ NULL, - /* FSMB2BCNF_E_SETUP_ACK */ NULL, - /* FSMB2BCNF_E_PROCEEDING */ NULL, - /* FSMB2BCNF_E_ALERTING */ NULL, - /* FSMB2BCNF_E_CONNECTED */ NULL, - /* FSMB2BCNF_E_CONNECTED_ACK */ NULL, - /* FSMB2BCNF_E_RELEASE */ NULL, - /* FSMB2BCNF_E_RELEASE_COMPLETE */ NULL, - /* FSMB2BCNF_E_FEATURE */ fsmb2bcnf_ev_idle_feature, - /* FSMB2BCNF_E_FEATURE_ACK */ NULL, - /* FSMB2BCNF_E_OFFHOOK */ NULL, - /* FSMB2BCNF_E_ONHOOK */ NULL, - /* FSMB2BCNF_E_LINE */ NULL, - /* FSMB2BCNF_E_DIGIT_BEGIN */ NULL, - /* FSMB2BCNF_E_DIGIT */ NULL, - /* FSMB2BCNF_E_DIALSTRING */ NULL, - /* FSMB2BCNF_E_MWI */ NULL, - /* FSMB2BCNF_E_SESSION_AUDIT */ NULL - }, - -/* FSMB2BCNF_S_ACTIVE --------------------------------------------------- */ - { - /* FSMB2BCNF_E_SETUP */ NULL, - /* FSMB2BCNF_E_SETUP_ACK */ NULL, - /* FSMB2BCNF_E_PROCEEDING */ NULL, - /* FSMB2BCNF_E_ALERTING */ fsmb2bcnf_ev_active_feature, - /* FSMB2BCNF_E_CONNECTED */ NULL, - /* FSMB2BCNF_E_CONNECTED_ACK */ NULL, - /* FSMB2BCNF_E_RELEASE */ fsmb2bcnf_ev_active_release, - /* FSMB2BCNF_E_RELEASE_COMPLETE */ fsmb2bcnf_ev_active_release_complete, - /* FSMB2BCNF_E_FEATURE */ fsmb2bcnf_ev_active_feature, - /* FSMB2BCNF_E_FEATURE_ACK */ fsmb2bcnf_ev_active_feature_ack, - /* FSMB2BCNF_E_OFFHOOK */ NULL, - /* FSMB2BCNF_E_ONHOOK */ fsmb2bcnf_ev_active_onhook, - /* FSMB2BCNF_E_LINE */ NULL, - /* FSMB2BCNF_E_DIGIT_BEGIN */ NULL, - /* FSMB2BCNF_E_DIGIT */ NULL, - /* FSMB2BCNF_E_DIALSTRING */ NULL, - /* FSMB2BCNF_E_MWI */ NULL, - /* FSMB2BCNF_E_SESSION_AUDIT */ NULL - } -}; - -static sm_table_t g_fsmb2bcnf_sm_table; -sm_table_t *pfsmb2bcnf_sm_table = &g_fsmb2bcnf_sm_table; - -const char * -fsmb2bcnf_state_name (int state) -{ - if ((state <= FSMB2BCNF_S_MIN) || (state >= FSMB2BCNF_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsmb2bcnf_state_names[state]); -} - - -static int -fsmb2bcnf_get_new_b2bcnf_id (void) -{ - static int b2bcnf_id = FSM_NO_ID; - - if (++b2bcnf_id < FSM_NO_ID) { - b2bcnf_id = 1; - } - - return (b2bcnf_id); -} - - -static void -fsmb2bcnf_init_ccb (fsmcnf_ccb_t *ccb) -{ - if (ccb != NULL) { - ccb->cnf_id = FSM_NO_ID; - ccb->cnf_call_id = CC_NO_CALL_ID; - ccb->cns_call_id = CC_NO_CALL_ID; - ccb->cnf_line = CC_NO_LINE; - ccb->cns_line = CC_NO_LINE; - ccb->bridged = FALSE; - ccb->active = FALSE; - ccb->cnf_ftr_ack = FALSE; - ccb->cnf_orig = CC_SRC_MIN; - } -} - -/** - * - * Get active trasnfer state machine information (in active state). - * - * @param none - * - * @return fsm_fcb_t if there is a active trasnfer pending - * else NULL - * - * @pre (none) - */ - -fsm_fcb_t *fsmb2bcnf_get_active_cnf(void) -{ - fsm_fcb_t *fcb; - fsmcnf_ccb_t *b2bccb; - - FSM_FOR_ALL_CBS(b2bccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - fcb = fsm_get_fcb_by_call_id_and_type(b2bccb->cnf_call_id, - FSM_TYPE_B2BCNF); - if (fcb && fcb->state == FSMB2BCNF_S_ACTIVE) { - return(fcb); - } - } - - return(NULL); -} - -static fsmcnf_ccb_t * -fsmb2bcnf_get_ccb_by_b2bcnf_id (int b2bcnf_id) -{ - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *ccb_found = NULL; - - FSM_FOR_ALL_CBS(ccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - if (ccb->cnf_id == b2bcnf_id) { - ccb_found = ccb; - - break; - } - } - - return (ccb_found); -} - - -/* - * Function: fsmb2bcnf_get_new_b2bcnf_context - * - * Parameters: - * b2bcnf_call_id: call_id for the call initiating the conference - * - * Description: This function creates a new conference context by: - * - getting a free ccb - * - creating new b2bcnf_id and cns_call_id - * - * Returns: ccb - * - */ -static fsmcnf_ccb_t * -fsmb2bcnf_get_new_b2bcnf_context (callid_t b2bcnf_call_id, line_t line) -{ - const char fname[] = "fsmb2bcnf_get_new_b2bcnf_context"; - fsmcnf_ccb_t *ccb; - - ccb = fsmb2bcnf_get_ccb_by_b2bcnf_id(FSM_NO_ID); - if (ccb != NULL) { - ccb->cnf_id = fsmb2bcnf_get_new_b2bcnf_id(); - ccb->cnf_call_id = b2bcnf_call_id; - ccb->cnf_line = line; - ccb->cns_line = line; - ccb->cns_call_id = cc_get_new_call_id(); - - FSM_DEBUG_SM(get_debug_string(FSMB2BCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - } else { - - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to get new b2bccb.\n", fname); - } - - return (ccb); -} - - -static fsmcnf_ccb_t * -fsmb2bcnf_get_ccb_by_call_id (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *ccb_found = NULL; - - FSM_FOR_ALL_CBS(ccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - if ((ccb->cnf_call_id == call_id) || (ccb->cns_call_id == call_id)) { - ccb_found = ccb; - - break; - } - } - - return (ccb_found); -} - - -static void -fsmb2bcnf_update_b2bcnf_context (fsmcnf_ccb_t *ccb, callid_t old_call_id, - callid_t new_call_id) -{ - const char fname[] = "fsmb2bcnf_update_b2bcnf_context"; - - if (ccb != NULL) { - if (old_call_id == ccb->cnf_call_id) { - ccb->cnf_call_id = new_call_id; - } else if (old_call_id == ccb->cns_call_id) { - ccb->cns_call_id = new_call_id; - } - - FSM_DEBUG_SM(get_debug_string(FSMB2BCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - } -} - -/* - * Function to get line number of other call associated in - * transfer. - * - * @param xcb and call_id. - * - * @return void - * - */ -line_t -fsmb2bcnf_get_other_line (fsmcnf_ccb_t *ccb, callid_t call_id) -{ - line_t other_line = CC_NO_LINE; - - if (ccb != NULL) { - if (ccb->cnf_call_id == call_id) { - other_line = ccb->cns_line; - } else if (ccb->cns_call_id == call_id) { - other_line = ccb->cnf_line; - } - } - - return (other_line); -} - -static callid_t -fsmb2bcnf_get_other_call_id (fsmcnf_ccb_t *ccb, callid_t call_id) -{ - callid_t other_call_id = CC_NO_CALL_ID; - - if (ccb != NULL) { - if (ccb->cnf_call_id == call_id) { - other_call_id = ccb->cns_call_id; - } else if (ccb->cns_call_id == call_id) { - other_call_id = ccb->cnf_call_id; - } - } - - return (other_call_id); -} - -/* - * Function: fsmb2bcnf_remove_fcb - * - * Parameters: - * b2bcnf_id: b2bcnf_id for the conference - * call_id: call_id that identifies the fcb to be removed - * - * Description: This function will remove the fcb identified by the given - * call_id from the ccb. And the function will free the ccb - * if both fcbs have been removed. - * - * Returns: none - * - * Note: This is a helper function for fsmb2bcnf_cleanup. It allows fsmb2bcnf_cleanup - * to cleanup one fcb (one call involved in the conference) independent - * of the other involved fcb. - */ -static void -fsmb2bcnf_remove_fcb (fsm_fcb_t *fcb, callid_t call_id) -{ - fsmcnf_ccb_t *ccb = fcb->b2bccb; - - if (ccb != NULL) { - fsmb2bcnf_update_b2bcnf_context(ccb, call_id, CC_NO_CALL_ID); - - /* - * Free the ccb if both fcb references have been removed. - */ - if ((ccb->cnf_call_id == CC_NO_CALL_ID) && - (ccb->cns_call_id == CC_NO_CALL_ID)) { - fsmb2bcnf_init_ccb(ccb); - } - } -} - - -static void -fsmb2bcnf_cleanup (fsm_fcb_t *fcb, int fname, boolean both) -{ - fsm_fcb_t *other_fcb = NULL; - callid_t call_id = fcb->call_id; - callid_t other_call_id = CC_NO_CALL_ID; - line_t other_line; - - other_call_id = fsmb2bcnf_get_other_call_id(fcb->b2bccb, call_id); - other_line = fsmb2bcnf_get_other_line(fcb->b2bccb, call_id); - - if (other_call_id != CC_NO_CALL_ID) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - } - - if (fcb->b2bccb && (call_id == fcb->b2bccb->cnf_call_id)) { - - if (other_call_id != CC_NO_CALL_ID) { - /* - * Not clearing consulation call, so change consultation - * call attribute to display connected softkey set. - * Do not change softkey set if it is a transfer o - */ - cc_call_attribute(other_call_id, other_line, NORMAL_CALL); - } - - } - /* - * Check if the user wanted to cleanup the whole ccb. - * If so, then we will grab the other fcb first and call this function - * again with this other fcb. The whole ccb will be freed after this block - * of code because both call_ids will be -1, which tells - * fsmb2bcnf_remove_fcb to free the ccb. - */ - if (both) { - if (other_call_id != CC_NO_CALL_ID) { - if (other_fcb != NULL) { - fsmb2bcnf_cleanup(other_fcb, fname, FALSE); - } - } - } - /* - * Remove the reference to this fcb from the ccb. - */ - fsmb2bcnf_remove_fcb(fcb, fcb->call_id); - - /* - * Move this fcb to the IDLE state - */ - fsm_change_state(fcb, fname, FSMB2BCNF_S_IDLE); - - /* - * Reset the data for this fcb. The fcb is still included in a call - * so set the call_id and dcb values accordingly. - */ - fsm_init_fcb(fcb, fcb->call_id, fcb->dcb, FSM_TYPE_B2BCNF); -} - - -void -fsmb2bcnf_free_cb (fim_icb_t *icb, callid_t call_id) -{ - fsm_fcb_t *fcb = NULL; - - if (call_id != CC_NO_CALL_ID) { - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_B2BCNF); - - if (fcb != NULL) { - fsmb2bcnf_cleanup(fcb, __LINE__, FALSE); - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } -} - - -/* - * fsmb2bcnf_check_if_ok_to_setup_conf - * - * Description: - * Checks if the requested call is ok to setup conference. - * - * Parameters: - * call_id - * - * Returns: TRUE - if the call is ok to setup conference - * FALSE - other cases - */ -boolean -fsmb2bcnf_check_if_ok_to_setup_conf (callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - if (call_id == CC_NO_CALL_ID) { - return (FALSE); - } - - dcb = fsm_get_dcb(call_id); - - if(dcb && dcb->policy == CC_POLICY_CHAPERONE - && dcb->is_conf_call == TRUE){ - return (FALSE); - } - - return (TRUE); -} - - -/* - * fsmb2bcnf_b2bcnf_invoke - * - * Description: - * This function implements the conference feature invocation. - * If the feature is already invoked and waiting for the - * feature ack back from the SIP stack then no action taken. - * Otherwise, the conf feature is invoked and state is SET. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with this call - * - * Returns: None - */ -static void -fsmb2bcnf_cnf_invoke (callid_t call_id, callid_t target_call_id, - line_t line, fsmcnf_ccb_t *ccb) -{ - sipspi_msg_t subscribe_msg; - ccsip_event_data_t *evt_data; - - /* - * post SIPSPI_EV_CC_SUBSCRIBE to SIP stack - */ - evt_data = (ccsip_event_data_t *) - cpr_malloc(sizeof(ccsip_event_data_t)); - if (evt_data == NULL) { - return; - } - memset(evt_data, 0, sizeof(ccsip_event_data_t)); - evt_data->type = EVENT_DATA_REMOTECC_REQUEST; - evt_data->u.remotecc_data.line = 0; - evt_data->u.remotecc_data.rcc_request_type = RCC_SOFTKEY_EVT; - evt_data->u.remotecc_data.rcc_int.rcc_softkey_event_msg.softkeyevent = RCC_SOFTKEY_CONFERENCE; - evt_data->u.remotecc_data.consult_gsm_id = target_call_id; - evt_data->u.remotecc_data.gsm_id = call_id; - - memset(&subscribe_msg, 0, sizeof(sipspi_msg_t)); - subscribe_msg.msg.subscribe.eventPackage = CC_SUBSCRIPTIONS_REMOTECC; - subscribe_msg.msg.subscribe.sub_id = CCSIP_SUBS_INVALID_SUB_ID; - subscribe_msg.msg.subscribe.auto_resubscribe = TRUE; - subscribe_msg.msg.subscribe.request_id = (long)ccb; - subscribe_msg.msg.subscribe.duration = 60; - subscribe_msg.msg.subscribe.subsNotCallbackTask = CC_SRC_GSM; - subscribe_msg.msg.subscribe.subsResCallbackMsgID = SUB_MSG_B2BCNF_SUBSCRIBE_RESP; - subscribe_msg.msg.subscribe.subsNotIndCallbackMsgID = SUB_MSG_B2BCNF_NOTIFY; - subscribe_msg.msg.subscribe.subsTermCallbackMsgID = SUB_MSG_B2BCNF_TERMINATE; - subscribe_msg.msg.subscribe.norefersub = FALSE; - subscribe_msg.msg.subscribe.eventData = evt_data; - subscribe_msg.msg.subscribe.dn_line = line; - - (void)sub_int_subscribe(&subscribe_msg); -} - -/** - * - * Cancel b2b conference feature by sending cancel event to SIP stack. - * This routine is used in roundtable phone. - * - * @param line, call_id, target_call_id, cause (implicit or explicit) - * - * @return void - * - * @pre (none) - */ -void -fsmb2bcnf_feature_cancel (fsmcnf_ccb_t *ccb, line_t line, callid_t call_id, - callid_t target_call_id, - cc_rcc_skey_evt_type_e cause) -{ - cc_feature_data_t data; - fsm_fcb_t *fcb_def; - - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - if ((cause == CC_SK_EVT_TYPE_EXPLI) && - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - fcb_def = fsm_get_fcb_by_call_id_and_type(target_call_id, FSM_TYPE_DEF); - - if ((cause == CC_SK_EVT_TYPE_EXPLI) && - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, target_call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - data.cancel.target_call_id = target_call_id; - data.cancel.call_id = call_id; - data.cancel.cause = cause; - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, CC_FEATURE_CANCEL, &data); -} - -/******************************************************************* - * event functions - */ - - -static sm_rcs_t -fsmb2bcnf_ev_idle_feature (sm_event_t *event) -{ - const char *fname = "fsmb2bcnf_ev_idle_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *ftr_data = &(msg->data); - fsmdef_dcb_t *dcb = fcb->dcb; - callid_t cns_call_id; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmcnf_ccb_t *ccb; - int free_lines; - cc_feature_data_t data; - fsm_fcb_t *other_fcb, *cns_fcb; - fsm_fcb_t *fcb_def; - callid_t other_call_id; - line_t newcall_line = 0; - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_RCC: - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_B2BCONF: - /* Connect the existing call to active trasnfer state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - if (ftr_data && msg->data_valid && - (ftr_data->b2bconf.target_call_id != CC_NO_CALL_ID) - && (cns_fcb = fsm_get_fcb_by_call_id_and_type(ftr_data->b2bconf.target_call_id, - FSM_TYPE_B2BCNF)) != NULL) { - /* - * Get a new ccb and new b2bcnf id - This is the handle that will - * identify the b2bcnf. - */ - ccb = fsmb2bcnf_get_new_b2bcnf_context(call_id, line); - - if (ccb==NULL || ccb->cnf_id == FSM_NO_ID) { - return(SM_RC_END); - } - - /* Conference origination id, required later. This indicates conf is - * because of UI or because of CTI - */ - ccb->cnf_orig = src_id; - - ccb->cns_call_id = ftr_data->b2bconf.target_call_id; - fcb->b2bccb = ccb; - cns_fcb->b2bccb = ccb; - - /* Find line information for target call. - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if (fcb_def != NULL && fcb_def->dcb) { - - ccb->cns_line = fcb_def->dcb->line; - - } else { - - return(SM_RC_END); - } - - fsm_change_state(fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - fsm_change_state(cns_fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, ccb->cns_call_id, - ccb->cns_line, CC_FEATURE_B2BCONF, NULL); - return(SM_RC_END); - - } - - - /* - * This call is the conference and we are initiating a local - * conference. So: - * 1. Make sure we have a free line to open a new call plane to - * collect digits (and place call) for the consultation call, - * 2. Create a new conference context, - * 3. Place this call on hold, - * 4. Send a newcall feature back to the GSM so that the - * consultation call can be initiated. - */ - - /* - * Check for any other active features which may block - * the conference. - */ - - /* - * The call must be in the connected state to initiate a conference - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def != NULL) && (fcb_def->state != FSMDEF_S_CONNECTED)) { - break; - } - - /* - * Make sure we have a free line to start the consultation call. - */ - //CSCsz38962 don't use expline for b2bcnf call - //free_lines = lsm_get_instances_available_cnt(line, TRUE); - free_lines = lsm_get_instances_available_cnt(line, FALSE); - if (free_lines <= 0) { - /* - * No free lines - let the user know and end this request. - */ - fsm_display_no_free_lines(); - - break; - } - - newcall_line = lsm_get_newcall_line(line); - if (newcall_line == NO_LINES_AVAILABLE) { - /* - * Error Pass Limit- let the user know and end this request. - */ - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - - break; - } - - /* - * Get a new ccb and new b2bcnf id - This is the handle that will - * identify the b2bcnf. - */ - ccb = fsmb2bcnf_get_new_b2bcnf_context(call_id, line); - - if (ccb==NULL || ccb->cnf_id == FSM_NO_ID) { - break; - } - - ccb->cnf_orig = src_id; - fcb->b2bccb = ccb; - ccb->cns_line = newcall_line; - - /* - * This call needs to go on hold so we can start the consultation - * call. Indicate feature indication should be send by setting - * call info type to hold and feature reason to conference. - */ - memset(&data, 0, sizeof(data)); - data.hold.call_info.type = CC_FEAT_HOLD; - data.hold.call_info.data.hold_resume_reason = CC_REASON_CONF; - data.hold.msg_body.num_parts = 0; - data.hold.call_info.data.call_info_feat_data.protect = TRUE; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, &data); - - /* - * Initiate the consultation call. - */ - data.newcall.cause = CC_CAUSE_CONF; - cns_call_id = ccb->cns_call_id; - sstrncpy(data.newcall.global_call_id, - ftr_data->b2bconf.global_call_id, CC_GCID_LEN); - data.newcall.prim_call_id = ccb->cnf_call_id; - data.newcall.hold_resume_reason = CC_REASON_CONF; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, newcall_line, - CC_FEATURE_NEW_CALL, &data); - - FSM_DEBUG_SM(get_debug_string(FSMB2BCNF_DBG_CNF_INITIATED), - ccb->cnf_id, call_id, cns_call_id, __LINE__); - - fsm_change_state(fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - sm_rc = SM_RC_END; - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (ftr_id) */ - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_NOTIFY: - - /* Since this message is specifically for conference, msg is - * consumed here and not forwarded - */ - if ((msg->data.notify.subscription == CC_SUBSCRIPTIONS_REMOTECC) - && (msg->data.notify.data.rcc.feature == CC_FEATURE_B2BCONF)) { - sm_rc = SM_RC_END; - } - break; - case CC_FEATURE_NEW_CALL: - /* - * If this is the consultation call involved in a conference, - * then set the rest of the data required to make the conference - * happen. The data is the b2bcnf_id in the fcb. The data is set now - * because we did not have the fcb when the conference was - * initiated. The fcb is created when a new_call event is - * received by the FIM, not when a conference event is received. - * - * Or this could be the call that originated the conference and - * the person he was talking to (the conference target) has - * decided to conference the trasnferor to another party. - */ - - /* - * Ignore this event if this call is not involved in a conference. - */ - ccb = fsmb2bcnf_get_ccb_by_call_id(call_id); - if (ccb == NULL) { - break; - } - fcb->b2bccb = ccb; - - /* - * Determine what state this b2bcnf should be in (b2bcnfing or b2bcnfed). - * If the cnfrn key has only been hit once, then this call will - * be in the cnfing state. If it has been hit the second time, - * then this call should go to the cnfed state. The latter - * case only happens when the calls are conferenced and one - * of the remote ends has decided to transfer one leg of the cnf. - * And it just so happens that the other call involved in the cnf - * should match this call, so we can just use it's state to - * assign the state to this call. - */ - other_call_id = fsmb2bcnf_get_other_call_id(ccb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - - if (other_fcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"FCP not found \n", fname); - } else { - fsm_change_state(fcb, __LINE__, other_fcb->state); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmb2bcnf_ev_active_release (sm_event_t *event) -{ - - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmcnf_ccb_t *ccb = fcb->b2bccb; - - /* For round table phone wait for NOTIFY response, so do not - * clear the conf state machine - */ - if (ccb->active == FALSE) { - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup((fsm_fcb_t *) event->data, __LINE__, TRUE); - } - - return (SM_RC_CONT); -} - -static sm_rcs_t -fsmb2bcnf_ev_active_release_complete (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmcnf_ccb_t *ccb = fcb->b2bccb; - - if (ccb->active == FALSE) { - - - fsmb2bcnf_cleanup((fsm_fcb_t *) event->data, __LINE__, TRUE); - } - - return (SM_RC_CONT); -} - -static sm_rcs_t -fsmb2bcnf_ev_active_feature (sm_event_t *event) -{ - static const char fname[] = "fsmb2bcnf_ev_active_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = fcb->b2bccb; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *feat_data = &(msg->data); - sm_rcs_t sm_rc = SM_RC_CONT; - callid_t other_call_id; - fsmdef_dcb_t *other_dcb; - fsm_fcb_t *other_fcb; - cc_action_data_t action_data; - fsm_fcb_t *cnf_fcb = NULL; - - fsm_sm_ftr(ftr_id, src_id); - - memset(&action_data, 0, sizeof(cc_action_data_t)); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_RCC: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_CANCEL: - sm_rc = SM_RC_END; - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, - CC_SK_EVT_TYPE_EXPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_HOLD: - /* Do not send out protect parameter for CTI generated conference - * and send protect=true for swap or hold call - */ - if ((msg->data_valid) && - (feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_SWAP || - feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_CONF || - feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_INTERNAL)) - { - feat_data->hold.call_info.data.call_info_feat_data.protect = TRUE; - } else if ((msg->data_valid) && - (feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_RCC)) { - //Do nothing remote-cc will terminate the feature layer. - - } else { - DEF_DEBUG(DEB_F_PREFIX"Invoke hold call_id = %d t_call_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, ccb->cns_call_id); - //Actual hold to this call, so break the feature layer. - ui_terminate_feature(ccb->cnf_line, ccb->cnf_call_id, ccb->cns_call_id); - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - } - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - case CC_FEATURE_B2BCONF: - /* Connect the existing call to active trasnfer state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - DEF_DEBUG(DEB_F_PREFIX"ACTIVE CNF call_id = %d, t_id = %d, cns_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, - feat_data->b2bconf.target_call_id, ccb->cns_call_id); - - if (feat_data && msg->data_valid && - (feat_data->b2bconf.target_call_id != CC_NO_CALL_ID)) { - /* End existing consult call and then link another - * call with the trasfer. This is the case where User can - * select active call instead of consultative call - */ - cnf_fcb = fsm_get_fcb_by_call_id_and_type(ccb->cns_call_id, - FSM_TYPE_DEF); - - /* If the call_id is different then active call has been picked - */ - - if (ccb->cns_call_id != feat_data->b2bconf.target_call_id) { - - cnf_fcb = fsm_get_fcb_by_call_id_and_type(ccb->cns_call_id, - FSM_TYPE_B2BCNF); - - if (cnf_fcb != NULL) { - DEF_DEBUG(DEB_F_PREFIX"INVOKE ACTIVE CNF call_id = %d, t_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, - feat_data->b2bconf.target_call_id); - - cnf_fcb->b2bccb = ccb; - fsm_change_state(cnf_fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, ccb->cns_call_id, - ccb->cnf_line, CC_FEATURE_B2BCONF, NULL); - } - - return(SM_RC_END); - } - } - /* - * This is the second conference event for a local - * attended conference with consultation. - * - * The user is attempting to complete the conference, so - * resume the other leg of the conference call. - */ - ccb->active = TRUE; - - if (dcb) { - dcb->active_feature = CC_FEATURE_B2BCONF; - } - - other_call_id = fsmb2bcnf_get_other_call_id(ccb, call_id); - other_dcb = fsm_get_dcb(other_call_id); - - //Update confinvoked value through JPlatUi method. - ui_update_conf_invoked(other_dcb->line, other_call_id, TRUE); - - fsmb2bcnf_cnf_invoke(fsmb2bcnf_get_other_call_id(ccb, call_id), - call_id, other_dcb->line, ccb); - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - - fsm_change_state(other_fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - fsm_change_state(fcb, __LINE__, FSMB2BCNF_S_ACTIVE); - - sm_rc = SM_RC_END; - - break; - - case CC_FEATURE_END_CALL: - /* Release ccbs related to conference and allow event to pass through - * fsmdef - */ - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - - break; - - - case CC_FEATURE_RESUME: - /* to achieve SCCP phone behaviour, if the 1st call is resumed - * then conference should be terminated. - */ - if (ccb->cnf_orig == CC_SRC_RCC) { - if (ccb->cnf_call_id == call_id) { - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - ((cc_state_data_t *) (&(dcb->caller_id)))); - } - } - break; - - case CC_FEATURE_NOTIFY: - - if ((msg->data.notify.subscription == CC_SUBSCRIPTIONS_REMOTECC) - && (msg->data.notify.data.rcc.feature == CC_FEATURE_B2BCONF)) { - - if (msg->data.notify.cause_code != RCC_SUCCESS) { - fsmb2bcnf_feature_cancel(fcb->b2bccb, fcb->b2bccb->cnf_line, - fcb->b2bccb->cnf_call_id, - fcb->b2bccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - } - /* - * Conference key press has been accepted, so now terminate the - * conference data structures. This call is now same as any other - * regular call. All the future events are handled by fsmdef. - */ - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - sm_rc = SM_RC_END; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALL_PRESERVATION: - DEF_DEBUG(DEB_F_PREFIX"Invoke hold call_id = %d t_call_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, ccb->cns_call_id); - //Actual hold to this call, so break the feature layer. - ui_terminate_feature(ccb->cnf_line, ccb->cnf_call_id, ccb->cns_call_id); - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (sm_rc); -} - -static sm_rcs_t -fsmb2bcnf_ev_active_feature_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - callid_t call_id = msg->call_id; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - sm_rcs_t sm_rc = SM_RC_CONT; - cc_action_data_t data; - callid_t other_call_id; - callid_t other_ui_id; - - fsm_sm_ftr(ftr_id, src_id); - - memset(&data, 0, sizeof(cc_action_data_t)); - - switch (src_id) { - case CC_SRC_GSM: - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_B2BCONF: - /* Handle 2nd conference key press completion NOTIFY */ - if (msg->cause == CC_CAUSE_ERROR) { - other_call_id = - fsmb2bcnf_get_other_call_id(fcb->b2bccb, call_id); - - other_ui_id = lsm_get_ui_id(other_call_id); - ui_set_call_status(platform_get_phrase_index_str(CONF_CANNOT_COMPLETE), - msg->line, other_ui_id); - fsmb2bcnf_feature_cancel(fcb->b2bccb, fcb->b2bccb->cnf_line, fcb->b2bccb->cnf_call_id, - fcb->b2bccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - break; - } - - sm_rc = SM_RC_END; - break; - - case CC_FEATURE_NOTIFY: - - if ((msg->data.notify.subscription == CC_SUBSCRIPTIONS_REMOTECC) && - (msg->data.notify.data.rcc.feature == CC_FEATURE_B2BCONF)) { - - /* - * Conference key press has been accepted, so now terminate the - * conference data structures. This call is now same as any other - * regular call. All the future events are handled by fsmdef. - */ - fsmb2bcnf_cleanup(fcb, __LINE__, TRUE); - sm_rc = SM_RC_END; - } - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (sm_rc); -} - -void -fsmb2bcnf_get_sub_call_id_from_ccb(fsmcnf_ccb_t *ccb, callid_t *cnf_call_id, - callid_t *cns_call_id) -{ - static const char fname[] = "fsmb2bcnf_get_sub_call_id_from_ccb"; - - DEF_DEBUG(DEB_F_PREFIX"call_id = %d t_call_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, ccb->cns_call_id); - - *cnf_call_id = ccb->cnf_call_id; - *cns_call_id = ccb->cns_call_id; -} - -static sm_rcs_t -fsmb2bcnf_ev_active_onhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmcnf_ccb_t *ccb = fcb->b2bccb; - cc_onhook_t *msg = (cc_onhook_t *) event->msg; - - /* For RT phone active call list can be invoked during - * conf and that genertes onhook event for existing - * consult call. Conf state machine is not terminated - */ - if (msg->active_list == CC_REASON_ACTIVECALL_LIST) { - - ccb->cns_line = CC_NO_LINE; - ccb->cns_call_id = CC_NO_CALL_ID; - - } else { - fsmb2bcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmb2bcnf_cleanup((fsm_fcb_t *) event->data, __LINE__, TRUE); - } - - return (SM_RC_CONT); -} - -cc_int32_t -fsmb2bcnf_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsmcnf_ccb_t *ccb; - int i = 0; - - PR_ASSERT( i == 0 ); - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("%s", "show fsmb2bcnf\n"); - return (0); - } - - debugif_printf("%s", "\n-------------------------- FSMB2BCNF ccbs --------------------------"); - debugif_printf("%s", "\ni b2bcnf_id ccb cnf_call_id cns_call_id active bridged"); - debugif_printf("%s", "\n--------------------------------------------------------------------" - "\n"); - - FSM_FOR_ALL_CBS(ccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - debugif_printf("%-2d %-6d 0x%08p %-11d %-11d %-6d %-7d\n", - i++, ccb->cnf_id, ccb, ccb->cnf_call_id, - ccb->cns_call_id, ccb->active, ccb->bridged); - } - - return (0); -} - - -void -fsmb2bcnf_init (void) -{ - fsmcnf_ccb_t *ccb; - static const char *fname = "fsmb2bcnf_init"; - - - /* - * Initialize the ccbs. - */ - fsmb2bcnf_ccbs = (fsmcnf_ccb_t *) - cpr_malloc(sizeof(fsmcnf_ccb_t) * FSMCNF_MAX_CCBS); - - if (fsmb2bcnf_ccbs == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to allocate memory \ - forb2bcnf ccbs.\n", fname); - return; - } - - FSM_FOR_ALL_CBS(ccb, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS) { - fsmb2bcnf_init_ccb(ccb); - } - - /* - * Initialize the state/event table. - */ - g_fsmb2bcnf_sm_table.min_state = FSMB2BCNF_S_MIN; - g_fsmb2bcnf_sm_table.max_state = FSMB2BCNF_S_MAX; - g_fsmb2bcnf_sm_table.min_event = CC_MSG_MIN; - g_fsmb2bcnf_sm_table.max_event = CC_MSG_MAX; - g_fsmb2bcnf_sm_table.table = (&(fsmb2bcnf_function_table[0][0])); -} - - -callid_t -fsmb2bcnf_get_primary_call_id (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - - ccb = fsmb2bcnf_get_ccb_by_call_id(call_id); - - if (ccb && (ccb->cns_call_id == call_id)) { - return (fsmb2bcnf_get_other_call_id(ccb, call_id)); - } else { - return (CC_NO_CALL_ID); - } -} - -callid_t -fsmb2bcnf_get_consult_call_id (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - - ccb = fsmb2bcnf_get_ccb_by_call_id(call_id); - - if (ccb && ccb->cnf_call_id == call_id) { - return (fsmb2bcnf_get_other_call_id(ccb, call_id)); - } else { - return (CC_NO_CALL_ID); - } -} - -int -fsmutil_is_b2bcnf_consult_call (callid_t call_id) -{ - return fsmutil_is_cnf_consult_leg(call_id, fsmb2bcnf_ccbs, FSMCNF_MAX_CCBS); -} - -boolean -fsmb2bcnf_is_rcc_orig_b2bcnf (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - - ccb = fsmb2bcnf_get_ccb_by_call_id(call_id); - if (ccb && ccb->cnf_orig == CC_SRC_RCC) { - return TRUE; - } - - return FALSE; -} - -void -fsmb2bcnf_shutdown (void) -{ - cpr_free(fsmb2bcnf_ccbs); - fsmb2bcnf_ccbs = NULL; -} diff --git a/libs/sipcc/core/gsm/fsmcac.c b/libs/sipcc/core/gsm/fsmcac.c deleted file mode 100755 index 21c32ef81c..0000000000 --- a/libs/sipcc/core/gsm/fsmcac.c +++ /dev/null @@ -1,707 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "phntask.h" -#include "fsm.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "gsm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "debug.h" -#include "text_strings.h" -#include "sip_interface_regmgr.h" -#include "resource_manager.h" -#include "singly_link_list.h" -#include "platform_api.h" - -#define CAC_FAILURE_TIMEOUT 5 -cc_int32_t g_cacDebug = 0; - -/* CAC key */ -typedef struct { - callid_t call_id; -} cac_key_t; - - -typedef enum { - FSM_CAC_IDLE = 0, - FSM_CAC_REQ_PENDING = 1, - FSM_CAC_REQ_RESP = 2 -} fsm_cac_state_e; - -/* CAC structure to hold the data - */ -typedef struct cac_data_t { - void *msg_ptr; - callid_t call_id; - void *cac_fail_timer; - fsm_cac_state_e cac_state; - uint32_t sessions; -} cac_data_t; - -static sll_handle_t s_cac_list = NULL; - - - -/* - * Function responsible for searching the list waiting for - * bandwidth allocation. - * - * @param cac_data_t *key_p - pointer to the key. - * @param cac_data_t *cac_data - cac data. - * - * @return void - * - */ -static sll_match_e -fsm_cac_match_call_id (cac_data_t *key_p, cac_data_t *cac_data) -{ - if (cac_data->call_id == key_p->call_id) { - - return SLL_MATCH_FOUND; - } - - return SLL_MATCH_NOT_FOUND; - -} - -/* - * Function responsible to create new data information - * for cac. - * - * @param none. - * - * @return cac_data_t * - * - */ -static cac_data_t * -fsm_get_new_cac_data (void) -{ - static const char *fname="fsm_get_new_cac_data"; - cac_data_t *cac_mem; - - cac_mem = (cac_data_t *) cpr_malloc(sizeof(cac_data_t)); - - if (cac_mem == NULL) { - CAC_ERROR(CAC_F_PREFIX"No memory for CAC data.\n", - DEB_F_PREFIX_ARGS("CAC", fname)); - return (NULL); - } - - memset(cac_mem, 0, sizeof(cac_data_t)); - return (cac_mem); -} - -/** - * - * Release all cac related data. This includes timer, cac_data - * and message buffers - * - * @param cac_data cac data structure - * - * @return none. - * - * @pre (cac_data not_eq NULL) - */ - -static void -fsm_clear_cac_data (cac_data_t *cac_data) -{ - - if (cac_data->cac_fail_timer) { - (void) cprCancelTimer(cac_data->cac_fail_timer); - - (void) cprDestroyTimer(cac_data->cac_fail_timer); - } - - (void) sll_remove(s_cac_list, cac_data); - - fim_free_event(cac_data->msg_ptr); - - /* Release buffer too */ - cpr_free(cac_data->msg_ptr); - - cpr_free(cac_data); - -} - -/** - * - * Notifies the SIP stack and UI that CAC has failed. - * - * @param cac_data cac data structure - * - * @return none. - * - * @pre (cac_data not_eq NULL) - */ - -static void fsm_cac_notify_failure (cac_data_t *cac_data) -{ - const char fname[] = "fsm_cac_notify_failure"; - cc_setup_t *msg = (cc_setup_t *) cac_data->msg_ptr; - cc_msgs_t msg_id = msg->msg_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - int event_id = msg_id; - cc_srcs_t src_id = msg->src_id; - - /* Notify UI about the failure */ - lsm_ui_display_notify_str_index(STR_INDEX_NO_BAND_WIDTH); - - /* Send response from network side regarding the failure */ - if (event_id == CC_MSG_SETUP && - src_id == CC_SRC_SIP) { - DEF_DEBUG(DEB_F_PREFIX"Send CAC failure to SIP %d.\n", - DEB_F_PREFIX_ARGS("CAC", fname), cac_data->call_id); - cc_int_release(CC_SRC_GSM, CC_SRC_SIP, call_id, line, - CC_CAUSE_CONGESTION, NULL, NULL); - } else { - /* If the cac failed, GSM is not spinning yet, so just send the - * information to UI in this case. Other case, where GSM receives event - * will send the information from GSM. - * If the UI is not cleaned up, session infomation is not cleared. - */ - ui_call_state(evOnHook, line, call_id, CC_CAUSE_CONGESTION); - } - -} - -/** - * - * Initialize the cac timer. This timer is responsible for cleanup if the - * cac response is not received from lower layer. - * - * @param cac_data cac data structure - * timeout specify the time out in sec - * - * @return true if the timer is created scuccessfully. - * false if the timer is not created. - * - * @pre (cac_data not_eq NULL) - */ - -static boolean -fsm_init_cac_failure_timer(cac_data_t *cac_data, uint32_t timeout) -{ - const char fname[] = "fsm_init_cac_failure_timer"; - - CAC_DEBUG(DEB_F_PREFIX"cac_data call_id=%x\n", - DEB_F_PREFIX_ARGS("CAC", fname), - cac_data->call_id); - - cac_data->cac_fail_timer = - cprCreateTimer("CAC failure timer", GSM_CAC_FAILURE_TIMER, TIMER_EXPIRATION, - gsm_msg_queue); - - if (cac_data->cac_fail_timer == NULL) { - CAC_ERROR(CAC_F_PREFIX"CAC Timer allocation failed.\n", - DEB_F_PREFIX_ARGS("CAC", fname)); - return(FALSE); - } - - (void) cprStartTimer(cac_data->cac_fail_timer, timeout * 1000, - (void *)(long)cac_data->call_id); - - return(TRUE); -} - -/** - * - * Serches through cac link list and returns cac_data - * based on call_id. This search is a singly link list search. - * - * @param call_id call_id of the call - * - * @return cac_data if found in the list - * NULL if there is no cac_data - * - * @pre (call_id not_eq CC_NO_CALL_ID) - */ - -static cac_data_t * -fsm_cac_get_data_by_call_id (callid_t call_id) -{ - const char fname[] = "fsm_cac_get_data_by_call_id"; - cac_data_t *cac_data; - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - while (cac_data != NULL) { - - if (cac_data->call_id == call_id) { - CAC_DEBUG(DEB_F_PREFIX"cac_data found call_id=%x\n", - DEB_F_PREFIX_ARGS("CAC", fname), - cac_data->call_id); - return(cac_data); - } - - cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - - } - - CAC_DEBUG(DEB_F_PREFIX"cac_data NOT found.\n", - DEB_F_PREFIX_ARGS("CAC", fname)); - return(NULL); -} - -/** - * - * Initialize cac module by enabling debugs and creating a cac list. - * - * @param void - * - * @return void - * - * @pre (NULL) - */ -void fsm_cac_init (void) -{ - const char fname[] = "fsm_cac_init"; - - - /* allocate and initialize cac list */ - s_cac_list = sll_create((sll_match_e(*)(void *, void *)) - fsm_cac_match_call_id); - - if (s_cac_list == NULL) { - CAC_ERROR(CAC_F_PREFIX"CAC list creation failed.\n", - DEB_F_PREFIX_ARGS("CAC", fname)); - - } -} - -/** - * - * clears all the entries in the cac list - * - * @param void - * - * @return void - * - * @pre (NULL) - */ -void fsm_cac_clear_list (void) -{ - const char fname[] = "fsm_cac_clear_list"; - cac_data_t *cac_data; - cac_data_t *prev_cac_data; - - DEF_DEBUG(DEB_F_PREFIX"Clear all pending CAC dat.\n", - DEB_F_PREFIX_ARGS("CAC", fname)); - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - while (cac_data != NULL) { - - prev_cac_data = cac_data; - cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - - fsm_cac_notify_failure(prev_cac_data); - fsm_clear_cac_data(prev_cac_data); - } - -} - -/** - * - * Shutdown cac module, clears all the pending cac requests - * - * @param void - * - * @return void - * - * @pre (NULL) - */ -void fsm_cac_shutdown (void) -{ - - fsm_cac_clear_list(); - - sll_destroy(s_cac_list); - - s_cac_list = NULL; -} - -/** - * - * Check if there are pending CAC requests - * - * @param none - * - * @return cac_data returns first pending request. - * - * @pre (NULL) - */ -static cac_data_t * -fsm_cac_check_if_pending_req (void) -{ - cac_data_t *cac_data; - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - while (cac_data != NULL) { - - if (cac_data->cac_state == FSM_CAC_REQ_PENDING || - cac_data->cac_state == FSM_CAC_IDLE) { - - return(cac_data); - } - - cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - - } - - return(NULL); -} - -/** - * - * Check if there are pending CAC requests - * - * @param none - * - * @return cac_data returns first pending request. - * - * @pre (NULL) - */ -static cc_causes_t -fsm_cac_process_bw_allocation (cac_data_t *cac_data) -{ - const char fname[] = "fsm_cac_process_bw_allocation"; - - if (lsm_allocate_call_bandwidth(cac_data->call_id, cac_data->sessions) == - CC_CAUSE_CONGESTION) { - - DEF_DEBUG(DEB_F_PREFIX"CAC Allocation failed.\n", - DEB_F_PREFIX_ARGS("CAC", fname)); - - fsm_cac_notify_failure(cac_data); - - fsm_clear_cac_data(cac_data); - - return(CC_CAUSE_CONGESTION); - } - - cac_data->cac_state = FSM_CAC_REQ_PENDING; - - return(CC_CAUSE_OK); -} - -/** - * - * Check if there are pending CAC requests - * - * @param call_id request a cac for this call_id - * sessions number of sessions in the request - * msg ccapi msg, that is held to process - * till cac response is received. - * - * @return CC_CAUSE_BW_OK if the bandwidth is received. - * CC_CAUSE_Ok Call returned successfully, not sure about BW yet - * CC_CAUSE_ERROR: Call returned with failure. - * - * @pre (NULL) - */ -cc_causes_t -fsm_cac_call_bandwidth_req (callid_t call_id, uint32_t sessions, - void *msg) -{ - const char fname[] = "fsm_cac_call_bandwidth_req"; - cac_data_t *cac_data, *cac_pend_data; - - /* If wlan not connected return OK */ - cac_data = fsm_get_new_cac_data(); - - if (cac_data == NULL) { - - return(CC_CAUSE_CONGESTION); - } - - cac_data->msg_ptr = msg; - cac_data->call_id = call_id; - cac_data->cac_state = FSM_CAC_IDLE; - cac_data->sessions = sessions; - - fsm_init_cac_failure_timer(cac_data, CAC_FAILURE_TIMEOUT); - - /* Make sure there is no pending requests before submitting - * another one - */ - if ((cac_pend_data = fsm_cac_check_if_pending_req()) == NULL) { - - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - DEF_DEBUG(DEB_F_PREFIX"CAC request for %d sessions %d.\n", - DEB_F_PREFIX_ARGS("CAC", fname), call_id, sessions); - - if (fsm_cac_process_bw_allocation(cac_data) == CC_CAUSE_CONGESTION) { - - return(CC_CAUSE_CONGESTION); - } - - cac_data->cac_state = FSM_CAC_REQ_PENDING; - - } else if (cac_pend_data->cac_state == FSM_CAC_IDLE) { - - if (fsm_cac_process_bw_allocation(cac_pend_data) == - CC_CAUSE_CONGESTION) { - - /* Clear all remaining data */ - fsm_cac_clear_list(); - - return(CC_CAUSE_CONGESTION); - } - - } - - (void) sll_append(s_cac_list, cac_data); - - return(CC_CAUSE_OK); - -} - -/** - * - * This is called by gsm to cleanup the cac data. If there are any - * pending CAC requests and far end cancels the call, the pending - * request has to be canceled. - * - * @param call_id - call_id of the request - * - * @return none. - * - * @pre (NULL) - */ -void fsm_cac_call_release_cleanup (callid_t call_id) -{ - cac_data_t *cac_data; - - cac_data = fsm_cac_get_data_by_call_id(call_id); - - if (cac_data) { - - sll_remove(s_cac_list, cac_data); - - fsm_clear_cac_data(cac_data); - } - -} - - -/** - * - * Called when the bandwidth response with available bw is received. This - * also process held ccapi messages through fim event chain - * - * @param none - * - * @return CC_CAUSE_NO_RESOURCE No bandwidth - * CC_CAUSE_OK if ok - * - * - * @pre (NULL) - */ - -cc_causes_t -fsm_cac_process_bw_avail_resp (void) -{ - const char fname[] = "fsm_cac_process_bw_avail_resp"; - cac_data_t *cac_data = NULL; - cac_data_t *next_cac_data = NULL; - - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - if (cac_data != NULL) { - - switch (cac_data->cac_state) { - default: - case FSM_CAC_IDLE: - DEF_DEBUG(DEB_F_PREFIX"No Pending CAC request.\n", - DEB_F_PREFIX_ARGS("CAC", fname)); - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - if (fsm_cac_process_bw_allocation(cac_data) == CC_CAUSE_CONGESTION) { - - sll_remove(s_cac_list, cac_data); - - return(CC_CAUSE_NO_RESOURCE); - } - - - break; - case FSM_CAC_REQ_PENDING: - - next_cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - sll_remove(s_cac_list, cac_data); - - /* Request for the next bandwidth */ - DEF_DEBUG(DEB_F_PREFIX"Process pending responses %d.\n", - DEB_F_PREFIX_ARGS("CAC", fname), cac_data->call_id); - - /* Let GSM process completed request */ - fim_process_event(cac_data->msg_ptr, TRUE); - - fsm_clear_cac_data(cac_data); - - if (next_cac_data != NULL) { - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - DEF_DEBUG(DEB_F_PREFIX"Requesting next allocation %d.\n", - DEB_F_PREFIX_ARGS("CAC", fname), next_cac_data->call_id); - - if (fsm_cac_process_bw_allocation(next_cac_data) == - CC_CAUSE_CONGESTION) { - - /* If the next data was in idle state and the request fialed - * then clean up the remaining list - */ - if (next_cac_data->cac_state == FSM_CAC_IDLE) { - /* Clear all remaining data */ - fsm_cac_clear_list(); - } else { - - sll_remove(s_cac_list, next_cac_data); - } - - return(CC_CAUSE_NO_RESOURCE); - } - - } - - break; - } - - } - - return(CC_CAUSE_NO_RESOURCE); - -} - -/** - * - * Called when the bandwidth response with failed bw is received. This - * also process held ccapi messages through fim event chain - * - * @param none - * - * @return CC_CAUSE_NO_RESOURCE No bandwidth - * CC_CAUSE_OK if ok - * - * - * @pre (NULL) - */ -cc_causes_t -fsm_cac_process_bw_failed_resp (void) -{ - const char fname[] = "fsm_cac_process_bw_avail_resp"; - cac_data_t *cac_data = NULL; - cac_data_t *next_cac_data = NULL; - - - cac_data = (cac_data_t *) sll_next(s_cac_list, NULL); - - if (cac_data != NULL) { - - switch (cac_data->cac_state) { - default: - case FSM_CAC_IDLE: - DEF_DEBUG(DEB_F_PREFIX"No Pending request.\n", - DEB_F_PREFIX_ARGS("CAC", fname)); - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - if (fsm_cac_process_bw_allocation(cac_data) == CC_CAUSE_CONGESTION) { - - sll_remove(s_cac_list, cac_data); - - return(CC_CAUSE_NO_RESOURCE); - } - - break; - case FSM_CAC_REQ_PENDING: - - next_cac_data = (cac_data_t *) sll_next(s_cac_list, cac_data); - - sll_remove(s_cac_list, cac_data); - - /* Request for the next bandwidth */ - DEF_DEBUG(DEB_F_PREFIX"Process pending responses even after failure.\n", - DEB_F_PREFIX_ARGS("CAC", fname)); - - /* Let GSM process completed request */ - fsm_cac_notify_failure(cac_data); - - fsm_clear_cac_data(cac_data); - - if (next_cac_data != NULL) { - - /* - * Make sure sufficient bandwidth available to make a outgoing call. This - * should be done before allocating other resources. - */ - if (fsm_cac_process_bw_allocation(next_cac_data) == CC_CAUSE_CONGESTION) { - - /* If the next data was in idle state and the request fialed - * then clean up the remaining list - */ - if (next_cac_data->cac_state == FSM_CAC_IDLE) { - /* Clear all remaining data */ - fsm_cac_clear_list(); - } else { - - sll_remove(s_cac_list, next_cac_data); - } - - return(CC_CAUSE_NO_RESOURCE); - } - - } - - break; - } - - } - - return(CC_CAUSE_NO_RESOURCE); -} - -/** - * - * Process time-out event. This cause cac data to send failure notifications. - * - * @param void *tmr_data - timer data - * - * @return none - * - * - * @pre (NULL) - */ -void -fsm_cac_process_bw_fail_timer (void *tmr_data) -{ - const char fname[] = "fsm_cac_process_bw_fail_timer"; - - DEF_DEBUG(DEB_F_PREFIX"CAC request timedout %d.\n", - DEB_F_PREFIX_ARGS("CAC", fname), (callid_t)(long)tmr_data); - - /* Time-out causes same set of processing as bw failure - */ - fsm_cac_process_bw_failed_resp(); - -} - diff --git a/libs/sipcc/core/gsm/fsmcnf.c b/libs/sipcc/core/gsm/fsmcnf.c deleted file mode 100755 index 3f27e30eb1..0000000000 --- a/libs/sipcc/core/gsm/fsmcnf.c +++ /dev/null @@ -1,1750 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_stdio.h" -#include "fsm.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "config.h" -#include "debug.h" -#include "gsm_sdp.h" -#include "regmgrapi.h" -#include "platform_api.h" - -static fsmcnf_ccb_t *fsmcnf_ccbs; - -static int softkey_mask_list[MAX_SOFT_KEYS]; - -#define FSMCNF_CONNECTED_SET "CONNECTED" - -typedef enum { - FSMCNF_S_MIN = -1, - FSMCNF_S_IDLE, - FSMCNF_S_CNFING, - FSMCNF_S_CNFED, - FSMCNF_S_MAX -} fsmcnf_states_t; - -static const char *fsmcnf_state_names[] = { - "IDLE", - "CNFING", - "CNFED" -}; - - -static sm_rcs_t fsmcnf_ev_idle_setup(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_idle_feature(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfing_release(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfing_feature(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfing_onhook(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfed_release(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfed_feature(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfed_feature_ack(sm_event_t *event); -static sm_rcs_t fsmcnf_ev_cnfed_onhook(sm_event_t *event); - -static sm_function_t fsmcnf_function_table[FSMCNF_S_MAX][CC_MSG_MAX] = -{ -/* FSMCNF_S_IDLE ------------------------------------------------------------ */ - { - /* FSMCNF_E_SETUP */ fsmcnf_ev_idle_setup, - /* FSMCNF_E_SETUP_ACK */ NULL, - /* FSMCNF_E_PROCEEDING */ NULL, - /* FSMCNF_E_ALERTING */ NULL, - /* FSMCNF_E_CONNECTED */ NULL, - /* FSMCNF_E_CONNECTED_ACK */ NULL, - /* FSMCNF_E_RELEASE */ NULL, - /* FSMCNF_E_RELEASE_COMPLETE */ NULL, - /* FSMCNF_E_FEATURE */ fsmcnf_ev_idle_feature, - /* FSMCNF_E_FEATURE_ACK */ NULL, - /* FSMCNF_E_OFFHOOK */ NULL, - /* FSMCNF_E_ONHOOK */ NULL, - /* FSMCNF_E_LINE */ NULL, - /* FSMCNF_E_DIGIT_BEGIN */ NULL, - /* FSMCNF_E_DIGIT */ NULL, - /* FSMCNF_E_DIALSTRING */ NULL, - /* FSMCNF_E_MWI */ NULL, - /* FSMCNF_E_SESSION_AUDIT */ NULL - }, - -/* FSMCNF_S_CNFING --------------------------------------------------- */ - { - /* FSMCNF_E_SETUP */ NULL, - /* FSMCNF_E_SETUP_ACK */ NULL, - /* FSMCNF_E_PROCEEDING */ NULL, - /* FSMCNF_E_ALERTING */ NULL, - /* FSMCNF_E_CONNECTED */ NULL, - /* FSMCNF_E_CONNECTED_ACK */ NULL, - /* FSMCNF_E_RELEASE */ fsmcnf_ev_cnfing_release, - /* FSMCNF_E_RELEASE_COMPLETE */ NULL, - /* FSMCNF_E_FEATURE */ fsmcnf_ev_cnfing_feature, - /* FSMCNF_E_FEATURE_ACK */ NULL, - /* FSMCNF_E_OFFHOOK */ NULL, - /* FSMCNF_E_ONHOOK */ fsmcnf_ev_cnfing_onhook, - /* FSMCNF_E_LINE */ NULL, - /* FSMCNF_E_DIGIT_BEGIN */ NULL, - /* FSMCNF_E_DIGIT */ NULL, - /* FSMCNF_E_DIALSTRING */ NULL, - /* FSMCNF_E_MWI */ NULL, - /* FSMCNF_E_SESSION_AUDIT */ NULL - }, - -/* FSMCNF_S_CNFED ---------------------------------------------------- */ - { - /* FSMCNF_E_SETUP */ NULL, - /* FSMCNF_E_SETUP_ACK */ NULL, - /* FSMCNF_E_PROCEEDING */ NULL, - /* FSMCNF_E_ALERTING */ NULL, - /* FSMCNF_E_CONNECTED */ NULL, - /* FSMCNF_E_CONNECTED_ACK */ NULL, - /* FSMCNF_E_RELEASE */ fsmcnf_ev_cnfed_release, - /* FSMCNF_E_RELEASE_COMPLETE */ NULL, - /* FSMCNF_E_FEATURE */ fsmcnf_ev_cnfed_feature, - /* FSMCNF_E_FEATURE_ACK */ fsmcnf_ev_cnfed_feature_ack, - /* FSMCNF_E_OFFHOOK */ NULL, - /* FSMCNF_E_ONHOOK */ fsmcnf_ev_cnfed_onhook, - /* FSMCNF_E_LINE */ NULL, - /* FSMCNF_E_DIGIT_BEGIN */ NULL, - /* FSMCNF_E_DIGIT */ NULL, - /* FSMCNF_E_DIALSTRING */ NULL, - /* FSMCNF_E_MWI */ NULL, - /* FSMCNF_E_SESSION_AUDIT */ NULL - } -}; - -static sm_table_t fsmcnf_sm_table; -sm_table_t *pfsmcnf_sm_table = &fsmcnf_sm_table; - - -const char * -fsmcnf_state_name (int state) -{ - if ((state <= FSMCNF_S_MIN) || (state >= FSMCNF_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsmcnf_state_names[state]); -} - - -static int -fsmcnf_get_new_cnf_id (void) -{ - static int cnf_id = 0; - - if (++cnf_id < 0) { - cnf_id = 1; - } - - return (cnf_id); -} - - -static void -fsmcnf_init_ccb (fsmcnf_ccb_t *ccb) -{ - if (ccb != NULL) { - ccb->cnf_id = FSM_NO_ID; - ccb->cnf_call_id = CC_NO_CALL_ID; - ccb->cns_call_id = CC_NO_CALL_ID; - ccb->cnf_line = CC_NO_LINE; - ccb->cns_line = CC_NO_LINE; - ccb->bridged = FALSE; - ccb->active = FALSE; - ccb->flags = 0; - ccb->cnf_ftr_ack = FALSE; - } -} - - -static fsmcnf_ccb_t * -fsmcnf_get_ccb_by_cnf_id (int cnf_id) -{ - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *ccb_found = NULL; - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, FSMCNF_MAX_CCBS) { - if (ccb->cnf_id == cnf_id) { - ccb_found = ccb; - - break; - } - } - - return (ccb_found); -} - - -/* - * Function: fsmcnf_get_new_cnf_context - * - * Parameters: - * cnf_call_id: call_id for the call initiating the conference - * - * Description: This function creates a new conference context by: - * - getting a free ccb - * - creating new cnf_id and cns_call_id - * - * Returns: ccb - * - */ -static fsmcnf_ccb_t * -fsmcnf_get_new_cnf_context (callid_t cnf_call_id) -{ - static const char fname[] = "fsmcnf_get_new_cnf_context"; - fsmcnf_ccb_t *ccb; - - ccb = fsmcnf_get_ccb_by_cnf_id(FSM_NO_ID); - if (ccb != NULL) { - ccb->cnf_id = fsmcnf_get_new_cnf_id(); - ccb->cnf_call_id = cnf_call_id; - ccb->cns_call_id = cc_get_new_call_id(); - - FSM_DEBUG_SM(get_debug_string(FSMCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - } else { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to get new ccb.\n", fname); - } - - return (ccb); -} - - -fsmcnf_ccb_t * -fsmcnf_get_ccb_by_call_id (callid_t call_id) -{ - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *ccb_found = NULL; - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, FSMCNF_MAX_CCBS) { - if ((ccb->cnf_call_id == call_id) || (ccb->cns_call_id == call_id)) { - ccb_found = ccb; - - break; - } - } - - return (ccb_found); -} - - -static void -fsmcnf_update_cnf_context (fsmcnf_ccb_t *ccb, callid_t old_call_id, - callid_t new_call_id) -{ - static const char fname[] = "fsmcnf_update_cnf_context"; - - if (ccb != NULL) { - if (old_call_id == ccb->cnf_call_id) { - ccb->cnf_call_id = new_call_id; - } else if (old_call_id == ccb->cns_call_id) { - ccb->cns_call_id = new_call_id; - } - - FSM_DEBUG_SM(get_debug_string(FSMCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - } -} - - -callid_t -fsmcnf_get_other_call_id (fsmcnf_ccb_t *ccb, callid_t call_id) -{ - callid_t other_call_id = CC_NO_CALL_ID; - - if (ccb != NULL) { - if (ccb->cnf_call_id == call_id) { - other_call_id = ccb->cns_call_id; - } else if (ccb->cns_call_id == call_id) { - other_call_id = ccb->cnf_call_id; - } - } - - return (other_call_id); -} - -static void -fsmcnf_cnf_xfer (fsmcnf_ccb_t *ccb) -{ - fsmdef_dcb_t *dcb; - cc_feature_data_t ftr_data; - - dcb = fsm_get_dcb(ccb->cnf_call_id); - - /* - * Pretending attended transfer - */ - ftr_data.xfer.cause = CC_CAUSE_XFER_CNF; - ftr_data.xfer.target_call_id = ccb->cns_call_id; - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_XFER, &(ftr_data)); -} - - -/* - * Function: fsmcnf_remove_fcb - * - * Parameters: - * cnf_id: cnf_id for the conference - * call_id: call_id that identifies the fcb to be removed - * - * Description: This function will remove the fcb identified by the given - * call_id from the ccb. And the function will free the ccb - * if both fcbs have been removed. - * - * Returns: none - * - * Note: This is a helper function for fsmcnf_cleanup. It allows fsmcnf_cleanup - * to cleanup one fcb (one call involved in the conference) independent - * of the other involved fcb. - */ -static void -fsmcnf_remove_fcb (fsm_fcb_t *fcb, callid_t call_id) -{ - fsmcnf_ccb_t *ccb = fcb->ccb; - - if (ccb != NULL) { - fsmcnf_update_cnf_context(ccb, call_id, CC_NO_CALL_ID); - - /* - * Free the ccb if both fcb references have been removed. - */ - if ((ccb->cnf_call_id == CC_NO_CALL_ID) && - (ccb->cns_call_id == CC_NO_CALL_ID)) { - fsmcnf_init_ccb(ccb); - } - } -} - - -static void -fsmcnf_cleanup (fsm_fcb_t *fcb, int fname, boolean both) -{ - fsmcnf_ccb_t *ccb; - fsm_fcb_t *other_fcb, *fcb_def; - callid_t call_id = fcb->call_id; - callid_t other_call_id = CC_NO_CALL_ID; - - /* stop the channel mixing if we are currently doing it */ - ccb = fsmcnf_get_ccb_by_call_id(call_id); - other_call_id = fsmcnf_get_other_call_id(fcb->ccb, call_id); - /* Set session to be primary */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - if (fcb->ccb && (call_id == fcb->ccb->cnf_call_id)) { - - if (other_call_id != CC_NO_CALL_ID) { - /* - * Not clearing consulation call, so change consultation - * call attribute to display connected softkey set. - * Do not change softkey set if it is a transfer o - */ - if (ccb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to get CCB.\n", fname); - } else { - cc_call_attribute(other_call_id, ccb->cnf_line, NORMAL_CALL); - } - } - - } - - if (fcb_def && fcb_def->dcb) { - fcb_def->dcb->session = PRIMARY; - } - /* - * Check if the user wanted to cleanup the whole ccb. - * If so, then we will grab the other fcb first and call this function - * again with this other fcb. The whole ccb will be freed after this block - * of code because both call_ids will be -1, which tells - * fsmcnf_remove_fcb to free the ccb. - */ - if (both) { - other_call_id = fsmcnf_get_other_call_id(fcb->ccb, call_id); - if (other_call_id != CC_NO_CALL_ID) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - if (other_fcb != NULL) { - fsmcnf_cleanup(other_fcb, fname, FALSE); - } - } - } - - /* - * Remove the reference to this fcb from the ccb. - */ - fsmcnf_remove_fcb(fcb, fcb->call_id); - - /* - * Move this fcb to the IDLE state - */ - fsm_change_state(fcb, fname, FSMCNF_S_IDLE); - - /* - * Reset the data for this fcb. The fcb is still included in a call - * so set the call_id and dcb values accordingly. - */ - fsm_init_fcb(fcb, fcb->call_id, fcb->dcb, FSM_TYPE_CNF); -} - - -void -fsmcnf_free_cb (fim_icb_t *icb, callid_t call_id) -{ - fsm_fcb_t *fcb = NULL; - - if (call_id != CC_NO_CALL_ID) { - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_CNF); - - if (fcb != NULL) { - fsmcnf_cleanup(fcb, __LINE__, FALSE); - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } -} - - -/** - * - * Cancel conference feature by sending cancel event to SIP stack. - * This routine is used in roundtable phone. - * - * Copied and pasted from fsmb2bcnf_feature_cancel(). - * See also fsmxfr_feature_cancel(). - * - * @param line, call_id, target_call_id, cause (implicit or explicit) - * - * @return void - * - * @pre (none) - */ -void -fsmcnf_feature_cancel (fsmcnf_ccb_t *ccb, line_t line, callid_t call_id, - callid_t target_call_id) -{ - cc_feature_data_t data; - fsm_fcb_t *fcb_def; - - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - // 'cause' will always be CC_SK_EVT_TYPE_EXPLI for now since it's only - // called by fsmcnf_ev_cnfing_feature in the case of CC_FEAURE_CANCEL. - // Thus 'cause' is ignored (for now) until the whole SM is refactored. - if (/*(cause == CC_SK_EVT_TYPE_EXPLI) && */ - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - fcb_def = fsm_get_fcb_by_call_id_and_type(target_call_id, FSM_TYPE_DEF); - - if (/* (cause == CC_SK_EVT_TYPE_EXPLI) && */ - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, target_call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - data.cancel.target_call_id = target_call_id; - data.cancel.call_id = call_id; - data.cancel.cause = CC_SK_EVT_TYPE_EXPLI; - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, CC_FEATURE_CANCEL, &data); -} - -/******************************************************************* - * event functions - */ - - -static sm_rcs_t -fsmcnf_ev_idle_setup (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_setup_t *msg = (cc_setup_t *) event->msg; - callid_t call_id = msg->call_id; - fsmcnf_ccb_t *ccb; - - if (!msg->replaces) { - return (SM_RC_DEF_CONT); - } - - /* - * Check to see if this new setup call is a new call that replaces - * one of the conferenced call i.e. the this new call replacing the - * existing leg of a conferenced by XFER feature from SIP. The - * call id of this setup should match call id of a conference. - */ - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb == NULL) { - return (SM_RC_DEF_CONT); - } - - /* This new call is part of a conference */ - fcb->ccb = ccb; /* attach ccb to the new call chain */ - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFING); - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmcnf_ev_idle_feature (sm_event_t *event) -{ - static const char *fname = "fsmcnf_ev_idle_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - fsmdef_dcb_t *dcb = fcb->dcb; - callid_t cns_call_id; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmcnf_ccb_t *ccb; - int free_lines; - cc_feature_data_t data; - cc_action_data_t action_data; - fsmdef_dcb_t *other_dcb; - fsm_fcb_t *other_fcb; - fsm_fcb_t *fcb_def, *join_fcb_cnf; - cc_feature_data_t ftr_data = msg->data; - cc_feature_data_t *feat_data = &(msg->data); - fsm_fcb_t *cns_fcb; - callid_t other_call_id; - fsmxfr_xcb_t *xcb; - cc_causes_t cause; - - memset(&data, 0, sizeof(cc_feature_data_t)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_CONF: - - /* Connect the existing call to active conference state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - if (feat_data && msg->data_valid && - (feat_data->cnf.target_call_id != CC_NO_CALL_ID) - && (cns_fcb = fsm_get_fcb_by_call_id_and_type(feat_data->cnf.target_call_id, - FSM_TYPE_CNF)) != NULL) { - /* - * Get a new ccb and new b2bcnf id - This is the handle that will - * identify the b2bcnf. - */ - ccb = fsmcnf_get_new_cnf_context(feat_data->cnf.target_call_id); - - if (ccb == NULL || ccb->cnf_id == FSM_NO_ID) { - return(SM_RC_END); - } - - ccb->cns_call_id = call_id; - fcb->ccb = ccb; - cns_fcb->ccb = ccb; - ccb->cnf_line = line; - ccb->cns_line = line; - - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFING); - - fsm_change_state(cns_fcb, __LINE__, FSMCNF_S_CNFING); - - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, ccb->cns_call_id, - cns_fcb->dcb->line, CC_FEATURE_CONF, NULL); - return(SM_RC_END); - - } - - /* - * This call is the conference and we are initiating a local - * conference. So: - * 1. Make sure we have a free line to open a new call plane to - * collect digits (and place call) for the consultation call, - * 2. Create a new conference context, - * 3. Place this call on hold, - * 4. Send a newcall feature back to the GSM so that the - * consultation call can be initiated. - */ - - /* - * Check for any other active features which may block - * the conference. - */ - - /* - * The call must be in the connected state to initiate a conference. - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def != NULL) && (fcb_def->state != FSMDEF_S_CONNECTED)) { - break; - } - - /* - * Make sure we have a free line to start the consultation call. - */ - //CSCsz38962 don't use expline for local conf call - //free_lines = lsm_get_instances_available_cnt(line, TRUE); - free_lines = lsm_get_instances_available_cnt(line, FALSE); - if (free_lines <= 0) { - /* - * No free lines - let the user know and end this request. - */ - fsm_display_no_free_lines(); - - break; - } - - /* - * Get a new ccb and new cnf id - This is the handle that will - * identify the cnf. - */ - ccb = fsmcnf_get_new_cnf_context(call_id); - if (ccb == NULL || ccb->cnf_id == 0) { - break; - } - fcb->ccb = ccb; - ccb->cnf_line = line; - ccb->cns_line = line; - - /* - * This call needs to go on hold so we can start the consultation - * call. Indicate feature indication should be send by setting - * call info type to hold and feature reason to conference. - */ - data.hold.call_info.type = CC_FEAT_HOLD; - data.hold.call_info.data.hold_resume_reason = CC_REASON_CONF; - data.hold.msg_body.num_parts = 0; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, &data); - - /* - * Initiate the consultation call. - */ - data.newcall.cause = CC_CAUSE_CONF; - cns_call_id = ccb->cns_call_id; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, line, - CC_FEATURE_NEW_CALL, &data); - - FSM_DEBUG_SM(get_debug_string(FSMCNF_DBG_CNF_INITIATED), - ccb->cnf_id, call_id, cns_call_id, __LINE__); - - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFING); - - sm_rc = SM_RC_END; - - break; - - case CC_FEATURE_JOIN: - /* - * The call must be in the connected state to initiate a conference - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def != NULL) && (fcb_def->state != FSMDEF_S_CONNECTED)) { - break; - } - - /* - * Make sure that we have another active call on this line. - */ - other_dcb = fsmdef_get_other_dcb_by_line(call_id, dcb->line); - if (other_dcb == NULL) { - break; - } - - /* get other calls FCB */ - other_fcb = fsm_get_fcb_by_call_id_and_type(other_dcb->call_id, - FSM_TYPE_DEF); - if (other_fcb == NULL) { - break; - } - - if (other_fcb->state == FSMDEF_S_HOLDING) { - /* - * Get a new ccb and new cnf id - This is the handle that will - * identify the cnf. - */ - ccb = fsmcnf_get_new_cnf_context(call_id); - if (ccb == NULL) { - break; - } - fcb->ccb = ccb; - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFED); - - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_dcb->call_id, - FSM_TYPE_CNF); - if (other_fcb == NULL) { - fsmcnf_cleanup(fcb, __LINE__, TRUE); - break; - } - other_fcb->ccb = ccb; - fsm_change_state(other_fcb, __LINE__, FSMCNF_S_CNFED); - - ccb->cnf_call_id = dcb->call_id; - ccb->cns_call_id = other_dcb->call_id; - ccb->bridged = TRUE; - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(other_dcb, - &data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - sm_rc = SM_RC_END; - break; - } - data.resume.cause = CC_CAUSE_CONF; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_dcb->call_id, - other_dcb->line, CC_FEATURE_RESUME, &data); - - /* - * Update the UI for this call. - */ - action_data.update_ui.action = CC_UPDATE_CONF_ACTIVE; - (void)cc_call_action(other_dcb->call_id, other_dcb->line, - CC_ACTION_UPDATE_UI, &action_data); - } else { - fsm_display_feature_unavailable(); - } - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_NEW_CALL: - - /* - * If this is the consultation call involved in a conference, - * then set the rest of the data required to make the conference - * happen. The data is the cnf_id in the fcb. The data is set now - * because we did not have the fcb when the conference was - * initiated. The fcb is created when a new_call event is - * received by the FIM, not when a conference event is received. - * - * Or this could be the call that originated the conference and - * the person he was talking to (the conference target) has - * decided to conference the trasnferor to another party. - */ - - /* - * Ignore this event if this call is not involved in a conference. - */ - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb == NULL) { - break; - } - fcb->ccb = ccb; - - /* - * Determine what state this cnf should be in (cnfing or cnfed). - * If the cnfrn key has only been hit once, then this call will - * be in the cnfing state. If it has been hit the second time, - * then this call should go to the cnfed state. The latter - * case only happens when the calls are conferenced and one - * of the remote ends has decided to transfer one leg of the cnf. - * And it just so happens that the other call involved in the cnf - * should match this call, so we can just use it's state to - * assign the state to this call. - */ - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - - if(other_fcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to get FCB.\n", fname); - } else { - fsm_change_state(fcb, __LINE__, other_fcb->state); - } - - break; - - case CC_FEATURE_JOIN: - if (fsm_is_joining_call(ftr_data)) { - /* - * The join target call must be in the - * connected state to initiate a conference. - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, - FSM_TYPE_DEF); - if ((fcb_def == NULL) || - ((fcb_def->state != FSMDEF_S_CONNECTED) && - (fcb_def->state != FSMDEF_S_RESUME_PENDING))) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Join target \ - call is not at connected state\n", - DEB_L_C_F_PREFIX_ARGS(FSM, line, call_id, fname)); - break; - } - - /* Get the joining call fcb */ - join_fcb_cnf = fsm_get_fcb_by_call_id_and_type( - ftr_data.newcall.join.join_call_id, - FSM_TYPE_CNF); - - /* Create a conference context for the join target call */ - ccb = fsmcnf_get_new_cnf_context(call_id); - if (ccb == NULL || join_fcb_cnf == NULL) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Could not \ - find the conference context\n", - DEB_L_C_F_PREFIX_ARGS(FSM, line, call_id, fname)); - break; - } - - fcb->ccb = ccb; - join_fcb_cnf->ccb = ccb; - ccb->cnf_call_id = fcb_def->dcb->call_id; - /* Joining call is the consultative call of the conference */ - ccb->cns_call_id = join_fcb_cnf->dcb->call_id; - - join_fcb_cnf->dcb->group_id = fcb_def->dcb->group_id; - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFED); - fsm_change_state(join_fcb_cnf, __LINE__, FSMCNF_S_CNFED); - - softkey_mask_list[0] = skConfrn; - ui_select_feature_key_set(line, call_id, - FSMCNF_CONNECTED_SET, - softkey_mask_list, 1); - - ccb->flags |= JOINED; - - ccb->bridged = FALSE; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_NOTIFY: - if ((msg->data_valid == TRUE) && - (msg->data.notify.subscription == CC_SUBSCRIPTIONS_XFER) && - (msg->data.notify.method == CC_XFER_METHOD_REFER)) { - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((xcb != NULL) && (call_id == xcb->cns_call_id)) { - /* - * One leg of the conference has decided to transfer us. - * We need to - * 1. remove the transferred call from the conference - * context and associate the new call - * with the context, - * 2. cleanup this transferred fcb. - */ - ccb = fsmcnf_get_ccb_by_call_id(xcb->xfr_call_id); - if (ccb == NULL) { - break; - } - - other_fcb = - fsm_get_fcb_by_call_id_and_type(xcb->xfr_call_id, - FSM_TYPE_CNF); - if (other_fcb == NULL) { - break; - } - - fcb->ccb = ccb; - - fsmcnf_update_cnf_context(ccb, xcb->xfr_call_id, - xcb->cns_call_id); - - fsmcnf_cleanup(other_fcb, __LINE__, FALSE); - - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - - fsm_change_state(fcb, __LINE__, other_fcb->state); - - if (other_fcb->state == FSMCNF_S_CNFED) { - ccb->bridged = TRUE; - - /* - * Resume the other leg of the conference that was - * not transferred. - */ - other_dcb = fsm_get_dcb(other_call_id); - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(other_dcb, - &data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG_ERROR(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - fsmcnf_cleanup(fcb, __LINE__, TRUE); - sm_rc = SM_RC_END; - break; - } - data.resume.cause = CC_CAUSE_CONF; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - other_dcb->call_id, other_dcb->line, - CC_FEATURE_RESUME, &data); - } - - /* - * Update the UI for the just transferred leg. - */ - action_data.update_ui.action = CC_UPDATE_CONF_ACTIVE; - (void)cc_call_action(fcb->call_id, dcb->line, - CC_ACTION_UPDATE_UI, &action_data); - } - } - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static void -fsmcnf_update_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - callid_t other_call_id; - cc_action_data_t action_data; - fsm_fcb_t *other_fcb; - - /* - * Update the UI for the other call. - */ - other_call_id = fsmcnf_get_other_call_id(fcb->ccb, fcb->call_id); - if (other_call_id != CC_NO_CALL_ID) { - action_data.update_ui.action = CC_UPDATE_CONF_RELEASE; - (void)cc_call_action(other_call_id, fcb->dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - - /* Far end released its original call. Set the attribute of - * other call so it can display connected softkey set. - * - * Check only for the consultation leg since only that leg - * will need its attribute reset - the other leg does not - * have an atribute set. - */ - if (fcb->ccb && (fcb->call_id == fcb->ccb->cnf_call_id)) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - if (other_fcb != NULL) { - fsm_fcb_t *b2bcnf_fcb, *xfr_fcb; - b2bcnf_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - xfr_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - if ((b2bcnf_fcb != NULL && b2bcnf_fcb->b2bccb == NULL) && - (xfr_fcb != NULL && xfr_fcb->xcb == NULL)) { - cc_call_attribute(other_call_id, other_fcb->dcb->line, NORMAL_CALL); - } - } - } - } - - fsmcnf_cleanup(fcb, __LINE__, TRUE); -} - - -static sm_rcs_t -fsmcnf_ev_cnfing_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - callid_t call_id = msg->call_id; - fsmcnf_ccb_t *ccb = fcb->ccb; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *other_fcb; - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb != NULL) { - /* - * One leg of the conference has decided to transfer us. - * We need to - * 1. remove this call from the conference context and - * associate the new (transferred) call with the context, - * 2. cleanup this fcb. - */ - fsmcnf_update_cnf_context(ccb, call_id, xcb->cns_call_id); - - fsmcnf_cleanup(fcb, __LINE__, FALSE); - - other_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, - FSM_TYPE_CNF); - - if (other_fcb != NULL) { - other_fcb->ccb = ccb; - fsm_change_state(other_fcb, __LINE__, FSMCNF_S_CNFING); - } - - return (SM_RC_CONT); - } - - fsmcnf_update_release(event); - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmcnf_ev_cnfing_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = fcb->ccb; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - static const char fname[] = "fsmcnf_ev_cnfing_feature"; - cc_feature_data_t *feat_data = &(msg->data); - sm_rcs_t sm_rc = SM_RC_CONT; - callid_t other_call_id; - fsmdef_dcb_t *other_dcb; - fsm_fcb_t *other_fcb; - cc_action_data_t action_data; - cc_feature_data_t data; - cc_causes_t cause; - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_CANCEL: - sm_rc = SM_RC_END; - fsmcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id /*, - CC_SK_EVT_TYPE_EXPLI */); - fsmcnf_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_ANSWER: - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - if (other_call_id == CC_NO_CALL_ID) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - return (sm_rc); - } - other_dcb = fsm_get_dcb(other_call_id); - if (other_dcb == NULL) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - return (sm_rc); - } - /* - * The answer to the a setup with replaced we have received. - * The setup with replaced is automatically answered - * by xfer state machine as UI source (simulate user pressing - * the answer key). - * - * Set the group ID to the new call so that the voice can be - * mixed with the new call. - */ - dcb->group_id = other_dcb->group_id; - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFED); - return (sm_rc); - - default: - break; - } - /* Fall through */ - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_CONF: - /* - * This is the second conference event for a local - * attended conference with consultation. - * - * The user is attempting to complete the conference, so - * resume the other leg of the conference call. - */ - ccb->bridged = TRUE; - ccb->active = TRUE; - ccb->flags |= LCL_CNF; - - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - other_dcb = fsm_get_dcb(other_call_id); - - /* - * Since we are resuming the other leg, allocate the src_sdp - * because src_sdp was freed and set to null when this other-leg - * was put on hold. - */ - gsmsdp_update_local_sdp_media_capability(other_dcb, TRUE, FALSE); - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(other_dcb, - &data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG_ERROR(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - sm_rc = SM_RC_END; - break; - } - data.resume.cause = CC_CAUSE_CONF; - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_DEF); - if (other_fcb && other_fcb->state == FSMDEF_S_HOLDING) { - - other_dcb->session = LOCAL_CONF; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_dcb->call_id, - other_dcb->line, CC_FEATURE_RESUME, &data); - - } else { - /* Other call must be on hold */ - - dcb->session = LOCAL_CONF; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - ccb->cnf_line, CC_FEATURE_RESUME, &data); - - - } - - /* - * Update the UI for this call. - */ - action_data.update_ui.action = CC_UPDATE_CONF_ACTIVE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_CNF); - fsm_change_state(other_fcb, __LINE__, FSMCNF_S_CNFED); - fsm_change_state(fcb, __LINE__, FSMCNF_S_CNFED); - - sm_rc = SM_RC_END; - - break; - - case CC_FEATURE_END_CALL: - fsmcnf_update_release(event); - - break; - - case CC_FEATURE_HOLD: - if ((msg->data_valid) && - (feat_data->hold.call_info.data.hold_resume_reason != CC_REASON_SWAP && - feat_data->hold.call_info.data.hold_resume_reason != CC_REASON_CONF && - feat_data->hold.call_info.data.hold_resume_reason != CC_REASON_INTERNAL)) { - sm_rc = SM_RC_END; - DEF_DEBUG(DEB_F_PREFIX"Invoke hold call_id = %d t_call_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), ccb->cnf_call_id, ccb->cns_call_id); - //Actual hold to this call, so break the feature layer. - ui_terminate_feature(dcb->line, ccb->cnf_call_id, ccb->cns_call_id); - - fsmcnf_feature_cancel(ccb, ccb->cnf_line, ccb->cnf_call_id, - ccb->cns_call_id /*, - CC_SK_EVT_TYPE_EXPLI */); - fsmcnf_cleanup(fcb, __LINE__, TRUE); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmcnf_ev_cnfing_onhook (sm_event_t *event) -{ - fsmcnf_update_release(event); - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmcnf_ev_cnfed_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - callid_t call_id = msg->call_id; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = fcb->ccb; - callid_t other_call_id; - fsmdef_dcb_t *other_dcb; - cc_feature_data_t data; - cc_action_data_t action_data; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *other_fcb; - cc_causes_t cause; - - /* Conference is not active any more, clear that flag - */ - ccb->active = FALSE; - - if( ccb->flags & JOINED ){ - other_call_id = fsmcnf_get_other_call_id(ccb, call_id); - if(other_call_id != CC_NO_CALL_ID ){ - fsm_fcb_t *b2bcnf_fcb, *xfr_fcb; - b2bcnf_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_B2BCNF); - xfr_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - if ((b2bcnf_fcb != NULL && b2bcnf_fcb->b2bccb == NULL) && - (xfr_fcb != NULL && xfr_fcb->xcb == NULL)) { - cc_call_attribute(other_call_id, dcb->line, NORMAL_CALL); - } - } - } - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((xcb != NULL) && (!(ccb->flags & JOINED))) { - /* - * One leg of the conference has decided to transfer us. - * We need to: - * 1. remove this call from the conference context and - * associate the new (transferred) call with the context, - * 2. Resume the other leg of the conference that was not transferred. - * More than likely this leg was put on hold when the transfer - * was intitated if this was a REFER transfer. - * 3. - */ - fsmcnf_update_cnf_context(ccb, call_id, xcb->cns_call_id); - - fsmcnf_cleanup(fcb, __LINE__, FALSE); - - /* NOTE: - * Normally, we would reset the ccb->bridged flag to indicate - * that the bridge is not active. We do not want to do that in - * this case because we want the conference to bridge as soon as - * the target we are transferred to answers. - */ - - ccb->bridged = TRUE; - - /* - * Resume the other leg of the conference that was not transferred. - */ - other_call_id = fsmcnf_get_other_call_id(ccb, xcb->cns_call_id); - other_dcb = fsm_get_dcb(other_call_id); - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(other_dcb, - &data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG_ERROR(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (SM_RC_END); - } - data.resume.cause = CC_CAUSE_CONF; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_dcb->call_id, - other_dcb->line, CC_FEATURE_RESUME, &data); - - /* - * Update the UI for the just transferred leg. - */ - other_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, - FSM_TYPE_CNF); - - if (other_fcb != NULL) { - other_fcb->ccb = ccb; - - fsm_change_state(other_fcb, __LINE__, FSMCNF_S_CNFED); - - action_data.update_ui.action = CC_UPDATE_CONF_ACTIVE; - cc_call_action(other_fcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - return (SM_RC_CONT); - } - } - - fsmcnf_update_release(event); - - return (SM_RC_CONT); -} - - -static void -fsmcnf_other_feature (fsm_fcb_t *fcb, cc_features_t ftr_id) -{ - callid_t other_call_id; - - other_call_id = fsmcnf_get_other_call_id(fcb->ccb, fcb->call_id); - if (other_call_id != CC_NO_CALL_ID) { - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_call_id, - fcb->dcb->line, ftr_id, NULL); - } -} - - -static sm_rcs_t -fsmcnf_ev_cnfed_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmcnf_ccb_t *ccb = fcb->ccb; - fsmxfr_xcb_t *xcb; - int join = 1; - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_CANCEL: - sm_rc = SM_RC_END; - fsmcnf_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_END_CALL: - if ((ccb->flags & JOINED) && (ccb->bridged == FALSE)) { - /* Something went wrong during the barge/monitor call setup, clean up */ - fsmcnf_cleanup(fcb, __LINE__, TRUE); - return (sm_rc); - } - /* - * If bridge of conference call ends the call, other 2 - * users should still be able to talk to each other. - * So we simulate attended transfer when bridge tries - * to end the call. - */ - config_get_value(CFGID_CNF_JOIN_ENABLE, &join, sizeof(join)); - if (((ccb->bridged == TRUE) && (join) && !(ccb->flags & JOINED)) || - ((ccb->bridged == TRUE) && (ccb->flags & XFER))) { - - fsmcnf_cnf_xfer(ccb); - sm_rc = SM_RC_END; - } else { - /* - * The user is attempting to clear the call, therefore - * we need to also clear the other leg of this - * conference if it is active. - */ - fsmcnf_other_feature(fcb, ftr_id); - } - - fsmcnf_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_HOLD: - /* Don't process the Hold if we are still waiting - * on an ack from a previous Resume. - */ - if ((ccb->cnf_ftr_ack) && (src_id == CC_SRC_UI)) { - return (SM_RC_END); - } - - /* - * The user is attempting to hold the call, therefore we need - * to also hold the other leg of this conference. Only update - * the other leg if the conference is bridged and not involved - * in a transfer. - */ - if (ccb->bridged == TRUE) { - - if ((ccb->flags & XFER) && (src_id == CC_SRC_GSM)) { - fsmcnf_cleanup(fcb, __LINE__, TRUE); - return (sm_rc); - } - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((xcb == NULL) || (!(ccb->flags & XFER))) { - fsmcnf_other_feature(fcb, ftr_id); - ccb->cnf_ftr_ack = TRUE; - ccb->bridged = FALSE; - } - } - break; - - case CC_FEATURE_RESUME: - /* Don't process the Resume if we are still waiting - * on an ack from a previous Hold. - */ - if ((ccb->cnf_ftr_ack) && (src_id == CC_SRC_UI)) { - return (SM_RC_END); - } - - /* - * The user is attempting to resume the call, therefore we need - * to also resume the other leg of this conference. Only do this - * if the conference is not bridged. - */ - if (ccb->bridged == FALSE) { - fsmcnf_other_feature(fcb, ftr_id); - ccb->cnf_ftr_ack = TRUE; - ccb->bridged = TRUE; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALLINFO: - if ((ccb->flags & JOINED) && - (call_id == ccb->cns_call_id)) { - /* - * Call is already joined into, eat this call - * info event that came for the virtual bubble - */ - return (SM_RC_END); - } - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - case CC_FEATURE_XFER: - if (msg->data_valid == FALSE) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - switch (msg->data.xfer.method) { - case CC_XFER_METHOD_BYE: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - case CC_XFER_METHOD_REFER: - if ((msg->data.xfer.cause == CC_CAUSE_XFER_REMOTE) && - (msg->data.xfer.target_call_id != CC_NO_CALL_ID)) { - /* - * This operation is replacing this call leg with the - * new leg. This call is a target of a transfer. - * Replace the call id of this call with the new - * replacing call id. - */ - fsmcnf_update_cnf_context(ccb, call_id, - msg->data.xfer.target_call_id); - /* Drop this call from conferenced */ - fsmcnf_cleanup(fcb, __LINE__, FALSE); - } else { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmcnf_ev_cnfed_feature_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = fcb->ccb; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - sm_rcs_t sm_rc = SM_RC_CONT; - cc_feature_data_t ftr_data; - cc_causes_t cause; - char tmp_str[STATUS_LINE_MAX_LEN]; - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_HOLD: - /* - * HOLD request is pending. Let this event drop through - * to the default sm for handling. - */ - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } else { - ccb->cnf_ftr_ack = FALSE; - } - break; - - case CC_FEATURE_RESUME: - /* - * Resume request is pending. Let this event drop through - * to the default sm for handling. - */ - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - ccb->cnf_ftr_ack = FALSE; - - /* - * Check the status of the cause code - */ - if (msg->cause != CC_CAUSE_NORMAL) { - if ((platGetPhraseText(STR_INDEX_CNFR_FAIL_NOCODEC, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, ccb->cns_call_id, - fcb->dcb->line, CC_FEATURE_END_CALL, NULL); - - dcb = fsmdef_get_dcb_by_call_id(ccb->cnf_call_id); - if (dcb != NULL) { - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, - &ftr_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG_ERROR(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (SM_RC_END); - } - ftr_data.resume.cause = CC_CAUSE_OK; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_RESUME, &ftr_data); - } - - fsmcnf_cleanup(fcb, __LINE__, TRUE); - } - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmcnf_ev_cnfed_onhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmcnf_ccb_t *ccb = fcb->ccb; - int join = 1; - fsmdef_dcb_t *other_dcb; - boolean conf_id_valid = FALSE; - - /* If call_id of the ONHOOK received is of cnf_call_id, - * flag to dcb of cns_call_id to know of the event, - * and vice versa. We do not want to process more than - * one onhook for calls in a conf call. Note that this is - * needed because when in Speaker mode, onhook event is - * sent to each call_id in active state. - */ - if (fcb->call_id == ccb->cnf_call_id) { - other_dcb = fsm_get_dcb(ccb->cns_call_id); - } else { - other_dcb = fsm_get_dcb(ccb->cnf_call_id); - } - other_dcb->onhook_received = TRUE; - - // CSCtc04202, when conf_id_valid is FALSE,which mean at least one call is dropped - // Need release the whole conference session. - conf_id_valid = fsmcnd_conf_call_id_valid(ccb); - config_get_value(CFGID_CNF_JOIN_ENABLE, &join, sizeof(join)); - if (((ccb->bridged == TRUE) && (join) && !(ccb->flags & JOINED) && (conf_id_valid)) || - ((ccb->bridged == TRUE) && (ccb->flags & XFER) && (conf_id_valid))) { - /* - * If bridge of conference call ends the call other 2 - * users should still be able to talk to each other - * So we simulate attended transfer when bridge tries - * to end the call - */ - fsmcnf_cnf_xfer(ccb); - sm_rc = SM_RC_END; - } else { - /* - * The user is attempting to clear the call, therefore - * we need to also clear the other leg of this - * conference if it is active. - */ - fsmcnf_other_feature(fcb, CC_FEATURE_END_CALL); - } - - fsmcnf_cleanup(fcb, __LINE__, TRUE); - return (sm_rc); -} - - -cc_int32_t -fsmcnf_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsmcnf_ccb_t *ccb; - int i = 0; - - PR_ASSERT(i == 0); - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("%s", "show fsmcnf\n"); - return (0); - } - - debugif_printf("%s", "\n-------------------------- FSMCNF ccbs --------------------------"); - debugif_printf("%s", "\ni cnf_id ccb cnf_call_id cns_call_id active bridged"); - debugif_printf("%s", "\n-----------------------------------------------------------------" - "\n"); - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, FSMCNF_MAX_CCBS) { - debugif_printf("%-2d %-6d 0x%8p %-11d %-11d %-6d %-7d\n", - i++, ccb->cnf_id, ccb, ccb->cnf_call_id, - ccb->cns_call_id, ccb->active, ccb->bridged); - } - - return (0); -} - - -void -fsmcnf_init (void) -{ - fsmcnf_ccb_t *ccb; - static const char *fname = "fsmcnf_init"; - - - /* - * Initialize the ccbs. - */ - fsmcnf_ccbs = (fsmcnf_ccb_t *) - cpr_calloc(FSMCNF_MAX_CCBS, sizeof(fsmcnf_ccb_t)); - - if (fsmcnf_ccbs == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Failed to allocate memory for " \ - "cnf ccbs.\n", fname); - return; - } - - FSM_FOR_ALL_CBS(ccb, fsmcnf_ccbs, FSMCNF_MAX_CCBS) { - fsmcnf_init_ccb(ccb); - } - - /* - * Initialize the state/event table. - */ - fsmcnf_sm_table.min_state = FSMCNF_S_MIN; - fsmcnf_sm_table.max_state = FSMCNF_S_MAX; - fsmcnf_sm_table.min_event = CC_MSG_MIN; - fsmcnf_sm_table.max_event = CC_MSG_MAX; - fsmcnf_sm_table.table = (&(fsmcnf_function_table[0][0])); -} - -int -cc_is_cnf_call (callid_t call_id) -{ - if (call_id == CC_NO_CALL_ID) { - return FALSE; - } - return fsmutil_is_cnf_leg(call_id, fsmcnf_ccbs, FSMCNF_MAX_CCBS); -} - -void -fsmcnf_shutdown (void) -{ - cpr_free(fsmcnf_ccbs); - fsmcnf_ccbs = NULL; -} - -int -fsmutil_is_cnf_consult_call (callid_t call_id) -{ - return fsmutil_is_cnf_consult_leg(call_id, fsmcnf_ccbs, FSMCNF_MAX_CCBS); -} - -boolean -fsmcnd_conf_call_id_valid(fsmcnf_ccb_t *ccb){ - - static const char fname[] = "fsmcnd_conf_call_id_valid"; - if( ccb != NULL){ - FSM_DEBUG_SM(get_debug_string(FSMCNF_DBG_PTR), ccb->cnf_id, - ccb->cnf_call_id, ccb->cns_call_id, fname, ccb); - if((ccb->cnf_call_id != CC_NO_CALL_ID) && (ccb->cns_call_id != CC_NO_CALL_ID) ){ - return TRUE; - } - } - return FALSE; -} diff --git a/libs/sipcc/core/gsm/fsmdef.c b/libs/sipcc/core/gsm/fsmdef.c deleted file mode 100755 index 2c35f3dadb..0000000000 --- a/libs/sipcc/core/gsm/fsmdef.c +++ /dev/null @@ -1,8668 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "CCProvider.h" -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_rand.h" -#include "cpr_timers.h" -#include "cpr_errno.h" -#include "phone.h" -#include "lsm.h" -#include "fsm.h" -#include "sm.h" -#include "ccapi.h" -#include "ccsip_cc.h" -#include "phone_debug.h" -#include "fim.h" -#include "config.h" -#include "sdp.h" -#include "ccsip_sdp.h" // Temporary include -#include "rtp_defs.h" -#include "debug.h" -#include "gsm_sdp.h" -#include "vcm.h" -#include "uiapi.h" -#include "gsm.h" -#include "phntask.h" -#include "prot_configmgr.h" -#include "sip_interface_regmgr.h" -#include "dialplanint.h" -#include "subapi.h" -#include "text_strings.h" -#include "platform_api.h" -#include "peer_connection_types.h" -//#include "prlog.h" -#include "sessionHash.h" - -extern void update_kpmlconfig(int kpmlVal); -extern boolean g_disable_mass_reg_debug_print; -void escalateDeescalate(); - -#define FSMDEF_NO_NUMBER (NULL) -#define DIGIT_POUND ('#') -#define FSMDEF_MAX_DCBS (LSM_MAX_CALLS) -#define FSMDEF_CC_CALLER_ID ((cc_state_data_t *)(&(dcb->caller_id))) -#define RINGBACK_DELAY 90 - -// Minimum and maximum hold reversion timer in seconds -#define MIN_HOLD_REVERSION_INTERVAL_TIMER 10 -#define MAX_HOLD_REVERSION_INTERVAL_TIMER 1200 - -fsmdef_dcb_t *fsmdef_dcbs; - -static const char *fsmdef_state_names[] = { - "IDLE", - "COLLECTING_INFO", - "CALL_SENT", - "OUTGOING_PROCEEDING", - "KPML_COLLECTING_INFO", - "OUTGOING_ALERTING", - "INCOMING_ALERTING", - "CONNECTING", - "JOINING", - "CONNECTED", - "CONNECTED MEDIA PEND", - "RELEASING", - "HOLD_PENDING", - "HOLDING", - "RESUME_PENDING", - "PRESERVED" -}; - - -static sm_rcs_t fsmdef_ev_createoffer(sm_event_t *event); -static sm_rcs_t fsmdef_ev_createanswer(sm_event_t *event); -static sm_rcs_t fsmdef_ev_setlocaldesc(sm_event_t *event); -static sm_rcs_t fsmdef_ev_setremotedesc(sm_event_t *event); -static sm_rcs_t fsmdef_ev_setpeerconnection(sm_event_t *event); -static sm_rcs_t fsmdef_ev_localdesc(sm_event_t *event); -static sm_rcs_t fsmdef_ev_remotedesc(sm_event_t *event); -static sm_rcs_t fsmdef_ev_addstream(sm_event_t *event); -static sm_rcs_t fsmdef_ev_removestream(sm_event_t *event); -static sm_rcs_t fsmdef_ev_addcandidate(sm_event_t *event); -static sm_rcs_t fsmdef_ev_default(sm_event_t *event); -static sm_rcs_t fsmdef_ev_default_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_idle_setup(sm_event_t *event); -static sm_rcs_t fsmdef_ev_idle_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_idle_offhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_idle_dialstring(sm_event_t *event); -static sm_rcs_t fsmdef_ev_onhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_collectinginfo_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_collectinginfo_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_offhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_digit_begin(sm_event_t *event); -static sm_rcs_t fsmdef_ev_dialstring(sm_event_t *event); -static sm_rcs_t fsmdef_ev_proceeding(sm_event_t *event); -static sm_rcs_t fsmdef_ev_callsent_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_callsent_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_out_alerting(sm_event_t *event); -static sm_rcs_t fsmdef_ev_inalerting_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_inalerting_offhook(sm_event_t *event); -static sm_rcs_t fsmdef_handle_inalerting_offhook_answer(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_line(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connecting_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_media_pend_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_connected_media_pend_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_release_complete(sm_event_t *event); -static sm_rcs_t fsmdef_ev_releasing_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_releasing_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_releasing_onhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_hold_pending_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_hold_pending_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_release(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_onhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_holding_offhook(sm_event_t *event); -static sm_rcs_t fsmdef_ev_session_audit(sm_event_t *event); -static sm_rcs_t fsmdef_ev_resume_pending_feature(sm_event_t *event); -static sm_rcs_t fsmdef_ev_resume_pending_feature_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_preserved_feature(sm_event_t *event); -static void fsmdef_ev_join(cc_feature_data_t *data); - -static sm_rcs_t fsmdef_cfwd_clear_ccm(fsm_fcb_t *fcb); -static sm_rcs_t fsmdef_process_dialstring_for_callfwd(sm_event_t *event); -static sm_rcs_t fsmdef_process_cfwd_softkey_event(sm_event_t *event); -static sm_rcs_t fsmdef_cfwd_clear_ccm(fsm_fcb_t *fcb); -static sm_rcs_t fsmdef_ev_joining_connected_ack(sm_event_t *event); -static sm_rcs_t fsmdef_ev_joining_offhook(sm_event_t *event); - -static void fsmdef_b2bjoin_invoke(fsmdef_dcb_t *dcb, - cc_feature_data_t *join_data); -static void fsmdef_select_invoke(fsmdef_dcb_t *dcb, - cc_feature_data_t *select_data); -static void fsmdef_handle_join_pending(fsmdef_dcb_t *dcb); -static void fsmdef_append_dialstring_to_feature_uri(fsmdef_dcb_t *dcb, - const char *dialstring); -static boolean fsmdef_is_feature_uri_configured(cc_features_t ftr_id); -static void fsmdef_set_call_info_cc_call_state(fsmdef_dcb_t *dcb, - cc_states_t state, - cc_causes_t cause); -static boolean fsmdef_extract_join_target(sm_event_t *event); -static void fsmdef_ev_notify_feature(cc_feature_t *msg, fsmdef_dcb_t *dcb); -static void fsmdef_notify_hook_event(fsm_fcb_t *fcb, cc_msgs_t msg, - char *global_call_id, - callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, - monitor_mode_t monitor_mode, - cfwdall_mode_t cfwdall_mode); -static void fsmdef_update_callinfo_security_status(fsmdef_dcb_t *dcb, - cc_feature_data_call_info_t *call_info); -static void fsmdef_update_calltype (fsm_fcb_t *fcb, cc_feature_t *msg); - - -/* - * TODO Update events for correct JSEP transitions - * Instead of providing events for all states - */ -static sm_function_t fsmdef_function_table[FSMDEF_S_MAX][CC_MSG_MAX] = -{ -/* FSMDEF_S_IDLE ------------------------------------------------------------ */ - { - /* CC_MSG_SETUP */ fsmdef_ev_idle_setup, // New incoming - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_default, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_release_complete, - /* CC_MSG_FEATURE */ fsmdef_ev_idle_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_idle_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_default, - /* CC_MSG_LINE */ fsmdef_ev_idle_offhook, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_idle_dialstring, // new outgoing - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_COLLECT_INFO ---------------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_collectinginfo_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_collectinginfo_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_default, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_default, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_digit_begin, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_dialstring, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_CALL_SENT ------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_proceeding, - /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, - /* CC_MSG_CONNECTED */ fsmdef_ev_connected, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_callsent_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_default, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_OUTGOING_PROCEEDING --------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, - /* CC_MSG_CONNECTED */ fsmdef_ev_connected, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_callsent_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_default, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_KPML_COLLECT_INFO ----------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, - /* CC_MSG_CONNECTED */ fsmdef_ev_connected, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_collectinginfo_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_default, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_default, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_digit_begin, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_OUTGOING_ALERTING ----------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, - /* CC_MSG_CONNECTED */ fsmdef_ev_connected, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_callsent_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_default, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_INCOMING_ALERTING ----------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_inalerting_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_inalerting_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_inalerting_offhook, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_CONNECTING ------------------------------------------------------ */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_connected_ack, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_connecting_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_JOINING --------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_joining_connected_ack, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_connecting_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_joining_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_CONNECTED ------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_connected_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_CONNECTED_MEDIA_PEND ------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_connected_media_pend_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_connected_media_pend_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_RELEASING ------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_releasing_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_release_complete, - /* CC_MSG_FEATURE */ fsmdef_ev_releasing_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_default, - /* CC_MSG_ONHOOK */ fsmdef_ev_releasing_onhook, - /* CC_MSG_LINE */ fsmdef_ev_connected_line, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_HOLD_PENDING ---------------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_holding_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_hold_pending_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_hold_pending_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_default, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_default, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_HOLDING --------------------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_holding_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_holding_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_holding_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_holding_offhook, - /* CC_MSG_ONHOOK */ fsmdef_ev_holding_onhook, - /* CC_MSG_LINE */ fsmdef_ev_default, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_RESUME_PENDING -------------------------------------------------- */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_resume_pending_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_resume_pending_feature_ack, - /* CC_MSG_OFFHOOK */ fsmdef_ev_default, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_default, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - }, - -/* FSMDEF_S_PRESERVED ------------------------------------------------------ */ - { - /* CC_MSG_SETUP */ fsmdef_ev_default, - /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, - /* CC_MSG_PROCEEDING */ fsmdef_ev_default, - /* CC_MSG_ALERTING */ fsmdef_ev_default, - /* CC_MSG_CONNECTED */ fsmdef_ev_default, - /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, - /* CC_MSG_RELEASE */ fsmdef_ev_release, - /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, - /* CC_MSG_FEATURE */ fsmdef_ev_preserved_feature, - /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default, - /* CC_MSG_OFFHOOK */ fsmdef_ev_default, - /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, - /* CC_MSG_LINE */ fsmdef_ev_default, - /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, - /* CC_MSG_DIGIT_END */ fsmdef_ev_default, - /* CC_MSG_DIALSTRING */ fsmdef_ev_default, - /* CC_MSG_MWI */ fsmdef_ev_default, - /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, - /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, - /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, - /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, - /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, - /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, - /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate - } -}; - -static sm_table_t fsmdef_sm_table; -sm_table_t *pfsmdef_sm_table = &fsmdef_sm_table; - -/*-------------------------------------------------------------------------- - * Global data - *-------------------------------------------------------------------------- - */ -uint16_t g_numofselected_calls = 0; -boolean g_b2bjoin_pending = FALSE; -callid_t g_b2bjoin_callid = CC_NO_CALL_ID; - -static sdp_direction_e s_default_video_dir = SDP_DIRECTION_SENDRECV; -static sdp_direction_e s_session_video_dir = SDP_MAX_QOS_DIRECTIONS; - - -void set_default_video_pref(int pref) { - s_default_video_dir = pref; -} - -void set_next_sess_video_pref(int pref) { - s_session_video_dir = pref; -} - -const char * -fsmdef_state_name (int state) -{ - if ((state <= FSMDEF_S_MIN) || (state >= FSMDEF_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsmdef_state_names[state]); -} - -/* - * fsmdef_get_dcb_by_call_id - * - * return the dcb referenced by the given call_id - */ -fsmdef_dcb_t * -fsmdef_get_dcb_by_call_id (callid_t call_id) -{ - static const char fname[] = "fsmdef_get_dcb_by_call_id"; - fsmdef_dcb_t *dcb; - fsmdef_dcb_t *dcb_found = NULL; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id == call_id) { - dcb_found = dcb; - break; - } - } - - if (dcb_found) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_PTR), - dcb->call_id, dcb->line, fname, dcb_found); - } - - return (dcb_found); -} - - -/* - * fsmdef_check_if_chaperone_call_exist - * - * return the dcb referenced by the given call_id - */ -boolean -fsmdef_check_if_chaperone_call_exist (void) -{ - static const char fname[] = "fsmdef_check_if_chaperone_call_exist"; - fsmdef_dcb_t *dcb; - boolean result = FALSE; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if(dcb->policy == CC_POLICY_CHAPERONE){ - result = TRUE; - break; - } - } - - if (result) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_PTR), - dcb->call_id, dcb->line, fname, dcb); - } - - return result; -} - - -void fsmdef_get_rtp_stat (fsmdef_dcb_t *dcb , cc_kfact_t *kfactor) -{ - static const char fname[] ="fsmdef_get_rtp_stat"; - - int call_stats_flag; - fsmdef_media_t *media; - media = gsmsdp_find_audio_media(dcb); - - if (!media) { - GSM_ERR_MSG(GSM_F_PREFIX"dcb media pointer invalid\n", fname); - return; - } - - memset(kfactor, 0, sizeof(cc_kfact_t)); - config_get_value(CFGID_CALL_STATS, &call_stats_flag, sizeof(call_stats_flag)); - - if (call_stats_flag) { - vcmGetRtpStats(media->cap_index, dcb->group_id, - media->refid, - lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), &(kfactor->rxstats[0]), &(kfactor->txstats[0])); - } -} - -/** - * The function sets or clears the local hold status to the given media or - * for all of the media. - * - * @param[in]dcb - pointer to fsmdef_dcb_t. - * @param[in]media - specify which media to use. The value of - * NULL indicates for all media. - * @param[in]set - set local hold or clear local hold. - * - * @return none - * - * @pre (dcb not_eq NULL) - */ -static void -fsmdef_update_media_hold_status (fsmdef_dcb_t *dcb, fsmdef_media_t *media, - boolean set) -{ - fsmdef_media_t *start_media, *end_media; - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (GSMSDP_MEDIA_ENABLED(media)) { - if (set) { - FSM_SET_FLAGS(media->hold, FSM_HOLD_LCL); - } else { - FSM_RESET_FLAGS(media->hold, FSM_HOLD_LCL); - } - } - } -} - -/** - * The function checks to see whether all media streams are - * in locally held or not. - * - * @param[in]dcb - pointer to fsmdef_dcb_t. - * - * @return TRUE - all media streams are in local hold. - * FALSE - not all media streams are in local hold. - * - * @pre (dcb not_eq NULL) - */ -static boolean -fsmdef_all_media_are_local_hold (fsmdef_dcb_t *dcb) -{ - fsmdef_media_t *media; - /* - * Check the local hold status of each media to see if the - * media is already locally held or not. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - if (!FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL)) { - /* found one media that is not on hold */ - return (FALSE); - } - } - /* all media streams are local held */ - return (TRUE); -} - -/** - * The function gets the numbmer of media in local hold. - * - * @param[in]dcb - pointer to fsmdef_dcb_t. - * - * @return uint16_t for the number of media in local hold. - * - * @pre (dcb not_eq NULL) - */ -static unsigned int -fsmdef_num_media_in_local_hold (fsmdef_dcb_t *dcb) -{ - fsmdef_media_t *media; - unsigned int num_local_hold = 0; - - /* Check the local hold status of the media(s) */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - if (FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL)) { - num_local_hold++; - } - } - return (num_local_hold); -} - -/** - * The function is a convenient function to set each local hold in - * SDP for each media if it is marked as locally held. - * - * @param[in]dcb - pointer to fsmdef_dcb_t. - * - * @return None - * - * @pre (dcb not_eq NULL) - */ -static void -fsmdef_set_per_media_local_hold_sdp (fsmdef_dcb_t *dcb) -{ - fsmdef_media_t *media; - - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - if (FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL)) { - /* set local hold to this media entry */ - gsmsdp_set_local_hold_sdp(dcb, media); - } - } -} - -void -fsmdef_init_dcb (fsmdef_dcb_t *dcb, callid_t call_id, - fsmdef_call_types_t call_type, - string_t called_number, line_t line, fsm_fcb_t *fcb) -{ - string_t calling_name; - int blocking; - char name[MAX_LINE_NAME_SIZE]; - - dcb->call_id = call_id; - dcb->line = line; - - dcb->spoof_ringout_requested = FALSE; - dcb->spoof_ringout_applied = FALSE; - - dcb->log_disp = CC_CALL_LOG_DISP_UNKNWN; - - fsmutil_init_groupid(dcb, call_id, call_type); - - /* - * Fill in as much of the caller_id data as possible. - * Different data is available based on the call_type. - */ - switch (call_type) { - case FSMDEF_CALL_TYPE_OUTGOING: - config_get_value(CFGID_CALLERID_BLOCKING, &blocking, sizeof(blocking)); - if (line != 0) { - sip_config_get_display_name(line, name, sizeof(name)); - } - if (blocking & 1 || line == 0) { - calling_name = SIP_HEADER_ANONYMOUS_STR; - } else { - calling_name = name; - } - dcb->caller_id.calling_name = strlib_update(dcb->caller_id.calling_name, - calling_name); - dcb->caller_id.calling_number = - strlib_update(dcb->caller_id.calling_number, name); - - /* - * called_xxx data will be set when the fsmdef receives the dialstring. - */ - dcb->caller_id.called_name = strlib_empty(); - dcb->caller_id.called_number = strlib_empty(); - dcb->caller_id.orig_rpid_number = strlib_empty(); - - dcb->inbound = FALSE; - - break; - - case FSMDEF_CALL_TYPE_INCOMING: - case FSMDEF_CALL_TYPE_FORWARD: - /* - * calling_xxx data will be set when the fsmdef receives the setup. - */ - dcb->caller_id.calling_name = strlib_empty(); - dcb->caller_id.calling_number = strlib_empty(); - - dcb->caller_id.last_redirect_name = strlib_empty(); - dcb->caller_id.last_redirect_number = strlib_empty(); - dcb->caller_id.orig_called_name = strlib_empty(); - dcb->caller_id.orig_called_number = strlib_empty(); - dcb->caller_id.orig_rpid_number = strlib_empty(); - - sip_config_get_display_name(line, name, sizeof(name)); - dcb->caller_id.called_name = - strlib_update(dcb->caller_id.called_name, name); - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, called_number); - - dcb->inbound = TRUE; - - break; - - case FSMDEF_CALL_TYPE_NONE: - dcb->caller_id.calling_name = strlib_empty(); - dcb->caller_id.calling_number = strlib_empty(); - dcb->caller_id.called_name = strlib_empty(); - dcb->caller_id.called_number = strlib_empty(); - dcb->caller_id.alt_calling_number = strlib_empty(); - dcb->caller_id.last_redirect_name = strlib_empty(); - dcb->caller_id.last_redirect_number = strlib_empty(); - dcb->caller_id.orig_called_name = strlib_empty(); - dcb->caller_id.orig_called_number = strlib_empty(); - dcb->caller_id.orig_rpid_number = strlib_empty(); - dcb->inbound = FALSE; - - break; - default: - break; - } /* switch (call_type) { */ - - dcb->caller_id.display_calling_number = TRUE; - dcb->caller_id.display_called_number = TRUE; - - /* Initially, assume ui update is required for a new call. */ - dcb->ui_update_required = TRUE; - dcb->placed_call_update_required = TRUE; - - dcb->is_conf_call = FALSE; /*Initially, set to conf call false*/ - - dcb->digit_cnt = 0; - - dcb->call_type = call_type; - dcb->orientation = CC_ORIENTATION_NONE; - - dcb->caller_id.call_instance_id = 0; - - dcb->msgs_sent = FSMDEF_MSG_NONE; - dcb->msgs_rcvd = FSMDEF_MSG_NONE; - - dcb->send_release = FALSE; - - dcb->inband = FALSE; - dcb->inband_received = FALSE; - dcb->outofband = 0; - - dcb->remote_sdp_present = FALSE; - dcb->remote_sdp_in_ack = FALSE; - - dcb->sdp = NULL; - dcb->src_sdp_version = 0; - - dcb->dial_mode = DIAL_MODE_NUMERIC; - - dcb->hold_reason = CC_REASON_NONE; - - dcb->pd_updated = FALSE; - - dcb->alerting_tone = VCM_NO_TONE; - dcb->tone_direction = VCM_PLAY_TONE_TO_EAR; - - dcb->alert_info = ALERTING_NONE; - - dcb->dialplan_tone = FALSE; - - dcb->active_tone = VCM_NO_TONE; - - dcb->monrec_tone_action = FSMDEF_MRTONE_NO_ACTION; - dcb->monitor_tone_direction = VCM_PLAY_TONE_TO_EAR; - dcb->recorder_tone_direction = VCM_PLAY_TONE_TO_EAR; - - dcb->play_tone_action = FSMDEF_PLAYTONE_NO_ACTION; - - dcb->fcb = fcb; - - dcb->early_error_release = FALSE; - - dcb->active_feature = CC_FEATURE_NONE; - - /* Release transient timers if any have been allocated */ - if (dcb->err_onhook_tmr) { - (void) cprDestroyTimer(dcb->err_onhook_tmr); - dcb->err_onhook_tmr = NULL; - } - if (dcb->req_pending_tmr) { - (void) cprDestroyTimer(dcb->req_pending_tmr); - dcb->req_pending_tmr = NULL; - } - - FSM_SET_SECURITY_STATUS(dcb, CC_SECURITY_UNKNOWN); - FSM_SET_POLICY(dcb, CC_POLICY_UNKNOWN); - dcb->session = PRIMARY; - - dcb->dsp_out_of_resources = FALSE; - - if (dcb->selected) { - g_numofselected_calls--; - } - - dcb->selected = FALSE; - - dcb->select_pending = FALSE; - dcb->call_not_counted_in_mnc_bt = FALSE; - if (g_disable_mass_reg_debug_print == FALSE) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"call_not_counted_in_mnc_bt = FALSE\n", - DEB_L_C_F_PREFIX_ARGS(FSM, line, call_id, "fsmdef_init_dcb")); - } - - /* clear all bit flags */ - dcb->flags = 0; - dcb->onhook_received = FALSE; - - dcb->cur_video_avail = SDP_DIRECTION_INACTIVE; - - if ( s_session_video_dir != SDP_MAX_QOS_DIRECTIONS && - call_type == FSMDEF_CALL_TYPE_OUTGOING ) { - dcb->video_pref = s_session_video_dir; - s_session_video_dir = SDP_MAX_QOS_DIRECTIONS; - } else { - dcb->video_pref = s_default_video_dir; - } - - gsmsdp_init_media_list(dcb); - - dcb->join_call_id = CC_NO_CALL_ID; - dcb->callref = 0; - - dcb->ice_ufrag = NULL; - dcb->ice_pwd = NULL; - dcb->ice_default_candidate_addr[0] = '\0'; - - dcb->digest_alg[0] = '\0'; - dcb->digest[0] = '\0'; -} - - -static void -fsmdef_free_dcb (fsmdef_dcb_t *dcb) -{ - if (dcb == NULL) { - return; - } - - strlib_free(dcb->caller_id.calling_name); - strlib_free(dcb->caller_id.calling_number); - strlib_free(dcb->caller_id.alt_calling_number); - strlib_free(dcb->caller_id.called_name); - strlib_free(dcb->caller_id.called_number); - - strlib_free(dcb->caller_id.last_redirect_name); - strlib_free(dcb->caller_id.last_redirect_number); - strlib_free(dcb->caller_id.orig_called_name); - strlib_free(dcb->caller_id.orig_called_number); - strlib_free(dcb->caller_id.orig_rpid_number); - - /* Cancel any existing error onhook timer */ - if (dcb->err_onhook_tmr) { - (void) cprCancelTimer(dcb->err_onhook_tmr); - (void) cprDestroyTimer(dcb->err_onhook_tmr); - dcb->err_onhook_tmr = NULL; - } - - /* Cancel any existing request pending timer */ - if (dcb->req_pending_tmr) { - (void) cprCancelTimer(dcb->req_pending_tmr); - (void) cprDestroyTimer(dcb->req_pending_tmr); - dcb->req_pending_tmr = NULL; - } - - /* Cancel any existing ringback delay timer */ - if (dcb->ringback_delay_tmr) { - (void) cprCancelTimer(dcb->ringback_delay_tmr); - } - - // Free the call instance id - if (dcb->caller_id.call_instance_id != 0) { - fsmutil_free_ci_id(dcb->caller_id.call_instance_id, dcb->line); - } - - /* clean media list */ - gsmsdp_clean_media_list(dcb); - - gsmsdp_free(dcb); - - fsmdef_init_dcb(dcb, CC_NO_CALL_ID, FSMDEF_CALL_TYPE_NONE, NULL, - LSM_NO_LINE, NULL); - - /* - * Cache random numbers for SRTP keys - */ - gsmsdp_cache_crypto_keys(); - -} - -void -fsmdef_free_cb (fim_icb_t *icb, callid_t call_id) -{ - fsm_fcb_t *fcb = NULL; - fsmdef_dcb_t *dcb = NULL; - - if (call_id != CC_NO_CALL_ID) { - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb != NULL) { - fcb = dcb->fcb; - fsmdef_init_dcb(dcb, CC_NO_CALL_ID, FSMDEF_CALL_TYPE_NONE, - NULL, LSM_NO_LINE, NULL); - /* fsmdef_init_dcb(...,NULL) will always set the fcb ptr to NULL, - so if fsmdef_free_cb were called on that we'd have fcb==NULL here */ - if (fcb != NULL) { - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } else { - - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if (fcb != NULL) { - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } - } -} - - -/* - * ROUTINE: fsmdef_get_new_dcb - * - * DESCRIPTION: return a new dcb initialized with the given data - * - * PARAMETERS: - * call_id: call_id - * - * RETURNS: - * dcb: the new dcb - * - * NOTES: None - */ -fsmdef_dcb_t * -fsmdef_get_new_dcb (callid_t call_id) -{ - static const char fname[] = "fsmdef_get_new_dcb"; - fsmdef_dcb_t *dcb = NULL; - - /* - * Get a free dcb. - */ - if ((dcb = fsmdef_get_dcb_by_call_id(CC_NO_CALL_ID)) == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), call_id, 0, fname, - "no dcbs available"); - - return (NULL); - } - - dcb->call_id = call_id; - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_PTR), - dcb->call_id, dcb->line, fname, dcb); - - return (dcb); -} - - -/** - * - * Returns dcb related to connected call. - * - * @param none - * - * @return dcb of connected call. - * - * @pre none - */ - -fsmdef_dcb_t * -fsmdef_get_connected_call (void) -{ - fsmdef_dcb_t *dcb; - fsm_fcb_t *fcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id != CC_NO_CALL_ID) { - fcb = dcb->fcb; - if ((fcb != NULL) && (fcb->state == FSMDEF_S_RESUME_PENDING || - fcb->state == FSMDEF_S_CONNECTED || - fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND)) { - - return (dcb); - } - } - } - - return (NULL); -} - -/** - * - * Returns dcb related to alerting out call. - * - * @param none - * - * @return dcb of outgoing alerting call. - * - * @pre none - */ -static fsmdef_dcb_t * -fsmdef_get_alertingout_call (void) -{ - fsmdef_dcb_t *dcb; - fsm_fcb_t *fcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id != CC_NO_CALL_ID) { - fcb = dcb->fcb; - if ((fcb != NULL) && (fcb->state == FSMDEF_S_OUTGOING_ALERTING)) { - return (dcb); - } - } - } - - return (NULL); -} - -/* - * fsmdef_get_active_call_cnt - * - * Return the count of active calls aside from the - * callid passed in. - */ -int -fsmdef_get_active_call_cnt (callid_t callId) -{ - fsmdef_dcb_t *dcb; - int cnt = 0; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->call_id != CC_NO_CALL_ID) && (dcb->call_id != callId)) { - cnt++; - } - } - - return (cnt); -} - - -/* - * return the dcbs and count of calls that are ringing and - * are in error state not including the given call_id - * - * @param pointer to dcbs array - * @param call_id that should be ignored from search - * - * @return int number of ringing or error state calls - * - * @pre none -*/ -static int -fsmdef_get_ringing_n_error_call_dcbs (fsmdef_dcb_t **dcbs, callid_t ignore_call_id) -{ - fsmdef_dcb_t *dcb; - int cnt = 0; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->spoof_ringout_applied || - ((dcb->call_id != CC_NO_CALL_ID) && - (dcb->call_id != ignore_call_id) && - (dcb->fcb && ((dcb->fcb->state <= FSMDEF_S_CONNECTING) || - (dcb->fcb->state == FSMDEF_S_RELEASING))))) { - dcbs[cnt++] = dcb; - } - } - - return (cnt); -} - - -int -fsmdef_get_dcbs_in_held_state (fsmdef_dcb_t **dcbs, callid_t ignore_call_id) -{ - fsmdef_dcb_t *dcb; - int cnt = 0; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->call_id != CC_NO_CALL_ID) && - (dcb->call_id != ignore_call_id) && - (dcb->fcb && (dcb->fcb->state == FSMDEF_S_HOLDING || - dcb->fcb->state == FSMDEF_S_HOLD_PENDING))) { - dcbs[cnt++] = dcb; - } - } - - return (cnt); -} - -void fsmdef_call_cc_state_dialing (fsmdef_dcb_t *dcb, boolean suppress) -{ - cc_state_data_dialing_t data; - - if ( dcb->caller_id.called_number[0] == '\0' ) { - data.play_dt = TRUE; - } else { - data.play_dt = FALSE; - } - - data.suppress_stutter = suppress; - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_DIALING, - (cc_state_data_t *)(&data)); -} - -/* - * fsmdef_get_other_dcb_by_line - * - * return the dcb of the call that is active on a given line, - * not including the given call_id - */ -fsmdef_dcb_t * -fsmdef_get_other_dcb_by_line (callid_t call_id, line_t line) -{ - fsmdef_dcb_t *dcb; - fsmdef_dcb_t *dcb_found = NULL; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->call_id != CC_NO_CALL_ID) && - (dcb->line == line) && (dcb->call_id != call_id)) { - dcb_found = dcb; - } - } - - return (dcb_found); -} - -/* - * fsmdef_are_there_selected_calls_onotherline - * - * @param line - line number - * - * loop thru the dcbs and check if there are selected calls - * on a line other than this one - * - * @return TRUE, there are - * FALSE there are not - */ -boolean fsmdef_are_there_selected_calls_onotherline (line_t line) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->selected) { - if (dcb->line != line) { - return (TRUE); - } - } - } - return (FALSE); -} - -/* - * fsmdef_are_join_calls_on_same_line - * - * @param line - line number - * - * loop thru the dcbs and check if the line passed is the - * same as where the initial join started - * - * @return TRUE, they are on the same line - * FALSE not on the same line - */ -boolean fsmdef_are_join_calls_on_same_line (line_t line) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id == g_b2bjoin_callid) { - if (dcb->line != line) { - return (FALSE); - } else { - return (TRUE); - } - } - } - return (FALSE); -} - -/** - * - * Handles media capability update feature event from platform when - * media stream capability changes. - * - * @param[in]msg - pointer to the cc_feature_t. - * - * @return None. - * - * @pre (msg not_eq NULL) - */ -void -fsmdef_update_media_cap_feature_event (cc_feature_t *msg) -{ - static const char fname[] = "fsmdef_update_media_cap_feature_event"; - fsmdef_dcb_t *dcb; - fsm_fcb_t *fcb; - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"\n", DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, msg->call_id, fname)); - - /* - * Find the connected call to send the media capability update - * event to. There can be more than one call chains in - * connected state for an example, a call that participates in - * local conference, barged, monitored. All calls that - * are active are sent the update event. Each call leg will handle - * the event. - * - */ - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id != CC_NO_CALL_ID) { - fcb = dcb->fcb; - if ((fcb != NULL) && (fcb->state == FSMDEF_S_RESUME_PENDING || - fcb->state == FSMDEF_S_CONNECTED)) { - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_UPD_MEDIA_CAP, NULL); - - } - } - } -} - -/** - * - * Function to find and hold any connected call. - * - * @param call_id call id of the call - * @param wait flag to indicate if the caller has to wait ton invoke the event - * @param src_id source id of the caller where to post hold or endcall event. - * - * @return none - * - * @pre (wait == FALSE) - */ - -static void -fsmdef_find_and_hold_connected_call (callid_t call_id, boolean *wait, - cc_srcs_t src_id) -{ - fsmdef_dcb_t *con_dcb; - fsmcnf_ccb_t *ccb; - fsmcnf_ccb_t *con_ccb; - fsmxfr_xcb_t *xcb; - cc_feature_data_t data; - callid_t other_call_id; - callid_t other_call_id2; - - *wait = FALSE; - - /* - * Place the connected call, if there is one, on hold, - * but there are some restrictions to ignore the hold request: - * 1. the connected call must be different than the one requesting the hold, - * 2. the connected call is involved with this call in a conference and - * the conference is active. - * NOTE: for case 2, why do we not send a hold for each of the calls - * involved in the conference? Because, the fsmcnf will generate the - * second hold for the other leg of the conference when it receives - * this hold. - * 3. the connected call is in a conference with another call that is - * involved with a transfer. This is the case when two calls are in a - * conference and a bridge decides to transfer one leg of the bridge - * using REFER. I.E., cnf between A-B and A-C. B initiates transfer to D. - * B holds A-B, sends REFER to A, A holds A-B, initiates A-D, D answers, - * A hangs up A-B and connects conference. So, when A initiates A-D, - * we do not want to hold the active bridge between A-C. - */ - con_dcb = fsmdef_get_connected_call(); - if ((con_dcb != NULL) && ((con_dcb->call_id != call_id) || - (con_dcb->spoof_ringout_applied == FALSE))) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - con_ccb = fsmcnf_get_ccb_by_call_id(con_dcb->call_id); - - - if ((ccb == NULL) || (con_ccb == NULL) || - ((ccb == con_ccb) && (ccb->active != TRUE)) || (ccb != con_ccb)) { - other_call_id = fsmcnf_get_other_call_id(con_ccb, con_dcb->call_id); - xcb = fsmxfr_get_xcb_by_call_id(other_call_id); - - other_call_id2 = fsmxfr_get_other_call_id(xcb, other_call_id); - - if (call_id != other_call_id2) { - *wait = TRUE; - - data.hold.call_info.type = CC_FEAT_HOLD; - data.hold.call_info.data.hold_resume_reason = - CC_REASON_INTERNAL; - data.hold.msg_body.num_parts = 0; - data.hold.call_info.data.call_info_feat_data.swap = FALSE; - data.hold.call_info.data.call_info_feat_data.protect = FALSE; - cc_int_feature(src_id, CC_SRC_GSM, con_dcb->call_id, - con_dcb->line, CC_FEATURE_HOLD, &data); - } - } - } -} - -/* - * Function post a event to end the call which are in ringing - * reorder or busy and connecting state. This would indicate call function to - * wait on the existing event. - * - * @param call_id that should be ignored from search - * @param pointer to boolean to indicate if the caller has to wait - * - * @return none - * - * @pre none -*/ -static void -fsmdef_find_and_handle_ring_connecting_releasing_calls (callid_t call_id, boolean *wait) -{ - int i; - int act_dcb_cnt; - fsmdef_dcb_t *act_dcb; - fsmdef_dcb_t *act_dcbs[LSM_MAX_CALLS]; - cc_feature_data_t data; - - *wait = FALSE; - - data.endcall.cause = CC_CAUSE_NORMAL; - data.endcall.dialstring[0] = '\0'; - - act_dcb_cnt = fsmdef_get_ringing_n_error_call_dcbs(act_dcbs, call_id); - for (i = 0; i < act_dcb_cnt; i++) { - act_dcb = act_dcbs[i]; - /* - * Clear all the outgoing ringing lines (if there are any). - */ - if (act_dcb->call_type == FSMDEF_CALL_TYPE_OUTGOING || - act_dcb->spoof_ringout_applied) { - *wait = TRUE; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, act_dcb->call_id, - act_dcb->line, CC_FEATURE_END_CALL, &data); - - } - else if (act_dcb->fcb->state == FSMDEF_S_CONNECTING) { - /* If the call is in connecting state, then wait till SIP - * response to get the call in connected state. - * The call can be put on hold only when call is connected. - */ - *wait = TRUE; - } - } -} - -void -fsmdef_end_call (fsmdef_dcb_t *dcb, cc_causes_t cause) -{ - cc_feature_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - data.endcall.cause = cause; - data.endcall.dialstring[0] = '\0'; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); -} - -/* - * fsmdef_clear_preserved_calls - * - * Release any calls in the preserved state - */ -static void -fsmdef_clear_preserved_calls (boolean *wait) -{ - fsmdef_dcb_t *dcb; - - *wait = FALSE; - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->call_id != CC_NO_CALL_ID) && - (dcb->fcb->state == FSMDEF_S_PRESERVED)) { - *wait = TRUE; - fsmdef_end_call(dcb, CC_CAUSE_NORMAL); - } - } -} - -/** - * - * Checks to see if actions are required for existing calls before the new - * call can be activated. - * - * 1. Place the currently active connected call on hold. - * 2. Clear any ringing calls. - * 3. Release any call in the preserved state. - * - * @param is_newcall To indicate if this is a new call - * @param src_id source of the caller - * @param call_id call-id - * @param line line number - * @param feature feature which is waiting on hodling call. - * @param feature data - * - * @return TRUE if actions require delay before the new call may begin - * FALSE if no actions are required an the new call may begin - * - * @pre (wait, wait2, wait3 all FALSE) - */ -static boolean -fsmdef_wait_to_start_new_call (boolean is_newcall, cc_srcs_t src_id, callid_t call_id, - line_t line, cc_features_t feature, - cc_feature_data_t *data) -{ - boolean wait = FALSE; - boolean wait2 = FALSE; - boolean wait3 = FALSE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsmdef_find_and_hold_connected_call(call_id, &wait, src_id); - - fsmdef_find_and_handle_ring_connecting_releasing_calls(call_id, &wait2); - - fsmdef_clear_preserved_calls(&wait3); - - /* - * Requeue the message because we need to wait for call actions to complete - */ - if ((wait) || (wait2) || (wait3)) { - cc_int_feature(src_id, CC_SRC_GSM, call_id, line, feature, data); - } - - return (wait | wait2 | wait3); -} - -static cc_causes_t -fsmdef_get_cause (boolean data_valid, cc_feature_data_t *data) -{ - cc_causes_t cause; - - if (data_valid) { - cause = data->endcall.cause; - } else { - cause = CC_CAUSE_NORMAL; - } - - return (cause); -} - - -/** - * common function to release a call given cause code - * i.e onhooks the given call. - * - * @param[in] fcb The pointer to the fsm_fcb_t structure of this - * call chain. - * @param[in] cause release cause code. - * - * @param[in] send_release When set to TRUE the function sends release - * and waits for release complete. - * When set to FALSE the function cleans up - * dcb and release fcb. - * - * @pre (fcb not_eq NULL) - * - * @return sm_rcs_t indicates whether the execution of - * next statmachine to end (SM_RC_END) or clean up - * (SM_RC_CLEANUP) - * - * @Usage Note: The function uses send_release flag to - * as an indicator for sending release out or not. - * If release is sent, the function transitions fsmdef's - * state to FSMDEF_S_RELEASING and - * return the SM_RC_END to waite for release complete. - * - * Otherwise, it cleans up dcb and releases fcb and - * return SM_RC_CLEANUP to the caller. - * - * If the SM_RC_CLEANUP is returned, the caller should - * terminate any access or perform any operation - * afterward. - */ -sm_rcs_t -fsmdef_release (fsm_fcb_t *fcb, cc_causes_t cause, boolean send_release) -{ - fsmdef_dcb_t *dcb = fcb->dcb; - cc_state_data_t state_data; - cc_kfact_t kfactor; - fsmdef_media_t *media; - char tmp_str[STATUS_LINE_MAX_LEN]; - - if (!dcb) { - /* Already been released */ - return SM_RC_CLEANUP; - } - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Entered. cause= %s\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, __FUNCTION__), cc_cause_name(cause)); - - if (g_dock_undock_event != MEDIA_INTERFACE_UPDATE_NOT_REQUIRED) { - ui_update_media_interface_change(dcb->line, dcb->call_id, MEDIA_INTERFACE_UPDATE_FAIL); - } - memset(&kfactor, 0, sizeof(cc_kfact_t)); - /* Cancel any existing autoanswer timer */ - (void) cprCancelTimer(dcb->autoAnswerTimer); - - - /* - * Let Dialog Manager know that there is ONHOOK event - */ - fsmdef_notify_hook_event(fcb, CC_MSG_ONHOOK, NULL, CC_NO_CALL_ID, - CC_REASON_NONE, CC_MONITOR_NONE,CFWDALL_NONE); - - media = gsmsdp_find_audio_media(dcb); - if ((media) && (media->direction != SDP_DIRECTION_INACTIVE)) { - fsmdef_get_rtp_stat(dcb, &kfactor); - } - - if ( cause == CC_SIP_CAUSE_ANSWERED_ELSEWHERE ) { - ui_log_disposition(dcb->call_id, CC_CALL_LOG_DISP_IGNORE ); - } - - if ( cause == CC_CAUSE_RESP_TIMEOUT) { - if ((platGetPhraseText(STR_INDEX_RESP_TIMEOUT, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - lsm_ui_display_status(tmp_str, dcb->line, dcb->call_id); - } - } - - if (send_release) { - cc_int_release(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - cause, NULL, &kfactor); - /* - * Wait around for the release_complete. - */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_RELEASING); - - /* - * Only move the UI if we changed the UI's state when the call was - * received. - */ - if ((dcb->line != LSM_NO_LINE) || (cause != CC_CAUSE_BUSY)) { - state_data.onhook.caller_id = dcb->caller_id; - state_data.onhook.local = FALSE; - state_data.onhook.cause = CC_CAUSE_NORMAL; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ONHOOK, - &state_data); - } - return (SM_RC_END); - } else { - /* - * Only move the UI if we changed the UI's state when the call was - * initiated. - */ - if ((dcb->line != LSM_NO_LINE) || (cause != CC_CAUSE_BUSY)) { - state_data.onhook.caller_id = dcb->caller_id; - state_data.onhook.local = FALSE; - state_data.onhook.cause = CC_CAUSE_NORMAL; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ONHOOK, - &state_data); - } - - /* - * Only send a release complete to the remote end if they are waiting - * for it. This is the case when we have sent a proceeding or we - * have received a release. - */ - if (FSM_CHK_FLAGS(dcb->msgs_sent, FSMDEF_MSG_PROCEEDING) || - FSM_CHK_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE)) { - cc_int_release_complete(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, cause, &kfactor); - } - - fsm_change_state(fcb, __LINE__, FSMDEF_S_IDLE); - fsmdef_free_dcb(dcb); - fsm_release(fcb, __LINE__, cause); - /* - * fsmdef has been released, indiate cleanup FSM chain. - */ - return (SM_RC_CLEANUP); - } -} - -/* - * fsmdef_convert_esc_plus - * - * replaces an escaped "+" (%2B) with a real "+" - */ -static void -fsmdef_convert_esc_plus (const char *src_number) -{ - int i, len; - char *number; - - len = strlen(src_number) - 2; - number = (char *) src_number; - number[0] = '+'; - for (i = 1; i < len; i++) { - number[i] = number[i + 2]; - } - number[i] = '\0'; -} - -static boolean -fsmdef_compare_caller_id_string (string_t dest, string_t src) -{ - if ((dest == NULL) && (src == NULL)) { - /* - * Strings are same. - */ - return (FALSE); - } - - if ((dest == NULL) || (src == NULL)) { - /* - * Strings differ. - */ - return (TRUE); - } - - if (strncmp(dest, src, FSMDEF_MAX_CALLER_ID_LEN) != 0) { - /* - * Strings differ. - */ - return (TRUE); - } - - /* - * Strings are same. - */ - return (FALSE); -} - -static boolean -fsmdef_compare_caller_id (cc_caller_id_t *dest_caller_id, - cc_caller_id_t *src_caller_id) -{ - if (fsmdef_compare_caller_id_string(dest_caller_id->calling_name, - src_caller_id->calling_name)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->calling_number, - src_caller_id->calling_number)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->called_name, - src_caller_id->called_name)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->called_number, - src_caller_id->called_number)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->orig_called_name, - src_caller_id->orig_called_name)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->orig_called_number, - src_caller_id->orig_called_number)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->last_redirect_name, - src_caller_id->last_redirect_name)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->last_redirect_number, - src_caller_id->last_redirect_number)) { - return (TRUE); - } - - if (fsmdef_compare_caller_id_string(dest_caller_id->orig_rpid_number, - src_caller_id->orig_rpid_number)) { - return (TRUE); - } - - if (dest_caller_id->display_calling_number != src_caller_id->display_calling_number || - dest_caller_id->display_called_number != src_caller_id->display_called_number || - dest_caller_id->call_type != src_caller_id->call_type || - dest_caller_id->call_instance_id != src_caller_id->call_instance_id) { - return (TRUE); - } - - return (FALSE); -} - -static void -fsmdef_mv_caller_id (fsmdef_dcb_t *dcb, cc_caller_id_t *caller_id) -{ - /* - * Move the caller ID from the source to the storage in dcb if there - * is a change in what is already stored in the dcb. - */ - if (fsmdef_compare_caller_id(&dcb->caller_id, caller_id)) { - cc_mv_caller_id(&dcb->caller_id, caller_id); - dcb->ui_update_required = TRUE; - } -} - -static void -fsmdef_update_callinfo (fsm_fcb_t *fcb, cc_feature_t *msg) -{ - static const char fname[] = "fsmdef_update_callinfo"; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t *feat_data = &(msg->data); - cc_action_data_t action_data; - cc_caller_id_t *caller_id; - - if (msg->data_valid == FALSE) { - /* No data to use for update. Just ignore the event. */ - return; - } - - if ((feat_data->call_info.feature_flag & CC_UI_STATE) && - (feat_data->call_info.ui_state == CC_UI_STATE_RINGOUT)) { - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, - "setting spoof_ringout_requested"); - - dcb->spoof_ringout_requested = TRUE; - } else { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_RQSTD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_requested = FALSE; - } - - caller_id = &feat_data->call_info.caller_id; - - if (feat_data->call_info.feature_flag & CC_CALLER_ID) { - fsmdef_mv_caller_id(dcb, caller_id); - } - - /* - * If CCM provides a call instance id and it does not match - * the current call instance id, free the current call instance - * id and set the call instance id to the newly provided value. - */ - if (feat_data->call_info.feature_flag & CC_CALL_INSTANCE && - feat_data->call_info.caller_id.call_instance_id != dcb->caller_id.call_instance_id) { - if (dcb->caller_id.call_instance_id != 0) { - fsmutil_free_ci_id(dcb->caller_id.call_instance_id, dcb->line); - } - dcb->caller_id.call_instance_id = - feat_data->call_info.caller_id.call_instance_id; - fsmutil_set_ci_id(dcb->caller_id.call_instance_id, dcb->line); - dcb->ui_update_required = TRUE; - } - - /* - * Update security status - */ - fsmdef_update_callinfo_security_status(dcb, &feat_data->call_info); - - /* - * Update call policy - */ - if (feat_data->call_info.feature_flag & CC_POLICY) { - if (dcb->policy != feat_data->call_info.policy) { - dcb->policy = feat_data->call_info.policy; - dcb->ui_update_required = TRUE; - } - } - - /* - * Save orientation so that UI call update can be done at - * any time that UI needs to be updated. - */ - if (feat_data->call_info.feature_flag & CC_ORIENTATION) { - if (dcb->orientation != feat_data->call_info.orientation) { - dcb->orientation = feat_data->call_info.orientation; - dcb->ui_update_required = TRUE; - } - } - - /* - * This call info. event may be as part of media effecting - * signaling event (such as INVITE, re-INVITE, 180 etc.) - * which will be followed by actual media effected event. It is - * indicated by SIP stack to improve media cutting through as soonest. - * If SIP indicates that UI can be delayed then do not update call - * information now. The UI will be updated as part of media - * manipulation event that will follow. - * (Note: call info event is sent separately from the SIP signaling - * event currently and it is sent before SIP signaling event). - */ - if (feat_data->call_info.feature_flag & CC_DELAY_UI_UPDATE) { - /* Delay UI update */ - } else { - /* - * Only perform a UI update if something changed. - */ - if (dcb->ui_update_required == TRUE - || dcb->spoof_ringout_requested == TRUE) { - - action_data.update_ui.action = CC_UPDATE_CALLER_INFO; - action_data.update_ui.data.caller_info = feat_data->call_info; - - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, - dcb->line, fname, "UI update"); - } else { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, "No UI update"); - } - } - /* update callref */ - if ( dcb->callref == 0 ) { - dcb->callref = feat_data->call_info.callref; - ui_update_callref(dcb->line, dcb->call_id, feat_data->call_info.callref); - } - /* update gcid */ - if (feat_data->call_info.global_call_id[0] != '\0') { - ui_update_gcid(dcb->line, dcb->call_id, feat_data->call_info.global_call_id); - /* - * store the gcid lcb, this is used to prevent short ringing - * in scenarios where a call is routed to the calling phone. - */ - lsm_update_gcid(dcb->call_id, feat_data->call_info.global_call_id); - } -} - -/** - * Function: fsmdef_set_feature_timer - * - * Description: This function is called to set (start) timer for a - * given timer. The context of the timer is set so that upon - * expiration the corresponding context (dcb) can be obtained. - * - * Parameters: - * dcb - pointer to the fsmdef_dcb_t. The caller must ensure - * dcb is not NULL. - * timer - pointer to cprTimer_t. The caller must ensure that - * timer is not NULL. - * duration - the time duration for the timer to be set. - * - * Returns: - * N/A. - */ -static void -fsmdef_set_feature_timer (fsmdef_dcb_t *dcb, cprTimer_t *timer, - uint32_t duration) -{ - static const char fname[] = "fsmdef_set_feature_timer"; - - if (cprCancelTimer(*timer) != CPR_SUCCESS) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CANCEL_FAILED), - dcb->call_id, dcb->line, fname, "Feature", cpr_errno); - - return; - } - - if (cprStartTimer(*timer, duration, (void *)(long)dcb->call_id) == CPR_FAILURE) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_START_FAILED), - dcb->call_id, dcb->line, fname, "Feature", cpr_errno); - } -} - -static void -fsmdef_set_req_pending_timer (fsmdef_dcb_t *dcb) -{ - static const char fname[] = "fsmdef_set_req_pending_timer"; - uint32_t msec; - - if (dcb == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname); - return; - } - - if (!dcb->req_pending_tmr) { - dcb->req_pending_tmr = cprCreateTimer("Request Pending", - GSM_REQ_PENDING_TIMER, - TIMER_EXPIRATION, - gsm_msg_queue); - - if (dcb->req_pending_tmr == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED), - dcb->call_id, dcb->line, fname, "Request Pending"); - - return; - } - } - - if (dcb->inbound) { - // We did not initiate this call, so set timer between 0 and 2000ms - msec = abs(cpr_rand()) % 2000; - } else { - // We initiated this call, so set the timer between 2100 and 4000ms - msec = abs(cpr_rand()) % 1900 + 2100; - } - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Starting req pending timer for %d ms.\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), msec); - - fsmdef_set_feature_timer(dcb, &dcb->req_pending_tmr, msec); -} - -static void -fsmdef_set_ringback_delay_timer (fsmdef_dcb_t *dcb) -{ - static const char fname[] = "fsmdef_set_ringback_delay_timer"; - - if (dcb == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname); - return; - } - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Starting Ringback Delay timer" - " for %d ms.\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), RINGBACK_DELAY); - - fsmdef_set_feature_timer(dcb, &dcb->ringback_delay_tmr, RINGBACK_DELAY); -} - -/******************************************************************* - * event functions - */ -static sm_rcs_t -fsmdef_ev_default (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SM_DEFAULT_EVENT)); - if (fcb->dcb) { - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - } - return (SM_RC_END); -} - -/* - * Default event handler for feature_ack event - */ -static sm_rcs_t -fsmdef_ev_default_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_default_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_features_t ftr_id = msg->feature_id; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, "fsmdef_ev_default_feature_ack")); - - if (ftr_id == CC_FEATURE_SELECT) { - /* Reeceived the response for select, so turn the flag off */ - dcb->select_pending = FALSE; - if (dcb->selected) { - dcb->selected = FALSE; - g_numofselected_calls--; - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"call is unselected and number of selected \ - calls on the phone is %d\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, msg->call_id, fname), - g_numofselected_calls); - - } else { - dcb->selected = TRUE; - if ((g_b2bjoin_pending == FALSE) && - (dcb->active_feature == CC_FEATURE_B2B_JOIN)) { - g_b2bjoin_pending = TRUE; - g_b2bjoin_callid = dcb->call_id; - } - g_numofselected_calls++; - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"call is selected and number of selected \ - calls on the phone is %d\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), - g_numofselected_calls); - } - ui_call_selected(dcb->line, lsm_get_ui_id(dcb->call_id), (dcb->selected)?CC_DIALOG_LOCKED:CC_DIALOG_UNLOCKED); - - } else if (dcb->active_feature != ftr_id) { - // check if we are getting feature_ack for the active feature - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"feature_ack rcvd for %s but %s is active\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), - cc_feature_name(ftr_id), cc_feature_name(dcb->active_feature)); - - } - - // reset active feature - dcb->active_feature = CC_FEATURE_NONE; - - return (SM_RC_END); -} - - -static void -fsmdef_sm_ignore_ftr (fsm_fcb_t *fcb, int fname, cc_features_t ftr_id) -{ - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - if (fcb->dcb) { - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - } -} - -static void -fsmdef_sm_ignore_src (fsm_fcb_t *fcb, int fname, cc_srcs_t src_id) -{ - fsm_sm_ignore_src(fcb, __LINE__, src_id); - - if (fcb->dcb) { - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - } -} - -/* - * fsmdef_error_onhook_timeout - * - * Timer is started immediately after the call error. This function is called - * when there is a timeout event generated by the timer . - * - * @param[in] data The gsm ID (callid_t) of the call onhook timeout - * has occured. - * - * @return N/A - */ -void -fsmdef_error_onhook_timeout (void *data) -{ - static const char fname[] = "fsmdef_error_onhook_timeout"; - fsmdef_dcb_t *dcb; - callid_t call_id; - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "invalid data"); - return; - } - - /* Retrieve dcb from call id */ - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname); - - return; - } - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, "timeout"); - - cc_int_onhook(CC_SRC_GSM, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, - dcb->call_id, dcb->line, FALSE, FALSE); -} - -/** - * Function: fsmdef_feature_timer_timeout - * - * Description: This function is called when receives time out - * notification. The function then converts the timer event - * into the CCAPI event suitable for GSM's call state machine. - * - * Parameters: - * feature_id - corresponding feature ID of the timer event. - * data - the opaque data for the caller which is actually - * is the GSM's call id. - * - * Returns: - * NULL or - * pointer to the cc_feature_t. - */ -void * -fsmdef_feature_timer_timeout (cc_features_t feature_id, void *data) -{ - static const char fname[] = "fsmdef_feature_timer_timeout"; - cc_feature_t *pmsg; - callid_t call_id; - fsmdef_dcb_t *dcb; - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "timeout"); - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "invalid data"); - return NULL; - } - - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - /* The corresponding dcb for the call ID is not found */ - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname); - return (NULL); - } - - if (dcb->inband_received && feature_id == CC_FEATURE_RINGBACK_DELAY_TIMER_EXP) { - /* Double check if inbound ringback indication is received*/ - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "inband received!"); - return (NULL); - } - - pmsg = (cc_feature_t *) gsm_get_buffer(sizeof(*pmsg)); - if (!pmsg) { - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG1), - call_id, dcb->line, fname, - "failed to allocate feature timer message"); - return NULL; - } - - memset(pmsg, 0, sizeof(*pmsg)); - - pmsg->msg_id = CC_MSG_FEATURE; - pmsg->src_id = CC_SRC_GSM; - pmsg->call_id = call_id; - pmsg->line = dcb->line; - pmsg->feature_id = feature_id; - pmsg->data_valid = FALSE; - - return (void *) pmsg; -} - -/** - * - * Function handles idle setup request received from the network - * - * @sm_eent_t event - * - * @return SM_RC_END - * - * @pre (called_number and called_number not NULL) - * @pre (event->data not_eq NULL) - * @pre (event->msg not_eq NULL) - */ -static sm_rcs_t -fsmdef_ev_idle_setup (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_idle_setup"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_setup_t *msg = (cc_setup_t *) event->msg; - callid_t call_id = msg->call_id; - int temp; - string_t called_number = msg->caller_id.called_number; - string_t calling_number = msg->caller_id.calling_number; - fsmdef_dcb_t *dcb; - cc_causes_t cause; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *other_fcb; - callid_t other_call_id; - boolean alerting = TRUE; - boolean replaces = msg->replaces; - int other_active_calls; - boolean transfer_target = FALSE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Make sure we have a valid called_number. - */ - if ((called_number == NULL) || (called_number[0] == '\0')) { - return (SM_RC_CLEANUP); - } - - /* - * Check the called/calling number for the E.164 escaped "+" - * and convert it to a real "+" if present. - */ - if (cpr_strncasecmp(called_number, "%2B", 3) == 0) { - fsmdef_convert_esc_plus(called_number); - } - if (cpr_strncasecmp(calling_number, "%2B", 3) == 0) { - fsmdef_convert_esc_plus(calling_number); - } - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"called_number= %s calling_number= %s\n", - DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, msg->call_id, fname), - msg->caller_id.called_number, msg->caller_id.calling_number); - - //idle = lsm_is_phone_idle(); - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb && replaces) { - transfer_target = TRUE; - } - - /* - * Get a new incoming call context. - * if we the target of a transfer, request that the line - * availability be increased by one to account for the third - * instance of a line to become available to allow completion - * of transfer. - */ - cause = fsm_get_new_incoming_call_context(call_id, fcb, called_number, - transfer_target); - dcb = fcb->dcb; - if ((msg->call_info.type != CC_FEAT_MONITOR) && - (replaces != TRUE)) { - if (lsm_is_line_available(dcb->line, TRUE) == FALSE) { - /* increment it to compensate for decrementing while ending the call. */ - lsm_increment_call_chn_cnt(dcb->line); - fsmdef_end_call(dcb, CC_CAUSE_BUSY); - return (SM_RC_END); - } - lsm_increment_call_chn_cnt(dcb->line); - } - else { - /* - * join calls (barged, M & R) are not counted by CUCM. so we should not count either - */ - dcb->call_not_counted_in_mnc_bt = TRUE; - dcb->join_call_id = msg->call_info.data.join.join_call_id; - } - /* - * Set default orientation for the incoming setup as "from" to - * avoid updating UI when call info is received in "ACK" which - * shoule be "from" for typicall incoming call. - */ - dcb->orientation = CC_ORIENTATION_FROM; - - switch (cause) { - case CC_CAUSE_OK: - break; - - case CC_CAUSE_NO_RESOURCE: - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_CLEANUP); - - default: - fsmdef_end_call(dcb, cause); - return (SM_RC_END); - } - - /* - * Check for Anonymous call blocking. If low bit is set, - * then do not allow call. Note that we must allow both upper and lowercase - * ANON strings, hence the use of strcasestr - */ - config_get_value(CFGID_ANONYMOUS_CALL_BLOCK, &temp, sizeof(temp)); - if (temp & 1) { - /* - * We compare the calling name to the hardcoded Anonymous string we use in - * our SIP headers. This handles the case where calling name was pulled from - * the From header and was set to Anonymous. We also compare the calling name - * to the localized string index for Private which is what the calling name will - * be set to if an RPID header was received. - */ - char tmp_str[STATUS_LINE_MAX_LEN]; - sstrncpy(tmp_str, platform_get_phrase_index_str(UI_PRIVATE), sizeof(tmp_str)); - if (strcasestr(msg->caller_id.calling_name, SIP_HEADER_ANONYMOUS_STR) || - strcasestr(msg->caller_id.calling_name, tmp_str)) { - fsmdef_end_call(dcb, CC_CAUSE_ANONYMOUS); - return (SM_RC_END); - } - } - - /* - * Check if Call Waiting is disabled. - * If call-waiting is disabled and there is another call active - * then the GSM will return busy. - * unless this is a barge/monitor target call - * - */ - config_get_line_value(CFGID_LINE_CALL_WAITING, &temp, sizeof(temp), - dcb->line); - other_active_calls = fsmdef_get_active_call_cnt(call_id); - - if ((msg->call_info.type != CC_FEAT_MONITOR)) { - if ((!(temp & 1)) && (other_active_calls > 0) && - (!((xcb != NULL) && (xcb->mode == FSMXFR_MODE_TARGET)))) { - - fsmdef_end_call(dcb, CC_CAUSE_BUSY); - - return (SM_RC_END); - } - } - - /* - * If this is a call to replace another call, - * check that we have a call to replace - */ - other_call_id = fsmxfr_get_other_call_id(xcb, call_id); - if (replaces) { - if ((xcb == NULL) || (other_call_id == CC_NO_CALL_ID)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, "", - "No call to replace"); - - fsmdef_end_call(dcb, CC_CAUSE_NO_REPLACE_CALL); - return (SM_RC_END); - } - } - - - /* - * The called name and number will not be obtained from - * the setup. Remove it before getting from the setup message. - */ - if (msg->caller_id.called_name != NULL) { - strlib_free(msg->caller_id.called_name); - msg->caller_id.called_name = NULL; - } - if (msg->caller_id.called_number != NULL) { - strlib_free(msg->caller_id.called_number); - msg->caller_id.called_number = NULL; - } - /* Get the caller ID from the setup message */ - fsmdef_mv_caller_id(dcb, &msg->caller_id); - - if (msg->caller_id.call_type == CC_CALL_FORWARDED) { - - dcb->call_type = FSMDEF_CALL_TYPE_FORWARD; - } - - /* - * If a call instance id is provided, use it in the dcb. We will - * check to see that the call instance id provided differs from - * what is currently stored in the dcb before assigning it. - */ - if (msg->call_info.type == CC_FEAT_CALLINFO) { - cc_feature_data_call_info_t *data; - - data = &msg->call_info.data.call_info_feat_data; - if (data->feature_flag & CC_CALL_INSTANCE) { - if (data->caller_id.call_instance_id != 0 && - data->caller_id.call_instance_id != - dcb->caller_id.call_instance_id) { - if (dcb->caller_id.call_instance_id != 0) { - fsmutil_free_ci_id(dcb->caller_id.call_instance_id, - dcb->line); - } - dcb->caller_id.call_instance_id = - data->caller_id.call_instance_id; - fsmutil_set_ci_id(dcb->caller_id.call_instance_id, dcb->line); - } - } - - if (data->feature_flag & CC_SECURITY) { - FSM_SET_SECURITY_STATUS(dcb, data->security); - } - - if (data->feature_flag & CC_POLICY) { - FSM_SET_POLICY(dcb, data->policy); - } - } - dcb->alert_info = msg->alert_info; - dcb->alerting_ring = msg->alerting_ring; - dcb->alerting_tone = msg->alerting_tone; - - /* - * This is an incoming call, so we know we will need to send a - * RELEASE when we clear the call. - */ - dcb->send_release = TRUE; - - cause = gsmsdp_negotiate_offer_sdp(fcb, &msg->msg_body, TRUE); - if (cause != CC_CAUSE_OK) { - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - if (transfer_target) { - /* - * Send a proceeding event to the transfer call. - * - * The proceeding event will end the other call - * and answer the current call. - * - */ - cc_int_proceeding(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, &(dcb->caller_id)); - } - - cc_int_setup_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_SETUP_ACK); - - - - cc_int_proceeding(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id)); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_PROCEEDING); - - - alerting = fsmdef_extract_join_target(event); - - /* - * This might be the transfer call from the transferee to the target. - * In such a case we want this new call to match the state of the call - * that it is replacing. - */ - if (xcb != NULL) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_DEF); - if (other_fcb && (other_fcb->old_state == FSMDEF_S_CONNECTED || - other_fcb->old_state == FSMDEF_S_CONNECTED_MEDIA_PEND || - other_fcb->old_state == FSMDEF_S_RESUME_PENDING || - other_fcb->state == FSMDEF_S_CONNECTED || - other_fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND || - other_fcb->state == FSMDEF_S_RESUME_PENDING)) { - alerting = FALSE; - } - } - - - if (alerting == TRUE) { - /* - * set the call priority in lcb. This is used by ringer logic. - */ - if ((msg->call_info.type == CC_FEAT_CALLINFO) && - (msg->call_info.data.call_info_feat_data.priority == CC_CALL_PRIORITY_URGENT)) { - lsm_set_lcb_call_priority(call_id); - } - if ((msg->call_info.type == CC_FEAT_CALLINFO) && - (msg->call_info.data.call_info_feat_data.dusting == TRUE)) { - lsm_set_lcb_dusting_call(call_id); - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ALERTING, - FSMDEF_CC_CALLER_ID); - /* - * Currently we do not send SDP in the 180 response. - */ - cc_int_alerting(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL, FALSE); - - /* update callref */ - if ( dcb->callref == 0 ) { - dcb->callref = msg->call_info.data.call_info_feat_data.callref; - ui_update_callref(dcb->line, dcb->call_id, msg->call_info.data.call_info_feat_data.callref); - } - /* update gcid */ - ui_update_gcid(dcb->line, dcb->call_id, msg->call_info.data.call_info_feat_data.global_call_id); - /* - * store the gcid lcb, this is used to prevent short ringing - * in scenarios where a call is routed to the calling phone. - */ - lsm_update_gcid(dcb->call_id, msg->call_info.data.call_info_feat_data.global_call_id); - } - - ui_cc_capability(dcb->line, lsm_get_ui_id(dcb->call_id), msg->recv_info_list); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_ALERTING); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_INCOMING_ALERTING); - - return (SM_RC_END); -} - - -sm_rcs_t -fsmdef_dialstring (fsm_fcb_t *fcb, const char *dialstring, - cc_redirect_t *redirect, boolean replace, - cc_call_info_t *call_info) -{ - static const char fname[] = "fsmdef_dialstring"; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (dialstring) { - if (strlen(dialstring) > MAX_SIP_URL_LENGTH) { - FSM_DEBUG_SM(DEB_F_PREFIX"Dial string too long\n", DEB_F_PREFIX_ARGS(FSM, fname)); - /* Force clean up call without sending release */ - return (fsmdef_release(fcb, CC_CAUSE_INVALID_NUMBER, FALSE)); - } - } - - /* - * If there is active feature which is waiting for digit collection - * then use service URI preceded with dialed number. - */ - switch (dcb->active_feature) { - - case CC_FEATURE_CFWD_ALL: - fsmdef_append_dialstring_to_feature_uri(dcb, dialstring); - break; - - default: - if (dialstring) { - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, dialstring); - } - break; - } - - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - /* Force clean up call without sending release */ - return (fsmdef_release(fcb, cause, FALSE)); - } - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - /* Force clean up call without sending release */ - return (fsmdef_release(fcb, cause, FALSE)); - } - - /* - * Since we are sending setup to UI we will also have to send - * release to it to for sip stack to clean up the call - */ - dcb->send_release = TRUE; - - /* - * lsm_parse_displaystr will free present called number and return - * pointer to parsed called number - */ - dcb->caller_id.called_number = - lsm_parse_displaystr(dcb->caller_id.called_number); - - /* set default orientation for outgoing call */ - dcb->orientation = CC_ORIENTATION_TO; - dcb->inbound = FALSE; - - /* - * Invoke cc_call_state with modified caller_id for features such as - * pickups - */ - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_DIALING_COMPLETED, CC_CAUSE_MIN); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_SETUP); - - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_CALL_SENT, CC_CAUSE_MIN); - - /* - * Send setup or INVITE out after finishing all UI activities and media - * preparation. This is done as the final step in order to minimize - * UI activities/media activities to run concurrently while processing - * the response from the network. On the platform that uses Java VM to - * support UI and media, the time to process the UI and media activities - * may take longer than the network response time to the INVITE (such as - * voice mail case) and JNI calls may be blocked while invoking the - * UI or media calls in the LSM. - */ - cc_int_setup(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), dcb->alert_info, VCM_INSIDE_RING, - VCM_INSIDE_DIAL_TONE, redirect, call_info, replace, NULL, &msg_body); - fsm_change_state(fcb, __LINE__, FSMDEF_S_CALL_SENT); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_dialstring (sm_event_t *event) -{ - sm_rcs_t sm_rc; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - // handle dialstring event if from callfwdall - if (fsmdef_process_dialstring_for_callfwd(event) == SM_RC_END) { - // release the call started to collect callfwd info - dcb->send_release = FALSE; - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - } - - sm_rc = fsmdef_dialstring(fcb, ((cc_dialstring_t *)event->msg)->dialstring, - NULL, FALSE, NULL); - - return (sm_rc); -} - - -/** - * fsmdef_ev_createoffer - * - * Generates Offer SDP - * - */ -static sm_rcs_t -fsmdef_ev_createoffer (sm_event_t *event) { - // sm_rcs_t sm_rc; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause = CC_CAUSE_NORMAL; - cc_msgbody_info_t msg_body; - cc_feature_t *msg = (cc_feature_t *) event->msg; - line_t line = msg->line; - callid_t call_id = msg->call_id; - // cc_causes_t lsm_rc; - int sdpmode = 0; - char *ufrag = NULL; - char *ice_pwd = NULL; - short vcm_res; - session_data_t *sess_data_p = NULL; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - /* Force clean up call without sending release */ - return (fsmdef_release(fcb, cause, FALSE)); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_CLEANUP; - } - - if (msg->data.session.has_constraints) { - sess_data_p = (session_data_t *)findhash(msg->data.session.sessionid); - if (sess_data_p) { - gsmsdp_process_cap_constraints(dcb, sess_data_p->cc_constraints); - - if (0 > delhash(msg->data.session.sessionid)) { - FSM_DEBUG_SM (DEB_F_PREFIX"failed to delete hash sessid=0x%08x\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__), msg->data.session.sessionid); - } - cpr_free(sess_data_p); - } - } - - vcmGetIceParams(dcb->peerconnection, &ufrag, &ice_pwd); - if (!ufrag || !ice_pwd) { - ui_create_offer(evCreateOfferError, line, call_id, dcb->caller_id.call_instance_id, NULL); - return (fsmdef_release(fcb, cause, FALSE)); - } - - dcb->ice_ufrag = (char *)cpr_malloc(strlen(ufrag) + 1); - if (!dcb->ice_ufrag) - return SM_RC_END; - - sstrncpy(dcb->ice_ufrag, ufrag, strlen(ufrag) + 1); - free(ufrag); - - - dcb->ice_pwd = (char *)cpr_malloc(strlen(ice_pwd) + 1); - if (!dcb->ice_pwd) - return SM_RC_END; - - sstrncpy(dcb->ice_pwd, ice_pwd, strlen(ice_pwd) + 1); - free(ice_pwd); - - vcm_res = vcmGetDtlsIdentity(dcb->peerconnection, - dcb->digest_alg, FSMDEF_MAX_DIGEST_ALG_LEN, - dcb->digest, FSMDEF_MAX_DIGEST_LEN); - - if (vcm_res) { - FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetDtlsIdentity returned an error\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_END; - } - - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE); - if (cause != CC_CAUSE_OK) { - ui_create_offer(evCreateOfferError, line, call_id, dcb->caller_id.call_instance_id, NULL); - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, FALSE)); - } - - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - ui_create_offer(evCreateOfferError, line, call_id, dcb->caller_id.call_instance_id, NULL); - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, FALSE)); - } - - /* Pass offer SDP back to UI */ - ui_create_offer(evCreateOffer, line, call_id, dcb->caller_id.call_instance_id, msg_body.parts[0].body); - - return (SM_RC_END); -} - - -/** - * fsmdef_ev_createanswer - * - * Generates Answer SDP - * - */ -static sm_rcs_t -fsmdef_ev_createanswer (sm_event_t *event) { - // sm_rcs_t sm_rc; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_causes_t cause = CC_CAUSE_NORMAL; - cc_msgbody_info_t msg_body; - line_t line = msg->line; - callid_t call_id = msg->call_id; - // line_t free_line; - int sdpmode = 0; - // const char *called_number = "1234"; - // cc_causes_t lsm_rc; - // cc_msgbody_t *part; - // uint32_t body_length; - char *ufrag = NULL; - char *ice_pwd = NULL; - short vcm_res; - session_data_t *sess_data_p; - boolean has_audio; - boolean has_video; - boolean has_data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - return (fsmdef_release(fcb, cause, FALSE)); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_CLEANUP; - } - - if (msg->data.session.has_constraints) { - sess_data_p = (session_data_t *)findhash(msg->data.session.sessionid); - if (sess_data_p) { - gsmsdp_process_cap_constraints(dcb, sess_data_p->cc_constraints); - - if (0 > delhash(msg->data.session.sessionid)) { - FSM_DEBUG_SM (DEB_F_PREFIX"failed to delete hash sessid=0x%08x\n", - DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__), msg->data.session.sessionid); - } - cpr_free(sess_data_p); - } - } - - vcmGetIceParams(dcb->peerconnection, &ufrag, &ice_pwd); - if (!ufrag || !ice_pwd) { - ui_create_offer(evCreateAnswerError, line, call_id, dcb->caller_id.call_instance_id, NULL); - return (fsmdef_release(fcb, cause, FALSE)); - } - - dcb->ice_ufrag = (char *)cpr_malloc(strlen(ufrag) + 1); - if (!dcb->ice_ufrag) - return SM_RC_END; - - sstrncpy(dcb->ice_ufrag, ufrag, strlen(ufrag) + 1); - free(ufrag); - - - dcb->ice_pwd = (char *)cpr_malloc(strlen(ice_pwd) + 1); - if (!dcb->ice_pwd) - return SM_RC_END; - - sstrncpy(dcb->ice_pwd, ice_pwd, strlen(ice_pwd) + 1); - free(ice_pwd); - - vcm_res = vcmGetDtlsIdentity(dcb->peerconnection, - dcb->digest_alg, FSMDEF_MAX_DIGEST_ALG_LEN, - dcb->digest, FSMDEF_MAX_DIGEST_LEN); - - if (vcm_res) { - FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetDtlsIdentity returned an error\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_END; - } - - /* - * Determine what media types are offered, used to create matching local SDP - * for negotiation. - */ - gsmsdp_get_offered_media_types(fcb, dcb->sdp, &has_audio, &has_video, &has_data); - - /* - * The sdp member of the dcb has local and remote sdp - * this next function fills in the local part - */ - cause = gsmsdp_create_local_sdp(dcb, FALSE, has_audio, has_video, has_data, FALSE); - if (cause != CC_CAUSE_OK) { - ui_create_answer(evCreateAnswerError, line, call_id, dcb->caller_id.call_instance_id, NULL); - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - // Force clean up call without sending release - return (fsmdef_release(fcb, cause, FALSE)); - } - - /* TODO(ekr@rtfm.com): The second true is because we are acting as if we are - processing an offer. The first, however, is for an initial offer and we may - want to set that conditionally. */ - cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, FALSE, TRUE); - - if (cause != CC_CAUSE_OK) { - ui_create_answer(evCreateAnswerError, line, call_id, dcb->caller_id.call_instance_id, NULL); - return (fsmdef_release(fcb, cause, FALSE)); - } - - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - ui_create_answer(evCreateAnswerError, line, call_id, dcb->caller_id.call_instance_id, NULL); - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, FALSE)); - } - - /* Pass SDP back to UI */ - ui_create_answer(evCreateAnswer, line, call_id, dcb->caller_id.call_instance_id, msg_body.parts[0].body); - - return (SM_RC_END); -} - - -/** - * SetLocalDescription - * - */ -static sm_rcs_t -fsmdef_ev_setlocaldesc(sm_event_t *event) { - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_causes_t cause = CC_CAUSE_NORMAL; - cc_msgbody_info_t msg_body; - int action = msg->action; - // string_t sdp = msg->sdp; - int sdpmode = 0; - callid_t call_id = msg->call_id; - line_t line = msg->line; - // cc_causes_t lsm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - ui_set_local_description(evSetLocalDescError, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_SETLOCALDESCERROR); - return (SM_RC_END); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_CLEANUP; - } - - if (JSEP_OFFER == action) { - cause = gsmsdp_encode_sdp(dcb->sdp, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - ui_set_local_description(evSetLocalDescError, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_SETLOCALDESCERROR); - return (SM_RC_END); - } - - /* compare and fail if different: - * anant: Why? The JS should be able to modify the SDP. Commenting out for now (same for answer) - if (strcmp(msg_body.parts[0].body, msg->sdp) != 0) { - ui_set_local_description(evSetLocalDescError, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_SDPCHANGED); - return (SM_RC_END); - } - */ - - fsm_change_state(fcb, __LINE__, FSMDEF_S_CALL_SENT); - - } else if (JSEP_ANSWER == action) { - - /* compare SDP generated from CreateAnswer */ - cause = gsmsdp_encode_sdp(dcb->sdp, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - ui_set_local_description(evSetLocalDescError, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_SETLOCALDESCERROR); - return (SM_RC_END); - } - - /* compare and fail if different - if (strcmp(msg_body.parts[0].body, msg->sdp) != 0) { - ui_set_local_description(evSetLocalDescError, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_SDPCHANGED); - return (SM_RC_END); - }*/ - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_CONNECTED); - - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ANSWERED, - FSMDEF_CC_CALLER_ID); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTING); - - /* - * Now that we have negotiated the media, time to set up ICE. - * There also needs to be an ICE check in negotiate_media_lines. - */ - cause = gsmsdp_install_peer_ice_attributes(fcb); - if (cause != CC_CAUSE_OK) { - ui_set_local_description(evSetLocalDescError, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_SDPCHANGED); - return (SM_RC_END); - } - - /* taken from fsmdef_ev_connected_ack start rx and tx */ - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, NULL); - return (SM_RC_END); - } - - /* we may want to use the functionality in the following method - * to handle media capability changes, needs discussion - * fsmdef_transition_to_connected(fcb); - */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTED); - - } - - ui_set_local_description(evSetLocalDesc, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_OK); - - return (SM_RC_END); -} - - -/** - * SetRemoteDescription - * - */ -static sm_rcs_t -fsmdef_ev_setremotedesc(sm_event_t *event) { - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_causes_t cause = CC_CAUSE_NORMAL; - int action = msg->action; - int sdpmode = 0; - callid_t call_id = msg->call_id; - line_t line = msg->line; - // cc_causes_t lsm_rc; - cc_msgbody_t *part; - uint32_t body_length; - cc_msgbody_info_t msg_body; - boolean has_audio; - boolean has_video; - boolean has_data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - ui_set_remote_description(evSetRemoteDescError, line, call_id, - dcb->caller_id.call_instance_id, NULL, PC_SETREMOTEDESCERROR); - return (SM_RC_END); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_CLEANUP; - } - - cc_initialize_msg_body_parts_info(&msg_body); - - msg_body.num_parts = 1; - msg_body.content_type = cc_content_type_SDP; - part = &msg_body.parts[0]; - body_length = strlen(msg->sdp); - part->body = msg->sdp; - part->body_length = body_length; - part->content_type = cc_content_type_SDP; - part->content_disposition.required_handling = FALSE; - part->content_disposition.disposition = cc_disposition_session; - part->content_id = NULL; - - if (JSEP_OFFER == action) { - - cause = gsmsdp_process_offer_sdp(fcb, &msg_body, TRUE); - if (cause != CC_CAUSE_OK) { - ui_set_remote_description(evSetRemoteDescError, line, call_id, - dcb->caller_id.call_instance_id, NULL, PC_SETREMOTEDESCERROR); - return (SM_RC_END); - } - - /* - * Determine what media types are offered, used to create matching local SDP - * for negotiation. - */ - gsmsdp_get_offered_media_types(fcb, dcb->sdp, &has_audio, &has_video, &has_data); - - /* - * The sdp member of the dcb has local and remote sdp - * this next function fills in the local part - */ - cause = gsmsdp_create_local_sdp(dcb, TRUE, has_audio, has_video, has_data, FALSE); - if (cause != CC_CAUSE_OK) { - ui_set_remote_description(evSetRemoteDescError, line, call_id, dcb->caller_id.call_instance_id, - NULL, PC_SETREMOTEDESCERROR); - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - // Force clean up call without sending release - return (fsmdef_release(fcb, cause, FALSE)); - } - - cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, TRUE, FALSE); - if (cause != CC_CAUSE_OK) { - ui_set_remote_description(evSetRemoteDescError, line, call_id, dcb->caller_id.call_instance_id, - NULL, PC_SETREMOTEDESCERROR); - return (fsmdef_release(fcb, cause, FALSE)); - } - - gsmsdp_clean_media_list(dcb); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_INCOMING_ALERTING); - - } else if (JSEP_ANSWER == action) { - - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg_body); - if (cause != CC_CAUSE_OK) { - ui_set_remote_description(evSetRemoteDescError, line, call_id, dcb->caller_id.call_instance_id, - NULL, PC_SETREMOTEDESCERROR); - return (SM_RC_END); - } - - /* - * Now that we have negotiated the media, time to set up ICE. - * There also needs to be an ICE check in negotiate_media_lines. - */ - cause = gsmsdp_install_peer_ice_attributes(fcb); - if (cause != CC_CAUSE_OK) { - ui_set_remote_description(evSetRemoteDescError, line, call_id, dcb->caller_id.call_instance_id, - NULL, PC_SETREMOTEDESCERROR); - return (SM_RC_END); - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, FSMDEF_CC_CALLER_ID); - - /* we may want to use the functionality in the following method - * to handle media capability changes, needs discussion - * fsmdef_transition_to_connected(fcb); - * fsmdef_transition_to_connected(fcb); - */ - - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTED); - } - - ui_set_remote_description(evSetRemoteDesc, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_OK); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_localdesc(sm_event_t *event) { - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - // cc_causes_t cause = CC_CAUSE_NORMAL; - int sdpmode = 0; - // cc_causes_t lsm_rc; - // cc_msgbody_t *part; - // uint32_t body_length; - // cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - return (SM_RC_END); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_CLEANUP; - } - - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_remotedesc(sm_event_t *event) { - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - // cc_causes_t cause = CC_CAUSE_NORMAL; - int sdpmode = 0; - // cc_causes_t lsm_rc; - // cc_msgbody_t *part; - // uint32_t body_length; - // cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - - return (SM_RC_END); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_CLEANUP; - } - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_setpeerconnection(sm_event_t *event) { - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - // cc_causes_t cause = CC_CAUSE_NORMAL; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - int sdpmode = 0; - line_t line = msg->line; - cc_causes_t lsm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - return (SM_RC_END); - } - - if (!msg) - return SM_RC_END; - - if (!msg->data_valid) - return SM_RC_END; - - if (dcb == NULL) { - dcb = fsmdef_get_new_dcb(call_id); - if (dcb == NULL) { - return SM_RC_ERROR; - } - - lsm_rc = lsm_get_facility_by_line(call_id, line, FALSE, dcb); - if (lsm_rc != CC_CAUSE_OK) { - FSM_DEBUG_SM(DEB_F_PREFIX"lsm_get_facility_by_line failed.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_END; - } - - fsmdef_init_dcb(dcb, call_id, FSMDEF_CALL_TYPE_NONE, NULL, line, fcb); - - fsm_set_fcb_dcbs(dcb); - } - - PR_ASSERT(strlen(msg->data.pc.pc_handle) < PC_HANDLE_SIZE); - sstrncpy(dcb->peerconnection, msg->data.pc.pc_handle, sizeof(dcb->peerconnection)); - dcb->peerconnection_set = TRUE; - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_addstream(sm_event_t *event) { - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - // cc_causes_t cause = CC_CAUSE_NORMAL; - cc_feature_t *msg = (cc_feature_t *) event->msg; - int sdpmode = 0; - // cc_causes_t lsm_rc; - // cc_msgbody_t *part; - // uint32_t body_length; - // cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (sdpmode == FALSE) { - return (SM_RC_END); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_CLEANUP; - } - - /* - * This is temporary code to allow configuration of the two - * default streams. When multiple streams > 2 are supported this - * will be re-implemented. - */ - if (msg->data.track.media_type == VIDEO) { - dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE; - dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_SENDRECV; - dcb->media_cap_tbl->cap[CC_VIDEO_1].pc_stream = msg->data.track.stream_id; - dcb->media_cap_tbl->cap[CC_VIDEO_1].pc_track = msg->data.track.track_id; - } else if (msg->data.track.media_type == AUDIO) { - dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE; - dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_SENDRECV; - dcb->media_cap_tbl->cap[CC_AUDIO_1].pc_stream = msg->data.track.stream_id; - dcb->media_cap_tbl->cap[CC_AUDIO_1].pc_track = msg->data.track.track_id; - } else { - return (SM_RC_END); - } - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_removestream(sm_event_t *event) { - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - // cc_causes_t cause = CC_CAUSE_NORMAL; - cc_feature_t *msg = (cc_feature_t *) event->msg; - int sdpmode = 0; - // cc_causes_t lsm_rc; - // cc_msgbody_t *part; - // uint32_t body_length; - // cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (sdpmode == FALSE) { - - return (SM_RC_END); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_CLEANUP; - } - - /* - * This is temporary code to allow configuration of the two - * default streams. When multiple streams > 2 are supported this - * will be re-implemented. - */ - if (msg->data.track.media_type == AUDIO) { - dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE; - dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY; - dcb->video_pref = SDP_DIRECTION_SENDRECV; - } else if (msg->data.track.media_type == VIDEO) { - dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE; - dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY; - } else { - return (SM_RC_END); - } - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_addcandidate(sm_event_t *event) { - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - // cc_causes_t cause = CC_CAUSE_NORMAL; - cc_feature_t *msg = (cc_feature_t *) event->msg; - int sdpmode = 0; - short vcm_res; - // uint16_t level; - - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (sdpmode == FALSE) { - - return (SM_RC_END); - } - - if (dcb == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - return SM_RC_CLEANUP; - } - - - /* Perform level lookup based on mid value */ - /* comment until mid is properly updated - cause = gsmsdp_find_level_from_mid(dcb, (const char *)msg->data.candidate.mid, &level); - */ - - vcm_res = vcmSetIceCandidate(dcb->peerconnection, (char *)msg->data.candidate.candidate, msg->data.candidate.level); - if(vcm_res) { - FSM_DEBUG_SM(DEB_F_PREFIX"failure setting ice candidate.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - } - - - return (SM_RC_END); -} - -static void -fsmdef_check_active_feature (fsmdef_dcb_t *dcb, cc_features_t ftr_id) -{ - if ((dcb) && (dcb->active_feature != ftr_id)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_FTR_REQ_ACT), - dcb->call_id, dcb->line, - cc_feature_name(ftr_id), - cc_feature_name(dcb->active_feature)); - lsm_ui_display_notify(INDEX_STR_KEY_NOT_ACTIVE, NO_FREE_LINES_TIMEOUT); - } -} - -static sm_rcs_t -fsmdef_ev_idle_feature (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_idle_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *data = &(msg->data); - line_t line = msg->line; - cc_causes_t cause = CC_CAUSE_NORMAL; - callid_t call_id = fcb->call_id; - boolean expline; - sm_rcs_t sm_rc = SM_RC_END; - fsmcnf_ccb_t *ccb; - fsmxfr_xcb_t *xcb; - char *global_call_id = NULL; - - fsm_sm_ftr(ftr_id, src_id); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - if (dcb) { - dcb->video_pref = data->caps.support_direction; - } - break; - case CC_FEATURE_CFWD_ALL: - if (fsmdef_is_feature_uri_configured(ftr_id) == FALSE) { - fsm_display_feature_unavailable(); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - // handle cfwd event for ccm and non-ccm cases - // process feature event only if no other active feature - if ((dcb->active_feature == CC_FEATURE_NONE) && - (fsmdef_get_connected_call() == NULL)) { - dcb->active_feature = ftr_id; - (void) fsmdef_process_cfwd_softkey_event(event); - } else { - fsmdef_check_active_feature(dcb, ftr_id); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - break; - case CC_FEATURE_NEW_CALL: - - /* fetch the global_call_id from feature data */ - global_call_id = data->newcall.global_call_id; - - /* - * Set the expanded parameter. This parameter is used when - * requesting a free line. A transfer can request that the line - * availability be increased by one to account for the third - * instance of a line to become available for transfers. - */ - if (data != NULL) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((ccb != NULL) || (xcb != NULL)) { - expline = TRUE; - } else { - expline = FALSE; - } - } else { - expline = FALSE; - } - - /* - * Get a new outgoing call context if we have not already - * grabbed one. - */ - if (fcb->dcb == NULL) { - cause = fsm_get_new_outgoing_call_context(call_id, line, fcb, - expline); - switch (cause) { - case CC_CAUSE_OK: - break; - - case CC_CAUSE_NO_RESOURCE: - GSM_ERR_MSG("%s No Resource! Return SM_RC_CLEANUP.", fname); - return (SM_RC_CLEANUP); - - default: - /* - * No free lines. - */ - fsm_display_no_free_lines(); - - /* - * Send an endcall message. This behaviour is different - * than an offhook or line event because the new_call - * feature may have been generated by a transfer (as the - * consultation call) and will need this end_call message - * so that it can cleanup the transfer. The offhook can - * only come from the UI so it can just be cleaned up here - * without regard for a transfer. - */ - fsmdef_end_call(fcb->dcb, cause); - - return (SM_RC_END); - } - - dcb = fcb->dcb; - /* - * Let Dialog Manager know that there is OFFHOOK event - */ - fsmdef_notify_hook_event(fcb, CC_MSG_OFFHOOK, global_call_id, - data->newcall.prim_call_id, - data->newcall.hold_resume_reason, - CC_MONITOR_NONE,CFWDALL_NONE); - } - - - /* - * The user is attempting to start a new call on a specific line: - * 1. need to place the connected call (if there is one) on hold, - * 2. clear any outgoing ringing calls, - * 3. initiate this call. - */ - if (fsmdef_wait_to_start_new_call(TRUE, CC_SRC_GSM, call_id, line, - ftr_id, data)) { - return (SM_RC_END); - } - - //lsm_set_active_call_id(call_id); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_OFFHOOK, - FSMDEF_CC_CALLER_ID); - - if ( data->newcall.cause == CC_CAUSE_CONF || - data->newcall.cause == CC_CAUSE_XFER_LOCAL ) { - /* suppress stutter dial tone for conf and transfer features */ - fsmdef_call_cc_state_dialing(dcb, TRUE); - } else { - fsmdef_call_cc_state_dialing(dcb, FALSE); - } - - switch (data->newcall.cause) { - case CC_CAUSE_XFER_REMOTE: - /* - * This newcall feature is really the consultation part of - * a local transfer that has been transferred by the - * consultation call, so proceed as though this is a - * dialstring call since we already have the called_number. - */ - if (data->newcall.redirect.redirects[0].number[0] != '\0') { - sm_rc = fsmdef_dialstring(fcb, data->newcall.dialstring, - &(data->newcall.redirect), FALSE, - NULL); - - } else if (data->newcall.redirect.redirects[0].redirect_reason - == CC_REDIRECT_REASON_DEFLECTION) { - /* - * CC_REDIRECT_REASON_DEFLECTION shows that transferee is - * going to initiate a new call for replacing the call leg - * between transferor and target. - */ - - memset(data->newcall.redirect.redirects[0].number, 0, - sizeof(CC_MAX_DIALSTRING_LEN)); - sm_rc = fsmdef_dialstring(fcb, data->newcall.dialstring, - &(data->newcall.redirect), FALSE, - NULL); - - } else { - sm_rc = - fsmdef_dialstring(fcb, data->newcall.dialstring, NULL, - FALSE, NULL); - } - - return (sm_rc); - - case CC_CAUSE_REDIRECT: - sm_rc = fsmdef_dialstring(fcb, data->newcall.dialstring, - &(data->newcall.redirect), FALSE, - NULL); - return (sm_rc); - - case CC_CAUSE_XFER_BY_REMOTE: - - /* CC_REDIRECT_REASON_DEFLECTION shows that transferee is - * going to initiate a new call for replacing the call leg - * between transferor and target. - */ - - memset(data->newcall.redirect.redirects[0].number, 0, - sizeof(CC_MAX_DIALSTRING_LEN)); - sm_rc = fsmdef_dialstring(fcb, data->newcall.dialstring, - &(data->newcall.redirect), FALSE, - NULL); - return (sm_rc); - - default: - fsm_change_state(fcb, __LINE__, FSMDEF_S_COLLECT_INFO); - - return (SM_RC_END); - } - - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, data); - - /* - * There has to be a dcb to process this event. - */ - if (fcb->dcb == NULL) { - // commented out following line due to klocwork error - // call is dereferencing fcb->dcb when it is NULL (sorry, can't do that!) - // cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, NULL); - return (SM_RC_CLEANUP); - } - - if (dcb->call_type == FSMDEF_CALL_TYPE_INCOMING || - dcb->call_type == FSMDEF_CALL_TYPE_FORWARD) { - dcb->send_release = TRUE; - } - - return (fsmdef_release(fcb, cause, dcb->send_release)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - - } /* switch (src_id) { */ - - return (sm_rc); -} - -sm_rcs_t -fsmdef_offhook (fsm_fcb_t *fcb, cc_msgs_t msg_id, callid_t call_id, - line_t line, const char *dial_string, - sm_event_t *event, char *global_call_id, - callid_t prim_call_id, cc_hold_resume_reason_e consult_reason, - monitor_mode_t monitor_mode) -{ - boolean wait = FALSE; - boolean wait2 = FALSE; - boolean wait3 = FALSE; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Get a new outgoing call context if we have not already - * grabbed one. - */ - if (fcb->dcb == NULL) { - cause = fsm_get_new_outgoing_call_context(call_id, line, fcb, FALSE); - switch (cause) { - case CC_CAUSE_OK: - break; - - default: - /* - * No free lines - */ - fsm_display_no_free_lines(); - - if (fsmdef_get_connected_call() != NULL) { - lsm_speaker_mode(ON); - } else { - lsm_speaker_mode(OFF); - } - return (SM_RC_CLEANUP); - } - - /* - * Let Dialog Manager know that there is OFFHOOK event - */ - fsmdef_notify_hook_event(fcb, CC_MSG_OFFHOOK, global_call_id, - prim_call_id, consult_reason, monitor_mode,CFWDALL_NONE); - } - - - /* - * The user is attempting to start a new call on a specific line: - * 1. need to place the connected call (if there is one) on hold, - * 2. clear any outgoing ringing calls, or calls are in reorder/busy state - * 3. initiate this call. - */ - fsmdef_find_and_hold_connected_call(call_id, &wait, CC_SRC_GSM); - - fsmdef_find_and_handle_ring_connecting_releasing_calls(call_id, &wait2); - - fsmdef_clear_preserved_calls(&wait3); - - /* - * Requeue the message if we need to wait for the connected line to - * hold - */ - if ((wait == TRUE) || (wait2 == TRUE) || (wait3 == TRUE)) { - switch (msg_id) { - case CC_MSG_OFFHOOK: - cc_int_offhook(CC_SRC_GSM, CC_SRC_GSM, prim_call_id, consult_reason, - call_id, line, global_call_id, monitor_mode,CFWDALL_NONE); - break; - - case CC_MSG_LINE: - cc_int_line(CC_SRC_GSM, CC_SRC_GSM, call_id, line); - break; - - case CC_MSG_DIALSTRING: - cc_int_dialstring(CC_SRC_GSM, CC_SRC_GSM, call_id, line, - dial_string, global_call_id, monitor_mode); - break; - - case CC_MSG_FEATURE: - if (dial_string != NULL) { - cc_int_dialstring(CC_SRC_GSM, CC_SRC_GSM, call_id, line, - dial_string, global_call_id, monitor_mode); - break; - } - - /*FALLTHROUGH*/ - default: - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_CLEANUP); - } - - return (SM_RC_END); - } - - //lsm_set_active_call_id(call_id); - - return (SM_RC_SUCCESS); -} - - -static sm_rcs_t -fsmdef_ev_idle_offhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_offhook_t *msg = (cc_offhook_t *) event->msg; - fsmdef_dcb_t *dcb; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - sm_rc = fsmdef_offhook(fcb, msg->msg_id, msg->call_id, msg->line, NULL, - event, msg->global_call_id, msg->prim_call_id, - msg->hold_resume_reason, msg->monitor_mode); - - if (sm_rc != SM_RC_SUCCESS) { - return (sm_rc); - } - - dcb = fcb->dcb; - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_OFFHOOK, - FSMDEF_CC_CALLER_ID); - - fsmdef_call_cc_state_dialing(dcb, FALSE); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_COLLECT_INFO); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_idle_dialstring (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_dialstring_t *msg = (cc_dialstring_t *) event->msg; - fsmdef_dcb_t *dcb; - cc_action_data_t data; - sm_rcs_t sm_rc; - cc_call_info_t call_info; - cc_call_info_t *call_info_p = NULL; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - sm_rc = fsmdef_offhook(fcb, msg->msg_id, msg->call_id, msg->line, - msg->dialstring, event, msg->g_call_id, - CC_NO_CALL_ID, CC_REASON_NONE, msg->monitor_mode); - - if (sm_rc != SM_RC_SUCCESS) { - return (sm_rc); - } - - dcb = fcb->dcb; - - if (msg->dialstring) { - lsm_set_lcb_dialed_str_flag(dcb->call_id); - } - cc_call_state(dcb->call_id, dcb->line, CC_STATE_OFFHOOK, - FSMDEF_CC_CALLER_ID); - - data.tone.tone = VCM_INSIDE_DIAL_TONE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_TONE, &data); - - dcb->send_release = TRUE; - - /* Set call_info with global call_id, sent in the Initcallreq, - * If this call is not because Initcallreq, then don't set call_info - * Also, if this is a monitor call, add the mode to the call_info - */ - if (msg->g_call_id != NULL) { - - call_info.type = CC_FEAT_INIT_CALL; - call_info.data.initcall.monitor_mode = msg->monitor_mode; - sstrncpy(call_info.data.initcall.gcid, msg->g_call_id, CC_GCID_LEN); - - call_info_p = &call_info; - } - - if ( strncmp(CISCO_BLFPICKUP_STRING, msg->dialstring, strlen(CISCO_BLFPICKUP_STRING)) == 0 ) { - dcb->log_disp = CC_CALL_LOG_DISP_RCVD; - } - - sm_rc = fsmdef_dialstring(fcb, msg->dialstring, NULL, FALSE, call_info_p); - - return (sm_rc); -} - -static sm_rcs_t -fsmdef_ev_session_audit (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_session_audit"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_audit_sdp_req_t *audit_msg = (cc_audit_sdp_req_t *) event->msg; - cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (gsmsdp_encode_sdp_and_update_version(dcb, &msg_body) != CC_CAUSE_OK) { - /* - * Failed to encode our local sdp. Send ack to SIP stack with - * no message body. SIP stack will include previously send - * SDP in response to session audit request. - */ - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - - cc_int_audit_sdp_ack(CC_SRC_GSM, CC_SRC_SIP, audit_msg->call_id, - audit_msg->line, NULL); - } else { - cc_int_audit_sdp_ack(CC_SRC_GSM, CC_SRC_SIP, audit_msg->call_id, - audit_msg->line, &msg_body); - } - - /* - * If we are currently performing a spoofed ringout and the current session audit - * does not indicate that we should continue to do so, go back to connected state. - * But only change to connected state if not locally held. - */ - if (dcb->spoof_ringout_applied && - !dcb->spoof_ringout_requested) { - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - if ((fcb->state != FSMDEF_S_HOLDING) && - (fcb->state != FSMDEF_S_HOLD_PENDING)) { - /* - * If is at least one media entry that is not in loally held - * then go to connected state. - */ - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - } - - return (SM_RC_SUCCESS); -} - -static sm_rcs_t -fsmdef_ev_collectinginfo_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_CALL_FAILED, CC_CAUSE_INVALID_NUMBER); - - // Start onhook timer - if ( dcb->err_onhook_tmr) { - (void) cprDestroyTimer(dcb->err_onhook_tmr); - } - dcb->err_onhook_tmr = cprCreateTimer("Error Onhook", - GSM_ERROR_ONHOOK_TIMER, - TIMER_EXPIRATION, - gsm_msg_queue); - if (dcb->err_onhook_tmr == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED), - dcb->call_id, dcb->line, "", "Error Onhook"); - - return (SM_RC_CLEANUP); - } - - if (cprStartTimer(dcb->err_onhook_tmr, - FSMDEF_ERR_ONHOOK_TMR_SECS * 1000, - (void *)(long)dcb->call_id) == CPR_FAILURE) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_START_FAILED), - dcb->call_id, dcb->line, "", - "Error Onhook", cpr_errno); - return (SM_RC_CLEANUP); - } - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_collectinginfo_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_action_data_t data; - sm_rcs_t sm_rc = SM_RC_END; - cc_causes_t cause; - cc_feature_data_t *feature_data = &(msg->data); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (msg->feature_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = feature_data->caps.support_direction; - break; - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - if (fcb->state == FSMDEF_S_KPML_COLLECT_INFO) { - /* Clean up and send release */ - return (fsmdef_release(fcb, cause, TRUE)); - } - else { - /* Clean up without sending release */ - return (fsmdef_release(fcb, cause, FALSE)); - } - - case CC_FEATURE_NUMBER: - case CC_FEATURE_URL: - dcb->dial_mode = ((msg->feature_id == CC_FEATURE_NUMBER) ? - (DIAL_MODE_NUMERIC) : (DIAL_MODE_URL)); - - data.dial_mode.mode = dcb->dial_mode; - data.dial_mode.digit_cnt = dcb->digit_cnt; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_DIAL_MODE, - &data); - - break; - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - /* - * lsm_set_lcb_prevent_ringing() will check if there is a RINGIN call - * with the same GCID. If so, it will set a flag to prevent ringing. - */ - lsm_set_lcb_prevent_ringing(dcb->call_id); - break; - - case CC_FEATURE_SELECT: - fsmdef_select_invoke(dcb, feature_data); - return (SM_RC_END); - - case CC_FEATURE_CFWD_ALL: - if (fsmdef_is_feature_uri_configured(msg->feature_id) == FALSE) { - fsm_set_call_status_feature_unavailable(dcb->call_id, dcb->line); - - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - // handle cfwd event for ccm and non-ccm cases - // process feature event only if no other active feature - if (dcb->active_feature == CC_FEATURE_NONE) { - dcb->active_feature = ftr_id; - (void) fsmdef_process_cfwd_softkey_event(event); - } else { - fsmdef_check_active_feature(dcb, ftr_id); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - break; - - default: - dcb->active_feature = CC_FEATURE_NONE; - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - - return (sm_rc); -} - -/* - * Function: fsmdef_ev_digit_begin - * - * Parameters: event - * - * Description: This function is called each time a digit is - * received from the platform code. Currently, the platform code - * parses the dialplan. This function simply turns the - * dialtone off every time a digit is received and - * displays the appropriate keyset. (Eventually, this - * interface should be changed and GSM should have - * better knowledge of the dialplan.) - * - * Returns: SM_RC_END - */ -static sm_rcs_t -fsmdef_ev_digit_begin (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_digit_begin"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_digit_begin_t *msg = (cc_digit_begin_t *) event->msg; - char digit; - cc_action_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - digit = lsm_digit2ch(msg->digit); - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Digit Received= %c: stopping dial tone..\n", - DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, msg->call_id, fname), digit); - data.tone.tone = VCM_INSIDE_DIAL_TONE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_TONE, &data); - - /* - * Increment digit_cnt so that the proper keyset will be - * displayed. - */ - if (dcb->digit_cnt < CC_MAX_DIALSTRING_LEN) { - dcb->digit_cnt++; - } - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_proceeding (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - fcb->dcb->send_release = TRUE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - -#ifdef SAPP_SAPP_GSM - if ((event->msg != NULL) && - (((cc_proceeding_t *)(event->msg))->caller_id.called_name != NULL)) { - dcb->caller_id.called_name = - strlib_update(dcb->caller_id.called_name, - ((cc_proceeding_t *) (event->msg))->caller_id. - called_name); - } -#endif - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_FAR_END_PROCEEDING, - FSMDEF_CC_CALLER_ID); - - - fsm_change_state(fcb, __LINE__, FSMDEF_S_OUTGOING_PROCEEDING); - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_out_alerting (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_out_alerting"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_alerting_t *msg = (cc_alerting_t *) event->msg; - cc_causes_t cause = CC_CAUSE_ERROR; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - dcb->send_release = TRUE; - - dcb->inband = FALSE; - if (msg->inband) { - dcb->inband = TRUE; - - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg->msg_body); - if (cause != CC_CAUSE_OK) { - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * Record fact that we have successfully negotiated media that may be - * used for inband ringback. - */ - dcb->inband_received = TRUE; - FSM_DEBUG_SM(DEB_F_PREFIX"inband_received, cancel timer.\n", DEB_F_PREFIX_ARGS(FSM, fname)); - - /* - * If ringback delay timer has been started, cancel it now. - */ - if (cprCancelTimer(dcb->ringback_delay_tmr) != CPR_SUCCESS) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CANCEL_FAILED), - dcb->call_id, dcb->line, fname, "Ringback Delay", - cpr_errno); - } - } else { - /* - * Not inband alerting case. Set ringback delay timer so that local - * ringback will eventually be played. We delay the ringback for - * a short time to handle the case where the messages key was pressed. - * This is because VM server can respond very quickly with RTP, 183, - * and 200 and we do not want local ringback tone to interfere with - * the playing of the VM prompt. - */ - if (!cprIsTimerRunning(dcb->ringback_delay_tmr)) { - fsmdef_set_ringback_delay_timer(dcb); - } - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_FAR_END_ALERTING, - FSMDEF_CC_CALLER_ID); - - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - (void)fsmdef_release(fcb, CC_CAUSE_NO_MEDIA, dcb->send_release); - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_END); - } -// fsmdef_update_pd(dcb, FSMDEF_CALL_TYPE_OUTGOING); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_OUTGOING_ALERTING); - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_callsent_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_release_t *msg = (cc_release_t *) event->msg; - cc_causes_t cause = msg->cause; - cc_srcs_t src_id = msg->src_id; - sm_rcs_t sm_rc = SM_RC_END; - char tmp_str[STATUS_LINE_MAX_LEN]; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* if UI_STATE of BUSY in 183 Call-Info is causing the release, - do not modify dcb->send_release */ - if (cause != CC_CAUSE_UI_STATE_BUSY) { - dcb->send_release = FALSE; - } else { - // CSCti63677 - if ((fcb->state == FSMDEF_S_OUTGOING_ALERTING) && - (dcb->inband_received == TRUE) && - (dcb->placed_call_update_required)) { - - lsm_update_placed_callinfo(dcb); - dcb->placed_call_update_required = FALSE; - } - } - - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - /* For 500 response from the CCM, disconnect the call and clear the UI. - * There are several cases in which CCM sends down 500 response code to - * clear the call and UI. Some of the cases are CFWDALL, early conference - * and CTI transfer of ringing call - * - * Non-auto pickups do receive 480 response, it is OK release the call. - */ - if ((cause == CC_CAUSE_REMOTE_SERVER_ERROR) || - (((strncmp(dcb->caller_id.called_number, CISCO_BLFPICKUP_STRING, - (sizeof(CISCO_BLFPICKUP_STRING) - 1)) == 0)) && - ((cause == CC_TEMP_NOT_AVAILABLE) || (cause == CC_CAUSE_CONGESTION) ))) { - if (cause == CC_CAUSE_CONGESTION) { - if (platGetPhraseText(STR_INDEX_NO_CALL_FOR_PICKUP, (char *)tmp_str, STATUS_LINE_MAX_LEN - 1) == CPR_SUCCESS) - { - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, tmp_str, 2, FALSE, DEF_NOTIFY_PRI); - } - } - cause = CC_CAUSE_OK; - } - - switch (cause) { - case CC_CAUSE_ERROR: - case CC_CAUSE_NOT_FOUND: - case CC_CAUSE_BUSY: - case CC_CAUSE_CONGESTION: - case CC_CAUSE_INVALID_NUMBER: - case CC_CAUSE_PAYLOAD_MISMATCH: - case CC_CAUSE_REMOTE_SERVER_ERROR: - case CC_TEMP_NOT_AVAILABLE: - case CC_CAUSE_UI_STATE_BUSY: - case CC_CAUSE_NO_USER_ANS: - - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_CALL_FAILED, cause); - - if (cause != CC_CAUSE_UI_STATE_BUSY) { - cc_int_release_complete(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, cause, NULL); - } - /* see if the SIP stack has aborted this call early for some reason - * If SIP brought this down, we are still offhook on the UI, so - * when we get the release_complete from the 200 for the BYE, we - * need to ignore it, so that reorder can be played AND when the user - * hangs up, then the UI will be driven to a clean state. - */ - if (src_id == CC_SRC_SIP) { - dcb->early_error_release = TRUE; - } - - if ( dcb->err_onhook_tmr) { - (void) cprDestroyTimer(dcb->err_onhook_tmr); - } - dcb->err_onhook_tmr = cprCreateTimer("Error Onhook", - GSM_ERROR_ONHOOK_TIMER, - TIMER_EXPIRATION, - gsm_msg_queue); - if (dcb->err_onhook_tmr == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED), - dcb->call_id, dcb->line, "", "Error Onhook"); - return (SM_RC_CLEANUP); - } - - if (cprStartTimer(dcb->err_onhook_tmr, - FSMDEF_ERR_ONHOOK_TMR_SECS * 1000, - (void *)(long)dcb->call_id) == CPR_FAILURE) { - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_START_FAILED), - dcb->call_id, dcb->line, "", - "Error Onhook", cpr_errno); - - return (SM_RC_CLEANUP); - } - - break; - - default: - sm_rc = fsmdef_release(fcb, cause, dcb->send_release); - if (sm_rc == SM_RC_CLEANUP) { - /* - * FSM release indicates clean up, do not continue - * on since fcb and dcb have been freed or re-initialized. - */ - return (sm_rc); - } - } /* switch (cause) */ - - /*UI_STATE of BUSY in 183 is causing the release, so - *don't change state. This is needed to support - *callback feature. Since the callee is busy, we need - *update call UI status to "Busy" from "Ringout" to - *reflect this change. - */ - if (cause != CC_CAUSE_UI_STATE_BUSY) { - fsm_change_state(fcb, __LINE__, FSMDEF_S_RELEASING); - } else { - cc_action_data_t action_data; - action_data.update_ui.action = CC_UPDATE_SET_CALL_STATUS; - action_data.update_ui.data.set_call_status_parms.phrase_str_p = platform_get_phrase_index_str(LINE_BUSY); - action_data.update_ui.data.set_call_status_parms.timeout = 0; - action_data.update_ui.data.set_call_status_parms.call_id = dcb->call_id; - action_data.update_ui.data.set_call_status_parms.line = dcb->line; - /*Update UI status to "Busy".*/ - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - } - - return (sm_rc); -} - - -static sm_rcs_t -fsmdef_ev_callsent_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_causes_t cause; - cc_feature_data_redirect_t *data = &(msg->data.redirect); - cc_action_data_t action_data; - cc_feature_data_t *select_data = &(msg->data); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = select_data->caps.support_direction; - break; - case CC_FEATURE_NOTIFY: - if (src_id == CC_SRC_SIP) { - fsmdef_ev_notify_feature(msg, dcb); - } else { - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - - break; - - case CC_FEATURE_END_CALL: - /** - * In case of earlier attandence, there might a waiting call. - */ - lsm_remove_lcb_prevent_ringing(dcb->call_id); - /* - * Since user press the end call, no need to wait to play the busy tone. - * So, clear the early_error_release and clean the fcb/dcb. - */ - dcb->early_error_release = FALSE; - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - - return (fsmdef_release(fcb, cause, dcb->send_release)); - - case CC_FEATURE_REDIRECT: - /* - * The outgoing call has been redirected, so we need to: - * 1. ACK the redirect request, - * 2. release the current call, - * 3. start a new call to the redirect number. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, line, - CC_FEATURE_REDIRECT, NULL, CC_CAUSE_REDIRECT); - /* - * May need to update an xcb if this call is involved in a transfer. - */ - //xcb = fsmxfr_get_xcb_by_call_id(call_id); - // fsmxfr_update_xfr_context(xcb, call_id, redirect_call_id); - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, data->redirect_number); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_DIALING_COMPLETED, - FSMDEF_CC_CALLER_ID); - - break; - - - case CC_FEATURE_CALLINFO: - fsmdef_update_calltype(fcb, msg); - fsmdef_update_callinfo(fcb, msg); - /* - * lsm_set_lcb_prevent_ringing() will check if there is a RINGIN call - * with the same GCID. If so, it will set a flag to prevent ringing. - */ - lsm_set_lcb_prevent_ringing(dcb->call_id); - break; - - case CC_FEATURE_UPDATE: - /* Simply reply with a 200OK to a received UPDATE */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, line, - CC_FEATURE_UPDATE, NULL, CC_CAUSE_OK); - break; - - case CC_FEATURE_RINGBACK_DELAY_TIMER_EXP: - if (!dcb->inband_received) { - /* - * Ringback delay timer expired and we have not received - * a response from the far end indicating that they are - * playing inband ringback. Start local ringback tone now. - */ - action_data.tone.tone = VCM_ALERTING_TONE; - (void)cc_call_action(call_id, line, CC_ACTION_PLAY_TONE, - &action_data); - } - break; - - - case CC_FEATURE_SELECT: - fsmdef_select_invoke(dcb, select_data); - return (SM_RC_END); - - - case CC_FEATURE_SUBSCRIBE: - /* KPML subscription received so collect digits for KPML */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_KPML_COLLECT_INFO); - break; - - case CC_FEATURE_CFWD_ALL: - fsm_set_call_status_feature_unavailable(call_id, line); - - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) { */ - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_release_call (fsm_fcb_t *fcb, cc_feature_t *msg) -{ - cc_feature_data_t *data = &(msg->data); - cc_state_data_t state_data; - cc_causes_t cause; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - cause = fsmdef_get_cause(msg->data_valid, data); - - /* - * Do things a little different depending on the value of the - * release cause. - */ - switch (cause) { - case CC_CAUSE_XFER_LOCAL: - /* - * Send release and then wait for the release_complete. - */ - cc_int_release(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, data->endcall.cause, - data->endcall.dialstring, NULL); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_RELEASING); - - state_data.onhook.caller_id = dcb->caller_id; - state_data.onhook.local = TRUE; - state_data.onhook.cause = CC_CAUSE_NORMAL; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ONHOOK, &state_data); - - break; - - case CC_CAUSE_XFER_REMOTE: - /* - * No need to send release because the remote end initiated - * the transfer. - */ - dcb->send_release = FALSE; - return (fsmdef_release(fcb, cause, dcb->send_release)); - - case CC_CAUSE_XFER_CNF: - case CC_CAUSE_REPLACE: - /* - * We are the target of a transfer and this is the consultation - * call that is being replaced, so we just need to onhook this call - * but leave the signaling up until the stack notifies the FSM that - * the transfer is accepted - and then we will release the call. - * Same has to happen when bridge of conference ends the call. We are - * initiating transfer in this case so we want signaling to remain - * up while UI should be cleared up. - */ - state_data.onhook.caller_id = dcb->caller_id; - state_data.onhook.local = TRUE; - state_data.onhook.cause = CC_CAUSE_NORMAL; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ONHOOK, &state_data); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLDING); - - break; - - default: - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_inalerting_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_feature_data_t *data = &(msg->data); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - /* force an update to media cap */ - dcb->media_cap_tbl->id--; - gsmsdp_update_local_sdp_media_capability(dcb, FALSE, FALSE); - break; - - case CC_FEATURE_END_CALL: - return (fsmdef_release_call(fcb, msg)); - - case CC_FEATURE_ANSWER: - /* - * The user wants to answer this call, so... - * 1. need to place the connected call (if there is one) on hold, - * 2. clear all the outgoing ringing lines, - * 3. answer this call. - */ - if (fsmdef_wait_to_start_new_call(TRUE, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_ANSWER, NULL)) { - - /* - * Inform the LSM that the answering of this call has - * been delayed while waiting for other calls to clear. - */ - (void)cc_call_action(dcb->call_id, dcb->line, - CC_ACTION_ANSWER_PENDING, NULL); - - return (SM_RC_END); - } - - return (fsmdef_handle_inalerting_offhook_answer(event)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) { */ - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_UPDATE: - /* Simply reply with a 200 OK to a received UPDATE */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, line, - CC_FEATURE_UPDATE, NULL, CC_CAUSE_OK); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) { */ - - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (src_id) { */ - - return (SM_RC_END); -} - - -/* - * This function contains the common code for fsmdef_ev_inalerting_offhook() - * and the ANSWER event handling in the fsmdef_ev_inalerting_feature(). - */ -static sm_rcs_t -fsmdef_handle_inalerting_offhook_answer (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* Build our response SDP to include in the connected */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* For CCM, call_type indicate if the call is forwarded or not - * for forwarded call display will be shown as "Forward", only - * during ringing state. Once the call is connected then the call - * is shown as normal incoming call "From". so change call type now - * Do this only if Retain Forward Information is disabled or not configured. - * If configured/enabled then leave the call type as Forward. - */ - - if (dcb->call_type == FSMDEF_CALL_TYPE_FORWARD) { - if (!fsmdef_check_retain_fwd_info_state()) { - dcb->call_type = FSMDEF_CALL_TYPE_INCOMING; - /* - * Force us to update the UI so that any possible callinfo received - * prior to the call is answered takes effect. - */ - dcb->ui_update_required = TRUE; - } - } - - /* Cancel any existing autoanswer timer */ - (void)cprCancelTimer(dcb->autoAnswerTimer); - - cc_int_connected(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL, &msg_body); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_CONNECTED); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_ANSWERED, - FSMDEF_CC_CALLER_ID); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTING); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_inalerting_offhook (sm_event_t *event) -{ - return (fsmdef_handle_inalerting_offhook_answer(event)); -} - - -static sm_rcs_t -fsmdef_ev_connecting_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause; - cc_feature_data_t *data = &(msg->data); - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - break; - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - - return (fsmdef_release(fcb, cause, dcb->send_release)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - - return (fsmdef_release(fcb, cause, dcb->send_release)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } - - return (SM_RC_END); -} - -/** - * - * Function to handle transition to FSMDEF_S_CONNECTED. It checks - * whether there is any media capability that needs to be updated - * or not. If there is not then it transition to FSMDEF_S_CONNECTED - * otherwise it transitions to the FSMDEF_S_CONNECTED_MEDIA_PEND state - * and sends out the media update request. - * - * @param[in] fcb - The pointer to the fsm_fcb_t structure of this - * call. - * - * @return SM_RC_END or SM_RC_CLEANUP - * - * @pre (fcb not_eq NULL) - */ -static sm_rcs_t -fsmdef_transition_to_connected (fsm_fcb_t *fcb) -{ - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t feature_data; - sm_rcs_t sm_rc = SM_RC_END; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (dcb->req_pending_tmr) { - /* cancel any request pending timer, just in case */ - (void) cprCancelTimer(dcb->req_pending_tmr); - } - - /* - * Update the media capability without effecting the existing media line. - */ - if (!gsmsdp_update_local_sdp_media_capability(dcb, FALSE, FALSE)) { - /* not thing is changed, transition to connected state */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTED); - return (sm_rc); - } - - - feature_data.resume.call_info.type = CC_FEAT_NONE; - feature_data.resume.call_info.data.hold_resume_reason = CC_REASON_NONE; - feature_data.resume.msg_body.num_parts = 0; - feature_data.resume.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.resume.call_info.data.call_info_feat_data.protect = FALSE; - /* Encode SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, - &feature_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return(fsmdef_release(fcb, cause, dcb->send_release)); - } - - fsmdef_get_rtp_stat(dcb, &(feature_data.resume.kfactor)); - - /* Send feature request to SIP */ - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_MEDIA, &feature_data); - - - if (g_dock_undock_event == MEDIA_INTERFACE_UPDATE_STARTED) { - g_dock_undock_event = MEDIA_INTERFACE_UPDATE_IN_PROCESS; - ui_update_media_interface_change(dcb->line, dcb->call_id, MEDIA_INTERFACE_UPDATE_BEGIN); - } else if (g_dock_undock_event == MEDIA_INTERFACE_UPDATE_IN_PROCESS) { - DEF_DEBUG(DEB_F_PREFIX" MEDIA_INTERFACE_UPDATE is already in process. " - " Ignore another update event.\n", DEB_F_PREFIX_ARGS(FSM, "fsmdef_transition_to_connected")); - } - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTED_MEDIA_PEND); - return (sm_rc); -} - -static sm_rcs_t -fsmdef_ev_connected (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_connected"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_connected_t *msg = (cc_connected_t *) event->msg; - cc_causes_t cause; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - dcb->send_release = TRUE; - - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg->msg_body); - if (cause != CC_CAUSE_OK) { - - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - // Reset dcb->active_feature flag - dcb->active_feature = CC_FEATURE_NONE; - - /* Reset spoof ring out in case t was set before going to connected state. */ - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - - /* - * Cancel ringback delay timer - */ - if (cprCancelTimer(dcb->ringback_delay_tmr) != CPR_SUCCESS) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CANCEL_FAILED), - dcb->call_id, dcb->line, fname, "Ringback Delay", - cpr_errno); - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - - if ( dcb->log_disp != CC_CALL_LOG_DISP_UNKNWN ) { - ui_log_disposition(dcb->call_id, dcb->log_disp ); - } - - - ui_cc_capability(dcb->line, lsm_get_ui_id(dcb->call_id), msg->recv_info_list); - - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - (void)fsmdef_release(fcb, CC_CAUSE_NO_MEDIA, dcb->send_release); - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_END); - } - cc_int_connected_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_CONNECTED_ACK); - -// fsmdef_update_pd(dcb, FSMDEF_CALL_TYPE_OUTGOING); - - /* - * Handle media capability changes if there is before transition to - * connected state. - */ - sm_rc = fsmdef_transition_to_connected(fcb); - fsmutil_set_shown_calls_ci_element(dcb->caller_id.call_instance_id, dcb->line); - - return (sm_rc); -} - - -static sm_rcs_t -fsmdef_ev_connected_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_connected_ack_t *msg = (cc_connected_ack_t *) event->msg; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Check the remote SDP. The far end may not have included the SDP in an - * earlier message, which means that the SDP must be in this message. - */ - if (dcb->remote_sdp_in_ack == TRUE) { - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg->msg_body); - if (cause != CC_CAUSE_OK) { - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - (void)fsmdef_release(fcb, CC_CAUSE_NO_MEDIA, dcb->send_release); - cc_call_state(fcb->dcb->call_id, fcb->dcb->line, CC_STATE_UNKNOWN, - NULL); - return (SM_RC_END); - } - -// fsmdef_update_pd(dcb, FSMDEF_CALL_TYPE_INCOMING); - - /* - * Handle media capability changes if there is before transition to - * connected state. - */ - return (fsmdef_transition_to_connected(fcb)); -} - -/** - * The function handles local hold event but not sending any hold request - * out to the remote end. The local SDP is updated by the way. - * - * @param[in]fcb - pointer to fsm_fcb_t - * - * @return SM_RC_END or failrue. - * - * @pre (fcb not_eq NULL) - */ -static sm_rcs_t -fsm_hold_local_only (fsm_fcb_t *fcb) -{ - static const char fname[] = "fsm_hold_local_only"; - cc_state_data_t state_data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Check local hold status, and allow request if the media is not - * locally held. - */ - if (fsmdef_all_media_are_local_hold(dcb)) { - /* - * a new hold request is not allowed. Ignore the request - * but we should still ack the request. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_HOLD, NULL, CC_CAUSE_NORMAL); - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, dcb->line, - fname, "already hold"); - - return (SM_RC_END); - } - - state_data.hold.caller_id = dcb->caller_id; - state_data.hold.local = TRUE; - - /* - * Update the SDP so that offer indicates hold. Reinitialize the local - * sdp media to include all available codecs. We do this because our local - * list has been shortened to the one negotiated codec. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, TRUE, TRUE); - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_HOLD, &state_data); - - /* set all the media to local hold */ - fsmdef_update_media_hold_status(dcb, NULL, TRUE); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLDING); - - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT | CCSIP_SRC_SDP_BIT, - &dcb->sdp); - - return (SM_RC_END); -} - -/** - * The function handles local hold event. The function also supports - * re-sending hold request out such as during a glare condition. - * - * @param[in]fcb - pointer to fsm_fcb_t - * @param[in]data_p - pointer to the cc_feature_data_t of the - * hold feature. - * @param[in]resend - TRUE indicates to resend hold request. - * - * @return SM_RC_END or failrue. - * - * @pre (fcb not_eq NULL) - * @pre (data_p not_eq NULL) - */ -static sm_rcs_t -fsm_hold_local (fsm_fcb_t *fcb, cc_feature_data_t *data_p, - boolean resend) -{ - static const char fname[] = "fsm_hold_local"; - cc_state_data_t state_data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Check local hold status, and allow request if the media is not - * locally held or the caller indicates that to resend the hold - * request (such as in glare resolution). - */ - if (!resend && fsmdef_all_media_are_local_hold(dcb)) { - /* - * a new hold request is not allowed. Ignore the request - * but we should still ack the request. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_HOLD, NULL, - CC_CAUSE_NORMAL); - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, dcb->line, - fname, "already hold"); - return (SM_RC_END); - } - - state_data.hold.caller_id = dcb->caller_id; - state_data.hold.local = TRUE; - state_data.hold.reason = data_p->hold.call_info.data.hold_resume_reason; - - /* Store hold reason in case we need to resend the hold request due to - * request pending response. - */ - dcb->hold_reason = data_p->hold.call_info.data.hold_resume_reason; - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - - fsmdef_get_rtp_stat(dcb, &(data_p->hold.kfactor)); - - /* put the call on hold before building the SDP as DSP - * will then be able to give us a full set of codecs - * CUCM doesn't like to see a change in codecs on the fly - * ( i.e. without going to inactive state ) */ - cc_call_state(dcb->call_id, dcb->line, CC_STATE_HOLD, &state_data); - - /* - * Update the SDP so that offer indicates hold. Reinitialize the local - * sdp to include all available codecs. We do this because our - * local list has been shortened to the one negotiated codec. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, TRUE, TRUE); - - /* - * Do not expect any msg. body from local hold but free them - * just in case before build new SDP body to send out. - */ - cc_free_msg_body_parts(&data_p->hold.msg_body); - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &data_p->hold.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* set all the media to local hold */ - fsmdef_update_media_hold_status(dcb, NULL, TRUE); - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, data_p); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLDING); - - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT | CCSIP_SRC_SDP_BIT, - &dcb->sdp); - - return (SM_RC_END); -} - -/** - * Handles hold feature in connected media update pending state. - * - * @param[in] fcb The pointer to the fsm_fcb_t structure of this - * call chain. - * @param[in] data_p pointer to the cc_feature_data_t. - * - * @return sm_rsc_t indicates whether the execution of - * next statmachine to end or to clean up. - */ -static sm_rcs_t -fsm_connected_media_pend_local_hold (fsm_fcb_t *fcb, cc_feature_data_t *data_p) -{ - static const char fname[] = "fsm_hold_local_connected_media_pend"; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Check local hold status, and allow request if the media is not - * locally held. - */ - if (fsmdef_all_media_are_local_hold(dcb)) { - /* - * a new hold request is not allowed. Ignore the request - * but we should still ack the request. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_HOLD, NULL, - CC_CAUSE_NORMAL); - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, dcb->line, - fname, "already hold"); - return (SM_RC_END); - } - - if (dcb->req_pending_tmr && - cprIsTimerRunning(dcb->req_pending_tmr)) { - /* - * Request timer is running, that means we are waiting - * to re-send media update again due to previously glare. - * Since the previous offer has not been accepted, we can - * simply just send hold instead when glare resolution timer - * expires. - */ - - /* store the reason to resend when glare timer expires */ - dcb->hold_reason = data_p->hold.call_info.data.hold_resume_reason; - /* - * reset feature hold pending flag in case that there are - * multiple hold feature received while waiting for - * glare resolution to resolve. - */ - FSM_RESET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING); - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING); - return (SM_RC_END); - } - - /* - * We have sent media capability update out but have not received - * any response yet. The glare condition may occur but we can only - * assume that the media update was sent out at this point. - * We can not send out any more request until the result is - * known. We can not do any thing now but simply remember - * to re-send media with the hold feature pending when - * the result is known. - */ - FSM_SET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING); - return (SM_RC_END); -} - -/** - * common function to handles media feature from remote end. - * - * @param[in] fcb The pointer to the fsm_fcb_t structure of this - * call chain. - * @param[in] msg The pointer to cc_feature_t. - * - * @return sm_rsc_t indicates whether the execution of - * next statmachine to end or to clean up. - */ -static sm_rcs_t -fsmdef_remote_media (fsm_fcb_t *fcb, cc_feature_t *msg) -{ - static const char fname[] = "fsmdef_remote_media"; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t *data = &(msg->data); - cc_feature_data_t feature_data; - cc_causes_t cause; - boolean send_ack = TRUE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - memset(&feature_data, 0 , sizeof(cc_feature_data_t)); - /* - * Determine what type of RESUME/MEDIA this is: - * 1. third-party control is just trying to change the media - - * midcall-invite with no SDP, so we need to wait for the SDP - * in the SIP ACK before we can truly resume the media. - * 2. remote end wants to resume a held call or just a media - * changes. - * - * We can distinguish between the two because case 1 will not - * have any data and case 2 will have data. - */ - if (msg->data_valid == FALSE) { - /* - * Case 1. - * - * negotiate offer without SDP will reset all local media entries - * to have all codecs included. This is to re-advertise the - * capabilities again. - */ - (void) gsmsdp_negotiate_offer_sdp(fcb, NULL, FALSE); - - /* - * Update the media direction based on whether each media - * stream is locally held or not before sending out the - * offer SDP. - */ - fsmdef_set_per_media_local_hold_sdp(dcb); - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_MEDIA, - NULL); - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_START_RCV, - NULL); - } else { - /* - * SIP may send MEDIA feature when answer SDP is received in - * ACK. The secnario is found when remote resumes and the - * resume INVITE is a delayed media INVITE. We sent an offer in - * the 200 OK and gets the answer back in the ACK. In this - * case, SIP will send MEDIA feature to GSM. We need to check - * whether we are waiting for an answer in ACK or not and - * use the corresponding offer/answer SDP negotiation function. - */ - if (dcb->remote_sdp_in_ack) { - cause = gsmsdp_negotiate_answer_sdp(fcb, - &data->resume.msg_body); - if (cause != CC_CAUSE_OK) { - /* - * There is some thing wrong the answer SDP for some - * reason, can not go on. - */ - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * This is the answer to our previous offer, no need to - * to ack to SIP this one. - */ - send_ack = FALSE; - } else { - /* This is a new offer */ - - /* - * get k factor to be included in the feature ack. Getting - * the k factor needs to be done before maniputate media - * stream by the LSM. - */ - fsmdef_media_t *media = gsmsdp_find_audio_media(dcb); - if ((media) && (media->direction != SDP_DIRECTION_INACTIVE)) { - fsmdef_get_rtp_stat(dcb, &(feature_data.resume.kfactor)); - } - - cause = gsmsdp_negotiate_offer_sdp(fcb, - &data->resume.msg_body, FALSE); - if (cause != CC_CAUSE_OK) { - /* - * Received a sdp that cannot be accepted. - * It should just reject the new sdp offer rather than - * tearing down the call. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, msg->feature_id, NULL, cause); - return (SM_RC_END); - } - /* - * Update the media based on local hold. - */ - fsmdef_set_per_media_local_hold_sdp(dcb); - } - - /* - * If spoof ringout is not being requested and we are currently - * playing spoof ringout, transition the LSM from the far end alerting - * to the connected state. - */ - if ((!dcb->spoof_ringout_requested) && (dcb->spoof_ringout_applied)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } else { - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_MEDIA, - NULL); - } - } - - if (send_ack) { - /* Build SDP from our current SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &feature_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, msg->feature_id, &feature_data, - CC_CAUSE_NORMAL); - } - return (SM_RC_END); -} - -/** - * - * Function to handles connected state feature events. Function handles - * feature events generated by GSM, UI and SIP stack. - * - * @param sm_event_t event - * - * @return SM_RC_END or SM_RC_CLEANUP - * - * @pre (fcb->dcb not_eq NULL) - * @pre (event->data not_eq NULL) - * @pre (event->msg not_eq NULL) - */ -static sm_rcs_t -fsmdef_ev_connected_feature (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_connected_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *data = &(msg->data); - sm_rcs_t sm_rc; - cc_feature_data_t feature_data; - cc_action_data_t action_data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (msg->feature_id) { - case CC_FEATURE_HOLD: - /* If the line number is 0xFF, then this request - * came from GSM during a Transfer. We want to - * put the call on local hold only. We do not want - * to send a cc_feature to the SIP stack because - * that will cause an Invite Hold to go via SIP. - * We don't want to put the other end on hold, just - * ourselves. - */ - if (msg->line == 0xFF) { - sm_rc = fsm_hold_local_only(fcb); - } else { - if (msg->data_valid) { - sm_rc = fsm_hold_local(fcb, data, FALSE); - } else { - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - sm_rc = fsm_hold_local(fcb, &feature_data, FALSE); - } - - } - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_END_CALL: - sm_rc = fsmdef_release_call(fcb, msg); - - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_JOIN: - /* - * Send offhook to the new call that triggers the - * completion of the setup of the join in call - */ - fsmdef_ev_join(data); - break; - - case CC_FEATURE_SELECT: - if (msg->data_valid == FALSE) { - fsmdef_select_invoke(dcb, NULL); - } else { - fsmdef_select_invoke(dcb, data); - } - return (SM_RC_END); - - case CC_FEATURE_B2B_JOIN: - if (msg->data_valid == FALSE) { - fsmdef_b2bjoin_invoke(dcb, NULL); - } else { - fsmdef_b2bjoin_invoke(dcb, data); - } - return (SM_RC_END); - - case CC_FEATURE_DIRTRXFR: - case CC_FEATURE_UNDEFINED: - fsm_display_feature_unavailable(); - - fsmdef_handle_join_pending(dcb); - return (SM_RC_END); - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - // Force an re-INVITE by mismatching the id - dcb->media_cap_tbl->id--; - /* FALL THRU */ - case CC_FEATURE_UPD_MEDIA_CAP: - /* - * Media capability update request, check to see if - * there is any change in media capability and transition - * the pending state or stay in the connected state. - */ - sm_rc = fsmdef_transition_to_connected(fcb); - return (sm_rc); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - default: - fsmdef_handle_join_pending(dcb); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (msg->feature_id) */ - - break; - - case CC_SRC_SIP: - switch (msg->feature_id) { - - case CC_FEATURE_MEDIA: - /* - * remote send media update which can be resume or - * or just media changes. - */ - sm_rc = fsmdef_remote_media(fcb, msg); - return (sm_rc); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - action_data.update_ui.action = CC_UPDATE_CALL_PRESERVATION; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_UPDATE_UI, - &action_data); - fsm_change_state(fcb, __LINE__, FSMDEF_S_PRESERVED); - break; - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - case CC_FEATURE_UPDATE: - /* - * We only get an UPDATE feature event if we receive a medialess UPDATE. - * This type of event only conveys UI updates that are processed with - * a call info event. We do perform one check to see if we are currently - * spoofing ringout. If we are and the spoof ringout requested flag - * has been cleared, we tell the LSM to go connected. - */ - if ((!dcb->spoof_ringout_requested) && (dcb->spoof_ringout_applied)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - - /* - * For chaperone call, we will update call state here, to update - * the related key's status. - */ - if(dcb->policy == CC_POLICY_CHAPERONE){ - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - break; - - case CC_FEATURE_FAST_PIC_UPD: - - vcmMediaControl(CREATE_CALL_HANDLE(dcb->line, dcb->call_id), VCM_MEDIA_CONTROL_PICTURE_FAST_UPDATE); - - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (msg->feature_id) */ - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - -/** - * - * Function to handles connected state media update pending feature. - * - * @param sm_event_t event - * - * @return SM_RC_END or SM_RC_CLEANUP - * - * @pre (fcb->dcb not_eq NULL) - * @pre (event->data not_eq NULL) - * @pre (event->msg not_eq NULL) - */ -static sm_rcs_t -fsmdef_ev_connected_media_pend_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *data = &(msg->data); - sm_rcs_t sm_rc = SM_RC_END; - cc_feature_data_t feature_data; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (msg->feature_id) { - case CC_FEATURE_HOLD: - /* If the line number is 0xFF, then this request - * came from GSM during a Transfer. We want to - * put the call on local hold only. We do not want - * to send a cc_feature to the SIP stack because - * that will cause an Invite Hold to go via SIP. - * We don't want to put the other end on hold, just - * ourselves. - */ - if (msg->line == 0xFF) { - sm_rc = fsm_hold_local_only(fcb); - } else { - if (msg->data_valid) { - sm_rc = fsm_connected_media_pend_local_hold(fcb, data); - } else { - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - sm_rc = fsm_connected_media_pend_local_hold(fcb, - &feature_data); - } - } - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - /* FALL THRU */ - case CC_FEATURE_UPD_MEDIA_CAP: - /* We are already in the media update state */ - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - return (SM_RC_END); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - /* - * Glare resolution timer expires. - */ - if (FSM_CHK_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING)) { - /* There is a hold feature pending, send out hold instead */ - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - dcb->hold_reason; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - FSM_RESET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING); - return (fsm_hold_local(fcb, &feature_data, FALSE)); - } - - /* - * Check the possible media capbility changes. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, FALSE, FALSE); - feature_data.resume.call_info.type = CC_FEAT_NONE; - feature_data.resume.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.resume.msg_body.num_parts = 0; - feature_data.resume.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.resume.call_info.data.call_info_feat_data.protect = FALSE; - /* Encode SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, - &feature_data.resume.msg_body); - - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return(fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* Send feature request to SIP */ - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_MEDIA, &feature_data); - return (SM_RC_END); - - default: - /* - * The rest of the feature handles the same way as the - * connected feature handling. - */ - break; - } /* switch (msg->feature_id) */ - break; - - default: - /* - * The rest of the feature handles the same way as the - * connected feature handling. - */ - break; - } - - /* - * Unhandled features are handled by the normal connected feature - */ - return (fsmdef_ev_connected_feature(event)); -} - -/** - * - * Function to handles connected media update pending state feature ack - * events. - * - * @param sm_event_t event - * - * @return SM_RC_END or SM_RC_CLEANUP - * - * @pre (fcb->dcb not_eq NULL) - * @pre (event->data not_eq NULL) - * @pre (event->msg not_eq NULL) - */ -static sm_rcs_t -fsmdef_ev_connected_media_pend_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_connected_media_pend_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_features_t ftr_id = msg->feature_id; - cc_srcs_t src_id = msg->src_id; - cc_feature_data_t feature_data; - sm_rcs_t sm_rc = SM_RC_END; - cc_msgbody_info_t *msg_body; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - switch (src_id) { - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_MEDIA: - /* Media update feature ack from SIP */ - - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - /* - * The glare condition occurs from the previously sent - * media update. Starts a request pending timer so that - * we retry. - */ - fsmdef_set_req_pending_timer(dcb); - if (FSM_CHK_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING)) { - /* - * Feature hold is pending, abort the media capability - * update and retry with hold instead. - */ - FSM_RESET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING); - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING); - } - return (SM_RC_END); - } - - /* Check for error code reported */ - if ((msg->cause != CC_CAUSE_NORMAL) && - (msg->cause != CC_CAUSE_OK)) { - /* Unable to send media request */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG2), - dcb->call_id, dcb->line, fname, - " Media request failed, cause= ", msg->cause); - cc_call_state(dcb->call_id, dcb->line, CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - msg_body = &msg->data.resume.msg_body; - cause = gsmsdp_negotiate_answer_sdp(fcb, msg_body); - if (cause != CC_CAUSE_OK) { - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * Check to see if we have a feature request pending - */ - if (FSM_CHK_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING)) { - /* There is a hold feature pending, send out hold instead */ - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - dcb->hold_reason; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - FSM_RESET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING); - sm_rc = fsm_hold_local(fcb, &feature_data, FALSE); - } else { - /* - * If spoof ringout is not being requested and we are - * currently playing spoof ringout, transition the LSM from - * the far end alerting to the connected state. - */ - if ((!dcb->spoof_ringout_requested) && - (dcb->spoof_ringout_applied)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } else { - (void)cc_call_action(dcb->call_id, dcb->line, - CC_ACTION_MEDIA, NULL); - } - - /* - * Check any media capability changes that might occurs - * while we were in the middle of the previous transaction. - */ - sm_rc = fsmdef_transition_to_connected(fcb); - if (g_dock_undock_event != MEDIA_INTERFACE_UPDATE_NOT_REQUIRED) { - if (is_gsmsdp_media_ip_updated_to_latest(dcb) == TRUE) { - ui_update_media_interface_change(dcb->line, dcb->call_id, MEDIA_INTERFACE_UPDATE_SUCCESSFUL); - } else { - DEF_DEBUG("We must have received another MEDIA_INTERFACE_UPDATE events " - " while current MEDIA_INTERFACE_UPDATE event is in procoess. Sending re-invite again"); - escalateDeescalate(); - } - } - } - return (sm_rc); - - default: - break; - } - break; - - default: - break; - } - - /* call default feature ack handler to take common/default actions*/ - (void) fsmdef_ev_default_feature_ack(event); - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_offhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_action_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * User has gone offhook while using the speaker. - */ - data.speaker.on = FALSE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_SPEAKER, &data); - - //lsm_set_active_call_id(dcb->call_id); - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_connected_line (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - - /* - * Handle media capability changes if there is before transition to - * connected state. - */ - return (fsmdef_transition_to_connected(fcb)); -} - - -static sm_rcs_t -fsmdef_ev_onhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - sm_rcs_t sm_rc; - cc_action_data_t data; - int sdpmode = 0; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* currently this flag is only set by conference case. It signals - * that onhook has been received, do not process it anymore. - */ - if (dcb->onhook_received) { - dcb->onhook_received = FALSE; - return SM_RC_END; - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (sdpmode) { - if(dcb->ice_ufrag) - cpr_free(dcb->ice_ufrag); - - if(dcb->ice_pwd) - cpr_free(dcb->ice_pwd); - } - - /* - * If the user presses the ENDCALL softkey for an - * incoming call set the release cause to Busy. - */ - if (fcb->state == FSMDEF_S_INCOMING_ALERTING) { - sm_rc = fsmdef_release(fcb, CC_CAUSE_BUSY, dcb->send_release); - } else { - dcb->early_error_release = FALSE; - sm_rc = fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release); - } - - if (sm_rc == SM_RC_CLEANUP) { - /* This dcb has been cleaned up, do nothing more */ - return (sm_rc); - } else if (fcb->state == FSMDEF_S_HOLDING || - fcb->state == FSMDEF_S_HOLD_PENDING) { - data.ringer.on = TRUE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_RINGER, &data); - sm_rc = SM_RC_END; - } else { - sm_rc = SM_RC_END; - } - - return (sm_rc); -} - - -static sm_rcs_t -fsmdef_ev_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - dcb->send_release = FALSE; - - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - if (msg->cause == CC_CAUSE_REMOTE_DISCONN_REQ_PLAYTONE) { - - fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_CALL_FAILED, CC_CAUSE_REMOTE_DISCONN_REQ_PLAYTONE); - - /* what to return for return code */ - return(SM_RC_SUCCESS); - } else { - return (fsmdef_release(fcb, msg->cause, dcb->send_release)); - } -} - - -static sm_rcs_t -fsmdef_ev_releasing_release (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* see if the SIP stack has aborted this call early for some reason - * If SIP brought this down, we are still offhook on the UI. We - * need to ignore it, so that reorder can be played AND when the user - * hangs up, then the UI will be driven to a clean state. - */ - if (fcb->dcb->early_error_release == FALSE) { - - cc_int_release_complete(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - msg->cause, NULL); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_IDLE); - - fsmdef_free_dcb(dcb); - - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - fsm_release(fcb, __LINE__, msg->cause); - - return (SM_RC_CLEANUP); - } else { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SM_DEFAULT_EVENT)); - return (SM_RC_END); - } -} - - -static sm_rcs_t -fsmdef_ev_releasing_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause; - sm_rcs_t sm_rc = SM_RC_END; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (ftr_id) { - case CC_FEATURE_END_CALL: - cause = fsmdef_get_cause(msg->data_valid, &(msg->data)); - - /* Clean up call chain, no release sent */ - return (fsmdef_release(fcb, cause, FALSE)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - return (sm_rc); -} - - -static sm_rcs_t -fsmdef_ev_releasing_onhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* Clean up call chain, no release sent */ - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, FALSE)); -} - - -static sm_rcs_t -fsmdef_ev_release_complete (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (fcb->dcb == NULL) { - return (SM_RC_CLEANUP); - } - /* see if the SIP stack has aborted this call early for some reason - * If SIP brought this down, we are still offhook on the UI. We - * need to ignore it, so that reorder can be played AND when the user - * hangs up, then the UI will be driven to a clean state. - */ - if (fcb->dcb->early_error_release == FALSE) { - - fsm_change_state(fcb, __LINE__, FSMDEF_S_IDLE); - - fsmdef_free_dcb(fcb->dcb); - - fsm_release(fcb, __LINE__, - ((cc_release_complete_t *) (event->msg))->cause); - - return (SM_RC_CLEANUP); - - } else { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SM_DEFAULT_EVENT)); - return (SM_RC_END); - } -} - -static sm_rcs_t -fsmdef_ev_hold_pending_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = NULL; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_feature_data_t *data = &(msg->data); - cc_feature_data_t feature_data; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_UI): - case (CC_SRC_GSM): - switch (ftr_id) { - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - break; - - case CC_FEATURE_RESUME: - /* - * We will not be able to resume this call since we are in the - * hold pending state but we can place any other active call - * on hold. Find the connected call (if there is one) and place - * it on hold but not call if it is involved in a conference. - */ - if (msg->data.resume.cause != CC_CAUSE_CONF) { - if (fsmdef_wait_to_start_new_call(TRUE, src_id, call_id, line, - CC_FEATURE_RESUME, NULL)) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb != NULL) { - ccb->cnf_ftr_ack = FALSE; - } - } - } - return (SM_RC_END); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - dcb->hold_reason; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - sm_rc = fsm_hold_local(fcb, &feature_data, TRUE); - return sm_rc; - - case CC_FEATURE_END_CALL: - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_MEDIA: - return (fsmdef_remote_media(fcb, msg)); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - -/** - * feature ack event handler in hold pending state. - * - * @param[in] event Pointer to sm_event_t structure for feature ack event. - * - * @return Value of type sm_rcs_t to state machine - * - * @pre (event not_eqs NULL) and - * (event->data not_eqs NULL) and - * ((fsm_fcb_t *)(event->data)->dcb not_eqs NULL) - */ -static sm_rcs_t -fsmdef_ev_hold_pending_feature_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause; - cc_msgbody_info_t *msg_body; - cc_feature_data_t feature_data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_RESUME: - /* - * This is feature ack for resume. We received resume - * feature ack because the hold request was received while - * we are waiting to resume i.e. was in the - * resume pending state and resume request has been sent out. - * - * If the resume ack indicates glare, then ignore sending the - * resume and transition to holding (we were in hold and - * unable to send RESUME). Otherwise send hold out right away - * if there is no other error. - */ - fsm_sm_ftr(ftr_id, src_id); - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - /* - * The glare condition occurs from the previously sent - * resume transition to holding. - */ - (void)fsm_hold_local_only(fcb); - break; - } - - /* call default feature ack handler to take common/default actions*/ - (void) fsmdef_ev_default_feature_ack(event); - - if ((msg->cause != CC_CAUSE_NORMAL) && - (msg->cause != CC_CAUSE_OK)) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - if (msg->data_valid != TRUE) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - msg_body = &msg->data.resume.msg_body; - cause = gsmsdp_negotiate_answer_sdp(fcb, msg_body); - if (cause != CC_CAUSE_OK) { - return(fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * HOLD can be sent now. - */ - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - dcb->hold_reason; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - fsm_hold_local(fcb, &feature_data, FALSE); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_holding_release (sm_event_t *event) -{ - cc_release_t *msg = (cc_release_t *) event->msg; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (msg->cause != CC_CAUSE_XFER_LOCAL) { - fcb->dcb->send_release = FALSE; - } - - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - return (fsmdef_release(fcb, msg->cause, fcb->dcb->send_release)); -} - -static sm_rcs_t -fsmdef_ev_holding_onhook (sm_event_t *event) -{ - cc_onhook_t *msg = (cc_onhook_t *) event->msg; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (!(msg->softkey)) { - /* Meaning Hangup, ignore, a held call can't be hung up */ - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SM_DEFAULT_EVENT)); - return (SM_RC_END); - } - - /* - * Meaning EndCall softkey is sent, take down - * the call, this happens during failover. - */ - FSM_SET_FLAGS(dcb->msgs_rcvd, FSMDEF_MSG_RELEASE); - - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); -} - -/** - * - * fsmdef_reversion_timeout - Triggers LSM for doing Reversion alerts. - * - * @param fsmdef_dcb_t dcb for this call - * - * @return none - * - * @pre (dcb not_eq NULL) - */ - -void fsmdef_reversion_timeout(callid_t call_id) -{ - - int ret = CPR_SUCCESS; - - fsmdef_dcb_t *dcb = fsmdef_get_dcb_by_call_id(call_id) ; - - if ( (dcb == NULL ) || (dcb->fcb == NULL)) { - return; - } - - // check that we are in HOLDING state before proceeding - if ((dcb->fcb->state != FSMDEF_S_HOLDING) && - (dcb->fcb->state != FSMDEF_S_HOLD_PENDING)) { - return; - } - - if (dcb->reversionInterval > 0) { - ret = cprStartTimer(dcb->revertTimer, dcb->reversionInterval * 1000, (void*)(long)call_id); - } - - if ( ret == CPR_FAILURE ) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_START_FAILED), - dcb->call_id, dcb->line, "", "Reversion", cpr_errno); - return; - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_HOLD_REVERT, NULL); - -} - - -/** - * - * fsmdef_resume - Performs Resume Operation. - * - * @param sm_event_t event - * - * @return sm_rcs_t SM_RC_END - indicating the event has been consumed - * - * @pre (event not_eq NULL) - */ - -static void -fsmdef_resume (sm_event_t *event) -{ - - static const char fname[] = "fsmdef_resume"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmcnf_ccb_t *ccb = NULL; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_feature_data_t *data = &(msg->data); - cc_srcs_t src_id = msg->src_id; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_feature_data_t feature_data; - cc_causes_t cause; - boolean req_pending_tmr_running = FALSE; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * Ignore the request if local hold is not active. - */ - if (fsmdef_num_media_in_local_hold(dcb) == 0) { - /* - * No media in local held, should not happen here. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_RESUME, NULL, - CC_CAUSE_NORMAL); - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), call_id, dcb->line, - fname, "resume media not in hold state\n"); - return; - } - - (void) cprCancelTimer(dcb->revertTimer); - dcb->reversionInterval = -1; - /* - * Make sure the connected call (if there is one) goes on hold, - * but do not hold the connected call if it is involved in a - * conference. - */ - if (msg->data.resume.cause != CC_CAUSE_CONF) { - if (fsmdef_wait_to_start_new_call(TRUE, src_id, call_id, line, - CC_FEATURE_RESUME, (msg->data_valid ? - data : NULL))) { - - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb != NULL) { - ccb->cnf_ftr_ack = FALSE; - } - return ; - } - } - - /* Clear all media holding status */ - fsmdef_update_media_hold_status(dcb, NULL, FALSE); - - if (dcb->req_pending_tmr && cprIsTimerRunning(dcb->req_pending_tmr)) { - req_pending_tmr_running = TRUE; - } - - if (!req_pending_tmr_running) { - /* - * Reinitialize the local sdp to include all available codecs. - * We do this because it is possible that our local list - * may have been shortened to the one negotiated codec. This is - * the case when we receive an incoming call, we negotiate a - * single codec, copy it into the local sdp and send it back - * in the connected msg. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, TRUE, FALSE); - - if (msg->data_valid) { - feature_data.resume.call_info = data->resume.call_info; - } else { - feature_data.resume.call_info.type = CC_FEAT_RESUME; - feature_data.resume.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.resume.msg_body.num_parts = 0; - feature_data.resume.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.resume.call_info.data.call_info_feat_data.protect = FALSE; - } - /* Encode SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, - &feature_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - (void)fsmdef_release(fcb, cause, dcb->send_release); - return ; - } - } - - /* - * If spoof ringout is currently requested, transition to the - * far end alerting state instead of the connected state. - */ - if (dcb->spoof_ringout_requested) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, - "setting spoof_ringout_applied"); - - dcb->spoof_ringout_applied = TRUE; - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_FAR_END_ALERTING, FSMDEF_CC_CALLER_ID); - } else { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - /* Start receiving but not transmit, before sending resume */ - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_START_RCV, - NULL); - } - - if (!req_pending_tmr_running) { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_RESUME, &feature_data); - } - - /* - * We lock the UI until we learn the result of the resume request - */ - fim_lock_ui(call_id); - - /* Wait for feature ack */ - fsm_change_state(fcb, __LINE__, FSMDEF_S_RESUME_PENDING); - - return ; - -} - -/** - * - * fsmdef_ev_holding_offhook - Handles offhook in for holding state. - * - * @param sm_event_t event - * - * @return sm_rcs_t SM_RC_END - indicating the event has been consumed - * - * @pre (event not_eq NULL) - */ - -static sm_rcs_t -fsmdef_ev_holding_offhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (cprIsTimerRunning(dcb->revertTimer)) { - // Off hook resume calls only if HR is active else ignore this event - fsmdef_resume(event); - } - - return SM_RC_END; - -} - -static sm_rcs_t -fsmdef_ev_holding_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *data = &(msg->data); - cc_feature_data_t feature_data; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_UI): - case (CC_SRC_GSM): - switch (ftr_id) { - - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - break; - - case CC_FEATURE_HOLD: - if (msg->data_valid) { - sm_rc = fsm_hold_local(fcb, data, FALSE); - } else { - feature_data.hold.call_info.type = CC_FEAT_HOLD; - feature_data.hold.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.hold.msg_body.num_parts = 0; - feature_data.hold.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.hold.call_info.data.call_info_feat_data.protect = FALSE; - sm_rc = fsm_hold_local(fcb, &feature_data, FALSE); - } - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_HOLD_REVERSION: - // Stop the timer for alert interval - (void) cprCancelTimer(dcb->revertTimer); - dcb->reversionInterval = -1; - - // Do not revert if alertInterval is negative - if ( data->hold_reversion.alertInterval < 0 ) - return SM_RC_END; - // interval timer of 0 implies continue to revert - // Clamp the interval to be in MIN/MAX_HOLD_REVERSION_INTERVAL_TIMER - if ( data->hold_reversion.alertInterval > 0 && - data->hold_reversion.alertInterval < MIN_HOLD_REVERSION_INTERVAL_TIMER ) - data->hold_reversion.alertInterval = MIN_HOLD_REVERSION_INTERVAL_TIMER; - - if ( data->hold_reversion.alertInterval > MAX_HOLD_REVERSION_INTERVAL_TIMER ) - data->hold_reversion.alertInterval = MAX_HOLD_REVERSION_INTERVAL_TIMER; - - dcb->reversionInterval = data->hold_reversion.alertInterval ; - - fsmdef_reversion_timeout(fcb->dcb->call_id); - - fsmdef_handle_join_pending(dcb); - return SM_RC_END; - - case CC_FEATURE_RESUME: - fsmdef_resume(event); - break; - - case CC_FEATURE_END_CALL: - sm_rc = fsmdef_release_call(fcb, msg); - (void) cprCancelTimer(dcb->revertTimer); - dcb->reversionInterval = -1; - fsmdef_handle_join_pending(dcb); - return (sm_rc); - - case CC_FEATURE_SELECT: - if (msg->data_valid == FALSE) { - fsmdef_select_invoke(dcb, NULL); - } else { - fsmdef_select_invoke(dcb, data); - } - return (SM_RC_END); - - case CC_FEATURE_B2B_JOIN: - if (msg->data_valid == FALSE) { - fsmdef_b2bjoin_invoke(dcb, NULL); - } else { - fsmdef_b2bjoin_invoke(dcb, data); - } - return (SM_RC_END); - - case CC_FEATURE_DIRTRXFR: - case CC_FEATURE_UNDEFINED: - fsm_display_feature_unavailable(); - - fsmdef_handle_join_pending(dcb); - return (SM_RC_END); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - /* Ignore the request pending timer when in holding state */ - default: - fsmdef_handle_join_pending(dcb); - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_MEDIA: - return (fsmdef_remote_media(fcb, msg)); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - (void) cprCancelTimer(dcb->revertTimer); - dcb->reversionInterval = -1; - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - - -static sm_rcs_t -fsmdef_ev_holding_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_holding_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause = msg->cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - switch (src_id) { - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_HOLD: - if (cause == CC_CAUSE_REQUEST_PENDING) { - /* - * If this is feature ack for hold and request is pending, - * set a request pending timer so that we retry the hold - * feature request. - */ - fsmdef_set_req_pending_timer(dcb); - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING); - return (SM_RC_END); - } - - /* Check for error code reported */ - if ((cause != CC_CAUSE_NORMAL) && - (cause != CC_CAUSE_OK)) { - /* Unable to send hold request */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG2), - dcb->call_id, dcb->line, fname, - "HOLD request failed, cause= ", cause); - cc_call_state(dcb->call_id, dcb->line, CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - // update video_avail as we are not negotiating the answer below - dcb->cur_video_avail = SDP_DIRECTION_INACTIVE; - lsm_update_video_avail(dcb->line, dcb->call_id, dcb->cur_video_avail); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - /* call default feature ack handler to take common/default actions */ - (void) fsmdef_ev_default_feature_ack(event); - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_resume_pending_feature (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_resume_pending_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - callid_t call_id = msg->call_id; - cc_feature_data_t *data = &(msg->data); - cc_feature_data_t feature_data; - sm_rcs_t sm_rc; - cc_causes_t cause; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_UI): - switch (ftr_id) { - case CC_FEATURE_UPD_SESSION_MEDIA_CAP: - dcb->video_pref = data->caps.support_direction; - break; - - case CC_FEATURE_END_CALL: - fim_unlock_ui(call_id); - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - case CC_FEATURE_HOLD: - /* - * The UI should be locked but the hold event from UI here - * can be the result of other call chain wants to put this - * other call that may be in conected state or in resume - * pending state on hold. One example, the user want to - * resume a call that is on hold, that call chain will look - * for any other call in connected state or call in resume - * pending (about to be connected) and puts this call on hold. - * - * There are 2 choices here. If we are in this state and has - * not sent a resume out to the network, then simply - * transition to holding state. If resume has already - * been sent and we are here waiting for resume pending ack, - * then we can not send out hold immediately. In the later - * case, go to hold pending state and wait for resume - * feature ack to send hold out. - * - * In either case, UI can be unlocked since we are now - * about to hold again. - */ - fim_unlock_ui(dcb->call_id); - if (dcb->req_pending_tmr && - cprIsTimerRunning(dcb->req_pending_tmr)) { - /* - * Request timer is running, that means we are waiting - * to send resume or we already have sent one out - * but it resulted in glare condition and that we are waiting - * to resent it again. In this, just go back to hold state. - */ - (void) cprCancelTimer(dcb->req_pending_tmr); - - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, - "Received Hold while waiting to send resume\n"); - - /* Go back to holding without sending any thing out */ - (void)fsm_hold_local_only(fcb); - } else { - /* - * We have sent resume to the network and wait for - * for the feature ack. The glare condition can - * occur but we can only assume that resume was sent out - * at this point. We can not send out any more request - * until the result is known. - */ - if (msg->data_valid) { - dcb->hold_reason = - data->hold.call_info.data.hold_resume_reason; - } else { - dcb->hold_reason = CC_REASON_NONE; - } - // since we are going to hold stop the media now - // else the next new call or resume will result in 2 sets of media ports open - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_MEDIA, - NULL); - fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING); - } - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - case (CC_SRC_GSM): - switch (ftr_id) { - - case CC_FEATURE_HOLD: - sm_rc = fsm_hold_local_only(fcb); - fim_unlock_ui(call_id); - return (sm_rc); - - case CC_FEATURE_END_CALL: - fim_unlock_ui(call_id); - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - case CC_FEATURE_REQ_PEND_TIMER_EXP: - - /* - * Reinitialize the local sdp to include all available codecs. - * We do this because it is possible that our local list - * may have been shortened to the one negotiated codec. This is - * the case when we receive an incoming call, we negotiate a - * single codec, copy it into the local sdp and send it back - * in the connected msg. - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb, TRUE, FALSE); - - feature_data.resume.call_info.type = CC_FEAT_RESUME; - feature_data.resume.call_info.data.hold_resume_reason = - CC_REASON_NONE; - feature_data.resume.msg_body.num_parts = 0; - feature_data.resume.call_info.data.call_info_feat_data.swap = FALSE; - feature_data.resume.call_info.data.call_info_feat_data.protect = FALSE; - /* Encode SDP */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &feature_data.resume.msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* - * We lock the UI until we learn the result of the resume request. - */ - fim_lock_ui(call_id); - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - CC_FEATURE_RESUME, &feature_data); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - - break; - - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_MEDIA: - return (fsmdef_remote_media(fcb, msg)); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - case CC_FEATURE_CALL_PRESERVATION: - fim_unlock_ui(call_id); - return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release)); - - case CC_FEATURE_NOTIFY: - fsmdef_ev_notify_feature(msg, dcb); - break; - - case CC_FEATURE_UPDATE: - /* - * We only get an UPDATE feature event if we receive a medialess UPDATE. - * This type of event only conveys UI updates that are processed with - * a call info event. We do perform one check to see if we are currently - * spoofing ringout. If we are and the spoof ringout requested flag - * has been cleared, we tell the LSM to go connected which halts the - * spoofed ringout. - */ - if ((!dcb->spoof_ringout_requested) && (dcb->spoof_ringout_applied)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_CLR_SPOOF_APPLD), - dcb->call_id, dcb->line, fname); - - dcb->spoof_ringout_applied = FALSE; - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - -/** - * feature ack event handler in resume pending state. - * - * @param[in] event Pointer to sm_event_t structure for feature ack event. - * - * @return Value of type sm_rcs_t to state machine - * - * @pre (event not_eqs NULL) and - * (event->data not_eqs NULL) and - * ((fsm_fcb_t *)(event->data)->dcb not_eqs NULL) - */ -static sm_rcs_t -fsmdef_ev_resume_pending_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmdef_ev_resume_pending_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_causes_t cause; - cc_msgbody_info_t *msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case (CC_SRC_SIP): - switch (ftr_id) { - case CC_FEATURE_HOLD: - /* - * This can occur because SIP stack has not sent HOLD out yet - * but the user has pressed resume since we already moved - * to HOLD state as soon as the user pressed HOLD. Ignore the - * HOLD feature ACK except if it indicates error. If we get - * REQUEST_PENDING, we'll just move to connected state. - */ - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - fsm_change_state(fcb, __LINE__, FSMDEF_S_CONNECTED); - return (SM_RC_END); - } - if ((msg->cause != CC_CAUSE_NORMAL) && - (msg->cause != CC_CAUSE_OK)) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - case CC_FEATURE_RESUME: - /* - * If this is feature ack for resume and request is pending, - * set a request pending timer so that we retry the resume - * feature request. Otherwise, unlock the UI and continue - * processing. - */ - fsm_sm_ftr(ftr_id, src_id); - if ( msg->cause == CC_CAUSE_REQUEST_PENDING ) { - fsmdef_set_req_pending_timer(dcb); - return (SM_RC_END); - } else { - fim_unlock_ui(dcb->call_id); - } - /* call default feature ack handler to take common/default actions*/ - (void) fsmdef_ev_default_feature_ack(event); - - if ((msg->cause == CC_CAUSE_SERV_ERR_UNAVAIL) && - (dcb->hold_reason == CC_REASON_MONITOR_UPDATE)) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), - dcb->call_id, dcb->line, fname, - "msg->cause == CC_CAUSE_SERV_ERR_UNAVAIL, unable to monitor update\n"); - return (fsmdef_transition_to_connected(fcb)); - } - - if ((msg->cause != CC_CAUSE_NORMAL) && - (msg->cause != CC_CAUSE_OK)) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - if (msg->data_valid != TRUE) { - cc_call_state(dcb->call_id, dcb->line, - CC_STATE_UNKNOWN, NULL); - return(fsmdef_release(fcb, CC_CAUSE_ERROR, dcb->send_release)); - } - - msg_body = &msg->data.resume.msg_body; - cause = gsmsdp_negotiate_answer_sdp(fcb, msg_body); - if (cause != CC_CAUSE_OK) { - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - if (!dcb->spoof_ringout_applied) { - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - FSMDEF_CC_CALLER_ID); - } - /* - * Handle media capability changes if there is before transition - * to connected state to catch any changes during resume - * transaction. - */ - return (fsmdef_transition_to_connected(fcb)); - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - /* call default feature ack handler to take common/default actions */ - (void) fsmdef_ev_default_feature_ack(event); - - return (SM_RC_END); -} - -static sm_rcs_t -fsmdef_ev_preserved_feature (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - sm_rcs_t sm_rc; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fsm_sm_ftr(ftr_id, src_id); - - switch (src_id) { - case CC_SRC_UI: - case CC_SRC_GSM: - switch (msg->feature_id) { - - case CC_FEATURE_END_CALL: - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - break; - } - - break; - - case CC_SRC_SIP: - switch (msg->feature_id) { - case CC_FEATURE_HOLD: - case CC_FEATURE_RESUME: - sm_rc = fsmdef_release_call(fcb, msg); - return (sm_rc); - - case CC_FEATURE_MEDIA: - sm_rc = fsmdef_remote_media(fcb, msg); - return (sm_rc); - - case CC_FEATURE_CALLINFO: - fsmdef_update_callinfo(fcb, msg); - break; - - default: - fsmdef_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (msg->feature_id) */ - - break; - - default: - fsmdef_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (SM_RC_END); -} - -cc_int32_t -fsmdef_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsmdef_dcb_t *dcb; - fsm_fcb_t *fcb; - int i = 0; - callid_t call_id; - unsigned long strtoul_result; - char *strtoul_end; - - PR_ASSERT( i == 0 ); - /* - * Check if need help. - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("%s", "show fsmdef [all|rel]\n"); - } else if ((argc == 1) || (strcmp(argv[1], "all") == 0)) { - debugif_printf("%s", "\n-------- FSMDEF dcbs --------"); - debugif_printf("%s", "\ni call_id dcb line"); - debugif_printf("%s", "\n-----------------------------\n"); - - /* - * Print info for all dcbs. - */ - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - debugif_printf("%-2d %-7d 0x%8p %-4d\n", - i++, dcb->call_id, dcb, dcb->line); - } - } else if (strcmp(argv[1], "rel") == 0) { - errno = 0; - strtoul_result = strtoul(argv[2], &strtoul_end, 10); - - if (errno || argv[2] == strtoul_end || strtoul_result > USHRT_MAX) { - debugif_printf("%s parse error of call_id %s", __FUNCTION__, argv[2]); - return 0; - } - - call_id = (callid_t) strtoul_result; - - debugif_printf("\nDEF %-4d/%d: releasing\n", call_id, 0); - - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if (fcb == NULL) { - return (0); - } - - (void)fsmdef_release(fcb, CC_CAUSE_NORMAL, fcb->dcb->send_release); - } - return (0); -} - -/** - * - * This function is called to determine if the phone - * is in a state where autoAnswer is supported. Even - * if the feature is enabled on the line being called, - * the phone may be in a state that does not allow it. - * - * @param autoAnswerAlt to indicate what states auto answer enabled. - * @param myCallId call_id - * - * @return TRUE or FALSE - * - */ -static int -fsmdef_check_auto_answer_allowed (int autoAnswerAlt, callid_t myCallId) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->call_id != myCallId && dcb->fcb != NULL) { - /* - * autoAnswer is disabled if there is an incoming or an - * outgoing call that has not reached the connected state - * regardless of the value of autoAnswerAlt. - */ - if ((dcb->fcb->state == FSMDEF_S_COLLECT_INFO) || - (dcb->fcb->state == FSMDEF_S_CALL_SENT) || - (dcb->fcb->state == FSMDEF_S_OUTGOING_PROCEEDING) || - (dcb->fcb->state == FSMDEF_S_KPML_COLLECT_INFO) || - (dcb->fcb->state == FSMDEF_S_CONNECTING) || - (dcb->fcb->state == FSMDEF_S_JOINING)) { - return (FALSE); - } - - /* - * If autoAnswerAlt is 1, then autoAnswer is also - * disabled if there is a connected call or a call - * on hold. - */ - if (autoAnswerAlt == 1) { - if ((dcb->fcb->state == FSMDEF_S_CONNECTED) || - (dcb->fcb->state == FSMDEF_S_PRESERVED) || - (dcb->fcb->state == FSMDEF_S_RESUME_PENDING) || - (dcb->fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND) || - (dcb->fcb->state == FSMDEF_S_HOLDING) || - (dcb->fcb->state == FSMDEF_S_OUTGOING_ALERTING) || - (dcb->fcb->state == FSMDEF_S_INCOMING_ALERTING) || - (dcb->fcb->state == FSMDEF_S_HOLD_PENDING)) { - - return (FALSE); - } - } else if (autoAnswerAlt == 0) { - if ((dcb->fcb->state == FSMDEF_S_CONNECTED) || - (dcb->fcb->state == FSMDEF_S_PRESERVED) || - (dcb->fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND) || - (dcb->fcb->state == FSMDEF_S_OUTGOING_ALERTING)) { - - return (FALSE); - } - } - } - } - - return (TRUE); -} - -/** - * - * This function is called when a call is received on a - * line that has auto answer enabled and the autoAnswer - * timer has expired. - * - * @param data pointer to opaque data - * - * @return none - * - * @pre (fcb and fcb->dcb not_eq NULL) - * @pre (data should be fcb data) - */ - -void -fsmdef_auto_answer_timeout (void *data) -{ - static const char fname[] = "fsmdef_auto_answer_timeout"; - int autoAnswerAlternate = 0; - int autoAnswerOverride = 0; - int headSetActive = 0; - int speakerEnabled = 1; - callid_t call_id; - char autoAnswerMode[MAX_LINE_AUTO_ANS_MODE_SIZE]; - fsmdef_dcb_t *dcb; - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG1), 0, 0, fname, "invalid data"); - return; - } - - /* Retrieve dcb from call id */ - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - /* - * The only way this should happen is for the - * call to be released without cancelling the - * autoAnswer timer. - */ - FSM_DEBUG_SM(DEB_F_PREFIX"AutoAnswer timer expired but no dcb was found.\n", DEB_F_PREFIX_ARGS(FSM, fname)); - return; - } - - /* - * The device-based config parameter autoAnswerIdleAlternate - * determines what state the phone must be in for autoAnswer - * feature to be enabled. - */ - config_get_value(CFGID_AUTOANSWER_IDLE_ALTERNATE, &autoAnswerAlternate, - sizeof(autoAnswerAlternate)); - - if (fsmdef_check_auto_answer_allowed(autoAnswerAlternate, dcb->call_id)) { - /* - * Is headset active? No need to check if headset has been disabled - * on the phone because the headset will never be active if it has. - */ - headSetActive = platGetAudioDeviceStatus(VCM_AUDIO_DEVICE_HEADSET); - - /* - * If function call fails, just assume headset is not active - * and drive on - */ - if (headSetActive == -1) { - FSM_DEBUG_SM(DEB_F_PREFIX"platGetAudioDeviceStatus() for headset failed.\n", DEB_F_PREFIX_ARGS(FSM, fname)); - headSetActive = 0; - } - - /* - * Determine where the audio should be sent - */ - config_get_line_string(CFGID_LINE_AUTOANSWER_MODE, autoAnswerMode, - dcb->line, sizeof(autoAnswerMode)); - - /* - * Check to see if the speaker has been disabled - */ - config_get_value(CFGID_SPEAKER_ENABLED, &speakerEnabled, - sizeof(speakerEnabled)); - - /* - * autoAnswer using speaker - */ - if (strcasestr(autoAnswerMode, "speaker")) { - /* - * Speaker has not been disabled, normal processing. - */ - if (speakerEnabled) { - /* - * Enable audio path to speaker if headset is not being used. - */ - if (!headSetActive) { - platSetSpeakerMode(TRUE); - } - /* Send offhook event to GSM */ - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_ANSWER, NULL); - } else { - - /* - * Speaker is disabled, but autoAnswer is enabled and says to - * use the speaker. Check the device-based override - * parameter to see what action to take. If override is - * set just return and let normal call processing happen. - * If not, terminate the call. The best SIP response we - * could come up in this situation is to send a 480 - * Temporarily Unavailable. - */ - config_get_value(CFGID_AUTOANSWER_OVERRIDE, &autoAnswerOverride, - sizeof(autoAnswerOverride)); - if (!autoAnswerOverride) { - fsmdef_end_call(dcb, CC_TEMP_NOT_AVAILABLE); - } - - } - } else if (strcasestr(autoAnswerMode, "headset")) { - /* - * autoAnswer using headset. If headset is not enabled just let - * the phone ring normally. - */ - if (headSetActive) { - /* Send offhook event to GSM */ - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_ANSWER, NULL); - } - } else { - /* - * Unknown autoAnswer mode - */ - FSM_DEBUG_SM(DEB_F_PREFIX"Unknown autoAnswer Mode: %s AutoAnswer is disabled.\n", - DEB_F_PREFIX_ARGS(FSM, fname), autoAnswerMode); - } - } -} - -/* - * fsmdef_b2bjoin_invoke - * - * Description: - * This function implements the b2bjoin feature invocation. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with this call - * - * Returns: None - */ -static void -fsmdef_b2bjoin_invoke (fsmdef_dcb_t *dcb, cc_feature_data_t *join_data) -{ - cc_feature_data_t feature_data; - int join_across_lines; - cc_uint32_t major_ver; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - // Disable Join if the CUCM doesn't support it - platGetSISProtocolVer(&major_ver, NULL, NULL, NULL); - - if ( major_ver < SIS_PROTOCOL_MAJOR_VERSION_UNISON ) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1), dcb->call_id, dcb->line, - "fsmdef_b2bjoin_invoke", "Major sis is small than SIS_PROTOCOL_MAJOR_VERSION_UNISON, so, B2BJOIN is disabled"); - fsm_display_feature_unavailable(); - fsmdef_sm_ignore_ftr(dcb->fcb, __LINE__, CC_FEATURE_B2B_JOIN); - return; - } - - config_get_value(CFGID_JOIN_ACROSS_LINES, - &join_across_lines, sizeof(join_across_lines)); - /* - * Invoke B2BJoin feature towards SIP. It will send a REFER to CCM - */ - if (join_data) { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_B2B_JOIN, join_data); - } else { - - if ((g_b2bjoin_pending == FALSE) && (dcb->fcb->state == FSMDEF_S_HOLDING) - && ((fsmdef_get_connected_call() != NULL) || - (fsmdef_get_alertingout_call() != NULL))) { - /* Single Button Join case - * If Join is pressed on a held call while there is - * an active(connected or alerting) call, that completes the Join - */ - feature_data.b2bjoin.b2bjoin_callid = dcb->call_id; - feature_data.b2bjoin.b2bjoin_joincallid = dcb->call_id; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_B2B_JOIN, &feature_data); - return; - } - - if ((g_numofselected_calls == 0) || - ((g_b2bjoin_pending == FALSE) && (join_across_lines == JOIN_ACROSS_LINES_DISABLED) && - (fsmdef_are_there_selected_calls_onotherline(dcb->line) == TRUE))) { - dcb->active_feature = CC_FEATURE_B2B_JOIN; - feature_data.select.select = TRUE; - fsmdef_select_invoke(dcb,&feature_data); - fsm_display_use_line_or_join_to_complete(); - return; - } - if (g_b2bjoin_pending) { - if (join_across_lines == JOIN_ACROSS_LINES_DISABLED) { - if (fsmdef_are_join_calls_on_same_line(dcb->line) == FALSE) { - - fsm_display_use_line_or_join_to_complete(); - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; - return; - } - } - if (dcb->call_id== g_b2bjoin_callid) { - /* If join is pending, pressing Join on the same call will cancel it */ - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; - /* Remove the check mark from it*/ - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_SELECT, NULL); - return; - } - feature_data.b2bjoin.b2bjoin_callid = dcb->call_id; - if( g_b2bjoin_callid == CC_NO_CALL_ID ){ - feature_data.b2bjoin.b2bjoin_joincallid = dcb->call_id; - } - else{ - feature_data.b2bjoin.b2bjoin_joincallid = g_b2bjoin_callid; - } - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_B2B_JOIN, &feature_data); - - } else { - if ((g_numofselected_calls == 1) && (dcb->selected)) { - /* - * If this is only one selected call, pressing - * Join on it will start a new join operation - */ - g_b2bjoin_pending = TRUE; - g_b2bjoin_callid = dcb->call_id; - fsm_display_use_line_or_join_to_complete(); - return; - } - feature_data.b2bjoin.b2bjoin_callid = dcb->call_id; - feature_data.b2bjoin.b2bjoin_joincallid = dcb->call_id; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_B2B_JOIN, &feature_data); - } - } - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; -} - -/* - * fsmdef_select_invoke - * - * - * Description: - * This function implements the join feature invocation. - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with this call - * - * Returns: None - */ -static void -fsmdef_select_invoke (fsmdef_dcb_t *dcb, cc_feature_data_t *select_data) -{ - cc_feature_data_t feature_data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (dcb->select_pending) { - /* We have sent a select but have not received a - * response yet, so diallow further selects till then - */ - return; - } - if (select_data) { - feature_data.select.select = select_data->select.select; - } else { - if (dcb->selected == TRUE) { - feature_data.select.select = FALSE; - } else { - feature_data.select.select = TRUE; - } - } - if ((g_b2bjoin_pending) && (dcb->call_id== g_b2bjoin_callid)) { - /* If join is pending, pressing Select on the same call cancels join*/ - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; - } - dcb->select_pending = TRUE;; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_SELECT, &feature_data); -} - -/* - * handle_join_pending - * - * - * Description: - * This function checks if the join_pending flag - * needs to be cleared.due to the invocation of other features - * - * Parameters: - * fsmdef_dcb_t *dcb - dcb associated with this call - * - * Returns: None - */ -static void fsmdef_handle_join_pending (fsmdef_dcb_t *dcb) -{ - if ((g_b2bjoin_pending) && (dcb->call_id == g_b2bjoin_callid)) { - /* If join is pending, invoking any other feature cancels join*/ - g_b2bjoin_pending = FALSE; - g_b2bjoin_callid = CC_NO_CALL_ID; - } -} - - -/* - * fsmdef_process_dialstring_for_callfwd - * - * Description: - * This function processes the dialstring event for callfwd. - * - * Parameters: - * sm_event_t *event - data associated with this call/dialstring - * - * Returns: sm_rcs_t - */ -static sm_rcs_t -fsmdef_process_dialstring_for_callfwd (sm_event_t *event) -{ - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* - * For ccm case just return success. - * It will continue the call by sending INVITE - */ - return (SM_RC_SUCCESS); -} - - -/* - * fsmdef_process_cfwd_softkey_event - * - * Description: - * This function processes the cfwd softkey press event for callfwd. - * - * Parameters: - * sm_event_t *event - data associated with this call/dialstring - * - * Returns: sm_rcs_t - */ -static sm_rcs_t -fsmdef_process_cfwd_softkey_event (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_t *msg = (cc_feature_t *) event->msg; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *ftr_data = &(msg->data); - cc_action_data_t cc_data; - int skMask[MAX_SOFT_KEYS]; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - // check if callfwd is active (i.e. set previously) - if (lsm_check_cfwd_all_ccm(dcb->line)) { - // call fsmdef_dialstring() version of the function specific - // to cfwd feature - return (fsmdef_cfwd_clear_ccm(fcb)); - } - - - // code from here on is common to both modes/feature_id - if (fcb->state == FSMDEF_S_IDLE) { - - /* - * The user is attempting to start a cfwdall call on a specific line: - * 1. need to place the connected call (if there is one) on hold, - * 2. clear any outgoing ringing calls, - * 3. initiate this call. - */ - if (fsmdef_wait_to_start_new_call(TRUE, CC_SRC_GSM, dcb->call_id, dcb->line, ftr_id, ftr_data)) - { - dcb->active_feature = CC_FEATURE_NONE; - return (SM_RC_END); - } - - - // go offhook and then move to dialing state to collect digits - //only contains in initial NOTIFY to CUCM - fsmdef_notify_hook_event(fcb,CC_MSG_OFFHOOK, - ftr_data->newcall.global_call_id, - ftr_data->newcall.prim_call_id, - ftr_data->newcall.hold_resume_reason, - CC_MONITOR_NONE, - (ftr_id == CC_FEATURE_CFWD_ALL) ? CFWDALL_SET:CFWDALL_NONE); - cc_call_state(dcb->call_id, dcb->line, CC_STATE_OFFHOOK, - ((cc_state_data_t *) (&(dcb->caller_id)))); - - fsmdef_call_cc_state_dialing(dcb, FALSE); - - // stop the dial tone for parity with SCCP phone behavior - cc_data.tone.tone = VCM_INSIDE_DIAL_TONE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_TONE, - &cc_data); - - // give different (zip-zip) tone rather than dial tone. zip_zip - // is not a permanent tone so it will end on it's own without - // us telling media termination to stop playing the tone. - cc_data.tone.tone = VCM_ZIP_ZIP; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_PLAY_TONE, - &cc_data); - - // move to collect digit info state - fsm_change_state(fcb, __LINE__, FSMDEF_S_COLLECT_INFO); - } else { // we must be in FSMDEF_S_COLLECT_INFO state - // stop the dial tone for parity with SCCP phone behavior - cc_data.tone.tone = VCM_INSIDE_DIAL_TONE; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_TONE, - &cc_data); - - // give different (zip-zip) tone rather than dial tone. zip_zip - // is not a permanent tone so it will end on it's own without - // us telling media termination to stop playing the tone. - cc_data.tone.tone = VCM_ZIP_ZIP; - (void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_PLAY_TONE, - &cc_data); - } - ui_control_feature(dcb->line, dcb->call_id, skMask, 1, FALSE); - - return (SM_RC_END); -} - -/** - * This function is a reduced version of the fsmdef_dialstring() function. - * It is customized for sending INVITE out to CCM to clear CFA state. - * - * @param[in] fcb The pointer to the fsm_fcb_t structure of this - * call chain. - * - * @pre (fcb not_eq NULL) - * - * @return sm_rsc_t indicates whether the execution of - * next statmachine. - */ -static sm_rcs_t -fsmdef_cfwd_clear_ccm (fsm_fcb_t *fcb) -{ - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - cc_msgbody_info_t msg_body; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - // to clear CFA in CCM mode... only put service uri... no dialstring. - fsmdef_append_dialstring_to_feature_uri(dcb, NULL); - - // From here on all we need to do is send INVITE out. - // Since, its not a real call there is no need to update UI etc. - // Response to this call will be 5xx so it will be released by the SIP stack. - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - - /* Build SDP for sending out */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - return (fsmdef_release(fcb, cause, dcb->send_release)); - } - cc_int_setup(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), dcb->alert_info, VCM_INSIDE_RING, - VCM_INSIDE_DIAL_TONE, NULL, NULL, FALSE, NULL, &msg_body); - - /* - * Since we are sending setup to UI we will also have to send - * release to it to for sip stack to clean up the call - */ - dcb->send_release = TRUE; - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_SETUP); - - fsm_change_state(fcb, __LINE__, FSMDEF_S_CALL_SENT); - return (SM_RC_END); -} - -/* - * fsmdef_append_dialstring_to_feature_uri - * - * Description: - * This function appends dialstring to feature URI. - * - * Parameters: - * fsmdef_dcb_t *dcb, char *dialstring - * - * Return Value: none - * - * Note: TNP specific implementation. - */ -static void -fsmdef_append_dialstring_to_feature_uri (fsmdef_dcb_t *dcb, - const char *dialstring) -{ - char service_uri[MAX_URL_LENGTH]; - - service_uri[0] = '\0'; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (dcb == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_INVALID_DCB), - __FUNCTION__); - return; - } - - switch (dcb->active_feature) { - case CC_FEATURE_CFWD_ALL: - config_get_string(CFGID_CALL_FORWARD_URI, service_uri, - sizeof(service_uri)); - break; - default: - // do nothing - break; - } - - if (service_uri[0] != NUL) { - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, service_uri); - if (dialstring && dialstring[0]) { - dcb->caller_id.called_number = - strlib_append(dcb->caller_id.called_number, "-"); - dcb->caller_id.called_number = - strlib_append(dcb->caller_id.called_number, dialstring); - } - } else { - FSM_DEBUG_SM(DEB_F_PREFIX"Configured Feature/Service URI Not Found For Feature[%d]\n", DEB_F_PREFIX_ARGS(FSM, "fsmdef_append_dialstring_to_feature_uri"), (int)dcb->active_feature); - - if (dialstring && dialstring[0]) { - dcb->caller_id.called_number = - strlib_update(dcb->caller_id.called_number, dialstring); - } - } -} - - -/* - * fsmdef_is_feature_uri_configured - * - * Description: - * This function checks is a feature URI is configured. - * - * Parameters: - * cc_features_t ftr_id - * - * Return Value: TRUE or FALSE - * - * Note: TNP specific implementation. - */ -static boolean -fsmdef_is_feature_uri_configured (cc_features_t ftr_id) -{ - char service_uri[MAX_URL_LENGTH]; - - service_uri[0] = '\0'; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - switch (ftr_id) { - case CC_FEATURE_CFWD_ALL: - config_get_string(CFGID_CALL_FORWARD_URI, service_uri, - sizeof(service_uri)); - break; - default: - break; - } - - if (service_uri[0] != NUL) { - return TRUE; - } - - FSM_DEBUG_SM(DEB_F_PREFIX"Configured Feature/Service URI Not Found For Feature[%d]\n", DEB_F_PREFIX_ARGS(FSM, "fsmdef_is_feature_uri_configured"), (int)ftr_id); - return FALSE; -} - -/* - * fsmdef_check_if_ok_for_dial_call - * - * Description: - * This function checks if there is a call in collecting info state - * on a given line. - * - * Parameters: - * line_t line - * - * Returns: TRUE or FALSE - */ -boolean -fsmdef_check_if_ok_for_dial_call (line_t line) -{ - - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (((dcb->line == line) && (dcb->call_id != CC_NO_CALL_ID)) && - (dcb->fcb != NULL) && - ((dcb->fcb->state == FSMDEF_S_COLLECT_INFO) || - (dcb->fcb->state == FSMDEF_S_CALL_SENT) || - (dcb->fcb->state == FSMDEF_S_OUTGOING_PROCEEDING) || - (dcb->fcb->state == FSMDEF_S_KPML_COLLECT_INFO))) { - return (TRUE); - } - } - return (FALSE); -} - -/* - * fsmdef_check_if_ok_to_ans_call - * - * Description: - * Checks if given call is in ringing state. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE or FALSE - */ - -boolean -fsmdef_check_if_ok_to_ans_call (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - return (FALSE); - } - - if ((dcb->line != line) || ((dcb->fcb != NULL) && (dcb->fcb->state != FSMDEF_S_INCOMING_ALERTING))) { - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_check_if_ok_to_hold_call - * - * Description: - * Checks if the requested call is in connected state. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE - if there is a connected or resume pending call - * FALSE - if the call is not in above state - */ -boolean -fsmdef_check_if_ok_to_hold_call (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - - return (FALSE); - } - - if ((dcb->line != line) || - ((dcb->fcb != NULL) && - ((dcb->fcb->state != FSMDEF_S_CONNECTED) && - (dcb->fcb->state != FSMDEF_S_CONNECTED_MEDIA_PEND) && - (dcb->fcb->state != FSMDEF_S_RESUME_PENDING)))) { - - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_check_if_ok_to_resume_call - * - * Description: - * Checks if the requested call is in held state. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE or FALSE - */ -boolean -fsmdef_check_if_ok_to_resume_call (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - return (FALSE); - } - - if ((dcb->line != line) || ((dcb->fcb != NULL) &&(dcb->fcb->state != FSMDEF_S_HOLDING))) { - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_check_if_ok_to_run_feature - * - * Description: - * Checks if it is ok to run features on the call. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE or FALSE - */ -boolean -fsmdef_check_if_ok_to_run_feature (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - return (FALSE); - } - - if ((dcb->line != line) || - ((dcb->fcb != NULL) && - (dcb->fcb->state != FSMDEF_S_CONNECTED) && - (dcb->fcb->state != FSMDEF_S_CONNECTED_MEDIA_PEND))) { - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_check_if_ok_to_monitor_update_call - * - * Description: - * Checks if it is ok to update the monitoring call. - * - * Parameters: - * line - * call_id - * - * Returns: TRUE or FALSE - */ -boolean -fsmdef_check_if_ok_to_monitor_update_call (line_t line, callid_t call_id) -{ - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - return (FALSE); - } - - if ((dcb->line != line) || - ((dcb->fcb != NULL) && - (dcb->fcb->state != FSMDEF_S_CONNECTED))) { - return (FALSE); - } - - return (TRUE); -} - -/* - * fsmdef_set_call_info_cc_call_state - * - * Description: - * Sets the called number to readable localized values - * if it is service URI based feature and invokes cc_call_state() - * - * Parameters: - * dcb - * state - * - * Returns: none - */ -static void -fsmdef_set_call_info_cc_call_state (fsmdef_dcb_t *dcb, cc_states_t state, cc_causes_t cause) -{ - cc_state_data_t temp_data; - char tmp_str[CALL_BUBBLE_STR_MAX_LEN]; - int rc = CPR_FAILURE; - - tmp_str[0] = '\0'; - - switch (dcb->active_feature) { - case CC_FEATURE_CFWD_ALL: - rc = platGetPhraseText(STR_INDEX_CALL_FORWARD, - (char *) tmp_str, - CALL_BUBBLE_STR_MAX_LEN); - break; - default: - rc = CPR_FAILURE; - break; - } - - switch (state) { - - case CC_STATE_DIALING_COMPLETED: - temp_data.dialing_completed.caller_id = dcb->caller_id; - break; - - case CC_STATE_CALL_SENT: - temp_data.call_sent.caller_id = dcb->caller_id; - break; - - case CC_STATE_CALL_FAILED: - temp_data.call_failed.caller_id = dcb->caller_id; - temp_data.call_failed.cause = cause; - break; - - default: - /* Set the call id for other states */ - temp_data.offhook.caller_id = dcb->caller_id; - break; - } - - if ((rc == CPR_SUCCESS) && strlen(tmp_str) > 0) { - temp_data.offhook.caller_id.called_number = tmp_str; - } - - cc_call_state(dcb->call_id, dcb->line, state, &temp_data); -} - -/* - * fsmdef_get_dcb_by_call_instance_id - * - * Description: - * This function returns fsmdef DCB that has a match for a given call - * instance ID of a given line. - * - * Parameters: - * line - the dn line - * call_instance_id - for call instance ID. - * - * Returns: pointer to fsmdef_dcb_t if a matching dcb is found otherwise - * returns NULL - */ -fsmdef_dcb_t * -fsmdef_get_dcb_by_call_instance_id (line_t line, uint16_t call_instance_id) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if ((dcb->caller_id.call_instance_id == call_instance_id) && - (dcb->line == line)) { - return (dcb); - } - } - return (NULL); -} - -/* - * fsmdef_ev_join - * - * Description: - * The fsmdef_ev_join function sends an offhook event - * to the barging call and sets its state to FSMDEF_S_JOINING. - * - * Parameters: - * data - pointer to the cc_feature_data_t - * - * Returns: - * none - */ -static void -fsmdef_ev_join (cc_feature_data_t *data) -{ - fsm_fcb_t *fcb = NULL; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - fcb = fsm_get_fcb_by_call_id_and_type(data->newcall.join.join_call_id, - FSM_TYPE_DEF); - if (fcb) { - fsmdef_dcb_t *dcb = fcb->dcb; - - cc_int_offhook(CC_SRC_GSM, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, - dcb->call_id, dcb->line, NULL, CC_MONITOR_NONE,CFWDALL_NONE); - fsm_change_state(fcb, __LINE__, FSMDEF_S_JOINING); - } -} - -/* - * fsmdef_ev_joining_connected_ack - * - * Description: - * The fsmdef_ev_joining_connected_ack negotiates the sdp in the - * ack(if there is one) and sets the fsm/ccapi state to connected - * - * Parameters: - * event - pointer to the sm_event_t - * - * Returns: - * sm_rcs_t value - */ -static sm_rcs_t -fsmdef_ev_joining_connected_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_connected_ack_t *msg = (cc_connected_ack_t *) event->msg; - cc_causes_t cause; - fsmcnf_ccb_t *ccb; - fsm_fcb_t *join_target_fcb; - cc_feature_data_t data; - cc_uint32_t major_sis_ver = SIS_PROTOCOL_MAJOR_VERSION_SEADRAGON; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - memset(&data, 0, sizeof(data)); - - /* Check the remote SDP. The far end may not have included the SDP in an - * earlier message, which means that the SDP must be in this message. - */ - if (dcb->remote_sdp_in_ack == TRUE) { - cause = gsmsdp_negotiate_answer_sdp(fcb, &msg->msg_body); - if (cause != CC_CAUSE_OK) { - data.endcall.cause = cause; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - return (SM_RC_END); - } - } - - platGetSISProtocolVer(&major_sis_ver, NULL, NULL,NULL); - - ccb = fsmcnf_get_ccb_by_call_id(dcb->call_id); - - if (ccb) { - join_target_fcb = fsm_get_fcb_by_call_id_and_type(ccb->cnf_call_id, - FSM_TYPE_CNF); - if ((gsmsdp_is_media_encrypted(dcb) == FALSE) && - (gsmsdp_is_media_encrypted((join_target_fcb!= NULL)?join_target_fcb->dcb:NULL) == TRUE) && - (major_sis_ver < SIS_PROTOCOL_MAJOR_VERSION_MUSTER)) { - /* - * Target Call was secure, a non-secure is trying to Barge/Monitor, - * fail it - */ - data.endcall.cause = CC_CAUSE_SECURITY_FAILURE; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - return (SM_RC_END); - } - } - - cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED, - (cc_state_data_t *) &(dcb->caller_id)); - /* - * If DSP is not able to start rx/tx channels, release the call - */ - if (dcb->dsp_out_of_resources == TRUE) { - data.endcall.cause = CC_CAUSE_NO_MEDIA; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - return (SM_RC_END); - } - - if (ccb) { - /* - * Bridge the conference legs for the join call, even though - * it's done here, ccb should only be accessed from fsmcnf - */ - ccb->active = TRUE; - ccb->bridged = TRUE; - } - - /* - * Handle media capability changes if there is before transition to - * connected state. - */ - return(fsmdef_transition_to_connected(fcb)); -} - -/* - * fsmdef_ev_joining_offhook - * - * Description: - * The fsmdef_ev_joining_offhook creates the local sdp - * for the sip stack to send 200 Ok out - * - * Parameters: - * event - pointer to the sm_event_t - * - * Returns: - * sm_rcs_t value - */ -static sm_rcs_t -fsmdef_ev_joining_offhook (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_causes_t cause; - cc_msgbody_info_t msg_body; - cc_feature_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - /* Build our response SDP to include in the connected */ - cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); - if (cause != CC_CAUSE_OK) { - FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); - memset(&data, 0, sizeof(data)); - data.endcall.cause = cause; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - return (SM_RC_END); - } - cc_int_connected(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line, - &(dcb->caller_id), NULL, &msg_body); - - FSM_SET_FLAGS(dcb->msgs_sent, FSMDEF_MSG_CONNECTED); - - return (SM_RC_END); -} - -/* - * fsmdef_extract_join_target - * - * Description: - * The fsmdef_extract_join_target extract join target call id from - * the setup message and sends a JOIN event to that call - * - * Parameters: - * event - pointer to the sm_event_t - * - * Returns: - * TRUE or FALSE - */ -static boolean -fsmdef_extract_join_target (sm_event_t *event) -{ - static const char fname[] = "fsmdef_extract_join_target"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_setup_t *msg = (cc_setup_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - fsmdef_dcb_t *dcb; - fsmdef_dcb_t *join_dcb; - cc_feature_data_t data; - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - dcb = fcb->dcb; - - if ((msg->call_info.type == CC_FEAT_MONITOR) || - (dcb->session == WHISPER_COACHING)) { - - /* For now, null out the ui id */ - lsm_set_ui_id(dcb->call_id, CC_NO_CALL_ID); - join_dcb = - fsmdef_get_dcb_by_call_id(msg->call_info.data.join.join_call_id); - if (join_dcb) { - dcb->group_id = join_dcb->group_id; - memset(&data, 0, sizeof(data)); - data.newcall.join.join_call_id = call_id; - - if (dcb->session == WHISPER_COACHING) { - data.newcall.cause = CC_CAUSE_MONITOR; - } else if (msg->call_info.type == CC_FEAT_MONITOR) { - data.newcall.cause = CC_CAUSE_MONITOR; - // set the session leg of this dcb to monitor - dcb->session = MONITOR; - } - FSM_DEBUG_SM(DEB_L_C_F_PREFIX" dcb-session type is = %s \n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), - dcb->session == WHISPER_COACHING ? "WHISPER_COACHING" : - dcb->session == MONITOR ? "MONITOR" : "PRIMARY"); - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, join_dcb->call_id, line, - CC_FEATURE_JOIN, &data); - } else { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Unable to find join target dcb\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname)); - return (TRUE); - } - } else { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Unable to find join target call information\n", - DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname)); - return (TRUE); - } - return (FALSE); -} - - -/* - * fsmdef_ev_notify_feature - * - * Description: - * Handles NOTIFY event in different states. - * - * Parameters: - * msg - message pointer - * dcb - pointer to the fsmdef_dcb_t - * - * Returns: - * none - */ -static void -fsmdef_ev_notify_feature (cc_feature_t *msg, fsmdef_dcb_t *dcb) -{ - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - -} - -/* - * fsmdef_notify_hook_event - * - * Description: - * Send offhook/onhook events to SIP (DialogManager) task. - * - * Parameters: - * dcb - pointer to the fsmdef_dcb_t - * - * Returns: - * none - */ -static void -fsmdef_notify_hook_event (fsm_fcb_t *fcb, cc_msgs_t msg, char *global_call_id, - callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, - monitor_mode_t monitor_mode, - cfwdall_mode_t cfwdall_mode) -{ - FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); - - if (msg == CC_MSG_OFFHOOK) { - cc_int_offhook(CC_SRC_GSM, CC_SRC_SIP, prim_call_id, consult_reason, - fcb->dcb->call_id, fcb->dcb->line, - global_call_id, monitor_mode,cfwdall_mode); - } else if (msg == CC_MSG_ONHOOK) { - cc_int_onhook(CC_SRC_GSM, CC_SRC_SIP, prim_call_id, - consult_reason, fcb->dcb->call_id, fcb->dcb->line, FALSE, FALSE); - } - return; -} - -/* - * fsmdef_update_callinfo_security_status - * - * Description: - * The fsmdef_update_callinfo_security_status function updates the call - * information that applies to TNP platform. - * - * Parameters: - * dcb - pointer to the fsmdef_dcb_t - * call_info - pointer to the cc_feature_data_call_info_t - * - * Returns: - * none - */ -static void -fsmdef_update_callinfo_security_status (fsmdef_dcb_t *dcb, - cc_feature_data_call_info_t *call_info) -{ - /* - * Update security information - */ - if (call_info->feature_flag & CC_SECURITY) { - if (sip_regmgr_get_sec_level(dcb->line) != AUTHENTICATED && - sip_regmgr_get_sec_level(dcb->line) != ENCRYPTED ) { - // Signaling security can't be trusted downgrade security level to NOT_AUTHENTICATED - call_info->security = CC_SECURITY_NOT_AUTHENTICATED; - } - - if (dcb->security != call_info->security) { - FSM_SET_SECURITY_STATUS(dcb, call_info->security); - if ( call_info->security == CC_SECURITY_ENCRYPTED ) - ui_update_call_security(dcb->line, lsm_get_ui_id(dcb->call_id), CC_SECURITY_ENCRYPTED); - else - ui_update_call_security(dcb->line, lsm_get_ui_id(dcb->call_id), CC_SECURITY_UNKNOWN); - - dcb->ui_update_required = TRUE; - } - } -} - -/* - * fsmdef_check_retain_fwd_info_state - * - * Description: This function checks the "Retain Forward Information" config - * parameter (only for TNP). It returns TRUE if forward info is - * to be retained; FALSE otherwise. This config parameter is - * is used to change call bubble display from "Forward " to - * "From " when an incoming call is answered AND the config - * parameter value is set to TRUE. For non-TNP, this function - * will always return FALSE (i.e. not to retain fwd info). - * - * Parameters: none - * - * Return Value: TRUE or FALSE - */ -boolean -fsmdef_check_retain_fwd_info_state (void) -{ - int retain_fwd_info_cfg = 0; /* default to Disabled (or 0) for no-op */ - - config_get_value(CFGID_RETAIN_FORWARD_INFORMATION, - &retain_fwd_info_cfg, - sizeof(retain_fwd_info_cfg)); - - if (!retain_fwd_info_cfg) { - return (FALSE); /* do NOT retain forward information */ - } else { - return (TRUE); /* retain forward information */ - } -} - -void -fsmdef_init (void) -{ - static const char fname[] = "fsmdef_init"; - fsmdef_dcb_t *dcb; - - - /* - * Initialize the dcbs. - */ - fsmdef_dcbs = (fsmdef_dcb_t *) - cpr_calloc(FSMDEF_MAX_DCBS, sizeof(fsmdef_dcb_t)); - if (fsmdef_dcbs == NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"cpr_calloc returned NULL\n", - DEB_F_PREFIX_ARGS(FSM, fname)); - return; - } - - /* Create free media structure list */ - if (!gsmsdp_create_free_media_list()) { - FSM_DEBUG_SM(DEB_F_PREFIX"Unable to create free media list\n", - DEB_F_PREFIX_ARGS(FSM, fname)); - return; - } - - DEF_DEBUG(DEB_F_PREFIX"Disabling mass registration print", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - fsmdef_init_dcb(dcb, CC_NO_CALL_ID, FSMDEF_CALL_TYPE_NONE, - FSMDEF_NO_NUMBER, LSM_NO_LINE, NULL); - /* - * Allocate ringback delay timer for each dcb - */ - dcb->ringback_delay_tmr = cprCreateTimer("Ringback Delay", - GSM_RINGBACK_DELAY_TIMER, - TIMER_EXPIRATION, - gsm_msg_queue); - if (dcb->ringback_delay_tmr == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED), - dcb->call_id, dcb->line, fname, "Ringback Delay"); - return; - } - - /* - * Allocate auto answer timer for each dcb - */ - dcb->autoAnswerTimer = cprCreateTimer("Auto Answer", - GSM_AUTOANSWER_TIMER, - TIMER_EXPIRATION, - gsm_msg_queue); - if (dcb->autoAnswerTimer == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED), - dcb->call_id, dcb->line, fname, "Auto Answer"); - (void)cprDestroyTimer(dcb->ringback_delay_tmr); - dcb->ringback_delay_tmr = NULL; - return; - } - dcb->revertTimer = cprCreateTimer("Call Reversion", - GSM_REVERSION_TIMER, - TIMER_EXPIRATION, - gsm_msg_queue); - dcb->reversionInterval = -1; - if (dcb->revertTimer == NULL) { - FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED), - dcb->call_id, dcb->line, fname, "Hold Revertion"); - - (void)cprDestroyTimer(dcb->ringback_delay_tmr); - dcb->ringback_delay_tmr = NULL; - (void)cprDestroyTimer(dcb->autoAnswerTimer); - dcb->autoAnswerTimer = NULL; - return; - } - if (dcb == fsmdef_dcbs) { - g_disable_mass_reg_debug_print = TRUE; - } - } - g_disable_mass_reg_debug_print = FALSE; - - /* - * Initialize the state/event table. - */ - fsmdef_sm_table.min_state = FSMDEF_S_MIN; - fsmdef_sm_table.max_state = FSMDEF_S_MAX; - fsmdef_sm_table.min_event = CC_MSG_MIN; - fsmdef_sm_table.max_event = CC_MSG_MAX; - fsmdef_sm_table.table = (&(fsmdef_function_table[0][0])); -} - -void -fsmdef_shutdown (void) -{ - fsmdef_dcb_t *dcb; - - FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) { - if (dcb->req_pending_tmr) { - (void)cprDestroyTimer(dcb->req_pending_tmr); - } - if (dcb->err_onhook_tmr) { - (void)cprDestroyTimer(dcb->err_onhook_tmr); - } - if (dcb->ringback_delay_tmr) { - (void)cprDestroyTimer(dcb->ringback_delay_tmr); - } - if (dcb->autoAnswerTimer) { - (void)cprDestroyTimer(dcb->autoAnswerTimer); - } - if (dcb->revertTimer) { - (void)cprDestroyTimer(dcb->revertTimer); - } - - /* clean media list */ - gsmsdp_clean_media_list(dcb); - } - - /* destroy free media structure list */ - gsmsdp_destroy_free_media_list(); - - cpr_free(fsmdef_dcbs); - fsmdef_dcbs = NULL; -} - -static void -fsmdef_update_calltype (fsm_fcb_t *fcb, cc_feature_t *msg) { - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t *feat_data = &(msg->data); - cc_caller_id_t *caller_id; - - if (msg->data_valid == FALSE) { - /* No data to use for update. Just ignore the event. */ - return; - } - - if (feat_data->call_info.feature_flag & CC_CALLER_ID) { - caller_id = &feat_data->call_info.caller_id; - if (caller_id->call_type == CC_CALL_FORWARDED) { - if (fsmdef_check_retain_fwd_info_state()) { - dcb->call_type = FSMDEF_CALL_TYPE_FORWARD; - } - } - } -} - diff --git a/libs/sipcc/core/gsm/fsmxfr.c b/libs/sipcc/core/gsm/fsmxfr.c deleted file mode 100755 index a6b022cdce..0000000000 --- a/libs/sipcc/core/gsm/fsmxfr.c +++ /dev/null @@ -1,3042 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "fim.h" -#include "lsm.h" -#include "sm.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "text_strings.h" -#include "fsm.h" -#include "uiapi.h" -#include "debug.h" -#include "regmgrapi.h" -#include "platform_api.h" - -extern fsmdef_dcb_t *fsmdef_dcbs; - -#define FSMXFR_NULL_DIALSTRING '\0' -static fsmxfr_xcb_t *fsmxfr_xcbs; - -typedef enum fsmxfr_states_t_ { - FSMXFR_S_MIN = -1, - FSMXFR_S_IDLE, - FSMXFR_S_ACTIVE, - FSMXFR_S_MAX -} fsmxfr_states_t; - -static const char *fsmxfr_state_names[] = { - "IDLE", - "ACTIVE" -}; - - -static sm_rcs_t fsmxfr_ev_idle_setup(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_idle_feature(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_idle_dialstring(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_connected_ack(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_release(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_release_complete(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_feature(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_feature_ack(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_onhook(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_dialstring(sm_event_t *event); -static sm_rcs_t fsmxfr_ev_active_proceeding(sm_event_t *event); - -static sm_function_t fsmxfr_function_table[FSMXFR_S_MAX][CC_MSG_MAX] = -{ -/* FSMXFR_S_IDLE ------------------------------------------------------------ */ - { - /* FSMXFR_E_SETUP */ fsmxfr_ev_idle_setup, - /* FSMXFR_E_SETUP_ACK */ NULL, - /* FSMXFR_E_PROCEEDING */ NULL, - /* FSMXFR_E_ALERTING */ NULL, - /* FSMXFR_E_CONNECTED */ NULL, - /* FSMXFR_E_CONNECTED_ACK */ NULL, - /* FSMXFR_E_RELEASE */ NULL, - /* FSMXFR_E_RELEASE_COMPLETE */ NULL, - /* FSMXFR_E_FEATURE */ fsmxfr_ev_idle_feature, - /* FSMXFR_E_FEATURE_ACK */ NULL, - /* FSMXFR_E_OFFHOOK */ NULL, - /* FSMXFR_E_ONHOOK */ NULL, - /* FSMXFR_E_LINE */ NULL, - /* FSMXFR_E_DIGIT_BEGIN */ NULL, - /* FSMXFR_E_DIGIT */ NULL, - /* FSMXFR_E_DIALSTRING */ fsmxfr_ev_idle_dialstring, - /* FSMXFR_E_MWI */ NULL, - /* FSMXFR_E_SESSION_AUDIT */ NULL - }, - -/* FSMXFR_S_ACTIVE ---------------------------------------------------- */ - { - /* FSMXFR_E_SETUP */ NULL, - /* FSMXFR_E_SETUP_ACK */ NULL, - /* FSMXFR_E_PROCEEDING */ fsmxfr_ev_active_proceeding, - /* FSMXFR_E_ALERTING */ NULL, - /* FSMXFR_E_CONNECTED */ NULL, - /* FSMXFR_E_CONNECTED_ACK */ fsmxfr_ev_active_connected_ack, - /* FSMXFR_E_RELEASE */ fsmxfr_ev_active_release, - /* FSMXFR_E_RELEASE_COMPLETE */ fsmxfr_ev_active_release_complete, - /* FSMXFR_E_FEATURE */ fsmxfr_ev_active_feature, - /* FSMXFR_E_FEATURE_ACK */ fsmxfr_ev_active_feature_ack, - /* FSMXFR_E_OFFHOOK */ NULL, - /* FSMXFR_E_ONHOOK */ fsmxfr_ev_active_onhook, - /* FSMXFR_E_LINE */ NULL, - /* FSMXFR_E_DIGIT_BEGIN */ NULL, - /* FSMXFR_E_DIGIT */ NULL, - /* FSMXFR_E_DIALSTRING */ fsmxfr_ev_active_dialstring, - /* FSMXFR_E_MWI */ NULL, - /* FSMXFR_E_SESSION_AUDIT */ NULL - } -}; - -static sm_table_t fsmxfr_sm_table; -sm_table_t *pfsmxfr_sm_table = &fsmxfr_sm_table; - -const char * -fsmxfr_state_name (int state) -{ - if ((state <= FSMXFR_S_MIN) || (state >= FSMXFR_S_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (fsmxfr_state_names[state]); -} - - -static int -fsmxfr_get_new_xfr_id (void) -{ - static int xfr_id = 0; - - if (++xfr_id < 0) { - xfr_id = 1; - } - - return (xfr_id); -} - -/** - * - * Sets/rest transfer complete flag in the DCB so it can be used in - * UI to indicate if the call is ended because of xfer or endcall. - * - * @cns_call_id consult call id - * @Xfr_call_id transfer call id - * - * @return none - * - * @pre (none) - */ -void fsmxfr_mark_dcb_for_xfr_complete(callid_t cns_call_id, callid_t xfr_call_id, - boolean set_flag) -{ - fsm_fcb_t *cns_fcb, *xfr_fcb; - - cns_fcb = fsm_get_fcb_by_call_id_and_type(cns_call_id, - FSM_TYPE_DEF); - xfr_fcb = fsm_get_fcb_by_call_id_and_type(xfr_call_id, - FSM_TYPE_DEF); - if (set_flag) { - if (cns_fcb && cns_fcb->dcb) { - FSM_SET_FLAGS(cns_fcb->dcb->flags, FSMDEF_F_XFER_COMPLETE); - } - if (xfr_fcb && xfr_fcb->dcb) { - FSM_SET_FLAGS(xfr_fcb->dcb->flags, FSMDEF_F_XFER_COMPLETE); - } - } else { - if (cns_fcb && cns_fcb->dcb) { - FSM_RESET_FLAGS(cns_fcb->dcb->flags, FSMDEF_F_XFER_COMPLETE); - } - if (xfr_fcb && xfr_fcb->dcb) { - FSM_RESET_FLAGS(xfr_fcb->dcb->flags, FSMDEF_F_XFER_COMPLETE); - } - } -} - -/** - * - * Get active trasnfer state machine information (in active state). - * - * @param none - * - * @return fsm_fcb_t if there is a active trasnfer pending - * else NULL - * - * @pre (none) - */ - - -fsm_fcb_t *fsmxfr_get_active_xfer(void) -{ - fsm_fcb_t *fcb; - fsmxfr_xcb_t *xcb; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - fcb = fsm_get_fcb_by_call_id_and_type(xcb->xfr_call_id, - FSM_TYPE_XFR); - if (fcb && fcb->state == FSMXFR_S_ACTIVE) { - return(fcb); - } - } - - return(NULL); -} - - -static void -fsmxfr_init_xcb (fsmxfr_xcb_t *xcb) -{ - if (xcb != NULL) { - xcb->xfr_id = FSM_NO_ID; - xcb->xfr_call_id = CC_NO_CALL_ID; - xcb->cns_call_id = CC_NO_CALL_ID; - xcb->xfr_line = CC_NO_LINE; - xcb->cns_line = CC_NO_LINE; - xcb->type = FSMXFR_TYPE_NONE; - xcb->method = CC_XFER_METHOD_NONE; - xcb->cnf_xfr = FALSE; - xcb->active = FALSE; - xcb->mode = FSMXFR_MODE_TRANSFEROR; - xcb->xfer_comp_req = FALSE; - xcb->xfr_orig = CC_SRC_MIN; - - if (xcb->xcb2 != NULL) { - fsmxfr_init_xcb(xcb->xcb2); - xcb->xcb2 = NULL; - } - - if (xcb->dialstring != NULL) { - cpr_free(xcb->dialstring); - xcb->dialstring = NULL; - } - if (xcb->queued_dialstring != NULL) { - cpr_free(xcb->queued_dialstring); - xcb->queued_dialstring = NULL; - } - if (xcb->referred_by != NULL) { - cpr_free(xcb->referred_by); - xcb->referred_by = NULL; - } - } -} - - -static fsmxfr_xcb_t * -fsmxfr_get_xcb_by_xfr_id (int xfr_id) -{ - static const char fname[] = "fsmxfr_get_xcb_by_xfr_id"; - fsmxfr_xcb_t *xcb; - fsmxfr_xcb_t *xcb_found = NULL; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - if (xcb->xfr_id == xfr_id) { - xcb_found = xcb; - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_PTR), xcb->xfr_id, - xcb->xfr_call_id, xcb->cns_call_id, fname, xcb); - - break; - } - } - - - return (xcb_found); -} - - -/* - * Function: fsmxfr_get_new_xfr_context - * - * Parameters: - * xfr_call_id: call_id for the call initiating the transfer - * type: attended or unattended transfer - * method: BYE/ALSO or REFER method of transfer - * local: local or remote initiated transfer - * - * Description: This function creates a new transfer context by: - * - getting a free xcb - * - creating new xfr_id and cns_call_id - * - * Returns: xcb - * - */ -static fsmxfr_xcb_t * -fsmxfr_get_new_xfr_context (callid_t xfr_call_id, line_t line, fsmxfr_types_t type, - cc_xfer_methods_t method, fsmxfr_modes_t mode) -{ - static const char fname[] = "fsmxfr_get_new_xfr_context"; - fsmxfr_xcb_t *xcb; - - xcb = fsmxfr_get_xcb_by_xfr_id(FSM_NO_ID); - if (xcb != NULL) { - xcb->xfr_id = fsmxfr_get_new_xfr_id(); - xcb->xfr_call_id = xfr_call_id; - xcb->cns_call_id = cc_get_new_call_id(); - xcb->xfr_line = line; - xcb->cns_line = line; - xcb->type = type; - xcb->method = method; - xcb->mode = mode; - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_PTR), xcb->xfr_id, - xcb->xfr_call_id, xcb->cns_call_id, fname, xcb); - } - - return (xcb); -} - - -fsmxfr_xcb_t * -fsmxfr_get_xcb_by_call_id (callid_t call_id) -{ - fsmxfr_xcb_t *xcb; - fsmxfr_xcb_t *xcb_found = NULL; - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - if ((xcb->xfr_call_id == call_id) || (xcb->cns_call_id == call_id)) { - xcb_found = xcb; - break; - } - } - - return (xcb_found); -} - -/** - * - * Cancel tranfer operation by sending cancel event to SIP stack. - * This routine is used in roundtable phone. - * - * @param line, call_id, target_call_id, cause (implicit or explicit) - * - * @return void - * - * @pre (none) - */ -void -fsmxfr_feature_cancel (fsmxfr_xcb_t *xcb, line_t line, callid_t call_id, - callid_t target_call_id, - cc_rcc_skey_evt_type_e cause) -{ - static const char fname[] = "fsmxfr_feature_cancel"; - cc_feature_data_t data; - fsm_fcb_t *fcb_def; - - DEF_DEBUG(DEB_F_PREFIX"Sending cancel call_id = %d, t_id=%d, cause = %d\n", - DEB_F_PREFIX_ARGS(GSM, fname), call_id, target_call_id, cause); - - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - if ((cause == CC_SK_EVT_TYPE_EXPLI) && - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - fcb_def = fsm_get_fcb_by_call_id_and_type(target_call_id, FSM_TYPE_DEF); - - if ((cause == CC_SK_EVT_TYPE_EXPLI) && - (fcb_def != NULL) && ((fcb_def->dcb->selected == FALSE) && - ((fcb_def->state == FSMDEF_S_OUTGOING_ALERTING) || - ((fcb_def->state == FSMDEF_S_CONNECTED) && - (fcb_def->dcb->spoof_ringout_requested == TRUE) && - (fcb_def->dcb->spoof_ringout_applied == TRUE))))) { - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, target_call_id, - line, CC_FEATURE_END_CALL, NULL); - } - - data.cancel.target_call_id = target_call_id; - data.cancel.call_id = call_id; - data.cancel.cause = cause; - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, CC_FEATURE_CANCEL, &data); -} - - -void -fsmxfr_update_xfr_context (fsmxfr_xcb_t *xcb, callid_t old_call_id, - callid_t new_call_id) -{ - static const char fname[] = "fsmxfr_update_xfr_context"; - FSM_DEBUG_SM(DEB_F_PREFIX"Entered. \n", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_update_xfr_context")); - - if (xcb != NULL) { - if (old_call_id == xcb->xfr_call_id) { - xcb->xfr_call_id = new_call_id; - } else if (old_call_id == xcb->cns_call_id) { - xcb->cns_call_id = new_call_id; - } - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_PTR), xcb->xfr_id, - xcb->xfr_call_id, xcb->cns_call_id, fname, xcb); - } -} - -/* - * Function to get line number of other call associated in - * transfer. - * - * @param xcb and call_id. - * - * @return void - * - */ -line_t -fsmxfr_get_other_line (fsmxfr_xcb_t *xcb, callid_t call_id) -{ - line_t other_line = CC_NO_LINE; - - if (xcb != NULL) { - if (xcb->xfr_call_id == call_id) { - other_line = xcb->cns_line; - } else if (xcb->cns_call_id == call_id) { - other_line = xcb->xfr_line; - } - } - - return (other_line); -} - -callid_t -fsmxfr_get_other_call_id (fsmxfr_xcb_t *xcb, callid_t call_id) -{ - callid_t other_call_id = CC_NO_CALL_ID; - - if (xcb != NULL) { - if (xcb->xfr_call_id == call_id) { - other_call_id = xcb->cns_call_id; - } else if (xcb->cns_call_id == call_id) { - other_call_id = xcb->xfr_call_id; - } - } - - return (other_call_id); -} - - -/* - * Function: fsmxfr_remove_fcb - * - * Parameters: - * xfr_id: xfr_id for the transfer - * call_id: call_id that identifies the fcb to be removed - * - * Description: This function will remove the fcb identified by the given - * call_id from the xcb. And the function will free the xcb - * if both fcbs have been removed. - * - * Returns: none - * - * Note: This is a helper function for fsmxfr_cleanup. It allows fsmxfr_cleanup - * to cleanup one fcb (one call involved in the transfer) independent - * of the other involved fcb. - */ -static void -fsmxfr_remove_fcb (fsm_fcb_t *fcb, callid_t call_id) -{ - fsmxfr_xcb_t *xcb = fcb->xcb; - FSM_DEBUG_SM(DEB_F_PREFIX"Entered. \n", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_remove_fcb")); - - if (xcb != NULL) { - fsmxfr_update_xfr_context(xcb, call_id, CC_NO_CALL_ID); - - /* - * Free the xcb if both fcb references have been removed. - */ - if ((xcb->xfr_call_id == CC_NO_CALL_ID) && - (xcb->cns_call_id == CC_NO_CALL_ID)) { - fsmxfr_init_xcb(xcb); - } - } -} - - -static void -fsmxfr_cnf_cleanup (fsmxfr_xcb_t *xcb) -{ - fsmdef_dcb_t *xfr_dcb; - fsmdef_dcb_t *cns_dcb; - cc_feature_data_t ftr_data; - - cns_dcb = fsm_get_dcb(xcb->cns_call_id); - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - - ftr_data.endcall.cause = CC_CAUSE_NORMAL; - ftr_data.endcall.dialstring[0] = '\0'; - /* - * This is a conference transfer hence we are cleaning - * up both the lines - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - cns_dcb->call_id, cns_dcb->line, - CC_FEATURE_END_CALL, &ftr_data); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - xfr_dcb->call_id, xfr_dcb->line, - CC_FEATURE_END_CALL, &ftr_data); -} - - -static void -fsmxfr_cleanup (fsm_fcb_t *fcb, int fname, boolean both) -{ - fsm_fcb_t *other_fcb = NULL; - callid_t call_id = fcb->call_id; - callid_t other_call_id = CC_NO_CALL_ID; - line_t other_line; - - - FSM_DEBUG_SM(DEB_F_PREFIX"Entered. \n", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_cleanup")); - other_call_id = fsmxfr_get_other_call_id(fcb->xcb, call_id); - other_line = fsmxfr_get_other_line(fcb->xcb, call_id); - - if (other_call_id != CC_NO_CALL_ID) { - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - } - - if (fcb->xcb && (fcb->xcb->cnf_xfr != TRUE) && - (call_id == fcb->xcb->xfr_call_id)) { - - if (other_call_id != CC_NO_CALL_ID) { - /* - * Not clearing consulation call, so change consultation call - * attribute to display connected softkey set. Do not change - * softkey set if it is a transfer o - */ - cc_call_attribute(other_call_id, other_line, NORMAL_CALL); - } - } - /* - * Check if the user wanted to cleanup the whole xcb. - * If so, then we will grab the other fcb first and call this function - * again with this other fcb. The whole xcb will be freed after this block - * of code because both call_ids will be -1, which tells - * fsmxfr_remove_fcb to free the xcb. - */ - if (both) { - FSM_DEBUG_SM(DEB_F_PREFIX"clean both. \n", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_cleanup")); - - if (other_call_id != CC_NO_CALL_ID) { - if (other_fcb != NULL) { - fsmxfr_cleanup(other_fcb, fname, FALSE); - } else { - /* - * If there is no other FCB, we need to clean up so that the - * XCB will be deleted. - */ - fsmxfr_update_xfr_context(fcb->xcb, other_call_id, - CC_NO_CALL_ID); - } - } - } - - /* - * Remove the reference to this fcb from the xcb - */ - fsmxfr_remove_fcb(fcb, fcb->call_id); - - /* - * Move this fcb to the IDLE state - */ - fsm_change_state(fcb, fname, FSMXFR_S_IDLE); - - /* - * Reset the data for this fcb. The fcb is still included in a call - * so set the call_id and dcb values accordingly. - */ - fsm_init_fcb(fcb, fcb->call_id, fcb->dcb, FSM_TYPE_XFR); -} - - -void -fsmxfr_free_cb (fim_icb_t *icb, callid_t call_id) -{ - fsm_fcb_t *fcb = NULL; - - if (call_id != CC_NO_CALL_ID) { - fcb = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_XFR); - - if (fcb != NULL) { - fsmxfr_cleanup(fcb, __LINE__, FALSE); - fsm_init_fcb(fcb, CC_NO_CALL_ID, FSMDEF_NO_DCB, FSM_TYPE_NONE); - } - } -} - - -fsmxfr_types_t -fsmxfr_get_xfr_type (callid_t call_id) -{ - fsmxfr_xcb_t *xcb; - fsmxfr_types_t type = FSMXFR_TYPE_BLND_XFR; - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb != NULL) { - type = xcb->type; - } - - return (type); -} - - -cc_features_t -fsmxfr_type_to_feature (fsmxfr_types_t type) -{ - cc_features_t feature; - - if (type == FSMXFR_TYPE_XFR) { - feature = CC_FEATURE_XFER; - } else { - feature = CC_FEATURE_BLIND_XFER; - } - - return (feature); -} - - -/******************************************************************* - * event functions - */ - - -static sm_rcs_t -fsmxfr_ev_idle_setup (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_setup_t *msg = (cc_setup_t *) event->msg; - fsmxfr_xcb_t *xcb; - - /* - * If this is the consultation call involved in a transfer, - * then set the rest of the data required to make the transfer - * happen. The data is the xcb in the fcb. The data is set now - * because we did not have the fcb when the transfer was - * initiated. The fcb is created when a new_call event is - * received by the FIM, not when a transfer event is received. - */ - - /* - * Ignore this event if this call is not involved in a transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(msg->call_id); - if (xcb == NULL) { - return (SM_RC_DEF_CONT); - } - fcb->xcb = xcb; - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - return (SM_RC_CONT); -} - - -static boolean -fsmxfr_copy_dialstring (char **saved_dialstring, char *dialstring) -{ - char *tempstring; - int len; - - if (saved_dialstring == NULL) { - return (FALSE); - } - - /* - * Make sure we have a valid dialstring. - */ - if ((dialstring == NULL) || (dialstring[0] == '\0')) { - return (FALSE); - } - - /* - * Copy the dialstring to the xcb. We will need it later when - * SIP sends the RELEASE so that we can send out the - * NEWCALL to start the call to the target. - */ - len = (strlen(dialstring) + 1) * sizeof(char); - tempstring = (char *) cpr_malloc(len); - if (tempstring != NULL) { - sstrncpy(tempstring, dialstring, len); - - *saved_dialstring = tempstring; - } - - return (TRUE); -} - -static void -fsmxfr_set_xfer_data (cc_causes_t cause, cc_xfer_methods_t method, - callid_t target_call_id, char *dialstring, - cc_feature_data_xfer_t *xfer) -{ - xfer->cause = cause; - xfer->method = method; - xfer->target_call_id = target_call_id; - sstrncpy(xfer->dialstring, dialstring, CC_MAX_DIALSTRING_LEN); -} - - -static boolean -fsmxfr_remote_transfer (fsm_fcb_t *fcb, cc_features_t ftr_id, - callid_t call_id, line_t line, char *dialstring, - char *referred_by) -{ - fsmxfr_types_t type; - int free_lines; - cc_feature_data_t data; - fsmxfr_xcb_t *xcb; - fsmxfr_xcb_t *primary_xcb; - callid_t cns_call_id; - line_t newcall_line = 0; - - memset(&data, 0, sizeof(cc_feature_data_t)); - - /* - * Make sure we have a free line for the consultation - * call if this is an attended transfer. We do not need this - * check for an unattended transfer, because the stack will - * send up a release for the call being transferred, which will - * then trigger the fsmxfr to send out the newcall in the same - * plane of the call being released. - */ - if (ftr_id == CC_FEATURE_XFER) { - /* - * Make sure we have a free line to start the - * consultation call. - */ - free_lines = lsm_get_instances_available_cnt(line, TRUE); - if (free_lines <= 0) { - /* - * No free lines - let the user know and end this - * request. - */ - fsm_display_no_free_lines(); - - return (FALSE); - } - } - - newcall_line = lsm_get_newcall_line(line); - if (newcall_line == NO_LINES_AVAILABLE) { - /* - * Error Pass Limit - let the user know and end this request. - */ - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return (FALSE); - } - - /* - * Get a new xcb and new xfr id - This is the handle that will - * identify the xfr. - */ - type = ((ftr_id == CC_FEATURE_XFER) ? - (FSMXFR_TYPE_XFR) : (FSMXFR_TYPE_BLND_XFR)); - - primary_xcb = fsmxfr_get_xcb_by_call_id(call_id); - - xcb = fsmxfr_get_new_xfr_context(call_id, line, type, CC_XFER_METHOD_REFER, - FSMXFR_MODE_TRANSFEREE); - if (xcb == NULL) { - return (FALSE); - } - - if (primary_xcb) { - fcb->xcb->xcb2 = xcb; - fcb->xcb->active = TRUE; - } else { - fcb->xcb = xcb; - } - - xcb->cns_line = newcall_line; - cns_call_id = xcb->cns_call_id; - fsmxfr_set_xfer_data(CC_CAUSE_OK, CC_XFER_METHOD_REFER, cns_call_id, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, ftr_id, &data, CC_CAUSE_NORMAL); - - if (ftr_id == CC_FEATURE_XFER) { - /* - * This call needs to go on hold so we can start the - * consultation call. The call may already be on hold, - * so the event will just be silently ignored. We set - * the line number to 0xFF so that GSM will know this - * came from a transfer and we only want to put the call - * on local hold. We don't want to send an Invite Hold - * to the SIP stack. - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - 0xFF, CC_FEATURE_HOLD, NULL); - - /* - * Initiate the consultation call. - */ - - /* - * Make sure we have a valid dialstring. - */ - if ((dialstring == NULL) || (dialstring[0] == '\0')) { - return (FALSE); - } - - /* - * memset is done because if redirects[0].number is - * corrupted we might think that it is a blind - * transfer - */ - memset(data.newcall.redirect.redirects[0].number, 0, - sizeof(CC_MAX_DIALSTRING_LEN)); - data.newcall.cause = CC_CAUSE_XFER_REMOTE; - data.newcall.redirect.redirects[0].redirect_reason = - CC_REDIRECT_REASON_DEFLECTION; - sstrncpy(data.newcall.dialstring, dialstring, CC_MAX_DIALSTRING_LEN); - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, newcall_line, - CC_FEATURE_NEW_CALL, &data); - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_XFR_INITIATED), - xcb->xfr_id, call_id, cns_call_id, __LINE__); - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - } else { /* CC_FEATURE_BLIND_XFER */ - /* - * Make sure we have a valid dialstring. - */ - if ((fsmxfr_copy_dialstring(&xcb->dialstring, dialstring) == TRUE) && - (fsmxfr_copy_dialstring(&xcb->referred_by, referred_by) == TRUE)) { - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - } else { - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - } - - return (TRUE); -} - - -static sm_rcs_t -fsmxfr_ev_idle_feature (sm_event_t *event) -{ - const char *fname = "fsmxfr_ev_idle_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *ftr_data = &(msg->data); - fsmdef_dcb_t *dcb = fcb->dcb; - fsm_fcb_t *other_fcb; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmxfr_types_t type; - int free_lines; - cc_feature_data_t data; - cc_causes_t cause = msg->data.xfer.cause; - cc_xfer_methods_t method; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *fcb_def; - fsm_fcb_t *cns_fcb, *con_fcb, *sel_fcb; - boolean int_rc = FALSE; - callid_t cns_call_id; - line_t newcall_line = 0; - - memset(&data, 0, sizeof(data)); - fsm_sm_ftr(ftr_id, src_id); - - /* - * Consume the XFER events and don't pass them along to the other FSMs. - */ - if ((ftr_id == CC_FEATURE_BLIND_XFER) || (ftr_id == CC_FEATURE_XFER)) { - sm_rc = SM_RC_END; - } - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_DIRTRXFR: - - /* If there is a active xfer pending - * then link this transfer to active transfer - */ - other_fcb = fsmxfr_get_active_xfer(); - if (other_fcb) { - if (other_fcb->xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer\n", fname); - return (SM_RC_END); - } - /* End existing consult call and then link another - * call with the trasfer - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_fcb->xcb->cns_call_id, - other_fcb->xcb->cns_line, CC_FEATURE_END_CALL, NULL); - other_fcb->xcb->cns_call_id = call_id; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_fcb->xcb->xfr_call_id, - other_fcb->xcb->xfr_line, CC_FEATURE_DIRTRXFR, NULL); - - return(SM_RC_END); - } - fsm_get_fcb_by_selected_or_connected_call_fcb(call_id, &con_fcb, &sel_fcb); - - /* If there is a call selected use that for direct transfer */ - if (sel_fcb) { - other_fcb = sel_fcb; - } else if (con_fcb) { - other_fcb = con_fcb; - } else { - /* No connected call or selected call */ - return(SM_RC_CONT); - } - - /* Make sure atleast one call has been selected, connected and this call - * is not in the focus - */ - if ((fsmutil_get_num_selected_calls() > 1) && (dcb->selected == FALSE)) { - //return error - return(SM_RC_CONT); - } - - if (other_fcb->xcb == NULL || other_fcb->xcb->xfr_line != line) { - //Not on same line display a message - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer\n", fname); - return(SM_RC_CONT); - } - - xcb = fsmxfr_get_new_xfr_context(call_id, line, FSMXFR_TYPE_XFR, - CC_XFER_METHOD_REFER, - FSMXFR_MODE_TRANSFEROR); - if (xcb == NULL) { - break; - } - - xcb->xfr_orig = src_id; - fcb->xcb = xcb; - - xcb->type = FSMXFR_TYPE_DIR_XFR; - xcb->cns_call_id = other_fcb->dcb->call_id; - - other_fcb->xcb = xcb; - /* - * Emulating user hitting transfer key for second time - * in attended transfer - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_DIRTRXFR, NULL); - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - return(SM_RC_END); - - case CC_FEATURE_BLIND_XFER: - case CC_FEATURE_XFER: - - /* Connect the existing call to active trasnfer state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - if ((cause != CC_CAUSE_XFER_CNF) && - (ftr_data && msg->data_valid) && - (ftr_data->xfer.target_call_id != CC_NO_CALL_ID) && - ((cns_fcb = fsm_get_fcb_by_call_id_and_type(ftr_data->xfer.target_call_id, - FSM_TYPE_XFR)) != NULL)) { - /* In this case there is no active xcb but upper layer - * wants to complete a trasnfer with 2 different call_ids - */ - xcb = fsmxfr_get_new_xfr_context(call_id, line, FSMXFR_TYPE_XFR, - CC_XFER_METHOD_REFER, - FSMXFR_MODE_TRANSFEROR); - if (xcb == NULL) { - return(SM_RC_END); - } - - fcb->xcb = xcb; - cns_fcb->xcb = xcb; - xcb->type = FSMXFR_TYPE_DIR_XFR; - - xcb->cns_call_id = ftr_data->xfer.target_call_id; - - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - - /* Find line information for target call. - */ - if (fcb_def && fcb_def->dcb) { - - xcb->cns_line = fcb_def->dcb->line; - - } else { - - return(SM_RC_END); - } - - fsm_change_state(cns_fcb, __LINE__, FSMXFR_S_ACTIVE); - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xcb->xfr_call_id, - line, CC_FEATURE_DIRTRXFR, NULL); - - return(SM_RC_END); - } - - /* - * This call is the transferor and we are initiating a local - * transfer. So: - * 1. Make sure we have a free line to open a new call plane to - * collect digits (and place call) for the transfer target, - * 2. Create a new transfer context, - * 3. Place this call on hold, - * 4. Send a newcall feature back to the GSM so that the - * consultation call can be initiated. - */ - - /* - * Check for any other active features which may block - * the transfer. - */ - - /* - * The call must be in the connected state to initiate a transfer. - */ - fcb_def = fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def != NULL) && - (fcb_def->state != FSMDEF_S_CONNECTED) && - (cause != CC_CAUSE_XFER_CNF)) { - break; - } - - /* - * If it's not a conference transfer make sure we have a free - * line to start the consultation call. - */ - if (cause != CC_CAUSE_XFER_CNF) { - //CSCsz38962 don't use expline for local-initiated transfer - //free_lines = lsm_get_instances_available_cnt(line, TRUE); - free_lines = lsm_get_instances_available_cnt(line, FALSE); - if (free_lines <= 0) { - /* - * No free lines - let the user know and end this request. - */ - fsm_display_no_free_lines(); - - break; - } - - newcall_line = lsm_get_newcall_line(line); - if (newcall_line == NO_LINES_AVAILABLE) { - /* - * Error Pass Limit - let the user know and end this request. - */ - lsm_ui_display_notify_str_index(STR_INDEX_ERROR_PASS_LIMIT); - return (FALSE); - } - } - - /* - * Get a new xcb and new xfr id - This is the handle that will - * identify the xfr. - */ - type = ((ftr_id == CC_FEATURE_XFER) ? - (FSMXFR_TYPE_XFR) : (FSMXFR_TYPE_BLND_XFR)); - - xcb = fsmxfr_get_new_xfr_context(call_id, line, type, - CC_XFER_METHOD_REFER, - FSMXFR_MODE_TRANSFEROR); - if (xcb == NULL) { - break; - } - xcb->xfr_orig = src_id; - fcb->xcb = xcb; - /* - * If not conference transfer initiate the consultation call. - * For conference transfer we already have both calls setup. - */ - if (cause != CC_CAUSE_XFER_CNF) { - /* - * Set the consultative line to new line id. - */ - xcb->cns_line = newcall_line; - /* - * Record the active feature if it is a blind xfer. - */ - if (ftr_id == CC_FEATURE_BLIND_XFER) { - dcb->active_feature = ftr_id; - } - - /* - * This call needs to go on hold so we can start the - * consultation call. Indicate feature indication should - * be send and set the feature reason. - */ - data.hold.call_info.type = CC_FEAT_HOLD; - data.hold.call_info.data.hold_resume_reason = CC_REASON_XFER; - data.hold.msg_body.num_parts = 0; - data.hold.call_info.data.call_info_feat_data.protect = TRUE; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, &data); - - cns_call_id = xcb->cns_call_id; - if (ftr_data->xfer.cause == CC_CAUSE_XFER_LOCAL_WITH_DIALSTRING) { - cc_int_dialstring(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, newcall_line, - ftr_data->xfer.dialstring, NULL, 0); - } else { - data.newcall.cause = CC_CAUSE_XFER_LOCAL; - if (ftr_data->xfer.dialstring[0] != 0) { - data.newcall.cause = CC_CAUSE_XFER_BY_REMOTE; - sstrncpy(data.newcall.dialstring, ftr_data->xfer.dialstring, - CC_MAX_DIALSTRING_LEN); - } - - if (ftr_data->xfer.global_call_id[0] != 0) { - sstrncpy(data.newcall.global_call_id, - ftr_data->xfer.global_call_id, CC_GCID_LEN); - } - data.newcall.prim_call_id = xcb->xfr_call_id; - data.newcall.hold_resume_reason = CC_REASON_XFER; - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_call_id, newcall_line, - CC_FEATURE_NEW_CALL, &data); - } - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_XFR_INITIATED), - xcb->xfr_id, call_id, cns_call_id, __LINE__); - } else { - other_fcb = - fsm_get_fcb_by_call_id_and_type(msg->data.xfer.target_call_id, - FSM_TYPE_XFR); - if (other_fcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer\n", fname); - break; - } - - other_fcb->xcb = xcb; - /* - * The xfr_call_id is the call that is being replaced by - * the cns_call_id. - */ - fsmxfr_update_xfr_context(xcb, xcb->cns_call_id, - msg->data.xfer.target_call_id); - xcb->cnf_xfr = TRUE; - fsm_change_state(other_fcb, __LINE__, FSMXFR_S_ACTIVE); - /* - * Emulating user hitting transfer key for second time - * in attended transfer - */ - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_XFER, NULL); - } - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_NEW_CALL: - - /* - * If this is the consultation call involved in a transfer, - * then set the rest of the data required to make the transfer - * happen. The data is the xcb in the fcb. The data is set now - * because we did not have the fcb when the transfer was - * initiated. The fcb is created when a new_call event is - * received by the FIM, not when a transfer event is received. - * - * Or this could be the call that originated the - * transfer (the transferor) and - * the person he was talking to (the transfer target) has - * decided to transfer the transferor to another target. - */ - - /* - * Ignore this event if this call is not involved in a transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb == NULL) { - break; - } - fcb->xcb = xcb; - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_BLIND_XFER: - case CC_FEATURE_XFER: - if (msg->data_valid == FALSE) { - break; - } - - method = msg->data.xfer.method; - - switch (method) { - case CC_XFER_METHOD_BYE: - /* - * This is a remote initiated transfer using the - * BYE/ALSO method. - * - * The transferor has sent us, the transferee, a BYE with - * the transfer target. - * - * 1. Create a new transfer context - * 2. Ack the feature request. - * - * We need to wait for the RELEASE from SIP and then we will - * send out the NEWCALL to initiate the call to the target. - */ - - /* - * Transfer is valid only for a remote originated transfer. - */ - if (msg->data.xfer.cause != CC_CAUSE_XFER_REMOTE) { - break; - } - - /* - * Check for any other active features which may block - * the transfer. - */ - - /* - * Get a new xcb and new xfr id - This is the handle that will - * identify the xfr. - */ - type = ((ftr_id == CC_FEATURE_XFER) ? - (FSMXFR_TYPE_XFR) : (FSMXFR_TYPE_BLND_XFR)); - - xcb = fsmxfr_get_new_xfr_context(call_id, line, type, method, - FSMXFR_MODE_TRANSFEREE); - if (xcb == NULL) { - break; - } - xcb->xfr_orig = src_id; - fcb->xcb = xcb; - - fsmxfr_set_xfer_data(CC_CAUSE_OK, method, - xcb->cns_call_id, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, ftr_id, &data, CC_CAUSE_NORMAL); - - /* - * Make sure we have a valid dialstring. - */ - if (fsmxfr_copy_dialstring(&xcb->dialstring, - msg->data.xfer.dialstring) == TRUE) { - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - } else { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - - break; - - case CC_XFER_METHOD_REFER: - /* - * This event is because: - * 1. we are the target involved in a transfer or - * 2. it is a remote initiated transfer using the REFER method. - * - * Case 1: - * The transferee has attempted to setup a call with us, - * the target. The call has been setup successfully so the - * SIP stack is informing us that we are the target. - * - * 1. Ack the request, - * 2. Create a new transfer context. - * - * Case 2: - * The transferor has sent us, the transferee, a REFER with - * the transfer target. We will attempt to contact the target - * and then report the result to the transferor. - * - * 1. Verify that we have a free line to start the - * consultation call, - * 2. Create a new transfer context, - * 3. Place this call on hold, - * 4. Send a newcall feature back to the GSM so that the - * consultation call can be initiated. - */ - - /* - * Check if this is case 1. - * We know this because the target_call_id can only be set - * for this case. - */ - if ((msg->data.xfer.cause == CC_CAUSE_XFER_REMOTE) && - (msg->data.xfer.target_call_id != CC_NO_CALL_ID)) { - type = ((ftr_id == CC_FEATURE_XFER) ? - (FSMXFR_TYPE_XFR) : (FSMXFR_TYPE_BLND_XFR)); - - xcb = fsmxfr_get_new_xfr_context(call_id, line, type, - CC_XFER_METHOD_REFER, - FSMXFR_MODE_TARGET); - if (xcb == NULL) { - break; - } - xcb->xfr_orig = src_id; - fcb->xcb = xcb; - - /* - * The xfr_call_id is the call that is being replaced by - * the cns_call_id (which the stack supplied). - */ - fsmxfr_update_xfr_context(xcb, xcb->cns_call_id, - msg->data.xfer.target_call_id); - cns_call_id = xcb->cns_call_id; - /* - * Set the correct xfer_data. The target_call_id must be - * CC_NO_CALL_ID so that the stack can tell that this is - * a case 1 transfer. - */ - fsmxfr_set_xfer_data(CC_CAUSE_XFER_REMOTE, - method, - CC_NO_CALL_ID, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, ftr_id, &data, - CC_CAUSE_NORMAL); - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - - break; - } - - /* - * I guess we are at case 2... - * Transfer should be done only if call's present state - * is either on hold or connected - */ - fcb_def = - fsm_get_fcb_by_call_id_and_type(call_id, FSM_TYPE_DEF); - if ((fcb_def->state == FSMDEF_S_CONNECTED) || - (fcb_def->state == FSMDEF_S_CONNECTED_MEDIA_PEND) || - (fcb_def->state == FSMDEF_S_RESUME_PENDING) || - (fcb_def->state == FSMDEF_S_HOLD_PENDING) || - (fcb_def->state == FSMDEF_S_HOLDING)) { - int_rc = - fsmxfr_remote_transfer(fcb, ftr_id, call_id, dcb->line, - msg->data.xfer.dialstring, - msg->data.xfer.referred_by); - } - - if (int_rc == FALSE) { - fsmxfr_set_xfer_data(CC_CAUSE_ERROR, CC_XFER_METHOD_REFER, - CC_NO_CALL_ID, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, - line, ftr_id, &data, CC_CAUSE_ERROR); - } - break; - - default: - break; - } /* switch (xfr_data->method) */ - - break; - case CC_FEATURE_NOTIFY: - if (ftr_data->notify.subscription != CC_SUBSCRIPTIONS_XFER) { - /* This notify is not for XFER subscription */ - break; - } - data.notify.cause = msg->data.notify.cause; - data.notify.cause_code = msg->data.notify.cause_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = - msg->data.notify.blind_xferror_gsm_id; - data.notify.final = TRUE; - - if (data.notify.blind_xferror_gsm_id == CC_NO_CALL_ID) { - if (msg->data.notify.cause == CC_CAUSE_OK) { - data.endcall.cause = CC_CAUSE_OK; - sm_rc = SM_RC_END; - /* - * If dcb is NULL, we received a final NOTIFY after the - * the dcb was cleared. This can happen when we receive - * BYE before final NOTIFY on the result of the REFER - * sent for xfer. If dcb is NULL, just quietly ignore - * the NOTIFY event. Otherwise, kick off the release of - * the call. - */ - if (dcb) { - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - dcb->call_id, dcb->line, - CC_FEATURE_END_CALL, &data); - } - } - } else { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - data.notify.blind_xferror_gsm_id, - line, CC_FEATURE_NOTIFY, &data); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - sm_rc = SM_RC_DEF_CONT; - break; - } /* switch (src_id) */ - - return (sm_rc); -} - -static sm_rcs_t -fsmxfr_ev_idle_dialstring (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - fsmxfr_xcb_t *xcb; - sm_rcs_t sm_rc = SM_RC_CONT; - - /* - * Ignore this event if this call is not involved in a transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb == NULL) { - return sm_rc; - } - fcb->xcb = xcb; - - fsm_change_state(fcb, __LINE__, FSMXFR_S_ACTIVE); - return (fsmxfr_ev_active_dialstring(event)); -} - - - - -static sm_rcs_t -fsmxfr_ev_active_proceeding (sm_event_t *event) -{ - cc_proceeding_t *msg = (cc_proceeding_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - cc_feature_data_t data; - fsmxfr_xcb_t *xcb; - fsm_fcb_t *other_fcb; - callid_t other_call_id; - line_t other_line; - - /* - * Ignore this event if this call is not involved in a transfer - * or we are not the target of the transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((xcb == NULL) || (xcb->mode != FSMXFR_MODE_TARGET)) { - return (SM_RC_CONT); - } - - other_call_id = fsmxfr_get_other_call_id(xcb, call_id); - other_line = fsmxfr_get_other_line(xcb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, FSM_TYPE_DEF); - - /* - * Release the transfer call. - * - * We need to release the transfer call (which is really - * the consultation call from the transferor to us - * the target), because we want the next call coming in - * to replace this one. - */ - data.endcall.cause = CC_CAUSE_REPLACE; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_call_id, - other_line, CC_FEATURE_END_CALL, &data); - - /* - * Only answer the call if the call being replaced was connected - * or is currently connected, otherwise just let this call be setup - * normally so that it will ring. - */ - - if (other_fcb && (other_fcb->old_state == FSMDEF_S_CONNECTED || - other_fcb->old_state == FSMDEF_S_CONNECTED_MEDIA_PEND || - other_fcb->old_state == FSMDEF_S_RESUME_PENDING || - other_fcb->state == FSMDEF_S_CONNECTED || - other_fcb->state == FSMDEF_S_CONNECTED_MEDIA_PEND || - other_fcb->state == FSMDEF_S_RESUME_PENDING)) { - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, call_id, - line, CC_FEATURE_ANSWER, NULL); - } - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmxfr_ev_active_connected_ack (sm_event_t *event) -{ - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_connected_ack_t *msg = (cc_connected_ack_t *) event->msg; - fsmxfr_xcb_t *xcb; - - /* - * If we are the target and this is the call from the transferree - * to the target, then we need to cleanup the rest of the transfer. - * We need to do this because the consultation call is already cleared - * from the transfer but the transfer call was not. - */ - - /* - * Ignore this event if this call is not involved in a transfer. - */ - xcb = fsmxfr_get_xcb_by_call_id(msg->call_id); - if ((xcb == NULL) || (xcb->mode != FSMXFR_MODE_TARGET)) { - return (SM_RC_CONT); - } - - /* - * Remove this call from the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, FALSE); - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmxfr_ev_active_release (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_release"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_release_t *msg = (cc_release_t *) event->msg; - callid_t call_id = msg->call_id; - fsmdef_dcb_t *dcb = fcb->dcb; - callid_t new_call_id; - callid_t other_call_id; - line_t other_line; - fsmxfr_xcb_t *xcb = fcb->xcb; - cc_feature_data_t data; - boolean secondary = FALSE; - cc_action_data_t action_data; - fsm_fcb_t *other_fcb; - FSM_DEBUG_SM(DEB_F_PREFIX"Entered. \n", DEB_F_PREFIX_ARGS(FSM, "fsmxfr_ev_active_release")); - - /* - * Complete a transfer if we have a pending transfer. - */ - memset(&data, 0, sizeof(cc_feature_data_t)); - - /* - * Check if this is a transfer of a transfer. - */ - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find a transfer call to cancel.\n", fname); - return (SM_RC_CONT); - } - - if ((xcb->active == TRUE) && (xcb->xcb2 != NULL)) { - xcb = xcb->xcb2; - secondary = TRUE; - } - - if ((xcb->dialstring != NULL) && (xcb->dialstring[0] != '\0')) { - /* - * Grab the call_id for the call to the target. - * This will either already be in the xcb or we will need to - * get a new one. The call_id will be in the xcb if we are the - * transferee. - */ - if (xcb->active == TRUE) { - new_call_id = cc_get_new_call_id(); - fsmxfr_update_xfr_context(xcb, call_id, new_call_id); - } else { - new_call_id = fsmxfr_get_other_call_id(xcb, call_id); - if (secondary == TRUE) { - fsmxfr_update_xfr_context(fcb->xcb, call_id, new_call_id); - } - } - - data.newcall.cause = CC_CAUSE_XFER_REMOTE; - sstrncpy(data.newcall.dialstring, xcb->dialstring, - CC_MAX_DIALSTRING_LEN); - - cpr_free(xcb->dialstring); - xcb->dialstring = NULL; - memset(data.newcall.redirect.redirects[0].number, 0, - sizeof(CC_MAX_DIALSTRING_LEN)); - if (xcb->referred_by != NULL) { - sstrncpy(data.newcall.redirect.redirects[0].number, - xcb->referred_by, CC_MAX_DIALSTRING_LEN); - - cpr_free(xcb->referred_by); - xcb->referred_by = NULL; - } - - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, new_call_id, - dcb->line, CC_FEATURE_NEW_CALL, &data); - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_XFR_INITIATED), xcb->xfr_id, - xcb->xfr_call_id, xcb->cns_call_id, __LINE__); - - if (secondary == TRUE) { - fsmxfr_init_xcb(xcb); - fcb->xcb->active = FALSE; - fcb->xcb->xcb2 = NULL; - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, FALSE); - } else if (xcb->active == TRUE) { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, FALSE); - fcb->xcb->active = FALSE; - } else { - /* - * Reset the xcb call_id that was used for the call to the target. - * The value was just temporary and it needs to be reset so that - * the cleanup function works properly. - */ - fsmxfr_update_xfr_context(xcb, new_call_id, CC_NO_CALL_ID); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - - xcb->active = FALSE; - } else { - if (secondary == TRUE) { - /* - * This is the secondary transfer of a primary transfer. - * We need to: - * 1. update the primary xcb to point to this just transferred - * call, - * 2. mark the primary xcb as inactive since we just completed the - * secondary transfer, - * 3. point the newly transferred call to the primary xcb and - * update the UI to show that this is a local transfer (the - * UI was set as though the call was a remote transfer). - * 4. blow away this secondary xcb and cleanup the fcb, - */ - new_call_id = fsmxfr_get_other_call_id(xcb, call_id); - fsmxfr_update_xfr_context(fcb->xcb, call_id, new_call_id); - - fcb->xcb->active = FALSE; - - other_fcb = fsm_get_fcb_by_call_id_and_type(new_call_id, - FSM_TYPE_XFR); - if (other_fcb == NULL) { - return (SM_RC_CONT); - } - other_fcb->xcb = fcb->xcb; - - fsmxfr_init_xcb(xcb); - - action_data.update_ui.action = CC_UPDATE_XFER_PRIMARY; - (void)cc_call_action(other_fcb->dcb->call_id, dcb->line, - CC_ACTION_UPDATE_UI, &action_data); - - fsmxfr_cleanup(fcb, __LINE__, FALSE); - } else { - /* - * One of the parties in the transfer has decided to release - * the call, so go ahead and cleanup this transfer. - */ - other_call_id = fsmxfr_get_other_call_id(xcb, call_id); - other_line = fsmxfr_get_other_line(xcb, call_id); - - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - if (xcb->cnf_xfr) { - /* - * This is the transfer for bridging a transfer call so - * clear the second line also. - */ - xcb->cnf_xfr = FALSE; - if (other_fcb == NULL) { - return (SM_RC_CONT); - } - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_call_id, - other_line, CC_FEATURE_END_CALL, NULL); - } - - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - - } - } - - return (SM_RC_CONT); -} - - -static sm_rcs_t -fsmxfr_ev_active_release_complete (sm_event_t *event) -{ - fsmxfr_cleanup((fsm_fcb_t *) event->data, __LINE__, TRUE); - - return (SM_RC_CONT); -} - -static char *fsmxfr_get_dialed_num (fsmdef_dcb_t *dcb) -{ - static const char fname[] = "fsmxfr_get_dialed_num"; - char *tmp_called_number; - /* Get the dialed number only if the call is outgoing type */ - - tmp_called_number = lsm_get_gdialed_digits(); - - DEF_DEBUG(DEB_F_PREFIX"called_dialed_num = %s\n", - DEB_F_PREFIX_ARGS(GSM, fname), tmp_called_number); - - /* Get dialed number to put in the refer-to header. If there - * is no dialed number then use RPID or from header value - */ - if (tmp_called_number == NULL || (*tmp_called_number) == NUL) { - - if (dcb->caller_id.called_number[0] != NUL) { - DEF_DEBUG(DEB_F_PREFIX"called_dcb_num = %s\n", - DEB_F_PREFIX_ARGS(GSM, fname), (char *)dcb->caller_id.called_number); - return((char *)dcb->caller_id.called_number); - - } else { - DEF_DEBUG(DEB_F_PREFIX"calling_dcb_num = %s\n", - DEB_F_PREFIX_ARGS(GSM, fname), (char *)dcb->caller_id.calling_number); - return((char *)dcb->caller_id.calling_number); - } - } - - /* - * if tmp_called_number is same as what we receive in RPID, - * then get the called name from RPID if provided. - */ - if (dcb->caller_id.called_number != NULL && - dcb->caller_id.called_number[0] != NUL) { - /* if Cisco PLAR string is used, use the RPID value */ - if (strncmp(tmp_called_number, CC_CISCO_PLAR_STRING, sizeof(CC_CISCO_PLAR_STRING)) == 0) { - tmp_called_number = (char *)dcb->caller_id.called_number; - } - } - - return(tmp_called_number); -} - -static void -fsmxfr_initiate_xfr (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_initiate_xfr"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - fsm_fcb_t *cns_fcb = NULL; - fsmdef_dcb_t *dcb = fcb->dcb; - fsmdef_dcb_t *xfr_dcb; - fsmdef_dcb_t *cns_dcb; - cc_feature_data_t data; - fsmxfr_xcb_t *xcb = fcb->xcb; - char *called_num = NULL; - - /* - * Place the consultation call on hold. - */ - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer\n", fname); - return; - } - - cns_dcb = fsm_get_dcb(xcb->cns_call_id); - cns_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, - FSM_TYPE_DEF); - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - - /* - * If the consultation call is not connected - * treat it like a blind xfer. - */ - if (cns_fcb != NULL) { - /* - * If the transfer key is pressed twice, before the sofkey gets - * updated in response to first transfer key, the 2nd transfer key - * press is treated as a transfer complete and we try to initate - * the transfer to the connected call itself. To prevent this, check - * the state of the call to see if we should - * ignore the 2nd transfer key press. - */ - if ((cns_fcb->state == FSMDEF_S_COLLECT_INFO) || - (cns_fcb->state == FSMDEF_S_OUTGOING_PROCEEDING) || - (cns_fcb->state == FSMDEF_S_KPML_COLLECT_INFO)) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Ignore the xfer xid %d cid %d %d\n", - DEB_L_C_F_PREFIX_ARGS(FSM, xcb->xfr_line, xcb->xfr_call_id, "fsmxfr_initiate_xfr"), - xcb->xfr_id, xcb->xfr_call_id, xcb->cns_call_id); - return; - } - - /* - * Indicate that xfer completion has been requested - */ - xcb->xfer_comp_req = TRUE; - - if (cns_fcb->state < FSMDEF_S_CONNECTED) { - data.endcall.cause = CC_CAUSE_NO_USER_RESP; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, cns_dcb->call_id, - cns_dcb->line, CC_FEATURE_END_CALL, &data); - /* - * Instruct the stack to transfer the call. - */ - called_num = fsmxfr_get_dialed_num(cns_dcb); - if (called_num && called_num[0] != '\0') { - - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, - xcb->method, cns_dcb->call_id, - called_num, - &(data.xfer)); - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_XFER, &data); - } else { - /* - * Can't transfer the call without a dialstring, so - * just cleanup the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - if (xcb->cnf_xfr) { - /* - * If it is a conference transfer clear up the - * calls. - */ - fsmxfr_cnf_cleanup(xcb); - } - } - } else { - /* - * If the consulation call is already on hold and - * the intial call isn't then place ourselves on - * hold (user hit the rocker arm switch). Otherwise, - * place the consulation call on hold. Make sure we - * do not send feature indication by setting the - * call info type to none. - */ - data.hold.call_info.type = CC_FEAT_NONE; - data.hold.msg_body.num_parts = 0; - if (((cns_fcb->state == FSMDEF_S_HOLDING) || - (cns_fcb->state == FSMDEF_S_HOLD_PENDING)) && - ((fcb->state != FSMDEF_S_HOLDING) && - (fcb->state != FSMDEF_S_HOLD_PENDING))) { - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, dcb->line, - CC_FEATURE_HOLD, &data); - } else { - /* just place on hold */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - cns_dcb->call_id, cns_dcb->line, - CC_FEATURE_HOLD, &data); - } - } - } -} - -static sm_rcs_t -fsmxfr_ev_active_feature (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_feature"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *msg = (cc_feature_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - cc_feature_data_t *feat_data = &(msg->data); - fsmdef_dcb_t *xfr_dcb, *cns_dcb; - cc_feature_data_t data; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmxfr_xcb_t *xcb = fcb->xcb; - boolean int_rc; - char tmp_str[STATUS_LINE_MAX_LEN]; - char *called_num = NULL; - fsm_fcb_t *cns_fcb = NULL; - - fsm_sm_ftr(ftr_id, src_id); - - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer\n", fname); - return (SM_RC_CONT); - } - - /* - * Consume the XFER and NOTIFY events and don't pass them along - * to the other FSMs. - */ - if ((ftr_id == CC_FEATURE_BLIND_XFER) || - (ftr_id == CC_FEATURE_XFER) || (ftr_id == CC_FEATURE_NOTIFY)) { - if (ftr_id == CC_FEATURE_NOTIFY) { - if (msg->data_valid && - (msg->data.notify.subscription != CC_SUBSCRIPTIONS_XFER)) { - /* The subscription is not XFER, let the event flow through */ - return (SM_RC_CONT); - } - } - sm_rc = SM_RC_END; - } - - switch (src_id) { - case CC_SRC_UI: - switch (ftr_id) { - case CC_FEATURE_CANCEL: - sm_rc = SM_RC_END; - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_EXPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_XFER: - /* Connect the existing call to active trasnfer state - * machine. If the UI generates the event with target - * call_id in the data then terminate the existing consulatative - * call and link that to another call. - */ - DEF_DEBUG(DEB_F_PREFIX"ACTIVE XFER call_id = %d, cns_id = %d, t_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->xfr_call_id, - feat_data->xfer.target_call_id, xcb->cns_call_id); - - if (feat_data && msg->data_valid && - (xcb->cns_call_id != feat_data->xfer.target_call_id)) { - - cns_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, - FSM_TYPE_DEF); - - if (cns_fcb != NULL) { - DEF_DEBUG(DEB_F_PREFIX"INVOKE ACTIVE XFER call_id = %d, t_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->xfr_call_id, - feat_data->xfer.target_call_id); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xcb->xfr_call_id, - xcb->xfr_line, CC_FEATURE_DIRTRXFR, NULL); - } - - return(SM_RC_END); - } - switch (xcb->method) { - case CC_XFER_METHOD_BYE: - case CC_XFER_METHOD_REFER: - /* - * This is the second transfer event for a local - * attended transfer with consultation. - * - * The user is attempting to complete the transfer, so - * 1. place the consultation call on hold, - * 2. instruct the stack to transfer the call. - */ - fsmxfr_initiate_xfr(event); - lsm_set_hold_ringback_status(xcb->cns_call_id, FALSE); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) { */ - break; - case CC_FEATURE_RESUME: - break; - - case CC_FEATURE_END_CALL: - if (xcb->mode == FSMXFR_MODE_TRANSFEREE) { - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (call_id == xcb->cns_call_id) { - /* - * Transferee ended call before transfer was completed. - * Notify the transfer call of the status of the - * transfer. - */ - data.notify.cause = CC_CAUSE_ERROR; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.final = TRUE; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_NOTIFY, &data); - } - } - lsm_set_hold_ringback_status(xcb->cns_call_id, TRUE); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_HOLD: - if ((msg->data_valid) && - (feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_SWAP || - feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_XFER || - feat_data->hold.call_info.data.hold_resume_reason == CC_REASON_INTERNAL)) - { - feat_data->hold.call_info.data.call_info_feat_data.protect = TRUE; - } else { - DEF_DEBUG(DEB_F_PREFIX"Invoke hold call_id = %d t_call_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->xfr_call_id, xcb->cns_call_id); - //Actual hold to this call, so break the feature layer. - ui_terminate_feature(xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - - break; - - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_DIRTRXFR: - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - called_num = fsmxfr_get_dialed_num(xfr_dcb); - - if (called_num && called_num[0] != '\0') { - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, - xcb->method, xcb->cns_call_id, - called_num, - &(data.xfer)); - - data.xfer.method = CC_XFER_METHOD_DIRXFR; - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - call_id, line, - CC_FEATURE_XFER, &data); - } else { - /* - * Can't transfer the call without a dialstring, so - * just cleanup the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - return(SM_RC_END); - case CC_FEATURE_END_CALL: - /* - * Only cleanup the whole xfer if we know that we don't have - * an outstanding blind transfer and if we are not the target. - * We need the xcb to hang around because other users (lsm,...) - * may still want to do something special and the xcb is the only - * way they know that the call is involved in a transfer. - */ - if (xcb->type == FSMXFR_TYPE_BLND_XFR) { - fsmxfr_cleanup(fcb, __LINE__, FALSE); - } else if ((xcb->type == FSMXFR_TYPE_XFR) && - (msg->data.endcall.cause == CC_CAUSE_NO_USER_RESP)) { - - DEF_DEBUG(DEB_F_PREFIX"Xfer type =%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->type); - - if ((platGetPhraseText(STR_INDEX_TRANSFERRING, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - lsm_ui_display_status(tmp_str, xcb->xfr_line, xcb->xfr_call_id); - } - - if (xcb->xfer_comp_req == FALSE) { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - } else { - // Mark it as transfer complete. - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, TRUE); - } - fsmxfr_cleanup(fcb, __LINE__, FALSE); - } else if (xcb->mode == FSMXFR_MODE_TARGET) { - break; - } else { - /* Early attended transfer generates internal END_CALL event - * do not send cancel in that case - */ - if (xcb->xfer_comp_req == FALSE) { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - } - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - break; - - case CC_FEATURE_HOLD: - ui_set_local_hold(dcb->line, dcb->call_id); - if(msg->data_valid) { - feat_data->hold.call_info.data.call_info_feat_data.protect = TRUE; - } - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - case CC_SRC_SIP: - switch (ftr_id) { - case CC_FEATURE_CALL_PRESERVATION: - DEF_DEBUG(DEB_F_PREFIX"Preservation call_id = %d t_call_id=%d\n", - DEB_F_PREFIX_ARGS(GSM, fname), xcb->xfr_call_id, xcb->cns_call_id); - ui_terminate_feature(xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - break; - - case CC_FEATURE_BLIND_XFER: - case CC_FEATURE_XFER: - if (msg->data_valid == FALSE) { - break; - } - - /* - * Transfer is valid only for a remote originated transfer. - */ - if (msg->data.xfer.cause != CC_CAUSE_XFER_REMOTE) { - break; - } - - /* - * This call is already involved in a transfer as the transferor, - * but one of the parties, the transferee or target has decided to - * transfer that leg also. So, now we have a transfer of a transfer. - */ - switch (msg->data.xfer.method) { - case CC_XFER_METHOD_BYE: - /* - * Check for any other active features which may block - * the transfer. - */ - - fsmxfr_set_xfer_data(CC_CAUSE_OK, CC_XFER_METHOD_BYE, - CC_NO_CALL_ID, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, ftr_id, &data, CC_CAUSE_NORMAL); - - /* - * Make sure we have a valid dialstring. - */ - if (fsmxfr_copy_dialstring(&xcb->dialstring, - msg->data.xfer.dialstring) == FALSE) { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - break; - } - - /* - * Mark the active flag in the xcb. This flag is used later - * when the RELEASE comes from SIP, so that the GSM - * knows that this call is still involved in a transfer. - */ - xcb->active = TRUE; - - break; - - case CC_XFER_METHOD_REFER: - int_rc = fsmxfr_remote_transfer(fcb, ftr_id, call_id, dcb->line, - msg->data.xfer.dialstring, - msg->data.xfer.referred_by); - - if (int_rc == FALSE) { - fsmxfr_set_xfer_data(CC_CAUSE_ERROR, CC_XFER_METHOD_REFER, - CC_NO_CALL_ID, - FSMXFR_NULL_DIALSTRING, &(data.xfer)); - - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, call_id, - dcb->line, ftr_id, &data, - CC_CAUSE_ERROR); - } - break; - - default: - break; - } /* switch (msg->data.xfer.method) */ - - break; - - case CC_FEATURE_NOTIFY: - /* - * This could be: - * 1. for an unattended transfer. - * The transferee is notifying us, the transferor, of the status - * of the transfer, ie. was the transferee able to connect to - * the target? - * - * 2. Or this is an attended transfer, and this is the call from - * the transferee to the target. The stack will NOTIFY the GSM - * of the status of the call after it receives a message - * from the network indicating success of failure. - */ - if (msg->data_valid == FALSE) { - break; - } - - /* - * Ack the request. - */ - cc_int_feature_ack(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, - dcb->line, CC_FEATURE_NOTIFY, NULL, - CC_CAUSE_NORMAL); - - switch (xcb->type) { - case FSMXFR_TYPE_BLND_XFR: - switch (msg->data.notify.method) { - case CC_XFER_METHOD_BYE: - /* - * This notification is really from the SIP stack. - * The network will not send a NOTIFY for a BYE/Also - * transfer, so the SIP stack just sends one up when - * it uses that method. - */ - - /* - * Release the transfer call. - */ - data.endcall.cause = CC_CAUSE_OK; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_END_CALL, &data); - break; - - case CC_XFER_METHOD_REFER: - if (msg->data.notify.cause == CC_CAUSE_OK) { - /* - * Release the transfer call. - */ - /* Set the dcb flag to indicate transfer is complete, so that - * it won't display endcall in this case - */ - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, TRUE); - - data.endcall.cause = CC_CAUSE_OK; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_END_CALL, &data); - } else { - fsmxfr_cleanup(fcb, __LINE__, TRUE); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - dcb->line, CC_FEATURE_RESUME, NULL); - } - break; - - default: - break; - } /* switch (msg->data.notify.method) { */ - - break; - case FSMXFR_TYPE_DIR_XFR: - /* - * Clear the transfer call if the transfer was OK, - * else just cleanup the transfer. The consultation - * call will be released by the target. - */ - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (msg->data.notify.cause == CC_CAUSE_OK) { - data.endcall.cause = CC_CAUSE_OK; - - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, TRUE); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_END_CALL, - &data); - } else { - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - dcb->line, xcb->xfr_call_id); - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - dcb->line, xcb->cns_call_id); - } - if (xcb->cnf_xfr) { - /* - * If it is a conference transfer clear up the - * calls. - */ - fsmxfr_cnf_cleanup(xcb); - } - break; - - case FSMXFR_TYPE_XFR: - switch (msg->data.notify.method) { - case CC_XFER_METHOD_BYE: - /* - * Release the consultation call. - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xcb->cns_call_id, - dcb->line, CC_FEATURE_END_CALL, NULL); - - /* - * Release the call being transferred. - */ - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xcb->xfr_call_id, - dcb->line, CC_FEATURE_END_CALL, NULL); - break; - - case CC_XFER_METHOD_REFER: - /* - * This notification is from either the target (which is - * the consultation call) or the transferee (which is the - * transfer call). - * - * So, do the following based on each case: - * - * 1. consultation call: this is the transferee receiving - * notification of the status of the call from the - * transferee to the target. - * - notify the transfer call. - * - the transfer call will be released by the transferor - * after receiving the above notification and the - * consultation call will remain. - * - * 2. transfer call: this is the transferor receiving - * notification of the status of the call from the - * transferee to the target. - * - release the transfer call. - * - the consultation call will be released by the target. - */ - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (call_id == xcb->cns_call_id) { - /* - * Notify the transfer call of the status of the - * transfer. - */ - data.notify.cause = msg->data.notify.cause; - data.notify.cause_code = msg->data.notify.cause_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = - msg->data.notify.blind_xferror_gsm_id; - data.notify.final = TRUE; - if (data.notify.blind_xferror_gsm_id == CC_NO_CALL_ID) { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - xfr_dcb->call_id, xfr_dcb->line, - CC_FEATURE_NOTIFY, &data); - } else { - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - data.notify.blind_xferror_gsm_id, - msg->line, CC_FEATURE_NOTIFY, &data); - } - } else { - /* - * Clear the transfer call if the transfer was OK, - * else just cleanup the transfer. The consultation - * call will be released by the target. - */ - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer\n", fname); - break; - } - - if (msg->data.notify.cause == CC_CAUSE_OK) { - data.endcall.cause = CC_CAUSE_OK; - - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, TRUE); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_END_CALL, - &data); - } else { - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - dcb->line, xcb->xfr_call_id); - fsmxfr_mark_dcb_for_xfr_complete(xcb->cns_call_id, - xcb->xfr_call_id, FALSE); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - /* - * Resume the consultation call. - * if xcb->cns_call_id == 0, then cns call is already ended. - */ - if (xcb->cns_call_id != CC_NO_CALL_ID) { - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - dcb->line, xcb->cns_call_id); - cns_dcb = fsm_get_dcb (xcb->cns_call_id); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, - xcb->cns_call_id, cns_dcb->line, - CC_FEATURE_RESUME, NULL); - } - - if (xcb->cnf_xfr) { - /* - * If it is a conference transfer clear up the - * calls. - */ - fsmxfr_cnf_cleanup(xcb); - } - } - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } /* if (call_id == xcb->cns_call_id) */ - break; - - default: - break; - } /* switch (msg->data.notify.method) { */ - - break; - - default: - break; - } /* switch (xcb->type) { */ - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (ftr_id) */ - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - break; - } /* switch (src_id) */ - - return (sm_rc); -} - -static void -fsmxfr_requeue_blind_xfer_dialstring (fsmdef_dcb_t *dcb, fsmxfr_xcb_t *xcb) -{ - /* - * This is the result of the feature hold so we - * can clear the active feature. - */ - dcb->active_feature = CC_FEATURE_NONE; - - /* - * If there is a dialstring on the xcb, it is because the - * dialstring event for the consultative call has already - * been received. We delayed handling the dialstring until - * the result of the hold request has been received. We - * are now ready to process the dial string so requeue it - * for processing - */ - if (xcb->queued_dialstring && xcb->queued_dialstring[0] != '\0') { - cc_dialstring(CC_SRC_UI, xcb->cns_call_id, dcb->line, - xcb->queued_dialstring); - cpr_free(xcb->queued_dialstring); - xcb->queued_dialstring = NULL; - } -} - -static sm_rcs_t -fsmxfr_ev_active_feature_ack (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_feature_ack"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_ack_t *msg = (cc_feature_ack_t *) event->msg; - cc_srcs_t src_id = msg->src_id; - cc_features_t ftr_id = msg->feature_id; - fsmdef_dcb_t *dcb = fcb->dcb; - cc_feature_data_t data; - sm_rcs_t sm_rc = SM_RC_CONT; - fsmxfr_xcb_t *xcb = fcb->xcb; - fsmdef_dcb_t *xfr_dcb = NULL; - char *called_num = NULL; - - fsm_sm_ftr(ftr_id, src_id); - - /* - * Consume the XFER events and don't pass them along to the other FSMs. - */ - if ((ftr_id == CC_FEATURE_BLIND_XFER) || (ftr_id == CC_FEATURE_XFER)) { - sm_rc = SM_RC_END; - } - - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer\n", fname); - return (sm_rc); - } - - switch (src_id) { - case CC_SRC_SIP: - case CC_SRC_GSM: - switch (ftr_id) { - case CC_FEATURE_BLIND_XFER: - switch (xcb->type) { - case FSMXFR_TYPE_BLND_XFR: - switch (msg->data.xfer.method) { - case CC_XFER_METHOD_REFER: - /* - * Clear the call if the transfer was OK, else just cleanup - * the transfer. - */ - if (msg->cause == CC_CAUSE_OK) { - // This does not indicate that transfer was successful. So wait for the NOTIFYs. - //data.endcall.cause = CC_CAUSE_OK; - - //cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, dcb->call_id, - //dcb->line, CC_FEATURE_END_CALL, &data); - } else { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } /* switch (msg->data.xfer.method) { */ - - break; - - default: - break; - } /* switch (xcb->type) { */ - break; - - case CC_FEATURE_HOLD: - if (msg->cause == CC_CAUSE_REQUEST_PENDING) { - /* - * HOLD request is pending. Let this event drop through - * to the default sm for handling. - */ - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - break; - } - - /* - * If this is the hold response during a blind transfer, - * check to see if a dialstring has been queued for processing. - */ - if (xcb->type == FSMXFR_TYPE_BLND_XFR && - xcb->xfr_call_id == fcb->call_id) { - fsmxfr_requeue_blind_xfer_dialstring(dcb, xcb); - break; - } - - /* - * If xfer soft key has not been pressed a second time then - * don't transfer the call. - */ - if (!xcb->xfer_comp_req) { - break; - } - - - /* If there is any error reported from SIP stack then clear the - * transfer data. One such case is where digest authentication - * fails due to maximum retry (of 2). SIP stack generates a valid - * ACK event by setting cause code to ERROR - */ - if (msg->cause == CC_CAUSE_ERROR) { - - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - xcb->xfr_line, xcb->xfr_call_id); - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - xcb->cns_line, xcb->cns_call_id); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, xcb->cns_call_id, - CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - - break; - } - - /* - * Instruct the stack to transfer the call. - */ - if (xcb->type == FSMXFR_TYPE_XFR) { - /* - * Check to see which side of the transfer - * the request is coming from. if it is from - * the XFR side, make sure the CNS side is - * indeed in the Held state. - */ - if (xcb->cns_call_id == fcb->call_id) { - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - - called_num = fsmxfr_get_dialed_num(fcb->dcb); - - if (called_num && called_num[0] != '\0') { - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, - xcb->method, fcb->dcb->call_id, - called_num, - &(data.xfer)); - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_XFER, &data); - } else { - /* - * Can't transfer the call without a dialstring, so - * just cleanup the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - } else { - /* - * This is hold response on the xfer call leg. - * - * Check to see if dialstring has been queued for - * processing. If so, it is requeued to GSM and - * we delay until the consultative call is setup. - */ - //if (fsmxfr_requeue_blind_xfer_dialstring(dcb, xcb)) { - // break; - //} - - /* - * Get the dcb of the consultative call. - */ - xfr_dcb = fsm_get_dcb(xcb->cns_call_id); - - /* - * We must wait for the hold request on the consultative - * call to complete before completing the xfer. The state - * of the consultative call must be FSMDEF_S_HOLDING. - * FSMDEF_S_HOLDING is not a completed hold request which - * is why it is not checked for here. - */ - if (xfr_dcb->fcb->state != FSMDEF_S_HOLDING) { - break; - } else { - - called_num = fsmxfr_get_dialed_num(xfr_dcb); - - if (called_num && called_num[0] != '\0') { - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, - xcb->method, xfr_dcb->call_id, - called_num, - &(data.xfer)); - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, - fcb->dcb->call_id, fcb->dcb->line, - CC_FEATURE_XFER, &data); - } else { - /* - * Can't transfer the call without a dialstring, so - * just cleanup the transfer. - */ - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - } - } - } - break; - - case CC_FEATURE_XFER: - - if (msg->cause != CC_CAUSE_OK) { - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - xcb->xfr_line, xcb->xfr_call_id); - lsm_ui_display_status(platform_get_phrase_index_str(TRANSFER_FAILED), - xcb->cns_line, xcb->cns_call_id); - fsmxfr_feature_cancel(xcb, xcb->xfr_line, xcb->xfr_call_id, - xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } else { - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - } - break; - - default: - fsm_sm_ignore_ftr(fcb, __LINE__, ftr_id); - - break; - } /* switch (ftr_id) */ - - break; - - default: - fsm_sm_ignore_src(fcb, __LINE__, src_id); - - break; - } /* switch (src_id) */ - - return (sm_rc); -} - - -static sm_rcs_t -fsmxfr_ev_active_onhook (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_onhook"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_onhook_t *msg = (cc_onhook_t *) event->msg; - callid_t call_id = msg->call_id; - callid_t other_call_id; - fsmxfr_xcb_t *xcb = fcb->xcb; - fsm_fcb_t *other_fcb; - fsmdef_dcb_t *xfr_dcb; - cc_feature_data_t data; - fsm_fcb_t *cns_fcb, *xfr_fcb; - int onhook_xfer = 0; - - if (xcb == NULL) { - GSM_DEBUG_ERROR(GSM_F_PREFIX"Cannot find the active xfer\n", fname); - return (SM_RC_CONT); - } - - cns_fcb = fsm_get_fcb_by_call_id_and_type(xcb->cns_call_id, FSM_TYPE_DEF); - xfr_fcb = fsm_get_fcb_by_call_id_and_type(xcb->xfr_call_id, FSM_TYPE_DEF); - - if (xcb->cnf_xfr) { - /* - * This is the conference transfer so clear the - * second line also. - */ - xcb->cnf_xfr = FALSE; - other_call_id = fsmxfr_get_other_call_id(xcb, call_id); - other_fcb = fsm_get_fcb_by_call_id_and_type(other_call_id, - FSM_TYPE_XFR); - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, other_call_id, - other_fcb ? other_fcb->dcb->line:CC_NO_LINE, CC_FEATURE_END_CALL, NULL); - fsmxfr_cleanup(fcb, __LINE__, TRUE); - return (SM_RC_CONT); - } - - if (xcb->mode == FSMXFR_MODE_TRANSFEREE) { - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (call_id == xcb->cns_call_id) { - /* - * Transferee ended call before transfer was completed. - * Notify the transfer call of the status of the - * transfer. - * - * Note: This must be changed when fix is put in for configurable - * onhook xfer (CSCsb86757) so that 200 NOTIFY is sent when - * xfer is completed. fsmxfr_initiate_xfr will take care - * of this for us so just need to make sure the NOTIFY is - * sent to SIP stack only when xfer is abandoned due to - * onhook. - */ - data.notify.cause = CC_CAUSE_ERROR; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.final = TRUE; - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xfr_dcb->call_id, - xfr_dcb->line, CC_FEATURE_NOTIFY, &data); - if (cns_fcb && cns_fcb->state != FSMDEF_S_HOLDING && - cns_fcb->state != FSMDEF_S_HOLD_PENDING) { - fsmxfr_feature_cancel(xcb, xfr_dcb->line, - xcb->xfr_call_id, xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - /* - * fix bug CSCtb23681. - */ - if( xfr_dcb->fcb->state == FSMDEF_S_HOLDING ) - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, xfr_dcb->call_id,xfr_dcb->line, CC_FEATURE_END_CALL, NULL); - return (SM_RC_CONT); - } - } - - if (msg->softkey) { - /* - * Softkey set to TRUE indicates endcall softkey was pressed. - * This causes the call with focus to release. - */ - if ((call_id == xcb->cns_call_id) && - (cns_fcb->state == FSMDEF_S_HOLDING || - cns_fcb->state == FSMDEF_S_HOLD_PENDING)) { - /* ignore the onhook event for the held consultation call */ - } if (msg->active_list == CC_REASON_ACTIVECALL_LIST) { - /* Active call list has been requested also - * existing consult call is canceled - * But transfer state machine will remain - * intact as feature layer is still running.*/ - xcb->cns_call_id = CC_NO_CALL_ID; - xcb->cns_line = CC_NO_LINE; - - }else { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, - xcb->xfr_call_id, xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - - fsmxfr_cleanup(fcb, __LINE__, TRUE); - } - return (SM_RC_CONT); - } else { - /* - * Softkey set to FALSE indicates handset, speaker button, or - * headset went onhook. This causes the transfer to complete - * if onhook xfer is enabled by config. - */ - config_get_value(CFGID_XFR_ONHOOK_ENABLED, &onhook_xfer, - sizeof(onhook_xfer)); - if (onhook_xfer && ((cns_fcb->state == FSMDEF_S_OUTGOING_ALERTING)|| - (cns_fcb->state == FSMDEF_S_CONNECTED))) { - fsmxfr_initiate_xfr(event); - return (SM_RC_END); - } else if (onhook_xfer && xfr_fcb && - ((xfr_fcb->state == FSMDEF_S_OUTGOING_ALERTING)|| - (xfr_fcb->state == FSMDEF_S_CONNECTED))) { - fsmxfr_initiate_xfr(event); - return (SM_RC_END); - } else { - fsmxfr_feature_cancel(xcb, xcb->xfr_line, - xcb->xfr_call_id, xcb->cns_call_id, CC_SK_EVT_TYPE_IMPLI); - - fsmxfr_cleanup(fcb, __LINE__, TRUE); - return (SM_RC_CONT); - } - } -} - - -/* - * This event can only happen if the user initiated a blind transfer. - */ -static sm_rcs_t -fsmxfr_ev_active_dialstring (sm_event_t *event) -{ - static const char fname[] = "fsmxfr_ev_active_dialstring"; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_dialstring_t *msg = (cc_dialstring_t *) event->msg; - callid_t call_id = msg->call_id; - line_t line = msg->line; - fsmdef_dcb_t *xfr_dcb; - fsmxfr_xcb_t *xcb = fcb->xcb; - cc_feature_data_t data; - char *dialstring; - - /* - * Make sure we have a valid dialstring. - */ - dialstring = msg->dialstring; - if ((dialstring == NULL) || (dialstring[0] == '\0')) { - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"dialstring= %c\n", - DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, call_id, fname), '\0'); - return (SM_RC_END); - } - - FSM_DEBUG_SM(DEB_L_C_F_PREFIX"dialstring= %s\n", - DEB_L_C_F_PREFIX_ARGS(FSM, msg->line, call_id, fname), dialstring); - - /* - * If this is a blind xfer and we have received the dialstring - * before the original call has received a response to the hold - * request, defer processing the dialstring event. active_feature - * will be set to CC_FEATURE_BLIND_XFER if we are still waiting - * for the hold response. The dial string is saved on the xcb - * until needed. - */ - if (xcb == NULL) { - return (SM_RC_END); - } - - xfr_dcb = fsm_get_dcb(xcb->xfr_call_id); - if (xfr_dcb == NULL) { - return (SM_RC_END); - } - - if (xfr_dcb->active_feature == CC_FEATURE_BLIND_XFER) { - if (!fsmxfr_copy_dialstring(&xcb->queued_dialstring, dialstring)) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX"unable to copy dialstring\n", - msg->line, call_id, fname); - } - return (SM_RC_END); - } - - if (xcb->type == FSMXFR_TYPE_BLND_XFR) { - lsm_set_hold_ringback_status(xcb->cns_call_id, FALSE); - } - /* - * Make sure that this event came from the consultation call and that - * this is a blind transfer. We ignore the event if this is a transfer - * with consultation, because we want to talk to the target. For an - * unattended transfer this event is the final event needed to complete - * the transfer. - */ - if ((xcb->cns_call_id != call_id) || (xcb->type != FSMXFR_TYPE_BLND_XFR)) { - return (SM_RC_CONT); - } - - switch (xcb->method) { - case CC_XFER_METHOD_BYE: - case CC_XFER_METHOD_REFER: - /* - * This is an unattended transfer so: - * 1. clear the consultation call, - * 2. instruct the stack to initiate the transfer. - */ - - /* - * Release this call because it was only used to collect digits. - */ - data.endcall.cause = CC_CAUSE_NORMAL; - cc_int_feature(CC_SRC_GSM, CC_SRC_GSM, call_id, - line, CC_FEATURE_END_CALL, &data); - - - /* - * Send an event to the transferer call leg so it can send the called - * number to the transferee. - */ - fsmxfr_set_xfer_data(CC_CAUSE_XFER_LOCAL, xcb->method, CC_NO_CALL_ID, - dialstring, &(data.xfer)); - - cc_int_feature(CC_SRC_GSM, CC_SRC_SIP, xcb->xfr_call_id, - line, fsmxfr_type_to_feature(xcb->type), &data); - - FSM_DEBUG_SM(get_debug_string(FSMXFR_DBG_XFR_INITIATED), - xcb->xfr_id, xcb->xfr_call_id, xcb->cns_call_id, __LINE__); - - break; - - default: - break; - } /* switch (xcb->method) */ - - return (SM_RC_END); -} - - -cc_int32_t -fsmxfr_show_cmd (cc_int32_t argc, const char *argv[]) -{ - fsmxfr_xcb_t *xcb; - int i = 0; - - PR_ASSERT( i == 0 ); - /* - * Check if need help. - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("%s", "show fsmxfr\n"); - return (0); - } - - debugif_printf("%s", "\n------------------------ FSMXFR xcbs -------------------------"); - debugif_printf("%s", "\ni xfr_id xcb type method xfr_call_id cns_call_id"); - debugif_printf("%s", "\n--------------------------------------------------------------\n"); - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - debugif_printf("%-2d %-6d 0x%8p %-4d %-6d %-11d %-11d\n", - i++, xcb->xfr_id, xcb, xcb->type, xcb->method, - xcb->xfr_call_id, xcb->cns_call_id); - } - - return (0); -} - - -void -fsmxfr_init (void) -{ - fsmxfr_xcb_t *xcb; - - - /* - * Initialize the xcbs. - */ - fsmxfr_xcbs = (fsmxfr_xcb_t *) - cpr_calloc(FSMXFR_MAX_XCBS, sizeof(fsmxfr_xcb_t)); - - FSM_FOR_ALL_CBS(xcb, fsmxfr_xcbs, FSMXFR_MAX_XCBS) { - fsmxfr_init_xcb(xcb); - } - - /* - * Initialize the state/event table. - */ - fsmxfr_sm_table.min_state = FSMXFR_S_MIN; - fsmxfr_sm_table.max_state = FSMXFR_S_MAX; - fsmxfr_sm_table.min_event = CC_MSG_MIN; - fsmxfr_sm_table.max_event = CC_MSG_MAX; - fsmxfr_sm_table.table = (&(fsmxfr_function_table[0][0])); -} - -cc_transfer_mode_e -cc_is_xfr_call (callid_t call_id) -{ - static const char fname[] = "cc_is_xfr_call"; - int mode; - - if (call_id == CC_NO_CALL_ID) { - return CC_XFR_MODE_NONE; - } - mode = fsmutil_is_xfr_leg(call_id, fsmxfr_xcbs, FSMXFR_MAX_XCBS); - - switch (mode) { - case FSMXFR_MODE_TRANSFEROR: - FSM_DEBUG_SM(DEB_F_PREFIX"xfer mode is transferor for call id = %d\n", DEB_F_PREFIX_ARGS(FSM, fname), call_id); - return CC_XFR_MODE_TRANSFEROR; - case FSMXFR_MODE_TRANSFEREE: - FSM_DEBUG_SM(DEB_F_PREFIX"xfer mode is transferee for call id = %d\n", DEB_F_PREFIX_ARGS(FSM, fname), call_id); - return CC_XFR_MODE_TRANSFEREE; - case FSMXFR_MODE_TARGET: - FSM_DEBUG_SM(DEB_F_PREFIX"xfer mode is target for call id = %d\n", DEB_F_PREFIX_ARGS(FSM, fname), call_id); - return CC_XFR_MODE_TARGET; - default: - FSM_DEBUG_SM(DEB_F_PREFIX"invalid xfer mode %d for call id = %d\n", DEB_F_PREFIX_ARGS(FSM, fname), mode, call_id); - return CC_XFR_MODE_NONE; - } -} - -void -fsmxfr_shutdown (void) -{ - cpr_free(fsmxfr_xcbs); - fsmxfr_xcbs = NULL; -} - -int -fsmutil_is_xfr_consult_call (callid_t call_id) -{ - return fsmutil_is_xfr_consult_leg(call_id, fsmxfr_xcbs, FSMXFR_MAX_XCBS); -} - -callid_t -fsmxfr_get_consult_call_id (callid_t call_id) -{ - fsmxfr_xcb_t *xcb; - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - - if (xcb && call_id == xcb->xfr_call_id) { - return (fsmxfr_get_other_call_id(xcb, call_id)); - } else { - return (CC_NO_CALL_ID); - } -} - -callid_t -fsmxfr_get_primary_call_id (callid_t call_id) -{ - fsmxfr_xcb_t *xcb; - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - - if (xcb && (xcb->cns_call_id == call_id)) { - return (fsmxfr_get_other_call_id(xcb, call_id)); - } else { - return (CC_NO_CALL_ID); - } -} diff --git a/libs/sipcc/core/gsm/gsm.c b/libs/sipcc/core/gsm/gsm.c deleted file mode 100755 index fdf9e83f39..0000000000 --- a/libs/sipcc/core/gsm/gsm.c +++ /dev/null @@ -1,608 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_memory.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_time.h" -#include "cpr_rand.h" -#include "cpr_timers.h" -#include "cpr_threads.h" -#include "phone.h" -#include "phntask.h" -#include "gsm.h" -#include "lsm.h" -#include "vcm.h" -#include "fsm.h" -#include "phone_debug.h" -#include "debug.h" -#include "fim.h" -#include "gsm_sdp.h" -#include "ccsip_subsmanager.h" -#include "dialplanint.h" -#include "kpmlmap.h" -#include "subapi.h" -#include "platform_api.h" - -static void sub_process_feature_msg(uint32_t cmd, void *msg); -static void sub_process_feature_notify(ccsip_sub_not_data_t *msg, callid_t call_id, - callid_t other_call_id); -static void sub_process_b2bcnf_msg(uint32_t cmd, void *msg); -void fsmb2bcnf_get_sub_call_id_from_ccb(fsmcnf_ccb_t *ccb, callid_t *cnf_call_id, - callid_t *cns_call_id); -cprMsgQueue_t gsm_msg_queue; -void destroy_gsm_thread(void); -void dp_shutdown(); -extern void dcsm_process_jobs(void); -extern void dcsm_init(void); -extern void dcsm_shutdown(void); - -/* Flag to see whether we can start processing events */ - -static boolean gsm_initialized = FALSE; -extern cprThread_t gsm_thread; -static media_timer_callback_fp* media_timer_callback = NULL; - -/** - * Add media falsh one time timer call back. It's for ROUNDTABLE only. - */ -void -gsm_set_media_callback(media_timer_callback_fp* callback) { - media_timer_callback = callback; -} - -void -gsm_set_initialized (void) -{ - gsm_initialized = TRUE; -} - -boolean -gsm_get_initialize_state (void) -{ - return gsm_initialized; -} - -cprBuffer_t -gsm_get_buffer (uint16_t size) -{ - return cpr_malloc(size); -} - - -cpr_status_e -gsm_send_msg (uint32_t cmd, cprBuffer_t buf, uint16_t len) -{ - phn_syshdr_t *syshdr; - - syshdr = (phn_syshdr_t *) cprGetSysHeader(buf); - if (!syshdr) { - return CPR_FAILURE; - } - syshdr->Cmd = cmd; - syshdr->Len = len; - - if (cprSendMessage(gsm_msg_queue, buf, (void **) &syshdr) == CPR_FAILURE) { - cprReleaseSysHeader(syshdr); - return CPR_FAILURE; - } - return CPR_SUCCESS; -} - - -boolean -gsm_process_msg (uint32_t cmd, void *msg) -{ - static const char fname[] = "gsm_process_msg"; - boolean release_msg = TRUE; - cc_msgs_t msg_id = ((cc_setup_t *)msg)->msg_id; - int event_id = msg_id; - - GSM_DEBUG(DEB_F_PREFIX"cmd= 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - - switch (cmd) { - case GSM_GSM: - case GSM_SIP: - if (gsm_initialized) { - - if (event_id == CC_MSG_FEATURE && - (((cc_feature_t *) msg)->feature_id == CC_FEATURE_CAC_RESP_PASS)) { - - fsm_cac_process_bw_avail_resp (); - - /* Release all memory for CC_FEATURE_CAC_..message */ - release_msg = TRUE; - - GSM_DEBUG(DEB_F_PREFIX"CAC Message Processed: 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - } else if (event_id == CC_MSG_FEATURE && - (((cc_feature_t *) msg)->feature_id == CC_FEATURE_CAC_RESP_FAIL)) { - - fsm_cac_process_bw_failed_resp (); - - /* Release all memory for CC_FEATURE_CAC_..message */ - release_msg = TRUE; - - GSM_DEBUG(DEB_F_PREFIX"CAC Message Processed: 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - } else { - - release_msg = fim_process_event(msg, FALSE); - GSM_DEBUG(DEB_F_PREFIX"Message Processed: 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - } - } - if (release_msg == TRUE) { - fim_free_event(msg); - } - break; - - default: - GSM_DEBUG(DEB_F_PREFIX"Unknown Cmd received: 0x%x\n", DEB_F_PREFIX_ARGS(GSM, fname), cmd); - break; - } - - return(release_msg); -} - - -void -gsm_process_timer_expiration (void *msg) -{ - static const char fname[] = "gsm_process_timer_expiration"; - cprCallBackTimerMsg_t *timerMsg; - void *timeout_msg = NULL; - - timerMsg = (cprCallBackTimerMsg_t *) msg; - TMR_DEBUG(DEB_F_PREFIX"Timer %s expired\n", DEB_F_PREFIX_ARGS(GSM, fname), timerMsg->expiredTimerName); - - switch (timerMsg->expiredTimerId) { - - case GSM_MULTIPART_TONES_TIMER: - case GSM_CONTINUOUS_TONES_TIMER: - lsm_tmr_tones_callback(timerMsg->usrData); - break; - - case GSM_ERROR_ONHOOK_TIMER: - fsmdef_error_onhook_timeout(timerMsg->usrData); - break; - - case GSM_AUTOANSWER_TIMER: - fsmdef_auto_answer_timeout(timerMsg->usrData); - break; - - case GSM_REVERSION_TIMER: - fsmdef_reversion_timeout((callid_t)(long)timerMsg->usrData); - break; - - case GSM_CAC_FAILURE_TIMER: - fsm_cac_process_bw_fail_timer(timerMsg->usrData); - break; - - case GSM_DIAL_TIMEOUT_TIMER: - dp_dial_timeout(timerMsg->usrData); - break; - - case GSM_KPML_INTER_DIGIT_TIMER: - kpml_inter_digit_timer_callback(timerMsg->usrData); - break; - case GSM_KPML_CRITICAL_DIGIT_TIMER: - case GSM_KPML_EXTRA_DIGIT_TIMER: - break; - - case GSM_KPML_SUBSCRIPTION_TIMER: - kpml_subscription_timer_callback(timerMsg->usrData); - break; - - case GSM_REQ_PENDING_TIMER: - timeout_msg = fsmdef_feature_timer_timeout( - CC_FEATURE_REQ_PEND_TIMER_EXP, - timerMsg->usrData); - break; - - case GSM_RINGBACK_DELAY_TIMER: - timeout_msg = fsmdef_feature_timer_timeout( - CC_FEATURE_RINGBACK_DELAY_TIMER_EXP, - timerMsg->usrData); - break; - case GSM_FLASH_ONCE_TIMER: - if (media_timer_callback != NULL) { - (* ((media_timer_callback)))(); - } - break; - case GSM_TONE_DURATION_TIMER: - lsm_tone_duration_tmr_callback(timerMsg->usrData); - break; - default: - GSM_ERR_MSG(GSM_F_PREFIX"unknown timer %d\n", fname, - timerMsg->expiredTimerName); - break; - } - - /* - * If there is a timer message to be processed by state machine, - * hands it to GSM state machine here. - */ - if (timeout_msg != NULL) { - /* Let state machine handle glare timer expiration */ - gsm_process_msg(GSM_GSM, timeout_msg); - cpr_free(timeout_msg); - } -} - -static void -gsm_init (void) -{ - /* Placeholder for any initialization tasks */ -} - -void -gsm_shutdown (void) -{ - gsm_initialized = FALSE; - - lsm_shutdown(); - fsm_shutdown(); - fim_shutdown(); - dcsm_shutdown(); -} - -void -gsm_reset (void) -{ - dp_reset(); - lsm_reset(); - fsmutil_free_all_shown_calls_ci_map(); -} - -void -GSMTask (void *arg) -{ - static const char fname[] = "GSMTask"; - void *msg; - phn_syshdr_t *syshdr; - boolean release_msg = TRUE; - - /* - * Get the GSM message queue handle - * A hack until the tasks in irx are - * CPRized. - */ - gsm_msg_queue = (cprMsgQueue_t) arg; - if (!gsm_msg_queue) { - GSM_ERR_MSG(GSM_F_PREFIX"invalid input, exiting\n", fname); - return; - } - - if (platThreadInit("GSMTask") != 0) { - return; - } - /* - * Adjust relative priority of GSM thread. - */ - (void) cprAdjustRelativeThreadPriority(GSM_THREAD_RELATIVE_PRIORITY); - - /* - * Initialize all the GSM modules - */ - lsm_init(); - fsm_init(); - fim_init(); - gsm_init(); - dcsm_init(); - - cc_init(); - - fsmutil_init_shown_calls_ci_map(); - /* - * On Win32 platform, the random seed is stored per thread; therefore, - * each thread needs to seed the random number. It is recommended by - * MS to do the following to ensure randomness across application - * restarts. - */ - cpr_srand((unsigned int)time(NULL)); - - /* - * Cache random numbers for SRTP keys - */ - gsmsdp_cache_crypto_keys(); - - while (1) { - - release_msg = TRUE; - - msg = cprGetMessage(gsm_msg_queue, TRUE, (void **) &syshdr); - if (msg) { - switch (syshdr->Cmd) { - case TIMER_EXPIRATION: - gsm_process_timer_expiration(msg); - break; - - case GSM_SIP: - case GSM_GSM: - release_msg = gsm_process_msg(syshdr->Cmd, msg); - break; - - case DP_MSG_INIT_DIALING: - case DP_MSG_DIGIT_STR: - case DP_MSG_STORE_DIGIT: - case DP_MSG_DIGIT: - case DP_MSG_DIAL_IMMEDIATE: - case DP_MSG_REDIAL: - case DP_MSG_ONHOOK: - case DP_MSG_OFFHOOK: - case DP_MSG_UPDATE: - case DP_MSG_DIGIT_TIMER: - case DP_MSG_CANCEL_OFFHOOK_TIMER: - dp_process_msg(syshdr->Cmd, msg); - break; - - case SUB_MSG_B2BCNF_SUBSCRIBE_RESP: - case SUB_MSG_B2BCNF_NOTIFY: - case SUB_MSG_B2BCNF_TERMINATE: - sub_process_b2bcnf_msg(syshdr->Cmd, msg); - break; - - case SUB_MSG_FEATURE_SUBSCRIBE_RESP: - case SUB_MSG_FEATURE_NOTIFY: - case SUB_MSG_FEATURE_TERMINATE: - sub_process_feature_msg(syshdr->Cmd, msg); - break; - - case SUB_MSG_KPML_SUBSCRIBE: - case SUB_MSG_KPML_TERMINATE: - case SUB_MSG_KPML_NOTIFY_ACK: - case SUB_MSG_KPML_SUBSCRIBE_TIMER: - case SUB_MSG_KPML_DIGIT_TIMER: - kpml_process_msg(syshdr->Cmd, msg); - break; - - case REG_MGR_STATE_CHANGE: - gsm_reset(); - break; - case THREAD_UNLOAD: - destroy_gsm_thread(); - break; - - default: - GSM_ERR_MSG(GSM_F_PREFIX"Unknown message\n", fname); - break; - } - - cprReleaseSysHeader(syshdr); - if (release_msg == TRUE) { - cpr_free(msg); - } - - /* Check if there are pending messages for dcsm - * if it in the right state perform its operation - */ - dcsm_process_jobs(); - } - } -} - -/** - * This function will process SUBSCRIBED feature NOTIFY messages. - * - * @param[in] msg - pointer to ccsip_sub_not_data_t - * - * @return none - * - * @pre (msg != NULL) - */ -static void sub_process_b2bcnf_sub_resp (ccsip_sub_not_data_t *msg) -{ - static const char fname[] = "sub_process_b2bcnf_sub_resp"; - - callid_t call_id = CC_NO_CALL_ID; - callid_t other_call_id = CC_NO_CALL_ID; - cc_causes_t cause; - - fsmb2bcnf_get_sub_call_id_from_ccb ((fsmcnf_ccb_t *)(msg->request_id), - &call_id, &other_call_id); - - if (msg->u.subs_result_data.status_code == 200 || - msg->u.subs_result_data.status_code == 202 ) { - - cause = CC_CAUSE_OK; - - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs response = OK\n", - DEB_F_PREFIX_ARGS(GSM,fname)); - - } else { - - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs response = ERROR\n", - DEB_F_PREFIX_ARGS(GSM,fname)); - - cause = CC_CAUSE_ERROR; - } - - cc_feature_ack(CC_SRC_GSM, call_id, msg->line_id, CC_FEATURE_B2BCONF, NULL, cause); -} - -/** - * This function will process b2bcnf feature NOTIFY messages. - * - * @param[in] cmd - command - * @param[in] msg - pointer to ccsip_sub_not_data_t - * - * @return none - * - * @pre (msg != NULL) - */ -static void sub_process_b2bcnf_msg (uint32_t cmd, void *msg) -{ - static const char fname[] = "sub_process_b2bcnf_msg"; - cc_feature_data_t data; - callid_t call_id, other_call_id = CC_NO_CALL_ID; - - fsmb2bcnf_get_sub_call_id_from_ccb((fsmcnf_ccb_t *)((ccsip_sub_not_data_t *)msg)->request_id, - &call_id, &other_call_id); - switch (cmd) { - case SUB_MSG_B2BCNF_SUBSCRIBE_RESP: - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs response\n", - DEB_F_PREFIX_ARGS(GSM,fname)); - sub_process_b2bcnf_sub_resp((ccsip_sub_not_data_t *)msg); - break; - - case SUB_MSG_B2BCNF_NOTIFY: - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs notify\n", - DEB_F_PREFIX_ARGS(GSM,fname)); - sub_process_feature_notify((ccsip_sub_not_data_t *)msg, call_id, other_call_id); - break; - case SUB_MSG_B2BCNF_TERMINATE: - /* - * This is posted by SIP stack if it is shutting down or rolling over. - * if so, notify b2bcnf to cleanup state machine. - */ - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs terminate\n", - DEB_F_PREFIX_ARGS(GSM,fname)); - - data.notify.subscription = CC_SUBSCRIPTIONS_REMOTECC; - data.notify.method = CC_RCC_METHOD_REFER; - data.notify.data.rcc.feature = CC_FEATURE_B2BCONF; - - data.notify.cause = CC_CAUSE_ERROR; - - cc_feature(CC_SRC_GSM, call_id, 0, CC_FEATURE_NOTIFY, &data); - - break; - default: - GSM_DEBUG(DEB_F_PREFIX"B2BCNF subs unknown event\n", - DEB_F_PREFIX_ARGS(GSM,fname)); - break; - } -} - -/** - * This function will process SUBSCRIBED feature NOTIFY messages. - * - * @param[in] cmd - command - * @param[in] msg - pointer to ccsip_sub_not_data_t - * - * @return none - * - * @pre (msg != NULL) - */ -static void sub_process_feature_msg (uint32_t cmd, void *msg) -{ - callid_t call_id; - cc_feature_ack_t temp_msg; - - switch (cmd) { - case SUB_MSG_FEATURE_SUBSCRIBE_RESP: - /* - * if the response in non-2xx final, we should reset the active feature. - */ - call_id = (callid_t)(((ccsip_sub_not_data_t *)msg)->request_id); - if (((ccsip_sub_not_data_t *)msg)->u.subs_result_data.status_code > 299) { - memset(&temp_msg, 0, sizeof(temp_msg)); - temp_msg.msg_id = CC_MSG_FEATURE_ACK; - temp_msg.src_id = CC_SRC_GSM; - temp_msg.call_id = call_id; - fim_process_event((void *)&temp_msg, FALSE); - } - break; - case SUB_MSG_FEATURE_NOTIFY: - call_id = (callid_t)(((ccsip_sub_not_data_t *)msg)->request_id); - sub_process_feature_notify((ccsip_sub_not_data_t *)msg, call_id, - CC_NO_CALL_ID); - break; - case SUB_MSG_FEATURE_TERMINATE: - /* - * This is posted by SIP stack if it is shutting down or rolling over. - * if so, sip stack already cleaned up the subscription. so do nothing. - */ - break; - } -} - -/** - * This function will process SUBSCRIBED feature NOTIFY messages. - * - * @param[in] msg - pointer to ccsip_sub_not_data_t - * - * @return none - * - * @pre (msg != NULL) - */ -static void sub_process_feature_notify (ccsip_sub_not_data_t *msg, callid_t call_id, - callid_t other_call_id) -{ - static const char fname[] = "sub_process_feature_notify"; - ccsip_event_data_t *ev_data; - cc_feature_ack_t temp_msg; - - - /* - * send response to NOTIFY. - */ - (void)sub_int_notify_ack(msg->sub_id, SIP_STATUS_SUCCESS, msg->u.notify_ind_data.cseq); - - /* - * if the subscription state is terminated, clean up the subscription. - */ - if (msg->u.notify_ind_data.subscription_state == SUBSCRIPTION_STATE_TERMINATED) { - /* - * post SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED. - * do not force SUB/NOT mgr to cleanup SCB immediately, because we may have to handle digest - * challenges to terminating SUBSCRIBE sent. - */ - (void)sub_int_subscribe_term(msg->sub_id, FALSE, msg->request_id, CC_SUBSCRIPTIONS_REMOTECC); - - } - ev_data = msg->u.notify_ind_data.eventData; - msg->u.notify_ind_data.eventData = NULL; - if (ev_data == NULL) { - GSM_ERR_MSG(DEB_F_PREFIX"No body in the NOTIFY message\n", - DEB_F_PREFIX_ARGS(GSM, fname)); - /* - * if (no content & subscription state is TERMINATED - * then reset active_feature to NONE. - */ - if (msg->u.notify_ind_data.subscription_state == SUBSCRIPTION_STATE_TERMINATED) { - memset(&temp_msg, 0, sizeof(temp_msg)); - temp_msg.msg_id = CC_MSG_FEATURE_ACK; - temp_msg.src_id = CC_SRC_GSM; - temp_msg.call_id = call_id; - fim_process_event((void *)&temp_msg, FALSE); - } - return; - } - - // other types of event data is not supported as of now. - free_event_data(ev_data); -} - -/* - * return TRUE if GSM is considered idle, - * currently this means lsm is idle - * FALSE otherwise. - */ -boolean -gsm_is_idle (void) -{ - if (lsm_is_phone_idle()) { - return (TRUE); - } - return (FALSE); -} - -/* - * Function: destroy_gsm_thread - * Description: shutdown gsm and kill gsm thread - * Parameters: none - * Returns: none - */ -void destroy_gsm_thread() -{ - static const char fname[] = "destroy_gsm_thread"; - DEF_DEBUG(DEB_F_PREFIX"Unloading GSM and destroying GSM thread\n", - DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - gsm_shutdown(); - dp_shutdown(); - kpml_shutdown(); - (void) cprDestroyThread(gsm_thread); -} diff --git a/libs/sipcc/core/gsm/gsm_sdp.c b/libs/sipcc/core/gsm/gsm_sdp.c deleted file mode 100644 index 2f18f474b2..0000000000 --- a/libs/sipcc/core/gsm/gsm_sdp.c +++ /dev/null @@ -1,6610 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_in.h" -#include "cpr_rand.h" -#include "cpr_stdlib.h" -#include "lsm.h" -#include "fsm.h" -#include "ccapi.h" -#include "ccsip_sdp.h" -#include "sdp.h" -#include "gsm.h" -#include "gsm_sdp.h" -#include "util_string.h" -#include "rtp_defs.h" -#include "debug.h" -#include "dtmf.h" -#include "prot_configmgr.h" -#include "dns_utils.h" -#include "sip_interface_regmgr.h" -#include "platform_api.h" -#include "vcm.h" -//#include "prlog.h" -#include "plstr.h" -#include "sdp_private.h" - -//TODO Need to place this in a portable location -#define MULTICAST_START_ADDRESS 0xe1000000 -#define MULTICAST_END_ADDRESS 0xefffffff - -/* Only first octet contains codec type */ -#define GET_CODEC_TYPE(a) ((uint8_t)((a) & 0XFF)) - -#define GSMSDP_SET_MEDIA_DIABLE(media) \ - (media->src_port = 0) - -#define CAST_DEFAULT_BITRATE 320000 -/* - * The maximum number of media lines per call. This puts the upper limit - * on * the maximum number of media lines per call to resource hogging. - * The value of 8 is intended up to 2 audio and 2 video streams with - * each stream can offer IPV4 and IPV6 alternate network address type - * in ANAT group (RFC-4091). - */ -#define GSMSDP_MAX_MLINES_PER_CALL (8) - -/* - * Permanent number of free media structure elements for media structure - * that represents media line in the SDP. The maximum number of elements - * is set to equal number of call or LSM_MAX_CALLS. This should be enough - * to minimumly allow typical a single audio media stream per call scenario - * without using dynamic memory. - * - * If more media structures are needed than this number, the addition - * media structures are allocated from heap and they will be freed back - * from heap after thehy are not used. The only time where the heap - * is used when phone reaches the maximum call capacity and each one - * of the call is using more than one media lines. - */ -#define GSMSDP_PERM_MEDIA_ELEMS (LSM_MAX_CALLS) - -/* - * The permanent free media structure elements use static array. - * It is to ensure a low overhead for this a typical single audio call. - */ -static fsmdef_media_t gsmsdp_free_media_chunk[GSMSDP_PERM_MEDIA_ELEMS]; -static sll_lite_list_t gsmsdp_free_media_list; - -typedef enum { - MEDIA_TABLE_GLOBAL, - MEDIA_TABLE_SESSION -} media_table_e; - -/* Forward references */ -static cc_causes_t -gsmsdp_init_local_sdp (const char *peerconnection, cc_sdp_t **sdp_pp); - -static void -gsmsdp_set_media_capability(fsmdef_media_t *media, - const cc_media_cap_t *media_cap); -static fsmdef_media_t * -gsmsdp_add_media_line(fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap, - uint8_t cap_index, uint16_t level, - cpr_ip_type addr_type, boolean offer); - - -extern cc_media_cap_table_t g_media_table; - -extern boolean g_disable_mass_reg_debug_print; -/** - * A wraper function to return the media capability supported by - * the platform and session. This is a convient place if policy - * to get the capability table as it applies to the session - * updates the media_cap_tbl ptr in dcb - * - * @param[in]dcb - pointer to the fsmdef_dcb_t - - * - * @return - pointer to the the media capability table for session - */ -static const cc_media_cap_table_t *gsmsdp_get_media_capability (fsmdef_dcb_t *dcb_p) -{ - static const char *fname = "gsmsdp_get_media_capability"; - int sdpmode = 0; - - if (g_disable_mass_reg_debug_print == FALSE) { - GSM_DEBUG(DEB_F_PREFIX"dcb video pref %x\n", - DEB_F_PREFIX_ARGS(GSM, fname), dcb_p->video_pref); - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if ( dcb_p->media_cap_tbl == NULL ) { - dcb_p->media_cap_tbl = (cc_media_cap_table_t*) cpr_malloc(sizeof(cc_media_cap_table_t)); - if ( dcb_p->media_cap_tbl == NULL ) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"media table malloc failed.\n", - dcb_p->line, dcb_p->call_id, fname); - return NULL; - } - } - - *(dcb_p->media_cap_tbl) = g_media_table; - - /* - * Turn off two default streams, this is temporary - * until we can handle multiple streams properly - */ - if (sdpmode) { - dcb_p->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE; - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE; - dcb_p->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY; - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY; - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = TRUE; - } else { - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = FALSE; - - if ( dcb_p->video_pref == SDP_DIRECTION_INACTIVE) { - // do not enable video - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE; - } - - if ( dcb_p->video_pref == SDP_DIRECTION_RECVONLY ) { - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref; - } - - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDONLY ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE; - DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from sendonly\n", - dcb_p->line, dcb_p->call_id, fname); - } - } else if ( dcb_p->video_pref == SDP_DIRECTION_SENDONLY ) { - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref; - } - - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_RECVONLY ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE; - DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from recvonly\n", - dcb_p->line, dcb_p->call_id, fname); - } - } // else if requested is SENDRECV just go by capability - } - - return (dcb_p->media_cap_tbl); -} - -/* - * Process a single constraint for one media capablity - */ -void gsmsdp_process_cap_constraint(cc_media_cap_t *cap, - const char *constraint) { - /* Check constraint string for values "TRUE" or "FALSE" - (currently set in PeerConnectionImpl.cpp, with only - two possible hardcoded values). - TODO -- The values that constraints can take are - fairly narrow and enumerated; they should probably - use an enumeration rather than a string. See bug 811360. - */ - if (constraint[0] == 'F') { - cap->support_direction &= ~SDP_DIRECTION_FLAG_RECV; - } else if (constraint[0] == 'T') { - cap->support_direction |= SDP_DIRECTION_FLAG_RECV; - } -} - -/* - * Process constraints only related to media capabilities., i.e - * OfferToReceiveAudio, OfferToReceiveVideo - */ -void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb, - const cc_media_constraints_t* constraints) { - int i = 0; - - for (i=0; iconstraint_count; i++) { - if (strcmp(constraints_table[OfferToReceiveAudio].name, - constraints->constraints[i]->name) == 0) { - gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_AUDIO_1], - constraints->constraints[i]->value); - } else if (strcmp(constraints_table[OfferToReceiveVideo].name, - constraints->constraints[i]->name) == 0) { - gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_VIDEO_1], - constraints->constraints[i]->value); - } - } -} - -/** - * Copy an fsmdef_media_t's payload list to its previous_sdp's payload list - * - * @param[in]media - pointer to the fsmdef_media_t to update - */ -void gsmsdp_copy_payloads_to_previous_sdp (fsmdef_media_t *media) -{ - // static const char *fname = "gsmsdp_copy_payloads_to_previous_sdp"; - - if ((!media->payloads) && (NULL != media->previous_sdp.payloads)) - { - cpr_free(media->previous_sdp.payloads); - media->previous_sdp.payloads = NULL; - media->previous_sdp.num_payloads = 0; - } - - /* Ensure that there is enough space to hold all the payloads */ - if (media->num_payloads > media->previous_sdp.num_payloads) - { - media->previous_sdp.payloads = - cpr_realloc(media->previous_sdp.payloads, - media->num_payloads * sizeof(vcm_payload_info_t)); - } - - /* Copy the payloads over */ - media->previous_sdp.num_payloads = media->num_payloads; - memcpy(media->previous_sdp.payloads, media->payloads, - media->num_payloads * sizeof(vcm_payload_info_t)); - media->previous_sdp.num_payloads = media->num_payloads; -} - -/** - * Find an entry for the specified codec type in the vcm_payload_info_t - * list array. - * - * @param[in]codec - Codec type to find - * @param[in]payload_info - Array of payload info entries - * @param[in]num_payload_info - Total number of elements in payload_info - * @param[in]instance - Which instance of the codec to find - * (e.g., if more than one entry for a codec type) - * - * @return Pointer to the payload info if found; - * NULL when no match is found. - */ -vcm_payload_info_t *gsmsdp_find_info_for_codec(rtp_ptype codec, - vcm_payload_info_t *payload_info, - int num_payload_info, - int instance) { - int i; - for (i = 0; i < num_payload_info; i++) { - if (payload_info[i].codec_type == codec) - { - instance--; - if (instance == 0) { - return &(payload_info[i]); - } - } - } - return NULL; -} - - -/** - * Sets up the media track table - * - * @param[in]dcb - pointer to the fsmdef_dcb_t - * - * @return - pointer to the the media track table for session - */ -static const cc_media_remote_stream_table_t *gsmsdp_get_media_stream_table (fsmdef_dcb_t *dcb_p) -{ - static const char *fname = "gsmsdp_get_media_stream_table"; - if ( dcb_p->remote_media_stream_tbl == NULL ) { - dcb_p->remote_media_stream_tbl = (cc_media_remote_stream_table_t*) cpr_malloc(sizeof(cc_media_remote_stream_table_t)); - memset(dcb_p->remote_media_stream_tbl, 0, sizeof(cc_media_remote_stream_table_t)); - - if ( dcb_p->remote_media_stream_tbl == NULL ) { - - GSM_ERR_MSG(GSM_L_C_F_PREFIX"media track table malloc failed.\n", - dcb_p->line, dcb_p->call_id, fname); - return NULL; - } - } - - return (dcb_p->remote_media_stream_tbl); -} - -/** - * The function creates a free media structure elements list. The - * free list is global for all calls. The function must be called once - * during GSM initializtion. - * - * @param None. - * - * @return TRUE - free media structure list is created - * successfully. - * FALSE - failed to create free media structure - * list. - */ -boolean -gsmsdp_create_free_media_list (void) -{ - uint32_t i; - fsmdef_media_t *media; - - /* initialize free media_list structure */ - (void)sll_lite_init(&gsmsdp_free_media_list); - - /* - * Populate the free list: - * Break the entire chunk into multiple free elements and link them - * onto to the free media list. - */ - media = &gsmsdp_free_media_chunk[0]; /* first element */ - for (i = 0; i < GSMSDP_PERM_MEDIA_ELEMS; i++) { - (void)sll_lite_link_head(&gsmsdp_free_media_list, - (sll_lite_node_t *)media); - media = media + 1; /* next element */ - } - - /* Successful create media free list */ - return (TRUE); -} - -/** - * The function destroys the free media structure list. It should be - * call during GSM shutdown. - * - * @param None. - * - * @return None. - */ -void -gsmsdp_destroy_free_media_list (void) -{ - /* - * Although the free chunk is not allocated but, - * NULL out the free list header to indicate that the - * there is not thing from the free chunk. - */ - (void)sll_lite_init(&gsmsdp_free_media_list); -} - -/** - * The function allocates a media structure. The function - * attempts to obtain a free media structure from the free media - * structure list first. If free list is empty then the media structure - * is allocated from a memory pool. - * - * @param None. - * - * @return pointer to the fsmdef_media_t if successful or - * NULL when there is no free media structure - * is available. - */ -static fsmdef_media_t * -gsmsdp_alloc_media (void) -{ - static const char fname[] = "gsmsdp_alloc_media"; - fsmdef_media_t *media = NULL; - - /* Get a media element from the free list */ - media = (fsmdef_media_t *)sll_lite_unlink_head(&gsmsdp_free_media_list); - if (media == NULL) { - /* no free element from cache, allocate it from the pool */ - media = cpr_malloc(sizeof(fsmdef_media_t)); - GSM_DEBUG(DEB_F_PREFIX"get from dynamic pool, media %x\n", - DEB_F_PREFIX_ARGS(GSM, fname), media); - } - return (media); -} - -/** - * The function frees a media structure back to the free list or - * heap. If the media structure is from the free list then it - * is put back to the free list otherwise it will be freed - * back to the dynamic pool. - * - * @param[in]media - pointer to fsmdef_media_t to free back to - * free list. - * - * @return pointer to the fsmdef_media_t if successful - * NULL when there is no free media structure - * is available. - */ -static void -gsmsdp_free_media (fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_free_media"; - - if (media == NULL) { - return; - } - - if (media-> video != NULL ) { - vcmFreeMediaPtr(media->video); - } - - if(media->payloads != NULL) { - cpr_free(media->payloads); - media->payloads = NULL; - media->num_payloads = 0; - } - /* - * Check to see if the element is part of the - * free chunk space. - */ - if ((media >= &gsmsdp_free_media_chunk[0]) && - (media <= &gsmsdp_free_media_chunk[GSMSDP_PERM_MEDIA_ELEMS-1])) { - /* the element is part of free chunk, put it back to the list */ - (void)sll_lite_link_head(&gsmsdp_free_media_list, - (sll_lite_node_t *)media); - } else { - /* this element is from the dynamic pool, free it back */ - cpr_free(media); - GSM_DEBUG(DEB_F_PREFIX"free media 0x%x to dynamic pool\n", - DEB_F_PREFIX_ARGS(GSM, fname), media); - } -} - -/** - * Initialize the media entry. The function initializes media - * entry. - * - * @param[in]media - pointer to fsmdef_media_t of the media entry to be - * initialized. - * - * @return none - * - * @pre (media not_eq NULL) - */ -static void -gsmsdp_init_media (fsmdef_media_t *media) -{ - media->refid = CC_NO_MEDIA_REF_ID; - media->type = SDP_MEDIA_INVALID; /* invalid (free entry) */ - media->packetization_period = ATTR_PTIME; - media->max_packetization_period = ATTR_MAXPTIME; - media->mode = (uint16_t)vcmGetILBCMode(); - media->vad = VCM_VAD_OFF; - /* Default to audio codec */ - media->level = 0; - media->dest_port = 0; - media->dest_addr = ip_addr_invalid; - media->is_multicast = FALSE; - media->multicast_port = 0; - media->avt_payload_type = RTP_NONE; - media->src_port = 0; - media->src_addr = ip_addr_invalid; - media->rcv_chan = FALSE; - media->xmit_chan = FALSE; - - media->direction = SDP_DIRECTION_INACTIVE; - media->direction_set = FALSE; - media->transport = SDP_TRANSPORT_INVALID; - media->tias_bw = SDP_INVALID_VALUE; - media->profile_level = 0; - - media->previous_sdp.avt_payload_type = RTP_NONE; - media->previous_sdp.dest_addr = ip_addr_invalid; - media->previous_sdp.dest_port = 0; - media->previous_sdp.direction = SDP_DIRECTION_INACTIVE; - media->previous_sdp.packetization_period = media->packetization_period; - media->previous_sdp.max_packetization_period = media->max_packetization_period; - media->previous_sdp.payloads = NULL; - media->previous_sdp.num_payloads = 0; - media->previous_sdp.tias_bw = SDP_INVALID_VALUE; - media->previous_sdp.profile_level = 0; - - media->hold = FSM_HOLD_NONE; - media->flags = 0; /* clear all flags */ - media->cap_index = CC_MAX_MEDIA_CAP; /* max is invalid value */ - media->video = NULL; - media->candidate_ct = 0; - media->rtcp_mux = FALSE; - media->protocol = NULL; - media->payloads = NULL; - media->num_payloads = 0; -} - -/** - * - * Returns a pointer to a new the fsmdef_media_t for a given dcb. - * The default media parameters will be intialized for the known or - * supported media types. The new media is also added to the media list - * in the dcb. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media_type - sdp_media_e. - * @param[in]level - uint16_t for media line level. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_get_new_media (fsmdef_dcb_t *dcb_p, sdp_media_e media_type, - uint16_t level) -{ - static const char fname[] = "gsmsdp_get_new_media"; - fsmdef_media_t *media; - static media_refid_t media_refid = CC_NO_MEDIA_REF_ID; - sll_lite_return_e sll_lite_ret; - - /* check to ensue we do not handle too many media lines */ - if (GSMSDP_MEDIA_COUNT(dcb_p) >= GSMSDP_MAX_MLINES_PER_CALL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"exceeding media lines per call\n", - dcb_p->line, dcb_p->call_id, fname); - return (NULL); - } - - /* allocate new media entry */ - media = gsmsdp_alloc_media(); - if (media != NULL) { - /* initialize the media entry */ - gsmsdp_init_media(media); - - /* assigned media reference id */ - if (++media_refid == CC_NO_MEDIA_REF_ID) { - media_refid = 1; - } - media->refid = media_refid; - media->type = media_type; - media->level = level; - - /* append the media to the active list */ - sll_lite_ret = sll_lite_link_tail(&dcb_p->media_list, - (sll_lite_node_t *)media); - if (sll_lite_ret != SLL_LITE_RET_SUCCESS) { - /* fails to put the new media entry on to the list */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"error %d when add media to list\n", - dcb_p->line, dcb_p->call_id, fname, sll_lite_ret); - gsmsdp_free_media(media); - media = NULL; - } - } - return (media); -} - -/** - * The function removes the media entry from the list of a given call and - * then deallocates the media entry. - * - * @param[in]dcb - pointer to fsmdef_def_t for the dcb whose - * media to be removed from. - * @param[in]media - pointer to fsmdef_media_t for the media - * entry to be removed. - * - * @return none - * - * @pre (dcb not_eq NULL) - */ -static void gsmsdp_remove_media (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_remove_media"; - cc_action_data_t data; - - if (media == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"removing NULL media\n", - dcb_p->line, dcb_p->call_id, fname); - return; - } - - if (media->rcv_chan || media->xmit_chan) { - /* stop media, if it is opened */ - data.stop_media.media_refid = media->refid; - (void)cc_call_action(dcb_p->call_id, dcb_p->line, CC_ACTION_STOP_MEDIA, - &data); - } - /* remove this media off the list */ - (void)sll_lite_remove(&dcb_p->media_list, (sll_lite_node_t *)media); - - /* Release the port */ - vcmRxReleasePort(media->cap_index, dcb_p->group_id, media->refid, - lsm_get_ms_ui_call_handle(dcb_p->line, dcb_p->call_id, CC_NO_CALL_ID), media->src_port); - - /* free media structure */ - gsmsdp_free_media(media); -} - -/** - * The function performs cleaning media list of a given call. It walks - * through the list and deallocates each media entries. - * - * @param[in]dcb - pointer to fsmdef_def_t for the dcb whose - * media list to be cleaned. - * - * @return none - * - * @pre (dcb not_eq NULL) - */ -void gsmsdp_clean_media_list (fsmdef_dcb_t *dcb_p) -{ - fsmdef_media_t *media = NULL; - - while (TRUE) { - /* unlink head and free the media */ - media = (fsmdef_media_t *)sll_lite_unlink_head(&dcb_p->media_list); - if (media != NULL) { - gsmsdp_free_media(media); - } else { - break; - } - } -} - -/** - * - * The function is used for per call media list initialization. It is - * an interface function to other module for initializing the media list - * used during a call. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t where the media list - * will be attached to. - * - * @return None. - * @pre (dcb not_eq NULL) - */ -void gsmsdp_init_media_list (fsmdef_dcb_t *dcb_p) -{ - const cc_media_cap_table_t *media_cap_tbl; - const cc_media_remote_stream_table_t *media_track_tbl; - const char fname[] = "gsmsdp_init_media_list"; - - /* do the actual media element list initialization */ - (void)sll_lite_init(&dcb_p->media_list); - - media_cap_tbl = gsmsdp_get_media_capability(dcb_p); - - if (media_cap_tbl == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capbility available\n", - dcb_p->line, dcb_p->call_id, fname); - } - - media_track_tbl = gsmsdp_get_media_stream_table(dcb_p); - - if (media_track_tbl == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media tracks available\n", - dcb_p->line, dcb_p->call_id, fname); - } -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * correspoinding media level in the SDP. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]level - uint16_t for media line level. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_find_media_by_level (fsmdef_dcb_t *dcb_p, uint16_t level) -{ - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches - * the level. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->level == level) { - /* found a match */ - return (media); - } - } - return (NULL); -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * correspoinding reference ID. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]refid - media reference ID to look for. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -fsmdef_media_t * -gsmsdp_find_media_by_refid (fsmdef_dcb_t *dcb_p, media_refid_t refid) -{ - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches - * the reference ID. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->refid == refid) { - /* found a match */ - return (media); - } - } - return (NULL); -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * correspoinding capability index. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]cap_index - capability table index. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_find_media_by_cap_index (fsmdef_dcb_t *dcb_p, uint8_t cap_index) -{ - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches - * the reference ID. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->cap_index == cap_index) { - /* found a match */ - return (media); - } - } - return (NULL); - -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * first audio type in the SDP. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -fsmdef_media_t *gsmsdp_find_audio_media (fsmdef_dcb_t *dcb_p) -{ - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches - * SDP_MEDIA_AUDIO type. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->type == SDP_MEDIA_AUDIO) { - /* found a match */ - return (media); - } - } - return (NULL); -} - -/** - * - * The function finds an unused media line given type. - * - * @param[in]sdp - void pointer of thd SDP libray handle. - * @param[in]media_type - media type of the unused line. - * - * @return level (line) of the unused one if found or - * 0 if there is no unused one found. - */ -static uint16_t -gsmsdp_find_unused_media_line_with_type (void *sdp, sdp_media_e media_type) -{ - uint16_t num_m_lines, level; - int32_t port; - - num_m_lines = sdp_get_num_media_lines(sdp); - for (level = 1; level <= num_m_lines; level++) { - port = sdp_get_media_portnum(sdp, level); - if (port == 0) { - /* This slot is not used, check the type */ - if (sdp_get_media_type(sdp, level) == media_type) { - /* Found an empty slot that has the same media type */ - return (level); - } - } - } - /* no unused media line of the given type found */ - return (0); -} - -/** - * - * The function returns the media cap entry pointer to the caller based - * on the index. - * - * @param[in]cap_index - uint8_t for index of the media cap table. - * - * @return pointer to the media cap entry if one is available. - * NULL if none is available. - * - */ -static const cc_media_cap_t * -gsmsdp_get_media_cap_entry_by_index (uint8_t cap_index, fsmdef_dcb_t *dcb_p) -{ - const cc_media_cap_table_t *media_cap_tbl; - - media_cap_tbl = dcb_p->media_cap_tbl; - - if (media_cap_tbl == NULL) { - return (NULL); - } - - if (cap_index >= CC_MAX_MEDIA_CAP) { - return (NULL); - } - return (&media_cap_tbl->cap[cap_index]); -} - -/** - * - * Returns a pointer to the fsmdef_media_t in the dcb for the - * corresponding media line. It looks for another media line - * with the same type and cap_index but different level - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media - current media level. - * - * @return pointer to the fsmdef_media_t of the corresponding - * media entry in the dcb. - * @pre (dcb not_eq NULL) - */ -fsmdef_media_t * -gsmsdp_find_anat_pair (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - fsmdef_media_t *searched_media = NULL; - - /* - * search the all entries that has a the same capability index - * but at a different level. The only time that this is true is - * both media are in the same ANAT group. - */ - GSMSDP_FOR_ALL_MEDIA(searched_media, dcb_p) { - if ((searched_media->cap_index == media->cap_index) && - (searched_media->level != media->level)) { - /* found a match */ - return (searched_media); - } - } - return (NULL); -} - -/** - * - * The function queries platform to see if the platform is capable - * of handle mixing additional media or not. - * - * P2: This may go away when integrate with the platform. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t structure. - * @param[in]media_type - media type to be mixed. - * - * @return TRUE the media can be mixed. - * FALSE the media can not be mixed - * - * @pre (dcb_p not_eq NULL) - */ -static boolean -gsmsdp_platform_addition_mix (fsmdef_dcb_t *dcb_p, sdp_media_e media_type) -{ - return (FALSE); -} - - -/** - * - * The function updates the local time stamp during SDP offer/answer - * processing. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]offer - boolean indicates this is procssing an offered - * SDP - * @param[in]initial_offer - boolean indicates this is processin an - * initial offered SDP. - * - * @return none. - * @pre (dcb not_eq NULL) - */ -static void -gsmsdp_update_local_time_stamp (fsmdef_dcb_t *dcb_p, boolean offer, - boolean initial_offer) -{ - const char fname[] = "gsmsdp_update_local_time_stamp"; - void *local_sdp_p; - void *remote_sdp_p; - - local_sdp_p = dcb_p->sdp->src_sdp; - remote_sdp_p = dcb_p->sdp->dest_sdp; - - /* - * If we are processing an offer sdp, need to set the - * start time and stop time based on the remote SDP - */ - if (initial_offer) { - /* - * Per RFC3264, time description of answer must equal that - * of the offer. - */ - (void) sdp_set_time_start(local_sdp_p, - sdp_get_time_start(remote_sdp_p)); - (void) sdp_set_time_stop(local_sdp_p, sdp_get_time_stop(remote_sdp_p)); - } else if (offer) { - /* - * Set t= line based on remote SDP - */ - if (sdp_timespec_valid(remote_sdp_p) != TRUE) { - GSM_DEBUG(DEB_L_C_F_PREFIX"\nTimespec is invalid.\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - (void) sdp_set_time_start(local_sdp_p, "0"); - (void) sdp_set_time_stop(local_sdp_p, "0"); - } else { - if (sdp_get_time_start(local_sdp_p) != - sdp_get_time_start(remote_sdp_p)) { - (void) sdp_set_time_start(local_sdp_p, - sdp_get_time_start(remote_sdp_p)); - } - if (sdp_get_time_stop(local_sdp_p) != - sdp_get_time_stop(remote_sdp_p)) { - (void) sdp_set_time_stop(local_sdp_p, - sdp_get_time_stop(remote_sdp_p)); - } - } - } -} - -/** - * - * The function gets the local source address address and puts it into - * the media entry. - * - * @param[in]media - pointer to fsmdef_media_t structure to - * get the local address into. - * - * @return none. - * @pre (media not_eq NULL) - */ -static void -gsmsdp_get_local_source_v4_address (fsmdef_media_t *media) -{ - int nat_enable = 0; - char curr_media_ip[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t addr; - const char fname[] = "gsmsdp_get_local_source_v4_address"; - - /* - * Get device address. - */; - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - init_empty_str(curr_media_ip); - config_get_value(CFGID_MEDIA_IP_ADDR, curr_media_ip, - MAX_IPADDR_STR_LEN); - if (is_empty_str(curr_media_ip) == FALSE) { - - str2ip(curr_media_ip, &addr); - util_ntohl(&addr, &addr); - if (util_check_if_ip_valid(&media->src_addr) == FALSE) { - // Update the media Src address only if it is invalid - media->src_addr = addr; - GSM_ERR_MSG("%s: Update IP %s", fname, curr_media_ip); - } - } else { - sip_config_get_net_device_ipaddr(&media->src_addr); - } - } else { - sip_config_get_nat_ipaddr(&media->src_addr); - } -} - -/* - * - * The function gets the local source address address and puts it into - * the media entry. - * - * @param[in]media - pointer to fsmdef_media_t structure to - * get the local address into. - * - * @return none. - * @pre (media not_eq NULL) - */ -static void -gsmsdp_get_local_source_v6_address (fsmdef_media_t *media) -{ - int nat_enable = 0; - - /* - * Get device address. - */ - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_ipv6_device_ipaddr(&media->src_addr); - } else { - sip_config_get_nat_ipaddr(&media->src_addr); - } -} - -/** - * Set the connection address into the SDP. - * - * @param[in]sdp_p - pointer to SDP (type void) - * @param[in]level - media level or line. - * @param[in]addr - string representation of IP address. - * Assumed to be IPV6 if larger than 15. - * - * @return none. - * @pre (sdp_p not_eq NULL) and (addr not_eq NULL) - * - */ -static void -gsmsdp_set_connection_address (void *sdp_p, uint16_t level, char *addr) -{ - /* - * c= line
- */ - - (void) sdp_set_conn_nettype(sdp_p, level, SDP_NT_INTERNET); - - if (addr && (strlen(addr) > strlen("123.123.123.123"))) - { - // Long IP address, must be IPV6 - (void) sdp_set_conn_addrtype(sdp_p, level, SDP_AT_IP6); - } - else - { - (void) sdp_set_conn_addrtype(sdp_p, level, SDP_AT_IP4); - } - - (void) sdp_set_conn_address(sdp_p, level, addr); -} - -/* - * gsmsdp_set_2543_hold_sdp - * - * Description: - * - * Manipulates the local SDP of the specified DCB to indicate hold - * to the far end using 2543 style signaling. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose SDP is to be manipulated. - * - */ -static void -gsmsdp_set_2543_hold_sdp (fsmdef_dcb_t *dcb_p, uint16 level) -{ - (void) sdp_set_conn_nettype(dcb_p->sdp->src_sdp, level, SDP_NT_INTERNET); - (void) sdp_set_conn_addrtype(dcb_p->sdp->src_sdp, level, SDP_AT_IP4); - (void) sdp_set_conn_address(dcb_p->sdp->src_sdp, level, "0.0.0.0"); -} - - -/* - * gsmsdp_set_video_media_attributes - * - * Description: - * - * Add the specified video media format to the SDP. - * - * Parameters: - * - * media_type - The media type (format) to add to the specified SDP. - * sdp_p - Pointer to the SDP the media attribute is to be added to. - * level - The media level of the SDP where the media attribute is to be added. - * payload_number - AVT payload type if the media attribute being added is - * RTP_AVT. - * - */ -static void -gsmsdp_set_video_media_attributes (uint32_t media_type, void *cc_sdp_p, uint16_t level, - uint16_t payload_number) -{ - uint16_t a_inst; - void *sdp_p = ((cc_sdp_t*)cc_sdp_p)->src_sdp; - - switch (media_type) { - case RTP_H263: - case RTP_H264_P0: - case RTP_H264_P1: - case RTP_VP8: - /* - * add a=rtpmap line - */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTPMAP, &a_inst) - != SDP_SUCCESS) { - return; - } - - (void) sdp_attr_set_rtpmap_payload_type(sdp_p, level, 0, a_inst, - payload_number); - - switch (media_type) { - case RTP_H263: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_H263v2); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_VIDEO_CLOCKRATE); - break; - case RTP_H264_P0: - case RTP_H264_P1: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_H264); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_VIDEO_CLOCKRATE); - break; - case RTP_VP8: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_VP8); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_VIDEO_CLOCKRATE); - break; - } - GSM_DEBUG("gsmsdp_set_video_media_attributes- populate attribs %d\n", payload_number ); - - vcmPopulateAttribs(cc_sdp_p, level, media_type, payload_number, FALSE); - - break; - - default: - break; - } -} - -/* - * gsmsdp_set_media_attributes - * - * Description: - * - * Add the specified media format to the SDP. - * - * Parameters: - * - * media_type - The media type (format) to add to the specified SDP. - * sdp_p - Pointer to the SDP the media attribute is to be added to. - * level - The media level of the SDP where the media attribute is to be added. - * payload_number - AVT payload type if the media attribute being added is - * RTP_AVT. - * - */ -static void -gsmsdp_set_media_attributes (uint32_t media_type, void *sdp_p, uint16_t level, - uint16_t payload_number) -{ - uint16_t a_inst, a_inst2, a_inst3, a_inst4; - int maxavbitrate = 0; - int maxcodedaudiobw = 0; - int usedtx = 0; - int stereo = 0; - int useinbandfec = 0; - int cbr = 0; - int maxptime = 0; - - - config_get_value(CFGID_MAXAVBITRATE, &maxavbitrate, sizeof(maxavbitrate)); - config_get_value(CFGID_MAXCODEDAUDIOBW, &maxcodedaudiobw, sizeof(maxcodedaudiobw)); - config_get_value(CFGID_USEDTX, &usedtx, sizeof(usedtx)); - config_get_value(CFGID_STEREO, &stereo, sizeof(stereo)); - config_get_value(CFGID_USEINBANDFEC, &useinbandfec, sizeof(useinbandfec)); - config_get_value(CFGID_CBR, &cbr, sizeof(cbr)); - config_get_value(CFGID_MAXPTIME, &maxptime, sizeof(maxptime)); - - - - switch (media_type) { - case RTP_PCMU: // type 0 - case RTP_PCMA: // type 8 - case RTP_G729: // type 18 - case RTP_G722: // type 9 - case RTP_ILBC: - case RTP_L16: - case RTP_ISAC: - case RTP_OPUS: - /* - * add a=rtpmap line - */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTPMAP, &a_inst) - != SDP_SUCCESS) { - return; - } - - (void) sdp_attr_set_rtpmap_payload_type(sdp_p, level, 0, a_inst, - payload_number); - - switch (media_type) { - case RTP_PCMU: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_PCMU); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - break; - case RTP_PCMA: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_PCMA); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - break; - case RTP_G729: - { - - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_G729); - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst2) - != SDP_SUCCESS) { - return; - } - (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst2, - payload_number); - (void) sdp_attr_set_fmtp_annexb(sdp_p, level, 0, a_inst2, FALSE); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - } - break; - - case RTP_G722: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_G722); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - break; - - case RTP_L16: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_L16_256K); - - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_L16_CLOCKRATE); - break; - - case RTP_ILBC: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_ILBC); - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst2) - != SDP_SUCCESS) { - return; - } - (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst2, - payload_number); - (void) sdp_attr_set_fmtp_mode(sdp_p, level, 0, a_inst2, vcmGetILBCMode()); - - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - break; - - case RTP_ISAC: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_ISAC); - - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_ISAC_CLOCKRATE); - break; - - case RTP_OPUS: - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_OPUS); - - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_OPUS_CLOCKRATE); - (void) sdp_attr_set_rtpmap_num_chan (sdp_p, level, 0, a_inst, 2); - - /* a=fmtp options */ - if (maxavbitrate || maxcodedaudiobw || usedtx || stereo || useinbandfec || cbr) { - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst2) - != SDP_SUCCESS) { - return; - } - - (void) sdp_attr_set_fmtp_payload_type (sdp_p, level, 0, a_inst2, payload_number); - - if (maxavbitrate) - sdp_attr_set_fmtp_max_average_bitrate (sdp_p, level, 0, a_inst2, FMTP_MAX_AVERAGE_BIT_RATE); - - if(usedtx) - sdp_attr_set_fmtp_usedtx (sdp_p, level, 0, a_inst2, FALSE); - - if(stereo) - sdp_attr_set_fmtp_stereo (sdp_p, level, 0, a_inst2, FALSE); - - if(useinbandfec) - sdp_attr_set_fmtp_useinbandfec (sdp_p, level, 0, a_inst2, FALSE); - - if(maxcodedaudiobw) { - sdp_attr_set_fmtp_maxcodedaudiobandwidth (sdp_p, level, 0, a_inst2, - max_coded_audio_bandwidth_table[opus_fb].name); - } - - if(cbr) - sdp_attr_set_fmtp_cbr (sdp_p, level, 0, a_inst2, FALSE); - } - - /* a=ptime attribute */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_PTIME, &a_inst3) - != SDP_SUCCESS) { - return; - } - - sdp_attr_set_simple_u32(sdp_p, SDP_ATTR_PTIME, level, 0, a_inst3, ATTR_PTIME); - - if(maxptime) { - /* a=maxptime attribute */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_MAXPTIME, &a_inst4) - != SDP_SUCCESS) { - return; - } - - sdp_attr_set_simple_u32(sdp_p, SDP_ATTR_MAXPTIME, level, 0, a_inst4, ATTR_MAXPTIME); - } - - break; - } - break; - - case RTP_AVT: - /* - * add a=rtpmap line - */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_RTPMAP, &a_inst) - != SDP_SUCCESS) { - return; - } - (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst, - SIPSDP_ATTR_ENCNAME_TEL_EVENT); - (void) sdp_attr_set_rtpmap_payload_type(sdp_p, level, 0, a_inst, - payload_number); - (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst, - RTPMAP_CLOCKRATE); - - /* - * Malloc the mediainfo structure - */ - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst) - != SDP_SUCCESS) { - return; - } - (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst, - payload_number); - (void) sdp_attr_set_fmtp_range(sdp_p, level, 0, a_inst, - SIPSDP_NTE_DTMF_MIN, - SIPSDP_NTE_DTMF_MAX); - - - break; - - default: - /* The remaining coded types aren't supported, but are listed below - * as a reminder - * RTP_CELP = 1, - * RTP_GSM = 3, - * RTP_G726 = 2, - * RTP_G723 = 4, - * RTP_DVI4 = 5, - * RTP_DVI4_II = 6, - * RTP_LPC = 7, - * RTP_G722 = 9, - * RTP_G728 = 15, - * RTP_JPEG = 26, - * RTP_NV = 28, - * RTP_H261 = 31 - */ - - break; - } -} - -/* - * gsmsdp_set_sctp_attributes - * - * Description: - * - * Add the specified SCTP media format to the SDP. - * - * Parameters: - * - * sdp_p - Pointer to the SDP the media attribute is to be added to. - * level - The media level of the SDP where the media attribute is to be added. - */ -static void -gsmsdp_set_sctp_attributes (void *sdp_p, uint16_t level, fsmdef_media_t *media) -{ - uint16_t a_inst; - - if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst) - != SDP_SUCCESS) { - return; - } - - /* Use SCTP port in place of fmtp payload type */ - (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst, media->sctp_port); - - sdp_attr_set_fmtp_data_channel_protocol (sdp_p, level, 0, a_inst, WEBRTC_DATA_CHANNEL_PROT); - - sdp_attr_set_fmtp_streams (sdp_p, level, 0, a_inst, 16); -} - -/* - * gsmsdp_set_remote_sdp - * - * Description: - * - * Sets the specified SDP as the remote SDP in the DCB. - * - * Parameters: - * - * dcb_p - Pointer to the DCB. - * sdp_p - Pointer to the SDP to be set as the remote SDP in the DCB. - */ -static void -gsmsdp_set_remote_sdp (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p) -{ - dcb_p->remote_sdp_present = TRUE; -} - -/* - * gsmsdp_get_sdp_direction_attr - * - * Description: - * - * Given a sdp_direction_e enumerated type, returns a sdp_attr_e - * enumerated type. - * - * Parameters: - * - * direction - The SDP direction used to determine which sdp_attr_e to return. - * - */ -static sdp_attr_e -gsmsdp_get_sdp_direction_attr (sdp_direction_e direction) -{ - sdp_attr_e sdp_attr = SDP_ATTR_SENDRECV; - - switch (direction) { - case SDP_DIRECTION_INACTIVE: - sdp_attr = SDP_ATTR_INACTIVE; - break; - case SDP_DIRECTION_SENDONLY: - sdp_attr = SDP_ATTR_SENDONLY; - break; - case SDP_DIRECTION_RECVONLY: - sdp_attr = SDP_ATTR_RECVONLY; - break; - case SDP_DIRECTION_SENDRECV: - sdp_attr = SDP_ATTR_SENDRECV; - break; - default: - GSM_ERR_MSG("\nFSMDEF ERROR: replace with formal error text"); - } - - return sdp_attr; -} - -/* - * gsmsdp_set_sdp_direction - * - * Description: - * - * Adds a direction attribute to the given media line in the - * specified SDP. - * - * Parameters: - * - * media - pointer to the fsmdef_media_t for the media entry. - * direction - The direction to use when setting the direction attribute. - * sdp_p - Pointer to the SDP to set the direction attribute against. - */ -static void -gsmsdp_set_sdp_direction (fsmdef_media_t *media, - sdp_direction_e direction, void *sdp_p) -{ - sdp_attr_e sdp_attr = SDP_ATTR_SENDRECV; - uint16_t a_instance = 0; - - /* - * Convert the direction to an SDP direction attribute. - */ - sdp_attr = gsmsdp_get_sdp_direction_attr(direction); - if (media->level) { - (void) sdp_add_new_attr(sdp_p, media->level, 0, sdp_attr, &a_instance); - } else { - /* Just in case that there is no level defined, add to the session */ - (void) sdp_add_new_attr(sdp_p, SDP_SESSION_LEVEL, 0, sdp_attr, - &a_instance); - } -} - -/* - * gsmsdp_get_ice_attributes - * - * Description: - * - * Returns the ice attribute strings at a given level - * - * Parameters: - * - * session - true = session level attributes, false = media line attribs - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP whose ice candidates are being searched. - * ice_attribs - return ice attribs at this level in an array - * attributes_ctp - count of array of media line attributes - */ - -static boolean -gsmsdp_get_ice_attributes (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, char ***ice_attribs, int *attributes_ctp) -{ - uint16_t num_a_lines = 0; - uint16_t i; - sdp_result_e result; - char* ice_attrib; - - result = sdp_attr_num_instances(sdp_p, level, 0, sdp_attr, &num_a_lines); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("enumerating ICE attributes failed\n"); - return FALSE; - } - - if (num_a_lines < 1) { - GSM_ERR_MSG("enumerating ICE attributes returned 0 attributes\n"); - return TRUE; - } - - *ice_attribs = (char **)cpr_malloc(num_a_lines * sizeof(char *)); - - if (!(*ice_attribs)) - return FALSE; - - *attributes_ctp = 0; - - for (i = 0; i < num_a_lines; i++) { - result = sdp_attr_get_ice_attribute (sdp_p, level, 0, sdp_attr, (uint16_t) (i + 1), - &ice_attrib); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to retrieve ICE attribute\n"); - cpr_free(*ice_attribs); - return FALSE; - } - (*ice_attribs)[i] = (char *) cpr_calloc(1, strlen(ice_attrib) + 1); - if(!(*ice_attribs)[i]) - return FALSE; - - sstrncpy((*ice_attribs)[i], ice_attrib, strlen(ice_attrib) + 1); - (*attributes_ctp)++; - } - - return TRUE; -} - -/* - * gsmsdp_set_attributes - * - * Description: - * - * Adds an ice attribute attributes to the specified SDP. - * - * Parameters: - * - * session - true = session level attribute, false = media line attribute - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * ice_attrib - ice attribute to set - */ -static void -gsmsdp_set_ice_attribute (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, char *ice_attrib) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, sdp_attr, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute\n"); - return; - } - - result = sdp_attr_set_ice_attribute(sdp_p, level, 0, sdp_attr, a_instance, ice_attrib); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute\n"); - } -} - -/* - * gsmsdp_set_rtcp_mux_attribute - * - * Description: - * - * Adds an ice attribute attributes to the specified SDP. - * - * Parameters: - * - * session - true = session level attribute, false = media line attribute - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * rtcp_mux - ice attribute to set - */ -static void -gsmsdp_set_rtcp_mux_attribute (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, boolean rtcp_mux) -{ - uint16_t a_instance = 0; - sdp_result_e result; - - result = sdp_add_new_attr(sdp_p, level, 0, sdp_attr, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute\n"); - return; - } - - result = sdp_attr_set_rtcp_mux_attribute(sdp_p, level, 0, sdp_attr, a_instance, rtcp_mux); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set attribute\n"); - } -} - -/* - * gsmsdp_set_dtls_fingerprint_attribute - * - * Description: - * - * Adds an dtls fingerprint attribute attributes to the specified SDP. - * - * Parameters: - * - * session - true = session level attribute, false = media line attribute - * level - The media level of the SDP where the media attribute exists. - * sdp_p - Pointer to the SDP to set the ice candidate attribute against. - * hash_func - hash function string, e.g. "sha-1" - * hash_func_len - string len - * fingerprint - fingerprint attribute to set - * fingerprint_len - string len of fingerprint - */ -static void -gsmsdp_set_dtls_fingerprint_attribute (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, - char *hash_func,char *fingerprint) -{ - uint16_t a_instance = 0; - sdp_result_e result; - char hash_and_fingerprint[FSMDEF_MAX_DIGEST_ALG_LEN + FSMDEF_MAX_DIGEST_LEN + 2]; - - snprintf(hash_and_fingerprint, sizeof(hash_and_fingerprint), - "%s %s", hash_func, fingerprint); - - result = sdp_add_new_attr(sdp_p, level, 0, sdp_attr, &a_instance); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to add attribute\n"); - return; - } - - result = sdp_attr_set_dtls_fingerprint_attribute(sdp_p, level, 0, sdp_attr, a_instance, hash_and_fingerprint); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG("Failed to set dtls fingerprint attribute\n"); - } -} - -/* - * gsmsdp_remove_sdp_direction - * - * Description: - * - * Removes the direction attribute corresponding to the passed in direction - * from the media line of the specified SDP. - * - * Parameters: - * - * media - pointer to the fsmdef_media_t for the media entry. - * direction - The direction whose corresponding direction attribute - * is to be removed. - * sdp_p - Pointer to the SDP where the direction attribute is to be - * removed. - */ -static void -gsmsdp_remove_sdp_direction (fsmdef_media_t *media, - sdp_direction_e direction, void *sdp_p) -{ - sdp_attr_e sdp_attr = SDP_ATTR_SENDRECV; - - sdp_attr = gsmsdp_get_sdp_direction_attr(direction); - (void) sdp_delete_attr(sdp_p, media->level, 0, sdp_attr, 1); -} - -/* - * gsmsdp_set_local_sdp_direction - * - * Description: - * - * Sets the direction attribute for the local SDP. - * - * Parameters: - * - * dcb_p - The DCB where the local SDP is located. - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * direction - The media direction to set into the local SDP. - */ -void -gsmsdp_set_local_sdp_direction (fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - sdp_direction_e direction) -{ - /* - * If media direction was previously set, remove the direction attribute - * before adding the specified direction. Save the direction in previous - * direction before clearing it. - */ - if (media->direction_set) { - media->previous_sdp.direction = media->direction; - gsmsdp_remove_sdp_direction(media, media->direction, - dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL ); - media->direction_set = FALSE; - } - gsmsdp_set_sdp_direction(media, direction, dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL); - /* - * We could just get the direction from the local SDP when we need it in - * GSM, but setting the direction in the media structure gives a quick way - * to access the media direction. - */ - media->direction = direction; - media->direction_set = TRUE; -} - -/* - * gsmsdp_get_remote_sdp_direction - * - * Description: - * - * Returns the media direction from the specified SDP. We will check for the - * media direction attribute at the session level and the first AUDIO media line. - * If the direction attribute is specified at the media level, the media level setting - * overrides the session level attribute. - * - * Parameters: - * - * dcb_p - pointer to the fsmdef_dcb_t. - * level - media line level. - * dest_addr - pointer to the remote address. - */ -static sdp_direction_e -gsmsdp_get_remote_sdp_direction (fsmdef_dcb_t *dcb_p, uint16_t level, - cpr_ip_addr_t *dest_addr) -{ - sdp_direction_e direction = SDP_DIRECTION_SENDRECV; - cc_sdp_t *sdp_p = dcb_p->sdp; - uint16_t media_attr; - uint16_t i; - static const sdp_attr_e dir_attr_array[] = { - SDP_ATTR_INACTIVE, - SDP_ATTR_RECVONLY, - SDP_ATTR_SENDONLY, - SDP_ATTR_SENDRECV, - SDP_MAX_ATTR_TYPES - }; - - if (!sdp_p->dest_sdp) { - return direction; - } - - media_attr = 0; /* media level attr. count */ - /* - * Now check for direction as a media attribute. If found, the - * media attribute takes precedence over direction specified - * as a session attribute. - * - * In order to find out whether there is a direction attribute - * associated with a media line (or even at the - * session level) or not is to get the number of instances of - * that attribute via the sdp_attr_num_instances() first. The is - * because the sdp_get_media_direction() always returns a valid - * direction value even when there is no direction attribute with - * the media line (or session level). - * - * Note: there is no single attribute value to pass to the - * sdp_attr_num_instances() to get number a direction attribute that - * represents inactive, recvonly, sendonly, sendrcv. We have to - * look for each one of them individually. - */ - for (i = 0; (dir_attr_array[i] != SDP_MAX_ATTR_TYPES); i++) { - if (sdp_attr_num_instances(sdp_p->dest_sdp, level, 0, - dir_attr_array[i], &media_attr) == - SDP_SUCCESS) { - if (media_attr) { - /* There is direction attribute in the media line */ - direction = sdp_get_media_direction(sdp_p->dest_sdp, - level, 0); - break; - } - } - } - - /* - * Check for the direction attribute. The direction can be specified - * as a session attribute or a media stream attribute. If the direction - * is specified as a session attribute, the direction is applicable to - * all media streams in the SDP. - */ - if (media_attr == 0) { - /* no media level direction, get the direction from session */ - direction = sdp_get_media_direction(sdp_p->dest_sdp, - SDP_SESSION_LEVEL, 0); - } - - /* - * To support legacy way of signaling remote hold, we will interpret - * c=0.0.0.0 to be a=inactive - */ - if (dest_addr->type == CPR_IP_ADDR_IPV4 && - dest_addr->u.ip4 == 0) { - - direction = SDP_DIRECTION_INACTIVE; - } else { - - //todo IPv6: reject the request. - } - return direction; -} - -/** - * - * The function overrides direction for some special feature - * processing. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media - pointer to fsmdef_media_t for the media to - * override the direction. - * - * @return None. - * @pre (dcb_p not_eq NULL) and (media not_eq NULL) - */ -static void -gsmsdp_feature_overide_direction (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - /* - * Disable video if this is a BARGE with video - */ - if ( CC_IS_VIDEO(media->cap_index) && - dcb_p->join_call_id != CC_NO_CALL_ID ){ - media->support_direction = SDP_DIRECTION_INACTIVE; - } - - if (CC_IS_VIDEO(media->cap_index) && media->support_direction == SDP_DIRECTION_INACTIVE) { - DEF_DEBUG(GSM_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE \n", "gsmsdp_feature_overide_direction"); - } -} - -/* - * gsmsdp_negotiate_local_sdp_direction - * - * Description: - * - * Given an offer SDP, return the corresponding answer SDP direction. - * - * local hold remote direction support direction new local direction - * enabled inactive any inactive - * enabled sendrecv sendonly sendonly - * enabled sendrecv recvonly inactive - * enabled sendrecv sendrecv sendonly - * enabled sendrecv inactive inactive - * enabled sendonly any inactive - * enabled recvonly sendrecv sendonly - * enabled recvonly sendonly sendonly - * enabled recvonly recvonly inactive - * enabled recvonly inactive inactive - * disabled inactive any inactive - * disabled sendrecv sendrecv sendrecv - * disabled sendrecv sendonly sendonly - * disabled sendrecv recvonly recvonly - * disabled sendrecv inactive inactive - * disabled sendonly sendrecv recvonly - * disabled sendonly sendonly inactive - * disabled sendonly recvonly recvonly - * disabled sendonly inactive inactive - * disabled recvonly sendrecv sendonly - * disabled recvonly sendonly sendonly - * disabled recvonly recvonly inactive - * disabled recvonly inactive inactive - * - * Parameters: - * - * dcb_p - pointer to the fsmdef_dcb_t. - * media - pointer to the fsmdef_media_t for the current media entry. - * local_hold - Boolean indicating if local hold feature is enabled - */ -static sdp_direction_e -gsmsdp_negotiate_local_sdp_direction (fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - boolean local_hold) -{ - sdp_direction_e direction = SDP_DIRECTION_SENDRECV; - sdp_direction_e remote_direction = gsmsdp_get_remote_sdp_direction(dcb_p, - media->level, &media->dest_addr); - - if (remote_direction == SDP_DIRECTION_SENDRECV) { - if (local_hold) { - if ((media->support_direction == SDP_DIRECTION_SENDRECV) || - (media->support_direction == SDP_DIRECTION_SENDONLY)) { - direction = SDP_DIRECTION_SENDONLY; - } else { - direction = SDP_DIRECTION_INACTIVE; - } - } else { - direction = media->support_direction; - } - } else if (remote_direction == SDP_DIRECTION_SENDONLY) { - if (local_hold) { - direction = SDP_DIRECTION_INACTIVE; - } else { - if ((media->support_direction == SDP_DIRECTION_SENDRECV) || - (media->support_direction == SDP_DIRECTION_RECVONLY)) { - direction = SDP_DIRECTION_RECVONLY; - } else { - direction = SDP_DIRECTION_INACTIVE; - } - } - } else if (remote_direction == SDP_DIRECTION_INACTIVE) { - direction = SDP_DIRECTION_INACTIVE; - } else if (remote_direction == SDP_DIRECTION_RECVONLY) { - if ((media->support_direction == SDP_DIRECTION_SENDRECV) || - (media->support_direction == SDP_DIRECTION_SENDONLY)) { - direction = SDP_DIRECTION_SENDONLY; - } else { - direction = SDP_DIRECTION_INACTIVE; - } - } - - return direction; -} - -/* - * gsmsdp_add_default_audio_formats_to_local_sdp - * - * Description: - * - * Add all supported media formats to the local SDP of the specified DCB - * at the specified media level. If the call is involved in a conference - * call, only add G.711 formats. - * - * Parameters - * - * dcb_p - The DCB whose local SDP is to be updated with the default media formats. - * sdp_p - Pointer to the local sdp structure. This is added so call to this - * routine can be made irrespective of whether we have a dcb or not(To - * handle out-of-call options request for example) - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * - */ -static void -gsmsdp_add_default_audio_formats_to_local_sdp (fsmdef_dcb_t *dcb_p, - cc_sdp_t * sdp_p, - fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_add_default_audio_formats_to_local_sdp"; - int local_media_types[CC_MAX_MEDIA_TYPES]; - int16_t local_avt_payload_type = RTP_NONE; - DtmfOutOfBandTransport_t transport = DTMF_OUTOFBAND_NONE; - int type_cnt; - void *local_sdp_p = NULL; - uint16_t media_format_count; - uint16_t level; - int i; - - if (media) { - level = media->level; - } else { - level = 1; - } - local_sdp_p = (void *) sdp_p->src_sdp; - - /* - * Create list of supported codecs. Get all the codecs that the phone - * supports. - */ - media_format_count = sip_config_local_supported_codecs_get( - (rtp_ptype *) local_media_types, - CC_MAX_MEDIA_TYPES); - /* - * If there are no media payloads, it's because we are making an - * initial offer. We will be opening our receive port so we need to specify - * the media payload type to be used initially. We set the media payload - * type in the dcb to do this. Until we receive an answer from the far - * end, we will use our first choice payload type. i.e. the first payload - * type sent in our AUDIO media line. - */ - - if (dcb_p && media && media->num_payloads == 0) { - - if (media->payloads && - (media->num_payloads < media_format_count)) { - cpr_free(media->payloads); - media->payloads = NULL; - } - - if (!media->payloads) { - media->payloads = cpr_calloc(media_format_count, - sizeof(vcm_payload_info_t)); - } - - media->num_payloads = 0; - for (i = 0; i < media_format_count; i++) { - if (local_media_types[i] > RTP_NONE) { - media->payloads[i].codec_type = local_media_types[i]; - media->payloads[i].local_rtp_pt = local_media_types[i]; - media->payloads[i].remote_rtp_pt = local_media_types[i]; - media->num_payloads++; - } - } - gsmsdp_copy_payloads_to_previous_sdp(media); - } - - /* - * Get configured OOB DTMF setting and avt payload type if applicable - */ - config_get_value(CFGID_DTMF_OUTOFBAND, &transport, sizeof(transport)); - - if ((transport == DTMF_OUTOFBAND_AVT) || - (transport == DTMF_OUTOFBAND_AVT_ALWAYS)) { - int temp_payload_type = RTP_NONE; - - config_get_value(CFGID_DTMF_AVT_PAYLOAD, - &(temp_payload_type), - sizeof(temp_payload_type)); - local_avt_payload_type = (uint16_t) temp_payload_type; - } - - /* - * add all the audio media types - */ - for (type_cnt = 0; - (type_cnt < media_format_count) && - (local_media_types[type_cnt] > RTP_NONE); - type_cnt++) { - - if (sdp_add_media_payload_type(local_sdp_p, level, - (uint16_t)local_media_types[type_cnt], - SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding media payload type failed\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - gsmsdp_set_media_attributes(local_media_types[type_cnt], local_sdp_p, - level, (uint16_t)local_media_types[type_cnt]); - } - } - - /* - * add the avt media type - */ - if (local_avt_payload_type > RTP_NONE) { - if (sdp_add_media_payload_type(local_sdp_p, level, - local_avt_payload_type, - SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding AVT payload type failed\n", - dcb_p->line, dcb_p->call_id, fname); - } - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - gsmsdp_set_media_attributes(RTP_AVT, local_sdp_p, level, - local_avt_payload_type); - if (media) { - media->avt_payload_type = local_avt_payload_type; - } - } - } -} - -/* - * gsmsdp_add_default_video_formats_to_local_sdp - * - * Description: - * - * Add all supported media formats to the local SDP of the specified DCB - * at the specified media level. If the call is involved in a conference - * call, only add G.711 formats. - * - * Parameters - * - * dcb_p - The DCB whose local SDP is to be updated with the default media formats. - * sdp_p - Pointer to the local sdp structure. This is added so call to this - * routine can be made irrespective of whether we have a dcb or not(To - * handle out-of-call options request for example) - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * - */ -static void -gsmsdp_add_default_video_formats_to_local_sdp (fsmdef_dcb_t *dcb_p, - cc_sdp_t * sdp_p, - fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_add_default_video_formats_to_local_sdp"; - int video_media_types[CC_MAX_MEDIA_TYPES]; - int type_cnt; - void *local_sdp_p = NULL; - uint16_t video_format_count; - uint16_t level; - line_t line = 0; - callid_t call_id = 0; - int i; - - if (dcb_p && media) { - line = dcb_p->line; - call_id = dcb_p->call_id; - } - GSM_DEBUG(DEB_L_C_F_PREFIX"\n", DEB_L_C_F_PREFIX_ARGS(GSM, line, call_id, fname)); - - if (media) { - level = media->level; - } else { - level = 2; - } - local_sdp_p = (void *) sdp_p->src_sdp; - - /* - * Create list of supported codecs. Get all the codecs that the phone supports. - */ - - video_format_count = sip_config_video_supported_codecs_get( (rtp_ptype *) video_media_types, - CC_MAX_MEDIA_TYPES, TRUE /*offer*/); - - GSM_DEBUG(DEB_L_C_F_PREFIX"video_count=%d\n", DEB_L_C_F_PREFIX_ARGS(GSM, line, call_id, fname), video_format_count); - /* - * If the there are no media payloads, its because we are making an - * initial offer. We will be opening our receive port so we need to specify - * the media payload type to be used initially. We set the media payload - * type in the dcb to do this. Until we receive an answer from the far - * end, we will use our first choice payload type. i.e. the first payload - * type sent in our video media line. - */ - if (dcb_p && media && media->num_payloads == 0) { - if (media->payloads && - (media->num_payloads < video_format_count)) { - cpr_free(media->payloads); - media->payloads = NULL; - } - - if (!media->payloads) { - media->payloads = cpr_calloc(video_format_count, - sizeof(vcm_payload_info_t)); - } - - media->num_payloads = 0; - for (i = 0; i < video_format_count; i++) { - if (video_media_types[i] > RTP_NONE) { - media->payloads[i].codec_type = video_media_types[i]; - media->payloads[i].local_rtp_pt = video_media_types[i]; - media->payloads[i].remote_rtp_pt = video_media_types[i]; - media->num_payloads++; - } - } - gsmsdp_copy_payloads_to_previous_sdp(media); - } - - - /* - * add all the video media types - */ - for (type_cnt = 0; - (type_cnt < video_format_count) && - (video_media_types[type_cnt] > RTP_NONE); - type_cnt++) { - - if (sdp_add_media_payload_type(local_sdp_p, level, - (uint16_t)video_media_types[type_cnt], - SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR(1)\n", - line, call_id, fname); - } - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - gsmsdp_set_video_media_attributes(video_media_types[type_cnt], sdp_p, - level, (uint16_t)video_media_types[type_cnt]); - } - } -} - -/** - * This function sets the mid attr at the media level - * and labels the relevant media streams when phone is - * operating in a dual stack mode - * - * @param[in]src_sdp_p - Our source sdp. - * @param[in]level - The level of the media that we are operating on. - * - * @return - None - * - */ -static void gsmsdp_set_mid_attr (void *src_sdp_p, uint16_t level) -{ - uint16 inst_num; - - if (platform_get_ip_address_mode() == CPR_IP_MODE_DUAL) { - /* - * add a=mid line - */ - (void) sdp_add_new_attr(src_sdp_p, level, 0, SDP_ATTR_MID, &inst_num); - - (void) sdp_attr_set_simple_u32(src_sdp_p, SDP_ATTR_MID, level, 0, - inst_num, level); - } -} - -/** - * This function sets the anat attr to the session level - * and labels the relevant media streams - * - * @param[in]media - The media line that we are operating on. - * @param[in]dcb_p - Pointer to the DCB whose local SDP is to be updated. - * - * @return - None - * - */ -static void gsmsdp_set_anat_attr (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - void *src_sdp_p = (void *) dcb_p->sdp->src_sdp; - void *dest_sdp_p = (void *) dcb_p->sdp->dest_sdp; - uint16 inst_num; - uint16_t num_group_lines= 0; - uint16_t num_anat_lines = 0; - u32 group_id_1, group_id_2; - uint16_t i; - fsmdef_media_t *group_media; - - - if (dest_sdp_p == NULL) { - /* If this is our initial offer */ - if (media->addr_type == SDP_AT_IP4) { - group_media = gsmsdp_find_anat_pair(dcb_p, media); - if (group_media != NULL) { - /* - * add a=group line - */ - (void) sdp_add_new_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, &inst_num); - - (void) sdp_set_group_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, SDP_GROUP_ATTR_ANAT); - - (void) sdp_set_group_num_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, 2); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, group_media->level); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, media->level); - } - } - } else { - /* This is an answer, check if the offer rcvd had anat grouping */ - (void) sdp_attr_num_instances(dest_sdp_p, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, - &num_group_lines); - - for (i = 1; i <= num_group_lines; i++) { - if (sdp_get_group_attr(dest_sdp_p, SDP_SESSION_LEVEL, 0, i) == SDP_GROUP_ATTR_ANAT) { - num_anat_lines++; - } - } - - for (i = 1; i <= num_anat_lines; i++) { - group_id_1 = sdp_get_group_id(dest_sdp_p, SDP_SESSION_LEVEL, 0, i, 1); - group_id_2 = sdp_get_group_id(dest_sdp_p, SDP_SESSION_LEVEL, 0, i, 2); - - if ((media->level == group_id_1) || (media->level == group_id_2)) { - - group_media = gsmsdp_find_anat_pair(dcb_p, media); - if (group_media != NULL) { - if (sdp_get_group_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, i) != SDP_GROUP_ATTR_ANAT) { - /* - * add a=group line - */ - (void) sdp_add_new_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, &inst_num); - (void) sdp_set_group_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, SDP_GROUP_ATTR_ANAT); - - } - (void) sdp_set_group_num_id(src_sdp_p, SDP_SESSION_LEVEL, 0, i, 2); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, i, group_media->level); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, i, media->level); - - } else { - /* - * add a=group line - */ - (void) sdp_add_new_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, &inst_num); - (void) sdp_set_group_attr(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, SDP_GROUP_ATTR_ANAT); - - (void) sdp_set_group_num_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, 1); - (void) sdp_set_group_id(src_sdp_p, SDP_SESSION_LEVEL, 0, inst_num, media->level); - } - - } - } - } - gsmsdp_set_mid_attr (src_sdp_p, media->level); -} - -/* - * gsmsdp_update_local_sdp_media - * - * Description: - * - * Adds an AUDIO media line to the local SDP of the specified DCB. If all_formats - * is TRUE, sets all media formats supported by the phone into the local SDP, else - * only add the single negotiated media format. If an AUDIO media line already - * exists in the local SDP, remove it as this function completely rebuilds the - * AUDIO media line and will do so at the same media level as the pre-existing - * AUDIO media line. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose local SDP is to be updated. - * cc_sdp_p - Pointer to the SDP being updated. - * all_formats - If true, all supported media formats will be added to the - * AUDIO media line of the SDP. Otherwise, only the single - * negotiated media format is added. - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * transport - transport type to for this media line. - * - */ -static void -gsmsdp_update_local_sdp_media (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, - boolean all_formats, fsmdef_media_t *media, - sdp_transport_e transport) -{ - static const char fname[] = "gsmsdp_update_local_sdp_media"; - uint16_t port; - sdp_result_e result; - uint16_t level; - void *sdp_p; - int sdpmode = 0; - int i = 0; - - if (!dcb_p || !media) { - GSM_ERR_MSG(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname); - return; - } - level = media->level; - port = media->src_port; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - sdp_p = cc_sdp_p ? (void *) cc_sdp_p->src_sdp : NULL; - - if (sdp_p == NULL) { - - gsmsdp_init_local_sdp(dcb_p->peerconnection, &(dcb_p->sdp)); - - cc_sdp_p = dcb_p->sdp; - if ((cc_sdp_p == NULL) || (cc_sdp_p->src_sdp == NULL)) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"sdp is NULL and init failed \n", - dcb_p->line, dcb_p->call_id, fname); - return; - } - sdp_p = (void *) cc_sdp_p->src_sdp; - } else { - - /* - * Remove the audio stream. Reset direction_set flag since - * all media attributes have just been removed. - */ - sdp_delete_media_line(sdp_p, level); - media->direction_set = FALSE; - } - - result = sdp_insert_media_line(sdp_p, level); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Inserting media line to Sdp failed\n", - dcb_p->line, dcb_p->call_id, fname); - return; - } - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - gsmsdp_set_connection_address(sdp_p, media->level, dcb_p->ice_default_candidate_addr); - } - - (void) sdp_set_media_type(sdp_p, level, media->type); - - - (void) sdp_set_media_portnum(sdp_p, level, port, media->sctp_port); - - /* Set media transport and crypto attributes if it is for SRTP */ - gsmsdp_update_local_sdp_media_transport(dcb_p, sdp_p, media, transport, - all_formats); - - if (all_formats) { - /* - * Add all supported media formats to the local sdp. - */ - switch (media->type) { - case SDP_MEDIA_AUDIO: - gsmsdp_add_default_audio_formats_to_local_sdp(dcb_p, cc_sdp_p, - media); - break; - case SDP_MEDIA_VIDEO: - gsmsdp_add_default_video_formats_to_local_sdp(dcb_p, cc_sdp_p, - media); - break; - case SDP_MEDIA_APPLICATION: - gsmsdp_set_sctp_attributes (sdp_p, level, media); - break; - default: - GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR media %d for level %d is not" - " supported\n", - dcb_p->line, dcb_p->call_id, fname, media->level); - break; - } - } else { - /* - * Add negotiated codec list to the sdp - */ - for(i = 0; i < media->num_payloads; i++) { - result = - sdp_add_media_payload_type(sdp_p, level, - (uint16_t)(media->payloads[i].local_rtp_pt), - SDP_PAYLOAD_NUMERIC); - - if (result != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding dynamic payload type failed\n", - dcb_p->line, dcb_p->call_id, fname); - } - - switch (media->type) { - case SDP_MEDIA_AUDIO: - gsmsdp_set_media_attributes(media->payloads[i].codec_type, - sdp_p, level, - (uint16_t)(media->payloads[i].local_rtp_pt)); - break; - case SDP_MEDIA_VIDEO: - gsmsdp_set_video_media_attributes(media->payloads[i].codec_type, - cc_sdp_p, level, - (uint16_t)(media->payloads[i].local_rtp_pt)); - break; - case SDP_MEDIA_APPLICATION: - gsmsdp_set_sctp_attributes (sdp_p, level, media); - break; - default: - GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR media %d for level %d is" - " not supported\n", - dcb_p->line, dcb_p->call_id, fname, media->level); - break; - } - - }//end for - - /* - * add the avt media type - */ - if (media->avt_payload_type > RTP_NONE) { - result = sdp_add_media_payload_type(sdp_p, level, - (uint16_t)media->avt_payload_type, - SDP_PAYLOAD_NUMERIC); - if (result != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding AVT payload type failed\n", - dcb_p->line, dcb_p->call_id, fname); - } - gsmsdp_set_media_attributes(RTP_AVT, sdp_p, level, - (uint16_t) media->avt_payload_type); - } - } - - if (!sdpmode) - gsmsdp_set_anat_attr(dcb_p, media); -} - -/* - * gsmsdp_update_local_sdp - * - * Description: - * - * Updates the local SDP of the DCB based on the remote SDP. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose local SDP is to be updated. - * offer - Indicates whether the remote SDP was received in an offer - * or an answer. - * initial_offer - this media line is initial offer. - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * - * Return: - * TRUE - update the local SDP was successfull. - * FALSE - update the local SDP failed. - */ -static boolean -gsmsdp_update_local_sdp (fsmdef_dcb_t *dcb_p, boolean offer, - boolean initial_offer, - fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_update_local_sdp"; - cc_action_data_t data; - sdp_direction_e direction; - boolean local_hold = (boolean)FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL); - - if (media->src_port == 0) { - GSM_DEBUG(DEB_L_C_F_PREFIX"allocate receive port for media line\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - /* - * Source port has not been allocated, this could mean we - * processing an initial offer SDP, SDP that requets to insert - * a media line or re-insert a media line. - */ - data.open_rcv.is_multicast = FALSE; - data.open_rcv.listen_ip = ip_addr_invalid; - data.open_rcv.port = 0; - data.open_rcv.keep = FALSE; - /* - * Indicate type of media (audio/video etc) becase some for supporting - * video over vieo, the port is obtained from other entity. - */ - data.open_rcv.media_type = media->type; - data.open_rcv.media_refid = media->refid; - if (cc_call_action(dcb_p->call_id, dcb_p->line, CC_ACTION_OPEN_RCV, - &data) == CC_RC_SUCCESS) { - /* allocate port successful, save the port */ - media->src_port = data.open_rcv.port; - media->rcv_chan = FALSE; /* mark no RX chan yet */ - } else { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed\n", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - } - - /* - * Negotiate direction based on remote SDP. - */ - direction = gsmsdp_negotiate_local_sdp_direction(dcb_p, media, local_hold); - - /* - * Update Transmit SRTP transmit key if this SRTP session. - */ - if (media->transport == SDP_TRANSPORT_RTPSAVP) { - gsmsdp_update_crypto_transmit_key(dcb_p, media, offer, - initial_offer, direction); - } - - if (offer == TRUE) { - gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, FALSE, media, - media->transport); - } - - /* - * Set local sdp direction. - */ - if (media->direction_set) { - if (media->direction != direction) { - gsmsdp_set_local_sdp_direction(dcb_p, media, direction); - } - } else { - gsmsdp_set_local_sdp_direction(dcb_p, media, direction); - } - return (TRUE); -} - -/* - * gsmsdp_update_local_sdp_for_multicast - * - * Description: - * - * Updates the local SDP of the DCB based on the remote SDP for - * multicast. Populates the local sdp with the same addr:port as - * in the offer and the same direction as in the offer (as per - * rfc3264). - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose local SDP is to be updated. - * portnum - Remote port. - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * offer - boolean indicating an offer SDP if true. - * initial_offer - boolean indicating an initial offer SDP if true. - * - */ -static boolean -gsmsdp_update_local_sdp_for_multicast (fsmdef_dcb_t *dcb_p, - uint16_t portnum, - fsmdef_media_t *media, - boolean offer, - boolean initial_offer) -{ - static const char fname[] = "gsmsdp_update_local_sdp_for_multicast"; - sdp_direction_e direction; - char addr_str[MAX_IPADDR_STR_LEN]; - uint16_t level; - char *p_addr_str; - char *strtok_state; - - level = media->level; - - GSM_DEBUG(DEB_L_C_F_PREFIX"%d %d %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - portnum, level, initial_offer); - - direction = gsmsdp_get_remote_sdp_direction(dcb_p, media->level, - &media->dest_addr); - GSM_DEBUG(DEB_L_C_F_PREFIX"sdp direction: %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), direction); - /* - * Update Transmit SRTP transmit key any way to clean up the - * tx condition that we may have offered prior. - */ - gsmsdp_update_crypto_transmit_key(dcb_p, media, offer, initial_offer, - direction); - - gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, FALSE, - media, media->transport); - - /* - * Set local sdp direction same as on remote SDP for multicast - */ - if ((direction == SDP_DIRECTION_RECVONLY) || (direction == SDP_DIRECTION_INACTIVE)) { - if ((media->support_direction == SDP_DIRECTION_SENDRECV) || - (media->support_direction == SDP_DIRECTION_RECVONLY)) { - /* - * Echo same direction back in our local SDP but set the direction - * in DCB to recvonly so that LSM operations on rcv port work - * without modification. - */ - } else { - direction = SDP_DIRECTION_INACTIVE; - GSM_DEBUG(DEB_L_C_F_PREFIX"media line" - " does not support receive stream\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - gsmsdp_set_local_sdp_direction(dcb_p, media, direction); - media->direction_set = TRUE; - } else { - /* - * return FALSE indicating error - */ - return (FALSE); - } - - /* - * Set the ip addr to the multicast ip addr. - */ - ipaddr2dotted(addr_str, &media->dest_addr); - p_addr_str = PL_strtok_r(addr_str, "[ ]", &strtok_state); - - /* - * Set the local SDP port number to match far ends port number. - */ - (void) sdp_set_media_portnum(dcb_p->sdp->src_sdp, level, portnum, 0); - - /* - * c= line
- */ - (void) sdp_set_conn_nettype(dcb_p->sdp->src_sdp, level, SDP_NT_INTERNET); - (void) sdp_set_conn_addrtype(dcb_p->sdp->src_sdp, level, media->addr_type); - (void) sdp_set_conn_address(dcb_p->sdp->src_sdp, level, p_addr_str); - - return (TRUE); -} - -/* - * gsmsdp_get_remote_avt_payload_type - * - * Description: - * - * Returns the AVT payload type of the given audio line in the specified SDP. - * - * Parameters: - * - * level - The media level of the SDP where the media attribute is to be found. - * sdp_p - Pointer to the SDP whose AVT payload type is being searched. - * - */ -static int -gsmsdp_get_remote_avt_payload_type (uint16_t level, void *sdp_p) -{ - uint16_t i; - uint16_t ptype; - int remote_avt_payload_type = RTP_NONE; - uint16_t num_a_lines = 0; - const char *encname = NULL; - - /* - * Get number of RTPMAP attributes for the media line - */ - (void) sdp_attr_num_instances(sdp_p, level, 0, SDP_ATTR_RTPMAP, - &num_a_lines); - - /* - * Loop through AUDIO media line RTPMAP attributes. The last - * NET dynamic payload type will be returned. - */ - for (i = 0; i < num_a_lines; i++) { - ptype = sdp_attr_get_rtpmap_payload_type(sdp_p, level, 0, - (uint16_t) (i + 1)); - if (sdp_media_dynamic_payload_valid(sdp_p, ptype, level)) { - encname = sdp_attr_get_rtpmap_encname(sdp_p, level, 0, - (uint16_t) (i + 1)); - if (encname) { - if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_TEL_EVENT) == 0) { - remote_avt_payload_type = ptype; - } - } - } - } - return (remote_avt_payload_type); -} - - -#define MIX_NEAREND_STRING "X-mix-nearend" - -/* - * gsmsdp_negotiate_codec - * - * Description: - * - * Negotiates an acceptable codec from the local and remote SDPs - * - * Parameters: - * - * dcb_p - Pointer to DCB whose codec is being negotiated - * sdp_p - Pointer to local and remote SDP - * media - Pointer to the fsmdef_media_t for a given media entry whose - * codecs are being negotiated. - * offer - Boolean indicating if the remote SDP came in an OFFER. - * - * Returns: - * - * codec > 0: most preferred negotiated codec - * <= 0: negotiation failed - */ -static int -gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p, - fsmdef_media_t *media, boolean offer, - boolean initial_offer, uint16 media_level) -{ - static const char fname[] = "gsmsdp_negotiate_codec"; - rtp_ptype pref_codec = RTP_NONE; - uint16_t i; - uint16_t j; - int *master_list_p = NULL; - int *slave_list_p = NULL; - DtmfOutOfBandTransport_t transport = DTMF_OUTOFBAND_NONE; - int avt_payload_type; - uint16_t num_remote_types; - uint16_t num_local_types; - uint16_t num_master_types; - uint16_t num_slave_types; - int remote_codecs[CC_MAX_MEDIA_TYPES]; - int remote_payload_types[CC_MAX_MEDIA_TYPES]; - int local_codecs[CC_MAX_MEDIA_TYPES]; - sdp_payload_ind_e pt_indicator; - uint32 ptime = 0; - uint32 maxptime = 0; - const char* attr_label; - uint16_t level; - boolean explicit_reject = FALSE; - boolean found_codec = FALSE; - // int32_t num_match_payloads = 0; - int codec = RTP_NONE; - int remote_pt = RTP_NONE; - int32_t payload_types_count = 0; /* count for allocating right amout - of memory for media->payloads */ - int temp; - u16 a_inst; - vcm_payload_info_t *payload_info = NULL; - vcm_payload_info_t *previous_payload_info; - - if (!dcb_p || !sdp_p || !media) { - return (RTP_NONE); - } - - level = media_level; - attr_label = sdp_attr_get_simple_string(sdp_p->dest_sdp, - SDP_ATTR_LABEL, level, 0, 1); - - if (attr_label != NULL) { - if (strcmp(attr_label, MIX_NEAREND_STRING) == 0) { - dcb_p->session = WHISPER_COACHING; - } - } - /* - * Obtain list of payload types from the remote SDP - */ - num_remote_types = sdp_get_media_num_payload_types(sdp_p->dest_sdp, level); - - if (num_remote_types > CC_MAX_MEDIA_TYPES) { - num_remote_types = CC_MAX_MEDIA_TYPES; - } - - for (i = 0; i < num_remote_types; i++) { - temp = sdp_get_media_payload_type(sdp_p->dest_sdp, level, - (uint16_t) (i + 1), &pt_indicator); - remote_codecs[i] = GET_CODEC_TYPE(temp); - remote_payload_types[i] = GET_DYN_PAYLOAD_TYPE_VALUE(temp); - } - - /* - * Get all the codecs that the phone supports. - */ - if (media->type == SDP_MEDIA_AUDIO) { - num_local_types = sip_config_local_supported_codecs_get( - (rtp_ptype *)local_codecs, - CC_MAX_MEDIA_TYPES); - } else if (media->type == SDP_MEDIA_VIDEO) { - num_local_types = sip_config_video_supported_codecs_get( - (rtp_ptype *)local_codecs, CC_MAX_MEDIA_TYPES, offer); - } else { - GSM_DEBUG(DEB_L_C_F_PREFIX"unsupported media type %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - media->type); - return (RTP_NONE); - } - - /* - * Set the AVT payload type to whatever value the farend wants to use, - * but only if we have AVT turned on and the farend wants it - * or if we are configured to always send it - */ - config_get_value(CFGID_DTMF_OUTOFBAND, &transport, sizeof(transport)); - - /* - * Save AVT payload type for use by gsmsdp_compare_to_previous_sdp - */ - media->previous_sdp.avt_payload_type = media->avt_payload_type; - - switch (transport) { - case DTMF_OUTOFBAND_AVT: - avt_payload_type = gsmsdp_get_remote_avt_payload_type( - media->level, sdp_p->dest_sdp); - if (avt_payload_type > RTP_NONE) { - media->avt_payload_type = avt_payload_type; - } else { - media->avt_payload_type = RTP_NONE; - } - break; - - case DTMF_OUTOFBAND_AVT_ALWAYS: - avt_payload_type = gsmsdp_get_remote_avt_payload_type( - media->level, sdp_p->dest_sdp); - if (avt_payload_type > RTP_NONE) { - media->avt_payload_type = avt_payload_type; - } else { - /* - * If we are AVT_ALWAYS and the remote end is not using AVT, - * then send DTMF as out-of-band and use our configured - * payload type. - */ - config_get_value(CFGID_DTMF_AVT_PAYLOAD, - &media->avt_payload_type, - sizeof(media->avt_payload_type)); - - GSM_DEBUG(DEB_L_C_F_PREFIX"AVT_ALWAYS forcing out-of-band DTMF," - " payload_type = %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), - media->avt_payload_type); - } - break; - - case DTMF_OUTOFBAND_NONE: - default: - media->avt_payload_type = RTP_NONE; - break; - } - - /* - * Find a matching codec in our local list with the remote list. - * The local list was created with our preferred codec first in the list, - * so this will ensure that we will match the preferred codec with the - * remote list first, before matching other codecs. - */ - pref_codec = sip_config_preferred_codec(); - if (pref_codec != RTP_NONE) { - /* - * If a preferred codec was configured and the platform - * currently can do this codec, then it would be the - * first element of the local_codecs because of the - * logic in sip_config_local_supported_codec_get(). - */ - if (local_codecs[0] != pref_codec) { - /* - * preferred codec is configured but it is not avaible - * currently, treat it as there is no codec available. - */ - pref_codec = RTP_NONE; - } - } - - if (pref_codec == RTP_NONE) { - master_list_p = remote_codecs; - slave_list_p = local_codecs; - num_master_types = num_remote_types; - num_slave_types = num_local_types; - GSM_DEBUG(DEB_L_C_F_PREFIX"Remote Codec list is Master\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } else { - master_list_p = local_codecs; - slave_list_p = remote_codecs; - num_master_types = num_local_types; - num_slave_types = num_remote_types; - GSM_DEBUG(DEB_L_C_F_PREFIX"Local Codec list is Master\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - - /* - * Save payload information for use by gsmspd_compare_to_previous_sdp - */ - gsmsdp_copy_payloads_to_previous_sdp(media); - - /* - * Setup payload info structure list to store matched payload details - * in the SDP. - */ - media->num_payloads = 0; - if(num_master_types <= num_slave_types ) { - payload_types_count = num_master_types; - } else { - payload_types_count = num_slave_types; - } - - /* Remove any previously allocated lists */ - if (media->payloads) { - cpr_free(media->payloads); - } - - /* Allocate memory for PT value, local PT and remote PT. */ - media->payloads = cpr_calloc(payload_types_count, - sizeof(vcm_payload_info_t)); - - /* Store the ptime and maxptime parameter for this m= section */ - if (media->type == SDP_MEDIA_AUDIO) { - ptime = sdp_attr_get_simple_u32(sdp_p->dest_sdp, - SDP_ATTR_PTIME, level, 0, 1); - if (ptime != 0) { - media->packetization_period = (uint16_t) ptime; - } - maxptime = sdp_attr_get_simple_u32(sdp_p->dest_sdp, - SDP_ATTR_MAXPTIME, level, 0, 1); - if (maxptime != 0) { - media->max_packetization_period = (uint16_t) maxptime; - } - } - - for (i = 0; i < num_master_types; i++) { - for (j = 0; j < num_slave_types; j++) { - if (master_list_p[i] == slave_list_p[j]) { - - /* We've found a codec in common. Configure the coresponding - payload information structure */ - codec = slave_list_p[j]; - payload_info = &(media->payloads[media->num_payloads]); - - if (master_list_p == remote_payload_types) { - remote_pt = remote_payload_types[i]; - } else { - remote_pt = remote_payload_types[j]; - } - - payload_info->codec_type = codec; - payload_info->local_rtp_pt = remote_pt; - payload_info->remote_rtp_pt = remote_pt; - - /* If the negotiated payload type in an answer is different from - what we sent in our offer, we set the local payload type to - our default (since that's what we put in our offer) */ - if (!offer) { - previous_payload_info = - gsmsdp_find_info_for_codec(codec, - media->previous_sdp.payloads, - media->previous_sdp.num_payloads, 0); - if ((previous_payload_info == NULL) || - (previous_payload_info->local_rtp_pt - != payload_info->local_rtp_pt)) { - payload_info->local_rtp_pt = codec; - } - } - - if (media->type == SDP_MEDIA_AUDIO) { - - if (sdp_attr_rtpmap_payload_valid(sdp_p->dest_sdp, level, 0, - &a_inst, remote_pt) ) { - /* Set the number of channels -- if omitted, - default is 1 */ - payload_info->audio.channels = - sdp_attr_get_rtpmap_num_chan(sdp_p->dest_sdp, - level, 0, a_inst); - if (payload_info->audio.channels == 0) { - payload_info->audio.channels = 1; - } - - /* Set frequency = clock rate. This is generally - correct. Codecs can override this assumption on a - case-by-case basis in the switch construct below. */ - payload_info->audio.frequency = - sdp_attr_get_rtpmap_clockrate(sdp_p->dest_sdp, - level, 0, a_inst); - } else { - GSM_DEBUG(DEB_L_C_F_PREFIX"Could not find rtpmap " - "entry for payload %d -- setting defaults\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), codec); - payload_info->audio.channels = 1; - /* See http://www.iana.org/assignments/rtp-parameters/ - rtp-parameters.xml */ - switch (codec) { - case STATIC_RTP_AVP_DVI4_16000_1: - codec = RTP_DVI4; - payload_info->audio.frequency = 16000; - break; - case STATIC_RTP_AVP_L16_44100_2: - codec = RTP_L16; - payload_info->audio.frequency = 44100; - payload_info->audio.channels = 2; - break; - case STATIC_RTP_AVP_L16_44100_1: - codec = RTP_L16; - payload_info->audio.frequency = 44100; - break; - case STATIC_RTP_AVP_DVI4_11025_1: - codec = RTP_DVI4; - payload_info->audio.frequency = 11025; - break; - case STATIC_RTP_AVP_DVI4_22050_1: - codec = RTP_DVI4; - payload_info->audio.frequency = 22050; - break; - default: - payload_info->audio.frequency = 8000; - } - } - - - switch (codec) { - case RTP_PCMA: - case RTP_PCMU: - /* 20 ms = 1/50th of a second */ - payload_info->audio.packet_size = - payload_info->audio.frequency / 50; - - payload_info->audio.bitrate = 8 * - payload_info->audio.frequency * - payload_info->audio.channels; - break; - - - case RTP_OPUS: - if (!sdp_attr_rtpmap_payload_valid(sdp_p->dest_sdp, - level, 0, &a_inst, remote_pt) || - (payload_info->audio.frequency - != RTPMAP_OPUS_CLOCKRATE) || - (payload_info->audio.channels != 2)) { - - /* Be conservative in what we accept: any - implementation that does not use a 48 kHz - clockrate or 2 channels is broken. */ - explicit_reject = TRUE; - continue; // keep looking - } - - /* ********************************************* */ - /* TODO !! FIXME !! XXX - * We can't support two-channel Opus until we merge - * in webrtc.org upstream, rev 3050 or later. See - http://code.google.com/p/webrtc/issues/detail?id=1013 - * for details. We also need to have proper - * handling of the sprop-stereo and stereo SDP - * values before we use stereo encoding/decoding. - * Details in Mozilla Bug 818618. - */ - payload_info->audio.channels = 1; - /* ********************************************* */ - - /* Store fmtp options */ - sdp_attr_get_fmtp_max_average_bitrate ( - sdp_p->dest_sdp, level, 0, 1, - &payload_info->opus.max_average_bitrate); - - payload_info->opus.maxcodedaudiobandwidth = - sdp_attr_get_fmtp_maxcodedaudiobandwidth( - sdp_p->dest_sdp, level, 0, 1); - - sdp_attr_get_fmtp_usedtx (sdp_p->dest_sdp, level, 0, - 1, &payload_info->opus.usedtx); - - sdp_attr_get_fmtp_stereo (sdp_p->dest_sdp, level, 0, - 1, &payload_info->opus.stereo); - - sdp_attr_get_fmtp_useinbandfec (sdp_p->dest_sdp, - level, 0, 1, &payload_info->opus.useinbandfec); - - sdp_attr_get_fmtp_cbr (sdp_p->dest_sdp, level, 0, 1, - &payload_info->opus.cbr); - - /* Copied from media/webrtc/trunk/src/modules/ - audio_coding/main/source/acm_codec_database.cc */ - payload_info->audio.frequency = 32000; - payload_info->audio.packet_size = 960; - payload_info->audio.bitrate = 32000; - break; - - case RTP_ISAC: - /* TODO: Update these from proper SDP constructs */ - payload_info->audio.frequency = 16000; - payload_info->audio.packet_size = 480; - payload_info->audio.bitrate = 32000; - break; - - case RTP_ILBC: - payload_info->ilbc.mode = - (uint16_t)sdp_attr_get_fmtp_mode_for_payload_type( - sdp_p->dest_sdp, level, 0, remote_pt); - - /* TODO -- These should be updated to reflect the - actual frequency */ - if (payload_info->ilbc.mode == SIPSDP_ILBC_MODE20) - { - payload_info->audio.packet_size = 160; - payload_info->audio.bitrate = 15200; - } - else /* mode = 30 */ - { - payload_info->audio.packet_size = 240; - payload_info->audio.bitrate = 13300; - } - break; - - default: - GSM_DEBUG(DEB_L_C_F_PREFIX"codec=%d not setting " - "codec parameters (not implemented)\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), codec); - payload_info->audio.packet_size = -1; - payload_info->audio.bitrate = -1; - } /* end switch */ - - - } else if (media->type == SDP_MEDIA_VIDEO) { - if ( media-> video != NULL ) { - vcmFreeMediaPtr(media->video); - media->video = NULL; - } - - if (!vcmCheckAttribs(codec, sdp_p, level, - &media->video)) { - GSM_DEBUG(DEB_L_C_F_PREFIX"codec= %d ignored - " - "attribs not accepted\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), codec); - explicit_reject = TRUE; - continue; /* keep looking */ - } - - /* cache the negotiated profile_level and bandwidth */ - media->previous_sdp.tias_bw = media->tias_bw; - media->tias_bw = ccsdpGetBandwidthValue(sdp_p,level, 1); - if ( (attr_label = - ccsdpAttrGetFmtpProfileLevelId(sdp_p,level,0,1)) - != NULL ) { - media->previous_sdp.profile_level = - media->profile_level; - sscanf(attr_label,"%x", &media->profile_level); - } - - /* This should ultimately use RFC 6236 a=imageattr - if present */ - switch (codec) { - case RTP_VP8: - payload_info->video.width = 640; - payload_info->video.height = 480; - break; - case RTP_I420: - payload_info->video.width = 176; - payload_info->video.height = 144; - break; - default: - GSM_DEBUG(DEB_L_C_F_PREFIX"codec=%d not setting " - "codec parameters (not implemented)\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), codec); - payload_info->video.width = -1; - payload_info->video.height = -1; - } - } /* end video */ - - GSM_DEBUG(DEB_L_C_F_PREFIX"codec= %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, - dcb_p->call_id, fname), codec); - - - found_codec = TRUE; - if(media->num_payloads >= payload_types_count) { - /* We maxed our allocated memory -- processing is done. */ - return codec; - } - - /* Incrementing this number serves as a "commit" for the - payload_info. If we bail out of the loop before this - happens, then the collected information is abandoned. */ - media->num_payloads++; - - if(offer) { - /* If we are creating an answer, return after the first match. - TODO -- Eventually, we'll (probably) want to answer with - all the codecs we can receive. See bug 814227. */ - return codec; - } - } - } - } - - /* Return the most preferred codec */ - if(found_codec) { - return (media->payloads[0].codec_type); - } - - /* - * CSCsv84705 - we could not negotiate a common codec because - * the local list is empty. This condition could happen when - * using g729 in locally mixed conference in which another call - * to vcm_get_codec_list() would return 0 or no codec. So if - * this is a not an init offer, we should just go ahead and use - * the last negotiated codec if the remote list matches with - * currently used. - */ - if (!initial_offer && !explicit_reject) { - for (i = 0; i < num_remote_types; i++) { - if (media->num_payloads != 0 && media->payloads[0].codec_type == - remote_payload_types[i]) { - GSM_DEBUG(DEB_L_C_F_PREFIX"local codec list was empty codec= %d" - " local=%d remote =%d\n", DEB_L_C_F_PREFIX_ARGS(GSM, - dcb_p->line, dcb_p->call_id, fname), - media->payloads[0].codec_type, - media->payloads[0].local_rtp_pt, - media->payloads[0].remote_rtp_pt); - return (media->payloads[0].codec_type); - } - } - } - - return (RTP_NONE); -} - -static void -gsmsdp_negotiate_datachannel_attribs(fsmdef_dcb_t* dcb_p, cc_sdp_t* sdp_p, uint16_t level, fsmdef_media_t* media) -{ - uint32 num_streams; - // char *protocol; - - sdp_attr_get_fmtp_streams (sdp_p->dest_sdp, level, 0, 1, &num_streams); - - media->streams = num_streams; - - if(media->protocol == NULL) { - media->protocol = cpr_malloc(SDP_MAX_STRING_LEN+1); - if (media->protocol == NULL) - return; - } - sdp_attr_get_fmtp_data_channel_protocol(sdp_p->dest_sdp, level, 0, 1, media->protocol); - - media->sctp_port = sdp_attr_get_fmtp_payload_type (sdp_p->dest_sdp, level, 0, 1); - - /* Increment port for answer SDP */ - media->sctp_port++; -} - -/* - * gsmsdp_add_unsupported_stream_to_local_sdp - * - * Description: - * - * Adds a rejected media line to the local SDP. If there is already a media line at - * the specified level, check to see if it matches the corresponding media line in the - * remote SDP. If it does not, remove the media line from the local SDP so that - * the corresponding remote SDP media line can be added. Note that port will be set - * to zero indicating the media line is rejected. - * - * Parameters: - * - * scp_p - Pointer to the local and remote SDP. - * level - The media line level being rejected. - */ -static void -gsmsdp_add_unsupported_stream_to_local_sdp (cc_sdp_t *sdp_p, - uint16_t level) -{ - static const char fname[] = "gsmsdp_add_unsupported_stream_to_local_sdp"; - uint32_t remote_pt; - sdp_payload_ind_e remote_pt_indicator; - // cpr_ip_addr_t addr; - - if (sdp_p == NULL) { - GSM_ERR_MSG(GSM_F_PREFIX"sdp is null.\n", fname); - return; - } - - if (sdp_get_media_type(sdp_p->src_sdp, level) != SDP_MEDIA_INVALID) { - sdp_delete_media_line(sdp_p->src_sdp, level); - } - - if (sdp_p->dest_sdp == NULL) { - GSM_ERR_MSG(GSM_F_PREFIX"no remote SDP available\n", fname); - return; - } - - /* - * Insert media line at the specified level. - */ - if (sdp_insert_media_line(sdp_p->src_sdp, level) != SDP_SUCCESS) { - GSM_ERR_MSG(GSM_F_PREFIX"failed to insert a media line\n", fname); - return; - } - - /* - * Set the attributes of the media line. Specify port = 0 to - * indicate media line is rejected. - */ - (void) sdp_set_media_type(sdp_p->src_sdp, level, - sdp_get_media_type(sdp_p->dest_sdp, level)); - (void) sdp_set_media_portnum(sdp_p->src_sdp, level, 0, 0); - (void) sdp_set_media_transport(sdp_p->src_sdp, level, - sdp_get_media_transport(sdp_p->dest_sdp, level)); - - remote_pt = sdp_get_media_payload_type(sdp_p->dest_sdp, level, 1, - &remote_pt_indicator); - /* - * Don't like having to cast the payload type but sdp_get_media_payload_type - * returns a uint32_t but sdp_add_media_payload_type takes a uint16_t payload type. - * This needs to be fixed in Rootbeer. - */ - (void) sdp_add_media_payload_type(sdp_p->src_sdp, level, - (uint16_t) remote_pt, - remote_pt_indicator); - /* - * The rejected media line needs to have "c=" line since - * we currently do not include the "c=" at the session level. - * The sdp parser in other end point such as the SDP parser - * in the CUCM and in the phone ensures that there - * is at least one "c=" line that can be used with each media - * line. Such the parser will flag unsupported media line without - * "c=" in that media line and at the session as error. - * - * The solution to have "c=" at the session level and - * omitting "c=" at the media level all together can also - * resolve this problem. Since the phone is also supporting - * ANAT group for IPV4/IPV6 offering therefore selecting - * session level and determining not to include "c=" line - * at the media level can become complex. For this reason, the - * unsupported media line will have "c=" with 0.0.0.0 address instead. - */ - gsmsdp_set_connection_address(sdp_p->src_sdp, level, "0.0.0.0"); -} - -/* - * gsmsdp_get_remote_media_address - * - * Description: - * - * Extract the remote address from the given sdp. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing thhe DCB whose media lines are - * being negotiated - * sdp_p - Pointer to the the remote SDP - * level - media line level. - * dest_addr - pointer to the cpr_ip_addr_t structure to return - * remote address. - * - * Returns: - * FALSE - fails. - * TRUE - success. - * - */ -static boolean -gsmsdp_get_remote_media_address (fsmdef_dcb_t *dcb_p, - cc_sdp_t * sdp_p, uint16_t level, - cpr_ip_addr_t *dest_addr) -{ - const char fname[] = "gsmsdp_get_remote_media_address"; - const char *addr_str = NULL; - int dns_err_code; - boolean stat; - - *dest_addr = ip_addr_invalid; - - stat = sdp_connection_valid(sdp_p->dest_sdp, level); - if (stat) { - addr_str = sdp_get_conn_address(sdp_p->dest_sdp, level); - } else { - /* Address not at the media level. Try the session level. */ - stat = sdp_connection_valid(sdp_p->dest_sdp, SDP_SESSION_LEVEL); - if (stat) { - addr_str = sdp_get_conn_address(sdp_p->dest_sdp, SDP_SESSION_LEVEL); - } - } - - if (stat && addr_str) { - /* Assume that this is dotted address */ - if (str2ip(addr_str, dest_addr) != 0) { - /* It could be Fully Qualify DN, need to add DNS look up here */ - dns_err_code = dnsGetHostByName(addr_str, dest_addr, 100, 1); - if (dns_err_code) { - *dest_addr = ip_addr_invalid; - stat = FALSE; - GSM_ERR_MSG(GSM_L_C_F_PREFIX"DNS remote address error %d" - " with media at %d\n", dcb_p->line, dcb_p->call_id, - fname, dns_err_code, level); - } - } - } else { - /* - * No address the media level or the session level. - */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"No remote address from SDP with at %d\n", - dcb_p->line, dcb_p->call_id, fname, level); - } - /* - * Convert the remote address to host address to be used. It was - * found out that without doing so, the softphone can crash when - * in attempt to setup remote address to transmit API of DSP - * implementation on win32. - */ - util_ntohl(dest_addr, dest_addr); - return (stat); -} - -/* Function gsmsdp_is_multicast_address - * - * Inputs: - IP Address - * - * Returns: YES if is multicast address, no if otherwise - * - * Purpose: This is a utility function that tests to see if the passed - * address is a multicast address. It does so by verifying that the - * address is between 225.0.0.0 and 239.255.255.255. - * - * Note: Addresses passed are not in network byte order. - * - * Note2: Addresses between 224.0.0.0 and 224.255.255.225 are also multicast - * addresses, but 224.0.0.0 to 224.0.0.255 are reserved and it is recommended - * to start at 225.0.0.0. We need to research to see if this is a reasonable - * restriction. - * - */ -int -gsmsdp_is_multicast_address (cpr_ip_addr_t theIpAddress) -{ - if (theIpAddress.type == CPR_IP_ADDR_IPV4) { - /* - * Address already in host format - */ - if ((theIpAddress.u.ip4 >= MULTICAST_START_ADDRESS) && - (theIpAddress.u.ip4 <= MULTICAST_END_ADDRESS)) { - return (TRUE); - } - } else { - //todo IPv6: Check IPv6 multicast address here. - - } - return (FALSE); -} - -/** - * - * The function assigns or associate the new media line in the - * offered SDP to an entry in the media capability table. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]sdp_p - pointer to cc_sdp_t that contains the retmote SDP. - * @param[in]level - uint16_t for media line level. - * - * @return Pointer to the fsmdef_media_t if successfully - * found the anat pair media line otherwise return NULL. - * - * @pre (dcb not_eq NULL) - * @pre (sdp_p not_eq NULL) - * @pre (media not_eq NULL) - */ -static fsmdef_media_t* -gsmsdp_find_anat_media_line (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p, uint16_t level) -{ - fsmdef_media_t *anat_media = NULL; - u32 group_id_1, group_id_2; - u32 dst_mid, group_mid; - uint16_t num_group_lines= 0; - uint16_t num_anat_lines = 0; - uint16_t i; - - /* - * Get number of ANAT groupings at the session level for the media line - */ - (void) sdp_attr_num_instances(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, - &num_group_lines); - - for (i = 1; i <= num_group_lines; i++) { - if (sdp_get_group_attr(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i) == SDP_GROUP_ATTR_ANAT) { - num_anat_lines++; - } - } - - for (i = 1; i <= num_anat_lines; i++) { - - dst_mid = sdp_attr_get_simple_u32(sdp_p->dest_sdp, SDP_ATTR_MID, level, 0, 1); - group_id_1 = sdp_get_group_id(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i, 1); - group_id_2 = sdp_get_group_id(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i, 2); - - if (dst_mid == group_id_1) { - GSMSDP_FOR_ALL_MEDIA(anat_media, dcb_p) { - group_mid = sdp_attr_get_simple_u32(sdp_p->src_sdp, - SDP_ATTR_MID, (uint16_t) group_id_2, 0, 1); - if (group_mid == group_id_2) { - /* found a match */ - return (anat_media); - } - } - } else if (dst_mid == group_id_2) { - GSMSDP_FOR_ALL_MEDIA(anat_media, dcb_p) { - group_mid = sdp_attr_get_simple_u32(sdp_p->src_sdp, - SDP_ATTR_MID, (uint16_t) group_id_1, 0, 1); - if (group_mid == group_id_1) { - /* found a match */ - return (anat_media); - } - } - } - } - return (anat_media); -} - -/** - * - * The function validates if all the anat groupings - * have the right number of ids and their media type - * is not the same - * - * @param[in]sdp_p - pointer to the cc_sdp_t. - * - * @return TRUE - anat validation passes - * FALSE - anat validation fails - * - * @pre (dcb not_eq NULL) - * @pre (sdp_p not_eq NULL) - */ -static boolean -gsmsdp_validate_anat (cc_sdp_t *sdp_p) -{ - u16 i, num_group_id; - u32 group_id_1, group_id_2; - sdp_media_e media_type_gid1, media_type_gid2; - uint16_t num_group_lines= 0; - uint16_t num_anat_lines = 0; - - /* - * Get number of ANAT groupings at the session level for the media line - */ - (void) sdp_attr_num_instances(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, - &num_group_lines); - - for (i = 1; i <= num_group_lines; i++) { - if (sdp_get_group_attr(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i) == SDP_GROUP_ATTR_ANAT) { - num_anat_lines++; - } - } - - for (i = 1; i <= num_anat_lines; i++) { - num_group_id = sdp_get_group_num_id (sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i); - if ((num_group_id <=0) || (num_group_id > 2)) { - /* This anat line has zero or more than two grouping, this is invalid */ - return (FALSE); - } else if (num_group_id == 2) { - /* Make sure that these anat groupings are not of same type */ - group_id_1 = sdp_get_group_id(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i, 1); - group_id_2 = sdp_get_group_id(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i, 2); - media_type_gid1 = sdp_get_media_type(sdp_p->dest_sdp, (u16) group_id_1); - media_type_gid2 = sdp_get_media_type(sdp_p->dest_sdp, (u16) group_id_2); - if (media_type_gid1 != media_type_gid2) { - /* Group id types do not match */ - return (FALSE); - } - if (group_id_1 != sdp_attr_get_simple_u32(sdp_p->dest_sdp, SDP_ATTR_MID, (u16) group_id_1, 0, 1)) { - /* Group id does not match the mid at the corresponding line */ - return (FALSE); - } - if (group_id_2 != sdp_attr_get_simple_u32(sdp_p->dest_sdp, SDP_ATTR_MID, (u16) group_id_2, 0, 1)) { - return (FALSE); - } - } - } - - return (TRUE); -} - -/** - * - * The function validates if all the destination - * Sdp m lines have mid values and if those mid values match - * the source Sdp mid values - * - * @param[in]sdp_p - pointer to the cc_sdp_t - * @param[in]level - uint16_t for media line level. - * - * @return TRUE - mid validation passes - * FALSE - mid validation fails - * - * @pre (dcb not_eq NULL) - * @pre (sdp_p not_eq NULL) - */ -static boolean -gsmsdp_validate_mid (cc_sdp_t *sdp_p, uint16_t level) -{ - int32 src_mid, dst_mid; - u16 i; - uint16_t num_group_lines= 0; - uint16_t num_anat_lines = 0; - - /* - * Get number of ANAT groupings at the session level for the media line - */ - (void) sdp_attr_num_instances(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, SDP_ATTR_GROUP, - &num_group_lines); - - for (i = 1; i <= num_group_lines; i++) { - if (sdp_get_group_attr(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, i) == SDP_GROUP_ATTR_ANAT) { - num_anat_lines++; - } - } - - - if (num_anat_lines > 0) { - dst_mid = sdp_attr_get_simple_u32(sdp_p->dest_sdp, SDP_ATTR_MID, level, 0, 1); - if (dst_mid == 0) { - return (FALSE); - } - if (sdp_get_group_attr(sdp_p->src_sdp, SDP_SESSION_LEVEL, 0, 1) == SDP_GROUP_ATTR_ANAT) { - src_mid = sdp_attr_get_simple_u32(sdp_p->src_sdp, SDP_ATTR_MID, level, 0, 1); - if (dst_mid != src_mid) { - return (FALSE); - } - } - - } - return (TRUE); -} - -/** - * - * The function negotiates the type of the media lines - * based on anat attributes and ipv4/ipv6 settinsg. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media - pointer to the fsmdef_media_t - * - * @return TRUE - this media line can be kept - * FALSE - this media line can not be kept - * - * @pre (dcb not_eq NULL) - * @pre (sdp_p not_eq NULL) - */ -static boolean -gsmsdp_negotiate_addr_type (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_negotiate_addr_type"; - cpr_ip_type media_addr_type; - cpr_ip_mode_e ip_mode; - fsmdef_media_t *group_media; - - media_addr_type = media->dest_addr.type; - if ((media_addr_type != CPR_IP_ADDR_IPV4) && - (media_addr_type != CPR_IP_ADDR_IPV6)) { - /* Unknown/unsupported address type */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"address type is not IPv4 or IPv6\n", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - ip_mode = platform_get_ip_address_mode(); - /* - * find out whether this media line is part of an ANAT group or not. - */ - group_media = gsmsdp_find_anat_pair(dcb_p, media); - - /* - * It is possible that we have a media sink/source device that - * attached to the phone, then we only accept IPV4 for these device. - * - * The code below is using FSM_MEDIA_F_SUPPORT_SECURITY as indication - * whether this media line is mapped to the off board device or not. - * When we get a better API to find out then use the better API than - * checking the FSM_MEDIA_F_SUPPORT_SECURITY. - */ - if (!FSM_CHK_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY)) { - if (media_addr_type != CPR_IP_ADDR_IPV4) { - /* off board device we do not allow other address type but IPV4 */ - GSM_DEBUG(DEB_L_C_F_PREFIX"offboard device does not support IPV6\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return (FALSE); - } - - /* - * P2: - * Need an API to get address from the off board device. For now, - * use our local address. - */ - if ((ip_mode == CPR_IP_MODE_DUAL) || (ip_mode == CPR_IP_MODE_IPV4)) { - if (group_media != NULL) { - /* - * this media line is part of ANAT group, keep the previous - * one negotiated media line. - */ - return (FALSE); - } - gsmsdp_get_local_source_v4_address(media); - return (TRUE); - } - /* phone is IPV6 only mode */ - return (FALSE); - } - - if (ip_mode == CPR_IP_MODE_DUAL) { - /* - * In dual mode, IPV6 is preferred address type. If there is an - * ANAT then select the media line that has IPV6 address. - */ - if (group_media == NULL) { - /* - * no pair media line found, this can be the first media - * line negotiate. Keep this media line for now. - */ - if (media_addr_type == CPR_IP_ADDR_IPV4) { - gsmsdp_get_local_source_v4_address(media); - } else { - gsmsdp_get_local_source_v6_address(media); - } - return (TRUE); - } - - /* - * Found a ANAT pair media structure that this media line - * is part of. - */ - if (media_addr_type == CPR_IP_ADDR_IPV4) { - /* - * This media line is IPV4, keep the other line that have - * been accepted before i.e. it shows up first therefore - * the other one has preference. - */ - return (FALSE); - } - - /* This media line is IPV6 */ - if (group_media->src_addr.type == CPR_IP_ADDR_IPV4) { - /* - * The previous media line part of ANAT group is IPV4. The - * phone policy is to select IPV6 for media stream. Remove - * the previous media line and keep this media line (IPV6). - */ - gsmsdp_add_unsupported_stream_to_local_sdp(dcb_p->sdp, - group_media->level); - gsmsdp_remove_media(dcb_p, group_media); - /* set this media line source address to IPV6 */ - gsmsdp_get_local_source_v6_address(media); - return (TRUE); - } - /* - * keep the previous one is also IPV6, remove this one i.e. - * the one found has higher preferecne although this is not - * a valid ANAT grouping. - */ - return (FALSE); - } - - /* - * The phone is not in dual mode, the address type must be from the media - * line must match the address type that the phone is supporting. - */ - if ((ip_mode == CPR_IP_MODE_IPV6) && - (media_addr_type == CPR_IP_ADDR_IPV4)) { - /* incompatible address type */ - return (FALSE); - } - if ((ip_mode == CPR_IP_MODE_IPV4) && - (media_addr_type == CPR_IP_ADDR_IPV6)) { - /* incompatible address type */ - return (FALSE); - } - - if (group_media != NULL) { - /* - * This meida line is part of an ANAT group, keep the previous - * media line and throw away this line. - */ - return (FALSE); - } - - /* - * We have a compatible address type, set the source address based on - * the address type from the remote media line. - */ - if (media_addr_type == CPR_IP_ADDR_IPV4) { - gsmsdp_get_local_source_v4_address(media); - } else { - gsmsdp_get_local_source_v6_address(media); - } - /* keep this media line */ - return (TRUE); -} - -/** - * - * The function finds the best media capability that matches the offer - * media line according to the media table specified. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]sdp_p - pointer to cc_sdp_t that contains the retmote SDP. - * @param[in]media - pointer to the fsmdef_media_t. - * @param[in]media_table - media table to use (global or session) - * - * @return cap_index - the best match for the offer - * - * @pre (dcb_p not_eq NULL) - * @pre (sdp_p not_eq NULL) - * @pre (media not_eq NULL) - */ -static uint8_t -gsmdsp_find_best_match_media_cap_index (fsmdef_dcb_t *dcb_p, - cc_sdp_t *sdp_p, - fsmdef_media_t *media, - media_table_e media_table) -{ - const cc_media_cap_t *media_cap; - uint8_t cap_index, candidate_cap_index; - boolean srtp_fallback; - sdp_direction_e remote_direction, support_direction; - sdp_transport_e remote_transport; - sdp_media_e media_type; - - remote_transport = sdp_get_media_transport(sdp_p->dest_sdp, media->level); - remote_direction = gsmsdp_get_remote_sdp_direction(dcb_p, media->level, - &media->dest_addr); - srtp_fallback = sip_regmgr_srtp_fallback_enabled(dcb_p->line); - media_type = media->type; - - - /* - * Select the best suitable media capability entry that - * match this media line. - * - * The following rules are used: - * - * 1) rule out entry that is invalid or not enabled or with - * different media type. - * 2) rule out entry that has been used by other existing - * media line. - * - * After the above rules applies look for the better match for - * direction support and security support. The platform should - * arrange the capability table in preference order with - * higher prefered entry placed at the lower index in the table. - */ - candidate_cap_index = CC_MAX_MEDIA_CAP; - for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP; cap_index++) { - /* Find the cap entry that has the same media type and enabled */ - if (media_table == MEDIA_TABLE_GLOBAL) { - media_cap = &g_media_table.cap[cap_index]; - } else { - media_cap = gsmsdp_get_media_cap_entry_by_index(cap_index,dcb_p); - } - if ((media_cap == NULL) || !media_cap->enabled || - (media_cap->type != media_type)) { - /* does not exist, not enabled or not the same type */ - continue; - } - - /* Check for already in used */ - if (gsmsdp_find_media_by_cap_index(dcb_p, cap_index) != NULL) { - /* this capability entry has been used */ - continue; - } - - /* - * Check for security support. The rules below attempts to - * use entry that support security unless there is no entry - * and the SRTP fallback is enabled. If the remote offer is not - * SRTP just ignore the supported security and proceed on i.e. - * any entry is ok. - */ - if (remote_transport == SDP_TRANSPORT_RTPSAVP) { - if (!media_cap->support_security && !srtp_fallback) { - /* - * this entry does not support security and SRTP fallback - * is not enabled. - */ - continue; - } - if (!media_cap->support_security) { - /* - * this entry is not support security but srtp fallback - * is enabled, it potentially can be used - */ - candidate_cap_index = cap_index; - } - } - - /* - * Check for suitable direction support. The rules for matching - * directions are not exact rules. Try to match the closely - * offer as much as possible. This is the best we know. We can - * not guess what the real capability of the offer may have or will - * change in the future (re-invite). - */ - support_direction = media_cap->support_direction; - if (remote_direction == SDP_DIRECTION_INACTIVE) { - if (support_direction != SDP_DIRECTION_SENDRECV) { - /* prefer send and receive for inactive */ - candidate_cap_index = cap_index; - } - } else if (remote_direction == SDP_DIRECTION_RECVONLY) { - if ((support_direction != SDP_DIRECTION_SENDRECV) && - (support_direction != SDP_DIRECTION_SENDONLY)) { - /* incompatible direction */ - continue; - } else if (support_direction != SDP_DIRECTION_SENDONLY) { - candidate_cap_index = cap_index; - } - } else if (remote_direction == SDP_DIRECTION_SENDONLY) { - if ((support_direction != SDP_DIRECTION_SENDRECV) && - (support_direction != SDP_DIRECTION_RECVONLY)) { - /* incompatible direction */ - continue; - } else if (support_direction != SDP_DIRECTION_RECVONLY) { - candidate_cap_index = cap_index; - } - } else if (remote_direction == SDP_DIRECTION_SENDRECV) { - if (support_direction != SDP_DIRECTION_SENDRECV) { - candidate_cap_index = cap_index; - } - } - - if (candidate_cap_index == cap_index) { - /* this entry is not exactly best match, try other ones */ - continue; - } - /* this is the first best match found, use it */ - break; - } - - if (cap_index == CC_MAX_MEDIA_CAP) { - if (candidate_cap_index != CC_MAX_MEDIA_CAP) { - /* We have a candidate entry to use */ - cap_index = candidate_cap_index; - } - } - - return cap_index; -} - -/** - * - * The function finds the best media capability that matches the offer - * media line. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]sdp_p - pointer to cc_sdp_t that contains the retmote SDP. - * @param[in]media - pointer to the fsmdef_media_t. - * - * @return TRUE - successful assigning a capability entry - * to the media line. - * FALSE - failed to assign a capability entry to the - * media line. - * - * @pre (dcb_p not_eq NULL) - * @pre (sdp_p not_eq NULL) - * @pre (media not_eq NULL) - */ -static boolean -gsmsdp_assign_cap_entry_to_incoming_media (fsmdef_dcb_t *dcb_p, - cc_sdp_t *sdp_p, - fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_assign_cap_entry_to_incoming_media"; - const cc_media_cap_t *media_cap; - uint8_t cap_index; - fsmdef_media_t *anat_media; - - /* - * Find an existing media line that this media line belongs to the - * same media group. If found, the same cap_index will be used. - */ - anat_media = gsmsdp_find_anat_media_line(dcb_p, sdp_p, media->level); - if (anat_media != NULL) { - media_cap = gsmsdp_get_media_cap_entry_by_index(anat_media->cap_index, dcb_p); - if (media_cap == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capability\n", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - gsmsdp_set_media_capability(media, media_cap); - /* found the existing media line in the same ANAT group */ - media->cap_index = anat_media->cap_index; - return (TRUE); - } - - - cap_index = gsmdsp_find_best_match_media_cap_index(dcb_p, - sdp_p, - media, - MEDIA_TABLE_SESSION); - - if (cap_index == CC_MAX_MEDIA_CAP) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"reached max streams supported or" - " no suitable media capability\n", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - - /* set the capabilities to the media and associate with it */ - media_cap = gsmsdp_get_media_cap_entry_by_index(cap_index,dcb_p); - if (media_cap == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media cap\n", - dcb_p->line, dcb_p->call_id, fname); - return (FALSE); - } - gsmsdp_set_media_capability(media, media_cap); - - /* override the direction for special feature */ - gsmsdp_feature_overide_direction(dcb_p, media); - if (media->support_direction == SDP_DIRECTION_INACTIVE) { - GSM_DEBUG(DEB_L_C_F_PREFIX"feature overrides direction to inactive," - " no capability assigned\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return (FALSE); - } - - media->cap_index = cap_index; - GSM_DEBUG(DEB_L_C_F_PREFIX"assign media cap index %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), cap_index); - return (TRUE); -} - -/** - * - * The function handles negotiate adding of a media line. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media_type - media type. - * @param[in]level - media line. - * @param[in]remote_port - remote port - * @param[in]offer - boolean indicates offer or answer. - * - * @return pointer to fsmdef_media_t if media is successfully - * added or return NULL. - * - * @pre (dcb_p not_eq NULL) - * @pre (sdp_p not_eq NULL) - * @pre (remote_addr not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_negotiate_add_media_line (fsmdef_dcb_t *dcb_p, - sdp_media_e media_type, - uint16_t level, - uint16_t remote_port, - boolean offer) -{ - static const char fname[] = "gsmsdp_negotiate_add_media_line"; - fsmdef_media_t *media; - - if (remote_port == 0) { - /* - * This media line is new but marked as disbaled. - */ - return (NULL); - } - - if (!offer) { - /* - * This is not an offer, the remote end wants to add - * a new media line in the answer. - */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"remote trying add media in answer SDP\n", - dcb_p->line, dcb_p->call_id, fname); - return (NULL); - } - - /* - * Allocate a new raw media structure but not filling completely yet. - */ - media = gsmsdp_get_new_media(dcb_p, media_type, level); - if (media == NULL) { - /* unable to add another media */ - return (NULL); - } - - /* - * If this call is locally held, mark the media with local hold so - * that the negotiate direction will have the correct direction. - */ - if ((dcb_p->fcb->state == FSMDEF_S_HOLDING) || - (dcb_p->fcb->state == FSMDEF_S_HOLD_PENDING)) { - /* the call is locally held, set the local held status */ - FSM_SET_FLAGS(media->hold, FSM_HOLD_LCL); - } - return (media); -} - -/** - * - * The function handles negotiate remove of a media line. Note the - * removal of a media line does not actaully removed from the offer/answer - * SDP. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media - pointer to the fsmdef_media_t for the media entry - * to deactivate. - * @param[in]remote_port - remote port from the remote's SDP. - * @param[in]offer - boolean indicates offer or answer. - * - * @return TRUE - when line is inactive. - * FALSE - when line remains to be further processed. - * - * @pre (dcb not_eq NULL) and (media not_eq NULL) - */ -static boolean -gsmsdp_negotiate_remove_media_line (fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - uint16_t remote_port, - boolean offer) -{ - static const char fname[] = "gsmsdp_negotiate_remove_media_line"; - - if (offer) { - /* This is an offer SDP from the remote */ - if (remote_port != 0) { - /* the remote quests media is not for removal */ - return (FALSE); - } - /* - * Remote wants to remove the media line or to keep the media line - * disabled. Fall through. - */ - } else { - /* This is an answer SDP from the remote */ - if ((media->src_port != 0) && (remote_port != 0)) { - /* the media line is not for removal */ - return (FALSE); - } - /* - * There are 3 possible causes: - * 1) our offered port is 0 and remote's port is 0 - * 2) our offered port is 0 and remote's port is not 0. - * 3) our offered port is not 0 and remote's port is 0. - * - * In any of these cases, the media line will not be used. - */ - if ((media->src_port == 0) && (remote_port != 0)) { - /* we offer media line removal but the remote does not comply */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"remote insists on keeping media line\n", - dcb_p->line, dcb_p->call_id, fname); - } - } - - /* - * This media line is to be removed. - */ - return (TRUE); -} - -/* - * Find a media line based on the media type. - */ -fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb_p, sdp_media_e media_type) { - - fsmdef_media_t *media = NULL; - - /* - * search the all entries that has a valid media and matches the media type - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->type == media_type) { - /* found a match */ - return (media); - } - } - return (NULL); -} - -/* - * gsmsdp_negotiate_media_lines - * - * Description: - * - * Walk down the media lines provided in the remote sdp. Compare each - * media line to the corresponding media line in the local sdp. If - * the media line does not exist in the local sdp, add it. If the media - * line exists in the local sdp but is different from the remote sdp, - * change the local sdp to match the remote sdp. If the media line - * is an AUDIO format, negotiate the codec and update the local sdp - * as needed. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing thhe DCB whose media lines are being negotiated - * sdp_p - Pointer to the local and remote SDP - * initial_offer - Boolean indicating if the remote SDP came in the first OFFER of this session - * offer - Boolean indicating if the remote SDP came in an OFFER. - * notify_stream_added - Boolean indicating the UI should be notified of streams added - * - */ -cc_causes_t -gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer, - boolean offer, boolean notify_stream_added, boolean create_answer) -{ - static const char fname[] = "gsmsdp_negotiate_media_lines"; - cc_causes_t cause = CC_CAUSE_OK; - uint16_t num_m_lines = 0; - uint16_t num_local_m_lines = 0; - uint16_t i = 0; - sdp_media_e media_type; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - uint16_t port; - boolean update_local_ret_value = TRUE; - sdp_transport_e transport; - uint16_t crypto_inst; - boolean media_found = FALSE; - cpr_ip_addr_t remote_addr; - boolean new_media; - sdp_direction_e video_avail = SDP_DIRECTION_INACTIVE; - boolean unsupported_line; - fsmdef_media_t *media; - uint8_t cap_index; - sdp_direction_e remote_direction; - // boolean result; - int sdpmode = 0; - // char *session_pwd; - // cc_action_data_t data; - int j=0; - int rtcpmux = 0; - tinybool rtcp_mux = FALSE; - sdp_result_e sdp_res; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - num_m_lines = sdp_get_num_media_lines(sdp_p->dest_sdp); - if (num_m_lines == 0) { - GSM_DEBUG(DEB_L_C_F_PREFIX"no media lines found.\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return CC_CAUSE_NO_MEDIA; - } - - /* - * Validate the anat values - */ - if (!gsmsdp_validate_anat(sdp_p)) { - /* Failed anat validation */ - GSM_DEBUG(DEB_L_C_F_PREFIX"failed anat validation\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return (CC_CAUSE_NO_MEDIA); - } - - /* - * Process each media line in the remote SDP - */ - for (i = 1; i <= num_m_lines; i++) { - unsupported_line = FALSE; /* assume line will be supported */ - new_media = FALSE; - media = NULL; - media_type = sdp_get_media_type(sdp_p->dest_sdp, i); - - /* - * Only perform these checks when called from createanswer - * because at this point we are concerned as to which m= lines - * have been created in the answer. - */ - if (create_answer) { - - /* Since the incoming SDP might not be in the same order as - our media, we find them by type rather than location - for this check. Note that we're not checking for the - value of any _particular_ m= section; we're just checking - whether (at least) one of the specified type exists. */ - media = gsmsdp_find_media_by_media_type(dcb_p, media_type); - - if (media_type == SDP_MEDIA_AUDIO && !media) { - /* continue if answer will not add this m= line */ - continue; - } - - if (media_type == SDP_MEDIA_VIDEO && !media) { - continue; - } - - if (media_type == SDP_MEDIA_APPLICATION && !media) { - continue; - } - } - - port = (uint16_t) sdp_get_media_portnum(sdp_p->dest_sdp, i); - GSM_DEBUG(DEB_L_C_F_PREFIX"Port is %d at %d %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - port, i, initial_offer); - - switch (media_type) { - case SDP_MEDIA_AUDIO: - case SDP_MEDIA_VIDEO: - case SDP_MEDIA_APPLICATION: - /* - * Get remote address before other negotiations process in case - * the address 0.0.0.0 (old style hold) to be used - * for direction negotiation. - */ - if (!gsmsdp_get_remote_media_address(dcb_p, sdp_p, i, - &remote_addr)) { - /* failed to get the remote address */ - GSM_DEBUG(DEB_L_C_F_PREFIX"unable to get remote addr at %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - unsupported_line = TRUE; - break; - } - - /* - * Find the corresponding media entry in the dcb to see - * this has been negiotiated previously (from the - * last offer/answer session). - */ - if(!create_answer) - media = gsmsdp_find_media_by_level(dcb_p, i); - - if (media == NULL) { - /* No previous media, negotiate adding new media line. */ - media = gsmsdp_negotiate_add_media_line(dcb_p, media_type, i, - port, offer); - if (media == NULL) { - /* new one can not be added */ - unsupported_line = TRUE; - break; - } - /* - * This media is a newly added, it is by itself an - * initial offer of this line. - */ - new_media = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX"new media entry at %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - } else if (media->type == media_type) { - /* - * Use the remote port to determine whether the - * media line is to be removed from the SDP. - */ - if (gsmsdp_negotiate_remove_media_line(dcb_p, media, port, - offer)) { - /* the media line is to be removed from the SDP */ - unsupported_line = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX"media at %d is removed\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - break; - } - } else { - /* The media at the same level but not the expected type */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"mismatch media type at %d\n", - dcb_p->line, dcb_p->call_id, fname, i); - unsupported_line = TRUE; - break; - } - - /* Do not negotiate if media is set to inactive */ - if (SDP_DIRECTION_INACTIVE == media->direction) { - break; - } - - /* Reset multicast flag and port */ - media->is_multicast = FALSE; - media->multicast_port = 0; - - /* Update remote address */ - media->previous_sdp.dest_addr = media->dest_addr; - media->dest_addr = remote_addr; - - /* - * Associate the new media (for adding new media line) to - * the capability table. - */ - if (media->cap_index == CC_MAX_MEDIA_CAP) { - if (!gsmsdp_assign_cap_entry_to_incoming_media(dcb_p, sdp_p, - media)) { - unsupported_line = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX"unable to assign capability entry at %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - // Check if we need to update the UI that video has been offered - if ( offer && media_type == SDP_MEDIA_VIDEO && - ( ( g_media_table.cap[CC_VIDEO_1].support_direction != - SDP_DIRECTION_INACTIVE) ) ) { - // passed basic checks, now on to more expensive checks... - remote_direction = gsmsdp_get_remote_sdp_direction(dcb_p, - media->level, - &media->dest_addr); - cap_index = gsmdsp_find_best_match_media_cap_index(dcb_p, - sdp_p, - media, - MEDIA_TABLE_GLOBAL); - - GSM_DEBUG(DEB_L_C_F_PREFIX"remote_direction: %d global match %sfound\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - remote_direction, (cap_index != CC_MAX_MEDIA_CAP) ? "" : "not "); - if ( cap_index != CC_MAX_MEDIA_CAP && - remote_direction != SDP_DIRECTION_INACTIVE ) { - // this is an offer and platform can support video - GSM_DEBUG(DEB_L_C_F_PREFIX"\n\n\n\nUpdate video Offered Called %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), remote_direction); - lsm_update_video_offered(dcb_p->line, dcb_p->call_id, remote_direction); - } - } - break; - } - } - - /* - * Negotiate address type and take only address type - * that can be accepted. - */ - if (!gsmsdp_negotiate_addr_type(dcb_p, media)) { - unsupported_line = TRUE; - break; - } - - /* - * Negotiate RTP/SRTP. The result is the media transport - * which could be RTP/SRTP or fail. - */ - transport = gsmsdp_negotiate_media_transport(dcb_p, sdp_p, - offer, media, - &crypto_inst, i); - if (transport == SDP_TRANSPORT_INVALID) { - /* unable to negotiate transport */ - unsupported_line = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX"transport mismatch at %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - break; - } - - /* Don't need to negotiate a codec for an m= applicaton line */ - if (SDP_MEDIA_APPLICATION != media_type) { - - /* - * Negotiate to a single codec - */ - if (gsmsdp_negotiate_codec(dcb_p, sdp_p, media, offer, initial_offer, i) == - RTP_NONE) { - /* unable to negotiate codec */ - unsupported_line = TRUE; - /* Failed codec negotiation */ - cause = CC_CAUSE_PAYLOAD_MISMATCH; - GSM_DEBUG(DEB_L_C_F_PREFIX"codec mismatch at %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - break; - } - } else { - gsmsdp_negotiate_datachannel_attribs(dcb_p, sdp_p, i, media); - } - - /* - * Both media transport (RTP/SRTP) and codec are - * now negotiated to common ones, update transport - * parameters to be used for SRTP, if there is any. - */ - gsmsdp_update_negotiated_transport(dcb_p, sdp_p, media, - crypto_inst, transport, i); - GSM_DEBUG(DEB_F_PREFIX"local transport after updating negotiated: %d\n",DEB_F_PREFIX_ARGS(GSM, fname), sdp_get_media_transport(dcb_p->sdp->src_sdp, 1)); - /* - * Add to or update media line to the local SDP as needed. - */ - if (gsmsdp_is_multicast_address(media->dest_addr)) { - /* - * Multicast, if the address is multicast - * then change the local sdp and do the necessary - * call to set up reception of multicast packets - */ - GSM_DEBUG(DEB_L_C_F_PREFIX"Got multicast offer\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - media->is_multicast = TRUE; - media->multicast_port = port; - update_local_ret_value = - gsmsdp_update_local_sdp_for_multicast(dcb_p, port, - media, offer, - new_media); - } else { - update_local_ret_value = gsmsdp_update_local_sdp(dcb_p, - offer, - new_media, - media); - } - GSM_DEBUG(DEB_F_PREFIX"local transport after updateing local SDP: %d\n",DEB_F_PREFIX_ARGS(GSM, fname), sdp_get_media_transport(dcb_p->sdp->src_sdp, 1)); - - /* - * Successful codec negotiated cache direction for ui video update - */ - if (media_type == SDP_MEDIA_VIDEO ) { - video_avail = media->direction; - } - - if (update_local_ret_value == TRUE) { - media->previous_sdp.dest_port = media->dest_port; - media->dest_port = port; - if (media_type == SDP_MEDIA_AUDIO || sdpmode) { - /* at least found one workable audio media line */ - media_found = TRUE; - } - } else { - /* - * Rejecting multicast because direction is not RECVONLY - */ - unsupported_line = TRUE; - update_local_ret_value = TRUE; - } - - /* - * Negotiate rtcp-mux - */ - - sdp_res = sdp_attr_get_rtcp_mux_attribute (sdp_p->dest_sdp, i, - 0, SDP_ATTR_RTCP_MUX, 1, &rtcp_mux); - - if (SDP_SUCCESS == sdp_res) { - media->rtcp_mux = TRUE; - } - - if (!unsupported_line) { - - if (sdpmode) { - int j; - - /* Set ICE */ - for (j=0; jcandidate_ct; j++) { - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, media->level, - sdp_p->src_sdp, media->candidatesp[j]); - } - - config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux)); - if (rtcpmux) { - gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, media->level, sdp_p->src_sdp, TRUE); - } - - if (notify_stream_added) { - /* - * Add track to remote streams in dcb - */ - int pc_stream_id = 0; - - if (SDP_MEDIA_APPLICATION != media_type) { - lsm_add_remote_stream (dcb_p->line, dcb_p->call_id, media, &pc_stream_id); - gsmsdp_add_remote_stream(i-1, pc_stream_id, dcb_p, media); - } else { - /* - * Inform VCM that a Data Channel has been negotiated - */ - lsm_data_channel_negotiated(dcb_p->line, dcb_p->call_id, media, &pc_stream_id); - } - } - } - } - - break; - - default: - /* Not a support media type stream */ - unsupported_line = TRUE; - break; - } - - if (unsupported_line) { - /* add this line to unsupported line */ - gsmsdp_add_unsupported_stream_to_local_sdp(sdp_p, i); - gsmsdp_set_mid_attr(sdp_p->src_sdp, i); - /* Remove the media if one to be removed */ - if (media != NULL) { - /* remove this media off the list */ - gsmsdp_remove_media(dcb_p, media); - } - } - if (!gsmsdp_validate_mid(sdp_p, i)) { - /* Failed mid validation */ - cause = CC_CAUSE_NO_MEDIA; - GSM_DEBUG(DEB_L_C_F_PREFIX"failed mid validation at %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); - } - } - - /* - * Must have at least one media found and at least one audio - * line. - */ - if (!media_found) { - if (cause != CC_CAUSE_PAYLOAD_MISMATCH) { - cause = CC_CAUSE_NO_MEDIA; - } - } else { - if (cause == CC_CAUSE_PAYLOAD_MISMATCH) { - /* - * some media lines have codec mismatch but there are some - * that works, do not return error. - */ - cause = CC_CAUSE_OK; - } - - /* - * If we are processing an offer sdp, need to set the - * start time and stop time based on the remote SDP - */ - gsmsdp_update_local_time_stamp(dcb_p, offer, initial_offer); - - /* - * workable media line was found. Need to make sure we don't - * advertise more than workable media lines. Loop through - * remaining media lines in local SDP and set port to zero. - */ - num_local_m_lines = sdp_get_num_media_lines(sdp_p->src_sdp); - if (num_local_m_lines > num_m_lines) { - for (i = num_m_lines + 1; i <= num_local_m_lines; i++) { - (void) sdp_set_media_portnum(sdp_p->src_sdp, i, 0, 0); - } - } - - /* - * Update UI for Remote Stream Added - */ - if (sdpmode) { - - /* Fail negotiation if DTLS is not in SDP */ - cause = gsmsdp_configure_dtls_data_attributes(fcb_p); - if (cause != CC_CAUSE_OK) { - GSM_DEBUG("gsmsdp_negotiate_media_lines- DTLS negotiation failed\n"); - return cause; - } - - /* ToDO(emannion) - * Fail negotiation if ICE is not negotiated. - */ - - /* - * Bubble the stream added event up to the PC UI - */ - if (notify_stream_added) { - for (j=0; j < CC_MAX_STREAMS; j++ ) { - /* If this stream has been created it should have > 0 tracks. */ - if (dcb_p->remote_media_stream_tbl->streams[j].num_tracks) { - ui_on_remote_stream_added(evOnRemoteStreamAdd, dcb_p->line, dcb_p->call_id, - dcb_p->caller_id.call_instance_id, dcb_p->remote_media_stream_tbl->streams[j]); - - /* Setting num_tracks == 0 indicates stream not set */ - dcb_p->remote_media_stream_tbl->streams[j].num_tracks = 0; - } - } - } - } - } - /* - * We have negotiated the line, clear flag that we have set - * that we are waiting for an answer SDP in ack. - */ - dcb_p->remote_sdp_in_ack = FALSE; - - /* - * check to see if UI needs to be updated for video - */ - GSM_DEBUG(DEB_L_C_F_PREFIX"Update video Avail Called %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname),video_avail); - - // update direction but preserve the cast attrib - dcb_p->cur_video_avail &= CC_ATTRIB_CAST; - dcb_p->cur_video_avail |= (uint8_t)video_avail; - - lsm_update_video_avail(dcb_p->line, dcb_p->call_id, dcb_p->cur_video_avail); - - return cause; -} - -/* - * This function returns boolean parameters indicating what media types - * exist in the offered SDP. - */ -cc_causes_t -gsmsdp_get_offered_media_types (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean *has_audio, - boolean *has_video, boolean *has_data) -{ - cc_causes_t cause = CC_CAUSE_OK; - uint16_t num_m_lines = 0; - uint16_t i = 0; - sdp_media_e media_type; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - // boolean result; - - num_m_lines = sdp_get_num_media_lines(sdp_p->dest_sdp); - if (num_m_lines == 0) { - GSM_DEBUG(DEB_L_C_F_PREFIX"no media lines found.\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, __FUNCTION__)); - return CC_CAUSE_NO_MEDIA; - } - - *has_audio = FALSE; - *has_video = FALSE; - *has_data = FALSE; - - /* - * Process each media line in the remote SDP - */ - for (i = 1; i <= num_m_lines; i++) { - media_type = sdp_get_media_type(sdp_p->dest_sdp, i); - - if(SDP_MEDIA_AUDIO == media_type) - *has_audio = TRUE; - else if(SDP_MEDIA_VIDEO == media_type) - *has_video = TRUE; - else if(SDP_MEDIA_APPLICATION == media_type) - *has_data = TRUE; - } - - return cause; -} - -/* - * gsmsdp_init_local_sdp - * - * Description: - * - * This function initializes the local sdp for generation of an offer sdp or - * an answer sdp. The following sdp values are initialized. - * - * v= line - * o= line
- * s= line - * t= line - * - * Parameters: - * - * peerconnection - handle to peerconnection object - * sdp_pp - Pointer to the local sdp - * - * returns cc_causes_t - * CC_CAUSE_OK - indicates success - * CC_CAUSE_ERROR - indicates failure - */ -static cc_causes_t -gsmsdp_init_local_sdp (const char *peerconnection, cc_sdp_t **sdp_pp) -{ - char addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t ipaddr; - unsigned long session_id = 0; - char session_version_str[GSMSDP_VERSION_STR_LEN]; - void *local_sdp_p = NULL; - cc_sdp_t *sdp_p = NULL; - int nat_enable = 0; - char *p_addr_str; - cpr_ip_mode_e ip_mode; - char *strtok_state; - - if (!peerconnection || !sdp_pp) { - return CC_CAUSE_ERROR; - } - - ip_mode = platform_get_ip_address_mode(); - /* - * Get device address. We will need this later. - */ - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - if ((ip_mode == CPR_IP_MODE_DUAL) || (ip_mode == CPR_IP_MODE_IPV6)) { - sip_config_get_net_ipv6_device_ipaddr(&ipaddr); - } else if (ip_mode == CPR_IP_MODE_IPV4) { - sip_config_get_net_device_ipaddr(&ipaddr); - } - } else { - sip_config_get_nat_ipaddr(&ipaddr); - } - - - ipaddr2dotted(addr_str, &ipaddr); - - p_addr_str = PL_strtok_r(addr_str, "[ ]", &strtok_state); - - /* - * Create the local sdp struct - */ - if (*sdp_pp == NULL) { - sipsdp_src_dest_create(peerconnection, - CCSIP_SRC_SDP_BIT, sdp_pp); - } else { - sdp_p = *sdp_pp; - if (sdp_p->src_sdp != NULL) { - sipsdp_src_dest_free(CCSIP_SRC_SDP_BIT, sdp_pp); - } - sipsdp_src_dest_create(peerconnection, - CCSIP_SRC_SDP_BIT, sdp_pp); - } - sdp_p = *sdp_pp; - - if ( sdp_p == NULL ) - return CC_CAUSE_ERROR; - - local_sdp_p = sdp_p->src_sdp; - - /* - * v= line - */ - (void) sdp_set_version(local_sdp_p, SIPSDP_VERSION); - - /* - * o= line - *
- */ - (void) sdp_set_owner_username(local_sdp_p, SIPSDP_ORIGIN_USERNAME); - - session_id = abs(cpr_rand() % 28457); - snprintf(session_version_str, sizeof(session_version_str), "%d", - (int) session_id); - (void) sdp_set_owner_sessionid(local_sdp_p, session_version_str); - - snprintf(session_version_str, sizeof(session_version_str), "%d", 0); - (void) sdp_set_owner_version(local_sdp_p, session_version_str); - - (void) sdp_set_owner_network_type(local_sdp_p, SDP_NT_INTERNET); - - if ((ip_mode == CPR_IP_MODE_DUAL) || (ip_mode == CPR_IP_MODE_IPV6)) { - (void) sdp_set_owner_address_type(local_sdp_p, SDP_AT_IP6); - } else if (ip_mode == CPR_IP_MODE_IPV4) { - (void) sdp_set_owner_address_type(local_sdp_p, SDP_AT_IP4); - } - (void) sdp_set_owner_address(local_sdp_p, p_addr_str); - - /* - * s= line - */ - (void) sdp_set_session_name(local_sdp_p, SIPSDP_SESSION_NAME); - - /* - * t= line - * We init these to zero. If we are building an answer sdp, these will - * be reset from the offer sdp. - */ - (void) sdp_set_time_start(local_sdp_p, "0"); - (void) sdp_set_time_stop(local_sdp_p, "0"); - - return CC_CAUSE_OK; -} - -/** - * The function sets the capabilities from media capability to the - * media structure. - * - * @param[in]media - pointer to the fsmdef_media_t to be set with - * capabilites from the media_cap. - * @param[in]media_cap - media capability to be used with this new media - * line. - * - * @return None. - * - * @pre (media not_eq NULL) - * @pre (media_cap not_eq NULL) - */ -static void -gsmsdp_set_media_capability (fsmdef_media_t *media, - const cc_media_cap_t *media_cap) -{ - /* set default direction */ - media->direction = media_cap->support_direction; - media->support_direction = media_cap->support_direction; - if (media_cap->support_security) { - /* support security */ - FSM_SET_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY); - } -} - -/** - * The function adds a media line into the local SDP. - * - * @param[in]dcb_p - pointer to the fsmdef_dcb_t - * @param[in]media_cap - media capability to be used with this new media - * line. - * @param[in]cap_index - media capability entry index to associate with - * the media line. - * @param[in]level - media line order in the SDP so called level. - * @param[in]addr_type - cpr_ip_type for address of the media line to add. - * - * @return Pointer to the fsmdef_media_t if successfully - * add a new line otherwise return NULL. - * - * @pre (dcb_p not_eq NULL) - * @pre (media_cap not_eq NULL) - */ -static fsmdef_media_t * -gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap, - uint8_t cap_index, uint16_t level, - cpr_ip_type addr_type, boolean offer) -{ - static const char fname[] = "gsmsdp_add_media_line"; - cc_action_data_t data; - fsmdef_media_t *media = NULL; - int i=0; - int rtcpmux = 0; - int sctp_port = 0; - - switch (media_cap->type) { - case SDP_MEDIA_AUDIO: - case SDP_MEDIA_VIDEO: - case SDP_MEDIA_APPLICATION: - media = gsmsdp_get_new_media(dcb_p, media_cap->type, level); - if (media == NULL) { - /* should not happen */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media entry available\n", - dcb_p->line, dcb_p->call_id, fname); - return (NULL); - } - - /* set capabilities */ - gsmsdp_set_media_capability(media, media_cap); - - /* associate this media line to the capability entry */ - media->cap_index = cap_index; /* keep the media cap entry index */ - - /* override the direction for special feature */ - gsmsdp_feature_overide_direction(dcb_p, media); - if (media->support_direction == SDP_DIRECTION_INACTIVE) { - GSM_DEBUG(DEB_L_C_F_PREFIX"feature overrides direction to inactive" - " no media added\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - - /* - * For an answer, SDP_DIRECTION_INACTIVE will now add an m= - * line but it is disabled. - */ - if (!offer) { - media->src_port = 0; - } else { - gsmsdp_remove_media(dcb_p, media); - return (NULL); - } - } - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - /* - * Get the local RTP port. The src port will be set in the dcb - * within the call to cc_call_action(CC_ACTION_OPEN_RCV) - */ - data.open_rcv.is_multicast = FALSE; - data.open_rcv.listen_ip = ip_addr_invalid; - data.open_rcv.port = 0; - data.open_rcv.keep = FALSE; - /* - * Indicate type of media (audio/video etc) becase some for - * supporting video over vieo, the port is obtained from other - * entity. - */ - data.open_rcv.media_type = media->type; - data.open_rcv.media_refid = media->refid; - if (cc_call_action(dcb_p->call_id, dcb_p->line, - CC_ACTION_OPEN_RCV, - &data) != CC_RC_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed\n", - dcb_p->line, dcb_p->call_id, fname); - gsmsdp_remove_media(dcb_p, media); - return (NULL); - } - - /* allocate port successful, save the port */ - - media->src_port = data.open_rcv.port; - - if(media_cap->type == SDP_MEDIA_APPLICATION) { - config_get_value(CFGID_SCTP_PORT, &sctp_port, sizeof(sctp_port)); - media->sctp_port = sctp_port; - } - - /* - * Setup the local soruce address. - */ - if (addr_type == CPR_IP_ADDR_IPV6) { - gsmsdp_get_local_source_v6_address(media); - } else if (addr_type == CPR_IP_ADDR_IPV4) { - gsmsdp_get_local_source_v4_address(media); - } else { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"invalid IP address mode\n", - dcb_p->line, dcb_p->call_id, fname); - gsmsdp_remove_media(dcb_p, media); - return (NULL); - } - - } - - /* - * Initialize the media transport for RTP or SRTP (or do not thing - * and leave to the gsmsdp_update_local_sdp_media to set default) - */ - gsmsdp_init_sdp_media_transport(dcb_p, dcb_p->sdp->src_sdp, media); - - - gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, TRUE, media, - media->transport); - - if (media->support_direction != SDP_DIRECTION_INACTIVE) { - - gsmsdp_set_local_sdp_direction(dcb_p, media, media->direction); - - /* - * wait until here to set ICE candidates as SDP is now initialized - */ - for (i=0; icandidate_ct; i++) { - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, dcb_p->sdp->src_sdp, media->candidatesp[i]); - } - - config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux)); - if (rtcpmux) { - gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, level, dcb_p->sdp->src_sdp, TRUE); - } - - - /* - * Since we are initiating an initial offer and opening a - * receive port, store initial media settings. - */ - media->previous_sdp.avt_payload_type = media->avt_payload_type; - media->previous_sdp.direction = media->direction; - media->previous_sdp.packetization_period = media->packetization_period; - gsmsdp_copy_payloads_to_previous_sdp(media); - break; - } - - default: - /* Unsupported media type, not added */ - GSM_DEBUG(DEB_L_C_F_PREFIX"media type %d is not supported\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), media_cap->type); - break; - } - return (media); -} - -/* - * gsmsdp_create_local_sdp - * - * Description: - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose local SDP is to be updated. - * force_streams_enabled - temporarily generate SDP even when no - * streams are added - * - * returns cc_causes_t - * CC_CAUSE_OK - indicates success - * CC_CAUSE_ERROR - indicates failure - */ -cc_causes_t -gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled, - boolean audio, boolean video, boolean data, boolean offer) -{ - static const char fname[] = "gsmsdp_create_local_sdp"; - uint16_t level; - const cc_media_cap_table_t *media_cap_tbl; - const cc_media_cap_t *media_cap; - cpr_ip_mode_e ip_mode; - uint8_t cap_index; - fsmdef_media_t *media; - boolean has_audio; - int sdpmode = 0; - boolean media_enabled; - - if ( CC_CAUSE_OK != gsmsdp_init_local_sdp(dcb_p->peerconnection, - &(dcb_p->sdp)) ) - return CC_CAUSE_ERROR; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - dcb_p->src_sdp_version = 0; - - media_cap_tbl = dcb_p->media_cap_tbl; - - if (media_cap_tbl == NULL) { - /* should not happen */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capbility available\n", - dcb_p->line, dcb_p->call_id, fname); - return (CC_CAUSE_ERROR); - } - - media_cap = &media_cap_tbl->cap[0]; - level = 0; - for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP-1; cap_index++) { - - /* Build local m lines based on m lines that were in the offered SDP */ - media_enabled = TRUE; - if (FALSE == audio && SDP_MEDIA_AUDIO == media_cap->type) { - media_enabled = FALSE; - } else if (FALSE == video && SDP_MEDIA_VIDEO == media_cap->type) { - media_enabled = FALSE; - } else if (FALSE == data && SDP_MEDIA_APPLICATION == media_cap->type) { - media_enabled = FALSE; - } - - /* - * Add each enabled media line to the SDP - */ - if (media_enabled && ( media_cap->enabled || force_streams_enabled)) { - level = level + 1; /* next level */ - ip_mode = platform_get_ip_address_mode(); - if (ip_mode >= CPR_IP_MODE_IPV6) { - if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, - level, CPR_IP_ADDR_IPV6, offer) - == NULL) { - /* fail to add a media line, go back one level */ - level = level - 1; - } - - if (ip_mode == CPR_IP_MODE_DUAL) { - level = level + 1; /* next level */ - if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, - level, CPR_IP_ADDR_IPV4, offer) == - NULL) { - /* fail to add a media line, go back one level */ - level = level - 1; - } - } - } else { - if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, level, - CPR_IP_ADDR_IPV4, offer) == NULL) { - /* fail to add a media line, go back one level */ - level = level - 1; - } - } - } - /* next capability */ - media_cap++; - } - - if (level == 0) { - /* - * Did not find media line for the SDP and we do not - * support SDP without any media line. - */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media line for SDP\n", - dcb_p->line, dcb_p->call_id, fname); - return (CC_CAUSE_ERROR); - } - - /* - * - * This is a suitable place to add ice ufrag and pwd to the SDP - */ - - if (dcb_p->ice_ufrag) - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_UFRAG, SDP_SESSION_LEVEL, dcb_p->sdp->src_sdp, dcb_p->ice_ufrag); - if (dcb_p->ice_pwd) - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_PWD, SDP_SESSION_LEVEL, dcb_p->sdp->src_sdp, dcb_p->ice_pwd); - - if(strlen(dcb_p->digest_alg) > 0) - gsmsdp_set_dtls_fingerprint_attribute (SDP_ATTR_DTLS_FINGERPRINT, SDP_SESSION_LEVEL, - dcb_p->sdp->src_sdp, dcb_p->digest_alg, dcb_p->digest); - - if (!sdpmode) { - - /* - * Ensure that there is at least one audio line. - */ - has_audio = FALSE; - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->type == SDP_MEDIA_AUDIO) { - has_audio = TRUE; /* found one audio line, done */ - break; - } - } - if (!has_audio) { - /* No audio, do not allow */ - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no audio media line for SDP\n", - dcb_p->line, dcb_p->call_id, fname); - return (CC_CAUSE_ERROR); - } - } - - return CC_CAUSE_OK; -} - -/** - * The function creates a SDP that contains phone's current - * capability for an option. - * - * @param[in/out]sdp_pp - pointer to a pointer to cc_sdp_t to return - * the created SDP. - * @return none. - * @pre (sdp_pp not_eq NULL) - */ -void -gsmsdp_create_options_sdp (cc_sdp_t ** sdp_pp) -{ - cc_sdp_t *sdp_p; - - /* This empty string represents to associated peerconnection object */ - if (gsmsdp_init_local_sdp("", sdp_pp) == CC_CAUSE_ERROR) { - return; - } - - sdp_p = *sdp_pp; - - /* - * Insert media line at level 1. - */ - if (sdp_insert_media_line(sdp_p->src_sdp, 1) != SDP_SUCCESS) { - // Error - return; - } - - (void) sdp_set_media_type(sdp_p->src_sdp, 1, SDP_MEDIA_AUDIO); - (void) sdp_set_media_portnum(sdp_p->src_sdp, 1, 0, 0); - gsmsdp_set_media_transport_for_option(sdp_p->src_sdp, 1); - - /* - * Add all supported media formats to the local sdp. - */ - gsmsdp_add_default_audio_formats_to_local_sdp(NULL, sdp_p, NULL); - - /* Add Video m line if video caps are enabled */ - if ( g_media_table.cap[CC_VIDEO_1].enabled == TRUE ) { - if (sdp_insert_media_line(sdp_p->src_sdp, 2) != SDP_SUCCESS) { - // Error - return; - } - - (void) sdp_set_media_type(sdp_p->src_sdp, 2, SDP_MEDIA_VIDEO); - (void) sdp_set_media_portnum(sdp_p->src_sdp, 2, 0, 0); - gsmsdp_set_media_transport_for_option(sdp_p->src_sdp, 2); - - gsmsdp_add_default_video_formats_to_local_sdp(NULL, sdp_p, NULL); - } -} - -/** - * The function checks and removes media capability for the media - * lines that is to be removed. - * - * @param[in]dcb_p - Pointer to DCB - * - * @return TRUE - if there is a media line removed. - * FALSE - if there is no media line to remove. - * - * @pre (dcb_p not_eq NULL) - */ -static boolean -gsmsdp_check_remove_local_sdp_media (fsmdef_dcb_t *dcb_p) -{ - static const char fname[] = "gsmsdp_check_remove_local_sdp_media"; - fsmdef_media_t *media, *media_to_remove; - const cc_media_cap_t *media_cap; - boolean removed = FALSE; - - media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - while (media) { - media_cap = gsmsdp_get_media_cap_entry_by_index(media->cap_index,dcb_p); - if (media_cap != NULL) { - /* found the corresponding capability of the media line */ - if (!media_cap->enabled) { - GSM_DEBUG(DEB_L_C_F_PREFIX"remove media at level %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), media->level); - /* set the media line to unused */ - gsmsdp_add_unsupported_stream_to_local_sdp(dcb_p->sdp, - media->level); - /* - * remember the media to remove and get the next media to - * work on before removing this media off the linked list. - */ - media_to_remove = media; - media = GSMSDP_NEXT_MEDIA_ENTRY(media); - - /* remove the media from the list */ - gsmsdp_remove_media(dcb_p, media_to_remove); - removed = TRUE; - continue; - } - } - media = GSMSDP_NEXT_MEDIA_ENTRY(media); - } - return (removed); -} - -/** - * The function checks and adds media capability for the media - * lines that is to be added. - * - * @param[in]dcb_p - Pointer to DCB - * @param[in]hold - TRUE indicates the newly media line - * should have direction that indicates hold. - * - * @return TRUE - if there is a media line added. - * FALSE - if there is no media line to added. - * - * @pre (dcb_p not_eq NULL) - */ -static boolean -gsmsdp_check_add_local_sdp_media (fsmdef_dcb_t *dcb_p, boolean hold) -{ - static const char fname[] = "gsmsdp_check_add_local_sdp_media"; - fsmdef_media_t *media; - const cc_media_cap_t *media_cap; - uint8_t cap_index; - uint16_t num_m_lines, level_to_use; - void *src_sdp; - boolean need_mix = FALSE; - boolean added = FALSE; - cpr_ip_mode_e ip_mode; - cpr_ip_type ip_addr_type[2]; /* for 2 IP address types */ - uint16_t i, num_ip_addrs; - - if (fsmcnf_get_ccb_by_call_id(dcb_p->call_id) != NULL) { - /* - * This call is part of a local conference. The mixing - * support will be needed for additional media line. - * If platform does not have capability to support mixing - * of a particular media type for the local conference, either - * leg in the conference will not see addition media line - * added. - */ - need_mix = TRUE; - } - - /* - * Find new media entries to be added. - */ - src_sdp = dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL; - for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP; cap_index++) { - media_cap = gsmsdp_get_media_cap_entry_by_index(cap_index, dcb_p); - if (media_cap == NULL) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capbility available\n", - dcb_p->line, dcb_p->call_id, fname); - continue; - } - if (!media_cap->enabled) { - /* this entry is disabled, skip it */ - continue; - } - media = gsmsdp_find_media_by_cap_index(dcb_p, cap_index); - if (media != NULL) { - /* this media entry exists, skip it */ - continue; - } - - /* - * This is a new entry the capability table to be added. - */ - if (CC_IS_AUDIO(cap_index) && need_mix) { - if (!gsmsdp_platform_addition_mix(dcb_p, media_cap->type)) { - /* platform can not support additional mixing of this type */ - GSM_DEBUG(DEB_L_C_F_PREFIX"no support addition mixing for %d " - "media type\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - media_cap->type); - continue; - } - } - - /* - * It depends on current address mode, if the mode is dual mode then - * we need to add 2 media lines. - */ - ip_mode = platform_get_ip_address_mode(); - switch (ip_mode) { - case CPR_IP_MODE_DUAL: - /* add both addresses, IPV6 line is first as it is prefered */ - num_ip_addrs = 2; - ip_addr_type[0] = CPR_IP_ADDR_IPV6; - ip_addr_type[1] = CPR_IP_ADDR_IPV4; - break; - case CPR_IP_MODE_IPV6: - /* add IPV6 address only */ - num_ip_addrs = 1; - ip_addr_type[0] = CPR_IP_ADDR_IPV6; - break; - default: - /* add IPV4 address only */ - num_ip_addrs = 1; - ip_addr_type[0] = CPR_IP_ADDR_IPV4; - break; - } - /* add media line or lines */ - for (i = 0; i < num_ip_addrs; i++) { - /* - * This is a new stream to add, find an unused media line - * in the SDP. Find the unused media line that has the same - * media type as the one to be added. The RFC-3264 allows reuse - * any unused slot in the SDP body but it was recomended to use - * the same type to increase the chance of interoperability by - * using the unuse slot that has the same media type. - */ - level_to_use = gsmsdp_find_unused_media_line_with_type(src_sdp, - media_cap->type); - if (level_to_use == 0) { - /* no empty slot is found, add a new line to the SDP */ - num_m_lines = sdp_get_num_media_lines(src_sdp); - level_to_use = num_m_lines + 1; - } - GSM_DEBUG(DEB_L_C_F_PREFIX"add media at level %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), level_to_use); - - /* add a new media */ - media = gsmsdp_add_media_line(dcb_p, media_cap, cap_index, - level_to_use, ip_addr_type[i], FALSE); - if (media != NULL) { - /* successfully add a new media line */ - if (hold) { - /* this new media needs to be sent out with hold */ - gsmsdp_set_local_hold_sdp(dcb_p, media); - } - added = TRUE; - } else { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"Unable to add a new media\n", - dcb_p->line, dcb_p->call_id, fname); - } - } - } - return (added); -} - -/** - * The function checks support direction changes and updates the support - * direction of media lines. - * - * @param[in]dcb_p - Pointer to DCB - * @param[in]no_sdp_update - TRUE indicates do not update SDP. - * - * @return TRUE - if there is a media line support direction - * changes. - * FALSE - if there is no media line that has - * support direction change. - * - * @pre (dcb_p not_eq NULL) - */ -static boolean -gsmsdp_check_direction_change_local_sdp_media (fsmdef_dcb_t *dcb_p, - boolean no_sdp_update) -{ - static const char fname[] = "gsmsdp_check_direction_change_local_sdp_media"; - fsmdef_media_t *media; - const cc_media_cap_t *media_cap; - boolean direction_change = FALSE; - sdp_direction_e save_supported_direction; - - media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - while (media) { - media_cap = gsmsdp_get_media_cap_entry_by_index(media->cap_index, dcb_p); - if (media_cap != NULL) { - if (media->support_direction != - media_cap->support_direction) { - /* - * There is a possibility that supported direction has - * been overrided due to some feature. Check to see - * the supported direction remains the same after override - * take place. If it is different then there is a direction - * change. - */ - save_supported_direction = media->support_direction; - media->support_direction = media_cap->support_direction; - gsmsdp_feature_overide_direction(dcb_p, media); - if (media->support_direction == save_supported_direction) { - /* nothing change after override */ - } else { - /* there is no override, this is a change */ - direction_change = TRUE; - } - if (direction_change) { - /* Support direction changed */ - GSM_DEBUG(DEB_L_C_F_PREFIX"change support direction at level %d" - " from %d to %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), - media->level, media->support_direction, - media_cap->support_direction); - if (no_sdp_update) { - /* - * The caller does not want to update SDP. - */ - media->direction = media_cap->support_direction; - } else { - /* - * Need to update direction in the SDP. - * The direction in the media structure will - * be set by the gsmsdp_set_local_sdp_direction. - */ - gsmsdp_set_local_sdp_direction(dcb_p, media, - media->support_direction); - } - } - } - } - media = GSMSDP_NEXT_MEDIA_ENTRY(media); - } - return (direction_change); -} - -/** - * The function resets media specified takes the hold state into account - * - * @param[in]dcb_p - Pointer to DCB - * @param[in]media - Media to be updated - * @param[in]hold - Set media line will be set to hold. - */ -static void gsmsdp_reset_media(fsmdef_dcb_t *dcb_p, fsmdef_media_t *media, boolean hold){ - gsmsdp_reset_local_sdp_media(dcb_p, media, hold); - if (hold) { - gsmsdp_set_local_hold_sdp(dcb_p, media); - } else { - gsmsdp_set_local_resume_sdp(dcb_p, media); - } -} - -/** - * - * This functions checks if the media IP Address has changed - * - * Convert the configMedia IP String to Ip address format, - * check if it is valid and then compare to current media source - * address, if the address is valid and the media source and - * config media ip differ, then - * - * 1) Stop the media to close the socket - * 2) Set flag to true, to initiate re-invite - * 3) Update the media src addr - * 4) Update the c= line to reflect the new IP address source - * - * @param[in]dcb_p - Pointer to DCB - * @return TRUE - if IP changed - * FALSE - if no no IP changed - * - * @pre (dcb_p not_eq NULL) - */ -boolean -gsmsdp_media_ip_changed (fsmdef_dcb_t *dcb_p) -{ - static const char fname[] = "gsmsdp_media_ip_changed"; - boolean ip_changed = FALSE; - cpr_ip_addr_t addr ; - char curr_media_ip[MAX_IPADDR_STR_LEN]; - char addr_str[MAX_IPADDR_STR_LEN]; - fsmdef_media_t *media; - - /* - * Check if media IP has changed - */ - init_empty_str(curr_media_ip); - config_get_value(CFGID_MEDIA_IP_ADDR, curr_media_ip, - MAX_IPADDR_STR_LEN); - if (!is_empty_str(curr_media_ip)) { - str2ip(curr_media_ip, &addr); - util_ntohl(&addr, &addr); - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if ((util_check_if_ip_valid(&media->src_addr) == TRUE) && - (util_check_if_ip_valid(&addr) == TRUE) && - (util_compare_ip(&media->src_addr, &addr) == FALSE)) { - ipaddr2dotted(curr_media_ip, &media->src_addr); // for logging - - (void)cc_call_action(dcb_p->call_id, dcb_p->line, - CC_ACTION_STOP_MEDIA, - NULL); - ip_changed = TRUE; - media->src_addr = addr; - if (dcb_p->sdp != NULL) { - gsmsdp_set_connection_address(dcb_p->sdp->src_sdp, - media->level, - dcb_p->ice_default_candidate_addr); - } - ipaddr2dotted(addr_str, &media->src_addr); // for logging - GSM_ERR_MSG("%s MEDIA IP_CHANGED: after Update IP %s"\ - " before %s" ,fname, addr_str, curr_media_ip ); - } - } - } - - return (ip_changed); -} - -/** - * this function will check whether the media ip addres in local sdp is same as to - * media IP provided by application. If IP differs, then re-INVITE request is posted. - */ -boolean is_gsmsdp_media_ip_updated_to_latest( fsmdef_dcb_t * dcb ) { - cpr_ip_addr_t media_ip_in_host_order ; - char curr_media_ip[MAX_IPADDR_STR_LEN]; - fsmdef_media_t *media; - - init_empty_str(curr_media_ip); - config_get_value(CFGID_MEDIA_IP_ADDR, curr_media_ip, MAX_IPADDR_STR_LEN); - if (is_empty_str(curr_media_ip) == FALSE) { - str2ip(curr_media_ip, &media_ip_in_host_order); - util_ntohl(&media_ip_in_host_order, &media_ip_in_host_order); - - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (util_check_if_ip_valid(&media->src_addr) == TRUE) { - if (util_compare_ip(&media->src_addr, &media_ip_in_host_order) == FALSE) { - return FALSE; - } - } - } - } - return TRUE; -} - - -/** - * - * The function checks for media capability changes and updates the - * local SDP for the changes. The function also provides a couple of options - * 1) reset the unchange media lines to initialize the codec list, - * crypto etc. and 2) an option to update media directions for all - * media lines for hold. 3) - * - * @param[in]dcb_p - Pointer to DCB - * @param[in]reset - Reset the unchanged media lines to include all - * codecs etc. again. - * @param[in]hold - Set media line will be set to hold. - * - * @return TRUE - if media changes occur. - * FALSE - if no media change occur. - * - * @pre (dcb_p not_eq NULL) - */ -boolean -gsmsdp_update_local_sdp_media_capability (fsmdef_dcb_t *dcb_p, boolean reset, - boolean hold) -{ - static const char fname[] = "gsmsdp_update_local_sdp_media_capability"; - fsmdef_media_t *media; - boolean change_found = FALSE; - boolean check_for_change = FALSE; - - change_found = gsmsdp_media_ip_changed(dcb_p); - - /* - * check to see if media capability table has changed, by checking - * the ID. - */ - if ((g_media_table.id != dcb_p->media_cap_tbl->id) || reset) { - - /* - * capabilty table ID different or we are doing a reset for - * the full offer again, need to check for various changes. - * Update capabilities to match platform caps - */ - check_for_change = TRUE; - } - - /* - * Find any capability changes. The changes allowed are: - * 1) media entry is disabled (to be removed). - * 2) supported direction change. - * 3) new media entry is enabled (to be added) keep it the last one. - * - * Find a media to be removed first so that if there is another - * media line to add then there might be an unused a media line in the - * SDP to use. - */ - if (check_for_change && gsmsdp_check_remove_local_sdp_media(dcb_p)) { - /* there were some media lines removed */ - change_found = TRUE; - } - - /* - * Find media lines that may have direction changes - */ - if ( check_for_change && - gsmsdp_check_direction_change_local_sdp_media(dcb_p, reset)) { - /* there were media lines that directions changes */ - change_found = TRUE; - } - - /* - * Reset all the existing media lines to have full codec etc. - * again if the caller requested. - */ - if (reset) { - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - gsmsdp_reset_media(dcb_p, media, hold); - } - } - - /* - * Find new media entries to be added. - */ - if ( check_for_change && gsmsdp_check_add_local_sdp_media(dcb_p, hold)) { - change_found = TRUE; - } - - if (change_found) { - GSM_DEBUG(DEB_L_C_F_PREFIX"media capability change found \n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - - - /* report back any changes made */ - return (change_found); -} - -/* - * gsmsdp_reset_local_sdp_media - * - * Description: - * - * This function initializes the media portion of the local sdp. The following - * lines are initialized. - * - * m= line - * a= session level line - * - * Parameters: - * - * dcb_p - Pointer to DCB whose local SDP media is to be initialized - * media - Pointer to fsmdef_media_t for the media entry of the SDP. - * If the value is NULL, it indicates all medie entries i the - * dcb is reset. - * hold - Boolean indicating if SDP is being initialized for sending hold - * - */ -void -gsmsdp_reset_local_sdp_media (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media, - boolean hold) -{ - fsmdef_media_t *start_media, *end_media; - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - - /* - * Reset media transport in preparation for hold or resume. - * It is possible that transport media may - * change from the current media transport (for SRTP re-offer - * to a different end point). - */ - gsmsdp_reset_sdp_media_transport(dcb_p, dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL, - media, hold); - - gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, TRUE, media, - media->transport); - - - /* - * a= line - * If hold is being signaled, do not alter the media direction. This - * will be taken care of by the state machine handler function. - */ - if (!hold) { - /* - * We are not locally held, set direction to the supported - * direction. - */ - gsmsdp_set_local_sdp_direction(dcb_p, media, - media->support_direction); - } - } -} - -/* - * gsmsdp_set_local_hold_sdp - * - * Description: - * - * Manipulates the local SDP of the specified DCB to indicate hold - * to the far end. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose SDP is to be manipulated. - * media - Pointer to the fsmdef_media_t for the current media entry. - * If the value is NULL, it indicates all medie entries i the - * dcb is reset. - */ -void -gsmsdp_set_local_hold_sdp (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - int old_style_hold = 0; - fsmdef_media_t *start_media, *end_media; - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - /* - * Check if configuration indicates that the old style hold should be - * signaled per RFC 2543. That is, c=0.0.0.0. Although - * 2543 does not speak to the SDP direction attribute, we set - * the direction to INACTIVE to be consistent with the connection - * address setting. - */ - config_get_value(CFGID_2543_HOLD, &old_style_hold, - sizeof(old_style_hold)); - if (old_style_hold) { - gsmsdp_set_2543_hold_sdp(dcb_p, media->level); - gsmsdp_set_local_sdp_direction(dcb_p, media, - SDP_DIRECTION_INACTIVE); - } else { - /* - * RFC3264 states that hold is signaled by setting the media - * direction attribute to SENDONLY if in SENDRECV mode. - * INACTIVE if RECVONLY mode (mutual hold). - */ - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_SENDONLY) { - gsmsdp_set_local_sdp_direction(dcb_p, media, - SDP_DIRECTION_SENDONLY); - } else { - gsmsdp_set_local_sdp_direction(dcb_p, media, - SDP_DIRECTION_INACTIVE); - } - } - } -} - -/* - * gsmsdp_set_local_resume_sdp - * - * Description: - * - * Manipulates the local SDP of the specified DCB to indicate hold - * to the far end. - * - * Parameters: - * - * dcb_p - Pointer to the DCB whose SDP is to be manipulated. - * media - Pointer to the fsmdef_media_t for the current media entry. - * - */ -void -gsmsdp_set_local_resume_sdp (fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) -{ - fsmdef_media_t *start_media, *end_media; - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb_p); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - /* - * We are not locally held, set direction to the supported - * direction. - */ - gsmsdp_set_local_sdp_direction(dcb_p, media, media->support_direction); - } -} - -/* - * gsmsdp_encode_sdp - * - * Description: - * The function encodes SDP from the internal SDP representation - * to the SDP body to be sent out. - * - * Parameters: - * sdp_p - pointer to the internal SDP info. block. - * msg_body - pointer to the msg body info. block. - * - * Returns: - * cc_causes_t to indicate failure or success. - */ -cc_causes_t -gsmsdp_encode_sdp (cc_sdp_t *sdp_p, cc_msgbody_info_t *msg_body) -{ - char *sdp_body; - cc_msgbody_t *part; - uint32_t body_length; - - if (msg_body == NULL) { - return CC_CAUSE_ERROR; - } - - /* Support single SDP encoding for now */ - sdp_body = sipsdp_write_to_buf(sdp_p, &body_length); - - if (sdp_body == NULL) { - return CC_CAUSE_ERROR; - } else if (body_length == 0) { - cpr_free(sdp_body); - return CC_CAUSE_ERROR; - } - - /* Clear off the bodies info */ - cc_initialize_msg_body_parts_info(msg_body); - - /* Set up for one SDP entry */ - msg_body->num_parts = 1; - msg_body->content_type = cc_content_type_SDP; - part = &msg_body->parts[0]; - part->body = sdp_body; - part->body_length = body_length; - part->content_type = cc_content_type_SDP; - part->content_disposition.required_handling = FALSE; - part->content_disposition.disposition = cc_disposition_session; - part->content_id = NULL; - return CC_CAUSE_OK; -} - -/* - * gsmsdp_encode_sdp_and_update_version - * - * Description: - * The function encodes SDP from the internal SDP representation - * to the SDP body to be sent out. It also post-increments the owner - * version number to prepare for the next SDP to be sent out. - * - * Parameters: - * sdp_p - pointer to DCB whose local SDP is to be encoded. - * msg_body - pointer to the msg body info. block. - * - * Returns: - * cc_causes_t to indicate failure or success. - */ -cc_causes_t -gsmsdp_encode_sdp_and_update_version (fsmdef_dcb_t *dcb_p, cc_msgbody_info_t *msg_body) -{ - char version_str[GSMSDP_VERSION_STR_LEN]; - - snprintf(version_str, sizeof(version_str), "%d", dcb_p->src_sdp_version); - - if ( dcb_p->sdp == NULL || dcb_p->sdp->src_sdp == NULL ) - { - if ( CC_CAUSE_OK != gsmsdp_init_local_sdp(dcb_p->peerconnection, - &(dcb_p->sdp)) ) - { - return CC_CAUSE_ERROR; - } - } - (void) sdp_set_owner_version(dcb_p->sdp->src_sdp, version_str); - - if (gsmsdp_encode_sdp(dcb_p->sdp, msg_body) != CC_CAUSE_OK) { - return CC_CAUSE_ERROR; - } - - dcb_p->src_sdp_version++; - return CC_CAUSE_OK; -} - -/* - * gsmsdp_get_sdp - * - * Description: - * The function searches the SDP from the the all of msg. body parts. - * All body parts having the content type SDP will be stored at the - * given destination arrays. The number of SDP body are returned to - * indicate the number of SDP bodies found. The function searches - * the msg body in backward to order to form SDP in the destination array - * to be from the highest to the lowest preferences. - * - * Parameters: - * msg_body - pointer to the incoming message body or cc_msgbody_info_t. - * part_array - pointer to pointer of cc_msgbody_t to store the - * sorted order of the incoming SDP. - * max_part - the maximum number of SDP can be written to the - * part_array or the part_array size. - * Returns: - * The number of SDP parts found. - */ -static uint32_t -gsmsdp_get_sdp_body (cc_msgbody_info_t *msg_body, - cc_msgbody_t **part_array, - uint32_t max_parts) -{ - uint32_t i, count; - cc_msgbody_t *part; - - if ((msg_body == NULL) || (msg_body->num_parts == 0)) { - /* No msg. body or no body parts in the msg. */ - return (0); - } - /* - * Extract backward. The SDP are sent from the lowest - * preference to the highest preference. The highest - * preference will be extracted first into the given array - * so that when we negotiate, the SDP we will attempt to - * negotiate from the remote's highest to the lowest - * preferences. - */ - count = 0; - part = &msg_body->parts[msg_body->num_parts - 1]; - for (i = 0; (i < msg_body->num_parts) && (i < max_parts); i++) { - if (part->content_type == cc_content_type_SDP) { - /* Found an SDP, keep the pointer to the part */ - *part_array = part; /* save pointer to SDP entry */ - part_array++; /* next entry */ - count++; - } - /* next one backward */ - part--; - } - /* return the number of SDP bodies found */ - return (count); -} - -/* - * gsmsdp_realloc_dest_sdp - * - * Description: - * The function re-allocates the internal SDP info. block for the - * remote or destination SDP. If there the SDP info. or the - * SDP block does not exist, the new one is allocated. If SDP block - * exists, the current one is released and is replaced by a new one. - * - * Parameters: - * dcb_p - pointer to fsmdef_dcb_t. - * - * Returns: - * cc_causes_t to indicate failure or success. - */ -static cc_causes_t -gsmsdp_realloc_dest_sdp (fsmdef_dcb_t *dcb_p) -{ - /* There are SDPs to process, prepare for parsing the SDP */ - if (dcb_p->sdp == NULL) { - /* Create internal SDP information block with dest sdp block */ - sipsdp_src_dest_create(dcb_p->peerconnection, - CCSIP_DEST_SDP_BIT, &dcb_p->sdp); - } else { - /* - * SDP info. block exists, remove the previously received - * remote or destination SDP and create a new one for - * the new SDP. - */ - if (dcb_p->sdp->dest_sdp) { - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT, &dcb_p->sdp); - } - sipsdp_src_dest_create(dcb_p->peerconnection, - CCSIP_DEST_SDP_BIT, &dcb_p->sdp); - } - - /* No SDP info block and parsed control block are available */ - if ((dcb_p->sdp == NULL) || (dcb_p->sdp->dest_sdp == NULL)) { - /* Unable to create internal SDP structure to parse SDP. */ - return CC_CAUSE_ERROR; - } - return CC_CAUSE_OK; -} - -/* - * gsmsdp_negotiate_answer_sdp - * - * Description: - * - * Interface function used to negotiate an ANSWER SDP. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing the DCB whose local SDP is being negotiated. - * msg_body - Pointer to the cc_msgbody_info_t that contain the remote - * - */ -cc_causes_t -gsmsdp_negotiate_answer_sdp (fsm_fcb_t *fcb_p, cc_msgbody_info_t *msg_body) -{ - static const char fname[] = "gsmsdp_negotiate_answer_sdp"; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - cc_msgbody_t *sdp_bodies[CC_MAX_BODY_PARTS]; - uint32_t i, num_sdp_bodies; - cc_causes_t status; - char *sdp_body; - - /* Get just the SDP bodies */ - num_sdp_bodies = gsmsdp_get_sdp_body(msg_body, &sdp_bodies[0], - CC_MAX_BODY_PARTS); - GSM_DEBUG(DEB_F_PREFIX"\n",DEB_F_PREFIX_ARGS(GSM, fname)); - if (num_sdp_bodies == 0) { - /* - * Clear the call - we don't have any remote SDP info! - */ - return CC_CAUSE_ERROR; - } - - /* There are SDPs to process, prepare for parsing the SDP */ - if (gsmsdp_realloc_dest_sdp(dcb_p) != CC_CAUSE_OK) { - /* Unable to create internal SDP structure to parse SDP. */ - return CC_CAUSE_ERROR; - } - - /* - * Parse the SDP into internal structure, - * now just parse one - */ - status = CC_CAUSE_ERROR; - for (i = 0; (i < num_sdp_bodies); i++) { - if ((sdp_bodies[i]->body != NULL) && (sdp_bodies[i]->body_length > 0)) { - /* Found a body */ - sdp_body = sdp_bodies[i]->body; - if (sdp_parse(dcb_p->sdp->dest_sdp, &sdp_body, - (uint16_t)sdp_bodies[i]->body_length) - == SDP_SUCCESS) { - status = CC_CAUSE_OK; - break; - } - } - } - if (status != CC_CAUSE_OK) { - /* Error parsing SDP */ - return status; - } - - gsmsdp_set_remote_sdp(dcb_p, dcb_p->sdp); - - status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, FALSE, FALSE, TRUE, TRUE); - GSM_DEBUG(DEB_F_PREFIX"returns with %d\n",DEB_F_PREFIX_ARGS(GSM, fname), status); - return (status); -} - - - - -/* - * gsmsdp_negotiate_offer_sdp - * - * Description: - * - * Interface function used to negotiate an OFFER SDP. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing the DCB whose local SDP is being negotiated. - * msg_body - Pointer to remote SDP body infostructure. - * init - Boolean indicating if the local SDP should be initialized as if this is the - * first local SDP of this session. - * - */ -cc_causes_t -gsmsdp_negotiate_offer_sdp (fsm_fcb_t *fcb_p, - cc_msgbody_info_t *msg_body, boolean init) -{ - cc_causes_t status; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - - status = gsmsdp_process_offer_sdp(fcb_p, msg_body, init); - if (status != CC_CAUSE_OK) - return status; - - /* - * If a new error code has been added to sdp processing please make sure - * the sip side is aware of it - */ - status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, init, TRUE, FALSE, FALSE); - return (status); -} - - -/* - * gsmsdp_process_offer_sdp - * - * Description: - * - * Interface function used to process an OFFER SDP. - * Does not negotiate. - * - * Parameters: - * - * fcb_p - Pointer to the FCB containing the DCB whose local SDP is being negotiated. - * msg_body - Pointer to remote SDP body infostructure. - * init - Boolean indicating if the local SDP should be initialized as if this is the - * first local SDP of this session. - * - */ -cc_causes_t -gsmsdp_process_offer_sdp (fsm_fcb_t *fcb_p, - cc_msgbody_info_t *msg_body, boolean init) -{ - static const char fname[] = "gsmsdp_process_offer_sdp"; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - cc_causes_t status; - cc_msgbody_t *sdp_bodies[CC_MAX_BODY_PARTS]; - uint32_t i, num_sdp_bodies; - char *sdp_body; - - /* Get just the SDP bodies */ - num_sdp_bodies = gsmsdp_get_sdp_body(msg_body, &sdp_bodies[0], - CC_MAX_BODY_PARTS); - GSM_DEBUG(DEB_L_C_F_PREFIX"Init is %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), init); - if (num_sdp_bodies == 0) { - /* - * No remote SDP. So we will offer in our response and receive far end - * answer in the ack. Only need to create local sdp if this is first offer - * of a session. Otherwise, we will send what we have. - */ - if (init) { - if ( CC_CAUSE_OK != gsmsdp_create_local_sdp(dcb_p, FALSE, TRUE, TRUE, TRUE, TRUE)) { - return CC_CAUSE_ERROR; - } - } else { - /* - * Reset all media entries that we have to offer all capabilities - */ - (void)gsmsdp_update_local_sdp_media_capability(dcb_p, TRUE, FALSE); - } - dcb_p->remote_sdp_in_ack = TRUE; - return CC_CAUSE_OK; - } - - /* There are SDPs to process, prepare for parsing the SDP */ - if (gsmsdp_realloc_dest_sdp(dcb_p) != CC_CAUSE_OK) { - /* Unable to create internal SDP structure to parse SDP. */ - return CC_CAUSE_ERROR; - } - - /* - * Parse the SDP into internal structure, - * now just parse one - */ - status = CC_CAUSE_ERROR; - for (i = 0; (i < num_sdp_bodies); i++) { - if ((sdp_bodies[i]->body != NULL) && (sdp_bodies[i]->body_length > 0)) { - /* Found a body */ - sdp_body = sdp_bodies[i]->body; - if (sdp_parse(dcb_p->sdp->dest_sdp, &sdp_body, - (uint16_t)sdp_bodies[i]->body_length) - == SDP_SUCCESS) { - status = CC_CAUSE_OK; - break; - } - } - } - if (status != CC_CAUSE_OK) { - /* Error parsing SDP */ - return status; - } - - if (init) { - (void)gsmsdp_init_local_sdp(dcb_p->peerconnection, &(dcb_p->sdp)); - /* Note that there should not a previous version here as well */ - } - - gsmsdp_set_remote_sdp(dcb_p, dcb_p->sdp); - - return (status); -} - -/* - * gsmsdp_install_peer_ice_attributes - * - * Read ICE parameters from the SDP and set them into - * the ice engine. Check SESSION_LEVEL first then each media line. - * - * fcb_p - pointer to the fcb - * - */ -cc_causes_t -gsmsdp_install_peer_ice_attributes(fsm_fcb_t *fcb_p) -{ - char *ufrag; - char *pwd; - char **candidates; - int candidate_ct; - sdp_result_e sdp_res; - short vcm_res; - fsmdef_dcb_t *dcb_p = fcb_p->dcb; - cc_sdp_t *sdp_p = dcb_p->sdp; - fsmdef_media_t *media; - // int level; - short result; - - /* Tolerate missing ufrag/pwd here at the session level - because it might be at the media level */ - sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, - SDP_ATTR_ICE_UFRAG, 1, &ufrag); - if (sdp_res != SDP_SUCCESS) - ufrag = NULL; - - sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, SDP_SESSION_LEVEL, 0, - SDP_ATTR_ICE_PWD, 1, &pwd); - if (sdp_res != SDP_SUCCESS) - pwd = NULL; - - if (ufrag && pwd) { - vcm_res = vcmSetIceSessionParams(dcb_p->peerconnection, ufrag, pwd); - if (vcm_res) - return (CC_CAUSE_ERROR); - } - - /* Now process all the media lines */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) - continue; - - sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, media->level, 0, - SDP_ATTR_ICE_UFRAG, 1, &ufrag); - if (sdp_res != SDP_SUCCESS) - ufrag = NULL; - - sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, media->level, 0, - SDP_ATTR_ICE_PWD, 1, &pwd); - if (sdp_res != SDP_SUCCESS) - pwd = NULL; - - candidate_ct = 0; - candidates = NULL; - result = gsmsdp_get_ice_attributes (SDP_ATTR_ICE_CANDIDATE, media->level, sdp_p->dest_sdp, - &candidates, &candidate_ct); - if(!result) - return (CC_CAUSE_ERROR); - - /* Set ICE parameters into ICE engine */ - - vcm_res = vcmSetIceMediaParams(dcb_p->peerconnection, media->level, ufrag, pwd, - candidates, candidate_ct); - - /* Clean up */ - if(candidates) { - int i; - - for (i=0; idcb; - cc_sdp_t *sdp_p = dcb_p->sdp; - fsmdef_media_t *media; - // int level = SDP_SESSION_LEVEL; - // short result; - char *token; - char line_to_split[FSMDEF_MAX_DIGEST_ALG_LEN + FSMDEF_MAX_DIGEST_LEN + 2]; - char *delim = " "; - char digest_alg[FSMDEF_MAX_DIGEST_ALG_LEN]; - char digest[FSMDEF_MAX_DIGEST_LEN]; - char *strtok_state; - cc_causes_t cause = CC_CAUSE_OK; - - /* First check for session level algorithm and key */ - sdp_session_res = sdp_attr_get_dtls_fingerprint_attribute (sdp_p->dest_sdp, SDP_SESSION_LEVEL, - 0, SDP_ATTR_DTLS_FINGERPRINT, 1, &session_fingerprint); - - /* Now process all the media lines */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) - continue; - - /* check for media level algorithm and key */ - sdp_res = sdp_attr_get_dtls_fingerprint_attribute (sdp_p->dest_sdp, media->level, - 0, SDP_ATTR_DTLS_FINGERPRINT, 1, &fingerprint); - - if (SDP_SUCCESS == sdp_res ) { - if (strlen(fingerprint) >= sizeof(line_to_split)) - return CC_CAUSE_ERROR; - sstrncpy(line_to_split, fingerprint, sizeof(line_to_split)); - } else if (SDP_SUCCESS == sdp_session_res) { - if (strlen(session_fingerprint) >= sizeof(line_to_split)) - return CC_CAUSE_ERROR; - sstrncpy(line_to_split, session_fingerprint, sizeof(line_to_split)); - } else { - cause = CC_CAUSE_ERROR; - continue; - } - - if (SDP_SUCCESS == sdp_res || SDP_SUCCESS == sdp_session_res) { - if(!(token = PL_strtok_r(line_to_split, delim, &strtok_state))) - return CC_CAUSE_ERROR; - - if (strlen(token) >= sizeof(digest_alg)) - return CC_CAUSE_ERROR; - - sstrncpy(digest_alg, token, sizeof(digest_alg)); - if(!(token = PL_strtok_r(NULL, delim, &strtok_state))) - return CC_CAUSE_ERROR; - - if (strlen(token) >= sizeof(digest)) - return CC_CAUSE_ERROR; - - sstrncpy(digest, token, sizeof(digest)); - - if (strlen(digest_alg) >= sizeof(media->negotiated_crypto.algorithm)) - return CC_CAUSE_ERROR; - - sstrncpy(media->negotiated_crypto.algorithm, digest_alg, sizeof(media->negotiated_crypto.algorithm)); - if (strlen(media->negotiated_crypto.algorithm) == 0) { - return CC_CAUSE_ERROR; - } - - if (strlen(digest) >= sizeof(media->negotiated_crypto.digest)) - return CC_CAUSE_ERROR; - - sstrncpy(media->negotiated_crypto.digest, digest, sizeof(media->negotiated_crypto.digest)); - if (strlen(media->negotiated_crypto.digest) == 0) { - return CC_CAUSE_ERROR; - } - - /* Here we have DTLS data */ - cause = CC_CAUSE_OK; - - } else { - GSM_DEBUG(DEB_F_PREFIX"DTLS attribute error\n", - DEB_F_PREFIX_ARGS(GSM, __FUNCTION__)); - return CC_CAUSE_ERROR; - } - } - - return cause; -} - -/* - * gsmsdp_free - * - * Description: - * The function frees SDP resources that were allocated during the - * course of the call. - * - * Parameters: - * dcb_p - pointer to fsmdef_dcb_t. - */ -void -gsmsdp_free (fsmdef_dcb_t *dcb_p) -{ - if ((dcb_p != NULL) && (dcb_p->sdp != NULL)) { - sipsdp_free(&dcb_p->sdp); - dcb_p->sdp = NULL; - } -} - -/* - * gsmsdp_sdp_differs_from_previous_sdp - * - * Description: - * - * Interface function used to compare newly received SDP to previously - * received SDP. Returns FALSE if attributes of interest are the same. - * Otherwise, returns TRUE. - * - * Parameters: - * - * rcv_only - If TRUE, check for receive port perspective. - * media - Pointer to the fsmdef_media_t for the current media entry. - */ -boolean -gsmsdp_sdp_differs_from_previous_sdp (boolean rcv_only, fsmdef_media_t *media) -{ - static const char fname[] = "gsmsdp_sdp_differs_from_previous_sdp"; - char prev_addr_str[MAX_IPADDR_STR_LEN]; - char dest_addr_str[MAX_IPADDR_STR_LEN]; - int i; - - /* Consider attributes of interest for both directions */ - - if ((0 == media->num_payloads) || (0 == media->previous_sdp.num_payloads) || - (media->num_payloads != media->previous_sdp.num_payloads)){ - GSM_DEBUG(DEB_F_PREFIX"previous # payloads: %d new # payloads: %d\n", - DEB_F_PREFIX_ARGS(GSM, fname), - media->previous_sdp.num_payloads, media->num_payloads); - } - - if (media->previous_sdp.avt_payload_type != media->avt_payload_type){ - GSM_DEBUG(DEB_F_PREFIX"previous avt PT: %d new avt PT: %d\n", - DEB_F_PREFIX_ARGS(GSM, fname), - media->previous_sdp.avt_payload_type, - media->avt_payload_type); - return TRUE; - } - - for (i = 0; i < media->num_payloads; i++) { - if ((media->previous_sdp.payloads[i].remote_rtp_pt != - media->payloads[i].remote_rtp_pt) || - (media->previous_sdp.payloads[i].codec_type != - media->payloads[i].codec_type)){ - GSM_DEBUG(DEB_F_PREFIX"previous dynamic payload (PT) #%d: " - "%d; new dynamic payload: %d\n", - DEB_F_PREFIX_ARGS(GSM, fname), i, - media->previous_sdp.payloads[i].remote_rtp_pt, - media->payloads[i].remote_rtp_pt); - GSM_DEBUG(DEB_F_PREFIX"previous codec #%d: %d; new codec: %d\n", - DEB_F_PREFIX_ARGS(GSM, fname), i, - media->previous_sdp.payloads[i].codec_type, - media->payloads[i].codec_type); - return TRUE; - } - } - - /* - * Consider attributes of interest for transmit directions. - * If previous dest port is 0 then this is the first time - * we received sdp for comparison. We treat this situation - * as if addr and port did not change. - */ - if ( (media->previous_sdp.dest_port != 0) && (rcv_only == FALSE)) { - if ((util_compare_ip(&(media->previous_sdp.dest_addr), - &(media->dest_addr)) == FALSE) || - (media->previous_sdp.dest_port != media->dest_port)) { - prev_addr_str[0] = '\0'; /* ensure valid string if convesion fails */ - dest_addr_str[0] = '\0'; - ipaddr2dotted(prev_addr_str, &media->previous_sdp.dest_addr); - ipaddr2dotted(dest_addr_str, &media->dest_addr); - GSM_DEBUG(DEB_F_PREFIX"previous address: %s new address: %s\n", - DEB_F_PREFIX_ARGS(GSM, fname), prev_addr_str, dest_addr_str); - GSM_DEBUG(DEB_F_PREFIX"previous port: %d new port: %d\n", - DEB_F_PREFIX_ARGS(GSM, fname), media->previous_sdp.dest_port, media->dest_port); - return TRUE; - } else if ( media->tias_bw != media->previous_sdp.tias_bw) { - GSM_DEBUG(DEB_F_PREFIX"previous bw: %d new bw: %d\n", - DEB_F_PREFIX_ARGS(GSM, fname), media->previous_sdp.tias_bw, media->tias_bw); - return TRUE; - } else if ( media->profile_level != media->previous_sdp.profile_level) { - GSM_DEBUG(DEB_F_PREFIX"previous prof_level: %X new prof_level: %X\n", - DEB_F_PREFIX_ARGS(GSM, fname), media->previous_sdp.profile_level, media->profile_level); - return TRUE; - } - } - - - /* Check crypto parameters if we are doing SRTP */ - if (gsmsdp_crypto_params_change(rcv_only, media)) { - return TRUE; - } - return FALSE; -} - - -/* - * gsmsdp_add_remote_stream - * - * Description: - * - * For each remote media stream add a track to the dcb for the - * current session. - * - * Parameters: - * - * idx - Stream index - * pc_stream_id - stream id from vcm layer, will be set as stream id - * - * dcb_p - Pointer to the DCB whose SDP is to be manipulated. - * media - Pointer to the fsmdef_media_t for the current media entry. - */ -void gsmsdp_add_remote_stream(uint16_t idx, int pc_stream_id, fsmdef_dcb_t *dcb_p, fsmdef_media_t *media) { - - /* - * This function is in its infancy, but when complete will create a list - * of streams, each with its list of tracks and associated data. - * Currently this just creates 1 track per 1 stream. - */ - - PR_ASSERT(idx < CC_MAX_STREAMS); - - if (idx < CC_MAX_STREAMS) { - dcb_p->remote_media_stream_tbl->streams[idx].num_tracks = 1; - dcb_p->remote_media_stream_tbl->streams[idx].media_stream_id = pc_stream_id; - dcb_p->remote_media_stream_tbl->streams[idx].track[0].media_stream_track_id = idx+1; - dcb_p->remote_media_stream_tbl->streams[idx].track[0].video = (media->type == 0 ? FALSE : TRUE); - } -} - -cc_causes_t -gsmsdp_find_level_from_mid(fsmdef_dcb_t * dcb_p, const char * mid, uint16_t *level) { - - fsmdef_media_t *media; - u32 mid_id; - char buf[5]; - - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) - continue; - - mid_id = sdp_attr_get_simple_u32(dcb_p->sdp->dest_sdp, SDP_ATTR_MID, media->level, 0, 1); - snprintf(buf, sizeof(buf), "%u", mid_id); - if (strcmp(mid, buf) == 0) { - *level = media->level; - return CC_CAUSE_OK; - } - } - return CC_CAUSE_VALUE_NOT_FOUND; -} diff --git a/libs/sipcc/core/gsm/gsm_sdp_crypto.c b/libs/sipcc/core/gsm/gsm_sdp_crypto.c deleted file mode 100644 index 93e8d32e05..0000000000 --- a/libs/sipcc/core/gsm/gsm_sdp_crypto.c +++ /dev/null @@ -1,1914 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include - -#include "cpr_types.h" -#include "cpr_rand.h" -#include "sdp.h" -#include "fsm.h" -#include "gsm_sdp.h" -#include "util_string.h" -#include "lsm.h" -#include "sip_interface_regmgr.h" -#include "plat_api.h" - -static const char *gsmsdp_crypto_suite_name[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] = -{ - "SDP_SRTP_UNKNOWN_CRYPTO_SUITE", - "SDP_SRTP_AES_CM_128_HMAC_SHA1_32", - "SDP_SRTP_AES_CM_128_HMAC_SHA1_80", - "SDP_SRTP_F8_128_HMAC_SHA1_80" -}; - -/* - * Cached random number pool. The size of the pool is for 10 key sets - * ahead. The number of cached keys are arbitrary picked to be large - * enough to sustain the number of basic calls. - */ -#define RAND_POOL_SIZE ((VCM_SRTP_MAX_KEY_SIZE+VCM_SRTP_MAX_SALT_SIZE)*10) -#define RAND_REQ_LIMIT 256 /* limit random number request */ -static unsigned char rand_pool[RAND_POOL_SIZE]; /* random number pool */ -static int rand_pool_bytes = 0; /* current numbers in rand pool */ - -/* - * Default key life time that phone supports, - * should be "2^48" but CCM does not support the value. Leave the - * life time to blank. - */ -#define GSMSDP_DEFALT_KEY_LIFETIME NULL - -/* Default algorithmID */ -#define GSMSDP_DEFAULT_ALGORITHM_ID VCM_AES_128_COUNTER - -/* - * Function: gsmsdp_cache_crypto_keys - * - * Parameters: - * N/A - * - * Description: - * The function fills the crypto graphically random number pool - * so that when SRTP key (and salt) is needed it is first obtained from - * cached pool during the call for a better response to the real time - * signalling event. - * - * Returns: - * N/A - */ -void -gsmsdp_cache_crypto_keys (void) -{ - int number_to_fill; - int accumulate_bytes; - int bytes; - - /* - * Only attempt to fill the cache when the pool needs to be - * filled and the phone is idle. - */ - if ((rand_pool_bytes == RAND_POOL_SIZE) || !lsm_is_phone_idle()) { - return; - } - - number_to_fill = RAND_POOL_SIZE - rand_pool_bytes; - accumulate_bytes = 0; - - while (accumulate_bytes < number_to_fill) { - bytes = number_to_fill - accumulate_bytes; - /* - * Limit the request the number bytes for each request to - * crypto graphic random number generator to prevent - * error. There is a maximum limit to per request. - */ - if (bytes > RAND_REQ_LIMIT) { - bytes = RAND_REQ_LIMIT; - } - - if (platGenerateCryptoRand(&rand_pool[accumulate_bytes], &bytes)) { - accumulate_bytes += bytes; - } else { - /* - * Failed to get the crypto random number, uses the - * cpr_rand(), to keep the call going. - */ - rand_pool[accumulate_bytes] = (uint8_t) (cpr_rand() & 0xff); - accumulate_bytes++; - } - } - rand_pool_bytes = RAND_POOL_SIZE; -} - -/* - * Function: gsmsdp_get_rand_from_cached_pool - * - * Parameters: - * dst_buf - pointer to the unsigned char for the buffer to - * store random number obtained from the cached pool. - * req_bytes - number of random number requested. - * - * Description: - * The function gets the random number from the cache pool. - * - * Returns: - * The number of random number obtained from the pool. - */ -static int -gsmsdp_get_rand_from_cached_pool (unsigned char *dst_buf, int req_bytes) -{ - int bytes; - - if (rand_pool_bytes == 0) { - /* the pool is empty */ - return 0; - } - - if (rand_pool_bytes >= req_bytes) { - /* There are enough bytes from the pool */ - bytes = req_bytes; - } else { - /* - * pool does not have enough random bytes, give whatever - * remains in the pool - */ - bytes = rand_pool_bytes; - } - - memcpy(dst_buf, &rand_pool[RAND_POOL_SIZE - rand_pool_bytes], bytes); - rand_pool_bytes -= bytes; - - /* Returns the actual number of bytes gotten from the pool */ - return (bytes); -} - -/* - * Function: gsmsdp_generate_key - * - * Description: - * The function generates key and salt for SRTP. - * - * Parameters: - * algorithmID - algorithm ID - * key - pointer to vcm_crypto_key_t to store key output. - * - * Returns: - * None - */ -static void -gsmsdp_generate_key (uint32_t algorithmID, vcm_crypto_key_t * key) -{ - int accumulate_len, len, total_bytes, bytes_from_cache; - uint8_t random[sizeof(key->key) + sizeof(key->salt)]; - uint8_t key_len, salt_len; - - if (algorithmID == VCM_AES_128_COUNTER) { - key_len = VCM_AES_128_COUNTER_KEY_SIZE; - salt_len = VCM_AES_128_COUNTER_SALT_SIZE; - } else { - /* Unsupported algorithm */ - key_len = VCM_SRTP_MAX_KEY_SIZE; - salt_len = VCM_SRTP_MAX_SALT_SIZE; - } - - /* - * Request random bytes one time for both key and salt to avoid - * the overhead of platGenerateCryptoRand(). - * - * The size of random byes should be based on the algorithmID - * used but since at this time only AES128 is used. - */ - accumulate_len = 0; - total_bytes = key_len + salt_len; - - while (accumulate_len < total_bytes) { - len = total_bytes - accumulate_len; - - /* Attempt to get random number from cached pool first */ - bytes_from_cache = - gsmsdp_get_rand_from_cached_pool(&random[accumulate_len], len); - if (bytes_from_cache) { - /* There are some random number from the cache */ - accumulate_len += bytes_from_cache; - } else { - /* - * The cached random number in the pool is empty. - * - * Attempt to get all of the random bytes in one request but - * if the number of random bytes is not enough then requesting - * until all bytes are accumulated. - */ - if (len > RAND_REQ_LIMIT) { - len = RAND_REQ_LIMIT; - } - if (platGenerateCryptoRand(&random[accumulate_len], &len)) { - accumulate_len += len; - } else { - /* - * Failed to get the crypto random number, uses the - * cpr_rand(), to keep the call going. - */ - random[accumulate_len] = (uint8_t) (cpr_rand() & 0xff); - accumulate_len++; - } - } - } - - /* - * Filled in key and salt from the random bytes generated. - */ - key->key_len = key_len; - memcpy(&key->key[0], &random[0], key->key_len); - - key->salt_len = salt_len; - memcpy(&key->salt[0], &random[key->key_len], key->salt_len); -} - -/* - * Function: gsmsdp_is_supported_crypto_suite - * - * Description: - * The function checks whether the given crypto suite from SDP - * is supported or not. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t type to be checked - * - * Returns: - * TRUE - the crypto suite is supported. - * FALSE - the crypto suite is not supported. - */ -static boolean -gsmsdp_is_supported_crypto_suite (sdp_srtp_crypto_suite_t crypto_suite) -{ - switch (crypto_suite) { - case SDP_SRTP_AES_CM_128_HMAC_SHA1_32: - /* These are the supported crypto suites */ - return (TRUE); - default: - return (FALSE); - } -} - -/* - * Function: gsmsdp_is_valid_keysize - * - * Description: - * The function checks whether the given key size is valid. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t type - * key_size - key size to check - * - * Returns: - * TRUE - the key size is valid - * FALSE - the key size is not valid - */ -static boolean -gsmsdp_is_valid_key_size (sdp_srtp_crypto_suite_t crypto_suite, - unsigned char key_size) -{ - /* - * Make sure the size fits the maximum key size currently supported. - * This to make sure that when a longer key size is added but - * the maximum key size is not updated. - */ - if (key_size > VCM_SRTP_MAX_KEY_SIZE) { - return (FALSE); - } - - /* Check key size against crypto suite */ - switch (crypto_suite) { - case SDP_SRTP_AES_CM_128_HMAC_SHA1_32: - if (key_size == VCM_AES_128_COUNTER_KEY_SIZE) { - return (TRUE); - } - break; - - default: - break; - } - return (FALSE); -} - -/* - * Function: gsmsdp_is_valid_salt_size - * - * Description: - * The function checks whether the given salt size is valid. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t type - * salt_size - salt size to check - * - * Returns: - * TRUE - the salt size is valid - * FALSE - the salt size is not valid - */ -static boolean -gsmsdp_is_valid_salt_size (sdp_srtp_crypto_suite_t crypto_suite, - unsigned char salt_size) -{ - /* - * Make sure the size fits the maximum salt size currently supported. - * This to make sure that when a longer salt size is added but - * the maximum salt size is not updated. - */ - if (salt_size > VCM_SRTP_MAX_SALT_SIZE) { - return (FALSE); - } - - /* Check salt size against crypter suite */ - switch (crypto_suite) { - case SDP_SRTP_AES_CM_128_HMAC_SHA1_32: - if (salt_size == VCM_AES_128_COUNTER_SALT_SIZE) { - return (TRUE); - } - break; - - default: - break; - } - return (FALSE); -} - -/* - * Function: gsmdsp_cmp_key - * - * Description: - * The function compares 2 keys. - * - * Parameters: - * key1 - pointer to vcm_crypto_key_t - * key2 - pointer to vcm_crypto_key_t - * - * Returns: - * TRUE - the 2 keys are different - * FALSE - the 2 keys are the same - */ -static boolean -gsmdsp_cmp_key (vcm_crypto_key_t *key1, vcm_crypto_key_t *key2) -{ - if ((key1 == NULL) && (key2 != NULL)) { - /* No key 1 but has key 2 -> different */ - return (TRUE); - } - if ((key1 != NULL) && (key2 == NULL)) { - /* Has key 1 but no key 2 -> different */ - return (TRUE); - } - if ((key1 == NULL) && (key2 == NULL)) { - /* No key 1 and no key 2 -> same */ - return (FALSE); - } - /* - * At this point pointer to key1 and key2 should not be NULL. Compare - * the key content - */ - if ((key1->key_len != key2->key_len) || (key1->salt_len != key2->salt_len)) { - /* Key length or salt length are not the same */ - return (TRUE); - } - if (key1->key_len != 0) { - if (memcmp(key1->key, key2->key, key1->key_len)) { - return (TRUE); - } - } - if (key1->salt_len != 0) { - if (memcmp(key1->salt, key2->salt, key1->salt_len)) { - return (TRUE); - } - } - /* Both keys are the same */ - return (FALSE); -} - -/* - * Function: gsmsdp_is_supported_session_parm - * - * Description: - * The function checks to see whether the session parameters given - * is supported or not. - * - * Parameters: - * session_parms - pointer to string of session parameters - * - * Returns: - * TRUE - the session parameters are supported - * FALSE - the session parameters are not supported - */ -static boolean -gsmsdp_is_supported_session_parm (const char *session_parms) -{ - int len; - const char *parm_ptr; - long strtol_result; - char *strtol_end; - - if (session_parms == NULL) { - /* No session parameters, this is acceptable */ - return (TRUE); - } - /* - * Only WSH is allowed even though the phone does not support it. - * The session param string can only have "WSH=nn" or (size of 6). - */ - len = strlen(session_parms); - if (strcmp(session_parms, "WSH=") && (len == 6)) { - parm_ptr = &session_parms[sizeof("WSH=") - 1]; /* point the wsh value */ - - errno = 0; - strtol_result = strtol(parm_ptr, &strtol_end, 10); - - /* minimum value of WSH is 64 */ - if (errno || parm_ptr == strtol_end || strtol_result < 64 || strtol_result > INT_MAX) { - return FALSE; - } - - return TRUE; - } - /* Other parameters are not supported */ - return (FALSE); -} - -/* - * Function: gsmsdp_crypto_suite_to_algorithmID - * - * Description: - * The function converts the given crypto suite from SDP into - * internal enumeration suitable for using with SRTP lib. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t type to converted into - * internal algorithm ID - * - * Returns: - * value VCM algorithmID - */ -static vcm_crypto_algorithmID -gsmsdp_crypto_suite_to_algorithmID (sdp_srtp_crypto_suite_t crypto_suite) -{ - /* Convert the supported crypto suite into the algorithm ID */ - switch (crypto_suite) { - case SDP_SRTP_AES_CM_128_HMAC_SHA1_32: - return (VCM_AES_128_COUNTER); - default: - return (VCM_INVLID_ALGORITM_ID); - } -} - -/* - * Function: gsmsdp_algorithmID_to_crypto_suite - * - * Description: - * The function converts the given crypto suite from SDP into - * internal enumeration suitable for using with SRTP lib. - * - * Parameters: - * algorithmID - algorithm ID to be converted into crypto suite - * - * Returns: - * crypto suite that is corresponding to the internal algorithmID - */ -static sdp_srtp_crypto_suite_t -gsmsdp_algorithmID_to_crypto_suite (vcm_crypto_algorithmID algorithmID) -{ - /* Convert the supported crypto suite into the crypto suite */ - switch (algorithmID) { - case VCM_AES_128_COUNTER: - return (SDP_SRTP_AES_CM_128_HMAC_SHA1_32); - default: - return (SDP_SRTP_UNKNOWN_CRYPTO_SUITE); - } -} - - -/* - * Function: gsmsdp_crypto_suite_string - * - * Description: - * The function converts crypto suite to string name. - * - * Parameters: - * crypto_suite - sdp_srtp_crypto_suite_t - * - * Returns: - * string constant of the corresponding crypto suite - */ -static const char * -gsmsdp_crypto_suite_string (sdp_srtp_crypto_suite_t crypto_suite) -{ - if (crypto_suite >= SDP_SRTP_MAX_NUM_CRYPTO_SUITES) { - return (gsmsdp_crypto_suite_name[SDP_SRTP_UNKNOWN_CRYPTO_SUITE]); - } - return (gsmsdp_crypto_suite_name[crypto_suite]); -} - -/* - * Function: gsmsdp_get_key_from_sdp - * - * Description: - * The function checks the key from the SDP. - * - * Parameters: - * dcb_p - pointer to the DCB. - * sdp_p - pointer to remote's SDP (void) - * level - the media level of the SDP of the media line. - * inst_num - instance number of the crypto attribute. - * key_st - pointer to fsmdef_crypto_key_t for the key to be returned. - * If pointer is NULL, the function acts as key validation. - * - * Returns: - * TRUE - The key is valid. - * FALSE - The key is not valid. - */ -static boolean -gsmsdp_get_key_from_sdp (fsmdef_dcb_t *dcb_p, void *sdp_p, uint16_t level, - uint16_t inst_num, vcm_crypto_key_t *key_st) -{ - const char *fname = "gsmsdp_get_key_from_sdp"; - unsigned char key_size; - unsigned char salt_size; - const char *key, *salt; - sdp_srtp_crypto_suite_t crypto_suite; - - /* Get the crypto suite */ - crypto_suite = sdp_attr_get_sdescriptions_crypto_suite(sdp_p, - level, 0, inst_num); - - /* Get key */ - key_size = sdp_attr_get_sdescriptions_key_size(sdp_p, level, 0, inst_num); - if (!gsmsdp_is_valid_key_size(crypto_suite, key_size)) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "SDP has invalid key size %d at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, key_size, level); - return (FALSE); - } - - key = sdp_attr_get_sdescriptions_key(sdp_p, level, 0, inst_num); - if (key == NULL) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "SDP has no key at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, level); - return (FALSE); - } - - /* Get salt */ - salt_size = sdp_attr_get_sdescriptions_salt_size(sdp_p, level, 0, inst_num); - if (!gsmsdp_is_valid_salt_size(crypto_suite, salt_size)) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "SDP has invalid salt size %d at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, salt_size, level); - return (FALSE); - } - salt = sdp_attr_get_sdescriptions_salt(sdp_p, level, 0, inst_num); - if (salt == NULL) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "SDP has no salt at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, level); - return (FALSE); - } - - /* - * Key and salt have been sanity check including their sizes, - * copy key and salt if the caller requests for it. - */ - if (key_st != NULL) { - /* The caller needs to copy of the key */ - key_st->key_len = key_size; - memcpy(key_st->key, key, key_size); - key_st->salt_len = salt_size; - memcpy(key_st->salt, salt, salt_size); - } - return (TRUE); -} - -/* - * Function: gsmsdp_local_offer_srtp - * - * Description: - * The function checks whether the local (phone) SRTP has been offered. - * - * Parameters: - * media - pointer to the fsmdef_media_t for the media entry. - * - * Returns: - * TRUE - local has offered SRTP - * FALSE - local has not offered SRTP - */ -static boolean -gsmsdp_local_offer_srtp (fsmdef_media_t *media) -{ - /* - * Use the local tag as an indication whether we have offered, - * SRTP or not. - */ - if (media->local_crypto.tag == SDP_INVALID_VALUE) { - return (FALSE); - } - return (TRUE); -} - -/* - * Function: gsmsdp_clear_local_offer_srtp - * - * Description: - * The function clears the flag to mark that the local SRTP has - * been offered. - * - * Parameters: - * media - pointer to the fsmdef_media_t for the media entry. - * - * Returns: - * none - */ -static void -gsmsdp_clear_local_offer_srtp (fsmdef_media_t *media) -{ - /* - * Use the local tag as an indication whether we have offered, - * SRTP or not. - */ - media->local_crypto.tag = SDP_INVALID_VALUE; -} - -/* - * Function: gsmsdp_check_common_crypto_param - * - * Description: - * The function checks common crypto parameters that can be shared - * by selecting an offer and checking the answer SDP. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated - * cc_sdp_p - pointer to cc_sdp_t structure - * level - the media level of the SDP of the media line - * inst - crypto attribute instance number of the - * answer crypto line - * offer - boolean indicates offer if it is set to TRUE - * - * Returns: - * TRUE - when crypto parameters are valid and acceptable - * FALSE - when crypto parameters are not valid or not acceptable - */ -static boolean -gsmsdp_check_common_crypto_param (fsmdef_dcb_t *dcb_p, void *sdp_p, - uint16_t level, uint16_t inst, boolean offer) -{ - const char *fname = "gsmsdp_check_common_crypto_param"; - const char *dir_str; /* direction string */ - const char *session_parms; - const char *mki_value = NULL; - uint16_t mki_length = 0; - - if (offer) { - dir_str = "Offer"; /* the caller is working on an offer SDP */ - } else { - dir_str = "Answer"; /* the caller is working on an answer SDP */ - } - - /* Validate the key */ - if (!gsmsdp_get_key_from_sdp(dcb_p, sdp_p, level, inst, NULL)) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "%s SDP has invalid key at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, dir_str, level); - return (FALSE); - } - - /* Check MKI, we do not support it */ - if (sdp_attr_get_sdescriptions_mki(sdp_p, level, 0, inst, - &mki_value, &mki_length) - != SDP_SUCCESS) { - /* something is wrong with decoding MKI field, do not use it */ - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Fail to obtain MKI from %s SDP at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, dir_str, level); - return (FALSE); - } - if (mki_length) { - /* this crypto line has MKI specified, we do not support it */ - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "%s SDP has MKI %d (not supported) at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, dir_str, mki_length, - level); - return (FALSE); - } - - /* Check session parameters */ - session_parms = sdp_attr_get_sdescriptions_session_params(sdp_p, - level, 0, inst); - if (!gsmsdp_is_supported_session_parm(session_parms)) { - /* some unsupported session parameters are found */ - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "%s SDP has unsupported session param at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, dir_str, level); - return (FALSE); - } - - /* This is good and acceptable one */ - return (TRUE); -} - -/* - * Function: gsmsdp_select_offer_crypto - * - * Description: - * Select remote the crypto attributes from the remote offered SDP. - * - * Parameters: - * dcb_p - pointer to the DCB - * sdp_p - pointer to remote's SDP (void) - * level - the media level of the SDP of the media line - * crypto_inst - pointer to crypto attribute instance number of the - * selected crypto line - * - * Returns: - * TRUE - when matching crypto parameters are found. - * FALSE - when matching crypto parameters are not found. - */ -static boolean -gsmsdp_select_offer_crypto (fsmdef_dcb_t *dcb_p, void *sdp_p, uint16_t level, - uint16_t *crypto_inst) -{ - const char *fname = "gsmsdp_select_offer_crypto"; - uint16_t num_attrs = 0; /* number of attributes */ - uint16_t attr; - int32_t tag; - sdp_attr_e attr_type; - sdp_result_e rc; - sdp_srtp_crypto_suite_t crypto_suite; - - /* Find the number of attributes at this level of media line */ - rc = sdp_get_total_attrs(sdp_p, level, 0, &num_attrs); - if (rc != SDP_SUCCESS) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Failed finding attributes for media level %d\n", - dcb_p->line, dcb_p->call_id, fname, level); - return (FALSE); - } - - /* - * Search all crypto attributes to find a valid one that phone - * can support. - * - * The search starts from the first attributes to the higher. The - * attributes are listed from the most preferred attribute to the - * least in the SDP. - */ - for (attr = 1; attr <= num_attrs; attr++) { - rc = sdp_get_attr_type(sdp_p, level, 0, attr, &attr_type, crypto_inst); - if ((rc != SDP_SUCCESS) || (attr_type != SDP_ATTR_SDESCRIPTIONS)) { - /* Can't not get the attribute or it is not sdescription */ - continue; - } - /* - * Found a crypto attribute, try to match the supported crypto suite - */ - crypto_suite = sdp_attr_get_sdescriptions_crypto_suite(sdp_p, - level, 0, - *crypto_inst); - if (!gsmsdp_is_supported_crypto_suite(crypto_suite)) { - /* this one is we can not support, look further */ - continue; - } - /* get crypto tag */ - tag = sdp_attr_get_sdescriptions_tag(sdp_p, level, 0, *crypto_inst); - if (tag == SDP_INVALID_VALUE) { - /* no tag associated with this crypto attribute */ - continue; - } - - /* Check common crypto parameters */ - if (!gsmsdp_check_common_crypto_param(dcb_p, sdp_p, level, - *crypto_inst, TRUE)) { - /* Some thing is wrong with the common crypto parameters */ - continue; - } - - /* Found a good crypto attribute to use */ - return (TRUE); - } - - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Failed finding supported crypto attribute for media level %d\n", - dcb_p->line, dcb_p->call_id, fname, level); - return (FALSE); -} - -/* - * Function: gsmsdp_check_answer_crypto_param - * - * Description: - * The function processes the answer crypto attributes. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated - * cc_sdp_p - pointer to cc_sdp_t structure - * media - pointer to the media for the SDP of the media line - * crypto_inst - pointer to crypto attribute instance number of the - * answer crypto line. - * - * Returns: - * TRUE - when matching crypto parameters are found - * FALSE - when matching crypto parameters are not found - */ -static boolean -gsmsdp_check_answer_crypto_param (fsmdef_dcb_t *dcb_p, cc_sdp_t * cc_sdp_p, - fsmdef_media_t *media, uint16_t *crypto_inst) -{ - const char *fname = "gsmsdp_check_answer_crypto_param"; - uint16_t num_attrs = 0; /* number of attributes */ - uint16_t attr; - uint16_t num_crypto_attr = 0; - int32_t dest_crypto_tag, offered_tag; - sdp_attr_e attr_type; - sdp_result_e rc; - sdp_srtp_crypto_suite_t crypto_suite; - vcm_crypto_algorithmID algorithmID; - void *dest_sdp = cc_sdp_p->dest_sdp; - uint16_t temp_inst, inst = 0; - uint16_t level; - - level = media->level; - /* Clear the crypto instance */ - *crypto_inst = 0; - - /* Find the number of attributes at this level of media line */ - if (sdp_get_total_attrs(dest_sdp, level, 0, &num_attrs) != SDP_SUCCESS) { - GSM_DEBUG(DEB_L_C_F_PREFIX - "Failed finding attributes for media level %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), level); - return (FALSE); - } - - /* - * Check to make sure that there is only crypto attribute in the - * answer SDP. - */ - for (attr = 1, num_crypto_attr = 0; attr <= num_attrs; attr++) { - rc = sdp_get_attr_type(dest_sdp, level, 0, attr, &attr_type, - &temp_inst); - if ((rc == SDP_SUCCESS) && (attr_type == SDP_ATTR_SDESCRIPTIONS)) { - num_crypto_attr++; - inst = temp_inst; - } - } - if (num_crypto_attr != 1) { - /* The remote answers with zero or more than one crypto attribute */ - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Answer SDP contains invalid number of" - " crypto attributes %d for media level %d\n", - dcb_p->line, dcb_p->call_id, fname, - num_crypto_attr, level); - return (FALSE); - } - - /* - * Check to make sure that the tag in the answer SDP is one of the - * offered SDP. - * Note: At this time of implementation there is only one crypto - * line sent out. When more than one cypher suites are supported, - * then the answer tag should be used to find the corresponding - * local crypto parameter. - */ - dest_crypto_tag = sdp_attr_get_sdescriptions_tag(dest_sdp, level, 0, inst); - - /* - * Selecting tag, if we have made an offer and have not received an answer - * before this one then tag to match is from the offered tag otherwise - * use the negotiated tag to match. The later case can occur as the - * following: - * phone --- INVITE+SDP ----> CCM - * <--- 100 ----- - * <--- 183+SDP ----- - * <--- 200+SDP ----- - * The first 183+SDP will conclude the offer/answer. The 200+SDP - * is also an answer which also contains negotiated tag. - */ - if (gsmsdp_local_offer_srtp(media)) { - /* - * We have made an offered and has not received an answer before - * this one, use the tag from the local crypto. - */ - offered_tag = media->local_crypto.tag; - algorithmID = media->local_crypto.algorithmID; - } else { - /* offer/answer has complete, use negotiated crypto */ - offered_tag = media->negotiated_crypto.tag; - algorithmID = media->negotiated_crypto.algorithmID; - } - if (dest_crypto_tag != offered_tag) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Answer SDP contains wrong tag %d vs %d" - " for the media level %d\n", - dcb_p->line, dcb_p->call_id, fname, - dest_crypto_tag, offered_tag, level); - return (FALSE); - } - - /* Check make sure that crypto suite is the same one that is offered */ - crypto_suite = sdp_attr_get_sdescriptions_crypto_suite(dest_sdp, level, - 0, inst); - if (gsmsdp_crypto_suite_to_algorithmID(crypto_suite) != algorithmID) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Answer SDP mismatch crypto suite %s at media level %d\n", - dcb_p->line, dcb_p->call_id, fname, - gsmsdp_crypto_suite_string(crypto_suite), level); - return (FALSE); - } - - /* Check common crypto parameters */ - if (!gsmsdp_check_common_crypto_param(dcb_p, dest_sdp, level, - inst, FALSE)) { - /* Some thing is wrong with the common crypto parameters */ - return (FALSE); - } - - *crypto_inst = inst; - return (TRUE); -} - -/* - * - * Function: gsmsdp_negotiate_offer_crypto - * - * Description: - * The function handles crypto parameters negotiation for - * an offer SDP. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated - * cc_sdp_p - pointer to cc_sdp_t structure - * media - pointer to fsmdef_media_t where the media transport is. - * crypto_inst - pointer to crypto attribute instance number of the - * selected crypto line - * - * Returns: - * transport - sdp_transport_e for RTP or SRTP or invalid - */ -static sdp_transport_e -gsmsdp_negotiate_offer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, uint16_t *crypto_inst, uint16 dest_level) -{ - sdp_transport_e remote_transport; - sdp_transport_e negotiated_transport = SDP_TRANSPORT_INVALID; - void *sdp_p = cc_sdp_p->dest_sdp; - int sdpmode = 0; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - *crypto_inst = 0; - remote_transport = sdp_get_media_transport(sdp_p, dest_level); - - /* negotiate media transport */ - switch (remote_transport) { - case SDP_TRANSPORT_RTPAVP: - /* Remote offers RTP for media transport, negotiated transport to RTP */ - negotiated_transport = SDP_TRANSPORT_RTPAVP; - break; - - case SDP_TRANSPORT_RTPSAVP: - - /* Remote offer SRTP for media transport */ - if (((sip_regmgr_get_sec_level(dcb_p->line) == ENCRYPTED) && - FSM_CHK_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY)) || sdpmode) { - /* The signalling with this line is encrypted, try to use SRTP */ - if (gsmsdp_select_offer_crypto(dcb_p, sdp_p, dest_level, crypto_inst)) { - /* Found a suitable crypto line from the remote offer */ - negotiated_transport = SDP_TRANSPORT_RTPSAVP; - } - } - - if (negotiated_transport == SDP_TRANSPORT_INVALID) { - /* - * Unable to find a suitable crypto or the signaling is - * not secure. Fall back to RTP if fallback is enabled. - */ - if (sip_regmgr_srtp_fallback_enabled(dcb_p->line)) { - negotiated_transport = SDP_TRANSPORT_RTPAVP; - } - } - break; - - case SDP_TRANSPORT_RTPSAVPF: - /* Remote offers Extended SRTP for media transport */ - negotiated_transport = SDP_TRANSPORT_RTPSAVPF; - break; - - case SDP_TRANSPORT_SCTPDTLS: - negotiated_transport = SDP_TRANSPORT_SCTPDTLS; - break; - - default: - /* Unknown */ - break; - } - return (negotiated_transport); -} - -/* - * - * Function: gsmsdp_negotiate_answer_crypto - * - * Description: - * The function handles crypto parameters negotiation for - * an answer SDP. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated - * cc_sdp_p - pointer to cc_sdp_t structure - * media - pointer to fsmdef_media_t where the media transport is. - * crypto_inst - pointer to crypto attribute instance number of the - * answer crypto line - * - * Returns: - * transport - sdp_transport_e for RTP or SRTP or invalid - */ -static sdp_transport_e -gsmsdp_negotiate_answer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, uint16_t *crypto_inst) -{ - const char *fname = "gsmsdp_check_answer_crypto"; - sdp_transport_e remote_transport, local_transport; - sdp_transport_e negotiated_transport = SDP_TRANSPORT_INVALID; - uint16_t level; - - level = media->level; - *crypto_inst = 0; - remote_transport = sdp_get_media_transport(cc_sdp_p->dest_sdp, level); - local_transport = sdp_get_media_transport(cc_sdp_p->src_sdp, level); - GSM_DEBUG(GSM_F_PREFIX "remote transport %d\n", fname, remote_transport); - GSM_DEBUG(GSM_F_PREFIX "local transport %d\n", fname, local_transport); - - /* negotiate media transport */ - switch (remote_transport) { - case SDP_TRANSPORT_RTPAVP: - /* Remote answer with RTP */ - if (local_transport == SDP_TRANSPORT_RTPSAVP) { - if (sip_regmgr_srtp_fallback_enabled(dcb_p->line)) { - /* Fall back allows, falls back to RTP */ - negotiated_transport = SDP_TRANSPORT_RTPAVP; - } - } else { - /* local and remote are using RTP */ - negotiated_transport = SDP_TRANSPORT_RTPAVP; - } - break; - - case SDP_TRANSPORT_RTPSAVP: - GSM_DEBUG(GSM_F_PREFIX "remote SAVP case\n", fname); - /* Remote answer with SRTP */ - if (local_transport == SDP_TRANSPORT_RTPSAVP) { - GSM_DEBUG(GSM_F_PREFIX "local SAVP case\n", fname); - /* Remote and local media transport are using SRTP */ - if (gsmsdp_check_answer_crypto_param(dcb_p, cc_sdp_p, media, - crypto_inst)) { - /* Remote's answer crypto parameters are ok */ - negotiated_transport = SDP_TRANSPORT_RTPSAVP; - GSM_DEBUG(GSM_F_PREFIX "crypto params verified\n", fname); - } - } else { - /* we offered RTP but remote comes back with SRTP, fail */ - } - break; - - case SDP_TRANSPORT_RTPSAVPF: - negotiated_transport = SDP_TRANSPORT_RTPSAVPF; - break; - - case SDP_TRANSPORT_SCTPDTLS: - negotiated_transport = SDP_TRANSPORT_SCTPDTLS; - break; - - default: - /* Unknown */ - break; - } - GSM_DEBUG(GSM_F_PREFIX "negotiated transport %d\n", fname, negotiated_transport); - return (negotiated_transport); -} - -/* - * - * Function: gsmsdp_negotiate_media_transport - * - * Description: - * The function is a wrapper for negotiation RTP or SRTP for offer - * or answer SDP. The negotiated crypto attributes instance number - * will be returned via pointer crypto_inst. - * - * Parameters: - * dcb_p - pointer to the DCB whose local SDP is to be updated. - * cc_sdp_p - pointer to cc_sdp_t structure that contains remote SDP. - * offer - boolean indicates the remote SDP is an offer SDP. - * media - pointer to fsmdef_media_t where the media transport is. - * crypto_inst - pointer to crypto attribute instance number of the - * selected crypto line. - * - * Returns: - * transport - sdp_transport_e for RTP or SRTP or invalid - */ -sdp_transport_e -gsmsdp_negotiate_media_transport (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, - boolean offer, fsmdef_media_t *media, - uint16_t *crypto_inst, uint16 level) -{ - sdp_transport_e transport; - - /* negotiate media transport based on offer or answer from the remote */ - if (offer) { - transport = gsmsdp_negotiate_offer_crypto(dcb_p, cc_sdp_p, media, - crypto_inst, level); - } else { - transport = gsmsdp_negotiate_answer_crypto(dcb_p, cc_sdp_p, media, - crypto_inst); - } - return (transport); -} - -/* - * - * Function: gsmsdp_add_single_crypto_attr - * - * Description: - * The function adds a single crypto attributes to the SDP. - * - * Parameters: - * cc_sdp_p - pointer to SDP - * level - the media level of the SDP where the media transport is - * crypto_suite - crypto suite - * key - pointer to SRTP key (fsmdef_crypto_key_t) - * lifetime - pointer to string const for the life time - * - * Returns: - * sdp_result_e - */ -static sdp_result_e -gsmsdp_add_single_crypto_attr (void *sdp_p, uint16_t level, int32_t tag, - sdp_srtp_crypto_suite_t crypto_suite, - vcm_crypto_key_t * key, char *lifetime) -{ - sdp_result_e rc; - uint16 inst_num; - - if (key == NULL) { - return (SDP_INVALID_PARAMETER); - } - - /* - * Add crypto attributes tag to the SDP, the tag is using - * from the remote tag which should have been negotiated. - */ - rc = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_SDESCRIPTIONS, &inst_num); - if (rc != SDP_SUCCESS) { - return (rc); - } - - rc = sdp_attr_set_sdescriptions_tag(sdp_p, level, 0, inst_num, tag); - if (rc != SDP_SUCCESS) { - return (rc); - } - - /* Add crypto suite */ - rc = sdp_attr_set_sdescriptions_crypto_suite(sdp_p, level, 0, inst_num, - crypto_suite); - if (rc != SDP_SUCCESS) { - return (rc); - } - - /* Add local key */ - rc = sdp_attr_set_sdescriptions_key(sdp_p, level, 0, inst_num, - (char *) key->key); - if (rc != SDP_SUCCESS) { - return (rc); - } - - rc = sdp_attr_set_sdescriptions_key_size(sdp_p, level, 0, inst_num, - key->key_len); - if (rc != SDP_SUCCESS) { - return (rc); - } - - /* Add salt */ - rc = sdp_attr_set_sdescriptions_salt(sdp_p, level, 0, inst_num, - (char *) key->salt); - if (rc != SDP_SUCCESS) { - return (rc); - } - - rc = sdp_attr_set_sdescriptions_salt_size(sdp_p, level, 0, inst_num, - key->salt_len); - if (rc != SDP_SUCCESS) { - return (rc); - } - - if (lifetime != NULL) { - rc = sdp_attr_set_sdescriptions_lifetime(sdp_p, level, 0, inst_num, - lifetime); - } - return (rc); -} - -/* - * - * Function: gsmsdp_add_all_crypto_lines - * - * Parameters: - * - * dcb_p - pointer to the DCB whose local SDP is to be updated. - * sdp_p - pointer to SDP. - * media - pointer to fsmdef_media_t where the media transport is. - * - * Description: - * The function adds all crypto lines to the SDP. - * - * Returns: - * N/A. - */ -static void -gsmsdp_add_all_crypto_lines (fsmdef_dcb_t *dcb_p, void *sdp_p, - fsmdef_media_t *media) -{ - const char *fname = "gsmsdp_add_all_crypto_lines"; - sdp_srtp_crypto_suite_t crypto_suite; - - /* - * Add all crypto lines, currently there is only one crypto - * line to add. - */ - media->local_crypto.tag = 1; - media->local_crypto.algorithmID = GSMSDP_DEFAULT_ALGORITHM_ID; - - /* Generate key */ - gsmsdp_generate_key(media->local_crypto.algorithmID, - &media->local_crypto.key); - - /* Get the crypto suite based on the algorithm ID */ - crypto_suite = - gsmsdp_algorithmID_to_crypto_suite(media->local_crypto.algorithmID); - if (gsmsdp_add_single_crypto_attr(sdp_p, media->level, - media->local_crypto.tag, crypto_suite, &media->local_crypto.key, - GSMSDP_DEFALT_KEY_LIFETIME) != SDP_SUCCESS) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Failed to add crypto attributes\n", - dcb_p->line, dcb_p->call_id, fname); - } -} - -/* - * Function: gsmsdp_init_crypto_context - * - * Description: - * Initializes crypto context. - * - * Parameters: - * media - pointer to the fsmdef_media_t for the media entry. - * - * Returns: - * none - */ -static void -gsmsdp_init_crypto_context (fsmdef_media_t *media) -{ - /* initialize local crypto parameters */ - media->local_crypto.tag = SDP_INVALID_VALUE; - media->local_crypto.algorithmID = VCM_NO_ENCRYPTION; - media->local_crypto.key.key_len = 0; - media->local_crypto.key.salt_len = 0; - - /* Initialized negotiated crypto parameter */ - media->negotiated_crypto.tag = SDP_INVALID_VALUE; - media->negotiated_crypto.algorithmID = VCM_NO_ENCRYPTION; - media->negotiated_crypto.tx_key.key_len = 0; - media->negotiated_crypto.tx_key.salt_len = 0; - media->negotiated_crypto.rx_key.key_len = 0; - media->negotiated_crypto.rx_key.salt_len = 0; - - media->negotiated_crypto.flags = 0; -} - -/* - * Function: gsmsdp_init_sdp_media_transport - * - * Description: - * The prepares or initializes crypto context for a fresh negotiation. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * sdp - pointer to SDP (void) - * media - pointer to the fsmdef_media_t for the media entry. - * - * Returns: - * N/A - */ -void -gsmsdp_init_sdp_media_transport (fsmdef_dcb_t *dcb_p, void *sdp_p, - fsmdef_media_t *media) -{ - int rtpsavpf = 0; - int sdpmode = 0; - - /* Initialize crypto context */ - gsmsdp_init_crypto_context(media); - - config_get_value(CFGID_RTPSAVPF, &rtpsavpf, sizeof(rtpsavpf)); - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (SDP_MEDIA_APPLICATION == media->type) { - media->transport = SDP_TRANSPORT_SCTPDTLS; - } else if (rtpsavpf) { - media->transport = SDP_TRANSPORT_RTPSAVPF; - } else if (sdpmode) { - media->transport = SDP_TRANSPORT_RTPSAVP; - } else if ((sip_regmgr_get_sec_level(dcb_p->line) != ENCRYPTED) || - (!FSM_CHK_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY))) { - /* - * The signaling is not encrypted or this media can not support - * security. - */ - media->transport = SDP_TRANSPORT_RTPAVP; - } else { - media->transport = SDP_TRANSPORT_RTPSAVP; - } -} - -/* - * Function: gsmsdp_reset_sdp_media_transport - * - * Description: - * The function resets media transport during mid call such as resume. - * The media transport may change from the current negotiated media. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * sdp - pointer to SDP (void) - * media - pointer to fsmdef_media_t where the media transport is. - * hold - indicates call is being hold - * - * Returns: - * N/A. - */ -void -gsmsdp_reset_sdp_media_transport (fsmdef_dcb_t *dcb_p, void *sdp_p, - fsmdef_media_t *media, boolean hold) -{ - if (hold) { - /* We are sending out hold, uses the same transport as negotiated */ - } else { - /* Resuming a call */ - if ((sip_regmgr_get_cc_mode(dcb_p->line) == REG_MODE_CCM)) { - /* - * In CCM mode, try to resume with full SRTP offer again - * if the current signalling is encrypted. In CCM mode, - * CCM will assist in crypto negotiation and fall back to - * RTP if necessary. This is useful when resuming a different - * end point and the new end point support SRTP even when the - * current media is not SRTP. For an example, when holding - * a call that was transferred to a new end point which - * it may be able to support SRTP. - */ - gsmsdp_init_sdp_media_transport(dcb_p, - dcb_p->sdp ? dcb_p->sdp->src_sdp : NULL, - media); - } else { - /* - * In non CCM mode, we do not know whether the new end - * point supports SRTP fall back and no assistance from - * CCM in negotiating of the crypto parameter, play safe by - * resuming with the same media transport. - */ - } - } -} - -/* - * Function: gsmsdp_set_media_transport_for_option - * - * Parameters: - * sdp - pointer to SDP (void). - * level - the media level of the SDP where the media transport is. - * - * Description: - * The function sets media transport for OPTION message. - * - * Returns: - * N/A. - */ -void -gsmsdp_set_media_transport_for_option (void *sdp_p, uint16_t level) -{ - const char *fname = "gsmsdp_set_media_transport_for_option"; - uint32_t algorithmID; - vcm_crypto_key_t key; - sdp_srtp_crypto_suite_t crypto_suite; - - - /* Use line 1 to determine whether to have RTP or SRTP */ - if (sip_regmgr_get_sec_level(1) != ENCRYPTED) { - /* line one is none secure, use RTP */ - (void) sdp_set_media_transport(sdp_p, level, SDP_TRANSPORT_RTPAVP); - return; - } - - /* Advertise SRTP with default attributes */ - (void) sdp_set_media_transport(sdp_p, level, SDP_TRANSPORT_RTPSAVP); - - /* Generate dummy key */ - crypto_suite = SDP_SRTP_AES_CM_128_HMAC_SHA1_32; - algorithmID = gsmsdp_crypto_suite_to_algorithmID(crypto_suite); - gsmsdp_generate_key(algorithmID, &key); - - /* Add crypto attributes */ - if (gsmsdp_add_single_crypto_attr(sdp_p, level, 1, crypto_suite, &key, - GSMSDP_DEFALT_KEY_LIFETIME) != SDP_SUCCESS) { - GSM_DEBUG_ERROR(GSM_F_PREFIX - "Failed to add crypto attributes\n", - fname); - } -} - -/* - * Function: gsmsdp_update_local_sdp_media_transport - * - * Description: - * The function updates the crypto attributes to the local SDP. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * sdp - pointer to SDP (void) - * media - pointer to fsmdef_media_t where the media transport is. - * sdp_transport_e - current media transport - * all - indicates that the update for new offer SDP - * - * Returns: - * none - */ -void -gsmsdp_update_local_sdp_media_transport (fsmdef_dcb_t *dcb_p, void *sdp_p, - fsmdef_media_t *media, - sdp_transport_e transport, boolean all) -{ - const char *fname = "gsmsdp_update_local_sdp_media_transport"; - sdp_srtp_crypto_suite_t crypto_suite; - uint16_t level; - - level = media->level; - /* Get the current transport before delete the media line */ - if (transport == SDP_TRANSPORT_INVALID) { - /* - * The transport is not specified, get it from the negotiated - * transport. This condition can occur when receive initial - * offered SDP. - */ - transport = media->transport; - } - - /* - * set media transport in local SDP only first time so that we remember what we offered. - */ - if (sdp_get_media_transport(sdp_p, level) == SDP_TRANSPORT_INVALID) { - (void) sdp_set_media_transport(sdp_p, level, transport); - } - - if (transport != SDP_TRANSPORT_RTPSAVP) { - /* - * transport is not SRTP, if this is the fall back to RTP then - * the existing crypto lines should have been removed by the - * media transport negotiation and thus no code is added here. - * The reason for this is not to call to the remove all crypto - * line all the time i.e. only removed them when related to - * SRTP media transport. - */ - return; - } - - /* Add crypto attributes to local SDP. */ - if (all || (media->negotiated_crypto.tag == SDP_INVALID_VALUE)) { - /* This is new offer or mid call media change occurs , - * or could be the result of sending full offer during mid-call invite - * without SDP (delayed media invite) as well - */ - if (media->negotiated_crypto.tag == SDP_INVALID_VALUE) { - /* - * This is the first time or fresh offering add all crypto - * lines. - */ - gsmsdp_add_all_crypto_lines(dcb_p, sdp_p, media); - return; - } else { - /* Fall through below and use existing crypto parameters */ - } - } - - /* - * tag and algorithm ID are from the negotiated crypto parameters. - */ - crypto_suite = - gsmsdp_algorithmID_to_crypto_suite( - media->negotiated_crypto.algorithmID); - if (gsmsdp_add_single_crypto_attr(sdp_p, level, - media->negotiated_crypto.tag, - crypto_suite, - &media->negotiated_crypto.tx_key, - GSMSDP_DEFALT_KEY_LIFETIME) - != SDP_SUCCESS) { - GSM_DEBUG_ERROR(GSM_L_C_F_PREFIX - "Failed to add crypto attributes\n", - dcb_p->line, dcb_p->call_id, fname); - } -} - -/* - * Function: gsmsdp_update_crypto_transmit_key - * - * Description: - * The function updates transmit key for SRTP session. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * media - pointer to fsmdef_media_t where the media transport is. - * offer - boolean indicates it is an offer - * initial_offer - boolean indicates it is an initial offer - * direction - new offered media direction - * - * Returns: - * none - */ -void -gsmsdp_update_crypto_transmit_key (fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - boolean offer, - boolean initial_offer, - sdp_direction_e direction) -{ - const char *fname = "gsmsdp_update_crypto_transmit_key"; - boolean generate_key = FALSE; - - if (media->transport != SDP_TRANSPORT_RTPSAVP) { - return; - } - - if (initial_offer || offer) { - /* This is an offer SDP, see if a new key needs to be generated */ - if (initial_offer) { - /* An initial offer always needs new key */ - generate_key = TRUE; - } else if ((util_compare_ip(&(media->previous_sdp.dest_addr), - &(media->dest_addr)) == FALSE) && - media->dest_addr.type != CPR_IP_ADDR_INVALID) { - //Todo IPv6: IPv6 does not support 0.0.0.0 hold. - - GSM_DEBUG(DEB_L_C_F_PREFIX - "Received offer with dest. address changes\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - /* - * This is just an offer and the destination address changes to - * is not 0.0.0.0 (hold) address, new key may be needed. There - * is a scenario where we get a delay media INVITE during the - * resume call (from the CCM for an example) and we have sent - * out 200 OK (offer SDP) with crypto parameters. Upon receiving - * ACK with SDP, the SIP stack in this notify GSM as a - * FEATURE MEDIA to GSM. GSM treats this as an offer SDP. - * This code path is entered with offer flag set where it should - * be an answer to our 200 OK offer early on. Check for this - * condition to see if we have an offer sent prior and if so - * do not generate new key if we already sent an offer out - * and has not get and answer SDP. Otherwise we will be generating - * a new key and do not sent out the key to the remote end which - * result in wrong local transmit key is being used. - */ - if (gsmsdp_local_offer_srtp(media)) { - /* - * We have sent out an offer but has not got an answer, - * use the already generated key - */ - media->negotiated_crypto.tx_key = media->local_crypto.key; - GSM_DEBUG(DEB_L_C_F_PREFIX - "Local offered SDP has been sent, use offered key\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } else { - generate_key = TRUE; - } - } else if ((media->direction == SDP_DIRECTION_INACTIVE) && - (direction != SDP_DIRECTION_INACTIVE)) { - if (!gsmsdp_local_offer_srtp(media)) { - /* - * Received an offer that changes the direction from - * inactive to some thing other than inactive, then - * generate a new key. The phone could be transferred - * to a new endpoint without destination address changes. - * This is possible if there is a passthrough MTP in - * between. The remote end point may be changed - * behind MTP but from this phone the destination addr. - * stays the same. - */ - generate_key = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX - "Received direction changes from inactive\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - } else if (media->negotiated_crypto.tx_key.key_len == 0) { - if (gsmsdp_local_offer_srtp(media)) { - /* - * This an answer to our offer sent similar to - * the address change scenario above (delayed media, we - * sent SDP in 200OK and got SDP in ACK but GSM treats - * SDP in ACK case as an offer rather than an answer). - * Use the key in the offered SDP. - */ - media->negotiated_crypto.tx_key = media->local_crypto.key; - GSM_DEBUG(DEB_L_C_F_PREFIX - "Local offered SDP has been sent, use offered key\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } else { - /* - * Do not have negotiated transmit key. - * - * The scenario that this can occur is when the - * call transition from RTP to SRTP in mid-call. - */ - generate_key = TRUE; - GSM_DEBUG(DEB_L_C_F_PREFIX - "Received offer but no tx key, generate new key\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - } else { - /* No need to generate new key */ - } - if (generate_key) { - /* - * This is an initial offer or mid-call offer and - * some conditions changes , generate a new transmit key. - */ - gsmsdp_generate_key(media->negotiated_crypto.algorithmID, - &media->negotiated_crypto.tx_key); - GSM_DEBUG(DEB_L_C_F_PREFIX - "Generate tx key\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - media->negotiated_crypto.flags |= FSMDEF_CRYPTO_TX_CHANGE; - } - } else { - /* This is an answer to our offer, set the tx key to the local key - * - * Note that when adding support to offer multiple crypto suite to - * the remote end, we need to select the corresponding local offer - * SDP from the matching tag. At this point, we only support one - * crypto to offer and just get to that entry - */ - if (gsmdsp_cmp_key(&media->local_crypto.key, - &media->negotiated_crypto.tx_key)) { - media->negotiated_crypto.flags |= FSMDEF_CRYPTO_TX_CHANGE; - GSM_DEBUG(DEB_L_C_F_PREFIX - "tx key changes in answered SDP\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - media->negotiated_crypto.tx_key = media->local_crypto.key; /* tx key */ - } - /* Complete offer/answer, clear condition that we have made an offered */ - gsmsdp_clear_local_offer_srtp(media); -} - -/* - * Function: gsmsdp_update_negotiated_transport - * - * Description: - * The function updates the transport and crypto parameters after the - * all negotiated parameters has been done. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t - * sdp - pointer to cc_sdp_t structure - * level - pointer to fsmdef_media_t where the media transport is. - * crypto_inst - pointer to crypto attribute instance number of the - * selected crypto line - * sdp_transport_e - negotiated media transport - * - * Returns: - * none - */ -void -gsmsdp_update_negotiated_transport (fsmdef_dcb_t *dcb_p, - cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, - uint16_t crypto_inst, - sdp_transport_e transport, - uint16 dest_level) -{ - const char *fname = "gsmsdp_update_negotiated_transport"; - sdp_srtp_crypto_suite_t crypto_suite; - void *dest_sdp = cc_sdp_p->dest_sdp; - vcm_crypto_algorithmID algorithmID; - vcm_crypto_key_t key; - uint16_t level; - - level = dest_level; - /* - * Also detect changes of the crypto parameters for Tx and Rx. - * It is done here to avoid adding last crypto parameters for Tx and - * Rx into the dcb structure since the parameters include key which - * are rather long. This minimize the dcb's increasing. - */ - /* reset changes flags */ - media->negotiated_crypto.flags &= ~(FSMDEF_CRYPTO_TX_CHANGE | - FSMDEF_CRYPTO_RX_CHANGE); - /* - * Detect the transport change between RTP to SRTP or ignore - * the first time transition from invalid transport. This - * prevents the change bits to be set for first time in RTP - * connection and causes the RX to be closed unnecessary. - */ - if ((media->transport != SDP_TRANSPORT_INVALID) && - (transport != media->transport)) { - /* We could fallback to RTP or resume from RTP to SRTP */ - media->negotiated_crypto.flags |= (FSMDEF_CRYPTO_TX_CHANGE | - FSMDEF_CRYPTO_RX_CHANGE); - GSM_DEBUG(DEB_L_C_F_PREFIX - "SDP media transport changed to %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), transport); - } - /* Update the negotiated media transport */ - media->transport = transport; - - if (media->transport != SDP_TRANSPORT_RTPSAVP) { - /* - * negotiate media transport to RTP, clear local offer SDP - * condition. - */ - GSM_DEBUG(DEB_L_C_F_PREFIX - "SDP media transport is RTP\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - return; - } - - GSM_DEBUG(DEB_L_C_F_PREFIX "SDP media transport is SRTP\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - - /* - * Get the crypto parameters from the remote's SDP, - * the parameters should already be validated during the - * media transport negotiation. Update the negotiated crypto parameter. - */ - crypto_suite = sdp_attr_get_sdescriptions_crypto_suite(dest_sdp, level, - 0, crypto_inst); - - /* Save the negotiated algorithm ID */ - algorithmID = gsmsdp_crypto_suite_to_algorithmID(crypto_suite); - if (algorithmID != media->negotiated_crypto.algorithmID) { - media->negotiated_crypto.flags |= (FSMDEF_CRYPTO_TX_CHANGE | - FSMDEF_CRYPTO_RX_CHANGE); - GSM_DEBUG(DEB_L_C_F_PREFIX "SDP algorithm ID change to %d\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), algorithmID); - } - media->negotiated_crypto.algorithmID = algorithmID; - - /* Save the negotiated crypto line tag */ - media->negotiated_crypto.tag = sdp_attr_get_sdescriptions_tag(dest_sdp, - level, 0, - crypto_inst); - - /* Get the remote's key */ - (void) gsmsdp_get_key_from_sdp(dcb_p, dest_sdp, level, crypto_inst, &key); - if (gsmdsp_cmp_key(&key, &media->negotiated_crypto.rx_key)) { - media->negotiated_crypto.flags |= FSMDEF_CRYPTO_RX_CHANGE; - GSM_DEBUG(DEB_L_C_F_PREFIX "SDP rx key changes\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - } - media->negotiated_crypto.rx_key = key; -} - -/* - * Function: gsmsdp_is_crypto_ready - * - * Parameters: - * media - pointer to fsmdef_media_t where the media transport is. - * rx - boolean indicates receiver. - * - * Description: - * The function returns to the caller whether receiver/transmitter is - * ready for open. - * - * Returns: - * TRUE - when the receiver is ready to received. - * FALSE - when the receive is not ready. - */ -boolean -gsmsdp_is_crypto_ready (fsmdef_media_t *media, boolean rx) -{ - /* - * If we offered SRTP then we need to wait for the negotiated key before - * allowing the Rx/Tx to be opened. If we did not offer (we received - * an offered SDP instead then we should have key negotiated). - */ - if (media->transport == SDP_TRANSPORT_RTPAVP || media->transport == SDP_TRANSPORT_RTPSAVPF) { - return (TRUE); - } - - /* - * Local has offered SRTP, check to see if the key is available. - */ - if (rx) { - if (media->negotiated_crypto.rx_key.key_len == 0) { - /* Have not received remote's crypto parameter yet, can't open Rx */ - return (FALSE); - } - } else { - if (media->negotiated_crypto.tx_key.key_len == 0) { - /* Have not received remote's crypto parameter yet, can't open Tx */ - return (FALSE); - } - } - /* Have remote's key */ - return (TRUE); -} - -/* - * Function: gsmsdp_is_media_encrypted - * - * Description: - * The function returns to the caller whether the media is - * encrypted or not. - * - * Parameters: - * dcb_p - pointer to the fsmdef_dcb_t. - * - * Returns: - * TRUE - when the media is encrypted. - * FALSE - when the media is not encrypted. - */ -boolean -gsmsdp_is_media_encrypted (fsmdef_dcb_t *dcb_p) -{ - fsmdef_media_t *media; - uint8_t num_encrypted; - - if (dcb_p == NULL) { - return(FALSE); - } - num_encrypted = 0; - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - - if (media->transport == SDP_TRANSPORT_RTPSAVP || media->transport == SDP_TRANSPORT_RTPSAVPF) { - num_encrypted++; - } - } - - if ((num_encrypted == 0) || - (num_encrypted != GSMSDP_MEDIA_COUNT(dcb_p))) { - /* - * the call does not have any media that is encrypted or - * there are some medias that are not encrypted. This is - * considered as non secure leg. - */ - return (FALSE); - } - return (TRUE); -} - -/* - * Function: gsmsdp_crypto_params_change - * - * Description: - * The function returns to the caller whether the crypto parameters - * change from the previous SDP or not. - * - * Parameters: - * rcv_only - If TRUE, check for receive port perspective. - * media - pointer to fsmdef_media_t where the media transport is. - * - * Returns: - * TRUE - when crypto parameters changed - * FALSE - when crypto parameters did not change - */ -boolean -gsmsdp_crypto_params_change (boolean rcv_only, fsmdef_media_t *media) -{ - if (rcv_only) { - if (media->negotiated_crypto.flags & FSMDEF_CRYPTO_RX_CHANGE) { - return (TRUE); - } - } else { - if (media->negotiated_crypto.flags & FSMDEF_CRYPTO_TX_CHANGE) { - return (TRUE); - } - } - return (FALSE); -} - -/** - * The function resets crypto parameters change status. - * - * @param[in] media - pointer to fsmdef_media_t. - * - * @return None. - * - * @pre (media not_eq NULL) - */ -void -gsmsdp_crypto_reset_params_change (fsmdef_media_t *media) -{ - media->negotiated_crypto.flags &= ~(FSMDEF_CRYPTO_RX_CHANGE | - FSMDEF_CRYPTO_TX_CHANGE); -} diff --git a/libs/sipcc/core/gsm/h/fim.h b/libs/sipcc/core/gsm/h/fim.h deleted file mode 100755 index 5eeb26a354..0000000000 --- a/libs/sipcc/core/gsm/h/fim.h +++ /dev/null @@ -1,66 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _FIM_H_ -#define _FIM_H_ - -#include "sm.h" -#include "fsm.h" - -/* - * This is an overlay structure. - * Every entity cb must have these two fields at the start of the cb - */ -typedef struct fim_cb_hdr_ { - callid_t call_id; - int state; -} fim_cb_hdr_t; - -#ifndef fim_icb_t__ -#define fim_icb_t__ -struct fim_icb_t_; -typedef struct fim_icb_t_ fim_icb_t; -#endif - -typedef void (*fim_func_t)(fim_icb_t *elem, callid_t call_id); - -typedef struct fim_scb_t_ { - fsm_types_t type; - sm_table_t *sm; - fim_func_t get_cb; - fim_func_t free_cb; -} fim_scb_t; - -struct fim_icb_t_ { - struct fim_icb_t_ *next_chn; - struct fim_icb_t_ *next_icb; - callid_t call_id; - boolean ui_locked; - void *cb; - fim_scb_t *scb; -}; - - -const char *fim_event_name(int event); -boolean fim_process_event(void *data, boolean cac_passed); -void fim_free_event(void *data); -void fim_init(void); -void fim_shutdown(void); -void fsmcnf_free_cb(fim_icb_t *icb, callid_t call_id); -void fsmxfr_free_cb(fim_icb_t *icb, callid_t call_id); -void fsmdef_free_cb(fim_icb_t *icb, callid_t call_id); -void fsmb2bcnf_free_cb(fim_icb_t *icb, callid_t call_id); - -void fim_lock_ui(callid_t call_id); -void fim_unlock_ui(callid_t call_id); - -cc_causes_t -fsm_cac_process_bw_avail_resp(void); -cc_causes_t -fsm_cac_process_bw_failed_resp(void); -cc_causes_t -fsm_cac_call_bandwidth_req(callid_t call_id, uint32_t sessions, - void *msg); - -#endif /* _FIM_H_ */ diff --git a/libs/sipcc/core/gsm/h/fsm.h b/libs/sipcc/core/gsm/h/fsm.h deleted file mode 100755 index c009179ad1..0000000000 --- a/libs/sipcc/core/gsm/h/fsm.h +++ /dev/null @@ -1,768 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _FSM_H_ -#define _FSM_H_ - -#include "cpr_types.h" -#include "sm.h" -#include "ccapi.h" -#include "vcm.h" -#include "ccsip_core.h" -#include "sll_lite.h" -#include "sessionConstants.h" -#include "ccsdp.h" - -/* TODO: BLASBERG - * fsm.h only needs the following from ccsip_core.h - * should put basic sip types into a separate hdr file -typedef enum { - ALERTING_NONE, - ALERTING_OLD, - ALERTING_TONE, - ALERTING_RING -} alertingType; -*/ - - -#define FSMCNF_MAX_CCBS (LSM_MAX_LINES) -#define FSMXFR_MAX_XCBS (LSM_MAX_LINES) -#define FSM_NO_ID (0) -#define FSMDEF_NO_DCB (NULL) -#define FSMDEF_ERR_ONHOOK_TMR_SECS (20) - -#define FSMDEF_MAX_DIGEST_ALG_LEN 10 -#define FSMDEF_MAX_DIGEST_LEN 32 * 3 - -// Should match define for SIP stack MAX_SIP_URL_LENGTH -#define FSMDEF_MAX_CALLER_ID_LEN (256) - -#ifndef fim_icb_t__ -#define fim_icb_t__ -struct fim_icb_t_; -typedef struct fim_icb_t_ fim_icb_t; -#endif - -typedef enum { - PRIMARY, - MONITOR, - LOCAL_CONF, - WHISPER_COACHING -} fsm_session_t; - -typedef enum { - DIAL_MODE_NUMERIC, - DIAL_MODE_URL -} dialMode_t; - -typedef enum { - FSMDEF_CALL_TYPE_MIN = -1, - FSMDEF_CALL_TYPE_NONE = CC_CALL_TYPE_NONE, - FSMDEF_CALL_TYPE_INCOMING = CC_CALL_TYPE_INCOMING, - FSMDEF_CALL_TYPE_OUTGOING = CC_CALL_TYPE_OUTGOING, - FSMDEF_CALL_TYPE_FORWARD = CC_CALL_TYPE_FORWARDED, - FSMDEF_CALL_TYPE_MAX -} fsmdef_call_types_t; - -typedef enum { - FSMDEF_S_MIN = -1, - FSMDEF_S_IDLE, - FSMDEF_S_COLLECT_INFO, - FSMDEF_S_CALL_SENT, - FSMDEF_S_OUTGOING_PROCEEDING, - FSMDEF_S_KPML_COLLECT_INFO, - FSMDEF_S_OUTGOING_ALERTING, - FSMDEF_S_INCOMING_ALERTING, - FSMDEF_S_CONNECTING, - FSMDEF_S_JOINING, - FSMDEF_S_CONNECTED, - FSMDEF_S_CONNECTED_MEDIA_PEND, - FSMDEF_S_RELEASING, - FSMDEF_S_HOLD_PENDING, - FSMDEF_S_HOLDING, - FSMDEF_S_RESUME_PENDING, - FSMDEF_S_PRESERVED, - FSMDEF_S_MAX -} fsmdef_states_t; - -typedef enum { - FSMDEF_MRTONE_NO_ACTION = 0, - FSMDEF_MRTONE_PLAYED_MONITOR_TONE, - FSMDEF_MRTONE_PLAYED_RECORDER_TONE, - FSMDEF_MRTONE_PLAYED_BOTH_TONES, - FSMDEF_MRTONE_RESUME_MONITOR_TONE, - FSMDEF_MRTONE_RESUME_RECORDER_TONE, - FSMDEF_MRTONE_RESUME_BOTH_TONES -} fsmdef_monrec_tone_action_e; - -typedef enum { - FSMDEF_PLAYTONE_NO_ACTION = 0, - FSMDEF_PLAYTONE_ZIP -} fsmdef_play_tone_action_e; - -/* Local crypto parameter is the local parameters to offer */ -typedef struct fsmdef_crypto_param_t_ { - int32_t tag; /* crypto attribute tag */ - vcm_crypto_algorithmID algorithmID; /* encryption algorithm. */ - vcm_crypto_key_t key; /* local key */ -} fsmdef_crypto_param_t; - -/* Negotiated crypto parameter */ -#define FSMDEF_CRYPTO_TX_CHANGE (1 << 0) /* crypto Tx parms. change */ -#define FSMDEF_CRYPTO_RX_CHANGE (1 << 1) /* crypto Tx parms. change */ -typedef struct fsmdef_negotiated_crypto_t_ { - int32_t tag; /* crypto attribute tag */ - vcm_crypto_algorithmID algorithmID; /* algorithm ID */ - vcm_crypto_key_t tx_key; /* tx key */ - vcm_crypto_key_t rx_key; /* rx key */ - uint32_t flags; /* misc. flags. */ - char algorithm[FSMDEF_MAX_DIGEST_ALG_LEN]; - char digest[FSMDEF_MAX_DIGEST_LEN]; -} fsmdef_negotiated_crypto_t; - -/* - * Saved attributes of interest from previously received SDP - */ -typedef struct fsmdef_previous_sdp_ { - uint16_t dest_port; - cpr_ip_addr_t dest_addr; - int32_t avt_payload_type; - - /* - * This field contains the number of elements in the payloads field. - */ - int32_t num_payloads; - vcm_payload_info_t* payloads; - - uint16_t packetization_period; - uint16_t max_packetization_period; - sdp_direction_e direction; - int32_t tias_bw; - int32_t profile_level; -} fsmdef_previous_sdp_t; - -typedef struct fsmdef_media_t_ { - sll_lite_node_t node; /* link node, must be first member of struct */ - media_refid_t refid; /* media reference id */ - sdp_media_e type; /* audio, video etc. media */ - sdp_addrtype_e addr_type;/* ipv4, ipv6 */ - int32_t avt_payload_type; - vcm_vad_t vad; - uint16_t packetization_period; - uint16_t max_packetization_period; - uint16_t mode; - uint16_t level; - boolean direction_set; - sdp_direction_e direction; /* current negotiated direction */ - sdp_direction_e support_direction; /* supported direction */ - sdp_transport_e transport; - uint16_t src_port; /* source port for this media stream */ - cpr_ip_addr_t src_addr; /* source addr for this media stream */ - uint16_t dest_port; /* destination port for this media stream */ - cpr_ip_addr_t dest_addr; /* destination addr for this media straam */ - /* Flag to indicate if Multicast */ - boolean is_multicast; - uint16_t multicast_port; - /* - * rcv_chan indicates if the receive media stream has been opened - */ - boolean rcv_chan; - /* - * xmit_chan indicates if the transmit media stream has been opened - */ - boolean xmit_chan; - - /* - * SRTP support. - */ - fsmdef_negotiated_crypto_t negotiated_crypto; - - /* - * Local crypto holds the local offered crypto set, keeps it in the - * dcb for fast access. The alternative to be kept in the - * SDP structure but is slower in retrieving it. In the future, - * it is possible that more than 1 crypto lines are offered but - * for now it is one. - */ - fsmdef_crypto_param_t local_crypto; - - /* - * Used to track previously received SDP for comparisons to - * newly received media to determine if RTP port recycling is - * required. Eliminates unnecessary recycling of ports which - * causes breaks in the audio stream. - */ - fsmdef_previous_sdp_t previous_sdp; - - /* - * hold tracks the hold state. The flag is a bit map so it is possible that - * the phone may have multiple holding states, ie. local and remote - */ - uint32_t hold; - /* - * Flags fields for various bit flags - */ -#define FSM_MEDIA_F_SUPPORT_SECURITY (1 << 0) /* supported security */ - uint32_t flags; - - /* - * capability index. The index into the media capbilty table - * that this media entry is coresponding to. - */ - uint8_t cap_index; - - /* Values cached from attributes */ - int32_t tias_bw; - int32_t profile_level; - - void *video; - - /* ICE Candidates */ - char **candidatesp; - int candidate_ct; - - /* - * rtcp-mux indicates media stream is muxed for RTP and RTCP - */ - boolean rtcp_mux; - - /* - * port number used in m= data channel line - */ - uint16_t sctp_port; - - /* - * Data Channel properties - */ - uint32 streams; - char *protocol; - - /* - * This field contains the number of elements in the payloads field. - */ - int32_t num_payloads; - - /* - * List of active lists of payloads negotiated - */ - vcm_payload_info_t* payloads; - -} fsmdef_media_t; - -struct fsm_fcb_t_; - -typedef struct { - callid_t call_id; - callid_t join_call_id; - line_t line; - cc_caller_id_t caller_id; - groupid_t group_id; - int digit_cnt; - fsmdef_call_types_t call_type; - fsm_session_t session; - boolean send_release; - int msgs_sent; - int msgs_rcvd; - boolean onhook_received; - - /* - * inband indicates if inband alerting is active - */ - boolean inband; - - /* - * inband_received indicates if inband alerting has been received. - * Once set, this bool stays set until dcb is reset. - */ - boolean inband_received; - - /* - * outofband tracks the payload type for outofband DTMF - */ - int outofband; - - /* - * Boolean indication of whether call was originated by phone or - * far end party. - */ - boolean inbound; - - /* - * The following data tracks the RTP info - */ - boolean remote_sdp_present; - boolean remote_sdp_in_ack; - uint16_t src_sdp_version; - cc_sdp_t *sdp; - - /* media list corresponding to m lines */ - sll_lite_list_t media_list; - - /* - * dial_mode tracks the state of the dialing mode icon, ie. alphanumeric or - * numeric - */ - dialMode_t dial_mode; - - /* - * pd_updated tracks whether or not the personal directory has - * been updated - */ - boolean pd_updated; - - /* tracks the ringing pattern to play */ - vcm_ring_mode_t alerting_ring; - - /* tracks the tone to play */ - vcm_tones_t alerting_tone; - - /* tracks the direction to play the tone. */ - uint16_t tone_direction; - - /* Was an alert-info header present, if so what did it contain */ - cc_alerting_type alert_info; - - /* used to determine when SIP stack releases the call early. */ - boolean early_error_release; - - /* used to determine when we are played a tone via the dialplan */ - boolean dialplan_tone; - - /* active tone (i.e. tone currently being played or requested to be played) */ - vcm_tones_t active_tone; - - /* indicates the action of monitor and recorder tones */ - fsmdef_monrec_tone_action_e monrec_tone_action; - - /* monitor/recorder tone direction to play out to */ - uint16_t monitor_tone_direction; - uint16_t recorder_tone_direction; - - /* indicates the action of play tone for a single time */ - fsmdef_play_tone_action_e play_tone_action; - - struct fsm_fcb_t_ *fcb; - - /* Feature that is currently active */ - cc_features_t active_feature; - - /* Reason for hold */ - cc_hold_resume_reason_e hold_reason; - - /* Feature invocation state. - * Each feature will correspond to unique bit in variable. - * Bit will be Set if feature is invoked and awaiting feature ACK. - * Bit will be Cleared if feature is ACKed or not yet invoked. - * Each array element will hold invocation state for 32 features. - * The resource manager utility is utilized to maintain the bit settings. - */ - void *feature_invocation_state; - - /* TRUE if CCM has requested phone to show ringout UI */ - boolean spoof_ringout_requested; - /* TRUE if GSM has applied ringout due to CCMs request to show ringout UI */ - boolean spoof_ringout_applied; - - /* Timer to go on hook after any call error */ - cprTimer_t err_onhook_tmr; - - /* Request pending timer */ - cprTimer_t req_pending_tmr; - - /* Ringback delay timer */ - cprTimer_t ringback_delay_tmr; - - /* - * save of orientation from callInfo to update UI at any time - * other than during call info. update such as after Tx start in - * order to update security icon. - */ - cc_orientation_e orientation; - - /* - * This boolean is used to short circuit sending UI update requests to the platform - * so that requests are only made when one of the call ui components requires - * updating. The same is done for placed call history. - */ - boolean ui_update_required; - boolean placed_call_update_required; - - boolean is_conf_call; - - cc_security_e security; - cc_policy_e policy; - - /* auto answer timer */ - cprTimer_t autoAnswerTimer; - int32_t reversionInterval; - cprTimer_t revertTimer; - - boolean dsp_out_of_resources; - - boolean selected; - - boolean select_pending; - - boolean call_not_counted_in_mnc_bt; - - /* - * The media_cap holds the current media caps of the call - */ - cc_media_cap_table_t *media_cap_tbl; - - /* - * Holds the remote stream track information to be passed to UI - */ - cc_media_remote_stream_table_t *remote_media_stream_tbl; - - /* - * Holds the local stream track information passed in from the UI - */ - cc_media_local_track_table_t *local_media_track_tbl; - -#define FSMDEF_F_HOLD_REQ_PENDING (1 << 0)/* hold feature pending */ -#define FSMDEF_F_XFER_COMPLETE (1 << 1)/* hold feature pending */ - uint32_t flags; /* misc. flags. */ - - int log_disp; - - uint8_t cur_video_avail; - sdp_direction_e video_pref; - unsigned int callref; /* Callref (CI) from CUCM */ - - char peerconnection[PC_HANDLE_SIZE]; /* A handle to the peerconnection */ - boolean peerconnection_set; - - char *ice_ufrag; - char *ice_pwd; - char ice_default_candidate_addr[MAX_IPADDR_STR_LEN]; - - char digest_alg[FSMDEF_MAX_DIGEST_ALG_LEN]; - char digest[FSMDEF_MAX_DIGEST_LEN]; - -} fsmdef_dcb_t; - -typedef enum fsm_types_t_ { - FSM_TYPE_MIN = -1, - FSM_TYPE_NONE = FSM_TYPE_MIN, - FSM_TYPE_HEAD, - FSM_TYPE_CNF, - FSM_TYPE_B2BCNF, - FSM_TYPE_XFR, - FSM_TYPE_DEF, - FSM_TYPE_MAX -} fsm_types_t; - -typedef enum fsm_hold_t_ { - FSM_HOLD_MIN = -1, - FSM_HOLD_NONE = 0, - FSM_HOLD_LCL = 1, - FSM_HOLD_MAX = 2 -} fsm_hold_t; - -typedef struct fsm_data_def_t_ { - int hold; -} fsm_data_def_t; - -typedef struct fsm_data_xfr_t_ { - int xfr_id; -} fsm_data_xfr_t; - -typedef struct fsm_data_t_ { - union { - fsm_data_def_t def; - fsm_data_xfr_t xfr; - } data; -} fsm_data_t; - -typedef struct fsmcnf_ccb_t_ { - cc_srcs_t cnf_orig; - int cnf_id; - callid_t cnf_call_id; - callid_t cns_call_id; - line_t cnf_line; - line_t cns_line; - boolean active; - boolean bridged; - -/* The following field encodes flags */ -#define JOINED 0x1 -#define XFER 0x2 -#define LCL_CNF 0x4 - uint32_t flags; - boolean cnf_ftr_ack; -} fsmcnf_ccb_t; - -typedef enum fsmxfr_types_t_ { - FSMXFR_TYPE_MIN = -1, - FSMXFR_TYPE_NONE, - FSMXFR_TYPE_XFR, - FSMXFR_TYPE_BLND_XFR, - FSMXFR_TYPE_DIR_XFR, - FSMXFR_TYPE_MAX -} fsmxfr_types_t; - -typedef enum fsmxfr_modes_t_ { - FSMXFR_MODE_MIN = -1, - FSMXFR_MODE_TRANSFEROR, - FSMXFR_MODE_TRANSFEREE, - FSMXFR_MODE_TARGET -} fsmxfr_modes_t; - -struct fsmxfr_xcb_t_; -typedef struct fsmxfr_xcb_t_ { - cc_srcs_t xfr_orig; - int xfr_id; - callid_t xfr_call_id; - callid_t cns_call_id; - line_t xfr_line; - line_t cns_line; - fsmxfr_types_t type; - cc_xfer_methods_t method; - char *dialstring; - char *queued_dialstring; - char *referred_by; - boolean active; - boolean cnf_xfr; - boolean xfer_comp_req; - fsmxfr_modes_t mode; - struct fsmxfr_xcb_t_ *xcb2; -} fsmxfr_xcb_t; - - -typedef struct fsm_fcb_t_ { - callid_t call_id; - - int state; - int old_state; - - fsm_types_t fsm_type; - - - /* - * fsmdef specific data - */ - fsmdef_dcb_t *dcb; - - /* - * fsmxfr specific data - */ - - fsmxfr_xcb_t *xcb; - /* - * fsmcnf specific data - */ - fsmcnf_ccb_t *ccb; - - /* - * fsmb2bcnf specific data - */ - fsmcnf_ccb_t *b2bccb; - -} fsm_fcb_t; - -typedef enum { - FSMDEF_MSG_MIN = -1, - FSMDEF_MSG_NONE = 0, - FSMDEF_MSG_SETUP = 1, - FSMDEF_MSG_SETUP_ACK = 2, - FSMDEF_MSG_PROCEEDING = 4, - FSMDEF_MSG_ALERTING = 8, - FSMDEF_MSG_CONNECTED = 16, - FSMDEF_MSG_CONNECTED_ACK = 32, - FSMDEF_MSG_RELEASE = 64, - FSMDEF_MSG_RELEASE_COMPLETE = 128, - FSMDEF_MSG_MAX -} fsmdef_msgs_t; - -#define FSM_FOR_ALL_CBS(cb, cbs, max_cbs) \ - for ((cb) = (cbs); (cb) <= &((cbs)[(max_cbs-1)]); (cb)++) - -#define FSM_CHK_FLAGS(flags, flag) ((flags) & (flag)) -#define FSM_SET_FLAGS(flags, flag) ((flags) |= (flag)) -#define FSM_RESET_FLAGS(flags, flag) ((flags) &= ~(flag)) -void *fsmdef_feature_timer_timeout(cc_features_t feature_id, void *); -void fsmdef_end_call(fsmdef_dcb_t *dcb, cc_causes_t cause); -void fsm_sm_ftr(cc_features_t ftr_id, cc_srcs_t src_id); -void fsm_sm_ignore_ftr(fsm_fcb_t *fcb, int fname, - cc_features_t ftr_id); -void fsm_sm_ignore_src(fsm_fcb_t *fcb, int fname, cc_srcs_t src_id); -const char *fsm_state_name(fsm_types_t type, int id); -const char *fsm_type_name(fsm_types_t type); -fsmdef_dcb_t *fsm_get_dcb(callid_t call_id); -void fsm_init_scb(fim_icb_t *icb, callid_t call_id); -fsm_fcb_t *fsm_get_fcb_by_call_id(callid_t call_id); -fsm_fcb_t *fsm_get_fcb_by_call_id_and_type(callid_t call_id, fsm_types_t type); -void -fsm_get_fcb_by_selected_or_connected_call_fcb(callid_t call_id, fsm_fcb_t **con_fcb_found, - fsm_fcb_t **sel_fcb_found); -fsm_fcb_t *fsm_get_new_fcb(callid_t call_id, fsm_types_t fsm_type); -void fsm_init(void); -void fsm_shutdown(void); -void fsm_release(fsm_fcb_t *fcb, int fname, cc_causes_t cause); -void fsm_change_state(fsm_fcb_t *fcb, int fname, int new_state); -void fsm_init_fcb(fsm_fcb_t *fcb, callid_t call_id, fsmdef_dcb_t *dcb, - fsm_types_t type); -void fsm_display_no_free_lines(void); -void fsm_display_use_line_or_join_to_complete(void); -void fsm_display_feature_unavailable(void); -void fsm_set_call_status_feature_unavailable(callid_t call_id, line_t line); - -cc_causes_t fsm_get_new_outgoing_call_context(callid_t call_id, line_t line, - fsm_fcb_t *fcb, boolean expline); -cc_causes_t fsm_get_new_incoming_call_context(callid_t call_id, fsm_fcb_t *fcb, - const char *called_number, - boolean expline); -sm_rcs_t fsmdef_release(fsm_fcb_t *fcb, cc_causes_t cause, - boolean send_release); -int fsmdef_get_call_type_by_call_id(callid_t call_id); -fsmdef_call_types_t fsmdef_get_call_id_by_call_ref(int call_ref); -fsmdef_dcb_t *fsmdef_get_dcb_by_call_id(callid_t call_id); -void fsmdef_init_dcb(fsmdef_dcb_t *dcb, callid_t call_id, - fsmdef_call_types_t call_type, - const char *called_number, line_t line, - fsm_fcb_t *fcb); -cc_causes_t fsm_set_fcb_dcbs (fsmdef_dcb_t *dcb); -fsmdef_dcb_t *fsmdef_get_new_dcb(callid_t call_id); -void fsmdef_init(void); -int fsmdef_get_active_call_cnt(callid_t callId); -fsmdef_dcb_t *fsmdef_get_connected_call(void); -boolean fsmdef_are_join_calls_on_same_line(line_t line); -boolean fsmdef_are_there_selected_calls_onotherline(line_t line); -fsmdef_dcb_t *fsmdef_get_other_dcb_by_line(callid_t call_id, line_t line); -int fsmdef_get_dcbs_in_held_state(fsmdef_dcb_t **dcb, - callid_t ignore_call_id); -sm_rcs_t fsmdef_offhook(fsm_fcb_t *fcb, cc_msgs_t msg_id, callid_t call_id, - line_t line, const char *dial_string, sm_event_t *event, - char *global_call_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, - monitor_mode_t monitor_mode); - -sm_rcs_t fsmdef_dialstring(fsm_fcb_t *fcb, const char *dialstring, - cc_redirect_t *redirect, boolean replace, - cc_call_info_t *call_info); - -fsmcnf_ccb_t *fsmcnf_get_ccb_by_call_id(callid_t call_id); -callid_t fsmcnf_get_other_call_id(fsmcnf_ccb_t *ccb, callid_t call_id); - -void fsmxfr_update_xfr_context(fsmxfr_xcb_t *xcb, callid_t old_call_id, - callid_t new_call_id); -fsmxfr_xcb_t *fsmxfr_get_xcb_by_call_id(callid_t call_id); -callid_t fsmxfr_get_other_call_id(fsmxfr_xcb_t *xcb, callid_t call_id); -fsmxfr_types_t fsmxfr_get_xfr_type(callid_t call_id); -cc_features_t fsmxfr_type_to_feature(fsmxfr_types_t type); - -#ifdef _WIN32 -extern void NotifyStateChange(callid_t callid, int32_t state); -#define NOTIFY_STATE_CHANGE(fcb,callid,state) NotifyStateChange(callid,state);dcsm_update_gsm_state(fcb,callid,state) -#else -#define NOTIFY_STATE_CHANGE(fcb,callid,state) dcsm_update_gsm_state(fcb,callid,state) -#endif - -const char *fsmdef_state_name(int id); -const char *fsmxfr_state_name(int id); -const char *fsmcnf_state_name(int id); - -void fsm_cac_init(void); -void fsmcnf_init(void); -void fsmxfr_init(void); -void fsmdef_init(void); -void fsmcnf_shutdown(void); -void fsmxfr_shutdown(void); -void fsmdef_shutdown(void); -void fsm_cac_shutdown(void); -void fsm_cac_call_release_cleanup(callid_t call_id); - -void fsmdef_reversion_timeout(callid_t call_id); -void fsm_cac_process_bw_fail_timer(void *tmr_data); -void fsmdef_auto_answer_timeout(void *); -const char *fsmb2bcnf_state_name(int id); -void fsmb2bcnf_init(void); -void fsmb2bcnf_shutdown(void); -int fsmutil_is_b2bcnf_consult_call(callid_t call_id); -callid_t fsmxfr_get_consult_call_id(callid_t call_id); -callid_t fsmb2bcnf_get_consult_call_id(callid_t call_id); -callid_t fsmb2bcnf_get_primary_call_id(callid_t call_id); -boolean fsmdef_check_if_ok_for_dial_call(line_t line); -boolean fsmdef_check_if_ok_to_ans_call(line_t line, callid_t call_id); -boolean fsmdef_check_if_ok_to_resume_call(line_t line, callid_t call_id); -boolean fsmdef_check_if_ok_to_hold_call(line_t line, callid_t call_id); -boolean fsmdef_check_if_ok_to_monitor_update_call(line_t line, callid_t call_id); -boolean fsmdef_check_if_ok_to_run_feature(line_t line, callid_t call_id); -fsmdef_dcb_t *fsmdef_get_dcb_by_call_instance_id(line_t line, - uint16 call_instance_id); -boolean fsmb2bcnf_check_if_ok_to_setup_conf (callid_t call_id); -boolean fsmdef_check_if_chaperone_call_exist (void); -void fsmdef_call_cc_state_dialing(fsmdef_dcb_t *dcb, boolean suppressStutter); -/* This macro is to identify incoming joining call */ -#define fsm_is_joining_call(feat_data) \ - ((feat_data.newcall.join.join_call_id != CC_NO_CALL_ID) && \ - ((feat_data.newcall.cause == CC_CAUSE_BARGE) || \ - (feat_data.newcall.cause == CC_CAUSE_MONITOR))) -/* These macros are for SRTP support */ -#define FSM_GET_SECURITY_STATUS(dcb) (dcb->security) -#define FSM_SET_SECURITY_STATUS(dcb, status) (dcb->security = status) -#define FSM_GET_POLICY(dcb) (dcb->policy) -#define FSM_SET_POLICY(dcb, status) (dcb->policy = status) -#define FSM_GET_CACHED_ORIENTATION(dcb) (dcb->orientation) -#define FSM_SET_CACHED_ORIENTATION(dcb, value) (dcb->orientation = value) -#define FSM_NEGOTIATED_CRYPTO_ALGORITHM_ID(media) \ - ((media->transport == SDP_TRANSPORT_RTPSAVP || \ - media->transport == SDP_TRANSPORT_RTPSAVPF) ? \ - media->negotiated_crypto.algorithmID : VCM_NO_ENCRYPTION) -#define FSM_NEGOTIATED_CRYPTO_RX_KEY(media) \ - &media->negotiated_crypto.rx_key -#define FSM_NEGOTIATED_CRYPTO_TX_KEY(media) \ - &media->negotiated_crypto.tx_key - -#define FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media) \ - media->negotiated_crypto.algorithm - -#define FSM_NEGOTIATED_CRYPTO_DIGEST(media) \ - media->negotiated_crypto.digest - -int fsmutil_get_call_attr(fsmdef_dcb_t *dcb, line_t line, callid_t call_id); -uint16_t fsmutil_get_ci_id(line_t line); -void fsmutil_init_ci_map(void); -void fsmdef_platform_dcb_init(fsmdef_dcb_t *dcb); -void fsmutil_free_all_ci_id(void); -void fsmutil_free_ci_id(uint16_t id, line_t line); -void fsmutil_set_ci_id(uint16_t id, line_t line); -void fsmutil_free_ci_map(void); -void fsmutil_show_ci_map(void); -void fsmutil_init_shown_calls_ci_map(void); -void fsmutil_free_all_shown_calls_ci_map(void); -void fsmutil_clear_shown_calls_ci_element(uint16_t id, line_t line); -void fsmutil_set_shown_calls_ci_element(uint16_t id, line_t line); -boolean fsmutil_is_shown_calls_ci_element_set(uint16_t id, line_t line); - - -callid_t fsmxfr_get_primary_call_id(callid_t call_id); -uint16_t fsmutil_get_num_selected_calls(void); -int fsmutil_is_cnf_consult_call(callid_t call_id); -int fsmutil_is_cnf_consult_leg(callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs, - uint16_t max_ccbs); -int fsmutil_is_xfr_consult_call(callid_t call_id); -int fsmutil_is_xfr_consult_leg(callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs, - uint16_t max_xcbs); -void fsmutil_init_groupid(fsmdef_dcb_t *dcb, callid_t call_id, - fsmdef_call_types_t call_type); -void fsmutil_process_feature_ack(fsmdef_dcb_t *dcb, cc_features_t feature_id); -void fsmutil_clear_all_feature_invocation_state(fsmdef_dcb_t *dcb); -void fsmutil_init_feature_invocation_state(fsmdef_dcb_t *dcb); -void fsmutil_free_feature_invocation_state(fsmdef_dcb_t *dcb); - -void fsmdef_error_onhook_timeout(void *data); - -int fsmutil_is_xfr_leg(callid_t call_id, fsmxfr_xcb_t *fsmxfr_xcbs, - unsigned short max_xcbs); -int fsmutil_is_cnf_leg(callid_t call_id, fsmcnf_ccb_t *fsmcnf_ccbs, - unsigned short max_ccbs); - -void fsm_display_control_ringin_calls(boolean hide); -void fsmdef_update_media_cap_feature_event(cc_feature_t *msg); -boolean fsmcnd_conf_call_id_valid(fsmcnf_ccb_t *ccb); - -boolean fsmdef_check_retain_fwd_info_state(void); -#endif diff --git a/libs/sipcc/core/gsm/h/gsm.h b/libs/sipcc/core/gsm/h/gsm.h deleted file mode 100755 index ba6cafccfc..0000000000 --- a/libs/sipcc/core/gsm/h/gsm.h +++ /dev/null @@ -1,59 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _GSM_H_ -#define _GSM_H_ - -#include "cpr_types.h" -#include "cpr_memory.h" -#include "cpr_ipc.h" -#include "cpr_stdio.h" - -#define GSM_ERR_MSG err_msg -typedef void(* media_timer_callback_fp) (void); -void gsm_set_media_callback(media_timer_callback_fp* callback); - -void gsm_set_initialized(void); -cpr_status_e gsm_send_msg(uint32_t cmd, cprBuffer_t buf, uint16_t len); -cprBuffer_t gsm_get_buffer(uint16_t size); -boolean gsm_is_idle(void); - -/* - * List of timers that the GSM task is responsible for. - * CPR will send a msg to the GSM task when these - * timers expire. CPR expects a timer id when the timer - * is created, this enum serves that purpose. - */ -typedef enum { - GSM_ERROR_ONHOOK_TIMER, - GSM_AUTOANSWER_TIMER, - GSM_DIAL_TIMEOUT_TIMER, - GSM_KPML_INTER_DIGIT_TIMER, - GSM_KPML_CRITICAL_DIGIT_TIMER, - GSM_KPML_EXTRA_DIGIT_TIMER, - GSM_KPML_SUBSCRIPTION_TIMER, - GSM_MULTIPART_TONES_TIMER, - GSM_CONTINUOUS_TONES_TIMER, - GSM_REQ_PENDING_TIMER, - GSM_RINGBACK_DELAY_TIMER, - GSM_REVERSION_TIMER, - GSM_FLASH_ONCE_TIMER, - GSM_CAC_FAILURE_TIMER, - GSM_TONE_DURATION_TIMER -} gsmTimerList_t; - -/* - * The common code creating the GSM timers needs to have - * access to the gsm_msg_queue variable since CPR - * needs to know where to send the timer expiration - * message. - */ -extern cprMsgQueue_t gsm_msg_queue; - -extern void kpml_process_msg(uint32_t cmd, void *msg); -extern void dp_process_msg(uint32_t cmd, void *msg); -extern void kpml_init(void); -extern void kpml_shutdown(void); - -#endif diff --git a/libs/sipcc/core/gsm/h/gsm_sdp.h b/libs/sipcc/core/gsm/h/gsm_sdp.h deleted file mode 100644 index 25ae4cfdb9..0000000000 --- a/libs/sipcc/core/gsm/h/gsm_sdp.h +++ /dev/null @@ -1,139 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _GSM_SDP_H_ -#define _GSM_SDP_H_ - - -#define GSMSDP_VERSION_STR_LEN (20) - -#define GSMSDP_MEDIA_VALID(media) \ - ((media != NULL) && (media->refid != CC_NO_MEDIA_REF_ID)) - -#define GSMSDP_MEDIA_ENABLED(media) \ - (GSMSDP_MEDIA_VALID(media) && (media->src_port != 0)) - -#define GSMSDP_MEDIA_COUNT(dcb) \ - (SLL_LITE_NODE_COUNT(&dcb->media_list)) - -#define GSMSDP_FIRST_MEDIA_ENTRY(dcb) \ - ((fsmdef_media_t *)SLL_LITE_LINK_HEAD(&dcb->media_list)) - -#define GSMSDP_NEXT_MEDIA_ENTRY(media) \ - ((fsmdef_media_t *)SLL_LITE_LINK_NEXT_NODE(media)) - -#define GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) \ - for (media = start_media; (media != NULL); \ - media = (media != end_media ? \ - GSMSDP_NEXT_MEDIA_ENTRY(media) : NULL)) - -#define GSMSDP_FOR_ALL_MEDIA(media, dcb) \ - for (media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); (media != NULL); \ - media = GSMSDP_NEXT_MEDIA_ENTRY(media)) - -typedef struct { - const char *name; - int value; -} gsmsdp_key_table_entry_t; - -typedef enum constraints_ { - OfferToReceiveAudio = 0, - OfferToReceiveVideo = 1, - VoiceActivityDetection = 2 -} constraints; - -static const gsmsdp_key_table_entry_t constraints_table[] = { - {"OfferToReceiveAudio", OfferToReceiveAudio}, - {"OfferToReceiveVideo", OfferToReceiveVideo}, - {"VoiceActivityDetection", VoiceActivityDetection} -}; - -cc_causes_t gsmsdp_create_local_sdp(fsmdef_dcb_t *dcb_p, boolean force_streams_enabled, - boolean audio, boolean video, boolean data, boolean offer); -void gsmsdp_create_options_sdp(cc_sdp_t **sdp_pp); -void gsmsdp_reset_local_sdp_media(fsmdef_dcb_t *dcb, fsmdef_media_t *media, - boolean hold); -void gsmsdp_set_local_sdp_direction(fsmdef_dcb_t *dcb_p, fsmdef_media_t *media, - sdp_direction_e direction); -void gsmsdp_set_local_hold_sdp(fsmdef_dcb_t *dcb, fsmdef_media_t *media); -void gsmsdp_set_local_resume_sdp(fsmdef_dcb_t *dcb, fsmdef_media_t *media); -cc_causes_t gsmsdp_negotiate_answer_sdp(fsm_fcb_t *fcb, - cc_msgbody_info_t *msg_body); -cc_causes_t gsmsdp_negotiate_offer_sdp(fsm_fcb_t *fcb, - cc_msgbody_info_t *msg_body, - boolean init); -cc_causes_t gsmsdp_process_offer_sdp(fsm_fcb_t *fcb, - cc_msgbody_info_t *msg_body, - boolean init); -cc_causes_t -gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer, - boolean offer, boolean notify_stream_added, boolean create_answer); - -boolean gsmsdp_sdp_differs_from_previous_sdp(boolean rcv_only, - fsmdef_media_t *media); -cc_causes_t gsmsdp_encode_sdp(cc_sdp_t *sdp_p, cc_msgbody_info_t *msg_body); -cc_causes_t gsmsdp_encode_sdp_and_update_version(fsmdef_dcb_t *dcb_p, - cc_msgbody_info_t *msg_body); -void gsmsdp_free(fsmdef_dcb_t *dcb_p); -fsmdef_media_t *gsmsdp_find_audio_media(fsmdef_dcb_t *dcb_p); - -#define gsmsdp_is_srtp_supported() (TRUE) -extern void gsmsdp_init_sdp_media_transport(fsmdef_dcb_t *dcb, - void *sdp, - fsmdef_media_t *media); -extern void gsmsdp_reset_sdp_media_transport(fsmdef_dcb_t *dcb, - void *sdp, - fsmdef_media_t *media, - boolean hold); -extern sdp_transport_e gsmsdp_negotiate_media_transport(fsmdef_dcb_t *dcb_p, - cc_sdp_t *cc_sdp_p, - boolean offer, - fsmdef_media_t *media, - uint16_t *inst_num, - uint16 level); -extern void gsmsdp_update_local_sdp_media_transport(fsmdef_dcb_t *dcb_p, - void *sdp_p, - fsmdef_media_t *media, - sdp_transport_e transport, - boolean all); -extern void gsmsdp_update_negotiated_transport(fsmdef_dcb_t *dcb_p, - cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, - uint16_t crypto_inst, - sdp_transport_e transport, - uint16 level); -extern void gsmsdp_update_crypto_transmit_key(fsmdef_dcb_t *dcb_p, - fsmdef_media_t *media, - boolean offer, - boolean initial_offer, - sdp_direction_e direction); -extern void gsmsdp_set_media_transport_for_option(void *sdp, uint16 level); -extern boolean gsmsdp_is_crypto_ready(fsmdef_media_t *media, boolean rx); -extern boolean gsmsdp_is_media_encrypted(fsmdef_dcb_t *dcb_p); -extern boolean gsmsdp_crypto_params_change(boolean rcv_only, - fsmdef_media_t *media); -extern void gsmsdp_crypto_reset_params_change(fsmdef_media_t *media); -extern void gsmsdp_cache_crypto_keys(void); -extern boolean gsmsdp_create_free_media_list(void); -extern void gsmsdp_destroy_free_media_list(void); -extern void gsmsdp_init_media_list(fsmdef_dcb_t *dcb_p); -extern void gsmsdp_clean_media_list(fsmdef_dcb_t *dcb); -extern fsmdef_media_t *gsmsdp_find_media_by_refid(fsmdef_dcb_t *dcb_p, - media_refid_t refid); -extern boolean gsmsdp_handle_media_cap_change(fsmdef_dcb_t *dcb_p, - boolean refresh, boolean hold); -extern boolean gsmsdp_update_local_sdp_media_capability(fsmdef_dcb_t *dcb_p, - boolean refresh, boolean hold); -boolean is_gsmsdp_media_ip_updated_to_latest( fsmdef_dcb_t * dcb ); - -void gsmsdp_add_remote_stream(uint16_t idx, int pc_stream_id, fsmdef_dcb_t * dcb, fsmdef_media_t *media); -cc_causes_t gsmsdp_install_peer_ice_attributes(fsm_fcb_t *fcb_p); -cc_causes_t gsmsdp_configure_dtls_data_attributes(fsm_fcb_t *fcb_p); -cc_causes_t gsmsdp_find_level_from_mid(fsmdef_dcb_t * dcb, const char * mid, uint16_t *level); -void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb, const cc_media_constraints_t* constraints); -cc_causes_t -gsmsdp_get_offered_media_types (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean *has_audio, boolean *has_video, boolean *has_data); -fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb, sdp_media_e media_type); -#endif - diff --git a/libs/sipcc/core/gsm/h/lsm.h b/libs/sipcc/core/gsm/h/lsm.h deleted file mode 100755 index b0df529747..0000000000 --- a/libs/sipcc/core/gsm/h/lsm.h +++ /dev/null @@ -1,180 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _LSM_H_ -#define _LSM_H_ - -#include "cpr_types.h" -#include "ccapi.h" -#include "uiapi.h" -#include "fsm.h" - - -#define LSM_NO_LINE (0) -#define LSM_NO_INSTANCE (0) -#define NO_LINES_AVAILABLE (0) - -/* FIXME GS - Breaking my own rule - need to figure out how to do a platform - * specific include file here - */ -#define LSM_MAX_LINES MAX_REG_LINES -#define LSM_MAX_INSTANCES (MAX_CALLS_PER_LINE-1) -#define LSM_MAX_EXP_INSTANCES MAX_CALLS_PER_LINE -#define LSM_MAX_CALLS MAX_CALLS - -#define NO_FREE_LINES_TIMEOUT (10) -#define CALL_ALERT_TIMEOUT (10) - -/* - * Used to play busy verfication tone - */ -#define BUSY_VERIFICATION_DELAY (10000) - -/* - * Temp until added to config - */ -#define TOH_DELAY (10000) - -/* - * Used to play msg waiting and stutter dialtones. - * Both tones are 100ms on/off repeating 10 and - * 3 times respectively, followed by steady dialtone. - * Due to DSP limitations we first tell the DSP to - * play the 100ms on/off pairs the correct number of - * times, set a timer, and then tell it to play dialtone. - */ -#define MSG_WAITING_DELAY (2050) -#define STUTTER_DELAY (650) - -/* - * Used to play the busy verfication tone which - * is two seconds of dialtone followed by the - * callwaiting tone every ten seconds. - */ -#define BUSY_VERIFY_DELAY (12000) - - -/* LSM states */ -typedef enum { - LSM_S_MIN = -1, - LSM_S_NONE = LSM_S_MIN, - LSM_S_IDLE, - LSM_S_PENDING, - LSM_S_OFFHOOK, - LSM_S_ONHOOK, - LSM_S_PROCEED, - LSM_S_RINGOUT, - LSM_S_RINGIN, - LSM_S_CONNECTED, - LSM_S_BUSY, - LSM_S_CONGESTION, - LSM_S_HOLDING, - LSM_S_CWT, - LSM_S_XFER, - LSM_S_ATTN_XFER, - LSM_S_CONF, - LSM_S_INVALID_NUMBER, - LSM_S_MAX -} lsm_states_t; - -boolean lsm_is_phone_idle(void); -int lsm_get_instances_available_cnt(line_t line, boolean expline); -void lsm_increment_call_chn_cnt(line_t line); -void lsm_decrement_call_chn_cnt(line_t line); -line_t lsm_get_newcall_line(line_t line); -callid_t lsm_get_active_call_id(void); -line_t lsm_get_line_by_call_id(callid_t call_id); -/* - * The lsm_get_facility_by_called_number() and the lsm_get_facility_by_line() - * below are defined to allow be used by fsm state mechine to bind the - * LSM to the FSM default state machine only. - */ -cc_causes_t lsm_get_facility_by_called_number(callid_t call_id, - const char *called_number, - line_t *free_line, - boolean expline, void *dcb); -cc_causes_t lsm_get_facility_by_line(callid_t call_id, line_t line, - boolean exp, void *dcb); -char lsm_digit2ch(int digit); -void lsm_set_active_call_id(callid_t call_id); -void lsm_init(void); -void lsm_shutdown(void); -void lsm_reset(void); -void lsm_ui_display_notify(const char *pNotifyStr, unsigned long timeout); -void lsm_ui_display_status(const char *pStatusStr, line_t line, - callid_t call_id); -string_t lsm_parse_displaystr(string_t displaystr); -void lsm_speaker_mode(short mode); -void lsm_add_remote_stream (line_t line, callid_t call_id, fsmdef_media_t *media, int *pc_stream_id); - -#ifdef _WIN32 -void terminate_active_calls(void); -#endif - -const char *lsm_state_name(lsm_states_t id); -void lsm_set_cfwd_all_nonccm(line_t line, char *callfwd_dialstring); -void lsm_set_cfwd_all_ccm(line_t line, char *callfwd_dialstring); -void lsm_clear_cfwd_all_nonccm(line_t line); -void lsm_clear_cfwd_all_ccm(line_t line); -int lsm_check_cfwd_all_nonccm(line_t line); -int lsm_check_cfwd_all_ccm(line_t line); -char *lsm_is_phone_forwarded(line_t line); -void lsm_tmr_tones_callback(void *); -void lsm_update_placed_callinfo(void *dcb); -void lsm_start_multipart_tone_timer(vcm_tones_t tone, uint32_t delay, - callid_t callId); -void lsm_start_continuous_tone_timer(vcm_tones_t tone, uint32_t delay, - callid_t callId); -void lsm_start_tone_duration_timer(vcm_tones_t tone, uint32_t delay, - cc_call_handle_t call_handle); -void lsm_stop_multipart_tone_timer(void); -void lsm_stop_continuous_tone_timer(void); -void lsm_stop_tone_duration_timer(void); -void lsm_tone_duration_tmr_callback(void *data); -void lsm_tone_start_with_duration (vcm_tones_t tone, short alert_info, cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction, uint32_t duration); -void lsm_update_active_tone(vcm_tones_t tone, callid_t call_id); -boolean lsm_is_tx_channel_opened(callid_t call_id); -void lsm_update_monrec_tone_action (vcm_tones_t tone, callid_t call_id, uint16_t direction); -void lsm_downgrade_monrec_tone_action(vcm_tones_t tone, callid_t call_id); -char *lsm_get_gdialed_digits(); -void lsm_set_hold_ringback_status(callid_t call_id, boolean ringback_status); - -extern callid_t lsm_get_ui_id(callid_t call_id); -extern cc_call_handle_t lsm_get_ms_ui_call_handle(line_t line, callid_t call_id, callid_t ui_id); -extern void lsm_set_ui_id(callid_t call_id, callid_t ui_id); -extern lsm_states_t lsm_get_state(callid_t call_id); - -extern void lsm_set_lcb_dusting_call(callid_t call_id); -extern void lsm_set_lcb_call_priority(callid_t call_id); -extern boolean lsm_is_it_priority_call(callid_t call_id); -extern void lsm_play_tone(cc_features_t feature_id); -extern boolean lsm_callwaiting(void); -extern void lsm_display_control_ringin_call (callid_t call_id, line_t line, boolean hide); -extern line_t lsm_find_next_available_line(line_t line, boolean same_dn, boolean incoming); -extern line_t lsm_get_available_line (boolean incoming); -extern boolean lsm_is_line_available(line_t line, boolean incoming); -extern void lsm_ui_display_notify_str_index(int str_index); -extern cc_causes_t lsm_allocate_call_bandwidth(callid_t call_id, int sessions); -extern void lsm_update_gcid(callid_t call_id, char * gcid); -extern void lsm_set_lcb_prevent_ringing(callid_t call_id); -extern void lsm_remove_lcb_prevent_ringing(callid_t call_id); -extern void lsm_set_lcb_dialed_str_flag(callid_t call_id); -void lsm_update_video_avail(line_t line, callid_t call_id, int dir); -void lsm_update_video_offered(line_t line, callid_t call_id, int dir); -callid_t lsm_get_callid_from_ui_id (callid_t uid); -void lsm_set_video_mute (callid_t call_id, int mute); -int lsm_get_video_mute (callid_t call_id); -void lsm_set_video_window (callid_t call_id, int flags, int x, int y, int h, int w); -void lsm_get_video_window (callid_t call_id, int *flags, int *x, int *y, int *h, int *w); -boolean lsm_is_kpml_subscribed (callid_t call_id); -void -lsm_util_tone_start_with_speaker_as_backup (vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction); - -void lsm_data_channel_negotiated (line_t line, callid_t call_id, fsmdef_media_t *media, int *pc_stream_id); - -#endif //_LSM_H_ - diff --git a/libs/sipcc/core/gsm/h/lsm_private.h b/libs/sipcc/core/gsm/h/lsm_private.h deleted file mode 100644 index 438cc869a6..0000000000 --- a/libs/sipcc/core/gsm/h/lsm_private.h +++ /dev/null @@ -1,58 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _LSM_PRIV_H_ -#define _LSM_PRIV_H_ - -#include "phone_types.h" -#include "ccapi.h" - -#define LSM_ERR_MSG err_msg - -#define LSM_DEFAULT_LINE (1) -#define LSM_DEFAULT_INSTANCE (1) -#define LSM_DEFAULT_PLANE (1) -#define LSM_DEFAULT_SPEAKER (0) - -#define LSM_MAX_LCBS (LSM_MAX_CALLS) - -#define LSM_FLAGS_SECURE_MEDIA (1 << 0) /* encrypted tx media */ -#define LSM_FLAGS_SECURE_MEDIA_UPDATE (1 << 1) /* update secure media icon needed */ -#define LSM_FLAGS_ANSWER_PENDING (1 << 2) /* answer is pending */ -#define LSM_FLAGS_DIALED_STRING (1 << 3) /* dialed a string */ -#define LSM_FLAGS_CALL_PRIORITY_URGENT (1 << 4) -#define LSM_FLAGS_PREVENT_RINGING (1 << 5) -#define LSM_FLAGS_DUSTING (1 << 6) /* the call is a dusting call */ - - -typedef struct lsm_lcb_t_ { - callid_t call_id; - line_t line; - call_events previous_call_event; - lsm_states_t state; - int mru; - boolean enable_ringback; - callid_t ui_id; - uint32_t flags; - fsmdef_dcb_t *dcb; /* the corresponding DCB chain for this lcm */ - char *gcid; /*global call identifier */ - int vid_mute; - int vid_flags; - int vid_x; - int vid_y; - int vid_h; - int vid_w; -} lsm_lcb_t; - -typedef struct lsm_info_t_ { - int call_in_progress; - callid_t active_call_id; - int active_call_plane; - line_t primary_line; - int speaker; -} lsm_info_t; - -lsm_lcb_t *lsm_get_lcb_by_call_id(callid_t call_id); - -#endif diff --git a/libs/sipcc/core/gsm/h/sm.h b/libs/sipcc/core/gsm/h/sm.h deleted file mode 100755 index 840aced0df..0000000000 --- a/libs/sipcc/core/gsm/h/sm.h +++ /dev/null @@ -1,44 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SM_H_ -#define _SM_H_ - -#include "phone_debug.h" - -typedef enum { - SM_RC_MIN = -2, - SM_RC_ERROR = -1, - SM_RC_SUCCESS, - SM_RC_CONT, - SM_RC_DEF_CONT, - SM_RC_END, - SM_RC_CLEANUP, - SM_RC_FSM_ERROR, - SM_RC_CSM_ERROR, - SM_RC_MAX -} sm_rcs_t; - -typedef struct _sm_event_t { - int state; - int event; - void *data; - void *msg; -} sm_event_t; - -typedef sm_rcs_t (*sm_function_t)(sm_event_t *event); - -typedef struct _sm_table_t { - int min_state; - int max_state; - int min_event; - int max_event; - sm_function_t *table; -} sm_table_t; - -sm_rcs_t sm_process_event(sm_table_t *tbl, sm_event_t *event ); -sm_rcs_t sm_process_event2(int state_id, int event_id, sm_table_t *tbl, - void *msg, void *cb); - -#endif diff --git a/libs/sipcc/core/gsm/lsm.c b/libs/sipcc/core/gsm/lsm.c deleted file mode 100755 index f55e04b1c6..0000000000 --- a/libs/sipcc/core/gsm/lsm.c +++ /dev/null @@ -1,6610 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_locks.h" -#include "cpr_stdio.h" -#include "cpr_timers.h" -#include "cpr_in.h" -#include "cpr_errno.h" -#include "phone_types.h" -#include "phone.h" -#include "sdp.h" -#include "lsm.h" -#include "phone_debug.h" -#include "fsm.h" -#include "gsm_sdp.h" -#include "vcm.h" -#include "ccsip_pmh.h" -#include "dtmf.h" -#include "debug.h" -#include "rtp_defs.h" -#include "lsm_private.h" -#include "dialplanint.h" -#include "kpmlmap.h" -#include "prot_configmgr.h" -#include "dialplan.h" -#include "sip_interface_regmgr.h" -#include "gsm.h" -#include "phntask.h" -#include "fim.h" -#include "util_string.h" -#include "platform_api.h" - -#ifndef NO -#define NO (0) -#endif - -#ifndef YES -#define YES (1) -#endif - -#define CALL_INFO_NONE (string_t)"" - -#define FROM_NOTIFY_PRI 1 // Same as SCCP phone behavior -#define LSM_DISPLAY_STR_LEN 256 - -static cc_rcs_t lsm_stop_tone (lsm_lcb_t *lcb, cc_action_data_tone_t *data); - -extern cc_media_cap_table_t g_media_table; - -static lsm_lcb_t *lsm_lcbs; -static uint32_t lsm_call_perline[MAX_REG_LINES]; -boolean lsm_mnc_reached[MAX_REG_LINES]; // maxnumcalls reached -static boolean lsm_bt_reached[MAX_REG_LINES]; //busy trigger reached - -/* This variable is used locally to reflect the CFA state (set/clear) - * when in CCM mode. - */ -static boolean cfwdall_state_in_ccm_mode[MAX_REG_LINES+1] ; - -static const char *lsm_state_names[LSM_S_MAX] = { - "IDLE", - "PENDING", - "OFFHOOK", - "ONHOOK", - "PROCEED", - "RINGOUT", - "RINGIN", - "CONNECTED", - "BUSY", - "CONGESTION", - "HOLDING", - "CWT", - "XFER", - "ATTN_XFER", - "CONF", - "INVALID_NUMBER" -}; - -static const char *cc_state_names[] = { - "OFFHOOK", - "DIALING", - "DIALING_COMPLETED", - "CALL_SENT", - "FAR_END_PROCEEDING", - "FAR_END_ALERTING", - "CALL_RECEIVED", - "ALERTING", - "ANSWERED", - "CONNECTED", - "HOLD", - "RESUME", - "ONHOOK", - "CALL_FAILED", - "HOLD_REVERT", - "STATE_UNKNOWN" -}; - - -static const char *cc_action_names[] = { - "SPEAKER", - "DIAL_MODE", - "MWI", - "MWI_LAMP", - "OPEN_RCV", - "UPDATE_UI", - "MEDIA", - "RINGER", - "LINE_RINGER", - "PLAY_TONE", - "STOP_TONE", - "STOP_MEDIA", - "START_RCV", - "ANSWER_PENDING", - "PLAY_BLF_ALERT_TONE" -}; - -/* names are corresponds to vcm_ring_mode_t structure */ -static const char *vm_alert_names[] = { - "NONE", -// "RINGER_OFF", - "VCM_RING_OFF", - "VCM_INSIDE_RING", - "VCM_OUTSIDE_RING", - "VCM_FEATURE_RING", - "VCM_BELLCORE_DR1", - "VCM_RING_OFFSET", - "VCM_BELLCORE_DR2", - "VCM_BELLCORE_DR3", - "VCM_BELLCORE_DR4", - "VCM_BELLCORE_DR5", - "VCM_BELLCORE_MAX", - "VCM_FLASHONLY_RING", - "VCM_STATION_PRECEDENCE_RING", - "VCM_MAX_RING" -}; - -/* Enum just to make code read better */ -/* the following values must be in sync with the values listed in edcs-387610 */ -typedef enum { - DISABLE = 1, - FLASH_ONLY = 2, - RING_ONCE = 3, - RING = 4, - BEEP_ONLY = 5 -} config_value_type_t; - -cprTimer_t lsm_tmr_tones; -cprTimer_t lsm_continuous_tmr_tones; -cprTimer_t lsm_tone_duration_tmr; -static uint32_t lsm_tmr_tones_ticks; -static int callWaitingDelay; -static int ringSettingIdle; -static int ringSettingActive; - -/* Ring mode set by remote-cc app */ -static cc_rcc_ring_mode_e cc_line_ringer_mode[MAX_REG_LINES+1] = - {CC_RING_DEFAULT}; -// Following data has to be non-stack b/c the way SIP stack uses it. -// It is used by the lsm_is_phone_forwarded() function only. -static char cfwdall_url[MAX_URL_LENGTH]; - -static void lsm_update_inalert_status(line_t line, callid_t call_id, - cc_state_data_alerting_t * data, - boolean notify); -static void lsm_util_start_tone(vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction); - -const char * -lsm_state_name (lsm_states_t id) -{ - if ((id <= LSM_S_MIN) || (id >= LSM_S_MAX)) { - return get_debug_string(GSM_UNDEFINED); - } - - return (lsm_state_names[id]); -} - - -static const char * -cc_state_name (cc_states_t id) -{ - if ((id <= CC_STATE_MIN) || (id >= CC_STATE_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (cc_state_names[id]); -} - - -static const char * -cc_action_name (cc_actions_t id) -{ - if ((id <= CC_ACTION_MIN) || (id >= CC_ACTION_MAX)) { - return (get_debug_string(GSM_UNDEFINED)); - } - - return (cc_action_names[id]); -} - - -char -lsm_digit2ch (int digit) -{ - switch (digit) { - case 0x0: - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - case 0x8: - case 0x9: - return (char)(digit + '0'); - case 0x0e: - return ('*'); - case 0x0f: - return ('#'); - default: - return ('x'); - } -} - - -void -lsm_debug_entry (callid_t call_id, line_t line, const char *fname) -{ - LSM_DEBUG(get_debug_string(LSM_DBG_ENTRY), call_id, line, fname); -} - -static void -lsm_ui_call_state (call_events event, line_t line, lsm_lcb_t *lcb, cc_causes_t cause) -{ - if (lcb->previous_call_event != event) { - lcb->previous_call_event = event; - - /* For local conference case, the second call is hidden - * so do not show that when the call is held, resumed, - * or moved to other state. This should be done only - * when local bridge is active - */ - ui_call_state(event, line, lcb->ui_id, cause); - } - else if(event == evConnected) { - //This is for Chaperone Conference case, if conference changed to a normal call, - //then need to update the call state to refresh the key's status. like re-enable - //Confrn key - ui_call_state(event, line, lcb->ui_id, cause); - } -} - -/** - * This function will control the display of the ringingin call based on the hide arg. - * - * @param[in] call_id - call id - * @param[in] line - line on which call is ringing. - * @param[in] hide - whether to hide or not - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) and (line != 0) - */ -void lsm_display_control_ringin_call (callid_t call_id, line_t line, boolean hide) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - ui_call_state(evRingIn, line, lcb->ui_id, CC_CAUSE_NORMAL); - } -} - -/** - * This function will be invoked by DEF SM to set if it is a dusting call. - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_set_lcb_dusting_call (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_DUSTING); - } -} - -/** - * This function will be invoked by DEF SM to set call priority. - * - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_set_lcb_call_priority (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_CALL_PRIORITY_URGENT); - } -} - - -/** - * This function sets the LSM_FLAGS_DIALED_STRING bit in lcb->flags - * - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_set_lcb_dialed_str_flag (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_DIALED_STRING); - } -} - -/** - * This function will be invoked by DEF SM to set gcid in lcb. - * - * @param[in] call_id - GSM call id. - * @param[in] gcid - GCID provided by CUCM. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_update_gcid (callid_t call_id, char * gcid) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - if (lcb->gcid == NULL) { - lcb->gcid = (char *)cpr_malloc(CC_GCID_LEN); - sstrncpy(lcb->gcid, gcid, CC_GCID_LEN); - } - } - -} -/** - * This function will be invoked by DEF SM. - * it will check if there is a RINGIN call - * with the same GCID. If so, it will set a flag to prevent ringing. - * - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -void lsm_set_lcb_prevent_ringing (callid_t call_id) -{ - lsm_lcb_t *lcb; - char *gcid; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return; - } - - gcid = lcb->gcid; - if (gcid == NULL) { - return; - } - - LSM_DEBUG(DEB_L_C_F_PREFIX"gcid=%d.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, call_id, "lsm_set_lcb_prevent_ringing"), gcid); - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->state == LSM_S_RINGIN) { - if ((lcb->gcid != NULL) && (strncmp(gcid, lcb->gcid, CC_GCID_LEN) == 0)) { - LSM_DEBUG(DEB_L_C_F_PREFIX"found ringing call.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, "lsm_set_lcb_prevent_ringing"), gcid); - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_PREVENT_RINGING); - } - break; - } - } -} - -void lsm_remove_lcb_prevent_ringing (callid_t call_id) -{ - lsm_lcb_t *lcb; - char *gcid; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return; - } - - gcid = lcb->gcid; - if (gcid == NULL) { - return; - } - - LSM_DEBUG(DEB_L_C_F_PREFIX"gcid=%d.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, call_id, "lsm_remove_lcb_prevent_ringing"), gcid); - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->state == LSM_S_RINGIN) { - if ((lcb->gcid != NULL) && (strncmp(gcid, lcb->gcid, CC_GCID_LEN) == 0)) { - //FSM_RESET_FLAGS(lcb->flags, LSM_FLAGS_ANSWER_PENDING); - lcb->flags = 0; - LSM_DEBUG(DEB_L_C_F_PREFIX"found ringing call, gcid=%d, lcb->flags=%d.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, "lsm_remove_lcb_prevent_ringing"), gcid, lcb->flags); - } - break; - } - } -} - -/** - * This function finds if the call is a priority call. - * - * @param[in] call_id - GSM call id. - * - * @return none - * - * @pre (call_id != CC_NO_CALL_ID) - */ -boolean lsm_is_it_priority_call (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return FALSE; - } - if (FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_CALL_PRIORITY_URGENT)) { - return TRUE; - } - return FALSE; -} - -/* - * Function: lsm_internal_update_call_info - * - * Parameters: - * lcb - pointer to lsm_lcb_t. - * dcb - pointer to fsmdef_dcb_t. - * - * Description: This is an internal function of LSM for updating call - * information to the UI that is not directly driven by the - * the explicit CALL INFO event from call control. - * - * It is a convenient function that used by some of the - * LSM handling function that needs to update call information - * to the UI during media changes. - * - * Returns: - * None. - * - */ -static void -lsm_internal_update_call_info (lsm_lcb_t *lcb, fsmdef_dcb_t *dcb) -{ - boolean inbound; - calltype_t call_type; - fsmcnf_ccb_t *ccb; - - if ((lcb == NULL) || (dcb == NULL)) { - return; - } - - if (!dcb->ui_update_required) { - return; - } - - /* For local conference, do not update the primary - * call bubbles call-info. Primary call is already - * displaying To conference in this case - * But dcb-> caller_id should be updated to - * refresh the UI when the call is dropped - */ - ccb = fsmcnf_get_ccb_by_call_id(lcb->call_id); - if (ccb && (ccb->flags & LCL_CNF) && (ccb->active) - && (ccb->cnf_call_id == lcb->call_id)) { - return; - } - dcb->ui_update_required = FALSE; - - /* Derive orientation of the call */ - switch (dcb->orientation) { - case CC_ORIENTATION_FROM: - inbound = TRUE; - break; - - case CC_ORIENTATION_TO: - inbound = FALSE; - break; - - default: - /* - * No orientation available, use the direction when call was started - */ - inbound = dcb->inbound; - break; - } - - if ((dcb->call_type == FSMDEF_CALL_TYPE_FORWARD) - && fsmdef_check_retain_fwd_info_state()) { - call_type = (inbound) ? (calltype_t)dcb->call_type:FSMDEF_CALL_TYPE_OUTGOING; - } else { - if (inbound) { - call_type = FSMDEF_CALL_TYPE_INCOMING; - } else { - call_type = FSMDEF_CALL_TYPE_OUTGOING; - } - } - - ui_call_info(dcb->caller_id.calling_name, - dcb->caller_id.calling_number, - dcb->caller_id.alt_calling_number, - dcb->caller_id.display_calling_number, - dcb->caller_id.called_name, - dcb->caller_id.called_number, - dcb->caller_id.display_called_number, - dcb->caller_id.orig_called_name, - dcb->caller_id.orig_called_number, - dcb->caller_id.last_redirect_name, - dcb->caller_id.last_redirect_number, - call_type, - lcb->line, lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - -} - -/** - * The function opens receive channel or allocates receive port. It depends - * on the "keep" member of the cc_action_data_open_rcv_t structure set - * up by the caller to whether opens a receive channel or just - * to allocate a receive port. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in/out] data - pointer to the cc_action_data_open_rcv_t. - * Upon a successful return, the port element - * of this structure will be filled with the actual - * receive port. - * @param[in] media - pointer to the fsmdef_media_t if a specific - * media to be operated on. - * - * @return CC_RC_ERROR or CC_RC_SUCCESS. - * - * @pre (lcb is_not NULL) and (data is_not NULL) - */ -static cc_rcs_t -lsm_open_rx (lsm_lcb_t *lcb, cc_action_data_open_rcv_t *data, - fsmdef_media_t *media) -{ - static const char fname[] = "lsm_open_rx"; - int port_allocated = 0; - cc_rcs_t rc = CC_RC_ERROR; - fsmdef_dcb_t *dcb; - int sdpmode = 0; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (rc); - } - - /* - * P2: At this point, it is a guess that refid from media structure - * may be needed. If it turns out to be not the case, then the - * code below that looks up media should be removed including - * the media parameter that is passed in. - */ - if (media == NULL) { - /* no explicit media parameter specified, look up based on refID */ - if (data->media_refid != CC_NO_MEDIA_REF_ID) { - media = gsmsdp_find_media_by_refid(dcb, - data->media_refid); - } - if (media == NULL) { - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, - lcb->line, fname, "no media refID %d found", - data->media_refid); - return (rc); - } - } - - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, lcb->line, fname, - "requested port", data->port); - - - sdpmode = 0; - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (data->keep == TRUE) { - if (sdpmode && strlen(dcb->peerconnection)) { - /* If we are doing ICE, don't try to re-open */ - port_allocated = data->port; - } - else { - //Todo IPv6: Add interface call for IPv6 - (void) vcmRxOpen(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id), data->port, - media->is_multicast ? &media->dest_addr:&media->src_addr, data->is_multicast, - &port_allocated); - } - if (port_allocated != -1) { - data->port = (uint16_t)port_allocated; - rc = CC_RC_SUCCESS; - } - } else { - - if (sdpmode) { - if (!strlen(dcb->peerconnection)) { - vcmRxAllocPort(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id), - data->port, - &port_allocated); - if (port_allocated != -1) { - data->port = (uint16_t)port_allocated; - rc = CC_RC_SUCCESS; - } - } else { - char **candidates; - int candidate_ct; - char *default_addr; - - vcmRxAllocICE(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id), - dcb->peerconnection, - media->level, - &default_addr, &port_allocated, - &candidates, &candidate_ct); - - // Check that we got a valid address and port - if (default_addr && (strlen(default_addr) > 0) && (port_allocated != -1)) { - sstrncpy(dcb->ice_default_candidate_addr, default_addr, sizeof(dcb->ice_default_candidate_addr)); - - data->port = (uint16_t)port_allocated; - media->candidate_ct = candidate_ct; - media->candidatesp = candidates; - rc = CC_RC_SUCCESS; - } - } - } - } - - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, lcb->line, fname, - "allocated port", port_allocated); - - return (rc); -} -/* - * This function updates the dscp value based on whether video is enable or not - * and video is active or not. - * @param[in] dcb - pointer to the fsmdef_dcb. - */ - -void lsm_update_dscp_value(fsmdef_dcb_t *dcb) -{ - static const char fname[] = "lsm_update_dscp_value"; - int dscp = 184; /* default 184 used for DSCP */ - // depending upon video is enabled or disabled ,set the dscp value. - if (dcb != NULL && dcb->cur_video_avail != SDP_DIRECTION_INACTIVE ) { - config_get_value(CFGID_DSCP_VIDEO, (int *)&dscp, sizeof(dscp)); - } else { - config_get_value(CFGID_DSCP_AUDIO, (int *)&dscp, sizeof(dscp)); - } - // We would use DSCP for video for both audio and video streams if this is a video call - if (dcb != NULL) { - LSM_DEBUG(DEB_L_C_F_PREFIX"Setting dscp=%d for Rx group_id=%d \n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), dscp, dcb->group_id); - vcmSetRtcpDscp(dcb->group_id, dscp); - } -} - -/** - * The function closes receive channel for a given media entry. - * The receive channel may not be closed if the caller intents to - * fresh the channel i.e close if needed but otherwise leave it open. - * When the caller indicates refreshing, the receive channel - * will be closed only when there is a difference in current SDP and - * the previous SDP. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in] refresh - channel to be refreshed i.e. close if necessary. - * @param[in] media - pointer to the fsmdef_media_t for the - * media entry to be refresh. - * - * If the value of media is NULL, it indicates that - * all current inused media entries. - * - * @return None. - * - * @pre (lcb is_not NULL) - */ -static void -lsm_close_rx (lsm_lcb_t *lcb, boolean refresh, fsmdef_media_t *media) -{ - static const char fname[] = "lsm_close_rx"; - fsmdef_media_t *start_media, *end_media; - fsmdef_dcb_t *dcb; - int sdpmode = 0; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - LSM_DEBUG(DEB_L_C_F_PREFIX"Called with refresh set to %d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), refresh); - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - /* close receive port on the media(s) */ - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (media->rcv_chan) { - /* - * If caller is releasing the port or if the caller is - * recycling the receive port and the codec has changed, close the - * receive port. Also stop bridging of media streams. - */ - if (!refresh || - (refresh && - gsmsdp_sdp_differs_from_previous_sdp(TRUE, media))) { - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), dcb->call_id, - dcb->line, fname, "port closed", - media->src_port); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - - vcmRxClose(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)); - } - media->rcv_chan = FALSE; - } - } - } -} - -/** - * The function closes transmit channel for a given media entry. - * The transmit channel may not be closed if the caller intents to - * fresh the port i.e close if needed but otherwise leave it open. - * When the caller indicates refreshing, the transmit channel - * will be closed only when there is a difference in current SDP and - * the previous SDP. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in] refresh - channel to be refreshed i.e. close if necessary. - * @param[in] media - pointer to the fsmdef_media_t for the - * media entry to be refresh. - * - * If the value of media is NULL, it indicates that - * all current inused media entries. - * - * @return None. - * - * @pre (lcb is_not NULL) - */ -static void -lsm_close_tx (lsm_lcb_t *lcb, boolean refresh, fsmdef_media_t *media) -{ - fsmdef_media_t *start_media, *end_media; - fsmdef_dcb_t *dcb; - static const char fname[] = "lsm_close_tx"; - int sdpmode = 0; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - LSM_DEBUG(DEB_L_C_F_PREFIX"called with refresh set to %d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), refresh); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - /* - * Close the RTP, but only if this call is using it and the capabilities - * have changed. - */ - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (media->xmit_chan == TRUE) { - - if (!refresh || - (refresh && - gsmsdp_sdp_differs_from_previous_sdp(FALSE, media))) { - - if (!sdpmode) { - vcmTxClose(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)); - } - - if (dcb->active_tone == VCM_MONITORWARNING_TONE || dcb->active_tone == VCM_RECORDERWARNING_TONE) { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Found active_tone: %d being played, current monrec_tone_action: %d. Need stop tone. \n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), fname, - dcb->active_tone, dcb->monrec_tone_action); - (void) lsm_stop_tone(lcb, NULL); - } - media->xmit_chan = FALSE; - LSM_DEBUG(DEB_L_C_F_PREFIX"closed", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname)); - } - } - } -} - -/** - * The function starts receive channel for a given media entry. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in] fname - pointer to to const. char for the name - * of the function that calls to this function. - * It is for debuging purpose. - * @param[in] media - pointer to the fsmdef_media_t for the - * media entry to be refresh. - * - * If the value of media is NULL, it indicates that - * all current inused media entries. - * - * @return None. - * - * @pre (lcb is_not NULL) - */ -static void -lsm_rx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media) -{ - static const char fname1[] = "lsm_rx_start"; - cc_action_data_open_rcv_t open_rcv; - uint16_t port; - groupid_t group_id = CC_NO_GROUP_ID; - callid_t call_id = lcb->call_id; - vcm_mixing_mode_t mix_mode = VCM_NO_MIX; - vcm_mixing_party_t mix_party = VCM_PARTY_NONE; - int ret_val; - fsmdef_media_t *start_media, *end_media; - boolean has_checked_conference = FALSE; - fsmdef_dcb_t *dcb, *grp_id_dcb; - vcm_mediaAttrs_t attrs; - int sdpmode = 0; - int pc_stream_id = 0; - int pc_track_id = 0; - attrs.video.opaque = NULL; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - return; - } - group_id = dcb->group_id; - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - /* Start receive channel for the media(s) */ - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not enabled */ - continue; - } - - /* - * Check to see if the receive port can be opened. - * For SRTP, the receive can not be opened if the remote's crypto - * parameters are not received yet. - */ - if (!gsmsdp_is_crypto_ready(media, TRUE)) { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Not ready to open receive port (%d)\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname, media->src_port); - continue; - } - - /* - * Open the RTP receive channel if it is not already open. - */ - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), dcb->call_id, dcb->line, - fname1, "rcv chan", media->rcv_chan); - if (media->rcv_chan == FALSE) { - - memset(&open_rcv, 0, sizeof(open_rcv)); - port = media->src_port; - - if (media->is_multicast && - (media->direction == SDP_DIRECTION_RECVONLY)) { - open_rcv.is_multicast = media->is_multicast; - open_rcv.listen_ip = media->dest_addr; - port = media->multicast_port; - } - open_rcv.port = port; - open_rcv.keep = TRUE; - open_rcv.media_type = media->type; - - if (!has_checked_conference) { - switch(dcb->session) - { - case WHISPER_COACHING: - mix_mode = VCM_MIX; - mix_party = VCM_PARTY_TxBOTH_RxNONE; - grp_id_dcb = fsmdef_get_dcb_by_call_id(dcb->join_call_id); - if (grp_id_dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - } else { - group_id = grp_id_dcb->group_id; - } - break; - - case MONITOR: - case LOCAL_CONF: - //AgentGreeting is MIX RXBOTH, SilentMonitoring is MIX TXBOTH - //so we have to use VCM_PARTY_BOTH for case MONITOR - mix_mode = VCM_MIX; - mix_party = VCM_PARTY_BOTH; - break; - case PRIMARY: - default: - mix_mode = VCM_NO_MIX; - mix_party = VCM_PARTY_NONE; - break; - } - has_checked_conference = TRUE; - } - - if (lsm_open_rx(lcb, &open_rcv, media) != CC_RC_SUCCESS) { - LSM_ERR_MSG(LSM_L_C_F_PREFIX"%s: open receive port (%d) failed.\n", - dcb->line, dcb->call_id, fname1, - fname, media->src_port); - } else { - /* successful open receive channel */ - media->rcv_chan = TRUE; /* recevied channel is created */ - /* save the source RX port */ - if (media->is_multicast) { - media->multicast_port = open_rcv.port; - } else { - media->src_port = open_rcv.port; - } - - /* TODO(ekr@rtfm.com): Needs changing for when we have > 2 streams */ - if ( media->cap_index == CC_VIDEO_1 ) { - attrs.video.opaque = media->video; - pc_stream_id = 1; - } else { - attrs.audio.packetization_period = media->packetization_period; - attrs.audio.max_packetization_period = media->max_packetization_period; - attrs.audio.avt_payload_type = media->avt_payload_type; - attrs.audio.mixing_mode = mix_mode; - attrs.audio.mixing_party = mix_party; - pc_stream_id = 0; - } - pc_track_id = 0; - dcb->cur_video_avail &= ~CC_ATTRIB_CAST; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (dcb->peerconnection) { - ret_val = vcmRxStartICE(media->cap_index, group_id, media->refid, - media->level, - pc_stream_id, - pc_track_id, - lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID), - dcb->peerconnection, - media->num_payloads, - media->payloads, - FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media), - FSM_NEGOTIATED_CRYPTO_DIGEST(media), - &attrs); - } else if (!sdpmode) { - if (media->payloads == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - return; - } - ret_val = vcmRxStart(media->cap_index, group_id, media->refid, - lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID), - media->payloads, - media->is_multicast ? &media->dest_addr:&media->src_addr, - port, - FSM_NEGOTIATED_CRYPTO_ALGORITHM_ID(media), - FSM_NEGOTIATED_CRYPTO_RX_KEY(media), - &attrs); - if (ret_val == -1) { - dcb->dsp_out_of_resources = TRUE; - return; - } - } else { - ret_val = CC_RC_ERROR; - } - - lsm_update_dscp_value(dcb); - - if (dcb->play_tone_action == FSMDEF_PLAYTONE_ZIP) - { - vcm_tones_t tone = VCM_ZIP; - uint16_t direction = dcb->tone_direction; - - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Found play_tone_action: %d. Need to play tone.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), fname, dcb->play_tone_action); - - // reset to initialized values - dcb->play_tone_action = FSMDEF_PLAYTONE_NO_ACTION; - dcb->tone_direction = VCM_PLAY_TONE_TO_EAR; - - lsm_util_tone_start_with_speaker_as_backup(tone, VCM_ALERT_INFO_OFF, - lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - direction); - } - } - } - } -} - -/** - * The function starts transmit channel for a given media entry. - * - * @param[in] lcb - pointer to the lsm_lcb_t. - * @param[in] fname - pointer to to const. char for the name - * of the function that calls to this function. - * It is for debuging purpose. - * @param[in] media - pointer to the fsmdef_media_t for the - * media entry to be refresh. - * - * If the value of media is NULL, it indicates that - * all current inused media entries. - * - * @return None. - * - * @pre (lcb is_not NULL) - */ - -#define LSM_TMP_VAD_LEN 64 - -static void -lsm_tx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media) -{ - static const char fname1[] = "lsm_tx_start"; - int dscp = 184; /* default 184 used for DSCP */ - char tmp[LSM_TMP_VAD_LEN]; - fsmcnf_ccb_t *ccb = NULL; - groupid_t group_id; - callid_t call_id = lcb->call_id; - vcm_mixing_mode_t mix_mode = VCM_NO_MIX; - vcm_mixing_party_t mix_party = VCM_PARTY_NONE; - fsmdef_media_t *start_media, *end_media; - boolean has_checked_conference = FALSE; - fsmdef_dcb_t *dcb; - vcm_mediaAttrs_t attrs; - int sdpmode; - long strtol_result; - char *strtol_end; - - attrs.video.opaque = NULL; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - return; - } - // Set the DSCP value for RTP stream. - if ( media != NULL ){ - // We would use DSCP for video for both audio and video streams if this - // is a video call - if ( dcb->cur_video_avail != SDP_DIRECTION_INACTIVE ) { - config_get_value(CFGID_DSCP_VIDEO, (int *)&dscp, sizeof(dscp)); - } else if ( CC_IS_AUDIO(media->cap_index)){ - // audio stream for audio only call shall use the DSCP for audio - // value. - config_get_value(CFGID_DSCP_AUDIO, (int *)&dscp, sizeof(dscp)); - } - } - group_id = dcb->group_id; - LSM_DEBUG(DEB_L_C_F_PREFIX"invoked\n", DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1)); - - if (media == NULL) { - /* NULL value of the given media indicates for all media */ - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - } else { - /* given media, uses the provided media */ - start_media = media; - end_media = media; - } - - /* Start receive channel for the media(s) */ - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not enabled */ - continue; - } - /* - * Check to see if the transmit port can be opened. - * For SRTP, the transmit port can not be opened if the remote's crypto - * parameters are not received yet. - */ - if (!gsmsdp_is_crypto_ready(media, FALSE)) { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Not ready to open transmit port\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - continue; - } - if (media->xmit_chan == FALSE && dcb->remote_sdp_present && - media->dest_addr.type != CPR_IP_ADDR_INVALID && media->dest_port) { - - /* evaluate the mode and group id once for all media entries */ - if (!has_checked_conference) { - switch(dcb->session) - { - case WHISPER_COACHING: - mix_mode = VCM_MIX; - mix_party = VCM_PARTY_TxBOTH_RxNONE; - group_id = fsmdef_get_dcb_by_call_id(dcb->join_call_id)->group_id; - break; - - case MONITOR: - case LOCAL_CONF: - //AgentGreeting is MIX RXBOTH, SilentMonitoring is MIX TXBOTH - //so we have to use VCM_PARTY_BOTH for case MONITOR - mix_mode = VCM_MIX; - mix_party = VCM_PARTY_BOTH; - break; - case PRIMARY: - default: - mix_mode = VCM_NO_MIX; - mix_party = VCM_PARTY_NONE; - break; - } - has_checked_conference = TRUE; - } - - /* - * Set the VAD value. - */ - /* can't use vad on conference calls - the dsp can't handle it. */ - ccb = fsmcnf_get_ccb_by_call_id(lcb->call_id); - if (ccb != NULL) { - media->vad = VCM_VAD_OFF; - } else { - config_get_string(CFGID_ENABLE_VAD, tmp, sizeof(tmp)); - - errno = 0; - - strtol_result = strtol(tmp, &strtol_end, 10); - - if (errno || tmp == strtol_end || - strtol_result < VCM_VAD_OFF || strtol_result > VCM_VAD_ON) { - LSM_ERR_MSG("%s parse error of vad: %s", __FUNCTION__, tmp); - return; - } - - media->vad = (vcm_vad_t) strtol_result; - } - - /* - * Open the transmit port and start sending, but only if we have - * the SDP for the remote end. - */ - - sdpmode = 0; - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - - if (vcmTxOpen(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)) != 0) { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: vcmTxOpen failed\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - continue; - } - } - - media->xmit_chan = TRUE; - - attrs.mute = FALSE; - if ( CC_IS_VIDEO(media->cap_index)) { - attrs.video.opaque = media->video; - if (lcb->vid_mute) { - attrs.mute = TRUE; - } - - } else if ( CC_IS_AUDIO(media->cap_index)){ - attrs.audio.packetization_period = media->packetization_period; - attrs.audio.max_packetization_period = media->max_packetization_period; - attrs.audio.avt_payload_type = media->avt_payload_type; - attrs.audio.vad = media->vad; - attrs.audio.mixing_mode = mix_mode; - attrs.audio.mixing_party = mix_party; - } - - dcb->cur_video_avail &= ~CC_ATTRIB_CAST; - - if (media->payloads == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname1); - return; - } - if (!strlen(dcb->peerconnection)){ - if (vcmTxStart(media->cap_index, group_id, - media->refid, - lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID), - media->payloads, - (short)dscp, - &media->src_addr, - media->src_port, - &media->dest_addr, - media->dest_port, - FSM_NEGOTIATED_CRYPTO_ALGORITHM_ID(media), - FSM_NEGOTIATED_CRYPTO_TX_KEY(media), - &attrs) == -1) - { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: vcmTxStart failed\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - dcb->dsp_out_of_resources = TRUE; - return; - } - } - else { - if (vcmTxStartICE(media->cap_index, group_id, - media->refid, - media->level, - /* TODO(emannion): his perhaps needs some error checking for validity. - See gsmsdp_get_media_cap_entry_by_index. */ - dcb->media_cap_tbl->cap[media->cap_index].pc_stream, - dcb->media_cap_tbl->cap[media->cap_index].pc_track, - lsm_get_ms_ui_call_handle(dcb->line, call_id, CC_NO_CALL_ID), - dcb->peerconnection, - media->payloads, - (short)dscp, - FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media), - FSM_NEGOTIATED_CRYPTO_DIGEST(media), - &attrs) == -1) - { - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: vcmTxStartICE failed\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - dcb->dsp_out_of_resources = TRUE; - return; - } - } - - lsm_update_dscp_value(dcb); - - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: vcmTxStart started\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname1), fname); - - if ( dcb->monrec_tone_action != FSMDEF_MRTONE_NO_ACTION) - { - vcm_tones_t tone = VCM_NO_TONE; - uint16_t direction = VCM_PLAY_TONE_TO_EAR; - boolean play_both_tones = FALSE; - - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Found monrec_tone_action: %d. Need to restart playing tone.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), fname, dcb->monrec_tone_action); - - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - tone = VCM_MONITORWARNING_TONE; - direction = dcb->monitor_tone_direction; - break; - - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - tone = VCM_RECORDERWARNING_TONE; - direction = dcb->recorder_tone_direction; - break; - - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - play_both_tones = TRUE; - tone = VCM_MONITORWARNING_TONE; - direction = dcb->monitor_tone_direction; - break; - - default: - break; - } - - if (play_both_tones == TRUE) { - lsm_util_tone_start_with_speaker_as_backup(VCM_RECORDERWARNING_TONE, VCM_ALERT_INFO_OFF, - lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->recorder_tone_direction); - } - - lsm_util_tone_start_with_speaker_as_backup(tone, VCM_ALERT_INFO_OFF, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - direction); - } - } - } -} - - -static cc_rcs_t -lsm_start_tone (lsm_lcb_t *lcb, cc_action_data_tone_t *data) -{ - callid_t call_id = lcb->call_id; - fsmdef_media_t *media; - - if (lcb->dcb == NULL) { - /* No dcb to work with */ - return (CC_RC_ERROR); - } - media = gsmsdp_find_audio_media(lcb->dcb); - - lsm_util_start_tone(data->tone, VCM_ALERT_INFO_OFF, lsm_get_ms_ui_call_handle(lcb->line, call_id, CC_NO_CALL_ID), lcb->dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - - return (CC_RC_SUCCESS); -} - -static cc_rcs_t -lsm_stop_tone (lsm_lcb_t *lcb, cc_action_data_tone_t *data) -{ - /* NOTE: For now, ignore data input parameter that may contain the tone type. - * We'll check active_tone in the dcb for the call_id and see if there - * is a valid tone playing. If so, then and only then issue tone stop. - */ - static const char fname[] = "lsm_stop_tone"; - callid_t call_id; - fsmdef_dcb_t *dcb; - - if (lcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX"NULL lcb passed\n", DEB_F_PREFIX_ARGS(LSM, fname)); - return (CC_RC_ERROR); - } - call_id = lcb->call_id; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX" NULL dcb passed for call_id = %d\n", DEB_F_PREFIX_ARGS(LSM, fname), call_id); - return (CC_RC_ERROR); - } - - /* for tnp do call stop only if active_tone is other than VCM_NO_TONE */ - if (dcb->active_tone != VCM_NO_TONE) { - fsmdef_media_t *media = gsmsdp_find_audio_media(lcb->dcb); - vcmToneStop(dcb->active_tone, dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)); - /* - * Both periodic tones, recording and monitoring, can be active at the - * same time. And because we only keep track of last tone, requested to - * play, through active_tone, so when the tone to be stopped is of - * periodic type, then it could be that both type of periodic tones - * could be playing and both should be stopped. If the second periodic - * tone is not playing then media server will ignore the stop request. - */ - if (dcb->active_tone == VCM_RECORDERWARNING_TONE || - dcb->active_tone == VCM_MONITORWARNING_TONE) - { - vcmToneStop(dcb->active_tone == VCM_RECORDERWARNING_TONE ? - VCM_MONITORWARNING_TONE : VCM_RECORDERWARNING_TONE, - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id)); - - /* in case need to play back the tone again when tx channel active */ - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_MONITOR_TONE; - break; - - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_RECORDER_TONE; - break; - - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_BOTH_TONES; - break; - - default: - break; - } - - LSM_DEBUG(DEB_L_C_F_PREFIX"%s: Setting monrec_tone_action: %d so resume to play correct tone.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), fname, - dcb->monrec_tone_action); - } - dcb->active_tone = VCM_NO_TONE; - } else { - LSM_DEBUG(DEB_L_C_F_PREFIX"Ignoring tone stop request\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, call_id, fname)); - } - - return (CC_RC_SUCCESS); -} - -/* - * Function - * - * @param[in] tone - tone type - * @param[in] alert_info - alertinfo header - * @param[in] call_handle- call handle - * @param[in] direction - network, speaker, both - * @param[in] duration - length of time for tone to be played - * - * @return none - */ -void -lsm_tone_start_with_duration (vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction, - uint32_t duration) -{ - - static const char *fname = "lsm_tone_start_with_duration"; - - DEF_DEBUG(DEB_L_C_F_PREFIX"tone=%-2d: direction=%-2d duration=%-2d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, GET_LINE_ID(call_handle), GET_CALL_ID(call_handle), fname), - tone, direction, duration); - - /* - * play the tone. audio path is always set by MSUI module. - */ - vcmToneStart (tone, alert_info, call_handle, group_id, stream_id, direction); - - lsm_update_active_tone (tone, GET_CALL_ID(call_handle)); - - lsm_start_tone_duration_timer (tone, duration, call_handle); -} - -/* - * Function: lsm_get_used_instances_cnt - * - * @param line - line number - * - * Description: find the number of used instances for this particular line - * - * @return number of used instances - * - */ -int lsm_get_used_instances_cnt (line_t line) -{ - static const char fname[] = "lsm_get_used_instances_cnt"; - int used_instances = 0; - lsm_lcb_t *lcb; - - if (!sip_config_check_line(line)) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)\n", fname, line); - - return (-1); - } - - /* - * Count home many instances are already in use for this particular line. - */ - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && - (lcb->line == line) && - (lcb->state != LSM_S_IDLE)) { - used_instances++; - } - } - - return (used_instances); -} - -/* - * Function: lsm_get_all_used_instances_cnt - * - * Description: find the number of used instances for all lines - * - * @return number of used instances for all lines - * - */ -int lsm_get_all_used_instances_cnt () -{ - int used_instances = 0; - lsm_lcb_t *lcb; - - /* - * Count home many instances are already in use for all lines. - */ - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && - (lcb->state != LSM_S_IDLE)) { - used_instances++; - } - } - - return (used_instances); -} - -/* - * Function: lsm_increment_call_chn_cnt - * - * @param line - line number - * - * Description: - * - * @return none - * - */ -void lsm_increment_call_chn_cnt (line_t line) -{ - uint32_t maxnumcalls = 0; - uint32_t busy_trigger = 0; - static const char fname[] = "lsm_increment_call_chn_cnt"; - - if ( line <=0 || line > MAX_REG_LINES ) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)\n", fname, line); - return; - } - lsm_call_perline[line-1]++; - config_get_line_value(CFGID_LINE_MAXNUMCALLS, &maxnumcalls, sizeof(maxnumcalls), line); - config_get_line_value(CFGID_LINE_BUSY_TRIGGER, &busy_trigger, sizeof(busy_trigger), line); - if (lsm_call_perline[line-1] == maxnumcalls) { - lsm_mnc_reached[line-1] = TRUE;; - ui_mnc_reached(line, TRUE); - } - if (lsm_call_perline[line - 1] == busy_trigger) { - lsm_bt_reached[line - 1] = TRUE;; - } - - LSM_DEBUG(DEB_F_PREFIX"number of calls on line[%d]=%d" - "MaxNumCalls[%d]_reached=%s BusyTrigger[%d]_reached=%s\n", - DEB_F_PREFIX_ARGS(LSM, fname), - line, lsm_call_perline[line-1], - maxnumcalls, (lsm_mnc_reached[line-1] == TRUE) ? "TRUE" : "FALSE", - busy_trigger,(lsm_bt_reached[line-1] == TRUE) ? "TRUE" : "FALSE"); -} - -/* - * Function: lsm_decrement_call_chn_cnt - * - * @param line - line number - * - * Description: - * - * @return none - * - */ -void lsm_decrement_call_chn_cnt (line_t line) -{ - uint32_t maxnumcalls = 0; - uint32_t busy_trigger = 0; - static const char fname[] = "lsm_decrement_call_chn_cnt"; - - if ( line <=0 || line > MAX_REG_LINES ) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)\n", fname, line); - return; - } - - lsm_call_perline[line-1]--; - config_get_line_value(CFGID_LINE_MAXNUMCALLS, &maxnumcalls, sizeof(maxnumcalls), line); - config_get_line_value(CFGID_LINE_BUSY_TRIGGER, &busy_trigger, sizeof(busy_trigger), line); - if (lsm_call_perline[line-1] <= (maxnumcalls-1)) { - lsm_mnc_reached[line-1] = FALSE; - ui_mnc_reached(line, FALSE); - } - if (lsm_call_perline[line - 1] == (busy_trigger -1)) { - lsm_bt_reached[line - 1] = FALSE;; - } - LSM_DEBUG(DEB_F_PREFIX"number of calls on line[%d]=%d" - "MaxNumCalls[%d]_reached=%s BusyTrigger[%d]_reached=%s\n", - DEB_F_PREFIX_ARGS(LSM, fname), - line, lsm_call_perline[line-1], - maxnumcalls, (lsm_mnc_reached[line-1] == TRUE) ? "TRUE" : "FALSE", - busy_trigger,(lsm_bt_reached[line-1] == TRUE) ? "TRUE" : "FALSE"); -} - -#define NO_ROLLOVER 0 -#define ROLLOVER_ACROSS_SAME_DN 1 -#define ROLLOVER_NEXT_AVAILABLE_LINE 2 - -/* - * Function: lsm_find_next_available_line - * - * @param line - line number - * @param same_dn - whether lines with same DN to be looked at. - * @param incoming - whether we are looking for an available line for an anticipated incoming call. - * - * Description: - * - * - * @return found line number - * - */ -line_t lsm_find_next_available_line (line_t line, boolean same_dn, boolean incoming) -{ - char current_line_dn_name[MAX_LINE_NAME_SIZE]; - char dn_name[MAX_LINE_NAME_SIZE]; - uint32_t line_feature; - line_t i, j; - boolean *limit_reached; - - /* determine whether to use MNC or BT limit */ - if (incoming == TRUE) { - limit_reached = lsm_bt_reached; - } - else { - limit_reached = lsm_mnc_reached; - } - - config_get_line_string(CFGID_LINE_NAME, current_line_dn_name, line, sizeof(current_line_dn_name)); - /* This line has exhausted its limit, start rollover */ - /* First, search the lines on top of the current one */ - for (i=line+1; i <= MAX_REG_LINES; i++) { - config_get_line_value(CFGID_LINE_FEATURE, &line_feature, sizeof(line_feature), i); - - /* if it is not a DN, skip it */ - if (line_feature != cfgLineFeatureDN) { - continue; - } - /* Does this line have room to take the call */ - if (limit_reached[i-1] == FALSE) { - if (same_dn == TRUE) { - config_get_line_string(CFGID_LINE_NAME, dn_name, i, sizeof(dn_name)); - /* Does this line have the same DN */ - if (cpr_strcasecmp(dn_name, current_line_dn_name) == 0) { - return (i); - } - } else { - return (i); - } - } - } - /* - * We went up to the top and couldn't find an available line, - * start from line 1 and search up to the current line, thus - * we are treating the available lines as a circular pool - */ - - for (j=1; j <= line; j++) { - config_get_line_value(CFGID_LINE_FEATURE, &line_feature, sizeof(line_feature), j); - - /* if it is not a DN, skip it */ - if (line_feature != cfgLineFeatureDN) { - continue; - } - /* Does this line have room to take the call */ - if (limit_reached[j-1] == FALSE) { - if (same_dn == TRUE) { - config_get_line_string(CFGID_LINE_NAME, dn_name, j, sizeof(dn_name)); - /* Does this line have the same DN */ - if (cpr_strcasecmp(dn_name, current_line_dn_name) == 0) { - return (j); - } - } else { - return (j); - } - } - } - - return (NO_LINES_AVAILABLE); -} -/* - * Function: lsm_get_newcall_line - * - * @param line - line number - * - * Description: find out a line that has room to make a - * new call based on the rollover settings - * - * @return found line number - * - */ -line_t lsm_get_newcall_line (line_t line) -{ - static const char fname[] = "lsm_get_newcall_line"; - int rollover; - line_t found_line; - - if (!lsm_mnc_reached[line-1]) { - /* Still room for extra calls on this line */ - return (line); - } - - config_get_value(CFGID_ROLLOVER, &rollover, sizeof(int)); - - if (rollover == NO_ROLLOVER) { - DEF_DEBUG(DEB_F_PREFIX"NO Rollover, no lines\n", DEB_F_PREFIX_ARGS(LSM, fname)); - return (NO_LINES_AVAILABLE); - } - - - if (rollover == ROLLOVER_ACROSS_SAME_DN) { - /* Look for a line with the same DN */ - return (lsm_find_next_available_line(line, TRUE, FALSE)); - } - - if (rollover == ROLLOVER_NEXT_AVAILABLE_LINE) { - /* Look for a line with the same DN first */ - found_line = lsm_find_next_available_line(line, TRUE, FALSE); - - if (found_line == NO_LINES_AVAILABLE) { - /* - * If nothing found, just look for any line, does - * not necessarily have to have the same DN - */ - return (lsm_find_next_available_line(line, FALSE, FALSE)); - } else { - return (found_line); - } - } - - DEF_DEBUG(DEB_F_PREFIX"No lines available\n", DEB_F_PREFIX_ARGS(LSM, fname)); - - return (NO_LINES_AVAILABLE); -} - -/* - * Function: lsm_get_available_line - * - * @param incoming - whether we are looking for an available line for an anticipated incoming call. - * - * Description: find out a line that has room to make a - * new call starting from the first line. - * - * @return found line number - * - */ -line_t lsm_get_available_line (boolean incoming) -{ - line_t line = 1; /* start with line 1 */ - - if (incoming == FALSE) { - if (!lsm_mnc_reached[line-1]) { - /* Still room for extra calls on this line */ - return (line); - } - } - else { - if (!lsm_bt_reached[line-1]) { - /* Still room for extra calls on this line */ - return (line); - } - } - return (lsm_find_next_available_line(line, FALSE, incoming)); -} - -/* - * Function: lsm_is_line_available_for_outgoing_call - * - * @param line - * @param incoming - whether we are looking for an available line for an anticipated incoming call. - * - * Description: find out if the line has room to make a new call - * - * @return TRUE/FALSE - * - */ -boolean lsm_is_line_available (line_t line, boolean incoming) -{ - if (incoming == FALSE) { - if (!lsm_mnc_reached[line-1]) { - /* Still room for extra calls on this line */ - return (TRUE); - } - } - else { - if (!lsm_bt_reached[line-1]) { - /* Still room for incoming calls on this line */ - return (TRUE); - } - } - return (FALSE); -} - -/* - * lsm_get_instances_available_cnt - * - * return the number of available instances for this particular line - * - * NOTE: The function can return negative values, which the user should read - * as no available lines. - */ -int -lsm_get_instances_available_cnt (line_t line, boolean expline) -{ - static const char fname[] = "lsm_get_instances_available_cnt"; - int max_instances; - int used_instances = 0; - int free_instances; - - if (!sip_config_check_line(line)) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)\n", fname, line); - - return (-1); - } - - used_instances = lsm_get_used_instances_cnt(line); - - max_instances = (expline) ? (LSM_MAX_EXP_INSTANCES) : (LSM_MAX_INSTANCES); - - free_instances = max_instances - used_instances; - - if(free_instances > 0){ - int all_used_instances = lsm_get_all_used_instances_cnt(); - int all_max_instances = (expline) ? (LSM_MAX_CALLS) : (LSM_MAX_CALLS - 1); - int all_free_instances = all_max_instances - all_used_instances; - free_instances = ((free_instances < all_free_instances) ? free_instances : all_free_instances); - LSM_DEBUG("lsm_get_instances_available_cnt: line=%d, expline=%d, free=%d, all_used=%d, all_max=%d, all_free=%d\n", - line, expline, free_instances, all_used_instances, all_max_instances, all_free_instances); - - } - LSM_DEBUG("lsm_get_instances_available_cnt: line=%d, expline=%d, free_instances=%d\n", - line, expline, free_instances); - return (free_instances); -} - - -static void -lsm_init_lcb (lsm_lcb_t *lcb) -{ - lcb->call_id = CC_NO_CALL_ID; - lcb->line = LSM_NO_LINE; - lcb->previous_call_event = evMaxEvent; - lcb->state = LSM_S_IDLE; - lcb->mru = 0; - lcb->enable_ringback = TRUE; - lcb->flags = 0; - lcb->dcb = NULL; - lcb->gcid = NULL; - lcb->vid_flags = 0; //set to not visible - lcb->ui_id = CC_NO_CALL_ID; -} - -/** - * Return the port back to Media service component - * @param [in] lcb - lsm control block - * - */ -static void lsm_release_port (lsm_lcb_t *lcb) -{ - static const char fname[] = "lsm_release_port"; - fsmdef_media_t *start_media, *end_media; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - int sdpmode = 0; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - LSM_DEBUG(DEB_L_C_F_PREFIX, - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname)); - - start_media = GSMSDP_FIRST_MEDIA_ENTRY(dcb); - end_media = NULL; /* NULL means till the end of the list */ - - GSMSDP_FOR_MEDIA_LIST(media, start_media, end_media, dcb) { - if (!sdpmode) { - vcmRxReleasePort(media->cap_index, dcb->group_id, media->refid, - lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id), media->src_port); - } - } -} - -static void -lsm_free_lcb (lsm_lcb_t *lcb) -{ - lsm_release_port(lcb); - cpr_free(lcb->gcid); - lsm_init_lcb(lcb); -} - - -/** - * lsm_get_free_lcb - * return a free instance of the given line - * - * @param[in]call_id - gsm call id to allocate the lcb instance with. - * @param[in]line - line that the lcb instnce will be associated with - * @param[in]dcb - fsmdef_dcb_t structure that the lcb instance will - * be associated with. - * @return pointer to lsm_lcb_t if there is an available lcb otherwise - * returns NULL. - * @pre (dcb not_eq NULL) - */ -static lsm_lcb_t * -lsm_get_free_lcb (callid_t call_id, line_t line, fsmdef_dcb_t *dcb) -{ - static const char fname[] = "lsm_get_free_lcb"; - static int mru = 0; - lsm_lcb_t *lcb; - lsm_lcb_t *lcb_found = NULL; - - if (!sip_config_check_line(line)) { - LSM_ERR_MSG(LSM_F_PREFIX"invalid line (%d)\n", fname, line); - - return (NULL); - } - - - /* - * Set mru (most recently used). - * Used to determine which call came in first. - */ - if (++mru < 0) { - mru = 1; - } - - /* - * Find a free lcb. - */ - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id == CC_NO_CALL_ID) && (lcb->state == LSM_S_IDLE)) { - lcb_found = lcb; - lcb->call_id = call_id; - lcb->line = line; - lcb->state = LSM_S_PENDING; - lcb->mru = mru; - lcb->dcb = dcb; - // start unmuted if txPref is true - lcb->vid_mute = cc_media_getVideoAutoTxPref() ? FALSE : TRUE; - - lcb->ui_id = call_id; /* default UI ID is the same as call_id */ - break; - } - } - - return (lcb_found); -} - - -lsm_lcb_t * -lsm_get_lcb_by_call_id (callid_t call_id) -{ - lsm_lcb_t *lcb; - lsm_lcb_t *lcb_found = NULL; - LSM_DEBUG(DEB_L_C_F_PREFIX"call_id=%d.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, 0, call_id, "lsm_get_lcb_by_call_id"), call_id); - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->call_id == call_id) { - lcb_found = lcb; - break; - } - } - - return (lcb_found); -} - -/** - * This function returns the LSM state for the given call_id. - * - * @param[in] call_id - call id - * - * @return lsm_states_t of the given call_id. If the - * there is no call associated with the given - * call ID it returns the LSM_S_NONE. - */ -lsm_states_t -lsm_get_state (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - - if (lcb == NULL) { - /* there is no call for this call id */ - return (LSM_S_NONE); - } - return (lcb->state); -} - -static void -lsm_change_state (lsm_lcb_t *lcb, int line_num, lsm_states_t new_state) -{ - static const char fname1[] = "lsm_change_state"; - LSM_DEBUG(DEB_L_C_F_PREFIX"%d: %s -> %s\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, fname1), - line_num, lsm_state_name(lcb->state), lsm_state_name(new_state)); - - lcb->state = new_state; -} - -boolean -lsm_is_phone_idle (void) -{ - static const char fname[] = "lsm_is_phone_idle"; - boolean idle = TRUE; - lsm_lcb_t *lcb; - - if(!lsm_lcbs){ - LSM_DEBUG(DEB_F_PREFIX"No lsm line cb\n", DEB_F_PREFIX_ARGS(LSM, fname)); - return (idle); - } - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && (lcb->state != LSM_S_IDLE)) { - idle = FALSE; - break; - } - } - - return (idle); -} - - - -/* - * Function: lsm_is_phone_inactive - * - * Parameters: None. - * - * Description: Determines if the phone is inactive. Inactive means the phone - * as active at some point, but now it is not - there are still - * calls on the phone but they are probably in a holding state. - * This is different from idle, which means that there are not - * any calls on the phone. - * - * Returns: - * inactive: FALSE: phone is not inactive - * TRUE: phone is inactive - */ -boolean -lsm_is_phone_inactive (void) -{ - boolean inactive = TRUE; - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && - ((lcb->state == LSM_S_OFFHOOK) || - (lcb->state == LSM_S_PENDING) || - (lcb->state == LSM_S_PROCEED) || - (lcb->state == LSM_S_RINGOUT) || - (lcb->state == LSM_S_RINGIN) || - (lcb->state == LSM_S_CONNECTED))) { - inactive = FALSE; - break; - } - } - - return (inactive); -} - -/* - * Function: lsm_callwaiting - * - * Parameters: None. - * - * Description: Determines if the phone is in a state that this - * call will be handled by the callwaiting code. TNP - * phones allow call-waiting when dialing digits while - * the legacy phones do not. - * - * Returns: - * inactive: FALSE: Treat as a normal call on an idle phone - * TRUE: Display incoming call and play call waiting tone - */ -boolean -lsm_callwaiting (void) -{ - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->call_id != CC_NO_CALL_ID) { - switch (lcb->state) { - case LSM_S_OFFHOOK: - case LSM_S_PROCEED: - case LSM_S_RINGOUT: - case LSM_S_CONNECTED: - return (TRUE); - - default: - break; - } - } - } - - return (FALSE); -} - -static callid_t -lsm_find_state (lsm_states_t state) -{ - callid_t found_callid = CC_NO_CALL_ID; - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && (lcb->state == state)) { - found_callid = lcb->call_id; - break; - } - } - - return (found_callid); -} - -/** - * lsm_get_facility_by_called_number - * return facility by the given called_number. - * - * @param[in]call_id - gsm's call_id for a new call. - * @param[in]called_number - pointer to the called number. - * @paran[in/out]free_line - pointer to the line_t to store - * the result line number corresponding - * to the called number given. - * @param[in]expline - boolean indicating extra instance - * is needed. - * @param[in]dcb - pointer to void but it must be - * a pointer to fsmdef_dcb_t to bind with - * the new LCB. The reason to use a void - * pointer is the declaration of the function - * is in lsm.h. The lsm.h file is used by - * components outside gsm environment. Those - * modules would need to include the fsm.h - * which is not desirable. Using void pointer - * avoids this problem. - * - * @return cc_cause_t - * - * @pre (called_number not_eq NULL) - * @pre (free_line not_eq NULL) - * @pre (dcb not_eq NULL) - */ -cc_causes_t -lsm_get_facility_by_called_number (callid_t call_id, - const char *called_number, - line_t *free_line, boolean expline, - void *dcb) -{ - static const char fname[] = "lsm_get_facility_by_called_number"; - line_t line; - lsm_lcb_t *lcb; - int free_instances; - line_t madn_line; - - lsm_debug_entry(call_id, 0, fname); - LSM_DEBUG(DEB_F_PREFIX"called_number= %s\n", DEB_F_PREFIX_ARGS(LSM, fname), called_number); - - //line = sip_config_get_line_by_called_number(1, called_number); - line = 1; - if (line == 0) { - return (CC_CAUSE_UNASSIGNED_NUM); - } - *free_line = line; - - /* check for a MADN line */ - madn_line = sip_config_get_line_by_called_number((line_t)(line + 1), - called_number); - - /* - * Check to see if we even have any available instances. - */ - free_instances = lsm_get_instances_available_cnt(line, expline); - - /* if it is a MADN line and it already has a call, then go to next - * line with this MADN number. - */ - if ((madn_line) && (free_instances < 2)) { - while (madn_line) { - free_instances = lsm_get_instances_available_cnt(madn_line, expline); - if (free_instances == 2) { - *free_line = line = madn_line; - break; - } - madn_line = sip_config_get_line_by_called_number((line_t)(madn_line + 1), - called_number); - } - if (madn_line == 0) { - return (CC_CAUSE_BUSY); - } - } - - if (free_instances <= 0) { - return (CC_CAUSE_BUSY); - } - - lcb = lsm_get_free_lcb(call_id, line, (fsmdef_dcb_t *)dcb); - if (lcb == NULL) { - return (CC_CAUSE_NO_RESOURCE); - } - - return (CC_CAUSE_OK); -} - -/** - * lsm_allocate_call_bandwidth - * - * @param[in] none. - * - * The wlan interface puts into unique situation where call control - * has to allocate the worst case bandwith before creating a - * inbound or outbound call. The function call will interface through - * media API into wlan to get the call bandwidth. The function - * return is asynchronous and will block till the return media - * callback signals to continue the execution. - * - * @return true if the bandwidth can be allocated else false. - * @pre none - */ - -cc_causes_t lsm_allocate_call_bandwidth (callid_t call_id, int sessions) -{ - //get line for vcm - line_t line = lsm_get_line_by_call_id(call_id); - //cc_feature(CC_SRC_GSM, call_id, 0, CC_FEATURE_CAC_RESP_PASS, NULL); - - /* Activate the wlan before allocating bandwidth */ - vcmActivateWlan(TRUE); - - if (vcmAllocateBandwidth(lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), sessions)) { - return(CC_CAUSE_OK); - } - - return(CC_CAUSE_CONGESTION); -} - -/** - * lsm_get_facility_by_line - * return facility by the given line - * - * @param[in]call_id - gsm's call_id for a new call. - * @param[in]line - line - * @param[in]expline - boolean indicating extra instance - * is needed. - * @param[in]dcb - pointer to void but it must be - * a pointer to fsmdef_dcb_t to bind with - * the new LCB. The reason to use a void - * pointer is the declaration of the function - * is in lsm.h. The lsm.h file is used by - * components outside gsm environment. Those - * modules would need to include the fsm.h - * which is not desirable. Using void pointer - * avoids this problem. - * - * @return cc_cause_t - * @pre (dcb not_eq NULL) - */ -cc_causes_t -lsm_get_facility_by_line (callid_t call_id, line_t line, boolean expline, - void *dcb) -{ - static const char fname[] = "lsm_get_facility_by_line"; - lsm_lcb_t *lcb; - int free_instances; - - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), call_id, line, fname, - "exp", expline); - - /* - * Check to see if we even have any available instances - */ - free_instances = lsm_get_instances_available_cnt(line, expline); - if (free_instances <= 0) { - return (CC_CAUSE_BUSY); - } - - lcb = lsm_get_free_lcb(call_id, line, (fsmdef_dcb_t *)dcb); - if (lcb == NULL) { - return (CC_CAUSE_NO_RESOURCE); - } - - return (CC_CAUSE_OK); -} - - -#ifdef _WIN32 -/* This function enumerates over the lcbs - * and attempts to terminate the call - * This is used by softphone when - * it exits and the softphone is - * still engaged in a call - */ -void -terminate_active_calls (void) -{ - callid_t call_id = CC_NO_CALL_ID; - lsm_lcb_t *lcb; - line_t line; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->call_id != CC_NO_CALL_ID) { - line = lsm_get_line_by_call_id(lcb->call_id); - /* Currently cc_feature does a better job of releasing the call - * compared to cc_onhook. - */ - //cc_onhook(CC_SRC_UI, call_id, line); - cc_feature(CC_SRC_UI, call_id, line, CC_FEATURE_END_CALL, NULL); - call_id = lcb->call_id; - } - } -} - - -#endif - -line_t -lsm_get_line_by_call_id (callid_t call_id) -{ - fsmdef_dcb_t *dcb; - line_t line; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb != NULL) { - line = dcb->line; - } else { - line = LSM_DEFAULT_LINE; - } - - return (line); -} - -/* - * This is a callback function for those tones that are - * played in two parts (stutter and msgwaiting) or played - * every x seconds, but are not steady tones (call waiting). - * - * @param[in] data The gsm ID (callid_t) of the call of the - * tones timer has timeout. - * - * @return N/A - */ -void -lsm_tmr_tones_callback (void *data) -{ - static const char fname[] = "lsm_tmr_tones_callback"; - callid_t call_id; - fsmdef_dcb_t *dcb = NULL; - fsmdef_media_t *media; - - LSM_DEBUG(DEB_F_PREFIX"invoked", DEB_F_PREFIX_ARGS(LSM, fname)); - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - LSM_DEBUG(DEB_F_PREFIX"invalid call id\n", DEB_F_PREFIX_ARGS(LSM, fname)); - return; - } - - /* - * A call-waiting tone should be played if these conditions are met: - * 1. A line must be ringing for an incoming call - * 2. The phone must be in a state that we handle callwaiting - */ - /* Retrieve dcb from call id */ - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX"no dcb found for call_id %d\n", DEB_F_PREFIX_ARGS(LSM, fname), call_id); - return; - } - - media = gsmsdp_find_audio_media(dcb); - - if ((lsm_find_state(LSM_S_RINGIN) > CC_NO_CALL_ID) && (lsm_callwaiting())) { - - /* Determine what tone/ringing pattern to play */ - switch (dcb->alert_info) { - - case ALERTING_RING: - - /* Need to map the alerting patterns to the call waiting patterns */ - switch (dcb->alerting_ring) { - case VCM_BELLCORE_DR2: - lsm_util_start_tone(VCM_CALL_WAITING_2_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - case VCM_BELLCORE_DR3: - lsm_util_start_tone(VCM_CALL_WAITING_3_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - case VCM_BELLCORE_DR4: - lsm_util_start_tone(VCM_CALL_WAITING_4_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - default: - lsm_util_start_tone(VCM_CALL_WAITING_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - } - break; - - case ALERTING_TONE: - - /* Busy verify is just 2 secs of dialtone followed by - * a call waiting tone every 10 secs. The rest of the - * tones are just played once. - */ - switch (dcb->alerting_tone) { - case VCM_BUSY_VERIFY_TONE: - lsm_util_start_tone(VCM_CALL_WAITING_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - if (cprStartTimer(lsm_tmr_tones, BUSY_VERIFICATION_DELAY, - (void *)(long)dcb->call_id) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } - break; - - case VCM_CALL_WAITING_TONE: - case VCM_CALL_WAITING_2_TONE: - case VCM_CALL_WAITING_3_TONE: - case VCM_CALL_WAITING_4_TONE: - lsm_util_start_tone(dcb->alerting_tone, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - - case VCM_MSG_WAITING_TONE: - case VCM_STUTTER_TONE: - lsm_util_start_tone(VCM_INSIDE_DIAL_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - lsm_tmr_tones_ticks = 0; - break; - default: - break; - } - break; - - default: - lsm_util_start_tone(VCM_CALL_WAITING_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - - break; - } - - } else if (dcb->dialplan_tone) { - dcb->dialplan_tone = FALSE; - switch (dcb->alert_info) { - - case ALERTING_TONE: - /* - * Currently the only supported multi-part tones - * played via the dialplan are Message Waiting and - * Stutter dialtones. - */ - switch (dcb->alerting_tone) { - case VCM_MSG_WAITING_TONE: - case VCM_STUTTER_TONE: - lsm_util_start_tone(VCM_INSIDE_DIAL_TONE, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - - case VCM_HOLD_TONE: - lsm_util_start_tone(dcb->alerting_tone, NO, lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - dcb->tone_direction); - break; - - default: - break; - } - - break; - - default: - break; - } - } -} - -/* - * Function : lsm_start_multipart_tone_timer - * Parameters : Tone: 2nd part of tone to play - * Delay: Time to delay between playing the 1st and 2nd parts of the tone - * CallId: Used to retrieve the dcb for this call - * Purpose : This function is used to set up the dcb to play the 2nd part of - * the tone. A timer is started to allow the 1st tone to played to - * completion before the 2nd part is started. - */ -void -lsm_start_multipart_tone_timer (vcm_tones_t tone, - uint32_t delay, - callid_t callId) -{ - static const char fname[] = "lsm_start_multipart_tone_timer"; - fsmdef_dcb_t *dcb; - - /* Set up dcb for timer callback function */ - dcb = fsmdef_get_dcb_by_call_id(callId); - dcb->alert_info = ALERTING_TONE; - dcb->alerting_tone = tone; - dcb->dialplan_tone = TRUE; - - if (cprCancelTimer(lsm_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } - if (cprStartTimer(lsm_tmr_tones, delay, (void *)(long)dcb->call_id) == - CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } -} - -/* - * Function : lsm_stop_multipart_tone_timer - * Parameters : None - * Purpose : Called from vcm_stop_tones. That function - * will stop the 1st part of the tone, this - * function cancels the timer so the 2nd part - * will never be played. - */ -void -lsm_stop_multipart_tone_timer (void) -{ - static const char fname[] = "lsm_stop_multipart_tone_timer"; - - if (cprCancelTimer(lsm_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } -} - -/* - * Function : lsm_start_continuous_tone_timer - * Parameters : Tone: tone to play - * Delay: Time to delay between playing the tone - * CallId: Used to retrieve the dcb for this call - * Purpose : This function is used to set up the dcb to play a tone continuously. - * An example being the tone on hold tone. - */ -void -lsm_start_continuous_tone_timer (vcm_tones_t tone, - uint32_t delay, - callid_t callId) -{ - static const char fname[] = "lsm_start_continuous_tone_timer"; - fsmdef_dcb_t *dcb; - - /* Set up dcb for timer callback function */ - dcb = fsmdef_get_dcb_by_call_id(callId); - dcb->alert_info = ALERTING_TONE; - dcb->alerting_tone = tone; - dcb->dialplan_tone = TRUE; - - if (cprCancelTimer(lsm_continuous_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } - if (cprStartTimer(lsm_continuous_tmr_tones, delay, (void *)(long)dcb->call_id) - == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } -} - -/* - * Function : lsm_stop_continuous_tone_timer - * Parameters : None - * Purpose : Called from vcm_stop_tones. That function - * will stop the the tone, this function cancels - * the timer subsequent playing of the tone is not - * performed - */ -void -lsm_stop_continuous_tone_timer (void) -{ - static const char fname[] = "lsm_stop_continuous_tone_timer"; - - if (cprCancelTimer(lsm_continuous_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } -} - -/* - * Function : lsm_start_tone_duration_timer - * Parameters : Tone: tone type to play - * Duration: length of time for tone to play - * call_handle: Used to retrieve the dcb for this call - * Purpose : This function is used to set up the dcb to play the tone for - * a specified length of time. - */ -void -lsm_start_tone_duration_timer (vcm_tones_t tone, - uint32_t duration, - cc_call_handle_t call_handle) -{ - static const char fname[] = "lsm_start_tone_duration_timer"; - fsmdef_dcb_t *dcb; - - /* Set up dcb for timer callback function */ - dcb = fsmdef_get_dcb_by_call_id(GET_CALL_ID(call_handle)); - - if (cprCancelTimer(lsm_tone_duration_tmr) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } - if (cprStartTimer(lsm_tone_duration_tmr, duration*1000, (void *)(long)dcb->call_id) == - CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } -} - -/* - * Function : lsm_stop_tone_duration_timer - * Parameters : None - * Purpose : Called from vcm_stop_tones. That function - * will stop the tone. - */ -void -lsm_stop_tone_duration_timer (void) -{ - static const char fname[] = "lsm_stop_tone_duration_timer"; - - if (cprCancelTimer(lsm_tone_duration_tmr) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } -} - -/* - * This is a callback function for those tones that are - * played in two parts (stutter and msgwaiting) or played - * every x seconds, but are not steady tones (call waiting). - * - * @param[in] data The gsm ID (callid_t) of the call of the - * tones timer has timeout. - * - * @return N/A - */ -void -lsm_tone_duration_tmr_callback (void *data) -{ - static const char fname[] = "lsm_tone_duration_tmr_callback"; - callid_t call_id; - fsmdef_dcb_t *dcb = NULL; - fsmdef_media_t *media; - - LSM_DEBUG(DEB_F_PREFIX"invoked", DEB_F_PREFIX_ARGS(LSM, fname)); - - call_id = (callid_t)(long)data; - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - LSM_DEBUG(DEB_F_PREFIX"invalid call id\n", DEB_F_PREFIX_ARGS(LSM, fname)); - return; - } - - /* Retrieve dcb from call id */ - dcb = fsmdef_get_dcb_by_call_id(call_id); - if (dcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX"no dcb found for call_id %d\n", DEB_F_PREFIX_ARGS(LSM, fname), call_id); - return; - } - - media = gsmsdp_find_audio_media(dcb); - - vcmToneStop(dcb->active_tone, dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - lsm_get_ms_ui_call_handle(dcb->line, dcb->call_id, CC_NO_CALL_ID)); - - /* Up until this point, only sip core has started the call release procedure */ - /* since upon receipt of the BYE. Now that tone is completed playing as requested */ - /* in the BYE, need to continue processing with call clearing. */ - - cc_int_release(CC_SRC_GSM, CC_SRC_GSM, call_id, dcb->line, CC_CAUSE_NORMAL, NULL, NULL); -} - -/* - * LSM internal function that checks if any calls are in a pending - * answer condition. Such a condition occurs when the GSM has delayed - * answering an incoming call while trying to clear other calls. - * - * @return call_id if found, else CC_NO_CALL_ID. - */ -static callid_t -lsm_answer_pending (void) -{ - callid_t found_callid = CC_NO_CALL_ID; - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb->call_id != CC_NO_CALL_ID) && - (FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_ANSWER_PENDING))) { - - found_callid = lcb->call_id; - break; - } - } - - return (found_callid); -} - -/** - * - * Hold Reversion Alert - plays the ringer once. - * - * @param lsm_lcb_t lcb for this call - * @param callid_t gsm_id - * @param line_t line - * - * @return none - * - * @pre (lcb not_eq NULL) - */ -static void -lsm_reversion_ringer (lsm_lcb_t *lcb, callid_t call_id, line_t line) -{ - vcm_ring_mode_t ringerMode = VCM_INSIDE_RING; - vcm_tones_t toneMode = VCM_CALL_WAITING_TONE; - - if (!lsm_callwaiting()) { - config_get_line_value(CFGID_LINE_RING_SETTING_IDLE, - &ringSettingIdle, sizeof(ringSettingIdle), - line); - if (cc_line_ringer_mode[line] == CC_RING_DISABLE) { - ringerMode = VCM_FLASHONLY_RING; - } else if (ringSettingIdle == DISABLE) { - ringerMode = VCM_RING_OFF; - } else if (ringSettingIdle == FLASH_ONLY) { - ringerMode = VCM_FLASHONLY_RING; - } - - vcmControlRinger(ringerMode, YES, NO, line, call_id); - - } else { - lsm_tmr_tones_ticks = 0; - - config_get_line_value(CFGID_LINE_RING_SETTING_ACTIVE, - &ringSettingActive, sizeof(ringSettingActive), - line); - if (ringSettingActive == DISABLE) { - ringerMode = VCM_RING_OFF; - } else if (ringSettingActive == FLASH_ONLY) { - ringerMode = VCM_FLASHONLY_RING; - } - - if (ringSettingActive == BEEP_ONLY) { - fsmdef_media_t *media = gsmsdp_find_audio_media(lcb->dcb); - - lsm_util_start_tone(toneMode, NO, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), lcb->dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - vcmControlRinger(ringerMode, YES, NO, line, call_id); - } - } -} - -/** - * This function will set beep only settings. - * - * @param[in] dcb - DEF S/M control block - * @param[out] toneMode_p - pointer to tone mode - * - * @return none - */ -static void -lsm_set_beep_only_settings (fsmdef_dcb_t *dcb, vcm_tones_t *toneMode_p) -{ - switch (dcb->alert_info) { - /* - * Map BTS requested ring pattern to corresponding call waiting - * pattern if phone is already offhook. All call waiting tones - * must be played every ten seconds and msg waiting and stutter - * dialtone are multi-part tones that play and then after - * 100 ms give steady dialtone. Set a timer to call the tone - * callback function for those tones. - */ - case ALERTING_RING: - lsm_tmr_tones_ticks = callWaitingDelay; - switch (dcb->alerting_ring) { - case VCM_BELLCORE_DR2: - *toneMode_p = VCM_CALL_WAITING_2_TONE; - break; - - case VCM_BELLCORE_DR3: - *toneMode_p = VCM_CALL_WAITING_3_TONE; - break; - - case VCM_BELLCORE_DR4: - *toneMode_p = VCM_CALL_WAITING_4_TONE; - break; - - default: - break; - } - break; - - /* BTS wishes to override call waiting tone */ - case ALERTING_TONE: - /* - * In violation of the spec, BTS will send tones in the - * Alert-Info header and if the phone is offhook, wants - * the phone to play the tone specified in the Alert-Info - * header instead of the normal call waiting tone. If this - * line is connected to a call manager follow the spec and - * always play the call waiting tone regardless of what was - * received in the Alert-Info header. - */ - if (sip_regmgr_get_cc_mode(dcb->line) == REG_MODE_CCM) { - dcb->alerting_tone = VCM_CALL_WAITING_TONE; - LSM_DEBUG(DEB_F_PREFIX"%s - Overriding value in Alert-Info header as line %d is \ - connected to a Call Manager.\n", - DEB_F_PREFIX_ARGS(LSM, "lsm_set_beep_only_settings"), dcb->line); - } - *toneMode_p = dcb->alerting_tone; - switch (dcb->alerting_tone) { - case VCM_MSG_WAITING_TONE: - lsm_tmr_tones_ticks = MSG_WAITING_DELAY; - break; - - case VCM_STUTTER_TONE: - lsm_tmr_tones_ticks = STUTTER_DELAY; - break; - - case VCM_BUSY_VERIFY_TONE: - lsm_tmr_tones_ticks = BUSY_VERIFY_DELAY; - break; - - case VCM_CALL_WAITING_TONE: - case VCM_CALL_WAITING_2_TONE: - case VCM_CALL_WAITING_3_TONE: - case VCM_CALL_WAITING_4_TONE: - lsm_tmr_tones_ticks = callWaitingDelay; - break; - - default: - break; - } - break; - - default: - lsm_tmr_tones_ticks = callWaitingDelay; - } -} - -/** - * - * Set ringer mode based on remote-cc input and configuration parameters. If there - * any other call pending then it should play call waiting tone. - * - * @param lsm_lcb_t lcb for this call - * @param callid_t gsm_id - * @param line_t line - * - * @return none - * - * @pre (lcb not_eq NULL) - */ -static void -lsm_set_ringer (lsm_lcb_t *lcb, callid_t call_id, line_t line, int alerting) -{ - static const char fname[] = "lsm_set_ringer"; - fsmdef_dcb_t *dcb; - boolean ringer_set = FALSE; - callid_t other_call_id = CC_NO_CALL_ID; - callid_t priority_call_id = CC_NO_CALL_ID; - int callHoldRingback = 0; - int dcb_cnt = 0; - int i = 0; - fsmxfr_xcb_t *xcb; - fsmcnf_ccb_t *ccb; - lsm_lcb_t *lcb2; - fsmdef_dcb_t *dcbs[LSM_MAX_CALLS]; - vcm_ring_mode_t ringerMode = VCM_INSIDE_RING; - short ringOnce = NO; - boolean alertInfo = NO; - vcm_tones_t toneMode = VCM_CALL_WAITING_TONE; - fsmdef_media_t *media; - boolean isDusting = FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_DUSTING) ? TRUE : FALSE; - int sdpmode = 0; - - - LSM_DEBUG(DEB_L_C_F_PREFIX"Entered, state=%d.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), lcb->state); - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - /* - * The ringer (or call-waiting tone) should be on if these - * conditions are met: - * 1. A line is ringing for an incoming call and no calls - * with a pending answer - * 2. A line is on hold - * and - * 3. No lines are connected - * - * Otherwise, turn on the call-waiting tones. - * - */ - - if (priority_call_id == CC_NO_CALL_ID) { - /* get the call_id of the line that triggers this if it is ringing and - pass down the correct line variable and its ring type and let the ring - manager decides. Originally we only find line first line in ringing state - which results in issue where Flash only line follows by audio ring line - ringing simultaneously, the phone does not ring audibly. - */ - if (lcb->state == LSM_S_RINGIN) { - other_call_id = call_id; - } else { - other_call_id = lsm_find_state(LSM_S_RINGIN); - } - } - - if (((priority_call_id != CC_NO_CALL_ID) || (other_call_id != CC_NO_CALL_ID)) && - (lsm_answer_pending() == CC_NO_CALL_ID)) { - /*sam - * may need to add (ringout and rtp open) to this check. - * It is possible that inband alerting is active for an outgoing call. - */ - dcb = fsmdef_get_dcb_by_call_id((priority_call_id != CC_NO_CALL_ID) ? - priority_call_id : other_call_id); - lcb = lsm_get_lcb_by_call_id((priority_call_id != CC_NO_CALL_ID) ? - priority_call_id : other_call_id); - isDusting = ((lcb != NULL) && FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_DUSTING)) ? TRUE : FALSE; - - /* - * TNP has line-based ringing so update the line parameter so - * if reflects what line is ringing, not which line had an action - * taken against it, i.e. if line 1 hangs up and line 2 is ringing, - * line will be equal to 1 (since that line hung-up), but it needs - * to be 2 since that is the line actually ringing. 40/60 can - * get away with this since it is device-based ringing. If there - * are multiple lines in the RINGIN state, the ringing will be - * based on the first line in the RINGIN state found. Could add - * the check if (other_call_id != callid) but line will equal - * dcb->line if the callids are the same so save a few CPU cycles - * by not having the check. No need to do a #ifdef TNP since - * it does matter which line we use on the 40/60 as it is device based. - */ - line = dcb->line; - - if (!lsm_callwaiting()) { - - LSM_DEBUG(DEB_L_C_F_PREFIX"No call waiting, lcb->line=%d, lcb->flag=%d.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, lcb->call_id, fname), - lcb->line, - lcb->flags); - - ringer_set = TRUE; - lsm_tmr_tones_ticks = 0; - - /* - * CFGID_LINE_RING_SETTING_IDLE is a config parameter that - * tells the phone what action to take for an incoming - * call on a phone with no active calls. - * - */ - - if (isDusting) { - ringSettingIdle = FLASH_ONLY; - } - else if (FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_PREVENT_RINGING)) { - /* - * If this phone is both calling and called device, do not play ring. - */ - ringSettingIdle = DISABLE; - } else if (cc_line_ringer_mode[line] == CC_RING_DISABLE) { - /* - * Disable - no ring or flash - */ - ringSettingIdle = FLASH_ONLY; - } else if (cc_line_ringer_mode[line] == CC_RING_ENABLE) { - ringSettingIdle = RING; - } else { - config_get_line_value(CFGID_LINE_RING_SETTING_IDLE, - &ringSettingIdle, sizeof(ringSettingIdle), - line); - } - LSM_DEBUG(DEB_L_C_F_PREFIX"Ring set mode=%d.\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), ringSettingIdle); - - /* - * Disable - no ring or flash - */ - if (ringSettingIdle == DISABLE) { - ringerMode = VCM_RING_OFF; - - /* - * Flash Only - No ringing, just flash. - */ - } else if (ringSettingIdle == FLASH_ONLY) { - ringerMode = VCM_FLASHONLY_RING; - - /* - * Ring once - ring the phone once - */ - } else if (ringSettingIdle == RING_ONCE) { - ringOnce = YES; - - /* - * Ring - normal operation. Ring the phone until answered, - * forwarded, or disconnected. - */ - } else if (ringSettingIdle == RING) { - - /* Determine what tone/ringing pattern to play */ - switch (dcb->alert_info) { - case ALERTING_NONE: - /* This is the default case nothing to do */ - break; - - case ALERTING_RING: - ringerMode = dcb->alerting_ring; - break; - - case ALERTING_OLD: - default: - alertInfo = YES; - } - } else if (ringSettingIdle == BEEP_ONLY) { - lsm_set_beep_only_settings (dcb, &toneMode); - - } - LSM_DEBUG(DEB_L_C_F_PREFIX"Alert info=%d, ringSettingIdle=%d, ringerMode=%d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), - dcb->alert_info, - ringSettingIdle, - ringerMode); - - /* - * If an active call is being held while there is an incoming - * call AND ringSettingBusyStationPolicy is 0, this flag will - * be false. - */ - if (alerting) { - /* - * If the line is connected to a CCM, Bellcore-Dr1 means - * play the defined ringer once. Bellcore-dr2 means play - * the defined ringer twice. - */ - if (sip_regmgr_get_cc_mode(line) == REG_MODE_CCM) { - if (ringerMode == VCM_BELLCORE_DR1) { - ringerMode = VCM_INSIDE_RING; - } else if (ringerMode == VCM_BELLCORE_DR2) { - ringerMode = VCM_OUTSIDE_RING; - } - } - if (ringSettingIdle == BEEP_ONLY) { - - LSM_DEBUG(DEB_L_C_F_PREFIX"Idle phone RING SETTING: Beep_only\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname)); - - media = gsmsdp_find_audio_media(lcb->dcb); - lsm_util_tone_start_with_speaker_as_backup(toneMode, NO, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), - lcb->dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - LSM_DEBUG(DEB_L_C_F_PREFIX"Idle phone RING SETTING: ringer Mode = %s," - " Ring once = %d, alertInfo = %d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), - vm_alert_names[ringerMode], ringOnce, alertInfo); - - vcmControlRinger(ringerMode, ringOnce, alertInfo, line, lcb->ui_id); - } - } - - if ( lcb->state != LSM_S_HOLDING && - lcb->state != LSM_S_RINGIN ) { - ui_set_call_status(platform_get_phrase_index_str(CALL_ALERTING), - line, lcb->ui_id); - } - } else { - - // Ring off all lines. - FSM_FOR_ALL_CBS(lcb2, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb2->call_id != CC_NO_CALL_ID) && - (lcb2->state == LSM_S_RINGIN) ) - { - LSM_DEBUG(DEB_L_C_F_PREFIX"Call waiting RING SETTING: " - "ringer Mode = RING_OFF, Ring once = NO, alertInfo = NO\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb2->line, lcb2->call_id, fname)); - vcmControlRinger(VCM_RING_OFF, NO, NO, lcb2->line, call_id); - } - } - ringer_set = TRUE; - lsm_tmr_tones_ticks = 0; - - /* - * ringSettingActive is a TNP only config parameter that - * tells the phone what action to take for an incoming - * call on a phone with an active call. - */ - if (isDusting) { - ringSettingActive = FLASH_ONLY; - } else { - config_get_line_value(CFGID_LINE_RING_SETTING_ACTIVE, - &ringSettingActive, sizeof(ringSettingActive), - line); - } - - /* - * Disable - no ring or flash - */ - if (ringSettingActive == DISABLE) { - ringerMode = VCM_RING_OFF; - - /* - * Flash Only - No ringing, just flash. - */ - } else if (ringSettingActive == FLASH_ONLY) { - ringerMode = VCM_FLASHONLY_RING; - - /* - * Ring once - ring the phone once - */ - } else if (ringSettingActive == RING_ONCE) { - ringOnce = YES; - - /* - * Ring - Ring the phone until answered, forwarded or - * disconnected. - * - * NOTE: This code is replicated above under checking - * RING_SETTING_IDLE above. Putting this common code - * in a function call saved a miniscule amount of memory - * at the cost of an additional function call for every - * call. It was decided it was not worth the cost, but - * has been documented in case the phone gets very, - * very low on memory in the future. - */ - } else if (ringSettingActive == RING) { - - /* Determine what tone/ringing pattern to play */ - switch (dcb->alert_info) { - case ALERTING_NONE: - /* This is the default case nothing to do */ - break; - - case ALERTING_RING: - ringerMode = dcb->alerting_ring; - break; - - case ALERTING_OLD: - default: - alertInfo = YES; - } - - /* - * BeepOnly - normal operation. Play call waiting tone. - */ - } else if (ringSettingActive == BEEP_ONLY) { - lsm_set_beep_only_settings (dcb, &toneMode); - - } - - /* - * If an active call is being held while there is an incoming - * call AND ringSettingBusyStationPolicy is 0, this flag will - * be false. - */ - if (alerting) { - /* - * The code above has set the variables to play either the ringer - * or a tone based on the ringSettingBusy. If the config variable - * is beeponly then call start_tone else call control_ringer. - */ - if (ringSettingActive == BEEP_ONLY) { - media = gsmsdp_find_audio_media(dcb); - - lsm_util_start_tone(toneMode, NO, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - - LSM_DEBUG(DEB_L_C_F_PREFIX"Active call RING SETTING: " - "ringer Mode = %s, Ring once = %d, alertInfo = %d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), - vm_alert_names[ringerMode], ringOnce, alertInfo); - - vcmControlRinger(ringerMode, ringOnce, alertInfo, line, lcb->ui_id); - } - } - - /* - * Start a timer to play multiple part tones if needed. - */ - if (lsm_tmr_tones_ticks > 0) { - if (cprCancelTimer(lsm_tmr_tones) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprCancelTimer", cpr_errno); - } - if (cprStartTimer(lsm_tmr_tones, lsm_tmr_tones_ticks, - (void *)(long)dcb->call_id) == CPR_FAILURE) { - LSM_DEBUG(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprStartTimer", cpr_errno); - } - } - } - } else if (lcb->state == LSM_S_IDLE) { - /* - * This line just hungup so let's check to see if call hold ringback - * is enabled and if we have any other holding lines. If so ring to - * alert the user that a line is still around. - */ - config_get_value(CFGID_CALL_HOLD_RINGBACK, &callHoldRingback, - sizeof(callHoldRingback)); - if (callHoldRingback & 0x1) { - callid_t ui_id; - - dcb_cnt = fsmdef_get_dcbs_in_held_state(dcbs, call_id); - for (i = 0, dcb = dcbs[i]; i < dcb_cnt; i++, dcb = dcbs[i]) { - ccb = fsmcnf_get_ccb_by_call_id(call_id); - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if ((lsm_is_phone_inactive() == TRUE) && - (ccb == NULL) && (xcb == NULL) && - (lcb->enable_ringback == TRUE)) { - LSM_DEBUG(DEB_L_C_F_PREFIX"Applying ringback\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, fname)); - ringer_set = TRUE; - - LSM_DEBUG(DEB_L_C_F_PREFIX"Hold RINGBACK SETTING: ringer Mode = " - "VCM_INSIDE_RING, Ring once = YES, alertInfo = YES\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, dcb->call_id, fname)); - vcmControlRinger(VCM_INSIDE_RING, YES, YES, line, call_id); - - /* Find the corresponding LCB to get to the UI ID */ - ui_id = lsm_get_ui_id(dcb->call_id); - ui_set_call_status(platform_get_phrase_index_str(CALL_INITIATE_HOLD), - dcb->line, ui_id); - } - } - } - } - - if (ringer_set == FALSE) { - - LSM_DEBUG(DEB_L_C_F_PREFIX"Ringer_set = False : " - "ringer Mode = VCM_RING_OFF, Ring once = NO, alertInfo = NO\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname)); - - - if (!sdpmode) { - vcmControlRinger(VCM_RING_OFF, NO, NO, line, call_id); - } - - } -} - -static cc_rcs_t -lsm_offhook (lsm_lcb_t *lcb, cc_state_data_offhook_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmxfr_xcb_t *xcb; - lsm_lcb_t *lcb2; - callid_t call_id2; - int attr; - fsmdef_dcb_t *dcb; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_OFFHOOK); - - /* - * Disable the ringer since the user is going offhook. Only calls - * in the RINGIN state should have ringing enabled. - */ - FSM_FOR_ALL_CBS(lcb2, lsm_lcbs, LSM_MAX_LCBS) { - if ((lcb2->call_id != CC_NO_CALL_ID) && - (lcb2->state == LSM_S_RINGIN)) { - - vcmControlRinger(VCM_RING_OFF, NO, NO, lcb2->line, lcb2->call_id); - } - } - - dp_offhook(line, call_id); - - attr = fsmutil_get_call_attr(dcb, line, call_id); - - ui_new_call(evOffHook, line, lcb->ui_id, attr, - dcb->caller_id.call_instance_id, - (boolean)FSM_CHK_FLAGS(lcb->flags, LSM_FLAGS_DIALED_STRING)); - - xcb = fsmxfr_get_xcb_by_call_id(call_id); - if (xcb != NULL) { - call_id2 = ((lcb->call_id == xcb->xfr_call_id) ? - (xcb->cns_call_id) : (xcb->xfr_call_id)); - lcb2 = lsm_get_lcb_by_call_id(call_id2); - } - - //vcmActivateWlan(TRUE); - - vcmEnableSidetone(YES); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_dialing (lsm_lcb_t *lcb, cc_state_data_dialing_t *data) -{ - fsmxfr_xcb_t *xcb = NULL; - int stutterMsgWaiting = 0; - fsmdef_dcb_t *dcb = lcb->dcb; - fsmdef_media_t *media = gsmsdp_find_audio_media(dcb); - - - if ( dcb == NULL) { - return (CC_RC_ERROR); - } - - /* don't provide dial tone on transfer unless we are the transferor. */ - xcb = fsmxfr_get_xcb_by_call_id(lcb->call_id); - if ((xcb != NULL) && (xcb->mode != FSMXFR_MODE_TRANSFEROR)) { - return (CC_RC_SUCCESS); - } - - /* - * Start dial tone if no digits have been entered - */ - if ((data->play_dt == TRUE) - && (dp_check_for_plar_line(lcb->line) == FALSE) - ) { - - /* get line based AMWI config */ - config_get_value(CFGID_LINE_MESSAGE_WAITING_AMWI + lcb->line - 1, &stutterMsgWaiting, - sizeof(stutterMsgWaiting)); - if ( stutterMsgWaiting != 1 && stutterMsgWaiting != 0) { - /* AMWI is not configured. Fallback on config for stutter dial tone */ - config_get_value(CFGID_STUTTER_MSG_WAITING, &stutterMsgWaiting, - sizeof(stutterMsgWaiting)); - stutterMsgWaiting &= 0x1; /* LSB indicates on/off */ - } - - if ( (data->suppress_stutter == FALSE) && - (ui_line_has_mwi_active(lcb->line)) && /* has msgs waiting */ - stutterMsgWaiting ) { - lsm_util_start_tone(VCM_STUTTER_TONE, FALSE, lsm_get_ms_ui_call_handle(lcb->line, CC_NO_CALL_ID, lcb->ui_id), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - lsm_util_start_tone(VCM_INSIDE_DIAL_TONE, FALSE, lsm_get_ms_ui_call_handle(lcb->line, CC_NO_CALL_ID, lcb->ui_id), - dcb->group_id, - ((media != NULL) ? media->refid : CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } - } - - /* - * For round table phone, post WAITINGFORDIGITS event, - * so that UI can pop up dialing screen. - * For TNP, this event gets ignored. - */ - ui_call_state(evWaitingForDigits, lcb->line, lcb->ui_id, CC_CAUSE_NORMAL); - - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_dialing_completed (lsm_lcb_t *lcb, cc_state_data_dialing_completed_t *data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb = lcb->dcb; - - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_PROCEED); - - /* If KPML is enabled then do not change UI state to - * proceed, more digit to collect - */ - if (dp_get_kpml_state()) { - return (CC_RC_SUCCESS); - } - - ui_call_info(data->caller_id.calling_name, - data->caller_id.calling_number, - data->caller_id.alt_calling_number, - data->caller_id.display_calling_number, - data->caller_id.called_name, - data->caller_id.called_number, - data->caller_id.display_called_number, - data->caller_id.orig_called_name, - data->caller_id.orig_called_number, - data->caller_id.last_redirect_name, - data->caller_id.last_redirect_number, - (calltype_t)dcb->call_type, - line, lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - - lsm_ui_call_state(evProceed, line, lcb, CC_CAUSE_NORMAL); - - (void) lsm_stop_tone(lcb, NULL); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_call_sent (lsm_lcb_t *lcb, cc_state_data_call_sent_t *data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - char tmp_str[STATUS_LINE_MAX_LEN]; - fsmdef_media_t *media; - static const char fname[] = "lsm_call_sent"; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_PROCEED); - - (void) lsm_stop_tone(lcb, NULL); - - /* - * We go ahead and start a rx port if our local SDP indicates - * the need in an attempt to be 3264 compliant. Since we have - * not yet locked down the codec, we will use preferred codec if - * configured. If not, we use the first codec in our local - * list of supported codecs. The codec list was initialized - * in fsmdef_init_local_sdp. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - continue; - } - LSM_DEBUG(DEB_F_PREFIX"%d %d %d\n", DEB_F_PREFIX_ARGS(LSM, fname), media->direction_set, - media->direction, media->is_multicast); - if ((media->direction_set) && - ((media->direction == SDP_DIRECTION_SENDRECV) || - (media->direction == SDP_DIRECTION_RECVONLY))) { - - lsm_rx_start(lcb, cc_state_name(CC_STATE_FAR_END_ALERTING), - media); - } - } - - if (!dp_get_kpml_state()) { - if ((platGetPhraseText(STR_INDEX_CALLING, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - ui_set_call_status(tmp_str, line, lcb->ui_id); - } - } - - /* - * cancel offhook to first digit timer. - */ - dp_int_cancel_offhook_timer(line, lcb->call_id); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_far_end_proceeding (lsm_lcb_t *lcb, - cc_state_data_far_end_proceeding_t * data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - - lsm_change_state(lcb, __LINE__, LSM_S_PROCEED); - - if (!dp_get_kpml_state()) { - ui_set_call_status(platform_get_phrase_index_str(CALL_PROCEEDING_IN), - line, lcb->ui_id); - /* - * update placed call info in call history with dialed digits - */ - dcb = lcb->dcb; - if (dcb != NULL && dcb->placed_call_update_required) { - lsm_update_placed_callinfo(dcb); - dcb->placed_call_update_required = FALSE; - } - } - - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_far_end_alerting (lsm_lcb_t *lcb, cc_state_data_far_end_alerting_t *data) -{ - static const char fname[] = "lsm_far_end_alerting"; - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - const char *status = NULL; - fsmcnf_ccb_t *ccb; - boolean rcv_port_started = FALSE; - char tmp_str[STATUS_LINE_MAX_LEN]; - boolean spoof_ringout; - fsmdef_media_t *media; - call_events call_state; - fsmdef_media_t *audio_media; - boolean is_session_progress = FALSE; - - - /* - * Need to check if rcv_chan is already open and if we will be - * receiving inband ringing. The recv_chan should always be - * open since we always open a receive channel when initiating a - * call. If inband ringing will be sent by the far end, we - * will close the receive port and reopen it using the codec - * negotiated when we received the SDP in the far ends call - * proceeding message. We want to close the receive port well - * ahead of reopening it due to some issue in the dsp where - * a close followed immediately by an open causes a reset of - * the DSP. - */ - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - audio_media = gsmsdp_find_audio_media(dcb); - - if (dcb->inband) { - /* close (with refresh) all media entries */ - lsm_close_rx(lcb, TRUE, NULL); - lsm_close_tx(lcb, TRUE, NULL); - } - - /* - * Check to see if we need to spoof ring out in connected or holding - * state. - * - * The LSM can be in holding state when the user is resuming - * currently held call that was early transferred to another party - * and the other party has not answered the call yet. - */ - if (dcb->spoof_ringout_requested && - ((lcb->state == LSM_S_CONNECTED) || (lcb->state == LSM_S_HOLDING))) { - /* Spoof ring out is requested in the connected/holding state */ - spoof_ringout = TRUE; - } else { - spoof_ringout = FALSE; - } - lsm_change_state(lcb, __LINE__, LSM_S_RINGOUT); - - /* Don't send the dialplan update msg if CFWD_ALL. Otherwise the invalid - * redial numer is saved. (CSCsv08816) - */ - if (dcb->active_feature != CC_FEATURE_CFWD_ALL) { - dp_int_update(line, call_id, data->caller_id.called_number); - } - - - /* - * Check for inband alerting or spoof ringout. - * If no inband alerting and this is not a spoof ringout case, - * just update the status line to show we are alerting. The local - * ringback tone will not be started until the ringback delay timer - * expires. - */ - if (dcb->inband != TRUE || spoof_ringout) { - status = platform_get_phrase_index_str(CALL_ALERTING_LOCAL); - - if (spoof_ringout) { - - if (audio_media) { - - /* - * Ringback delay timer is not used for spoof ringout case - * so start local ringback tone now. - */ - lsm_util_start_tone(VCM_ALERTING_TONE, FALSE, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), - dcb->group_id,audio_media->refid, - VCM_PLAY_TONE_TO_EAR); - } - - } - } else { - is_session_progress = TRUE; - (void) lsm_stop_tone(lcb, NULL); - - if ((platGetPhraseText(STR_INDEX_SESSION_PROGRESS, - (char *) tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - status = tmp_str; - } - - /* start receive and transmit for all media entries that are active */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not active */ - continue; - } - LSM_DEBUG(DEB_L_C_F_PREFIX"direction_set:%d direction:%d" - " dest_addr:0x%x is_multicast:%d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), - media->direction_set, - media->direction, media->dest_addr, - media->is_multicast); - - if (media->direction_set) { - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_RECVONLY) { - lsm_rx_start(lcb, - cc_state_name(CC_STATE_FAR_END_ALERTING), - media); - rcv_port_started = TRUE; - } - - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_SENDONLY) { - lsm_tx_start(lcb, - cc_state_name(CC_STATE_FAR_END_ALERTING), - media); - } - } - } - - if (!rcv_port_started) { - /* - * Since we had SDP we thought inband ringback was in order but - * media attributes indicate the receive port is to remain - * closed. In this case, go ahead and apply local ringback tone - * or user will hear silence. We do not depend on ringback delay - * timer to start the local ringback tone so we have to start it - * here. - */ - status = platform_get_phrase_index_str(CALL_ALERTING_LOCAL); - lsm_util_start_tone(VCM_ALERTING_TONE, FALSE, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), dcb->group_id, - ((audio_media != NULL) ? audio_media->refid : - CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } else { - lsm_set_ringer(lcb, call_id, line, YES); - } - } - - ccb = fsmcnf_get_ccb_by_call_id(call_id); - - /* Update call information */ - lsm_internal_update_call_info(lcb, dcb); - - /* This is the case where remote end of the call has been early trasnfered - * to another endpoint. - */ - - ccb = fsmcnf_get_ccb_by_call_id(lcb->call_id); - - if ((ccb != NULL) && (ccb->active == TRUE) && - (ccb->flags & LCL_CNF)) { - call_state = evConference; - } else { - call_state = evRingOut; - } - - /* If an invalid DN is dialed during CFA then CCM sends 183/Session Progress - * (a.k.a. far end alerting) so it can play the invalid DN announcement. In - * this case CCM sends 404 Not Found after playing the announcement. If we - * are here due to that situation then don't propagate call info or status - * to UI side as it will display "Session Progress" on the status line and - * will log the DN in Placed calls; and we don't want either. Just skip the - * update and following 404 Not Found will take care of playing/displaying - * Reorder. Note that this condition may occur only in TNP/CCM mode. - */ - if (dcb->active_feature != CC_FEATURE_CFWD_ALL) { - if(!is_session_progress) {//CSCtc18750 - /* - * update placed call info in call history with dialed digits - */ - if (dcb->placed_call_update_required) { - lsm_update_placed_callinfo(dcb); - dcb->placed_call_update_required = FALSE; - } - - if (status) { - ui_set_call_status(status, line, lcb->ui_id); - } - } - - lsm_ui_call_state(call_state, line, lcb, CC_CAUSE_NORMAL); - - } - /* For roundtable phones, UI will be in dial state, which is different from TNP UI, - * TNP UI does not have different dialing layer. In this case offhook dialing screen - * does not vanish untill GSM provides procced call status, hence all the softkeys are - * available during CFWD, which is not correct - */ - if (dcb->active_feature == CC_FEATURE_CFWD_ALL) { - lsm_ui_call_state(evReorder, line, lcb, CC_CAUSE_NORMAL); - } - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_call_received (lsm_lcb_t *lcb, cc_state_data_call_received_t *data) -{ - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_alerting (lsm_lcb_t *lcb, cc_state_data_alerting_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_RINGIN); - - dcb->ui_update_required = TRUE; - lsm_internal_update_call_info(lcb, dcb); - - ui_new_call(evRingIn, line, lcb->ui_id, NORMAL_CALL, - dcb->caller_id.call_instance_id, FALSE); - - fsmutil_set_shown_calls_ci_element(dcb->caller_id.call_instance_id, line); - lsm_ui_call_state(evRingIn, line, lcb, CC_CAUSE_NORMAL); - lsm_update_inalert_status(line, lcb->ui_id, data, TRUE); - - - lsm_set_ringer(lcb, call_id, line, YES); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_answered (lsm_lcb_t *lcb, cc_state_data_answered_t *data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_change_state(lcb, __LINE__, LSM_S_OFFHOOK); - - - lsm_internal_update_call_info(lcb, dcb); - - vcmControlRinger(VCM_RING_OFF, NO, NO, line, dcb->call_id); - - lsm_ui_call_state(evOffHook, line, lcb, CC_CAUSE_NORMAL); - - //vcmActivateWlan(TRUE); - - (void) lsm_stop_tone(lcb, NULL); - - return (CC_RC_SUCCESS); -} - -/** - * - * Function updates media paths based on the negotated parameters. - * - * @param lcb line control block - * @param caller_fname caller function name - * - * @return none - * - * @pre (dcb not_eq NULL) - * @pre (fname not_eq NULL) - */ -static void -lsm_update_media (lsm_lcb_t *lcb, const char *caller_fname) -{ - static const char fname[] = "lsm_update_media"; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - boolean rx_refresh; - boolean tx_refresh; - char addr_str[MAX_IPADDR_STR_LEN]; - int i; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), - fname); - return; - } - - addr_str[0] = '\0'; - - /* - * Close rx and tx port for media change. Check media direction - * to see if port should be closed or remain open. If the port - * needs to be kept open, lsm_close_* functions will check to - * see if any media attributes have changed. If anything has - * changed, the port is closed, otherwise the port remains - * open. If media direction is not set, treat as if set to inactive. - * Also, if multicast leave rx_refresh and tx_refresh to FALSE to - * force a socket close. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media) || - FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL)) { - /* this entry is not active or locally held */ - continue; - } - - rx_refresh = FALSE; - tx_refresh = FALSE; - - if ((media->direction_set) && (media->is_multicast == FALSE)) { - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_RECVONLY) { - rx_refresh = TRUE; - } - if (media->direction == SDP_DIRECTION_SENDRECV || - media->direction == SDP_DIRECTION_SENDONLY) { - tx_refresh = TRUE; - } - } - - lsm_close_rx(lcb, rx_refresh, media); - lsm_close_tx(lcb, tx_refresh, media); - - if (LSMDebug) { - /* debug is enabled, format the dest addr into string */ - ipaddr2dotted(addr_str, &media->dest_addr); - for (i = 0; i < media->num_payloads; i++) - { - LSM_DEBUG(DEB_L_C_F_PREFIX"%d rx, tx refresh's are %d %d" - ", dir=%d, payload=%d addr=%s, multicast=%d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, - dcb->call_id, fname), media->refid, rx_refresh, - tx_refresh, media->direction, - media->payloads[i], addr_str, media->is_multicast ); - } - } - if (rx_refresh || - (media->is_multicast && - media->direction_set && - media->direction == SDP_DIRECTION_RECVONLY)) { - lsm_rx_start(lcb, caller_fname, media); - } - if (tx_refresh) { - lsm_tx_start(lcb, caller_fname, media); - } - if ( rx_refresh && - (media->cap_index == CC_VIDEO_1)) { - // force an additional update so UI can refresh the remote view - ui_update_video_avail(dcb->line, lcb->ui_id, dcb->cur_video_avail); - LSM_DEBUG(DEB_L_C_F_PREFIX"Video Avail Called %d", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, lcb->ui_id, fname), dcb->cur_video_avail); - } - } -} - -/** - * - * Function to set media attributes and set the ui state. - * - * @param lcb line control block - * @param line line - * @param fname caller function name - * - * @return none - * - * @pre (dcb not_eq NULL) - * @pre (fname not_eq NULL) - */ -static void -lsm_call_state_media (lsm_lcb_t *lcb, line_t line, const char *fname) -{ - fsmcnf_ccb_t *ccb; - fsmdef_dcb_t *dcb; - call_events call_state; - callid_t call_id = lcb->call_id; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), - "lsm_call_state_media"); - return; - } - - ccb = fsmcnf_get_ccb_by_call_id(call_id); - - /* Update media parametes to the platform */ - lsm_update_media(lcb, fname); - - if ((ccb != NULL) && (ccb->active == TRUE)) { - /* For joined call leg, do not change UI state to conf. */ - if ((ccb->flags & JOINED) || - (fname == cc_state_name(CC_STATE_RESUME))) { - call_state = evConnected; - } else { - call_state = evConference; - } - } else { - call_state = evConnected; - } - - /* - * Possible media changes, update call information and followed - * by the state update. This is important sequence for 7940/60 - * SIP to force the BTXML update. - */ - // Commenting out original code for CSCsv72370. Leaving here for reference. - // lsm_internal_update_call_info(lcb, dcb); - - lsm_ui_call_state(call_state, line, lcb, CC_CAUSE_NORMAL); - // CSCsv72370 - Important sequence for TNP this follows state change - lsm_internal_update_call_info(lcb, dcb); -} - - -static cc_rcs_t -lsm_connected (lsm_lcb_t *lcb, cc_state_data_connected_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - int alerting = YES; - call_events original_call_event; - int ringSettingBusyStationPolicy; - boolean tone_stop_bool = TRUE; - int sdpmode = 0; - boolean start_ice = FALSE; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - original_call_event = lcb->previous_call_event; - /* - * If a held call is being resumed, check the - * policy to see if the phone should resume alerting. - */ - if (lcb->state == LSM_S_HOLDING) { - config_get_value(CFGID_RING_SETTING_BUSY_POLICY, - &ringSettingBusyStationPolicy, - sizeof(ringSettingBusyStationPolicy)); - if (0 == ringSettingBusyStationPolicy) { - alerting = NO; - } - - /* - * CSCtd31671: When agent phone resumes from a held call with - * monitor warning tone, the tone should not be stopped. - */ - if(lcb->dcb->active_tone == VCM_MONITORWARNING_TONE || lcb->dcb->active_tone == VCM_RECORDERWARNING_TONE) - tone_stop_bool = FALSE; - } - - /* Don't try to start ICE unless this is the first time connecting. - * TODO(ekr@rtfm.com): Is this the right ICE start logic? What about restarts - */ - if (strlen(dcb->peerconnection) && lcb->state != LSM_S_CONNECTED) - start_ice = TRUE; - - lsm_change_state(lcb, __LINE__, LSM_S_CONNECTED); - - if (!sdpmode) { - if (tone_stop_bool == TRUE) - (void) lsm_stop_tone(lcb, NULL); - } - - /* Start ICE */ - if (start_ice) { - short res = vcmStartIceChecks(dcb->peerconnection); - /* TODO(emannion): Set state to dead here. */ - if (res) - return CC_RC_SUCCESS; - } - - /* - * Open the RTP receive channel. - */ - lsm_call_state_media(lcb, line, cc_state_name(CC_STATE_CONNECTED)); - - - if (!sdpmode) { - vcmEnableSidetone(YES); - - lsm_set_ringer(lcb, call_id, line, alerting); - } - - FSM_RESET_FLAGS(lcb->flags, LSM_FLAGS_ANSWER_PENDING); - FSM_RESET_FLAGS(lcb->flags, LSM_FLAGS_DUSTING); - - /* - * update placed call info in call history with dialed digits - */ - if (dcb->placed_call_update_required) { - lsm_update_placed_callinfo(dcb); - dcb->placed_call_update_required = FALSE; - } - - /* - * If UI state was changed, update status line. - */ - if (lcb->previous_call_event != original_call_event) { - if (lcb->previous_call_event == evConference) { - } else { - - ui_set_call_status(platform_get_phrase_index_str(CALL_CONNECTED), - line, lcb->ui_id); - } - } - ui_update_video_avail(line, lcb->ui_id, dcb->cur_video_avail); - return (CC_RC_SUCCESS); -} - -/** - * Function: lsm_hold_reversion - * Perform Hold Reversion on the given call - * any other call pending then it should play call waiting tone. - * - * @param lsm_lcb_t lcb for this call - * - * @return cc_rcs_t SUCCESS or FAILURE of the operation - * - * @pre (lcb not_eq NULL) - */ - -static cc_rcs_t -lsm_hold_reversion (lsm_lcb_t *lcb) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - - // Update call state on the JAVA side - lsm_ui_call_state(evHoldRevert, line, lcb, CC_CAUSE_NORMAL); - - if (lsm_find_state(LSM_S_RINGIN) > CC_NO_CALL_ID) { - // No Reversion ringing if we have calls in ringing state - return CC_RC_SUCCESS; - } - ui_set_notification(line, call_id, - (char *)INDEX_STR_HOLD_REVERSION, CALL_ALERT_TIMEOUT, - FALSE, HR_NOTIFY_PRI); - lsm_reversion_ringer(lcb, call_id, line); - - return (CC_RC_SUCCESS); -} - -/* - * lsm_hold_local - * - * Move the phone into the Hold state. - * - * Function is used when the local side initiated the hold. - */ -static cc_rcs_t -lsm_hold_local (lsm_lcb_t *lcb, cc_state_data_hold_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - cc_causes_t cause; - int ringSettingBusyStationPolicy; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - /* - * Stop ringer if spoofing ringout for CCM - */ - if (dcb->spoof_ringout_applied) { - (void) lsm_stop_tone(lcb, NULL); - } - - /* hard close receive and transmit channels for all media entries */ - lsm_close_rx(lcb, FALSE, NULL); - lsm_close_tx(lcb, FALSE, NULL); - /* - * Note that local hold does not have any newer UI information from the - * network. Note need to update the call information and the UI will - * be collapsed with "blocked" icon to indicate hold. - */ - - lsm_change_state(lcb, __LINE__, LSM_S_HOLDING); - /* Round table phones need cause for the transfer or conference - Do not set the cause if the conference or transfer is created by - remote-cc - */ - cause = CC_CAUSE_NORMAL; - if (data->reason == CC_REASON_XFER) { - cause = CC_CAUSE_XFER_LOCAL; - } else if (data->reason == CC_REASON_CONF) { - cause = CC_CAUSE_CONF; - } - - lsm_ui_call_state(evHold, line, lcb, cause); - - ui_set_call_status(platform_get_phrase_index_str(CALL_INITIATE_HOLD), - line, lcb->ui_id); - - config_get_value(CFGID_RING_SETTING_BUSY_POLICY, - &ringSettingBusyStationPolicy, - sizeof(ringSettingBusyStationPolicy)); - if (ringSettingBusyStationPolicy) { - lsm_set_ringer(lcb, call_id, line, YES); - } else { - /* - * If the hold reason is internal this means the phone logic is placing - * a call on hold, not the user. Thus don't update the alerting for the - * hold state as the user should not hear the alerting pattern change - * as they did not place the call on hold. The phone places calls on hold - * in cases such as the phone has an active call, another call comes in - * for that line and the new call is answered. Therefore the phone places the - * active call on hold before answering the incoming call. - * - */ - if (data->reason == CC_REASON_INTERNAL) { - lsm_set_ringer(lcb, call_id, line, NO); - } else { - lsm_set_ringer(lcb, call_id, line, YES); - } - } - - vcmActivateWlan(FALSE); - - return (CC_RC_SUCCESS); -} - - -/* - * lsm_hold_remote - * - * Move the phone into the Hold state. - * - * Function is used when the remote side initiated the hold. - */ -static cc_rcs_t -lsm_hold_remote (lsm_lcb_t *lcb, cc_state_data_hold_t *data) -{ - static const char fname[] = "lsm_hold_remote"; - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - const char *prompt_status; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - /* close and re-open receive channel for all media entries */ - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not active */ - continue; - } - if (media->direction_set && - media->direction == SDP_DIRECTION_INACTIVE) { - lsm_close_rx(lcb, FALSE, media); - } else { - lsm_close_rx(lcb, TRUE, media); - } - - /* reopen the receive channel if the direction is RECVONLY */ - if (media->direction_set && - media->direction == SDP_DIRECTION_RECVONLY) { - lsm_rx_start(lcb, fname, media); - } - /* close tx if media is not inactive or receive only */ - if ((media->direction == SDP_DIRECTION_INACTIVE) || - (media->direction == SDP_DIRECTION_RECVONLY)) { - lsm_close_tx(lcb, FALSE, media); - } - } - - lsm_internal_update_call_info(lcb, dcb); - - lsm_ui_call_state(evRemHold, line, lcb, CC_CAUSE_NORMAL); - - prompt_status = ((lcb->state == LSM_S_CONNECTED) ? - platform_get_phrase_index_str(CALL_CONNECTED) : - platform_get_phrase_index_str(CALL_INITIATE_HOLD)); - ui_set_call_status(prompt_status, line, lcb->ui_id); - - lsm_set_ringer(lcb, call_id, line, YES); - - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_hold (lsm_lcb_t *lcb, cc_state_data_hold_t *data) -{ - cc_rcs_t cc_rc; - - if (data == NULL) { - return (CC_RC_ERROR); - } - - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, lcb->line, - "lsm_hold", "local", data->local); - - switch (data->local) { - case (TRUE): - cc_rc = lsm_hold_local(lcb, data); - break; - - case (FALSE): - cc_rc = lsm_hold_remote(lcb, data); - break; - - default: - cc_rc = CC_RC_ERROR; - break; - } - vcmEnableSidetone(NO); - return (cc_rc); -} - - -static cc_rcs_t -lsm_resume_local (lsm_lcb_t *lcb, cc_state_data_resume_t *data) -{ - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - - lsm_change_state(lcb, __LINE__, LSM_S_HOLDING); - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - ui_set_call_status(platform_get_phrase_index_str(CALL_CONNECTED), - line, lcb->ui_id); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_resume_remote (lsm_lcb_t *lcb, cc_state_data_resume_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - const char *prompt_status; - - if (lcb->dcb == NULL) { - return (CC_RC_ERROR); - } - - lsm_update_media(lcb, cc_state_name(CC_STATE_RESUME)); - - prompt_status = ((lcb->state == LSM_S_CONNECTED) ? - platform_get_phrase_index_str(CALL_CONNECTED) : - platform_get_phrase_index_str(CALL_INITIATE_HOLD)); - ui_set_call_status(prompt_status, line, lcb->ui_id); - - lsm_set_ringer(lcb, call_id, line, YES); - - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_resume (lsm_lcb_t *lcb, cc_state_data_resume_t *data) -{ - cc_rcs_t cc_rc; - - if (data == NULL) { - return (CC_RC_ERROR); - } - - LSM_DEBUG(get_debug_string(LSM_DBG_INT1), lcb->call_id, lcb->line, - "lsm_resume", "local", data->local); - - switch (data->local) { - case (TRUE): - cc_rc = lsm_resume_local(lcb, data); - break; - - case (FALSE): - cc_rc = lsm_resume_remote(lcb, data); - break; - - default: - cc_rc = CC_RC_ERROR; - break; - } - - vcmActivateWlan(TRUE); - - vcmEnableSidetone(YES); - return (cc_rc); -} - - -static cc_rcs_t -lsm_onhook (lsm_lcb_t *lcb, cc_state_data_onhook_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - fsmdef_dcb_t *dcb; - cc_causes_t cause; - int sdpmode = 0; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - dp_int_onhook(line, call_id); - - /* hard close receive and transmit channels for all media entries */ - lsm_close_rx(lcb, FALSE, NULL); - lsm_close_tx(lcb, FALSE, NULL); - - lsm_change_state(lcb, __LINE__, LSM_S_IDLE); - - if (lsm_is_phone_inactive()) { - vcmEnableSidetone(NO); - } - - ui_set_call_status(ui_get_idle_prompt_string(), line, lcb->ui_id); - - - (void) lsm_stop_tone(lcb, NULL); - - if (!sdpmode) { - vcmControlRinger(VCM_RING_OFF, NO, NO, line, dcb->call_id); - } - - lsm_set_ringer(lcb, call_id, line, YES); - - cause = data->cause; - if (FSM_CHK_FLAGS(dcb->flags, FSMDEF_F_XFER_COMPLETE)) { - DEF_DEBUG(DEB_F_PREFIX"Transfer complete.\n", DEB_F_PREFIX_ARGS(LSM, "lsm_onhook")); - cause = CC_CAUSE_XFER_COMPLETE; - } - lsm_ui_call_state(evOnHook, line, lcb, cause); - - - lsm_free_lcb(lcb); - - vcmActivateWlan(FALSE); - - vcmRemoveBandwidth(lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID)); - - return (CC_RC_SUCCESS); -} - -static cc_rcs_t -lsm_call_failed (lsm_lcb_t *lcb, cc_state_data_call_failed_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - vcm_tones_t tone; - lsm_states_t line_state; - const char *status = NULL; - call_events state; - boolean send_call_info = TRUE; - fsmdef_dcb_t *dcb; - boolean must_log = FALSE; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - /* For busy generated by UI-STATE in 183, do not manipulate the - * media port - */ - if (data->cause != CC_CAUSE_UI_STATE_BUSY) { - /* hard close receive and transmit channels for all media entries */ - lsm_close_rx(lcb, FALSE, NULL); - lsm_close_tx(lcb, FALSE, NULL); - } - - switch (data->cause) { - case (CC_CAUSE_BUSY): - line_state = LSM_S_BUSY; - state = evBusy; - tone = VCM_LINE_BUSY_TONE; - status = platform_get_phrase_index_str(LINE_BUSY); - dp_int_update(line, call_id, data->caller_id.called_number); - send_call_info = FALSE; - break; - - case (CC_CAUSE_UI_STATE_BUSY): - line_state = LSM_S_BUSY; - state = evBusy; - tone = VCM_LINE_BUSY_TONE; - dp_int_update(line, call_id, data->caller_id.called_number); - break; - - case (CC_CAUSE_INVALID_NUMBER): - line_state = LSM_S_INVALID_NUMBER; - state = evReorder; - tone = VCM_REORDER_TONE; - send_call_info = FALSE; - break; - - case (CC_CAUSE_CONGESTION): - case (CC_CAUSE_PAYLOAD_MISMATCH): - dp_int_update(line, call_id, data->caller_id.called_number); - - /* FALLTHROUGH */ - /*sa_ignore FALL_THROUGH*/ - default: - send_call_info = FALSE; - line_state = LSM_S_CONGESTION; - state = evReorder; - tone = VCM_REORDER_TONE; - if ( (data->cause == CC_CAUSE_NO_USER_ANS)|| - (data->cause == CC_TEMP_NOT_AVAILABLE) ) { - must_log = TRUE; - } - break; - } - - lsm_change_state(lcb, __LINE__, line_state); - - if (status) { - ui_set_call_status(status, line, lcb->ui_id); - } - - if (state == evReorder && !must_log) { - ui_log_disposition(dcb->call_id, CC_CALL_LOG_DISP_IGNORE); - } - - /* Send call info only if not error */ - if (send_call_info == TRUE) { - ui_call_info(data->caller_id.calling_name, - data->caller_id.calling_number, - data->caller_id.alt_calling_number, - data->caller_id.display_calling_number, - data->caller_id.called_name, - data->caller_id.called_number, - data->caller_id.display_called_number, - data->caller_id.orig_called_name, - data->caller_id.orig_called_number, - data->caller_id.last_redirect_name, - data->caller_id.last_redirect_number, - (calltype_t)dcb->call_type, - line, lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - } - - lsm_ui_call_state(state, line, lcb, CC_CAUSE_NORMAL); - - /* Tone played in remote-cc play tone request, so don't start tone again - */ - if ((data->cause != CC_CAUSE_UI_STATE_BUSY) && (data->cause != CC_CAUSE_REMOTE_DISCONN_REQ_PLAYTONE)) { - fsmdef_media_t *audio_media = gsmsdp_find_audio_media(dcb); - - lsm_util_start_tone(tone, FALSE, lsm_get_ms_ui_call_handle(line, call_id, CC_NO_CALL_ID), dcb->group_id, - ((audio_media != NULL) ? audio_media->refid : - CC_NO_MEDIA_REF_ID), - VCM_PLAY_TONE_TO_EAR); - } - - return (CC_RC_SUCCESS); -} - -static void -lsm_ringer (lsm_lcb_t *lcb, cc_action_data_ringer_t *data) -{ - vcm_ring_mode_t ringer; - line_t line = lcb->line; - - ringer = (data->on == FALSE) ? (VCM_RING_OFF) : (VCM_FEATURE_RING); - - LSM_DEBUG(DEB_F_PREFIX"CTI RING SETTING: line = %d, ringer Mode = %s," - "Ring once = NO, alertInfo = NO\n", DEB_F_PREFIX_ARGS(LSM, "lsm_ringer"), - line, vm_alert_names[ringer]); - - vcmControlRinger(ringer, NO, NO, line, lcb->call_id); -} - -static cc_rcs_t -lsm_dial_mode (lsm_lcb_t *lcb, cc_action_data_dial_mode_t *data) -{ - return (CC_RC_SUCCESS); -} - - -static cc_rcs_t -lsm_mwi (lsm_lcb_t *lcb, callid_t call_id, line_t line, - cc_action_data_mwi_t *data) -{ - ui_set_mwi(line, data->on, data->type, data->newCount, data->oldCount, data->hpNewCount, data->hpOldCount); - - return (CC_RC_SUCCESS); -} - - -/* - * Function: lsm_update_ui - * - * Parameters: - * call_id: - * line: - * data: - * - * Description: This function is used to hide the UI platform details from - * the FSMs. This function is provided to allow the FSMs - * to update the UI in certain cases. - * - * Returns: rc - * - */ -cc_rcs_t -lsm_update_ui (lsm_lcb_t *lcb, cc_action_data_update_ui_t *data) -{ - callid_t call_id = lcb->call_id; - line_t line = lcb->line; - lsm_states_t instance_state; - call_events call_state = evMaxEvent; - fsmcnf_ccb_t *ccb; - fsmdef_dcb_t *dcb; - boolean update = FALSE; - boolean inbound; - cc_feature_data_call_info_t *call_info; - call_events original_call_event; - lsm_lcb_t *lcb_tmp; - const char *conf_str;//[] = {(char)0x80, (char)0x34, (char)0x00}; - - instance_state = lcb->state; - - switch (data->action) { - case CC_UPDATE_CONF_ACTIVE: - - switch (instance_state) { - case LSM_S_RINGOUT: - call_state = evRingOut; - break; - - case LSM_S_CONNECTED: - default: - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if ((ccb != NULL) && (ccb->active == TRUE)) { - - conf_str = platform_get_phrase_index_str(UI_CONFERENCE); - lcb_tmp = lsm_get_lcb_by_call_id(ccb->cnf_call_id); - dcb = lcb_tmp->dcb; - ui_call_info(CALL_INFO_NONE, - CALL_INFO_NONE, - CALL_INFO_NONE, - 0, - conf_str, - CALL_INFO_NONE, - 0, - CALL_INFO_NONE, - CALL_INFO_NONE, - CALL_INFO_NONE, - CALL_INFO_NONE, - FSMDEF_CALL_TYPE_OUTGOING, - dcb->line, lcb_tmp->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - - call_state = evConference; - - } else if (instance_state == LSM_S_CONNECTED) { - - call_state = evConnected; - - } else { - - call_state = evRingOut; - } - break; - } /* switch (instance_state) { */ - - break; - - case CC_UPDATE_CALLER_INFO: - - /* For local conference, do not update the primary - * call bubbles call-info. Primary call is already - * displaying To conference in this case - * But dcb-> caller_id should be updated to - * refresh the UI when the call is dropped - */ - ccb = fsmcnf_get_ccb_by_call_id(call_id); - if (ccb && (ccb->flags & LCL_CNF) && - (ccb->cnf_call_id == call_id)) { - break; - } - - call_info = &data->data.caller_info; - dcb = lcb->dcb; - if (dcb == NULL || call_info == NULL) { - return (CC_RC_ERROR); - } - - inbound = dcb->inbound; - if (call_info->feature_flag & CC_ORIENTATION) { - inbound = - (call_info->orientation == CC_ORIENTATION_FROM) ? TRUE : FALSE; - update = TRUE; - } - - if (call_info->feature_flag & CC_CALLER_ID) { - update = TRUE; - /* - * This "if" block, without the "&& inbound" condition, was put in by Serhad - * to fix CSCsm58054 and it results in CSCso98110. The "inbound" condition - * is added to narrow the scope of CSCsm58054's fix. Note that "inbound" here - * refers to the perceived orientation set in call info. So for example, in case - * of a 3-way conf, and phone is the last party to receive the call, is ringing - * and then be joined into a conference, direction would be outbound. The display - * would say "To Conference". - */ - if ( (instance_state == LSM_S_RINGIN) && inbound ) { - cc_state_data_alerting_t alerting_data; - - alerting_data.caller_id = dcb->caller_id; - lsm_update_inalert_status(line, lcb->ui_id, &alerting_data, TRUE); - } - } - - if (call_info->feature_flag & CC_CALL_INSTANCE) { - update = TRUE; - } - - if (call_info->feature_flag & CC_SECURITY) { - update = TRUE; - } - - if (call_info->feature_flag & CC_POLICY) { - update = TRUE; - } - - /* - * If we are going to spoof ring out, skip the explicit UI update. - * the far end alerting handling will update the UI. Do not - * update UI twice. - */ - if (dcb->spoof_ringout_requested && - !dcb->spoof_ringout_applied && - lcb->state == LSM_S_CONNECTED) { - cc_state_data_far_end_alerting_t alerting_data; - - alerting_data.caller_id = dcb->caller_id; - (void) lsm_far_end_alerting(lcb, &alerting_data); - dcb->spoof_ringout_applied = TRUE; - } else if (update && dcb->ui_update_required) { - - calltype_t call_type; - - if (dcb->call_type == FSMDEF_CALL_TYPE_FORWARD) { - call_type = (inbound) ? (calltype_t)dcb->call_type:FSMDEF_CALL_TYPE_OUTGOING; - } else { - if (inbound) { - call_type = FSMDEF_CALL_TYPE_INCOMING; - } else { - call_type = FSMDEF_CALL_TYPE_OUTGOING; - } - } - - ui_call_info(dcb->caller_id.calling_name, - dcb->caller_id.calling_number, - dcb->caller_id.alt_calling_number, - dcb->caller_id.display_calling_number, - dcb->caller_id.called_name, - dcb->caller_id.called_number, - dcb->caller_id.display_called_number, - dcb->caller_id.orig_called_name, - dcb->caller_id.orig_called_number, - dcb->caller_id.last_redirect_name, - dcb->caller_id.last_redirect_number, - call_type, - line, - lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - - dcb->ui_update_required = FALSE; - - conf_str = platform_get_phrase_index_str(UI_CONFERENCE); - if(cpr_strncasecmp(dcb->caller_id.called_name, conf_str, strlen(conf_str)) == 0){ - dcb->is_conf_call = TRUE; - } else { - dcb->is_conf_call = FALSE; - } - } - - break; - - case CC_UPDATE_SET_CALL_STATUS: - { - /* set call status line */ - cc_set_call_status_data_t *call_status_p = - &data->data.set_call_status_parms; - ui_set_call_status(call_status_p->phrase_str_p, call_status_p->line, - lcb->ui_id); - break; - } - case CC_UPDATE_SET_NOTIFICATION: - { - /* set status line notification */ - cc_set_notification_data_t *call_notification_p = - &data->data.set_notification_parms; - ui_set_notification(line, lcb->ui_id, - call_notification_p->phrase_str_p, - call_notification_p->timeout, FALSE, - (char)call_notification_p->priority); - break; - } - case CC_UPDATE_CLEAR_NOTIFICATION: - /* clear status line notification */ - ui_clear_notification(); - break; - - case CC_UPDATE_SECURITY_STATUS: - /* update security status */ - break; - - case CC_UPDATE_XFER_PRIMARY: - call_state = evConnected; - break; - - case CC_UPDATE_CALL_PRESERVATION: - - /* Call is in preservation mode. Update UI so that only endcall softkey is available */ - ui_call_in_preservation(line, lcb->ui_id); - break; - - case CC_UPDATE_CALL_CONNECTED: - if (instance_state == LSM_S_CONNECTED) { - call_state = evConnected; - } - break; - - case CC_UPDATE_CONF_RELEASE: - dcb = lcb->dcb; - - if (instance_state == LSM_S_CONNECTED) { - call_state = evConnected; - - } else if (instance_state == LSM_S_RINGOUT) { - call_state = evRingOut; - } - - /* - * If we are going to spoof ring out, skip the explicit UI update. - * the far end alerting handling will update the UI. Do not - * update UI twice. - */ - if (dcb->spoof_ringout_requested && - !dcb->spoof_ringout_applied && - lcb->state == LSM_S_CONNECTED) { - cc_state_data_far_end_alerting_t alerting_data; - - alerting_data.caller_id = dcb->caller_id; - (void) lsm_far_end_alerting(lcb, &alerting_data); - dcb->spoof_ringout_applied = TRUE; - - call_state = evRingOut; - - } else { - calltype_t call_type; - if (dcb->orientation == CC_ORIENTATION_FROM) { - call_type = FSMDEF_CALL_TYPE_INCOMING; - } else if (dcb->orientation == CC_ORIENTATION_TO) { - call_type = FSMDEF_CALL_TYPE_OUTGOING; - } else { - call_type = (calltype_t)(dcb->call_type); - } - ui_call_info(dcb->caller_id.calling_name, - dcb->caller_id.calling_number, - dcb->caller_id.alt_calling_number, - dcb->caller_id.display_calling_number, - dcb->caller_id.called_name, - dcb->caller_id.called_number, - dcb->caller_id.display_called_number, - dcb->caller_id.orig_called_name, - dcb->caller_id.orig_called_number, - dcb->caller_id.last_redirect_name, - dcb->caller_id.last_redirect_number, - call_type, - line, - lcb->ui_id, - dcb->caller_id.call_instance_id, - FSM_GET_SECURITY_STATUS(dcb), - FSM_GET_POLICY(dcb)); - } - - - break; - - default: - break; - } - - if (call_state != evMaxEvent) { - original_call_event = lcb->previous_call_event; - - lsm_ui_call_state(call_state, line, lcb, CC_CAUSE_NORMAL); - if (original_call_event != call_state) { - /* Call state changed, take care of special event */ - switch (call_state) { - case evConference: - break; - - case evConnected: - case evWhisper: - ui_set_call_status( - platform_get_phrase_index_str(CALL_CONNECTED), - line, lcb->ui_id); - break; - - default: - break; - } - } - } - - return (CC_RC_SUCCESS); -} - - -/* - * Function: lsm_update_placed_callinfo - * - * Description: this helps log dialed digits (as opposed to RPID provided - * value) into placed calls. This also decides whether to - * log called party name received in RPID. - * - * Parameters: dcb - pointer to default SM control block - * - * Returns: none - * - */ -#define CISCO_PLAR_STRING "x-cisco-serviceuri-offhook" -void -lsm_update_placed_callinfo (void *data) -{ - const char *tmp_called_number = NULL; - const char *called_name = NULL; - fsmdef_dcb_t *dcb = NULL; - lsm_lcb_t *lcb; - static const char fname[] = "lsm_update_placed_callinfo"; - boolean has_called_number = FALSE; - - LSM_DEBUG(DEB_F_PREFIX"Entering ...\n", DEB_F_PREFIX_ARGS(LSM, fname)); - dcb = (fsmdef_dcb_t *) data; - lcb = lsm_get_lcb_by_call_id(dcb->call_id); - if (lcb == NULL) { - LSM_DEBUG(DEB_F_PREFIX"Exiting: lcb not found\n", DEB_F_PREFIX_ARGS(LSM, fname)); - return; - } - - if (dcb->caller_id.called_number != NULL && - dcb->caller_id.called_number[0] != NUL) { - has_called_number = TRUE; - } - - - tmp_called_number = lsm_get_gdialed_digits(); - - - /* if tmp_called_number is NULL or empty, return */ - if (tmp_called_number == NULL || (*tmp_called_number) == NUL) { - LSM_DEBUG(DEB_L_C_F_PREFIX"Exiting : dialed digits is empty\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, fname)); - return; - } - - /* - * if tmp_called_number is same as what we receive in RPID, - * then get the called name from RPID if provided. - */ - if (has_called_number) { - if (strcmp(tmp_called_number, CISCO_PLAR_STRING) == 0) { - tmp_called_number = dcb->caller_id.called_number; - } - /* if RPID number matches, dialed digits, use RPID name */ - if (strcmp(dcb->caller_id.called_number, tmp_called_number) == 0) { - called_name = dcb->caller_id.called_name; - } else { - char tmp_str[STATUS_LINE_MAX_LEN]; - platGetPhraseText(STR_INDEX_ANONYMOUS_SPACE, (char *)tmp_str, STATUS_LINE_MAX_LEN - 1); - if(strcmp(dcb->caller_id.called_number,tmp_str) == 0 - && strcmp(dcb->caller_id.orig_rpid_number, tmp_called_number) == 0 - && strcmp(dcb->caller_id.called_name, platform_get_phrase_index_str(UI_UNKNOWN)) != 0) { - called_name = dcb->caller_id.called_name; - } - } - } - ui_update_placed_call_info(lcb->line, lcb->call_id, called_name, - tmp_called_number); - LSM_DEBUG(DEB_L_C_F_PREFIX"Exiting: invoked ui_update_placed_call_info()\n", - DEB_L_C_F_PREFIX_ARGS(LSM, lcb->line, lcb->call_id, fname)); -} - -cc_int32_t -lsm_show_cmd (cc_int32_t argc, const char *arv[]) -{ - int i = 0; - lsm_lcb_t *lcb; - - PR_ASSERT( i == 0 ); - debugif_printf("\n------------------ LSM lcbs -------------------"); - debugif_printf("\ni call_id line state lcb"); - debugif_printf("\n-----------------------------------------------\n"); - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - debugif_printf("%-2d %-7d %-4d %-16s 0x%8p\n", - i++, lcb->call_id, lcb->line, - lsm_state_name(lcb->state), lcb); - - } - - return (0); -} - -void -lsm_init_config (void) -{ - /* - * The silent period between call waiting bursts is now configurable - * for TNP phones. Store away the value for the callwaiting code to use. - * The config is in seconds, but CPR expects the duration in milliseconds - * thus multiply the config value by 1000. Non-TNP phones default to - * 10 seconds. - */ - config_get_value(CFGID_CALL_WAITING_SILENT_PERIOD, &callWaitingDelay, - sizeof(callWaitingDelay)); - callWaitingDelay = callWaitingDelay * 1000; -} - -void -lsm_init (void) -{ - static const char fname[] = "lsm_init"; - lsm_lcb_t *lcb; - int i; - - /* - * Init the lcbs. - */ - lsm_lcbs = (lsm_lcb_t *) cpr_calloc(LSM_MAX_LCBS, sizeof(lsm_lcb_t)); - if (lsm_lcbs == NULL) { - LSM_ERR_MSG(LSM_F_PREFIX"lsm_lcbs cpr_calloc returned NULL\n", fname); - return; - } - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - lsm_init_lcb(lcb); - } - - /* - * Create tones and continous tone timer. The same call back function - * is utilized for each of these timers. - */ - lsm_tmr_tones = cprCreateTimer("lsm_tmr_tones", - GSM_MULTIPART_TONES_TIMER, - TIMER_EXPIRATION, gsm_msg_queue); - lsm_continuous_tmr_tones = cprCreateTimer("lsm_continuous_tmr_tones", - GSM_CONTINUOUS_TONES_TIMER, - TIMER_EXPIRATION, - gsm_msg_queue); - lsm_tone_duration_tmr = cprCreateTimer("lsm_tone_duration_tmr", - GSM_TONE_DURATION_TIMER, - TIMER_EXPIRATION, gsm_msg_queue); - lsm_init_config(); - - for (i=0 ; ioffhook)); -#ifdef TEST - test_dial_calls(line, call_id, 500, "10011234"); -#endif - break; - - case CC_STATE_DIALING: - result = lsm_dialing(lcb, &(data->dialing)); - break; - - case CC_STATE_DIALING_COMPLETED: - result = lsm_dialing_completed(lcb, &(data->dialing_completed)); - break; - - case CC_STATE_CALL_SENT: - result = lsm_call_sent(lcb, &(data->call_sent)); - break; - - case CC_STATE_FAR_END_PROCEEDING: - result = lsm_far_end_proceeding(lcb, &(data->far_end_proceeding)); - break; - - case CC_STATE_FAR_END_ALERTING: - result = lsm_far_end_alerting(lcb, &(data->far_end_alerting)); - break; - - case CC_STATE_CALL_RECEIVED: - result = lsm_call_received(lcb, &(data->call_received)); - break; - - case CC_STATE_ALERTING: - result = lsm_alerting(lcb, &(data->alerting)); - break; - - case CC_STATE_ANSWERED: - result = lsm_answered(lcb, &(data->answered)); - break; - - case CC_STATE_CONNECTED: - result = lsm_connected(lcb, &(data->connected)); -#ifdef TEST - test_disc_call(line, call_id); - test_line_offhook(line, cc_get_new_call_id()); -#endif - break; - - case CC_STATE_HOLD: - result = lsm_hold(lcb, &(data->hold)); - break; - - case CC_STATE_HOLD_REVERT: - result = lsm_hold_reversion(lcb); - break; - - case CC_STATE_RESUME: - result = lsm_resume(lcb, &(data->resume)); - break; - - case CC_STATE_ONHOOK: - result = lsm_onhook(lcb, &(data->onhook)); - break; - - case CC_STATE_CALL_FAILED: - result = lsm_call_failed(lcb, &(data->call_failed)); - break; - - default: - break; - } - - if (result == CC_RC_ERROR) { - LSM_DEBUG(get_debug_string(LSM_DBG_CC_ERROR), call_id, line, fname, - state, data); - } - - return; -} - -static cc_rcs_t -lsm_media (lsm_lcb_t *lcb, callid_t call_id, line_t line) -{ - fsmdef_dcb_t *dcb; - - dcb = lcb->dcb; - if (dcb == NULL) { - return (CC_RC_ERROR); - } - - if (!dcb->spoof_ringout_requested) { - lsm_update_media(lcb, "MEDIA"); - vcmEnableSidetone(YES); - } else if (!dcb->spoof_ringout_applied && - (lcb->state == LSM_S_CONNECTED)) { - cc_state_data_far_end_alerting_t alerting_data; - - alerting_data.caller_id = dcb->caller_id; - (void) lsm_far_end_alerting(lcb, &alerting_data); - dcb->spoof_ringout_applied = TRUE; - } - - return (CC_RC_SUCCESS); -} - -/* - * Function: lsm_stop_media - * - * Parameters: - * lcb - pointer to lsm_lcb_t, - * call_id - gsm call id for the call in used. - * line - line_t for the line number (dn line). - * data - action data. - * - * Description: - * The function simply stops media (close Rx and Tx) and set the - * proper ringer. - * - * Returns: None. - */ -static void -lsm_stop_media (lsm_lcb_t *lcb, callid_t call_id, line_t line, - cc_action_data_t *data) -{ - static const char fname[] = "lsm_stop_media"; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_DEBUG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - /* hard close receive and transmit channels */ - if ((data == NULL) || - (data->stop_media.media_refid == CC_NO_MEDIA_REF_ID)) { - /* no data provided or no specific ref ID, defaul to all entries */ - lsm_close_rx(lcb, FALSE, NULL); - lsm_close_tx(lcb, FALSE, NULL); - } else { - /* look up the media entry for the given reference ID */ - media = gsmsdp_find_media_by_refid(dcb, - data->stop_media.media_refid); - if (media != NULL) { - lsm_close_rx(lcb, FALSE, media); - lsm_close_tx(lcb, FALSE, media); - } else { - /* no entry found */ - LSM_DEBUG(DEB_L_C_F_PREFIX"no media with reference ID %d found\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, dcb->call_id, fname), - data->stop_media.media_refid); - return; - } - } - lsm_set_ringer(lcb, call_id, line, YES); -} - - - -/* - * lsm_add_remote_stream - * - * Description: - * The function adds a remote stream to the media subsystem - * - * Parameters: - * [in] line - line - * [in] call_id - GSM call ID - * [in] media - media line to add as remote stream - * [out] pc_stream_id - * Returns: None - */ -void lsm_add_remote_stream (line_t line, callid_t call_id, fsmdef_media_t *media, int *pc_stream_id) -{ - static const char fname[] = "lsm_add_remote_stream"; - fsmdef_dcb_t *dcb; - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - vcmCreateRemoteStream(media->cap_index, dcb->peerconnection, - pc_stream_id); - - } -} - -/* - * lsm_data_channel_negotiated - * - * Description: - * The function informs the API of a negotiated data channel m= line - * - * Parameters: - * [in] line - line - * [in] call_id - GSM call ID - * [in] media - media line to add as remote stream - * [out] pc_stream_id - * Returns: None - */ -void lsm_data_channel_negotiated (line_t line, callid_t call_id, fsmdef_media_t *media, int *pc_stream_id) -{ - static const char fname[] = "lsm_data_channel_negotiated"; - fsmdef_dcb_t *dcb; - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb) { - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - /* - * have access to media->streams, media->protocol, media->sctp_port - * vcmSetDataChannelParameters may need renaming TODO: jesup - */ - - vcmSetDataChannelParameters(dcb->peerconnection, media->streams, media->sctp_port, media->protocol); - - } -} - -/** - * - * Peform non call related action - * - * @param line_t line - * @param callid_t gsm_id - * @param action type of action - * @param cc_action_data_t line - * - * @return true if the action has been peformed, else false - * - * @pre (action == CC_ACTION_MWI_LAMP_ONLY || CC_ACTION_SET_LINE_RINGER || - CC_ACTION_PLAY_BLF_ALERTING_TONE) - */ -static boolean -cc_call_non_call_action (callid_t call_id, line_t line, - cc_actions_t action, cc_action_data_t *data) -{ - /* Certain requests are device based and does not contain any - * line number and call_id associated with it. So handle thoese - * requests here - */ - switch (action) { - - case CC_ACTION_MWI_LAMP_ONLY: - if (data != NULL) { - ui_change_mwi_lamp(data->mwi.on); - return(TRUE); - } - break; - - case CC_ACTION_SET_LINE_RINGER: - - if (data != NULL) { - return(TRUE); - } - break; - - case CC_ACTION_PLAY_BLF_ALERTING_TONE: - lsm_play_tone(CC_FEATURE_BLF_ALERT_TONE); - return TRUE; - - default: - break; - } - - return(FALSE); -} - -/* - * LSM API supports various actions such as play tone, stop tone, - * direct media operation etc. - * - * @param[in] call_id GSM call ID of an active call. - * @param[in] line line number of the line_t type. - * @param[in] action cc_actions_t for the desired action. - * @param[in] data cc_action_data_t data or parameters that may be - * required for certain action. - * - * @return cc_rcs_t status. - * - * @pre line not_eqs CC_NO_LINE - * @pre ((action equals CC_ACTION_PLAY_TONE) or - * (action equals CC_ACTION_STOP_TONE) or - * (action equals CC_ACTION_DIAL_MODE) or - * (action equals CC_ACTION_MWI) or - * (action equals CC_ACTION_OPEN_RCV) or - * (action equals CC_ACTION_UPDATE_UI) or - * (action equals CC_ACTION_RINGER)) - */ -cc_rcs_t -cc_call_action (callid_t call_id, line_t line, cc_actions_t action, - cc_action_data_t *data) -{ - static const char fname[] = "cc_call_action"; - cc_rcs_t result = CC_RC_SUCCESS; - lsm_lcb_t *lcb; - fsmdef_dcb_t *dcb; - fsmdef_media_t *media; - - LSM_DEBUG(get_debug_string(LSM_DBG_ENTRY), call_id, line, - cc_action_name(action)); - - /* perform non call related actions. lcb is not required - * for these actions - */ - if (cc_call_non_call_action(call_id, line, action, data)) { - return (result); - } - - lcb = lsm_get_lcb_by_call_id(call_id); - - if ((lcb == NULL) && (action != CC_ACTION_MWI)) { - LSM_DEBUG(get_debug_string(DEBUG_INPUT_NULL), fname); - return (CC_RC_ERROR); - } - - switch (action) { - case CC_ACTION_PLAY_TONE: - if (data != NULL) { - result = lsm_start_tone(lcb, &(data->tone)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_STOP_TONE: - if (data != NULL) { - result = lsm_stop_tone(lcb, &(data->tone)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_SPEAKER: - break; - - case CC_ACTION_DIAL_MODE: - if (data != NULL) { - result = lsm_dial_mode(lcb, &(data->dial_mode)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_MWI: - if (data != NULL) { - result = lsm_mwi(NULL, call_id, line, &(data->mwi)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_OPEN_RCV: - if (data != NULL) { - result = lsm_open_rx(lcb, &(data->open_rcv), NULL); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_UPDATE_UI: - if (data != NULL) { - result = lsm_update_ui(lcb, &(data->update_ui)); - } else { - result = CC_RC_ERROR; - } - break; - - case CC_ACTION_MEDIA: - result = lsm_media(lcb, call_id, line); - break; - - case CC_ACTION_RINGER: - if (data != NULL) { - lsm_ringer(lcb, &(data->ringer)); - } - break; - - case CC_ACTION_STOP_MEDIA: - lsm_stop_media(lcb, call_id, line, data); - break; - - case CC_ACTION_START_RCV: - /* start receiving */ - dcb = lcb->dcb; - if (dcb == NULL) { - /* No call ID */ - result = CC_RC_ERROR; - break; - } - - GSMSDP_FOR_ALL_MEDIA(media, dcb) { - if (!GSMSDP_MEDIA_ENABLED(media)) { - /* this entry is not active */ - continue; - } - - /* only support starting all receive channels for now */ - lsm_rx_start(lcb, fname, media); - } - break; - - case CC_ACTION_ANSWER_PENDING: - FSM_SET_FLAGS(lcb->flags, LSM_FLAGS_ANSWER_PENDING); - break; - - default: - break; - } - - - if (result == CC_RC_ERROR) { - LSM_DEBUG(get_debug_string(LSM_DBG_CC_ERROR), call_id, line, fname, - action, data); - } - - return (result); -} - - -void -lsm_ui_display_notify (const char *notify_str, unsigned long timeout) -{ - /* - * add 0 as (default) priority; it is don't care in legacy mode - */ - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, - (char *)notify_str, (int)timeout, FALSE, - DEF_NOTIFY_PRI); -} - -void -lsm_ui_display_status (const char *status_str, line_t line, callid_t call_id) -{ - lsm_lcb_t *lcb; - - if (call_id == CC_NO_CALL_ID) { - /* Invalid call id */ - return; - } - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return; - } - - ui_set_call_status((char *) status_str, line, lcb->ui_id); -} - -/** - * This function will display notification status line. - * - * @param[in] str_index - index into phrase dictionary - * - * @return none - */ -void lsm_ui_display_notify_str_index (int str_index) -{ - char tmp_str[STATUS_LINE_MAX_LEN]; - - if ((platGetPhraseText(str_index, - (char *)tmp_str, - (STATUS_LINE_MAX_LEN - 1))) == CPR_SUCCESS) { - lsm_ui_display_notify(tmp_str, NO_FREE_LINES_TIMEOUT); - } -} - -/* - * Function: lsm_parse_displaystr - * - * Parameters:string to be parsed - * - * Description:Wrapper function for parsing string to be displayed - * - * Returns: Pointer to parsed number - * - */ -string_t -lsm_parse_displaystr (string_t displaystr) -{ - return (sippmh_parse_displaystr(displaystr)); -} - -void -lsm_speaker_mode (short mode) -{ - ui_set_speaker_mode((boolean)mode); -} - -/* - * Function:lsm_update_active_tone - * - * Parameters: - * tone - tone type - * call_id - call identifier - * - * Description: Update dcb->active_tone if starting infinite duration tone. - * - * Returns:none - * - */ -void -lsm_update_active_tone (vcm_tones_t tone, callid_t call_id) -{ - static const char fname[] = "lsm_update_active_tone"; - fsmdef_dcb_t *dcb; - - /* if tone is any of following then set active_tone in dcb b/c these - * tones have infinite duration and need to be stopped. Other tones - * only play for a finite/short duration so no need to stop them as - * they will stop automatically. - */ - switch (tone) { - /* for all tones with infinite playing duration */ - case VCM_INSIDE_DIAL_TONE: - case VCM_LINE_BUSY_TONE: - case VCM_ALERTING_TONE: - case VCM_STUTTER_TONE: - case VCM_REORDER_TONE: - case VCM_OUTSIDE_DIAL_TONE: - case VCM_PERMANENT_SIGNAL_TONE: - case VCM_RECORDERWARNING_TONE: - case VCM_MONITORWARNING_TONE: - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb == NULL) { - /* Possibibly the ui_id was passed in and the dcb is no longer existed. - * Try to retrieve the corresponding dcb. - */ - dcb = fsmdef_get_dcb_by_call_id(lsm_get_callid_from_ui_id(call_id)); - } - - if (dcb != NULL) { - /* Ideally a call should not make a infinite tone start request - * (without making a stop request) while there is already one playing. - * However, DSP will start playing the new request tone by overriding - * the current one. Technically its okay. So, just printing a log msg. - */ - if (dcb->active_tone != VCM_NO_TONE) { - LSM_DEBUG(DEB_L_C_F_PREFIX"Active Tone current = %d new = %d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, call_id, fname), - dcb->active_tone, tone); - } - dcb->active_tone = tone; - } - break; - - default: - /* do nothing */ - break; - } -} - -/* - * Function: lsm_is_tx_channel_opened - * - * Parameters: call_id - * - * Description: check to see tx channel is openned - * - * Returns: TRUE or FALSE - * - */ -boolean -lsm_is_tx_channel_opened(callid_t call_id) -{ - fsmdef_dcb_t *dcb_p = fsmdef_get_dcb_by_call_id(call_id); - fsmdef_media_t *media = NULL; - - if (dcb_p == NULL) { - return (FALSE); - } - - /* - * search the all entries that has a valid media and matches - * SDP_MEDIA_AUDIO type. - */ - GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { - if (media->type == SDP_MEDIA_AUDIO) { - /* found a match */ - if (media->xmit_chan) - return (TRUE); - } - } - return (FALSE); -} - -/* - * Function:lsm_update_monrec_tone_action - * - * Parameters: - * tone - tone type - * call_id - call identifier - * - * Description: Update dcb->monrec_tone_action. - * - * Returns:none - * - */ -void -lsm_update_monrec_tone_action (vcm_tones_t tone, callid_t call_id, uint16_t direction) -{ - static const char fname[] = "lsm_update_monrec_tone_action"; - fsmdef_dcb_t *dcb; - boolean tx_opened = lsm_is_tx_channel_opened(call_id); - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - if (dcb != NULL) { - switch(tone) { - case VCM_MONITORWARNING_TONE: - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_NO_ACTION: - if (!tx_opened) { - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_MONITOR_TONE; - } else { - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_MONITOR_TONE; - } - break; - - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_BOTH_TONES; - break; - - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_BOTH_TONES; - break; - - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - default: - DEF_DEBUG(DEB_F_PREFIX"Invalid action request... tone:%d monrec_tone_action:%d \n", - DEB_F_PREFIX_ARGS("RCC", fname), tone, dcb->monrec_tone_action); - break; - } - dcb->monitor_tone_direction = direction; - break; - - case VCM_RECORDERWARNING_TONE: - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_NO_ACTION: - if (!tx_opened) { - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_RECORDER_TONE; - } else { - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_RECORDER_TONE; - } - break; - - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_BOTH_TONES; - break; - - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_BOTH_TONES; - break; - - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - default: - DEF_DEBUG(DEB_F_PREFIX"Invalid action request... tone:%d monrec_tone_action:%d \n", - DEB_F_PREFIX_ARGS("RCC", fname), tone, dcb->monrec_tone_action); - break; - } - dcb->recorder_tone_direction = direction; - break; - - default: - break; - } /* end of switch */ - - LSM_DEBUG(DEB_L_C_F_PREFIX"Start request for tone: %d. Set monrec_tone_action: %d\n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, call_id, fname), - tone, dcb->monrec_tone_action); - - } /* end of if */ -} - -/* - * Function:lsm_downgrade_monrec_tone_action - * - * Parameters: - * tone - tone type - * call_id - call identifier - * - * Description: Update dcb->monrec_tone_action. - * - * Returns:none - * - */ -void -lsm_downgrade_monrec_tone_action (vcm_tones_t tone, callid_t call_id) -{ - static const char fname[] = "lsm_downgrade_monrec_tone_action"; - fsmdef_dcb_t *dcb; - - dcb = fsmdef_get_dcb_by_call_id(call_id); - - /* Need to downgrade the monrec_tone_action */ - - if (dcb != NULL) { - switch (tone){ - case VCM_MONITORWARNING_TONE: - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_NO_ACTION; - break; - - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_RECORDER_TONE; - break; - - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_RECORDER_TONE; - break; - - case FSMDEF_MRTONE_NO_ACTION: - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - default: - DEF_DEBUG(DEB_F_PREFIX"Invalid action request... tone:%d monrec_tone_action:%d \n", - DEB_F_PREFIX_ARGS("RCC", fname), tone, dcb->monrec_tone_action); - break; - } - dcb->monitor_tone_direction = VCM_PLAY_TONE_TO_EAR; - break; - - case VCM_RECORDERWARNING_TONE: - switch (dcb->monrec_tone_action) { - case FSMDEF_MRTONE_PLAYED_RECORDER_TONE: - case FSMDEF_MRTONE_RESUME_RECORDER_TONE: - dcb->monrec_tone_action = FSMDEF_MRTONE_NO_ACTION; - break; - - case FSMDEF_MRTONE_RESUME_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_RESUME_MONITOR_TONE; - break; - - case FSMDEF_MRTONE_PLAYED_BOTH_TONES: - dcb->monrec_tone_action = FSMDEF_MRTONE_PLAYED_MONITOR_TONE; - break; - - case FSMDEF_MRTONE_NO_ACTION: - case FSMDEF_MRTONE_PLAYED_MONITOR_TONE: - case FSMDEF_MRTONE_RESUME_MONITOR_TONE: - default: - DEF_DEBUG(DEB_F_PREFIX"Invalid action request... tone:%d monrec_tone_action:%d \n", - DEB_F_PREFIX_ARGS("RCC", fname), tone, dcb->monrec_tone_action); - break; - } - dcb->recorder_tone_direction = VCM_PLAY_TONE_TO_EAR; - break; - - default: - break; - } /* end of switch */ - - LSM_DEBUG(DEB_L_C_F_PREFIX"Stop request for tone: %d Downgrade monrec_tone_action: %d \n", - DEB_L_C_F_PREFIX_ARGS(LSM, dcb->line, call_id, fname), - tone, dcb->monrec_tone_action); - } /* end of if */ -} - -/* - * Function: lsm_set_hold_ringback_status - * - * Parameters: - * callid_t - callid of the lcb - * ringback_status - status of call hold ringback - * - * Description: Function used to set the ringback status - * - * Returns:None - * - */ -void -lsm_set_hold_ringback_status(callid_t call_id, boolean ringback_status) -{ - lsm_lcb_t *lcb; - - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->call_id == call_id) { - LSM_DEBUG(DEB_F_PREFIX"Setting ringback to %d for lcb %d\n", - DEB_F_PREFIX_ARGS(LSM, "lsm_set_hold_ringback_status"), ringback_status, call_id); - lcb->enable_ringback = ringback_status; - break; - } - } -} - -void lsm_play_tone (cc_features_t feature_id) -{ - int play_tone; - - switch (feature_id) { - case CC_FEATURE_BLF_ALERT_TONE: - if (lsm_find_state(LSM_S_RINGIN) > CC_NO_CALL_ID) { - // No tone if we have calls in ringing state - return; - } - - if (!lsm_callwaiting()) { - config_get_value(CFGID_BLF_ALERT_TONE_IDLE, &play_tone, sizeof(play_tone)); - if (play_tone == 0) { - return; - } - lsm_util_tone_start_with_speaker_as_backup(VCM_CALL_WAITING_TONE, VCM_ALERT_INFO_OFF, - CC_NO_CALL_ID, CC_NO_GROUP_ID, - CC_NO_MEDIA_REF_ID, VCM_PLAY_TONE_TO_EAR); - } else { - config_get_value(CFGID_BLF_ALERT_TONE_BUSY, &play_tone, sizeof(play_tone)); - if (play_tone == 0) { - return; - } - lsm_util_tone_start_with_speaker_as_backup(VCM_CALL_WAITING_TONE, VCM_ALERT_INFO_OFF, - CC_NO_CALL_ID, CC_NO_GROUP_ID, - CC_NO_MEDIA_REF_ID, VCM_PLAY_TONE_TO_EAR); - } - break; - - default: - break; - } -} - -/* - * lsm_update_inalert_status - * - * Description: - * - * TNP specific implementation of status line update for inalert state. - * - * Parameters: - * - * line_t line - Line facility of the call - * callid_t call_id - Call id of call whose state is being reported - * cc_state_data_alerting_t * data - alerting callinfo. - * boolean notify - whether the msg be displayed at notify level. - * - * Returns: None - */ -static void -lsm_update_inalert_status (line_t line, callid_t call_id, - cc_state_data_alerting_t * data, - boolean notify) -{ - static const char fname[] = "lsm_update_inalert_status"; - char disp_str[LSM_DISPLAY_STR_LEN]; - - // get localized tag index for From and append one space character - sstrncpy(disp_str, platform_get_phrase_index_str(UI_FROM), - sizeof(disp_str)); - - LSM_DEBUG(DEB_L_C_F_PREFIX"+++ calling number = %s\n", - DEB_L_C_F_PREFIX_ARGS(LSM, line, call_id, fname), - data->caller_id.calling_number); - - // append calling number if present or localized tag for Unknown Number - // otherwise - if ((data->caller_id.calling_number) && - (data->caller_id.calling_number[0] != '\0') && - data->caller_id.display_calling_number) { - - sstrncat(disp_str, data->caller_id.calling_number, - sizeof(disp_str) - strlen(disp_str)); - } else { - sstrncat(disp_str, platform_get_phrase_index_str(UI_UNKNOWN), - sizeof(disp_str) - strlen(disp_str)); - } - - // we display (via notification) the "From ..." info for 10 seconds. - // Note that this will remain displayed for 10 sec even if the user - // answers the call or switches to another call. This happens because - // notification has higher priority than call status (e.g. connected). - // This is done to have parity with SCCP phone behavior. - if (notify == TRUE) { - ui_set_notification(line, call_id, - (char *)disp_str, (unsigned long)CALL_ALERT_TIMEOUT, - FALSE, FROM_NOTIFY_PRI); - } - // After the notification we wish to set the call status to From XXXX. Same as SCCP phone behavior - lsm_ui_display_status((char *)disp_str, line, call_id); - - return; -} - - - -/* - * lsm_set_cfwd_all_nonccm - * This function calls JNI API to set the CFA state and DN in non-ccm mode. - * - * @param[in] line - line on which to set the CFA - * @param[in] callfwd_dialstring: CFA DN (will be stored in flash) - * - * @return: None - */ -void -lsm_set_cfwd_all_nonccm (line_t line, char *callfwd_dialstring) -{ - // call Java API - ui_cfwd_status(line, TRUE, callfwd_dialstring, TRUE); -} - -/* - * lsm_set_cfwd_all_ccm - * - * Description: - * This function calls JNI API to set the CFA state and DN in ccm mode. - * - * Parameters: - * char * callfwd_dialstring: CFA DN (will NOT be stored in flash) - * - * Returns: None - */ -void -lsm_set_cfwd_all_ccm (line_t line, char *callfwd_dialstring) -{ - // set locally maintained variable - cfwdall_state_in_ccm_mode[line] = TRUE; - - // call Java API - ui_cfwd_status((line_t)line, TRUE, callfwd_dialstring, FALSE); -} - -/* - * lsm_clear_cfwd_all_nonccm - * This function calls JNI API to clear the CFA state and DN in non-ccm mode. - * - * @param[in] line - line on which to clear the CFA - * - * @return: None - */ -void -lsm_clear_cfwd_all_nonccm (line_t line) -{ - // call Java API - ui_cfwd_status(line, FALSE, "", TRUE); -} - - -/* - * lsm_clear_cfwd_all_ccm - * - * Description: - * This function calls JNI API to clear the CFA state and DN in ccm mode. - * - * Parameters: None - * - * Returns: None - */ -void -lsm_clear_cfwd_all_ccm (line_t line) -{ - // clear locally maintained variable - cfwdall_state_in_ccm_mode[line] = FALSE; - - // call Java API - ui_cfwd_status((line_t)line, FALSE, "", FALSE); -} - -/* - * lsm_check_cfwd_all_nonccm - * - * Description: - * This function returns the CFA state in non-ccm mode. - * - * @param[in] line - line on which to check the CFA - * - * @return: TRUE (if CFA set) or FALSE (if CFA clear) - */ -int -lsm_check_cfwd_all_nonccm (line_t line) -{ - char cfg_cfwd_url[MAX_URL_LENGTH]; - - cfg_cfwd_url[0] = '\0'; - - // get the callfwdall url value from the config/flash table - config_get_string(CFGID_LINE_CFWDALL+line-1, cfg_cfwd_url, MAX_URL_LENGTH); - - // return appropriate value: TRUE if non-NULL and FALSE otherwise - if (cfg_cfwd_url[0]) { - return ((int) TRUE); - } else { - return ((int) FALSE); - } -} - -/* - * lsm_check_cfwd_all_ccm - * - * Description: - * This function returns the CFA state in ccm mode. - * - * Parameters: None - * - * Returns: TRUE or FALSE - */ -int -lsm_check_cfwd_all_ccm (line_t line) -{ - return ((int) cfwdall_state_in_ccm_mode[line]); -} - -/* - * lsm_is_phone_forwarded - * - * Description: - * This function is called from SIP stack to check if received INVITE - * should be responded with 302 or not. In the CCM mode this function - * will always return NULL... that is process the INVITE as normal and - * DO NOT 302 it. In the non-CCM mode, if the cfwdall_url is non-NULL - * then it will form a proper string to use in 302 response; otherwise - * a NULL will be returned and the INVITE will be processed as normal. - * NOTE: most all code is reused from the legacy phone code. - * - * Parameters: line - line for which to check the CFA status - * - * Returns: NULL if forwarding is not set; - * string to use in 302 response if forwarding is set (non-CCM only) - */ -char * -lsm_is_phone_forwarded (line_t line) -{ - static const char fname[] = "lsm_is_phone_forwarded"; - char proxy_ipaddr_str[MAX_IPADDR_STR_LEN]; - int port_number = 5060; // use this value only if none found - char *domain = NULL; - char *port = NULL; - cpr_ip_addr_t proxy_ipaddr; - - - LSM_DEBUG(DEB_F_PREFIX"called\n", DEB_F_PREFIX_ARGS(LSM, fname)); - - // check if running in CCM mode. if so, return NULL that is cfwdall - // not applicable - if (sip_regmgr_get_cc_mode(TEL_CCB_START) == REG_MODE_CCM) { - return (NULL); - } - // get stored callfwdall url value from the config/flash table - - config_get_string(CFGID_LINE_CFWDALL+line-1, cfwdall_url, sizeof(cfwdall_url)); - - if (cfwdall_url[0]) { - // find domain and port - domain = strchr(cfwdall_url, '@'); - if (!domain) { - (void) sipTransportGetServerAddress(&proxy_ipaddr, - 1, TEL_CCB_START); - if (proxy_ipaddr.type != CPR_IP_ADDR_INVALID) { - ipaddr2dotted(proxy_ipaddr_str, &proxy_ipaddr); - port_number = sipTransportGetServerPort(1, TEL_CCB_START); - } - } else { - port = strchr(domain + 1, ':'); - } - - // handle 3 cases - if (domain == NULL) { - /* case (1): no domain or port present - * We have proxy's dotted ip address format. So, not FQDN check. - * Append domain/ip-addr and port. - */ - snprintf(cfwdall_url + strlen(cfwdall_url), - MAX_URL_LENGTH - strlen(cfwdall_url), - "@%s:%d", proxy_ipaddr_str, port_number); - } else if (port == NULL) { - /* case (2): domain present but no port - * Check if the domain is dotted IP address and add port - * only if dotted IP address is used - */ - if (!str2ip((const char *) domain + 1, &proxy_ipaddr)) { - port_number = sipTransportGetServerPort(1, TEL_CCB_START); - snprintf(cfwdall_url + strlen(cfwdall_url), - MAX_URL_LENGTH - strlen(cfwdall_url), - ":%d", port_number); - } - } else { - /* case (3): both domain and port present - * Both domain and port exists, but strip the port if the - * domain is FQDN - */ - memcpy(proxy_ipaddr_str, domain + 1, (port - domain - 1)); - *(proxy_ipaddr_str + (port - domain - 1)) = '\0'; - if (str2ip((const char *) proxy_ipaddr_str, &proxy_ipaddr) != 0) { - *port = '\0'; - } - } - return ((char *)cfwdall_url); - } else { - return ((char *)NULL); - } -} - -/* - * lsm_get_callid_from_ui_id() - * - * Description: - * The function gets the UI id from LSM's LCB for a given GSM call ID. - * - * Parameters: - * ui_id - UI ID. - * - * Returns: callid_t - */ -callid_t -lsm_get_callid_from_ui_id (callid_t uid) -{ - lsm_lcb_t *lcb; - FSM_FOR_ALL_CBS(lcb, lsm_lcbs, LSM_MAX_LCBS) { - if (lcb->ui_id == uid) { - return lcb->call_id; - } - } - return (CC_NO_CALL_ID); -} - -/* - * lsm_get_ui_id - * - * Description: - * The function gets the UI id from LSM's LCB for a given GSM call ID. - * - * Parameters: - * call_id - GSM call ID - * ui_id - UI ID. - * - * Returns: None - */ -callid_t -lsm_get_ui_id (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - return (lcb->ui_id); - } - return (CC_NO_CALL_ID); -} - -/* - * lsm_get_ms_ui_id - * - * Description: - * The function gets the UI id from LSM's LCB for a given GSM call ID. During - * certain features like barge ui_id is set to CC_NO_CALL_ID. - * - * Parameters: - * call_id - GSM call ID - * ui_id - UI ID. - * - * Returns: None - */ -cc_call_handle_t -lsm_get_ms_ui_call_handle (line_t line, callid_t call_id, callid_t ui_id) -{ - callid_t lsm_ui_id; - - if (ui_id != CC_NO_CALL_ID) { - return CREATE_CALL_HANDLE(line, ui_id); - } - - /* If ui_id present use that */ - lsm_ui_id = lsm_get_ui_id(call_id); - - if (lsm_ui_id != CC_NO_CALL_ID) { - return CREATE_CALL_HANDLE(line, lsm_ui_id); - } - - return CREATE_CALL_HANDLE(line, call_id); -} -/* - * lsm_set_ui_id - * - * Description: - * The function sets the UI id to LSM's LCB for a given GSM call ID. - * - * Parameters: - * call_id - GSM call ID - * ui_id - UI ID. - * - * Returns: None - */ -void -lsm_set_ui_id (callid_t call_id, callid_t ui_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - lcb->ui_id = ui_id; - } -} - -char * -lsm_get_gdialed_digits (void) -{ - return (dp_get_gdialed_digits()); -} - -/* - * lsm_update_video_avail - * - * Description: - * The function updates session about the video availability - * - * Parameters: - * line - line - * call_id - GSM call ID - * dir - video avail dir - * - * Returns: None - */ -void lsm_update_video_avail (line_t line, callid_t call_id, int dir) -{ - static const char fname[] = "lsm_update_video_avail"; - fsmdef_dcb_t *dcb; - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - dcb = lcb->dcb; - if (dcb == NULL) { - LSM_ERR_MSG(get_debug_string(DEBUG_INPUT_NULL), fname); - return; - } - - dir &= ~CC_ATTRIB_CAST; - - - ui_update_video_avail (line, lcb->ui_id, dir); - - lsm_update_dscp_value(dcb); - } -} - -/* - * lsm_update_video_offered - * - * Description: - * The function updates session about the video availability - * - * Parameters: - * line - line - * call_id - GSM call ID - * dir - video avail dir - * - * Returns: None - */ -void lsm_update_video_offered (line_t line, callid_t call_id, int dir) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - ui_update_video_offered (line, lcb->ui_id, dir); - } -} - -/* - * lsm_set_video_mute - * - * Description: - * The function sets the video mute state for the call - * - * Parameters: - * line - line - * call_id - This is the UI_ID coming from UI - * mute - mute state - * - * Returns: None - */ -void lsm_set_video_mute (callid_t call_id, int mute) -{ - lsm_lcb_t *lcb; - callid_t cid = lsm_get_callid_from_ui_id(call_id); // get GSM_ID from UI_ID - - lcb = lsm_get_lcb_by_call_id(cid); - if (lcb != NULL) { - lcb->vid_mute = mute; - } -} - -/* - * lsm_get_video_mute - * - * Description: - * The function gets the video mute state for the call - * - * Parameters: - * line - line - * call_id - GSM call ID - * - * Returns: t_video_mute - */ -int lsm_get_video_mute (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - return lcb->vid_mute; - } - return (-1); -} - - -/* - * lsm_set_video_window - * - * Description: - * The function sets the video window state for the call - * - * Parameters: - * call_id - This is the UI_ID coming from UI - * flags - video window flags - * x - video window x coordinate - * y - video window y coordinate - * h - video window height - * w - video window width - * - * Returns: None - */ -void lsm_set_video_window (callid_t call_id, int flags, int x, int y, int h, int w) -{ - lsm_lcb_t *lcb; - callid_t cid = lsm_get_callid_from_ui_id(call_id); // get GSM_ID from UI_ID - - lcb = lsm_get_lcb_by_call_id(cid); - if (lcb != NULL) { - lcb->vid_flags = flags; - lcb->vid_x = x; - lcb->vid_y = y; - lcb->vid_h = h; - lcb->vid_w = w; - } -} - -/* - * lsm_get_video_window - * - * Description: - * The function gets the video window for the call - * - * Parameters: - * call_id - GSM call ID - * *flags - video window flag - * *x - video window x coordinate - * *y - video window y coordinate - * *h - video window height - * *w - video window width - * - * Returns: void - */ -void lsm_get_video_window (callid_t call_id, int *flags, int *x, int *y, int *h, int *w) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb != NULL) { - *flags = lcb->vid_flags; - *x = lcb->vid_x; - *y = lcb->vid_y; - *h = lcb->vid_h; - *w = lcb->vid_w; - } -} - -/* - * lsm_is_kpml_subscribed - * - * Description: - * check if kpml is subscribed for this call - * - * Parameters: - * call_id - GSM call ID - * - * Returns: true/false - */ -boolean lsm_is_kpml_subscribed (callid_t call_id) -{ - lsm_lcb_t *lcb; - - lcb = lsm_get_lcb_by_call_id(call_id); - if (lcb == NULL) { - return FALSE; - } - return kpml_is_subscribed(call_id, lcb->line); -} - -/** - * A helper method to start the tone. - */ -static void lsm_util_start_tone(vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction) { - - int sdpmode = 0; - static const char fname[] = "lsm_util_start_tone"; - line_t line = GET_LINE_ID(call_handle); - callid_t call_id = GET_CALL_ID(call_handle); - DEF_DEBUG(DEB_F_PREFIX"Enter, line=%d, call_id=%d.\n", - DEB_F_PREFIX_ARGS(MED_API, fname), line, call_id); - - sdpmode = 0; - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - if (!sdpmode) { - vcmToneStart(tone, alert_info, call_handle, group_id, stream_id, direction); - } - /* - * Set delay value for multi-part tones and repeated tones. - * Currently the only multi-part tones are stutter and message - * waiting tones. The only repeated tones are call waiting and - * tone on hold tones. If the DSP ever supports stutter and - * message waiting tones, these tones can be removed from this - * switch statement. - */ - switch (tone) { - case VCM_MSG_WAITING_TONE: - lsm_start_multipart_tone_timer(tone, MSG_WAITING_DELAY, call_id); - break; - - case VCM_HOLD_TONE: - lsm_start_continuous_tone_timer(tone, TOH_DELAY, call_id); - break; - - default: - break; - } - - /* - * Update dcb->active_tone if start request - * is for an infinite duration tone. - */ - lsm_update_active_tone(tone, call_id); -} - -/* - * Plays a short tone. uses the open audio path. - * If no audio path is open, plays on speaker. - * - * @param[in] tone - tone type - * @param[in] alert_info - alertinfo header - * @param[in] call_id - call identifier - * @param[in] direction - network, speaker, both - * - * @return none - */ -void -lsm_util_tone_start_with_speaker_as_backup (vcm_tones_t tone, short alert_info, - cc_call_handle_t call_handle, groupid_t group_id, - streamid_t stream_id, uint16_t direction) { - static const char *fname = "lsm_util_tone_start_with_speaker_as_backup"; - line_t line = GET_LINE_ID(call_handle); - callid_t call_id = GET_CALL_ID(call_handle); - DEF_DEBUG(DEB_L_C_F_PREFIX"tone=%-2d: direction=%-2d\n", - DEB_L_C_F_PREFIX_ARGS(MED_API, line, call_id, fname), - tone, direction); - - //vcmToneStart - vcmToneStart(tone, alert_info, call_handle, group_id, stream_id, direction); - - /* - * Set delay value for multi-part tones and repeated tones. - * Currently the only multi-part tones are stutter and message - * waiting tones. The only repeated tones are call waiting and - * tone on hold tones. If the DSP ever supports stutter and - * message waiting tones, these tones can be removed from this - * switch statement. - */ - switch (tone) { - case VCM_MSG_WAITING_TONE: - lsm_start_multipart_tone_timer(tone, MSG_WAITING_DELAY, call_id); - break; - - case VCM_HOLD_TONE: - lsm_start_continuous_tone_timer(tone, TOH_DELAY, call_id); - break; - - default: - break; - } - - /* - * Update dcb->active_tone if start request - * is for an infinite duration tone. - */ - lsm_update_active_tone(tone, call_id); - -} diff --git a/libs/sipcc/core/gsm/media_cap_tbl.c b/libs/sipcc/core/gsm/media_cap_tbl.c deleted file mode 100644 index 46cce5e5b8..0000000000 --- a/libs/sipcc/core/gsm/media_cap_tbl.c +++ /dev/null @@ -1,158 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "ccapi.h" -#include "phone_debug.h" -#include "cc_debug.h" -#include "CCProvider.h" -#include "ccapi_snapshot.h" - -/** - * global media cap table for interaction between what platform - * can do and the GSM-SDP module - * AUDIO_1 is used for audio cannot be turned off - * VIDEO_1 is used for video - */ -cc_media_cap_table_t g_media_table = { - 1, - { - {CC_AUDIO_1,SDP_MEDIA_AUDIO,TRUE,TRUE,SDP_DIRECTION_RECVONLY}, - {CC_VIDEO_1,SDP_MEDIA_VIDEO,TRUE,TRUE,SDP_DIRECTION_RECVONLY}, - {CC_DATACHANNEL_1,SDP_MEDIA_APPLICATION,FALSE,TRUE,SDP_DIRECTION_SENDRECV}, - } -}; - -static boolean g_nativeVidSupported = FALSE; -static boolean g_vidCapEnabled = FALSE; -static boolean g_natve_txCap_enabled = FALSE; - -/** - * Simple method to trigger escalation and deescalation - * based on media capability changes - */ -void escalateDeescalate() { - g_media_table.id++; - if ( ccapp_get_state() != CC_INSERVICE ) { - VCM_DEBUG(MED_F_PREFIX"Ignoring video cap update\n", "escalateDeescalate"); - return; - } - - //post the event - cc_int_feature(CC_SRC_UI, CC_SRC_GSM, CC_NO_CALL_ID, - CC_NO_LINE, CC_FEATURE_UPD_MEDIA_CAP, NULL); -} - -cc_boolean cc_media_isTxCapEnabled() { - return g_natve_txCap_enabled; -} - -cc_boolean cc_media_isVideoCapEnabled() { - if ( g_nativeVidSupported ) { - return g_vidCapEnabled; - } - return FALSE; -} - -/** - * API to update the local video cap in the table - * called when native video support or vidCap cfg changes - * - * This method looks at video cap in cfg & native vid support on platform - */ -static void updateVidCapTbl(){ - - if ( g_vidCapEnabled ) { - if ( g_media_table.cap[CC_VIDEO_1].enabled == FALSE ) { - // cfg is enabled but cap tbl is not - if ( g_nativeVidSupported ) { - // we can do native now enable cap - g_media_table.cap[CC_VIDEO_1].enabled = TRUE; - g_media_table.cap[CC_VIDEO_1].support_direction = - g_natve_txCap_enabled?SDP_DIRECTION_SENDRECV:SDP_DIRECTION_RECVONLY; - if ( g_natve_txCap_enabled == FALSE ) { - - } - escalateDeescalate(); - } else { - - } - } - } else { - // disable vid cap - DEF_DEBUG(MED_F_PREFIX"video capability disabled \n", "updateVidCapTbl"); - - if ( g_media_table.cap[CC_VIDEO_1].enabled ) { - g_media_table.cap[CC_VIDEO_1].enabled = FALSE; - escalateDeescalate(); - } - } -} - - -/** - * API to update video capability on the device - * expected to be called once in the beginning only - */ -void cc_media_update_native_video_support(boolean val) { - DEF_DEBUG(MED_F_PREFIX"Setting native video support val=%d\n", "cc_media_update_native_video_support", val); - g_nativeVidSupported = val; - updateVidCapTbl(); -} - -/** - * - * API to update video capability on the device based on config - */ -void cc_media_update_video_cap(boolean val) { - DEF_DEBUG(MED_F_PREFIX"Setting video cap val=%d\n", "cc_media_update_video_cap", val); - g_vidCapEnabled = val; - updateVidCapTbl(); - if ( g_nativeVidSupported ) { - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_VIDEO_CAP_ADMIN_CONFIG_CHANGED, CC_DEVICE_ID); - } -} - -/** - * - * API to update video tx capability based on camera plugin events - */ - -void cc_media_update_native_video_txcap(boolean enable) { - - VCM_DEBUG(MED_F_PREFIX"Setting txcap val=%d\n", "cc_media_update_video_txcap", enable); - - if ( g_natve_txCap_enabled == enable ) { - // nothing to do - return; - } - - g_natve_txCap_enabled = enable; - ccsnap_gen_deviceEvent(CCAPI_DEVICE_EV_CAMERA_ADMIN_CONFIG_CHANGED, CC_DEVICE_ID); - - if ( g_nativeVidSupported && g_vidCapEnabled ) { - // act on camera events only iof native video is enabled - if ( g_natve_txCap_enabled ) { - - } else if (g_media_table.cap[CC_VIDEO_1].enabled) { - - } - - g_media_table.cap[CC_VIDEO_1].support_direction = - g_natve_txCap_enabled?SDP_DIRECTION_SENDRECV:SDP_DIRECTION_RECVONLY; - - escalateDeescalate(); - } -} - -static cc_boolean vidAutoTxPref=FALSE; -void cc_media_setVideoAutoTxPref(cc_boolean txPref){ - vidAutoTxPref = txPref; -} - -cc_boolean cc_media_getVideoAutoTxPref(){ - return vidAutoTxPref; -} - - diff --git a/libs/sipcc/core/gsm/sm.c b/libs/sipcc/core/gsm/sm.c deleted file mode 100755 index 80ba7a2f58..0000000000 --- a/libs/sipcc/core/gsm/sm.c +++ /dev/null @@ -1,78 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_stdio.h" -#include "sm.h" -#include "gsm.h" -#include "fsm.h" -#include "text_strings.h" -#include "ccapi.h" - -sm_rcs_t -sm_process_event (sm_table_t *tbl, sm_event_t *event) -{ - static const char fname[] = "sm_process_event"; - int state_id = event->state; - int event_id = event->event; - sm_rcs_t rc = SM_RC_ERROR; - fsm_fcb_t *fcb = (fsm_fcb_t *) event->data; - cc_feature_t *feat_msg = NULL; - line_t line_id; - fsm_types_t fsm_type; - callid_t call_id; - sm_function_t hdlr; /* cached handler in order to compute its addr once */ - - /* - * validate the state and event - * and that there is a valid function for this state-event pair. - */ - if ((state_id > tbl->min_state) && - (state_id < tbl->max_state) && - (event_id > tbl->min_event) && - (event_id < tbl->max_event)) { - rc = SM_RC_DEF_CONT; - /* - * Save some paramters for debuging, the event handler may - * free the fcb once returned. - */ - fsm_type = fcb->fsm_type; - call_id = fcb->call_id; - if ((hdlr = tbl->table[tbl->max_event * state_id + event_id]) != NULL) { - FSM_DEBUG_SM(DEB_F_PREFIX"%s %-4d: 0x%08lx: sm entry: (%s:%s)\n", - DEB_F_PREFIX_ARGS(FSM, fname), fsm_type_name(fsm_type), call_id, - tbl->table[tbl->max_event * state_id + event_id], - fsm_state_name(fsm_type, state_id), - cc_msg_name((cc_msgs_t)(event_id))); - - rc = hdlr(event); - } - - if (rc != SM_RC_DEF_CONT) { - /* For event_id == CC_MSG_FEATURE then display the - * feature associated with it. - */ - if (event_id == CC_MSG_FEATURE) { - feat_msg = (cc_feature_t *) event->msg; - } - line_id = ((cc_feature_t *) event->msg)->line; - - DEF_DEBUG(DEB_L_C_F_PREFIX"%-5s :(%s:%s%s)\n", - DEB_L_C_F_PREFIX_ARGS(GSM, line_id, call_id, fname), - fsm_type_name(fsm_type), - fsm_state_name(fsm_type, state_id), - cc_msg_name((cc_msgs_t)(event_id)), - feat_msg ? cc_feature_name(feat_msg->feature_id):" "); - } - } - /* - * Invalid state-event pair. - */ - else { - GSM_ERR_MSG(GSM_F_PREFIX"illegal state-event pair: (%d <-- %d)\n", - fname, state_id, event_id); - rc = SM_RC_ERROR; - } - - return rc; -} diff --git a/libs/sipcc/core/gsm/subapi.c b/libs/sipcc/core/gsm/subapi.c deleted file mode 100755 index 1dee58fa1e..0000000000 --- a/libs/sipcc/core/gsm/subapi.c +++ /dev/null @@ -1,269 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "cpr_stdlib.h" -#include "ccapi.h" -#include "ccsip_task.h" -#include "debug.h" -#include "phone_debug.h" -#include "phntask.h" -#include "phone.h" -#include "text_strings.h" -#include "string_lib.h" -#include "gsm.h" -#include "vcm.h" -#include "subapi.h" -#include "misc_apps_task.h" - - -static void -sub_print_msg (char *pData, int len) -{ - int ix; - int msg_id = *((int *)pData); - - buginf("\nCCAPI: cc_msg= %s, 0x=", cc_msg_name((cc_msgs_t)msg_id)); - for (ix = 0; ix < len; ix++) { - if ((ix % 8 == 0) && ix) { - buginf(" "); - } - if (ix % 24 == 0) { - buginf("\n"); - } - buginf("%02x ", *pData++); - } - buginf("\n"); -} - -cc_rcs_t -sub_send_msg (cprBuffer_t buf, uint32_t cmd, uint16_t len, cc_srcs_t dst_id) -{ - cpr_status_e rc; - - CC_DEBUG_MSG sub_print_msg((char *)buf, len); - - switch (dst_id) { - case CC_SRC_GSM: - rc = gsm_send_msg(cmd, buf, len); - if (rc == CPR_FAILURE) { - cpr_free(buf); - } - break; - case CC_SRC_SIP: - rc = SIPTaskSendMsg(cmd, buf, len, NULL); - if (rc == CPR_FAILURE) { - cpr_free(buf); - } - break; - case CC_SRC_MISC_APP: - rc = MiscAppTaskSendMsg(cmd, buf, len); - if (rc == CPR_FAILURE) { - cpr_free(buf); - } - break; - default: - rc = CPR_FAILURE; - break; - } - - return (rc == CPR_SUCCESS) ? CC_RC_SUCCESS : CC_RC_ERROR; -} - -cc_rcs_t -sub_int_subnot_register (cc_srcs_t src_id, cc_srcs_t dst_id, - cc_subscriptions_t evt_pkg, void *callback_fun, - cc_srcs_t dest_task, int msg_id, void *term_callback, - int term_msg_id, long min_duration, long max_duration) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.subs_reg.eventPackage = evt_pkg; - pmsg->msg.subs_reg.max_duration = max_duration; - pmsg->msg.subs_reg.min_duration = min_duration; - pmsg->msg.subs_reg.subsIndCallback = (ccsipSubsIndCallbackFn_t) - callback_fun; - pmsg->msg.subs_reg.subsIndCallbackMsgID = msg_id; - pmsg->msg.subs_reg.subsIndCallbackTask = dest_task; - pmsg->msg.subs_reg.subsTermCallback = (ccsipSubsTerminateCallbackFn_t) - term_callback; - pmsg->msg.subs_reg.subsTermCallbackMsgID = term_msg_id; - - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_SUBSCRIBE_REGISTER, - sizeof(*pmsg), dst_id); -} - -/* - * Function: sub_int_subscribe() - * - * Parameters: msg_p - pointer to sipspi_msg_t (input parameter) - * - * Description: posts SIPSPI_EV_CC_SUBSCRIBE to SIP task message queue. - * - * Returns: CC_RC_ERROR - failed to post msg. - * CC_RC_SUCCESS - successful posted msg. - */ -cc_rcs_t -sub_int_subscribe (sipspi_msg_t *msg_p) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - memcpy(pmsg, msg_p, sizeof(sipspi_msg_t)); - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_SUBSCRIBE, - sizeof(*pmsg), CC_SRC_SIP); -} - - -cc_rcs_t -sub_int_subscribe_ack (cc_srcs_t src_id, cc_srcs_t dst_id, sub_id_t sub_id, - uint16_t response_code, int duration) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.subscribe_resp.response_code = response_code; - pmsg->msg.subscribe_resp.sub_id = sub_id; - pmsg->msg.subscribe_resp.duration = duration; - - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_SUBSCRIBE_RESPONSE, - sizeof(*pmsg), dst_id); -} - - -cc_rcs_t -sub_int_notify (cc_srcs_t src_id, cc_srcs_t dst_id, sub_id_t sub_id, - ccsipNotifyResultCallbackFn_t notifyResultCallback, - int subsNotResCallbackMsgID, ccsip_event_data_t * eventData, - subscriptionState subState) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.notify.eventData = eventData; - pmsg->msg.notify.notifyResultCallback = notifyResultCallback; - pmsg->msg.notify.sub_id = sub_id; - pmsg->msg.notify.subsNotResCallbackMsgID = subsNotResCallbackMsgID; - pmsg->msg.notify.subState = subState; - - return sub_send_msg((cprBuffer_t) pmsg, SIPSPI_EV_CC_NOTIFY, - sizeof(*pmsg), dst_id); -} - -/* - * Function: sub_int_notify_ack() - * - * Parameters: sub_id - subcription id for sip stack to track the subscription. - * response_code - response code to be sent in response to NOTIFY. - * cseq : CSeq for which response is being sent. - * - * Description: posts SIPSPI_EV_CC_NOTIFY_RESPONSE to SIP task message queue. - * - * Returns: CC_RC_ERROR - failed to post msg. - * CC_RC_SUCCESS - successful posted msg. - */ -cc_rcs_t -sub_int_notify_ack (sub_id_t sub_id, uint16_t response_code, uint32_t cseq) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.notify_resp.sub_id = sub_id; - pmsg->msg.notify_resp.response_code = response_code; - pmsg->msg.notify_resp.cseq = cseq; - - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_NOTIFY_RESPONSE, - sizeof(*pmsg), CC_SRC_SIP); -} - - -/* - * Function: sub_int_subscribe_term() - * - * Parameters: sub_id - subcription id for sip stack to track the subscription. - * immediate - boolean flag to indicate if the termination be immediate. - * request_id - request id significant for out going subscriptions - * event_package - event package type - * - * Description: posts SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED to SIP task message queue. - * - * Returns: CC_RC_ERROR - failed to post msg. - * CC_RC_SUCCESS - successful posted msg. - */ -cc_rcs_t -sub_int_subscribe_term (sub_id_t sub_id, boolean immediate, int request_id, - cc_subscriptions_t event_package) -{ - sipspi_msg_t *pmsg; - - pmsg = (sipspi_msg_t *) cc_get_msg_buf(sizeof(*pmsg)); - if (!pmsg) { - return CC_RC_ERROR; - } - - pmsg->msg.subs_term.immediate = immediate; - pmsg->msg.subs_term.sub_id = sub_id; - pmsg->msg.subs_term.request_id = request_id; - pmsg->msg.subs_term.eventPackage = event_package; - - return sub_send_msg((cprBuffer_t)pmsg, SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED, - sizeof(*pmsg), CC_SRC_SIP); -} - -cc_rcs_t -sip_send_message (ccsip_sub_not_data_t * msg_data, cc_srcs_t dest_id, int msg_id) -{ - ccsip_sub_not_data_t *pmsg; - - pmsg = (ccsip_sub_not_data_t *) cc_get_msg_buf(sizeof(*pmsg)); - - if (!pmsg) { - return CC_RC_ERROR; - } - - memcpy(pmsg, msg_data, sizeof(*pmsg)); - - return sub_send_msg((cprBuffer_t)pmsg, msg_id, sizeof(*pmsg), dest_id); -} - - -cc_rcs_t -app_send_message (void *msg_data, int msg_len, cc_srcs_t dest_id, int msg_id) -{ - void *pmsg; - - pmsg = (void *) cc_get_msg_buf(msg_len); - - if (!pmsg) { - return CC_RC_ERROR; - } - - memcpy(pmsg, msg_data, msg_len); - - return sub_send_msg((cprBuffer_t)pmsg, msg_id, (uint16_t)msg_len, dest_id); -} diff --git a/libs/sipcc/core/includes/CSFLog.h b/libs/sipcc/core/includes/CSFLog.h deleted file mode 100644 index ea02257556..0000000000 --- a/libs/sipcc/core/includes/CSFLog.h +++ /dev/null @@ -1,46 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CSFLOG_H -#define CSFLOG_H - -#include - -typedef enum{ - CSF_LOG_CRITICAL =1, - CSF_LOG_ERROR, - CSF_LOG_WARNING, - CSF_LOG_NOTICE, - CSF_LOG_INFO, - CSF_LOG_DEBUG -} CSFLogLevel; - - - -#define CSFLogError(tag , format, ...) CSFLog( CSF_LOG_ERROR, __FILE__ , __LINE__ , tag , format , ## __VA_ARGS__ ) -#define CSFLogErrorV(tag , format, va_list_arg) CSFLogV(CSF_LOG_ERROR, __FILE__ , __LINE__ , tag , format , va_list_arg ) -#define CSFLogWarn(tag , format, ...) CSFLog( CSF_LOG_WARNING, __FILE__ , __LINE__ , tag , format , ## __VA_ARGS__ ) -#define CSFLogWarnV(tag , format, va_list_arg) CSFLogV(CSF_LOG_WARNING, __FILE__ , __LINE__ , tag , format , va_list_arg ) -#define CSFLogInfo(tag , format, ...) CSFLog( CSF_LOG_INFO, __FILE__ , __LINE__ , tag , format , ## __VA_ARGS__ ) -#define CSFLogInfoV(tag , format, va_list_arg) CSFLogV(CSF_LOG_INFO, __FILE__ , __LINE__ , tag , format , va_list_arg ) -#define CSFLogDebug(tag , format, ...) CSFLog(CSF_LOG_DEBUG, __FILE__ , __LINE__ , tag , format , ## __VA_ARGS__ ) -#define CSFLogDebugV(tag , format, va_list_arg) CSFLogV(CSF_LOG_DEBUG, __FILE__ , __LINE__ , tag , format , va_list_arg ) - -#ifdef __cplusplus -extern "C" -{ -#endif -#if 0 -void CSFLog( CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, ...); -void CSFLogV( CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, va_list args); -#else -#endif -#define CSFLog(pri, file, line, tag, format, ...) -#define CSFLogV(pri, file, line, tag, format, args) -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/libs/sipcc/core/includes/ccSession.h b/libs/sipcc/core/includes/ccSession.h deleted file mode 100755 index 398f4976a3..0000000000 --- a/libs/sipcc/core/includes/ccSession.h +++ /dev/null @@ -1,207 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSESSION_H_ -#define _CCSESSION_H_ - -#include "session.h" -#include "sessuri.h" - -#define SID_TYPE_SHIFT 28 -#define SID_LINE_SHIFT 16 - -#define GET_SESS_TYPE(x) ( (x & 0xF0000000) >> SID_TYPE_SHIFT ) -#define GET_LINEID(x) (line_t)( (x & 0xFFF0000) >> SID_LINE_SHIFT ) -#define GET_CALLID(x) (callid_t)(x & 0xFFFF) - - - - -/** - * ccSessionProviderCmd - * CallControl Provider Management Interface - * Called by Application to issue cmds to sipStack - * - * @param data - command and data - * data->cmd - see Session Provider Commands in session.h - * data->cmdData.ccData.reason - reason for SHUTDOWN/UNREGISTER_ALL_LINES CMD - CC_CAUSE_NORMAL/CC_CAUSE_NONE - * data->cmdData.ccData.reason_info - Descriptive stringa "notused" - * - * @return none - * - */ -void ccSessionProviderCmd(sessionProvider_cmd_t *data); - - -/** - * ccSessionProviderState - * Method to report provider state updates to Application - * - * @param state - indicates the Session Provider state CCApp_states_t - * @param data - ccProvider_state_t indicating - * data->stateData.ccData.mode - REGMODE CCM - * data->stateData.ccData.cause - FAILOVER/FALLBACK - * - * @return none - * - */ -void ccSessionProviderState(unsigned int state, ccProvider_state_t *data); - - -/** - * ccSessionCmd - * Method to Handle session lifecycle command such as realize, start etc. - * - * @param sCmd - session liefcycle command - * sCmd->cmd - REQUEST CMD - * sCmd->sessID - session ID - * - * @return none - * - */ - -void ccSessionCmd (sessionCmd_t *sCmd); - - -/** - * ccCreateSession - * - * Called by Application to create a new session - * - * @param param - uri_t - * param->param.call_session_param.line_id - line on which to create the session - * @return ccSession_id_t - id of the session created - */ - -session_id_t ccCreateSession(uri_t *param); - -/** - * ccCloseSession - * - * Called by Application to close a session - * - * @param sess_id - ID of the session to be closed - * - * @return 0 success -1 failure - * - */ - -int ccCloseSession(session_id_t sess_id); - -/* Need to document IDs and data for the following 4 methods */ - -/** - * ccInvokeFeature - * - * Called by Application to invoke feature on session - * - * @param featData - featID and Additional info if needed for the feature - * - * @return none - * - */ - -void ccInvokeFeature(session_feature_t *featData); - -/** - * ccInvokeProviderFeature - * - * Called by Application to invoke device specific features - * - * @param featData - Additional info if needed for the feature - * - * @return none - * - */ - -void ccInvokeProviderFeature(session_feature_t *featData); - - -/** - * ccSessionUpdate - * - * Called by sipstack to update session state and data - * - * @param eventID - ID of the event updating the session data - * @param session_data - event specific data - * - * @return none - * - */ - -void ccSessionUpdate(session_update_t *session); - - - -/** - * ccFeatureUpdate - * - * Called by sipstack to update feature state and data - * - * @param featureID - ID of the feature updated - * @param session_data - feature specific data - * - * @return none - * - */ - -void ccFeatureUpdate(feature_update_t *session); - -/***** Internal APIs below this line ***************/ - -/** - * ccCreateSession - * - * Called to create a CC session - * - * @param param - ccSession_create_param_t - * Contains the type of session and specific data - * - * @return ccSession_id_t - id of the session created - */ -session_id_t createSessionId(line_t line, callid_t call); - -void platform_sync_cfg_vers (char *cfg_ver, char *dp_ver, char *softkey_ver); -/********************************************************************************/ - -/* Misc getter/setter function to get set the following */ - -#define PROPERTY_ID_MWI 1 // per line -#define PROPERTY_ID_TIME 2 // unsigned long -#define PROPERTY_ID_KPML 3 -#define PROPERTY_ID_REGREASON 4 -#define PROPERTY_ID_SPKR_HDST 5 1 - -void setIntProperty(unsigned int id, int val); -int getIntProperty(unsigned int id); -void setStrProperty(unsigned int id, char * val); -char * getStrProperty(unsigned int id); - - -/* Preserved API's from TNP Platform */ -char *ccSetDP(const char *dp_file_name); -// update_label_n_speed_dial method here -void setPropertyCacheBoolean(int cfg_id, int bool_value); -void setPropertyCacheInteger(int cfg_id, int int_value); -void setPropertyCacheString(int cfg_id, const char *string_value); -void setPropertyCacheByte(int cfg_id, char byte_value); -void setPropertyCacheByteArray(int cfg_id, char *byte_value, int length); - -/* BLF */ -void ccBLFSubscribe(int request_id, int duration, const char *watcher, - const char *presentity, int app_id, int feature_mask); -void ccBLFUnsubscribe(int request_id); -void ccBLFUnsubscribeAll(); -void blf_notification(int request_id, int status, int app_id); - - -/********************************************************************** - -MID_JPlatUi_ui_log_status_msg, Ask RCDN team if log is changing? - -**********************************************************************/ - -#endif - diff --git a/libs/sipcc/core/includes/ccapi.h b/libs/sipcc/core/includes/ccapi.h deleted file mode 100755 index 011b57e8fb..0000000000 --- a/libs/sipcc/core/includes/ccapi.h +++ /dev/null @@ -1,1578 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCAPI_H_ -#define _CCAPI_H_ - -//#include "prtypes.h" -#include "cpr_types.h" -#include "cpr_memory.h" -#include "phone_types.h" -#include "string_lib.h" -#include "vcm.h" -#include "sdp.h" -#include "cc_constants.h" - -typedef unsigned int cc_security_e; -typedef unsigned int cc_select_state_e; -typedef unsigned int cc_call_type_e; -typedef unsigned int cc_policy_e; -typedef int cc_causes_t; -#define CC_CALL_OUTGOMING CC_CALL_TYPE_OUTGOING -#define CC_CALL_FORWARDED CC_CALL_TYPE_FORWARDED -#define CC_CALL_NONE CC_CALL_TYPE_NONE -#define CC_CALL_INCOMING CC_CALL_TYPE_INCOMING -#define SDP_SIZE 4096 /* must increase this */ -#define CANDIDATE_SIZE 150 -#define MID_SIZE 150 - -#include "sessionConstants.h" - -typedef int cc_features_t; -typedef unsigned int softkey_events; -typedef unsigned int cc_call_priority_e; -extern cc_reg_state_t ccapp_get_state(); - -/* Session FEATURES */ -/* please update cc_feature_names whenever this enum list is changed */ - -typedef enum { - CC_FEATURE_MIN = -1L, - CC_FEATURE_NONE, - CC_FEATURE_HOLD = 1L, - CC_FEATURE_RESUME, - CC_FEATURE_OFFHOOK, - CC_FEATURE_NEW_CALL, - CC_FEATURE_REDIAL, - CC_FEATURE_ONHOOK, - CC_FEATURE_KEYPRESS, - CC_FEATURE_DIAL, - CC_FEATURE_XFER, - CC_FEATURE_CFWD_ALL, - CC_FEATURE_END_CALL, - CC_FEATURE_ANSWER, - CC_FEATURE_INFO, - CC_FEATURE_CONF, - CC_FEATURE_JOIN, - CC_FEATURE_DIRTRXFR, - CC_FEATURE_SELECT, - CC_FEATURE_SPEEDDIAL, - CC_FEATURE_SWAP, - CC_FEATURE_SPEEDDIAL_BLF, - CC_FEATURE_BLIND_XFER_WITH_DIALSTRING, - CC_FEATURE_BKSPACE, - CC_FEATURE_CANCEL, - CC_FEATURE_DIALSTR, - CC_FEATURE_UPD_SESSION_MEDIA_CAP, - /* Not used in the session API */ - CC_FEATURE_MEDIA, - CC_FEATURE_UPDATE, - CC_FEATURE_CALLINFO, - CC_FEATURE_BLIND_XFER, - CC_FEATURE_NOTIFY, - CC_FEATURE_SUBSCRIBE, - CC_FEATURE_B2BCONF, - CC_FEATURE_B2B_JOIN, - CC_FEATURE_HOLD_REVERSION, - CC_FEATURE_BLF_ALERT_TONE, - CC_FEATURE_REQ_PEND_TIMER_EXP, - CC_FEATURE_NUMBER, - CC_FEATURE_URL, - CC_FEATURE_REDIRECT, - CC_FEATURE_RINGBACK_DELAY_TIMER_EXP, - CC_FEATURE_CALL_PRESERVATION, - CC_FEATURE_UPD_MEDIA_CAP, - CC_FEATURE_CAC_RESP_PASS, - CC_FEATURE_CAC_RESP_FAIL, - CC_FEATURE_FAST_PIC_UPD, - CC_FEATURE_UNDEFINED, - CC_FEATURE_CREATEOFFER, - CC_FEATURE_CREATEANSWER, - CC_FEATURE_SETLOCALDESC, - CC_FEATURE_SETREMOTEDESC, - CC_FEATURE_LOCALDESC, - CC_FEATURE_REMOTEDESC, - CC_FEATURE_SETPEERCONNECTION, - CC_FEATURE_ADDSTREAM, - CC_FEATURE_REMOVESTREAM, - CC_FEATURE_ADDICECANDIDATE, - CC_FEATURE_MAX -} group_cc_feature_t; - -#define skNewCall CC_FEATURE_NEW_CALL -#define skConfrn CC_FEATURE_CONF - -/* please update the following cc_feature_names whenever this feature list is changed */ - -#ifdef __CC_FEATURE_STRINGS__ -static const char *cc_feature_names[] = { - "NONE", - "HOLD", - "RESUME", - "OFFHOOK", - "NEW_CALL", - "REDIAL", - "ONHOOK", - "KEYPRESS", - "DIAL", - "XFER", - "CFWD_ALL", //10 - "END_CALL", - "ANSWER", - "INFO", - "CONF", - "JOIN", - "DIR_XFER", - "SELECT", - "SPEEDDIAL", - "SWAP", - "SDBLF", //45 - "BLIND_XFER_WITH_DIALSTRING", - "BSPACE", - "CANCEL", - "DIALSTR", - "UPD_SESSION_MEDIA_CAP", - "NEW_MEDIA", - "UPDATE", - "CALLINFO", - "BLIND_XFER", - "NOTIFY", - "SUBSCRIBE", - "B2BCONF", - "B2BJOIN", - "HOLD_REVERSION", //jni_max + 10 - "BLF_ALERT_TONE", - "REQPENDTMREXP", - "NUMBER", - "URL", - "REDIRECT", //jni_max + 20 - "RINGBACKDELAYTMREXP", - "CALL_PRESERVATION", - "UPD_MEDIA_CAP", - "CAC PASSED", - "CAC FAILED", - "FAST_PIC_UPD", - "UNDEFINED", - "CREATEOFFER", - "CREATEANSWER", - "SETLOCALDESC", - "SETREMOTEDESC", - "LOCALDESC", - "REMOTEDESC", - "SETPEERCONNECTION", - "ADDSTREAM", - "REMOVESTREAM", - "ADDICECANDIDATE", - "MAX" -}; - -/* This checks at compile-time that the cc_feature_names list - * is the same size as the cc_group_feature_t enum - */ -//PR_STATIC_ASSERT(PR_ARRAY_SIZE(cc_feature_names) == CC_FEATURE_MAX + 1); - -#endif - -/* - * Constants - */ -#define CC_MAX_DIALSTRING_LEN (512) -#define CC_MAX_MEDIA_TYPES (15) -#define CC_MAX_MEDIA_CAP (4) -#define CC_NO_CALL_ID (0) -#define CC_NO_LINE (0) -#define CC_NO_DATA (NULL) -#define CC_NO_MEDIA_REF_ID (0) -#define CC_MAX_REDIRECTS (1) -#define CC_MAX_BODY_PARTS 3 -#define CC_NO_GROUP_ID (0) -#define CC_NO_CALL_INST_ID (0) -#define CC_SHORT_DIALSTRING_LEN (64) -#define CC_CISCO_PLAR_STRING "x-cisco-serviceuri-offhook" -#define CISCO_BLFPICKUP_STRING "x-cisco-serviceuri-blfpickup" -#define JOIN_ACROSS_LINES_DISABLED 0 -#define CC_MAX_TRACKS 8 // query this figure -#define CC_MAX_STREAMS 2 // TODO: expand signaling to handle more than one of each a/v. - - -/* - * - * Support type definintions - * - */ -typedef enum cc_rcs_t_ { - CC_RC_MIN = -1, - CC_RC_SUCCESS, - CC_RC_ERROR, - CC_RC_MAX -} cc_rcs_t; - -typedef enum cc_msgs_t_ { - CC_MSG_MIN = -1, - CC_MSG_SETUP, - CC_MSG_SETUP_ACK, - CC_MSG_PROCEEDING, - CC_MSG_ALERTING, - CC_MSG_CONNECTED, - CC_MSG_CONNECTED_ACK, - CC_MSG_RELEASE, - CC_MSG_RELEASE_COMPLETE, - CC_MSG_FEATURE, - CC_MSG_FEATURE_ACK, - CC_MSG_OFFHOOK, - CC_MSG_ONHOOK, - CC_MSG_LINE, - CC_MSG_DIGIT_BEGIN, - CC_MSG_DIGIT_END, - CC_MSG_DIALSTRING, - CC_MSG_MWI, - CC_MSG_AUDIT, - CC_MSG_CREATEOFFER, - CC_MSG_CREATEANSWER, - CC_MSG_SETLOCALDESC, - CC_MSG_SETREMOTEDESC, - CC_MSG_REMOTEDESC, - CC_MSG_LOCALDESC, - CC_MSG_SETPEERCONNECTION, - CC_MSG_ADDSTREAM, - CC_MSG_REMOVESTREAM, - CC_MSG_ADDCANDIDATE, - CC_MSG_AUDIT_ACK, - CC_MSG_OPTIONS, - CC_MSG_OPTIONS_ACK, - CC_MSG_SUBSCRIBE, - CC_MSG_NOTIFY, - CC_MSG_FAILOVER_FALLBACK, - CC_MSG_INFO, - /* update the following strings table if this is changed */ - CC_MSG_MAX -} cc_msgs_t; - -#ifdef __CC_MESSAGES_STRINGS__ -static const char *cc_msg_names[] = { - "SETUP", - "SETUP_ACK", - "PROCEEDING", - "ALERTING", - "CONNECTED", - "CONNECTED_ACK", - "RELEASE", - "RELEASE_COMPLETE", - "FEAT:", - "FEATURE_ACK", - "OFFHOOK", - "ONHOOK", - "LINE", - "DIGIT_BEGIN", - "DIGIT_END", - "DIALSTRING", - "MWI", - "AUDIT", - "CREATEOFFER", - "CREATEANSWER", - "SETLOCALDESC", - "SETREMOTEDESC", - "REMOTEDESC", - "LOCALDESC", - "SETPEERCONNECTION", - "ADDSTREAM", - "REMOVESTREAM", - "ADDCANDIDATE", - "AUDIT_ACK", - "OPTIONS", - "OPTIONS_ACK", - "SUBSCRIBE", - "NOTIFY", - "FAILOVER_FALLBACK", - "INFO", - "INVALID", -}; - -/* This checks at compile-time that the cc_msg_names list - * is the same size as the cc_msgs_t enum - */ -//PR_STATIC_ASSERT(PR_ARRAY_SIZE(cc_msg_names) == CC_MSG_MAX + 1); - -#endif //__CC_MESSAGES_STRINGS__ - -typedef enum cc_srcs_t_ { - CC_SRC_MIN = -1, - CC_SRC_GSM, - CC_SRC_UI, - CC_SRC_SIP, - CC_SRC_MISC_APP, - CC_SRC_RCC, - CC_SRC_CCAPP, - CC_SRC_MAX -} cc_srcs_t; - - -typedef enum cc_transfer_mode_e_ { - CC_XFR_MODE_MIN = -1, - CC_XFR_MODE_NONE, - CC_XFR_MODE_TRANSFEROR, - CC_XFR_MODE_TRANSFEREE, - CC_XFR_MODE_TARGET, - CC_XFR_MODE_MAX -} cc_transfer_mode_e; - -typedef enum cc_regmgr_rsp_type_e_ { - CC_FAILOVER_RSP=0, - CC_RSP_START =1, - CC_RSP_COMPLETE=2 -} cc_regmgr_rsp_type_e; - -typedef enum cc_regmgr_rsp_e_ { - CC_REG_FAILOVER_RSP, - CC_REG_FALLBACK_RSP -} cc_regmgr_rsp_e; - -/* - * Identifies what was in the Alert-Info header - */ -typedef enum { - ALERTING_NONE, /* No alert-info header present */ - ALERTING_OLD, /* Unrecognized pattern or an error, mimic old behavior */ - ALERTING_TONE, /* Play tone */ - ALERTING_RING /* Play ringing pattern */ -} cc_alerting_type; - -typedef enum { - CC_MONITOR_NONE = 0, - CC_MONITOR_SILENT = 1, - CC_MONITOR_COACHING = 2 -} monitor_mode_t; - -typedef enum { - CFWDALL_NONE = -1, - CFWDALL_CLEAR, - CFWDALL_SET -} cfwdall_mode_t; - -/* Do not change enum values unless remote-cc xml has been changed */ - -typedef enum { - CC_RING_DEFAULT = 0, - CC_RING_ENABLE = 1, - CC_RING_DISABLE = 2 -} cc_rcc_ring_mode_e; - -/* Do not change enum values unless remote-cc xml has been changed */ - -typedef enum { - CC_SK_EVT_TYPE_DEF = 0, - CC_SK_EVT_TYPE_EXPLI = CC_SK_EVT_TYPE_DEF, - CC_SK_EVT_TYPE_IMPLI = 1 -} cc_rcc_skey_evt_type_e; - -/* media name with media capability table */ -typedef enum { - CC_AUDIO_1, - CC_VIDEO_1, - CC_DATACHANNEL_1, -} cc_media_cap_name; - -typedef struct cc_sdp_addr_t_ { - cpr_ip_addr_t addr; - unsigned int port; -} cc_sdp_addr_t; - -typedef struct cc_sdp_data_t_ { - cc_sdp_addr_t addr; - int media_types[CC_MAX_MEDIA_TYPES]; - int32_t avt_payload_type; -} cc_sdp_data_t; - -typedef struct cc_sdp_t_ { - sdp_t *src_sdp; /* pointer to source SDP */ - sdp_t *dest_sdp; /* pointer to received SDP */ -} cc_sdp_t; - -typedef enum -{ - cc_disposition_unknown = 0, - cc_disposition_render, - cc_disposition_session, - cc_dispostion_icon, - cc_disposition_alert, - cc_disposition_precondition -} cc_disposition_type_t; - -typedef struct -{ - cc_disposition_type_t disposition; - boolean required_handling; -} cc_content_disposition_t; - -typedef enum -{ - cc_content_type_unknown = 0, - cc_content_type_SDP, - cc_content_type_sipfrag, - cc_content_type_CMXML -} cc_content_type_t; - -typedef struct cc_msgbody_t_ { - cc_content_type_t content_type; - cc_content_disposition_t content_disposition; - uint32_t body_length; - char *body; - char *content_id; -} cc_msgbody_t; - -typedef struct cc_msgbody_info_t_ { - uint32_t num_parts; /* number of body parts */ - cc_content_type_t content_type; /* top level content type */ - cc_msgbody_t parts[CC_MAX_BODY_PARTS]; /* parts */ -} cc_msgbody_info_t; - -/* - * Message definitions - */ - -typedef enum cc_redirect_reasons_t { - CC_REDIRECT_REASON_MIN = -1, - CC_REDIRECT_REASON_NONE, - CC_REDIRECT_REASON_BUSY, - CC_REDIRECT_REASON_NOANSWER, - CC_REDIRECT_REASON_UNCONDITIONAL, - CC_REDIRECT_REASON_DEFLECTION, - CC_REDIRECT_REASON_UNAVAILABLE -} cc_redirect_reasons_t; - -typedef struct cc_redirect_t_ { - int count; - struct { - char number[CC_MAX_DIALSTRING_LEN]; - cc_redirect_reasons_t redirect_reason; - } redirects[CC_MAX_REDIRECTS]; -} cc_redirect_t; - -typedef enum { - CC_FEAT_NONE, - CC_FEAT_HOLD, - CC_FEAT_RESUME, - CC_FEAT_BARGE, - CC_FEAT_CBARGE, - CC_FEAT_REPLACE, - CC_FEAT_CALLINFO, - CC_FEAT_INIT_CALL, - CC_FEAT_MONITOR, - CC_FEAT_TOGGLE_TO_SILENT_MONITORING, - CC_FEAT_TOGGLE_TO_WHISPER_COACHING -} cc_call_info_e; - -typedef enum { - CC_REASON_NONE, - CC_REASON_XFER, - CC_REASON_CONF, - CC_REASON_SWAP, - CC_REASON_RCC, - CC_REASON_INTERNAL, - CC_REASON_MONITOR_UPDATE -} cc_hold_resume_reason_e; - -typedef enum { - CC_PURPOSE_NONE, - CC_PURPOSE_INFO, - CC_PURPOSE_ICON, - CC_PURPOSE_CARD -} cc_purpose_e; - -typedef enum { - CC_ORIENTATION_NONE = CC_CALL_TYPE_NONE, - CC_ORIENTATION_FROM = CC_CALL_TYPE_INCOMING, - CC_ORIENTATION_TO = CC_CALL_TYPE_OUTGOING -} cc_orientation_e; - -typedef enum { - CC_UI_STATE_NONE, - CC_UI_STATE_RINGOUT, - CC_UI_STATE_CONNECTED, - CC_UI_STATE_BUSY -} cc_ui_state_e; - -typedef enum { - CC_REASON_NULL, - CC_REASON_ACTIVECALL_LIST -} cc_onhook_reason_e; - -typedef enum { - CC_CALL_LOG_DISP_MISSED, - CC_CALL_LOG_DISP_RCVD, - CC_CALL_LOG_DISP_PLACED, - CC_CALL_LOG_DISP_UNKNWN, - CC_CALL_LOG_DISP_IGNORE -} cc_call_logdisp_e; - -/* - * The cc_caller_id_t structure contains caller IDs fields. - * Sending these fields accross components needs special care. - * There are CCAPI API that provide access or transport these fields - * by the source or by the destination. Any new caller IDs added, - * please update the APIs in ccapi.c to support the new fields. - * See cc_cp_caller(), cc_mv_caller_id() and cc_free_caller_id() functions. - */ -// mostly overlap with sessionTypes.h:cc_callinfo_t -typedef struct cc_caller_id_t_ { - string_t calling_name; - string_t calling_number; - string_t alt_calling_number; - boolean display_calling_number; - string_t called_name; - string_t called_number; - boolean display_called_number; - string_t orig_called_name; - string_t orig_called_number; - string_t last_redirect_name; - string_t last_redirect_number; - string_t orig_rpid_number; - cc_call_type_e call_type; - uint16_t call_instance_id; -} cc_caller_id_t; - -/* - * The followings are definitions of bits in the feature_flag of the - * cc_feature_data_call_info_t strucure. - * - * The CC_DELAY_UI_UPDATE flag is not related to call information but - * it indicates that the call info event signaled by SIP stack - * to GSM that UI update can be delayed due to media manipulation - * event will follow. This allows GSM to defer UI update to after the - * media manipulation event. - */ -#define CC_SECURITY 1 -#define CC_ORIENTATION (1<<1) -#define CC_UI_STATE (1<<2) -#define CC_CALLER_ID (1<<3) -#define CC_CALL_INSTANCE (1<<4) -#define CC_DELAY_UI_UPDATE (1<<5) -#define CC_POLICY (1<<6) - -typedef struct cc_feature_data_call_info_t_{ - uint16_t feature_flag; - cc_security_e security; - cc_policy_e policy; - cc_orientation_e orientation; - cc_ui_state_e ui_state; - cc_caller_id_t caller_id; - cc_call_priority_e priority; - boolean swap; //Indicate if hold/resume is because of swap - boolean protect; //indicate if the call has to be protected - boolean dusting; //indicate if it is a dusting call - uint32_t callref; - char global_call_id[CC_GCID_LEN]; -} cc_feature_data_call_info_t; - -typedef struct cc_replace_info_t_ { - callid_t remote_call_id; /* remote call ID to replace */ -} cc_replace_info_t; - -typedef struct cc_join_info_t_ { - callid_t join_call_id; -} cc_join_info_t; - -typedef struct cc_initcall_t { - char gcid[CC_GCID_LEN]; // Global call id used for CTI - monitor_mode_t monitor_mode; -} cc_initcall_t; - -typedef union { - cc_initcall_t initcall; - cc_hold_resume_reason_e hold_resume_reason; - cc_feature_data_call_info_t call_info_feat_data; - cc_purpose_e purpose; // Used for Barge, CBARGE - cc_replace_info_t replace; - cc_join_info_t join; -} cc_call_info_data_t; - -typedef struct { - cc_call_info_data_t data; - cc_call_info_e type; -} cc_call_info_t; - -typedef enum cc_xfer_methods_t_ { - CC_XFER_METHOD_MIN = -1, - CC_XFER_METHOD_NONE, - CC_XFER_METHOD_BYE, - CC_XFER_METHOD_REFER, - CC_XFER_METHOD_DIRXFR, - CC_RCC_METHOD_REFER, - CC_XFER_METHOD_MAX -} cc_xfer_methods_t; - -typedef enum cc_subscriptions_t_ { - CC_SUBSCRIPTIONS_MIN = -1, - CC_SUBSCRIPTIONS_NONE, - CC_SUBSCRIPTIONS_XFER, - CC_SUBSCRIPTIONS_DIALOG = CC_SUBSCRIPTIONS_DIALOG_EXT, - CC_SUBSCRIPTIONS_CONFIG, - CC_SUBSCRIPTIONS_KPML = CC_SUBSCRIPTIONS_KPML_EXT, - CC_SUBSCRIPTIONS_PRESENCE = CC_SUBSCRIPTIONS_PRESENCE_EXT, - CC_SUBSCRIPTIONS_REMOTECC = CC_SUBSCRIPTIONS_REMOTECC_EXT, - CC_SUBSCRIPTIONS_REMOTECC_OPTIONSIND = CC_SUBSCRIPTIONS_REMOTECC_OPTIONSIND_EXT, - CC_SUBSCRIPTIONS_CONFIGAPP = CC_SUBSCRIPTIONS_CONFIGAPP_EXT, - CC_SUBSCRIPTIONS_MEDIA_INFO = CC_SUBSCRIPTIONS_MEDIA_INFO_EXT, - CC_SUBSCRIPTIONS_MAX -} cc_subscriptions_t; - -typedef struct cc_feature_data_newcall_t_ { - char dialstring[CC_MAX_DIALSTRING_LEN]; - cc_causes_t cause; - cc_redirect_t redirect; - cc_replace_info_t replace; - cc_join_info_t join; - char global_call_id[CC_GCID_LEN]; - callid_t prim_call_id; /* For internal new call event - * refer primary call's call_id - */ - cc_hold_resume_reason_e hold_resume_reason; /* Reason for new consult call */ -} cc_feature_data_newcall_t; - -typedef struct cc_feature_data_xfer_t_ { - cc_causes_t cause; - char dialstring[CC_MAX_DIALSTRING_LEN]; - char referred_by[CC_MAX_DIALSTRING_LEN]; - cc_xfer_methods_t method; - callid_t target_call_id; - char global_call_id[CC_GCID_LEN]; -} cc_feature_data_xfer_t; - -typedef enum cc_app_type_t_ { - CC_APP_MIN = -1, - CC_APP_NONE, - CC_APP_CMXML, - CC_APP_REMOTECC, - CC_APP_MAX -} cc_app_type_t; - -typedef struct cc_refer_body_t_ { - struct cc_refer_body_t_ *next; - char refer_body[200]; - int refer_body_len; - cc_app_type_t app_type; -} cc_refer_body_t; - -typedef struct cc_feature_data_ind_t__ { - cc_causes_t cause; - char to[CC_MAX_DIALSTRING_LEN]; - char referred_by[CC_MAX_DIALSTRING_LEN]; - char referred_to[CC_MAX_DIALSTRING_LEN]; - cc_refer_body_t refer_body; -} cc_feature_data_ind_t; - -typedef struct cc_feature_data_endcall_t_ { - cc_causes_t cause; - char dialstring[CC_MAX_DIALSTRING_LEN]; -} cc_feature_data_endcall_t; - -typedef struct cc_kfact_t { - char rxstats[CC_KFACTOR_STAT_LEN]; - char txstats[CC_KFACTOR_STAT_LEN]; -} cc_kfact_t; - -typedef struct cc_feature_data_hold_t_ { - cc_msgbody_info_t msg_body; - cc_call_info_t call_info; - cc_kfact_t kfactor; -} cc_feature_data_hold_t; - -typedef struct cc_feature_data_hold_reversion_t_ { - int alertInterval; -} cc_feature_data_hold_reversion_t; - -typedef struct cc_feature_data_resume_t_ { - cc_causes_t cause; - cc_msgbody_info_t msg_body; - cc_call_info_t call_info; - cc_kfact_t kfactor; -} cc_feature_data_resume_t; - -typedef struct cc_feature_data_redirect_t_ { - char redirect_number[CC_MAX_DIALSTRING_LEN]; - cc_redirect_t redirect; -} cc_feature_data_redirect_t; - -typedef struct cc_feature_data_subscribe_t_ { - cc_subscriptions_t event_package; - boolean subscribe; - char subscribe_uri[CC_MAX_DIALSTRING_LEN]; - cc_srcs_t component; - int component_id; - int *callBack; -} cc_feature_data_subscribe_t; - -typedef enum cc_dialog_lock_e_ { - CC_DIALOG_UNLOCKED, /* unlocked */ - CC_DIALOG_LOCKED /* local selected or locked */ -} cc_dialog_lock_e; - -typedef struct cc_notify_data_config_t { - boolean config_state; -} cc_notify_data_config_t; - -typedef struct cc_notify_data_kpml_t { - boolean kpml_state; -} cc_notify_data_kpml_t; - - -typedef struct cc_notify_data_rcc_t { - cc_features_t feature; - cc_select_state_e select; -} cc_notify_data_rcc_t; - - -typedef union cc_notify_data_t { - cc_notify_data_config_t config; - cc_notify_data_kpml_t kpml; - cc_notify_data_rcc_t rcc; -} cc_notify_data_t; - -typedef struct cc_feature_data_notify_t_ { - cc_subscriptions_t subscription; - cc_xfer_methods_t method; - cc_causes_t cause; - // The refer data above should have been in a cc_notify_data_refer_t - int cause_code; - callid_t blind_xferror_gsm_id; - boolean final; - cc_notify_data_t data; -} cc_feature_data_notify_t; - -typedef struct cc_feature_data_update_t_ { - cc_msgbody_info_t msg_body; -} cc_feature_data_update_t; - -typedef struct cc_feature_data_b2bcnf_t_ { - cc_causes_t cause; - callid_t call_id; - callid_t target_call_id; - char global_call_id[CC_GCID_LEN]; -} cc_feature_data_b2bcnf_t; - -typedef struct cc_feature_data_record_t_ { - boolean subref_flag; -} cc_feature_data_record_t; - -typedef struct cc_feature_data_select_t_ { - boolean select; /* TRUE when select, FALSE when unselect */ -} cc_feature_data_select_t; - -typedef struct cc_feature_data_b2b_join_t_ { - callid_t b2bjoin_callid; - callid_t b2bjoin_joincallid; -} cc_feature_data_b2b_join_t; - - -typedef struct cc_media_cap_t_ { - cc_media_cap_name name; /* media channel name designator */ - sdp_media_e type; /* media type: audio, video etc */ - boolean enabled; /* this media is enabled or disabled */ - boolean support_security; /* security is supported */ - sdp_direction_e support_direction;/* supported direction */ - cc_media_stream_id_t pc_stream; /* The media stream in the PC */ - cc_media_track_id_t pc_track; /* The track ID in the media stream */ -} cc_media_cap_t; - -typedef struct cc_media_cap_table_t_ { - uint32_t id; - cc_media_cap_t cap[CC_MAX_MEDIA_CAP];/* capability table. */ -} cc_media_cap_table_t; - -typedef struct cc_media_track_t_ { - unsigned int media_stream_track_id; - boolean video; -} cc_media_track_t; - -typedef struct cc_media_remote_track_table_t_ { - uint32_t num_tracks; - uint32_t media_stream_id; - cc_media_track_t track[CC_MAX_TRACKS]; -} cc_media_remote_track_table_t; - -typedef struct cc_media_remote_stream_table_t_ { - cc_media_remote_track_table_t streams[CC_MAX_STREAMS]; -} cc_media_remote_stream_table_t; - -typedef struct cc_media_local_track_table_t_ { - uint32_t media_stream_id; - cc_media_track_t track[CC_MAX_TRACKS]; -} cc_media_local_track_table_t; - -typedef struct cc_feature_data_generic_t { - boolean subref_flag; - uint32_t eventid; -} cc_feature_data_generic_t; - -typedef struct cc_feature_data_cnf_t_ { - cc_causes_t cause; - callid_t call_id; - callid_t target_call_id; -} cc_feature_data_cnf_t; - -typedef struct cc_feature_data_cancel_t_ { - cc_rcc_skey_evt_type_e cause; - callid_t call_id; - callid_t target_call_id; -} cc_feature_data_cancel_t; - -typedef struct cc_feature_data_pc_t_ { - char pc_handle[PC_HANDLE_SIZE]; -} cc_feature_data_pc_t; - -typedef struct cc_feature_data_track_t_ { - cc_media_stream_id_t stream_id; - cc_media_track_id_t track_id; - cc_media_type_t media_type; -} cc_feature_data_track_t; - - -typedef struct cc_feature_candidate_t_ { - uint16_t level; - char candidate[CANDIDATE_SIZE]; - char mid[MID_SIZE]; -} cc_feature_candidate_t; - -typedef struct cc_feature_session_t_ { - unsigned int sessionid; - cc_boolean has_constraints; -} cc_feature_session_t; - - -typedef union cc_feature_data_t { - cc_feature_data_newcall_t newcall; - cc_feature_data_xfer_t xfer; - cc_feature_data_ind_t indication; - cc_feature_data_endcall_t endcall; - cc_feature_data_hold_t hold; - cc_feature_data_hold_reversion_t hold_reversion; - cc_feature_data_resume_t resume; - cc_feature_data_redirect_t redirect; - cc_feature_data_subscribe_t subscribe; - cc_feature_data_notify_t notify; - cc_feature_data_update_t update; - cc_feature_data_b2bcnf_t b2bconf; - cc_feature_data_call_info_t call_info; - cc_feature_data_record_t record; - cc_feature_data_select_t select; - cc_feature_data_b2b_join_t b2bjoin; - cc_feature_data_generic_t generic; - cc_feature_data_cnf_t cnf; - cc_feature_data_b2bcnf_t cancel; - cc_media_cap_t caps; - cc_feature_data_pc_t pc; - cc_feature_data_track_t track; - cc_feature_candidate_t candidate; - cc_feature_session_t session; -} cc_feature_data_t; - -typedef struct cc_setup_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_alerting_type alert_info; - vcm_ring_mode_t alerting_ring; - vcm_tones_t alerting_tone; - cc_caller_id_t caller_id; - cc_redirect_t redirect; - cc_call_info_t call_info; - boolean replaces; - string_t recv_info_list; - cc_msgbody_info_t msg_body; -} cc_setup_t; - -typedef struct cc_setup_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; - cc_msgbody_info_t msg_body; -} cc_setup_ack_t; - -typedef struct cc_proceeding_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; -} cc_proceeding_t; - -typedef struct cc_alerting_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; - cc_msgbody_info_t msg_body; - boolean inband; -} cc_alerting_t; - -typedef struct cc_connected_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; - string_t recv_info_list; - cc_msgbody_info_t msg_body; -} cc_connected_t; - -typedef struct cc_connected_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_caller_id_t caller_id; - cc_msgbody_info_t msg_body; -} cc_connected_ack_t; - -typedef struct cc_release_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_causes_t cause; - char dialstring[CC_MAX_DIALSTRING_LEN]; - cc_kfact_t kfactor; -} cc_release_t; - -typedef struct cc_release_complete_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_causes_t cause; - cc_kfact_t kfactor; -} cc_release_complete_t; - -typedef struct cc_feature_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_features_t feature_id; - cc_feature_data_t data; - boolean data_valid; - cc_jsep_action_t action; - char sdp[SDP_SIZE]; -} cc_feature_t; - -typedef struct cc_feature_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_features_t feature_id; - cc_feature_data_t data; - boolean data_valid; - cc_causes_t cause; -} cc_feature_ack_t; - -typedef struct cc_offhook_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - char global_call_id[CC_GCID_LEN]; - callid_t prim_call_id; /* For internal new call event - * refer primary call's call_id - */ - cc_hold_resume_reason_e hold_resume_reason; /* Reason for new consult call */ - monitor_mode_t monitor_mode; - cfwdall_mode_t cfwdall_mode; -} cc_offhook_t; - -typedef struct cc_onhook_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - boolean softkey; - callid_t prim_call_id; /* For internal new call event - * refer primary call's call_id - */ - cc_hold_resume_reason_e hold_resume_reason; /* Reason for new consult call */ - cc_onhook_reason_e active_list; /* onhook is because of active call - * press - */ -} cc_onhook_t; - -typedef struct cc_line_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; -} cc_line_t; - -typedef struct cc_digit_begin_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - int digit; -} cc_digit_begin_t; - -typedef struct cc_digit_end_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - int digit; -} cc_digit_end_t; - -typedef struct cc_dialstring_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - char dialstring[CC_MAX_DIALSTRING_LEN]; - char g_call_id[CC_GCID_LEN]; - monitor_mode_t monitor_mode; -} cc_dialstring_t; - -// mostly overlap with sessionTypes.h:cc_mwi_status_t -typedef struct cc_action_data_mwi_ { - boolean on; - int type; - int newCount; - int oldCount; - int hpNewCount; - int hpOldCount; -} cc_action_data_mwi_t; - -typedef struct cc_mwi_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_action_data_mwi_t msgSummary; -} cc_mwi_t; - -typedef struct cc_options_sdp_req_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - void * pMessage; -} cc_options_sdp_req_t; - -typedef struct cc_options_sdp_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - void * pMessage; - cc_msgbody_info_t msg_body; -} cc_options_sdp_ack_t; - -typedef struct cc_audit_sdp_req_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - boolean apply_ringout; -} cc_audit_sdp_req_t; - -typedef struct cc_audit_sdp_ack_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - callid_t call_id; - line_t line; - cc_msgbody_info_t msg_body; -} cc_audit_sdp_ack_t; - -typedef struct cc_feature_tmr_t_ { - callid_t call_id; - line_t line; - cc_features_t feature_id; -} cc_feature_tmr_t; - -typedef struct cc_regmgr_t_ { - cc_msgs_t msg_id; - cc_srcs_t src_id; - int rsp_type; - cc_regmgr_rsp_e rsp_id; - boolean wait_flag; -} cc_regmgr_t; - -// mostly overlap with sessionTypes.h:session_send_info_t -typedef struct cc_info_t { - cc_msgs_t msg_id; - cc_srcs_t not_used; // why not share a common struct?? why cast everything to cc_setup_t?? - callid_t call_id; - line_t line; - string_t info_package; - string_t content_type; - string_t message_body; -} cc_info_t; - -typedef struct cc_msg_t_ { - union { - cc_setup_t setup; - cc_setup_ack_t setup_ack; - cc_proceeding_t proceeding; - cc_alerting_t alerting; - cc_connected_t connected; - cc_connected_ack_t connected_ack; - cc_release_t release; - cc_release_complete_t release_complete; - cc_feature_t feature; - cc_feature_ack_t feature_ack; - cc_offhook_t offhook; - cc_onhook_t onhook; - cc_line_t line; - cc_digit_begin_t digit_begin; - cc_digit_end_t digit_end; - cc_dialstring_t dialstring; - cc_mwi_t mwi; - cc_options_sdp_ack_t options_ack; - cc_audit_sdp_ack_t audit_ack; - cc_info_t info; - } msg; -} cc_msg_t; - - -callid_t cc_get_new_call_id(void); -const char *cc_msg_name(cc_msgs_t id); -const char *cc_src_name(cc_srcs_t id); -const char *cc_cause_name(cc_causes_t id); -const char *cc_feature_name(cc_features_t id); - -void cc_int_setup(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_alerting_type alert_info, vcm_ring_mode_t alerting_ring, - vcm_tones_t alerting_tone, cc_redirect_t *redirect, - cc_call_info_t *call_info_p, boolean replaces, - string_t recv_info_list, cc_msgbody_info_t *msg_body); - -void cc_int_setup_ack(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body); - -void cc_int_proceeding(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id); - -void cc_int_alerting(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body, boolean inband); - -void cc_int_connected(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - string_t recv_info_list, cc_msgbody_info_t *msg_body); - -void cc_int_connected_ack(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_caller_id_t *caller_id, - cc_msgbody_info_t *msg_body); - -void cc_int_release(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_causes_t cause, const char *dialstring, - cc_kfact_t *kfactor); - -void cc_int_release_complete(cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, cc_causes_t cause, - cc_kfact_t *kfactor); - -void cc_int_feature2(cc_msgs_t msg_id, cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, cc_features_t feature_id, - cc_feature_data_t *data); - -void cc_createoffer(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_features_t feature_id, cc_feature_data_t *data); - -void cc_createanswer (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_features_t feature_id, string_t sdp, cc_feature_data_t *data); - -void cc_setlocaldesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - cc_features_t feature_id, cc_jsep_action_t action, string_t sdp, cc_feature_data_t *data); - -void cc_setremotedesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - cc_features_t feature_id, cc_jsep_action_t action, string_t sdp, cc_feature_data_t *data); - -void cc_localdesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - cc_features_t feature_id, cc_feature_data_t *data); - -void cc_remotedesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line, - cc_features_t feature_id, cc_feature_data_t *data); - -void cc_int_feature_ack(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_features_t feature_id, - cc_feature_data_t *data, cc_causes_t cause); - -void cc_int_offhook(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, callid_t call_id, - line_t line, char *global_call_id, - monitor_mode_t monitor_mode, - cfwdall_mode_t cfwdall_mode); - -void cc_int_onhook(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id, - cc_hold_resume_reason_e consult_reason, callid_t call_id, - line_t line, boolean softkey, cc_onhook_reason_e active_list); - -void cc_int_line(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line); - -void cc_int_digit_begin(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, int digit); - -void cc_int_digit_end(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, int digit); - -void cc_int_dialstring(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, const char *dialstring, - const char *g_call_id, monitor_mode_t monitor_mode); - -void cc_int_mwi(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, boolean on, int type, int newCount, - int oldCount, int hpNewCount, int hpOldCount); - -void cc_int_options_sdp_req(cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, void *pMessage); - -void cc_int_options_sdp_ack(cc_srcs_t src_id, cc_srcs_t dst_id, - callid_t call_id, line_t line, void *pMessage, - cc_msgbody_info_t *msg_body); - -void cc_int_audit_sdp_req(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, boolean apply_ringout); - -void cc_int_audit_sdp_ack(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, cc_msgbody_info_t *msg_body); - -void cc_int_info(cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, - line_t line, string_t info_package, string_t content_type, - string_t message_body); - -void cc_int_fail_fallback(cc_srcs_t src_id, cc_srcs_t dst_id, int rsp_type, - cc_regmgr_rsp_e rsp_id, boolean waited); -#define cc_fail_fallback_sip(a, b, c, d) cc_int_fail_fallback(a, CC_SRC_SIP, b, c, d) -#define cc_fail_fallback_gsm(a, b, c) cc_int_fail_fallback(a, CC_SRC_GSM, b, c, FALSE) - -#define cc_setup(a, b, c, d, e, f, g, h, i, j, k, l) cc_int_setup(a, CC_SRC_GSM, b, c, d, e, f, g, h, i, j, k, l) -#define cc_setup_ack(a, b, c, d, e) \ - cc_int_setup_ack(a, CC_SRC_GSM, b, c, d, e) -#define cc_proceeding(a, b, c, d) cc_int_proceeding(a, CC_SRC_GSM, b, c, d) -#define cc_alerting(a, b, c, d, e, f) \ - cc_int_alerting(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_connected(a, b, c, d, e, f) \ - cc_int_connected(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_connected_ack(a, b, c, d, e) \ - cc_int_connected_ack(a, CC_SRC_GSM, b, c, d, e) -#define cc_release(a, b, c, d, e, f) cc_int_release(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_release_complete(a, b, c, d, e) \ - cc_int_release_complete(a, CC_SRC_GSM, b, c, d, e) -#define cc_feature(a, b, c, d, e) cc_int_feature2(CC_MSG_FEATURE, a, CC_SRC_GSM, b, c, d, e) -#define cc_int_feature(a, b, c, d, e, f) cc_int_feature2(CC_MSG_FEATURE, a, b, c, d, e, f) -#define cc_feature_ack(a, b, c, d, e, f) \ - cc_int_feature_ack(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_offhook(a, b, c) cc_int_offhook(a, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, b, c, NULL, CC_MONITOR_NONE,CFWDALL_NONE) -#define cc_offhook_ext(a, b, c, d, e) cc_int_offhook(a, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, b, c, d, e,CFWDALL_NONE) -#define cc_onhook(a, b, c, d) cc_int_onhook(a, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, b, c, d, CC_REASON_NULL) -#define cc_onhook_ext(a, b, c, d, e) cc_int_onhook(a, CC_SRC_GSM, CC_NO_CALL_ID, CC_REASON_NONE, b, c, d, e) -#define cc_line(a, b, c) cc_int_line(a, CC_SRC_GSM, b, c) -#define cc_digit_begin(a, b, c, d) cc_int_digit_begin(a, CC_SRC_GSM, b, c, d) -#define cc_dialstring(a, b, c, d) cc_int_dialstring(a, CC_SRC_GSM, b, c, d, NULL, CC_MONITOR_NONE) -#define cc_dialstring_ext(a, b, c, d, e, f) cc_int_dialstring(a, CC_SRC_GSM, b, c, d, e, f) -#define cc_mwi(a, b, c, d, e, f, g, h, i) cc_int_mwi(a, CC_SRC_GSM, b, c, d, e, f, g, h, i ) -#define cc_options_sdp_req(a, b, c, d) cc_int_options_sdp_req(a, CC_SRC_GSM, b, c, d) -#define cc_audit_sdp_req(a, b, c, d) cc_int_audit_sdp_req(a, CC_SRC_GSM, b, c, d) - -typedef enum cc_types_t_ { - CC_TYPE_INVALID, - CC_TYPE_CCM, - CC_TYPE_OTHER -} cc_types_t; - -typedef enum cc_states_t_ { - CC_STATE_MIN = -1, - CC_STATE_OFFHOOK, - CC_STATE_DIALING, - CC_STATE_DIALING_COMPLETED, - CC_STATE_CALL_SENT, - CC_STATE_FAR_END_PROCEEDING, - CC_STATE_FAR_END_ALERTING, - CC_STATE_CALL_RECEIVED, - CC_STATE_ALERTING, - CC_STATE_ANSWERED, - CC_STATE_CONNECTED, - CC_STATE_HOLD, - CC_STATE_RESUME, - CC_STATE_ONHOOK, - CC_STATE_CALL_FAILED, - CC_STATE_HOLD_REVERT, - CC_STATE_UNKNOWN, - CC_STATE_MAX -} cc_states_t; - -/* Update cc_action_names structure in lsm.c with the - * corresponding change for the following structure. - */ -typedef enum cc_actions_t_ { - CC_ACTION_MIN = -1, - CC_ACTION_SPEAKER, - CC_ACTION_DIAL_MODE, - CC_ACTION_MWI, - CC_ACTION_MWI_LAMP_ONLY, - CC_ACTION_OPEN_RCV, - CC_ACTION_UPDATE_UI, - CC_ACTION_MEDIA, - CC_ACTION_RINGER, - CC_ACTION_SET_LINE_RINGER, - CC_ACTION_PLAY_TONE, - CC_ACTION_STOP_TONE, - CC_ACTION_STOP_MEDIA, - CC_ACTION_START_RCV, - CC_ACTION_ANSWER_PENDING, - CC_ACTION_PLAY_BLF_ALERTING_TONE, - CC_ACTION_MAX -} cc_actions_t; - -typedef enum cc_services_t_ { - CC_SERVICE_MIN = -1, - CC_SERVICE_MAX -} cc_services_t; - -typedef enum cc_update_ui_actions_t_ { - CC_UPDATE_MIN = -1, - CC_UPDATE_CONF_ACTIVE, - CC_UPDATE_CONF_RELEASE, - CC_UPDATE_XFER_PRIMARY, - CC_UPDATE_CALLER_INFO, - CC_UPDATE_SECURITY_STATUS, - CC_UPDATE_SET_CALL_STATUS, - CC_UPDATE_CLEAR_CALL_STATUS, - CC_UPDATE_SET_NOTIFICATION, - CC_UPDATE_CLEAR_NOTIFICATION, - CC_UPDATE_CALL_PRESERVATION, - CC_UPDATE_CALL_CONNECTED, - CC_UPDATE_MAX -} cc_update_ui_actions_t; - -typedef struct cc_state_data_offhook_t_ { - cc_caller_id_t caller_id; - int dial_mode; -} cc_state_data_offhook_t; - -/* - * This structure is passed in CC_STATE_DIALING to lsm to indicate - * wether a dialtone needs to be played or not - * should the stutter dial tone be suppressed or not - */ -typedef struct cc_state_data_dialing_t_ { - boolean play_dt; - boolean suppress_stutter; -} cc_state_data_dialing_t; - -typedef struct cc_state_data_dialing_completedt_ { - cc_caller_id_t caller_id; -} cc_state_data_dialing_completed_t; - -typedef struct cc_state_data_call_sent_t_ { - cc_caller_id_t caller_id; -} cc_state_data_call_sent_t; - -typedef struct cc_state_data_far_end_proceeding_t_ { - cc_caller_id_t caller_id; -} cc_state_data_far_end_proceeding_t; - -typedef struct cc_state_data_far_end_alerting_t_ { - cc_caller_id_t caller_id; -} cc_state_data_far_end_alerting_t; - -typedef struct cc_state_data_call_received_t_ { - cc_caller_id_t caller_id; -} cc_state_data_call_received_t; - -typedef struct cc_state_data_alerting_t_ { - cc_caller_id_t caller_id; -} cc_state_data_alerting_t; - -typedef struct cc_state_data_answered_t_ { - cc_caller_id_t caller_id; -} cc_state_data_answered_t; - -typedef struct cc_state_data_connected_t_ { - cc_caller_id_t caller_id; -} cc_state_data_connected_t; - -typedef struct cc_state_data_hold_t_ { - cc_caller_id_t caller_id; - boolean local; - cc_hold_resume_reason_e reason; -} cc_state_data_hold_t; - -typedef struct cc_state_data_resume_t_ { - cc_caller_id_t caller_id; - boolean local; -} cc_state_data_resume_t; - -typedef struct cc_state_data_onhook_t_ { - cc_caller_id_t caller_id; - boolean local; - cc_causes_t cause; -} cc_state_data_onhook_t; - -typedef struct cc_state_data_call_failed_t_ { - cc_caller_id_t caller_id; - cc_causes_t cause; -} cc_state_data_call_failed_t; - -typedef union cc_state_data_t_ { - cc_state_data_offhook_t offhook; - cc_state_data_dialing_t dialing; - cc_state_data_dialing_completed_t dialing_completed; - cc_state_data_call_sent_t call_sent; - cc_state_data_far_end_proceeding_t far_end_proceeding; - cc_state_data_far_end_alerting_t far_end_alerting; - cc_state_data_call_received_t call_received; - cc_state_data_alerting_t alerting; - cc_state_data_answered_t answered; - cc_state_data_connected_t connected; - cc_state_data_hold_t hold; - cc_state_data_resume_t resume; - cc_state_data_onhook_t onhook; - cc_state_data_call_failed_t call_failed; -} cc_state_data_t; - -typedef struct cc_action_data_digit_begin_ { - int tone; -} cc_action_data_digit_begin_t; - -typedef struct cc_action_data_tone_ { - vcm_tones_t tone; -} cc_action_data_tone_t; - -typedef struct cc_action_data_speaker_ { - boolean on; -} cc_action_data_speaker_t; - -typedef struct cc_action_data_dial_mode_ { - int mode; - int digit_cnt; -} cc_action_data_dial_mode_t; - -/* -typedef struct cc_action_data_mwi_ { - boolean on; - int32_t type; - int32_t newCount; - int32_t oldCount; - int32_t hpNewCount; - int32_t hpOldCount; -} cc_action_data_mwi_t; -*/ - -typedef struct cc_action_data_open_rcv_ { - boolean is_multicast; - cpr_ip_addr_t listen_ip; - uint16_t port; - boolean rcv_chan; - boolean keep; - media_refid_t media_refid; /* the ID of the media to reference to */ - sdp_media_e media_type; -} cc_action_data_open_rcv_t; - -typedef struct cc_set_call_status_data_ { - char *phrase_str_p; - int timeout; - callid_t call_id; - line_t line; -} cc_set_call_status_data_t; - -typedef struct cc_clear_call_status_data_ { - callid_t call_id; - line_t line; -} cc_clear_call_status_data_t; - -// mostly overlap with sessionTypes.h:cc_notification_data_t -typedef struct cc_set_notification_data_ { - char *phrase_str_p; - unsigned long timeout; - unsigned long priority; -} cc_set_notification_data_t; - -typedef union cc_update_ui_data_ { - cc_feature_data_call_info_t caller_info; - cc_set_call_status_data_t set_call_status_parms; - cc_clear_call_status_data_t clear_call_status_parms; - cc_set_notification_data_t set_notification_parms; - string_t security_status; -} cc_update_ui_data_t; - -typedef struct cc_action_data_update_ui_ { - cc_update_ui_actions_t action; - cc_update_ui_data_t data; -} cc_action_data_update_ui_t; - -typedef struct cc_action_data_ringer_ { - boolean on; -} cc_action_data_ringer_t; - -typedef struct cc_action_data_stop_media_ { - media_refid_t media_refid; /* the ID of the media to reference to */ -} cc_action_data_stop_media_t; - -typedef union cc_action_data_t_ { - cc_action_data_digit_begin_t digit_begin; - cc_action_data_tone_t tone; - cc_action_data_speaker_t speaker; - cc_action_data_dial_mode_t dial_mode; - cc_action_data_mwi_t mwi; - cc_action_data_open_rcv_t open_rcv; - cc_action_data_update_ui_t update_ui; - cc_action_data_ringer_t ringer; - cc_action_data_stop_media_t stop_media; -} cc_action_data_t; - -typedef struct cc_service_data_get_facility_by_line_ { - line_t line; -} cc_service_data_get_facility_by_line_t; - -typedef union cc_service_data_t_ { - cc_service_data_get_facility_by_line_t get_facility_by_line; -} cc_service_data_t; - - -typedef enum { - MEDIA_INTERFACE_UPDATE_NOT_REQUIRED, - MEDIA_INTERFACE_UPDATE_STARTED, - MEDIA_INTERFACE_UPDATE_IN_PROCESS -} dock_undock_event_t; - -extern dock_undock_event_t g_dock_undock_event; - -void cc_call_state(callid_t call_id, line_t line, cc_states_t state, - cc_state_data_t *data); -cc_rcs_t cc_call_action(callid_t call_id, line_t line, cc_actions_t action, - cc_action_data_t *data); -cc_rcs_t cc_call_service(callid_t call_id, line_t line, cc_services_t service, - cc_service_data_t *data); -void cc_call_attribute(callid_t call_id, line_t line, call_attr_t attr); -void cc_init(void); -void cc_free_msg_body_parts(cc_msgbody_info_t *msg_body); -void cc_free_msg_data(cc_msg_t *msg); -void cc_initialize_msg_body_parts_info(cc_msgbody_info_t *msg_body); -void cc_mv_msg_body_parts(cc_msgbody_info_t *dst_msg, - cc_msgbody_info_t *src_msg); -cc_rcs_t cc_cp_msg_body_parts(cc_msgbody_info_t *dst_msg, - cc_msgbody_info_t *src_msg); -void cc_mv_caller_id(cc_caller_id_t *dst_caller, cc_caller_id_t *src_caller); - //function that will be invoked by modules external to gsm: - -int cc_is_cnf_call(callid_t call_id); -cc_transfer_mode_e cc_is_xfr_call(callid_t call_id); - -extern cprBuffer_t cc_get_msg_buf(int min_size); -extern const char *cc_feature_name(cc_features_t id); -extern const char *cc_msg_name(cc_msgs_t id); -extern const char *cc_cause_name(cc_causes_t id); -extern void cc_media_update_native_video_support(boolean val); -extern void cc_media_update_video_cap(boolean val); -extern void cc_media_update_native_video_txcap(boolean val); -extern cc_boolean cc_media_isTxCapEnabled(); -extern cc_boolean cc_media_isVideoCapEnabled(); -extern void cc_media_setVideoAutoTxPref(cc_boolean txPref); -extern cc_boolean cc_media_getVideoAutoTxPref(); -#endif diff --git a/libs/sipcc/core/includes/check_sync.h b/libs/sipcc/core/includes/check_sync.h deleted file mode 100644 index c5dd8051df..0000000000 --- a/libs/sipcc/core/includes/check_sync.h +++ /dev/null @@ -1,46 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CHECK_SYNC_H -#define CHECK_SYNC_H - -#include "util_parse.h" - -typedef enum { - SYNCS_ANY, - SYNCS_GOT_VERSION, - SYNCS_GOT_VERSION_EQ, - SYNCS_GOT_SYNC, - SYNCS_GOT_SYNC_EQ, - SYNCS_GOT_GENERIC, - SYNCS_GOT_GENERIC_EQ -} sync_states; - -typedef enum { - SYNCF_NONE, - SYNCF_MY, - SYNCF_WILD -} SyncVersionFound_t; - -typedef struct { - char myVersion[MAX_LOAD_ID_STRING]; - char resetSync[MAX_SYNC_LEN]; - SyncVersionFound_t versionFound; -} VersionSync_t; - -#define SYNCINFO_XML "syncinfo.xml" -#define SYNC_BUF_SIZE 4096 - -extern int CheckSync; -extern int SyncInfoInProgress; -extern char *SyncBuffer; - -int check_sync_get(void); -void add_sync_info(char *version, char *sync, VersionSync_t *versionSync); -int parse_sync_entry(char **parseptr, VersionSync_t *versionSync); -int parse_sync_info(char *parseptr, VersionSync_t *versionSync); -void process_sync_info(char *syncInfo); -short handle_sync_message(short cmd, void *pData); - -#endif diff --git a/libs/sipcc/core/includes/ci.h b/libs/sipcc/core/includes/ci.h deleted file mode 100644 index e5d014cf4a..0000000000 --- a/libs/sipcc/core/includes/ci.h +++ /dev/null @@ -1,34 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CI_INCLUDED_H -#define _CI_INCLUDED_H - -#include "plat_api.h" -#include "plat_debug.h" - - -/* return codes for CI command processing */ -#define CI_OK (0) -#define CI_ERROR (1) -#define CI_INVALID (2) -#define CI_AMBIGUOUS (3) - -/* flags for CI processing */ -#define CI_PROMPT (0x0001) - -/* - * Prototypes for public functions - */ -void ci_init(); -int ci_process_input(const char *str, char *wkspace, int wklen); -int32_t ci_show_cmds(int32_t argc, const char *argv[]); -ci_callback ci_set_interceptor(ci_callback func); - -int ci_err_too_few(void); /* "Too few arguments" */ -int ci_err_too_many(void); /* "Too many arguments" */ -int ci_err_inv_arg(void); /* "Invalid argument" */ -uint32_t ci_streval(const char *str); - -#endif /* _CI_INCLUDED_H */ diff --git a/libs/sipcc/core/includes/config.h b/libs/sipcc/core/includes/config.h deleted file mode 100755 index bd149742dd..0000000000 --- a/libs/sipcc/core/includes/config.h +++ /dev/null @@ -1,195 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -#include "cpr_types.h" -#include "cpr_timers.h" -#include "cfgfile_utils.h" -#include "configmgr.h" -#include "prot_configmgr.h" -#include "phone.h" - -/* - * List of timers that the CFG task is responsible for. - * CPR will send a msg to the CFG task when these - * timers expire. CPR expects a timer id when the timer - * is created, this enum serves that purpose. - */ -typedef enum { - CFG_TFTP_RETRY_TIMER -} cfgTimerList_t; - -#define MAX_REQ_FIELDS 20 -#define MAX_FIELD_NAME_SIZE 30 -#define MAX_FIELD_VALUE_SIZE 30 -#define MAX_FIELDDESC_STR (MAX_FIELD_VALUE_SIZE+2) -#define MAX_TFTP_PATH_LEN 64 - -/* - * Definition of bits used in pDHCPInfo->extFields.ext.appStatus (32bits). - * Please note that some of these flags correspond to status flags - * asserted by Little App. Please see little_app.c, and make sure these - * flags are kept consistent. - */ - -#define APPSTATUS_UPGRADE_FAILED 0x80000000L - -/* maximum length of config file including comments */ -#define MAX_CFG_FILE_LENGTH 0x2000 - -/* minimum length of a registrion in seconds */ -#define MIN_REGISTRATION_PERIOD 20 - -#define BUF_TEST(); - -typedef enum { - ERASE_PROGRAM, - ERASE_ONLY, - PROGRAM_ONLY -} flash_mode_t; - -extern var_t prot_cfg_table[]; -extern cfg_rom_t *const prot_startup_config; -extern cfg_rom_t *const prot_running_config; -extern cfg_rom_t *const prot_temp_config; -extern int config_commit(int); -extern int prot_sanity_check_config_settings(void); -extern boolean prot_option_allowed_in_cfg_file(const char *); -extern void prot_shutdown(void); -extern int prot_config_change_notify(int); -extern void prot_disconnected(int); -extern int FlashaProgram(uint16_t *Source, uint16_t *Dest, uint32_t Size, - flash_mode_t mode); - -extern uint16_t g_NewVlan; -extern uint16_t g_NewRelease; -extern uint16_t g_NewErase; -extern char local_media_type_string[]; -extern char local_net_dev_type_string[]; - -void CFGTftpTimeout(int /*cpr_timer_t*/ *tmr); -int CFGProgramFlash(uint8_t *src, uint8_t *dst, uint32_t len); -int CFGEraseFlash(uint8_t *src, uint8_t *dst, uint32_t len); -int CFGEraseProgramFlash(uint8_t *src, uint8_t *dst, uint32_t len); -int CFGChksum(uint8_t *ptr, uint32_t len, uint32_t *csum, int dspmode, - int cmpmode); -int CFGGetUISettings(uint8_t *pData); -int CFGSetUISettings(void); -void CFGSetLockState(boolean); -boolean CFGIsLocked(void); -void cfg_set_running_config(void); -void cfg_get_stored_prot_settings(void); -void LoadTempConfigData(void); -void config_handle_cdp(int); -void cfg_sanity_check_media_range(void); -void cfg_check_la_appStatus(unsigned long appStatus); -void cfg_set_inhibitLoading(int yesno); -int cfg_get_inhibitLoading(void); - - -///////////////////////////////////////////////////////////// -// Configuration Variables replacing CUCM config file -// -//// -////// - -static const int gStartMediaPort = 16384; -static const int gStopMediaPort = 32766; -static const boolean gCallerIdBlocking = FALSE; -static const boolean gAnonblock = FALSE; -static const char gPreferredCodec[] = "none"; -static const char gDtmfOutOfBand[] = "avt"; -static const int gDtmfAvtPayload = 101; -static const int gDtmfDbLevel = 3; -static const int gSipRetx = 10; -static const int gSipInviteRetx = 6; -static const int gTimerT1 = 500; -static const int gTimerT2 = 4000; -static const int gTimerInviteExpires = 180; -static const int gTimerRegisterExpires = 3600; -static const boolean gRegisterWithProxy = TRUE; -static const char gBackupProxy[] = "USECALLMANAGER"; -static const int gBackupProxyPort = 5060; -static const char gEmergencyProxy[] = "USECALLMANAGER"; -static const int gEmergencyProxyPort = 5060; -static const char gOutboundProxy[] = "USECALLMANAGER"; -static const int gOutboundProxyPort = 5060; -static const boolean gNatRecievedProcessing = FALSE; -static const char gUserInfo[] = "None"; -static const boolean gRemotePartyID = TRUE; -static const boolean gSemiAttendedTransfer = TRUE; -static const int gCallHoldRingback = 2; -static const boolean gStutterMsgWaiting = FALSE; -static const char gCallForwardURI[] = "x-cisco-serviceuri-cfwdall"; -static const boolean gCallStats = TRUE; -static const int gTimerRegisterDelta = 5; -static const int gMaxRedirects = 70; -static const boolean gRfc2543Hold = FALSE; -static const boolean gLocalCfwdEnable = TRUE; -static const int gConnectionMonitorDuration = 120; -static const int gCallLogBlfEnabled = 3 & 0x1; -static const boolean gRetainForwardInformation = FALSE; -static const int gRemoteCcEnable = 1; -static const int gTimerKeepAliveExpires = 120; -static const int gTimerSubscribeExpires = 120; -static const int gTimerSubscribeDelta = 5; -static const int gKpml = 3; -static const boolean gNatEnabled = FALSE; -static const char gNatAddress[] = ""; -static const boolean gAnableVad = FALSE; -static const boolean gAutoAnswerAltBehavior = FALSE; -static const int gAutoAnswerTimer = 1; -static const boolean gAutoAnswerOverride = TRUE; -static const int gOffhookToFirstDigitTimer = 15000; -static const int gSilentPeriodBetweenCallWaitingBursts = 10; -static const int gRingSettingBusyStationPolicy = 0; -static const int gBlfAudibleAlertSettingOfIdleStation = 0; -static const int gBlfAudibleAlertSettingOfBusyStation = 0; -static const int gJoinAcrossLines = 0; -static const boolean gCnfJoinEnabled = TRUE; -static const int gRollover = 0; -static const boolean gTransferOnhookEnabled = FALSE; -static const int gDscpForAudio = 184; -static const int gDscpVideo = 136; -static const int gT302Timer = 5000; -static const int gLineIndex = 1; -static const int gFeatureID = 9; -static const char gProxy[] = "USECALLMANAGER"; -static const int gPort = 5060; -static const char gDisplayName[] = ""; -static const char gMessagesNumber[] = ""; -static const boolean gCallerName = TRUE; -static const boolean gCallerNumber = FALSE; -static const boolean gRedirectedNumber = FALSE; -static const boolean gDialedNumber = TRUE; -static const unsigned char gMessageWaitingLampPolicy = 3; -static const unsigned char gMessageWaitingAMWI = 1; -static const unsigned char gRingSettingIdle = 4; -static const unsigned char gRingSettingActive = 5; -static const int gMaxNumCalls = 1; -static const int gBusyTrigger = 1; -static const unsigned char gAutoAnswerEnabled = 2 & 0x1; -static const unsigned char gCallWaiting = 3 & 0x1; -static const int gDeviceSecurityMode = 1; -static const int gCcm2_sip_port = 5060; -static const int gCcm3_sip_port = 5060; -static const boolean gCcm1_isvalid = TRUE; -static const int gDscpCallControl = 1; -static const int gSpeakerEnabled = 1; -static const char gExternalNumberMask[] = ""; -static const char gVersion[] = "0.1"; -static const boolean gRTCPMUX = FALSE; -static const boolean gMAXAVBITRATE = FALSE; /* Following six are OPUS fmtp options */ -static const boolean gMAXCODEDAUDIOBW = FALSE; -static const boolean gUSEDTX = FALSE; -static const boolean gSTEREO = FALSE; -static const boolean gUSEINBANDFEC = FALSE; -static const boolean gCBR = FALSE; -static const boolean gMAXPTIME = FALSE; -static const int gSCTPPort = 5000; -static const int gNumDataStreams = 16; - -#endif /* _CONFIG_H_ */ diff --git a/libs/sipcc/core/includes/configapp.h b/libs/sipcc/core/includes/configapp.h deleted file mode 100644 index fae40922e5..0000000000 --- a/libs/sipcc/core/includes/configapp.h +++ /dev/null @@ -1,13 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CONFIGAPP_H -#define CONFIGAPP_H - -extern void configapp_init(); -extern void configapp_shutdown(); -extern void configapp_process_msg(uint32_t cmd, void *msg); - -#endif - diff --git a/libs/sipcc/core/includes/configmgr.h b/libs/sipcc/core/includes/configmgr.h deleted file mode 100755 index 3c0b4bee8a..0000000000 --- a/libs/sipcc/core/includes/configmgr.h +++ /dev/null @@ -1,62 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CONFIGMGR_H_ -#define _CONFIGMGR_H_ - -/* - * #defines for maximum length of the image names - * The MAX_LOAD_ID_LENGTH must be larger (or the same as) - * MAX_OLD_LOAD_ID_LENGTH or strange things may - * happen because they are used as indexes into - * arrays. - */ -#include "cpr_types.h" -#define MAX_LOAD_ID_LENGTH 60 -#define MAX_LOAD_ID_STRING MAX_LOAD_ID_LENGTH + 1 -#define MAX_OLD_LOAD_ID_LENGTH 8 -#define MAX_OLD_LOAD_ID_STRING MAX_OLD_LOAD_ID_LENGTH + 1 -#define MAX_URL_LENGTH 128 - -#define MAX_SYNC_LEN 33 -#define MAX_PHONE_LABEL 32 - -/* Start of section for new "protocol-inspecific" calls */ - -#define MAX_CONFIG_STRING_NAME 64 -#define DEFAULT_LINE 1 - -#define YESSTR "YES" -#define NOSTR "NO" -#define IPOFZEROS "0.0.0.0" - -enum ACTIONATTR { - AA_IGNORE = 0, - AA_COMMIT = 1, - AA_RELOAD = 1 << 1, - AA_REGISTER = 1 << 2, - AA_FORCE = 1 << 3, - AA_RESET = 1 << 4, - AA_SETTINGS = 1 << 5, - AA_BU_REG = 1 << 6 -}; - -/********************************************************* - * - * External Function Prototypes - * - *********************************************************/ -void config_get_string(int id, char *buffer, int buffer_len); -void config_set_string(int id, char *buffer); -void config_get_value(int id, void *buffer, int length); -void config_set_value(int id, void *buffer, int length); - -void config_get_line_string(int id, char *buffer, int line, int buffer_len); -void config_set_line_string(int id, char *buffer, int line); -void config_get_line_value(int id, void *buffer, int length, int line); -void config_set_line_value(int id, void *buffer, int length, int line); - -void config_init(void); - -#endif /* _CONFIGMGR_H_ */ diff --git a/libs/sipcc/core/includes/debug.h b/libs/sipcc/core/includes/debug.h deleted file mode 100644 index 19fd5e237b..0000000000 --- a/libs/sipcc/core/includes/debug.h +++ /dev/null @@ -1,108 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _DEBUG_INCLUDED_H /* allows multiple inclusion */ -#define _DEBUG_INCLUDED_H - -#include "cpr_types.h" -#include "plat_api.h" -#include "phone_debug.h" -#include "CSFLog.h" -#include - -typedef cc_int32_t (*debug_callback)(cc_int32_t argc, const char *argv[]); -typedef cc_int32_t (*show_callback)(cc_int32_t argc, const char *argv[]); -typedef cc_int32_t (*clear_callback)(cc_int32_t argc, const char *argv[]); - -typedef enum { - TEST_OPEN, - TEST_CLOSE, - TEST_KEY, - TEST_ONHOOK, - TEST_OFFHOOK, - TEST_SHOW, - TEST_HIDE, - TEST_PROFILE, - TEST_C3PO -} test_command_t; - - -typedef int32_t (*test_callback)(int32_t argc, const char *argv[], - test_command_t command); - -extern int32_t TestMode; -extern int32_t TestShow; - -typedef enum { - DEBUG_ENTRY_TYPE_FLAG, - DEBUG_ENTRY_TYPE_DEBUG_FUNC, - DEBUG_ENTRY_TYPE_SHOW_FUNC -} debug_entry_type_e; - -typedef struct { - const char *keyw; - union { - int32_t *flag; - debug_callback func; - show_callback show_func; - } u; - debug_entry_type_e type; - boolean show_tech; -} debug_entry_t; - -typedef struct { - const char *keyw; - union { - int32_t *flag; - clear_callback func; - } u; -} clear_entry_t; - -typedef struct { - const char *keyw; - const char *abrv; - const char *help; - boolean hidden; - union { - int32_t *flag; - test_callback func; - } u; - test_command_t command; -} test_entry_t; - - -typedef struct { - unsigned char flag; - unsigned char hookevent; - unsigned char keyevent; // keyevent and key will double as a timer value internally - unsigned char key; -} testevent_t; - -// The next 4 defines are used as flag values to specify the event types in the queue. -// Note that we cannot use the HOOKSCAN and KEYSCAN that are defined in phone.h, because -// HOOKSCAN requires a full integer. In order to minimize space in the test event queue -// we need short numbers. -#define TEST_NONE 0 -#define TEST_KEYSCAN 1 -#define TEST_HOOKSCAN 2 -#define TEST_TIMER 0x80 - - -#define MAX_DEBUG_NAME 50 -#define MAX_SHOW_NAME 50 -#define MAX_CLEAR_NAME 50 - -/* - * Prototypes for public functions - */ -void bind_test_keyword(const char *keyword, const char *abrv, boolean hidden, - test_callback func, test_command_t command, - const char *help); -testevent_t TESTGetEvent(void); - -// Send debug output to CSFLog -#define debugif_printf(format, ...) CSFLogDebug("debugif", format, ## __VA_ARGS__ ) -#define PR_ASSERT( test ) assert( test ) - -#endif /* _DEBUG_INCLUDED_H */ diff --git a/libs/sipcc/core/includes/dialplan.h b/libs/sipcc/core/includes/dialplan.h deleted file mode 100755 index ec1f93e610..0000000000 --- a/libs/sipcc/core/includes/dialplan.h +++ /dev/null @@ -1,111 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef DIALPLAN_H -#define DIALPLAN_H - -#include -#include "phone_types.h" - -#define DIALPLAN_MAX_SIZE 0x2000 -#define MAX_SUBTITUTIONS 5 -#define MAX_TONES 3 -#define MAX_TEMPLATE_LENGTH 196 -#define DIAL_ESCAPE '\\' -#define MAX_DIALSTRING 256 -#define DIAL_TIMEOUT 10 -#define MAX_DP_VERSION_STAMP_LEN (64+1) -extern char g_dp_version_stamp[MAX_DP_VERSION_STAMP_LEN]; - -typedef enum { - DIAL_NOMATCH = 0, - DIAL_GIVETONE, - DIAL_WILDPATTERN, - DIAL_FULLPATTERN, - DIAL_FULLMATCH, - DIAL_IMMEDIATELY -} DialMatchAction; - -/* Set enum values to match DialMatchAction */ -typedef enum { - DIALTONE_NOMATCH = 0, - DIALTONE_WILD = 2, - DIALTONE_FULL, - DIALTONE_EXACT -} DialToneMatch; - -typedef enum { - UserUnspec, - UserPhone, - UserIP -} UserMode; - -typedef enum { - RouteDefault, // Route using the default proxy - RouteEmergency, // Route using the emergency proxy - RouteFQDN // Route according to the FQDN in the entry -} RouteMode; - -struct DialTemplate { - struct DialTemplate *next; - char *pattern; - line_t line; - char *rewrite; - int timeout; - UserMode userMode; - RouteMode routeMode; - int tones_defined; - vcm_tones_t tone[MAX_TONES]; -}; - -struct StoredDialTemplate { - short size; // Size of header part of structure - short nextOffset; // total Number of bytes used in the entry - // A zero here is used as a last entry - int timeout; - line_t line; - UserMode userMode; - short pattern_offset; // Offset to the pattern string - short rewrite_offset; // Offset to the rewrite string - RouteMode routeMode; - int tones_defined; - vcm_tones_t tone[MAX_TONES]; - -}; - -typedef enum { - STATE_ANY, - STATE_GOT_MATCH, - STATE_GOT_MATCH_EQ, - STATE_GOT_LINE, - STATE_GOT_LINE_EQ, - STATE_GOT_TIMEOUT, - STATE_GOT_TIMEOUT_EQ, - STATE_GOT_USER, - STATE_GOT_USER_EQ, - STATE_GOT_REWRITE, - STATE_GOT_REWRITE_EQ, - STATE_GOT_ROUTE, - STATE_GOT_ROUTE_EQ, - STATE_GOT_TONE, - STATE_GOT_TONE_EQ, - STATE_START_TAG_COMPLETED, /* start tag parsing is complete when self-terminating () format is not used */ - STATE_END_TAG_STARTED, /* end tag started when we see ">3) -#define MILLISECONDS_TO_SAMPLES(PERIOD) ((PERIOD)<<3) - -#define MAX_TX_RTP_PORTS 2 -#define MAX_FRAMES_PER_PACKET 6 -#define MAX_VOICE_FRAME_SIZE 320 - -#define GSM_EFR_FRAME_SIZE 32 -#define GSM_FR_FRAME_SIZE 33 -#define G729_FRAME_SIZE 10 -#define G723_FRAME_SIZE63 24 -#define G723_FRAME_SIZE53 20 -#define G723_SID_FRAME_SIZE 4 -#define G729_SID_FRAME_SIZE 2 - -#define GSM_SAMPLES_PER_FRAME 160 -#define G729_SAMPLES_PER_FRAME 80 -#define G723_SAMPLES_PER_FRAME 240 -#define LINEAR_16KHZ_SAMPLES_PER_FRAME 160 // 10 ms = 160 samples @ 16 kHz - -#define MAX_ARM_TO_DSP_CHANNEL 3 -#define MAX_DSP_TO_ARM_CHANNEL 2 -#define HALF_SIZE_DATA_INGRESS 240 -#define RX_MAX MAX_ARM_TO_DSP_CHANNEL - -#define OPEN_OK 0 -#define OPEN_ERROR_DUPLICATE -1 - -#define ASSIGN_TX_CHANNEL (0x1) -#define ASSIGN_RX_CHANNEL (0x2) -#define CHANNEL_CLOSE_IN_PROGRESS (0x80000000) - -#define RTP_START_PORT 0x4000 -#define RTP_END_PORT 0x7FFE - -#define GET_DYN_PAYLOAD_TYPE_VALUE(a) ((a & 0XFF00) ? ((a & 0XFF00) >> 8) : a) -#define SET_PAYLOAD_TYPE_WITH_DYNAMIC(a,b) ((a << 8) | b) - - -//============================================================================= -// -// Enumeration Types -// -//----------------------------------------------------------------------------- -enum RTP_PAYLOAD_TYPES -{ - G711_MULAW_PAYLOAD_TYPE = 0, - GSM_FR_PAYLOAD_TYPE = 3, - G723_PAYLOAD_TYPE = 4, - G711_ALAW_PAYLOAD_TYPE = 8, - LINEAR_8KHZ_PAYLOAD_TYPE = 12, - TYPE13_SID_PAYLOAD_TYPE = 13, - G729_PAYLOAD_TYPE = 18, - GSM_EFR_PAYLOAD_TYPE = 20, - LINEAR_16KHZ_PAYLOAD_TYPE = 25, - AVT_PAYLOAD_TYPE = 101, - MASK_PAYLOAD_TYPE = 0x7f -}; - -enum RTP_TRANSMIT_STATES -{ - RTP_TX_FRAME, - RTP_TX_START, - RTP_TX_NO_FRAME, - RTP_TX_END = RTP_TX_NO_FRAME, - RTP_TX_SID -}; - -enum RTP_RX_STATES -{ - RTP_RX_NORMAL, - RTP_RX_FLUSH_SOON, - RTP_RX_FLUSH_NOW -}; - -enum RTP_TALKERS_TYPES -{ - FIRST_TALKER = 0, - LAST_TALKER = RX_MAX - 1, - NO_TALKER -}; - -typedef enum -{ - RTP_INGRESS = 0, - RTP_EGRESS -} t_RtpDirection; - -//============================================================================= -// -// Structure/Type definitions -// -//----------------------------------------------------------------------------- -typedef uint16_t rtp_channel_t; - -/********************************/ -/* RTP Call Stats Descriptor */ -/* */ -/********************************/ - -typedef struct -{ - int call_id; - unsigned long Rxduration; - unsigned long Rxpackets; - unsigned long Rxoctets; - unsigned long Rxlatepkts; - unsigned long Rxlostpkts; - unsigned long Txduration; - unsigned long Txpackets; - unsigned long Txoctets; -} t_callstats; - -#endif diff --git a/libs/sipcc/core/includes/scSession.h b/libs/sipcc/core/includes/scSession.h deleted file mode 100755 index 0525d1928b..0000000000 --- a/libs/sipcc/core/includes/scSession.h +++ /dev/null @@ -1,24 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "string_lib.h" -#include "sessionConstants.h" -#include "sessionTypes.h" - -/* CallControl Provider Management Interfaces */ -void scSessionProviderCmd(sessionProvider_cmd_t *data); - -/* CallControl Provider Management Updates */ -void scSessionProviderState(unsigned int state, scProvider_state_t *data); - -/* Session mgmt */ -session_id_t scCreateSession(session_create_param_t *param); -void scCloseSession(session_id_t sess_id); -void scInvokeFeature(session_feature_t *featData); - -/* Session Updates */ -void scSessionUpdate(session_update_t *session); -void scFeatureUpdate(feature_update_t *data); - - diff --git a/libs/sipcc/core/includes/session.h b/libs/sipcc/core/includes/session.h deleted file mode 100755 index 2b2390a262..0000000000 --- a/libs/sipcc/core/includes/session.h +++ /dev/null @@ -1,168 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SESSION_H_ -#define _SESSION_H_ - -#include "sessionConstants.h" -#include "sessionTypes.h" -#include "sessuri.h" - -/** - * sessionProviderCmd - * Session Provider Management Interfaces - * Called by Application to issue cmds to Session Provider - * - * @param data - sessionProvider_cmd_t - * Contains the command session provider type and provider specific data - * - * @return none - * - */ -void sessionProviderCmd(sessionProvider_cmd_t *); - -/** - * sessionProviderState - * Method to report session provider state updates to Application - * - * @param state - provider_state_t - * Contains the INS/OOS state along with provider specific data - * - * @return none - * - */ -void sessionProviderState(provider_state_t *state); - -/** - * createSession - * - * Called to create a session of requested type - * - * @param param - uri - * indicates type of session and specific params - * - * @return ccSession_id_t - id of the session created - */ - -session_id_t createSession(uri_t uri_info); - -/** - * closeSession - * - * Called to close an existing session - * - * @param sess_id - session id of the session to be closed - * - * @return >=0 success, -1 failure - */ - -int closeSession(session_id_t sess_id); - -/** - * sessionCmd - * Session Lifecycle Management Interfaces - * Called by Application to manage Session States - * - * @param data - sessionCmd_t - * Contains the command session type and session specific data - * - * @return none - * - */ -void sessionCmd(sessionCmd_t *sCmd); - -/** - * invokeFeature - * - * Called to invoke a feature on session or device - * - * @param feat - feature specific data along with its id - * @param featData - Additional info if needed for the feature - * - * @return none - * - */ - -void invokeFeature(session_feature_t *feat); - -/** - * invokeProviderFeature - * - * Called to invoke a feature on session or device - * - * @param feat - feature specific data along with its id - * @param featData - Additional info if needed for the feature - * - * @return none - * - */ - -void invokeProviderFeature(session_feature_t *feat); - -/** - * sessionUpdate - * - * Called by session provider to update session state and data - * - * @param session - session_update_t - * Contains session specific event state and data - * - * @return none - * - */ -void sessionUpdate(session_update_t *session); - -/** - * featureUpdate - * - * Called by session provider to update feature state and data - * not specific to a session - * - * @param feature - feature specific events and data - * - * @return none - * - */ -void featureUpdate(feature_update_t *feature); - - -/** - * sessionMgmt - * - * Called to manage various misc. functions of the device - * - * @param sessMgmt - the data - * - * @return none - * - */ -void sessionMgmt (session_mgmt_t *sess_mgmt); - -/** - * sessionSendInfo - * - * Called to send an Info Package - * - * @param send_info - the session ID and the Info Package to be sent - * - * @return none - * - */ -void sessionSendInfo (session_send_info_t *send_info); - -/** - * sessionRcvdInfo - * - * Called to forward a received Info Package (either parsed or unparsed) - * to the Java side - * - * @param rcvd_info - the session ID and Info Package received - * - * @return none - * - */ -void sessionRcvdInfo (session_rcvd_info_t *rcvd_info); - -#endif - diff --git a/libs/sipcc/core/includes/sessionConstants.h b/libs/sipcc/core/includes/sessionConstants.h deleted file mode 100755 index a094c3d867..0000000000 --- a/libs/sipcc/core/includes/sessionConstants.h +++ /dev/null @@ -1,364 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SESSION_CONSTANTS_H_ -#define _SESSION_CONSTANTS_H_ - -#include "cc_constants.h" - -typedef enum { - GROUP_TAG, - GROUP_SESSION_TYPE, - GROUP_CMD, - GROUP_STATE, - GROUP_CC_MODE, - GROUP_CC_REG_CAUSE, - GROUP_CC_FEATURE, - GROUP_DEVICE_FEATURE, - GROUP_RINGER_RESERVATION, - GROUP_CALL_STATE, - GROUP_CC_ATTR, - GROUP_CC_CALL_TYPE, - GROUP_CC_SECURITY, - GROUP_INFO_PKG_ID, - GROUP_CC_POLICY, - GROUP_UI_PRIVACY, - GROUP_SIP_BLF, - GROUP_SESSION_EVENT, - GROUP_CALL_EVENT, - GROUP_FILEPLAYER, - GROUP_MEDIA_EVENT, - GROUP_MEDIA_DIRECTION, - GROUP_PRIORITY, - GROUP_SESSION, - GROUP_CC_CAUSE -} group_t; - -typedef enum { - TAG_LINE = 1L, - TAG_STATE, - TAG_CCM_ADDR, - TAG_STATUS, - TAG_LCLCFWD, - TAG_CFANUM, - TAG_COUNT, - TAG_INSTANCE, - TAG_TIMEOUT, - TAG_PRIORITY, - TAG_NOTPROG, - TAG_RESET_TYPE, - TAG_ATTR, - TAG_INST, - TAG_SECURITY, - TAG_CLD_NAME, - TAG_CLD_NUMB, - TAG_CLG_NAME, - TAG_CLG_NUMB, - TAG_PRIVACY, - TAG_FEAT_SET, - TAG_FEATURE, - TAG_PROMPT, - TAG_ORIG_NAME, - TAG_ORIG_NUMB, - TAG_REDIR_NAME, - TAG_REDIR_NUMB, - TAG_ALT_CLG, - TAG_DISP_CLG, - TAG_DISP_CLD, - TAG_CALL_TYPE, - TAG_MODE, - TAG_CAUSE, - TAG_CALL_SELECTED, - TAG_BUTTON_NUMB, - TAG_SPEED_DIAL, - TAG_LABEL, - TAG_GCID, - TAG_LOGDISP, - TAG_MWI_TYPE, - TAG_NEW_COUNT, - TAG_OLD_COUNT, - TAG_HP_NEW_COUNT, - TAG_HP_OLD_COUNT, - TAG_MEDIA_TYPE, - TAG_MEDIA_DIRECTION, - TAG_MEDIA_MODE, - TAG_DURATION, - TAG_SESSION_HANDLE, - TAG_MCAP_ID, - TAG_GROUP_ID, - TAG_STREAM_ID, - TAG_REF_COUNT, - TAG_SESSION_ID, - TAG_RECV_INFO_LIST, - TAG_INFO_PACKAGE, - TAG_CONTENT_TYPE, - TAG_MESSAGE_BODY, - TAG_POLICY, - TAG_CFG_VER, - TAG_DP_VER, - TAG_SK_VER, - TAG_METHOD, - TAG_SIS_VER_NAME, - TAG_SIS_VER_MAJOR, - TAG_SIS_VER_MINOR, - TAG_SIS_VER_ADDTNL -} group_tag_t; - - -/* Session types supported */ -/* SESSIONTYPE_* is encoded into the MSB of session_feature_t.session_id */ -// XXX TODO figure out how to decouple this from the Java side constant -typedef enum { - SESSIONTYPE_CALLCONTROL = 1L, - SESSIONTYPE_RSTP, - SESSIONTYPE_RTP, - SESSIONTYPE_FILEPLAYER, - SESSIONTYPE_TONE, - SESSIONTYPE_CAPTURE -} group_session_type_t; - -/* Session Provider Management Commands */ -typedef enum { - CMD_INIT = 1L, - CMD_INSERVICE, - CMD_RESTART, - CMD_SHUTDOWN, - CMD_UNLOAD, - CMD_PRE_INIT, - CMD_PRO_BASE, - CMD_UNREGISTER_ALL_LINES = 10L, - CMD_REGISTER_ALL_LINES, - CMD_BLF_INIT -} group_cmd_t; - -/* Other provider specific cmds can be defined beginning with CMD_PRO_BASE */ -/* TBD from JNI */ -#define CC_CMD_UPDATELINES CMD_PRO_BASE - -/** - * Defines registration state - */ -typedef enum { - CC_CREATED_IDLE, - CC_OOS_FAILOVER, - CC_OOS_REGISTERING, - CC_OOS_AWAIT_CFG_SYNC, - CC_OOS_AWAIT_RESTART, - CC_INSERVICE, - CC_OOS_IDLE -} cc_reg_state_t; - -/* Other provider specific cmds can be defined beginning with STATE_PRO_BASE */ - - - -/* Device specific feature update IDs */ -typedef enum { - DEVICE_FEATURE_CFWD = 1L, - DEVICE_FEATURE_MWI, - DEVICE_FEATURE_MWILAMP, - DEVICE_FEATURE_MNC_REACHED, - DEVICE_SERVICE_CONTROL_REQ, - DEVICE_NOTIFICATION, - DEVICE_LABEL_N_SPEED, - DEVICE_REG_STATE, - DEVICE_CCM_CONN_STATUS, - DEVICE_CONDITIONAL_RESTART = 14L, - DEVICE_SYNC_CONFIG_VERSION, - DEVICE_ENABLE_VIDEO, - DEVICE_ENABLE_CAMERA, - DEVICE_FEATURE_BLF, - DEVICE_SUPPORTS_NATIVE_VIDEO -} group_device_feature_t; - -/* Ringer Reservation feature update IDs */ -typedef enum { - RINGER_RESERVATION_CREATED = 100L, - RINGER_RESERVATION_UPDATE -} group_ringer_reservation_t; - -/* Info Package */ -typedef enum { - INFO_PKG_ID_GENERIC_RAW = 0L -} group_info_pkg_id_t; - -/* Session Events */ -typedef enum { - SESSION_CREATED = 1L, - SESSION_CLOSED -} group_session_event_t; - -/* Call Session Events */ -typedef enum { - CALL_SESSION_CREATED = SESSION_CREATED, - CALL_SESSION_CLOSED = SESSION_CLOSED, - CALL_STATE = 3L, - CALL_NEWCALL, - CALL_INFORMATION, - CALL_ATTR, - CALL_SECURITY, - CALL_LOGDISP, - CALL_PLACED_INFO, - CALL_STATUS, - CALL_DELETE_LAST_DIGIT, - CALL_ENABLE_BKSP, - CALL_SELECT_FEATURE_SET, - CALL_SELECTED, - CALL_PRESERVATION_ACTIVE, - CALL_GCID, - CALL_FEATURE_CANCEL, - VIDEO_AVAIL = 20L, - CALL_RECV_INFO_LIST, - VIDEO_OFFERED, - RINGER_STATE, - CALL_CALLREF, - MEDIA_INTERFACE_UPDATE_BEGIN, - MEDIA_INTERFACE_UPDATE_SUCCESSFUL, - MEDIA_INTERFACE_UPDATE_FAIL, - CREATE_OFFER, - CREATE_ANSWER, - SET_LOCAL_DESC, - SET_REMOTE_DESC, - REMOTE_STREAM_ADD -} group_call_event_t; - -/* File Player Session Events */ -typedef enum { - FILEPLAYER_PLAYED = 300L, - FILEPLAYER_ALLOCATED -} group_fileplayer_t; - -typedef enum { - TONE_STARTED = 101L, - TONE_STOPPED, - MEDIA_INFO, - MEDIA_UPDATE -} group_media_event_t; - -//#include "com_cisco_sessionapi_MediaDirection.h" -typedef enum { - RX_DIRECTION = 0L, - TX_DIRECTION, - BI_DIRECTION -} group_media_direction_t; - -typedef enum { - PROMPTSTATUS_PROMPT = 10L, - PROMPTSTATUS_HIGH = 11L, - PROMPTSTATUS_NORMAL = 15L, - PROMPTSTATUS_MEDIA_MANAGER = 16L, - PROMPTSTATUS_NOTIFICATION = 20L, - PROMPTSTATUS_STATUS = 30L, - PROMPTSTATUS_LOW = 31L, - SOFTKEYBAR_APPLICATION_MANAGER = 100L, - SOFTKEYBAR_MEDIA_MANAGER = 50L -} group_priority_t; - -/* Session Features that can be invoked TBD should come from JNI */ -#define FEATURE_NONE 0 -#define FEATURE_VOLUME_CTRL 1 -#define FEATURE_PRO_BASE 0 - -/* Call Priority TBD should come from JNI */ -#define CC_CALL_PRIORITY_NORMAL 0 -#define CC_CALL_PRIORITY_URGENT 1 - -/* Session Commands TBD should come from JNI */ -typedef enum { - SESSION_REALIZE = 1, - SESSION_PREFETCH, - SESSION_START, - SESSION_STOP, - SESSION_DEALLOCATE, - SESSION_CLOSE, - SESSION_ALLOCATE -} group_session_t; - -/* - * CC Provider specific constants. - * These do not come from JNI Files - */ - -#include "phone_types.h" - -#define CC_ALL_LINES 255 -#define CC_SESSION_INVALID 0x01FFFFFF -#define CC_MAX_GCID CC_GCID_LEN - -/* 1-9 * # A B C D are number 1 thru 16 */ -#define BKSP_KEY 90 - -#ifdef __CC_CAUSE_STRINGS__ -static const char *cc_cause_names[] = { - "OK", - "ERR", - "UNASSIGNED_NUM", - "NO_RESOURCE", - "NO_ROUTE", - "NORMAL", - "BUSY", - "NO_USER_RESP", - "NO_USER_ANS", - "REJECT", - "INVALID_NUMBER", - "FACILITY_REJECTED", - "CALL_ID_IN_USE", - "XFER_LOCAL", - "XFER_REMOTE", - "XFER_BY_REMOTE", - "XFER_CONFERENCE", - "CONGESTION", - "ANONYMOUS", - "REDIRECT", - "PAYLOAD_MISMATCH", - "CONF", - "REPLACE", - "NO_REPLACE_CALL", - "NO_RESUME", - "NO_MEDIA", - "REQUEST_PENDING", - "INVALID_PARTICIPANT", - "NO_CONF_BRIDGE", - "MAX_PARTICIPANT", - "KEY_NOT_ACTIVE", - "TEMP_NOT_AVAILABLE", - "REMOTE_SERVER_ERROR", - "BARGE", - "CBARGE", - "NOT_FOUND", - "SECURITY_FAILURE", - "MONITOR", - "UI_STATE_BUSY", - "SIP_CAUSE_ANSWERED_ELSEWHERE", - "RETRIEVED", - "FORWARDED", - "ABANDONED", - "XFER_LOCAL_WITH_DIALSTRING", - "CAC_BW_OK", - "ONHOOK_FEAT_COMP", - "RESP_TIMEOUT", - "SERV_ERR_UNAVAIL", - "REMOTE_DISCONN_REQ_PLAYTONE", - "MAX_CAUSE" -}; -#endif //__CC_CAUSE_STRINGS__ - -#define MAX_SOFT_KEYS 16 - - -// eventually these should come from the Java side -typedef enum { - SESSION_MGMT_APPLY_CONFIG, - SESSION_MGMT_SET_TIME, - SESSION_MGMT_GET_PHRASE_TEXT, - SESSION_MGMT_SET_UNREG_REASON, - SESSION_MGMT_GET_UNREG_REASON, - SESSION_MGMT_UPDATE_KPMLCONFIG, - SESSION_MGMT_GET_AUDIO_DEVICE_STATUS, - SESSION_MGMT_CHECK_SPEAKER_HEADSET_MODE, - SESSION_MGMT_LINE_HAS_MWI_ACTIVE, - SESSION_MGMT_EXECUTE_URI -} session_mgmt_func_e; - -#endif diff --git a/libs/sipcc/core/includes/sessionTypes.h b/libs/sipcc/core/includes/sessionTypes.h deleted file mode 100755 index cc9b235516..0000000000 --- a/libs/sipcc/core/includes/sessionTypes.h +++ /dev/null @@ -1,427 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SESSIONTYPES_H_ -#define _SESSIONTYPES_H_ - -#include "string_lib.h" -#include "sessionConstants.h" -#include "ccsip_pmh.h" -#include "cc_constants.h" -#include "sip_ccm_transport.h" -#include "plat_api.h" - -/*********************** SESSION ID *****************/ -typedef unsigned int session_id_t ; - -typedef struct { - unsigned int reason; - string_t reason_info; -} ccSessionProvider_cmd_t; - -typedef struct { - string_t sis_ver_name ; //could be "cme" now. - unsigned int sis_ver_major; - unsigned int sis_ver_minor; - unsigned int sis_ver_addtnl; -}sis_ver; - -typedef struct { - unsigned int cause; - unsigned int mode; - sis_ver sis_ver_info; -} ccProvider_state_t; - -typedef struct { - line_t line_id; - string_t dial; -} ccSession_create_param_t; - -typedef struct { - string_t info; - string_t info1; - unsigned int state; - cc_jsep_action_t action; - cc_media_stream_id_t stream_id; - cc_media_track_id_t track_id; - cc_media_type_t media_type; - cc_level_t level; - unsigned int sessionid; - cc_boolean has_constraints; -} ccSession_feature_t; - -typedef struct { - int state; - int attr; - int inst; - line_t line_id; - int cause; - string_t sdp; - unsigned int media_stream_id; - unsigned int media_stream_track_id; -} cc_call_state_data_t; -/* CALL_SESSION_CREATED shall use the call_state as data*/ - -typedef struct -{ - string_t cldNum; - string_t cldName; -} cc_placed_call_info_t; - -typedef struct -{ - string_t clgName; - string_t clgNumber; - string_t altClgNumber; - boolean dispClgNumber; - string_t cldName; - string_t cldNumber; - boolean dispCldNumber; - string_t origCalledName; - string_t origCalledNumber; - string_t lastRedirectingName; - string_t lastRedirectingNumber; - unsigned short call_type; - unsigned short instance_id; - int security; - int policy; -} cc_callinfo_t; - -typedef struct { - string_t featSet; - int featMask[MAX_SOFT_KEYS]; -} cc_featurekey_set_t; - -typedef struct { - cc_boolean start; - vcm_ring_mode_t mode; - cc_boolean once; -} cc_ringer_state_t; - -/** - * Define call status to carry over timeout/priority that might be sent from CUCM. - * Note: if the values of timeout and priority are zero, then 2 second is the - * derfault value for the timeout. It's mostly the application based on UI - * design. - */ -typedef struct { - string_t status; - int timeout; - int priority; -} cc_call_status_t; - -typedef struct -{ - union { - cc_call_state_data_t state_data; - cc_placed_call_info_t plcd_info; - cc_callinfo_t call_info; - cc_call_status_t status; - char gcid[CC_MAX_GCID]; - int action; - int security; - cc_featurekey_set_t feat_set; - unsigned int target_sess_id; - unsigned int callref; - string_t recv_info_list; - cc_ringer_state_t ringer; - } data; -} ccSession_update_t; - -typedef struct { - line_t line; - unsigned int info; -} cc_line_data_t; - -typedef struct { - int state; - int info; -} cc_feature_state_t; - -typedef struct { - cc_blf_state_t state; - int request_id; - int app_id; -} cc_feature_blf_state_t; - -typedef struct { - int timeout; - boolean notifyProgress; - char priority; - string_t prompt; -} cc_notification_data_t; - -typedef struct { - line_t line; - unsigned char button; - string_t speed; - string_t label; -} cc_label_n_speed_t; - -typedef struct { - string_t cfg_ver; - string_t dp_ver; - string_t softkey_ver; -} cc_cfg_version_t; - -typedef struct { - line_t line; - boolean isFwd; - boolean isLocal; - string_t cfa_num; -} cc_cfwd_status_t; - -typedef struct { - string_t addr; - int status; -} cc_ccm_conn_t; - -typedef struct { - line_t line; - boolean status; - int type; - int newCount; - int oldCount; - int hpNewCount; - int hpOldCount; -} cc_mwi_status_t; - -typedef struct { - union { - cc_line_data_t line_info; // For line specific features - cc_feature_state_t state_data; // For device specific feature - cc_feature_blf_state_t blf_data; // For blf state updates. - cc_notification_data_t notification; - cc_label_n_speed_t cfg_lbl_n_spd; - cc_cfwd_status_t cfwd; // For CFWD ALL feature - cc_ccm_conn_t ccm_conn; - cc_mwi_status_t mwi_status; - unsigned int reset_type; - cc_cfg_version_t cfg_ver_data; - } data; -} ccFeature_update_t; - -typedef struct { - int data; -} ccSessionCmd_t; - -/*********************** STREAM SESSION TYPES *****************/ - -typedef struct { - unsigned int reason; -} scSessionProvider_cmd_t; - -typedef struct { - unsigned int mode; -} scSession_state_t; - -typedef struct { - line_t line_id; -} scSession_create_param_t; - -typedef struct { - string_t info; -} scSession_feature_t; - -typedef struct { - string_t info; -} scProvider_state_t; - -typedef struct { - int type; - int mcap_id; - int group_id; - int stream_id; - int call_id; - int direction; - int ref_count; - int session_handle;//session handle for ms rtp session -} rtp_session_info; - -typedef struct { - int refcount; -} rtp_session_update; - -typedef struct { - union { - int state; - rtp_session_info rtp_info; - rtp_session_update rtp_update; - } data; -} scSession_update_t; - -typedef struct { - string_t info; -} scFeature_update_t; - -typedef struct { - string_t info; -} scSessionCmd_t; - -typedef struct { - int id; - int data; -} rcFeature_update_t; - -/********************** SESSION TYPES ****************************/ - - -typedef struct { - unsigned int sessionType; - unsigned int cmd; - union { - ccSessionProvider_cmd_t ccData; - scSessionProvider_cmd_t scData; - } cmdData; -} sessionProvider_cmd_t; - -typedef struct { - unsigned int sessionType; - unsigned int state; - union { - ccProvider_state_t ccData; - scProvider_state_t scData; - } stateData; -} provider_state_t; - -typedef struct { - unsigned int sessionType; - string_t uri; - union { - ccSession_create_param_t ccData; - scSession_create_param_t scData; - } createData; -} session_create_param_t; - -typedef struct { - unsigned int session_id; - unsigned int featureID; - union { - ccSession_feature_t ccData; - scSession_feature_t scData; - } featData; -} session_feature_t; - -typedef struct { - unsigned int sessionID; - unsigned int eventID; - unsigned int sessType; - union { - ccSession_update_t ccSessionUpd; - scSession_update_t scSessionUpd; - } update; -}session_update_t; - -typedef struct { - unsigned int sessID; - unsigned int cmd; - union { - ccSessionCmd_t ccCmd; - scSessionCmd_t scCmd; - } cmdData; -}sessionCmd_t; - - -typedef struct { - unsigned int sessionType; - unsigned int featureID; - union { - ccFeature_update_t ccFeatUpd; - scFeature_update_t scFeatUpd; - rcFeature_update_t rcFeatUpd; - } update; -}feature_update_t; - - -typedef struct { - string_t config_version_stamp; - string_t dialplan_version_stamp; - string_t fcp_version_stamp; - string_t cucm_result; - string_t load_id; - string_t inactive_load_id; - string_t load_server; - string_t log_server; - boolean ppid; -} session_mgmt_config_t; - -typedef struct { - int result; -} session_mgmt_apply_config_result_t; - -typedef struct { - long gmt_time; -} session_mgmt_time_t; - -typedef struct { - int ret_val; - int ndx; - char *outstr; - uint32_t len; -} session_mgmt_phrase_text_t; - -typedef struct { - int unreg_reason; -} session_mgmt_unreg_reason_t; - -typedef struct { - int kpml_val; -} session_mgmt_kpmlconfig_t; - -typedef struct { - int enabled; - plat_audio_device_t device_type; -} session_mgmt_audio_device_status_t; - -typedef struct { - boolean enabled; -} session_mgmt_speaker_headset_mode_t; - -typedef struct { - boolean ret_val; - line_t line; -} session_mgmt_line_mwi_active_t; - -typedef struct { - string_t uri; -} session_mgmt_uri_t; - -typedef struct { - session_mgmt_func_e func_id; - union { - session_mgmt_config_t config; - session_mgmt_apply_config_result_t apply_config_result; - session_mgmt_time_t time; - session_mgmt_phrase_text_t phrase_text; - session_mgmt_unreg_reason_t unreg_reason; - session_mgmt_kpmlconfig_t kpmlconfig; - session_mgmt_audio_device_status_t audio_device_status; - session_mgmt_speaker_headset_mode_t speaker_headset_mode; - session_mgmt_line_mwi_active_t line_mwi_active; - session_mgmt_uri_t uri; - } data; -} session_mgmt_t; - - -typedef struct { - string_t info_package; - string_t content_type; - string_t message_body; -} info_generic_raw_t; - -typedef struct { - unsigned int sessionID; - info_generic_raw_t generic_raw; -} session_send_info_t; - -typedef struct { - unsigned int sessionID; - int packageID; - union { - info_generic_raw_t generic_raw; - } info; -} session_rcvd_info_t; - -#endif - diff --git a/libs/sipcc/core/includes/sessuri.h b/libs/sipcc/core/includes/sessuri.h deleted file mode 100644 index 8c5ffbf55a..0000000000 --- a/libs/sipcc/core/includes/sessuri.h +++ /dev/null @@ -1,171 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SESSURI_H_ -#define _SESSURI_H_ - -#define MAX_LEN_SCHEME_INFO 256 -#define MAX_STR_LEN_PARAM_TYPE 64 -#define MAX_STR_LEN_PARAM_VAL 64 - -/* - * Scheme names - */ -#define SCHEME_SIP "sip" -#define SCHEME_FILE "file" -#define SCHEME_RTP "rtp" -#define SCHEME_RTSP "rtsp" -#define SCHEME_CAPTURE "capture" - -/** - * - * Different URI types. - * - */ -typedef enum { - SCHEME_NONE=0, - SIP_URI, - FILE_URI, - CAPTURE_URI, - RTP_URI, - RTSP_URI -} scheme_e; - -/** - * parameter tags/names - * - */ - -#define LINE_TAG "line" - -/** - * Definitions for file player session - */ -#define CADENCE_TAG "cadence" -#define MEDIA_TYPE_TAG "media_type" -#define LOOP_COUNT_TAG "loop_count" -#define PRIORITY_TAG "priority" -#define FILEPTYPE_TAG "type" - -/** - * Definitions for raw rtp session - */ -#define DIRECTION_TAG "direction" -#define MULTICAST_TAG "mcast" -#define PAYLOADTYPE_TAG "payloadtype" -#define FRAMESIZE_TAG "framesize" -#define VADENABLE_TAG "vad" -#define PRECEDENCE_TAG "precedence" -#define MIXINGMODE_TAG "mode" -#define MIXINGPARTY_TAG "party" -#define CHANNELTYPE_TAG "channeltype" -#define LOCALADDRESS_TAG "localaddress" -#define LOCALPORT_TAG "localport" -#define ALGORITHM_TAG "algorithm" - -/** - * Param types required for various URIs. - * - */ -typedef enum { - LINE_PARAM=0, - MEDIA_TYPE_PARAM, - CADENCE_PARAM, - LOOP_COUNT_PARAM, - PRIORITY_PARAM, - MAX_QUERY_PARAM, - DIRECTION_PARAM, - MULTICAST_PARAM, - PAYLOADTYPE_PARAM, - FRAMESIZE_PARAM, - VADENABLE_PARAM, - PRECEDENCE_PARAM, - MIXINGMODE_PARAM, - MIXINGPARTY_PARAM, - CHANNELTYPE_PARAM, - LOCALADDRESS_PARAM, - LOCALPORT_PARAM, - ALGORITHM_PARAM, - FILETYPE_PARAM -} param_e; - -typedef enum { - MEDIA_TYPE_AUDIO, - MEDIA_TYPE_VIDEO, - MEDIA_TYPE_AUDIO_VIDEO, -} media_type_e; - -/** - * params related to call sessions. - * - */ -typedef struct { - int line_id; - media_type_e media_type; -} call_session_param_t; - -/** - * params related to capture sessions. - * - */ -typedef struct { - media_type_e media_type; -} capture_session_param_t; - -/** - * - * params related file sessions - */ -typedef struct { - int type; - int loop_count; - int cadence; - int priority; -} file_session_param_t; - -typedef struct { - int direction; - int multicast; - int payloadtype; - int framesize; - int vadenable; - int precedence; - int mixingmode; - int mixingparty; - int channeltype; - int localaddress; - int localport; - int algorithm; -} raw_rtp_session_param_t; - -/* - * generic param type - */ -typedef union params { - call_session_param_t call_session_param; - file_session_param_t file_session_param; - raw_rtp_session_param_t raw_session_param; - capture_session_param_t capture_session_param; -} param_t; - - -/* - * URI information. This is output of the Parser. - * - */ -typedef struct uri_s { - scheme_e scheme; - char scheme_specific[MAX_LEN_SCHEME_INFO]; - union - { - call_session_param_t call_session_param; - file_session_param_t file_session_param; - raw_rtp_session_param_t raw_session_param; - }param; - -} uri_t; - -int parse_uri(const char *uri, uri_t *uri_info); - -#endif diff --git a/libs/sipcc/core/includes/singly_link_list.h b/libs/sipcc/core/includes/singly_link_list.h deleted file mode 100644 index a0046abc6d..0000000000 --- a/libs/sipcc/core/includes/singly_link_list.h +++ /dev/null @@ -1,117 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SINGLY_LINK_LIST_H -#define _SINGLY_LINK_LIST_H - -typedef enum { - SLL_MATCH_FOUND, - SLL_MATCH_NOT_FOUND -} sll_match_e; - -/* - * type definition for find function pointer. The find function takes two arguments: - * 1. find_by_p - pointer to the key - * 2. data_p - pointer to the linked list node data. - */ -typedef sll_match_e(*sll_find_callback_t)(void *find_by_p, void *data_p); - -typedef void *sll_handle_t; - -typedef enum { - SLL_RET_SUCCESS, - SLL_RET_INVALID_ARGS, - SLL_RET_MALLOC_FAILURE, - SLL_RET_NODE_NOT_FOUND, - SLL_RET_LIST_NOT_EMPTY, - SLL_RET_OTHER_FAILURE -} sll_return_e; - -/* - * sll_create(): creates a signly linked list control block and initializes it. - * Applications shall call this first before performing any singly - * linked list primitives, such as append, remove, find or destroy. - * - * Parameters: find_fp - function pointer which will be used to find the matching node. - * - * Returns: list handle or NULL if it can not create the list. - */ -extern sll_handle_t sll_create(sll_find_callback_t find_fp); - -/* - * sll_destroy(): if the list is empty, it frees the list. - * It is the responsibility of the applications to empty - * the list before destroying the list. - * - * Parameters: list_handle - handle to the list. - * - * Returns: SLL_RET_SUCCESS if it successfully destroys. - * SLL_RET_INVALID_ARGS if the arguments are invalid. - * SLL_RET_LIST_NOT_EMPTY if the list is not empty. - */ -extern sll_return_e sll_destroy(sll_handle_t list_handle); - -/* - * sll_append(): creates a list node and appends it to the list. - * Applications are responsible for memory management of the - * data that the node will point to. - * - * Parameters: list_handle - handle to the list. - * data_p - pointer to the data that the list node will point to. - * - * Returns: SLL_RET_SUCCESS if it successfully appends. - * SLL_RET_INVALID_ARGS if the arguments are invalid. - * SLL_RET_MALLOC_FAILURE if memory allocation fails. - */ -extern sll_return_e sll_append(sll_handle_t list_handle, void *data_p); - -/* - * sll_remove(): removes the node from the list and frees the node. - * Applications are responsible for memory management of the - * data that the node points to. - * - * Parameters: list_handle - handle to the list. - * data_p - pointer to the data that the list node points to. - * - * Returns: SLL_RET_SUCCESS if it successfully removes. - * SLL_RET_INVALID_ARGS if the arguments are invalid. - * SLL_RET_NODE_NOT_FOUND if the node is not found in the list. - */ -extern sll_return_e sll_remove(sll_handle_t list_handle, void *data_p); - -/* - * sll_find(): finds the matching node data using find_fp function. - * - * Parameters: list_handle - handle to the list. - * find_by_p - pointer to the opaque data that will be used by find_fp function. - * - * Returns: pointer to the data or NULL if it can not find. - */ -extern void *sll_find(sll_handle_t list_handle, void *find_by_p); - -/* - * sll_next(): returns pointer to the data in the next node to the node holding data_p. - * if data_p is NULL, then returns pointer to the data in the first node. - * Applications can use this primitive to walk through the list. Typically, - * it can be used to remove the individual nodes and to destroy the list - * before shutting down/resetting the application. - * - * Parameters: list_handle - handle to the list. - * data_p - pointer to the data that the list node points to. - * - * Returns: pointer to the data or NULL if it can not find. - */ -extern void *sll_next(sll_handle_t list_handle, void *data_p); - -/* - * sll_count(): returns the number of elements in the list. - * count of the linked list. - * - * Parameters: list_handle - handle to the list. - * - * Returns: returns the number of elements in the list. - */ -extern unsigned int sll_count(sll_handle_t list_handle); - -#endif diff --git a/libs/sipcc/core/includes/sip_socket_api.h b/libs/sipcc/core/includes/sip_socket_api.h deleted file mode 100755 index 2969d7d8d0..0000000000 --- a/libs/sipcc/core/includes/sip_socket_api.h +++ /dev/null @@ -1,80 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_SOCKET_API_H__ -#define __SIP_SOCKET_API_H__ - -#include "cpr.h" -#include "cpr_socket.h" - -/** - * sipSocketSend - * - * @brief The sipSocketSend() function is a wrapper used by the sipstack to send - * data over a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc Specifies the socket created with cprSocket() to send - * @param[in] buf A pointer to the buffer of the message to send. - * @param[in] len Specifies the length in bytes of the message pointed to by the buffer argument. - * @param[in] flags - The options used for the send. - * - * - */ -ssize_t -sipSocketSend (cpr_socket_t soc, - CONST void *buf, - size_t len, - int32_t flags, - boolean secure); - -/** - * sipSocketRecv - * - * @brief The sipSocketRecv() function is a wrapper used by the sipstack to send - * data over a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc Specifies the socket created with cprSocket() to send - * @param[in] buf A pointer to the buffer of the message to send. - * @param[in] len Specifies the length in bytes of the message pointed to by the buffer argument. - * @param[in] flags - The options used for the recv. - */ -ssize_t -sipSocketRecv (cpr_socket_t soc, - void * RESTRICT buf, - size_t len, - int32_t flags, - boolean secure); - -/** - * sipSocketClose - * - * @brief The sipSocketClose() function is a wrapper used by the sipstack to - * close a socket. This function decides to use the secure versus unsecure - * connection based on the "secure" flag. - * - * @note - The implementation of both secure/non-secure is the same in RT/TNP - * products. It is different for the other vendors and hence we need this - * flexibility. - * - * @param[in] soc - The socket that needs to be destroyed - * - * @return CPR_SUCCESS on success otherwise, CPR_FAILURE. cpr_errno needs to be set in this case. - * - * @note The possible error values this function should return are - * @li [CPR_EBADF] socket is not a valid socket descriptor. - */ -cpr_status_e -sipSocketClose (cpr_socket_t soc, - boolean secure); -#endif diff --git a/libs/sipcc/core/includes/sntp.h b/libs/sipcc/core/includes/sntp.h deleted file mode 100644 index 93f53ea147..0000000000 --- a/libs/sipcc/core/includes/sntp.h +++ /dev/null @@ -1,92 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef SNTP_H -#define SNTP_H - -#include -#include -#include -#include - -#include -// Begin system specific includes -//#include -#include -#include -#include -#include -#include -#include -// End system specific includes - -#define MAX_IPADDR_STR_LEN 48 - -#define NTP_UTC_OFFSET (2208963600) -#define PORT_NTP (123) -#define MULTICAST_ADDR_NTP (0xE0000101L) -#define BROADCAST_ADDR (0xFFFFFFFF) -#define TIMEPORT (37) - -typedef enum { unicast, multicast, anycast, directed_broadcast } SNTP_Mode; - -typedef struct { - unsigned int precision:8; - unsigned int poll:8; - unsigned int stratum:8; - unsigned int mode:3; - unsigned int versionNumber:3; - unsigned int leapIndicator:2; -} NTPHeader_s; - -typedef struct { - union { - NTPHeader_s header; - unsigned long rawheader; - } u; - unsigned long rootDelay; - unsigned long rootDispersion; - unsigned long referenceIdentifier; - unsigned long referenceTimestamp[2]; - unsigned long originateTimestamp[2]; - unsigned long receiveTimestamp[2]; - unsigned long transmitTimestamp[2]; - // Removed the following fields since they are version 4 - // specific. - //unsigned long keyIdentifier; - //unsigned long messageDigest[4]; -} NTPStruct_s; - -typedef struct { - Socket *server_socket; // Socket to SNTP server - Socket *lsocket; // Local listening socket - Socket *bsocket; // Broadcast listening socket - Socket *msocket; // Multicast listening socket - char address[MAX_IPADDR_STR_LEN]; - unsigned long sntp_server_addr; - SNTP_Mode mode; - - unsigned long destinationTimestamp[2]; - long roundtripDelay[2]; - long timeOffset[2]; - long time_zone; -} SNTP_State; - -typedef union { - unsigned long NTPDataBuffer[17]; - NTPStruct_s NTPData; -} NTPPacket_u; - -void SNTPInit(void); -void SNTPStop(void); -int SNTPSend(void); -void SNTPCallback(irx_tmr_buf *pTmrBlk); -int SNTPRecv(SysHdr *pSm); -long NTPSemanticCheck(const NTPStruct_s *ntpdata); -void SNTPSecondUpdate(void); -void printNTPStruct(const NTPStruct_s *ntpdata, const SNTP_State *state); -long sntp_get_rand_seed(void); -void SNTPDebugInit(void); - -#endif diff --git a/libs/sipcc/core/includes/string_lib.h b/libs/sipcc/core/includes/string_lib.h deleted file mode 100755 index 1efb231c7d..0000000000 --- a/libs/sipcc/core/includes/string_lib.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _STRING_LIB_INCLUDED_H /* allows multiple inclusion */ -#define _STRING_LIB_INCLUDED_H - -#include "cpr_types.h" - -#define LEN_UNKNOWN -1 - -typedef struct string_block_t_ -{ - struct string_block_t_ *next; - uint16_t refcount; - uint16_t length; - const char *fname; - int line; - short signature; - char data[1]; -} string_block_t; - - -/* - * Prototypes for functions - */ - -string_t strlib_malloc(const char *str, int length, const char *fname, - int line); -string_t strlib_copy(string_t str); -string_t strlib_update(string_t destination, const char *source, - const char *fname, int line); -string_t strlib_append(string_t str, const char *toappend_str, - const char *fname, int line); -string_t strlib_prepend(string_t str, const char *toprepend_str, - const char *fname, int line); -void strlib_free(string_t str); -char *strlib_open(string_t str, int length, const char *fname, int line); -string_t strlib_close(char *str); -string_t strlib_printf(const char *format, ...); -string_t strlib_empty(void); -void strlib_debug_init(void); -long strlib_mem_used(void); -int strlib_test_memory_is_string(void *mem); -void strlib_init (void); - -#ifndef __STRINGLIB_INTERNAL__ -#define strlib_malloc(x,y) strlib_malloc(x,y,__FILE__,__LINE__) -#define strlib_update(x,y) strlib_update(x,y,__FILE__,__LINE__) -#define strlib_append(x,y) strlib_append(x,y,__FILE__,__LINE__) -#define strlib_prepend(x,y) strlib_prepend(x,y,__FILE__,__LINE__) -#define strlib_open(x,y) strlib_open(x,y,__FILE__,__LINE__) -#endif - - -#endif diff --git a/libs/sipcc/core/includes/subapi.h b/libs/sipcc/core/includes/subapi.h deleted file mode 100755 index 367842732a..0000000000 --- a/libs/sipcc/core/includes/subapi.h +++ /dev/null @@ -1,43 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SUBAPI_H_ -#define _SUBAPI_H_ - -#include "ccsip_subsmanager.h" - -cc_rcs_t sub_int_subnot_register(cc_srcs_t src_id, cc_srcs_t dst_id, - cc_subscriptions_t evt_pkg, void *callback_fun, - cc_srcs_t dest_task, int msg_id, - void *term_callback, int term_msg_id, - long min_duration, long max_duration); - -cc_rcs_t sub_int_subscribe(sipspi_msg_t *msg_p); - -cc_rcs_t sub_int_subscribe_ack(cc_srcs_t src_id, cc_srcs_t dst_id, - sub_id_t sub_id, uint16_t response_code, - int duration); - -cc_rcs_t sub_int_notify(cc_srcs_t src_id, cc_srcs_t dst_id, sub_id_t sub_id, - ccsipNotifyResultCallbackFn_t notifyResultCallback, - int subsNotResCallbackMsgID, - ccsip_event_data_t *eventData, - subscriptionState subState); - -cc_rcs_t sub_int_notify_ack(sub_id_t sub_id, uint16_t response_code, - uint32_t cseq); - -cc_rcs_t sub_int_subscribe_term(sub_id_t sub_id, boolean immediate, - int request_id, - cc_subscriptions_t event_package); - -cc_rcs_t sip_send_message(ccsip_sub_not_data_t *msg_data, - cc_srcs_t dest_task, int msg_id); - -cc_rcs_t app_send_message(void *msg_data, int msg_len, cc_srcs_t dest_id, - int msg_id); -extern cc_rcs_t -sub_send_msg (cprBuffer_t buf, uint32_t cmd, uint16_t len, cc_srcs_t dst_id); - -#endif diff --git a/libs/sipcc/core/includes/task.h b/libs/sipcc/core/includes/task.h deleted file mode 100755 index 6cbc937603..0000000000 --- a/libs/sipcc/core/includes/task.h +++ /dev/null @@ -1,28 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef TASK_H -#define TASK_H - -/* - *--------------------DEPRECATED FILE------------------------------- - * - * As part of Skittles project this file is deprecated. - * DO NOT add anything to this file. - * The contents of this file are really platform specific and - * have moved to phntask.h under - * src-bcm-tnp/h/phntask.h for CNU phones. - * src-arm-79xx/phntask.h for IRX phones. - * - * If you are doing SYNC merges _DO_ _NOT_ merge anything from parent - * This file is kept here because it comes from parent/grand parent branches - * and will not be removed from clearcase till Skittles collapses. - * [The fAQ on cc tools contains details of why ] - * - * If you have questions send email to skittles-dev - *--------------------------------------------------------------- - */ -#define SIP_TMR 0xffff //TODO CPR a temporary bogus number - -#endif /* TASK_H */ diff --git a/libs/sipcc/core/includes/time2.h b/libs/sipcc/core/includes/time2.h deleted file mode 100644 index cc02ce7dbe..0000000000 --- a/libs/sipcc/core/includes/time2.h +++ /dev/null @@ -1,192 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef TIME2_H -#define TIME2_H - -#include -#include -#include -#include -#include -#include - -// System specific includes - -// End system specific - -#define EPOCH_YEAR (1900) -#define EPOCH_SECONDS (0x80000000) -#define DAYS_PER_LEAP_YEAR (366) -#define DAYS_PER_YEAR (365) -#define DAYS_PER_WEEK (7) -#define LEAP_FOUR_CENTURY (400) -#define LEAP_CENTURY (100) -#define LEAP_YEAR (4) -// Calculated with 365.2425 days/year for the Gregorian calendar -#define SECONDS_PER_GREGORIAN_YEAR (31556952) -#define SECONDS_PER_YEAR (31536000) -#define SECONDS_PER_LEAP_YEAR (31622400) -#define SECONDS_PER_DAY (86400) -#define SECONDS_PER_HOUR (3600) -#define SECONDS_PER_MINUTE (60) -#define MINUTES_PER_HOUR (60) -#define HOURS_PER_DAY (24) -#define MAX_WEEKS_PER_MONTH (6) -#define MONTHS_PER_YEAR (12) - -#define STARTING_TIME (101 * SECONDS_PER_GREGORIAN_YEAR) - -//If 30 minutes have elapsed, clear time display -#define SNTP_MAX_TIME_SINCE_UPDATE 30*60 - -typedef enum { - SUNDAY = 0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY -} DAYS_NAMES_TO_NUMBER; - -typedef enum { - JANUARY = 0, - FEBRUARY, - MARCH, - APRIL, - MAY, - JUNE, - JULY, - AUGUST, - SEPTEMBER, - OCTOBER, - NOVEMBER, - DECEMBER -} MONTH_NAMES_TO_NUMBER; - -typedef struct { - time_t time; - unsigned short millitm; - short timezone; - short dstflag; -} timeb; - -typedef struct { - // Standard Gregorian calendar date - unsigned long year; // Range >= EPOCH_YEAR - unsigned long month; // Range 0-11, use MONTH_NAME_x for text - unsigned long day; // Range 1-31 - - // Standard 24 hour time format - unsigned long hour; // Range 0-23 - unsigned long minute; // Range 0-59 - unsigned long seconds; // Range 0-59 - - // Specifics about a year and the current date - unsigned long day_of_year; // Range 0-365 - unsigned long day_of_january_first; // Range 0-6, use DAY_NAME_x for text - unsigned long day_of_week; // Range 0-6, use DAY_NAME_x for text - unsigned long week_of_year; // Range 1-53 - - // Variables that are associated with leap years and calculations - unsigned long leap_years; // Non negative integer - unsigned long leap_flag; // Range 0-1, boolean - - // Time zone specifics set by user - long time_zone; // Timezone offset in seconds - unsigned long daylight_saving_offset; // Number of seconds to add (adjust) when DST starts - // e.g. daylight_saving_offset = 3600; // 1 hour - // when DST starts the code will add 1 hour to the GMT time and - // when DST stops it will stop adding 1 hour - unsigned long daylight_saving_start_month; // Range 0-11, use MONTH_NAME_x for text - unsigned long daylight_saving_start_day; // Range 1-31, if set to 0, only then will week of month is used - unsigned long daylight_saving_start_day_of_week; // Range 0-6, use DAY_NAME_x for text - unsigned long daylight_saving_start_week_of_month;// Range 0-6, First, second, etc. DAY_NAME of the month, zero denotes last week in month, e.g. day_of_week = 0, week_of_month = 1 => First Sunday of month - unsigned long daylight_saving_start_time; // Range 0-86399, number of seconds past midnight - unsigned long daylight_saving_stop_month; // Range 0-11, use MONTH_NAME_x for text - unsigned long daylight_saving_stop_day; // Range 1-31, if set to 0, only then will week of month is used - unsigned long daylight_saving_stop_day_of_week; // Range 0-6, use DAY_NAME_x for text - unsigned long daylight_saving_stop_week_of_month; // Range 0-6, First, second, etc. DAY_NAME of the month, zero denotes last week in month, e.g. day_of_week = 0, week_of_month = 1 => First Sunday of month - unsigned long daylight_saving_stop_time; // Range 0-86399, number of seconds past midnight - unsigned long daylight_saving_year_calc; // Non negative integer, non 0 means daylight saving start and stop second is calculated for given year - unsigned long daylight_saving_auto_adjust; // Range 0-1, boolean - - // Time zone specifics set by make_date - unsigned long is_daylight_saving; // Range 0-1, boolean - unsigned long daylight_saving_start_second; // Second in the year that daylight saving starts - unsigned long daylight_saving_stop_second; // Second in the year that daylight saving stops -} time2_s; - -typedef struct { - const char *TZ_NAME; - const long offset; -} TZ_STRUCT; - -// Time date externs -extern const char *const MONTH_NAMES_LONG[]; -extern const char *const MONTH_NAMES_SHORT[]; -extern const unsigned long DAYS_IN_MONTH[]; -extern const char *const DAY_NAMES_LONG[]; -extern const char *const DAY_NAMES_SHORT[]; -extern const char *const DAY_NAMES_ABBREV[]; -extern const TZ_STRUCT TZ_TABLE[]; - -long make_date(unsigned long secondsPastEpoch, time2_s *timeStruct); -const char *get_month_name_long(unsigned long month); -const char *get_month_name_short(unsigned long month); -const char *get_day_name_long(unsigned long day); -const char *get_day_name_short(unsigned long day); -const char *get_day_name_abrrev(unsigned long day); -long get_leap_years(unsigned long year); -unsigned long get_seconds_past_epoch(unsigned long nth, unsigned long day_name, unsigned long month, unsigned long year); -long is_leap_year(unsigned long year); -long range_check_time_struct(time2_s *ts); -unsigned long date_to_seconds(const time2_s *ts); -unsigned long time_to_seconds(const time2_s *ts); -unsigned long date_time_to_seconds(const time2_s *ts); -unsigned long get_local_time(void); -void get_precise_local_time(unsigned long *local_time); -long get_local_timezone(void); -long get_local_dst_active(void); -unsigned long time_to_short_string(const time2_s *ts, char *time_string); -unsigned long gmt_string_to_seconds(char *gmt_string, unsigned long *seconds); -unsigned long seconds_to_gmt_string(unsigned long seconds, char *gmt_string); -unsigned long diff_time(unsigned long t1, unsigned long t2); - -// This function is similar to the strcmp function in the string.h library -// It includes support for handling the NTP most significant bit rollover -// If t1 < t2 cmp_time returns -1 -// If t1 == t2 cmp_time returns 0 -// If t1 > t2 cmp_time returns 1 -long cmp_time(unsigned long t1, unsigned long t2); - -long diff_current_time(unsigned long t1, unsigned long *difference); -long parse_month(char *pString); -long parse_day_of_week(char *pString); -long parse_timezone(char *pString); -long parse_time(char *pString); - -/* - * Formats ulMilliseconds into elasped time in the form of - * HRS:MIN:SEC for less than 24 hours and then - * DAY(S) HRS:MIN:SEC for greater than 24 hours -*/ -void ascTimeDuration(unsigned long ulMilliseconds, char *ptimStr, int length); -void ascFormatDate(time2_s *ts, char * pDateStr, int length); -void ascFormatHrMinTime(time2_s *ts, char * pTimeStr, int length, char bFlashColon); -void FormatDateTime(char * ptimeStr, int length); -void FormatDebugTime(char *timeStr, int length,long ts); -char *GetDateTimeString(void); - -// Called once a second to update the time. Returns true indicating -// a roll-over indicating the display needs updated. -// Once a minute we need to update the time/date display and -// update the minute/hour/day etc. -// -int TimeOfDayUpdate(void); - -// Set the time of day clock -void SetTimeOfDay(time2_s *time); - -// Blank "turn off" the display of time -// called when there is a change to -// the time keeping systems on the phone -void ClearTimeDisplay(void); - -#endif diff --git a/libs/sipcc/core/includes/timer.h b/libs/sipcc/core/includes/timer.h deleted file mode 100755 index eb02e9e63f..0000000000 --- a/libs/sipcc/core/includes/timer.h +++ /dev/null @@ -1,49 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MGCP_TIMER_H -#define MGCP_TIMER_H - -#define TIMER_FREE 0x1 /* Indicates timer is free */ -#define TIMER_INITIALIZED 0x2 /* Indicates timer is initialized */ -#define TIMER_ACTIVE 0x4 /* Indicates timer is in list */ - -/* Timer event structure */ -typedef struct timer_struct -{ - unsigned int expiration_time; /* Expiration time */ - int interval; /* Timer period */ - void *parameter1; /* Timer expiration callback param */ - void *parameter2; /* Second timer expiration callback param */ - void (*expiration_callback) - (void *timer, void *parameter1, void *parameter2); /* Expiry handler */ - int flags; /* Debugging flags */ - struct timer_struct *pred; /* List predecessor */ - struct timer_struct *next; /* List successor */ -} timer_struct_type; - -extern unsigned long current_time(void); -extern void timer_event_activate(timer_struct_type *timer); -extern void *timer_event_allocate(void); -extern void timer_event_cancel(timer_struct_type *timer); -extern void timer_event_free(timer_struct_type *timer); -extern void timer_event_initialize(timer_struct_type *timer, - int period, - void (*expiration)(void *timer_event, - void *param1, - void *param2), - void *param1, void *param2); -extern void timer_event_process(void); -extern void timer_event_system_init(void); -extern boolean timer_expired(void); -extern void platform_timer_tick(void); -extern void platform_timer_init(void); - -#ifdef _WIN32 -extern void platform_timer_stop(void); -#endif -extern int timer_ms_to_ticks(int milliseconds); -extern boolean is_timer_active(timer_struct_type *timer); - -#endif diff --git a/libs/sipcc/core/includes/tnpphone.h b/libs/sipcc/core/includes/tnpphone.h deleted file mode 100644 index 80d4d62ac0..0000000000 --- a/libs/sipcc/core/includes/tnpphone.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef TNPPHONE_H -#define TNPPHONE_H - -#include "phone.h" - - -#ifdef SIP_OS_WINDOWS - - -#ifndef MAX_FILE_NAME -#define MAX_FILE_NAME 256 -#endif - -/* Defined in net_config.h */ -typedef struct -{ - uint8_t fName[MAX_FILE_NAME]; // Name of file being transfered - uint32_t rcvLen; - uint32_t maxSize; // The maximum size of the file to be read - uint8_t *fDest; // The destination address for transfer - uint32_t fHost; // Foreign IP address - uint16_t rtCode; - uint8_t taskId; - irx_lst_blk *pTaskList; -} TftpOpen; // TFTP Request - -#define CFG_PROGRAMMED 0x12300000L -#define CFG_PROGRAM_TFTP 0x12200000L -#define CFG_DHCP_DISABLE 0x00000001L -#define CFG_DHCP_TIMEOUT 0x00000002L -#define CFG_TFTP_TIMEOUT 0x00000004L -#define CFG_TFTP_NTFOUND 0x00000008L -#define CFG_TFTP_ACCESS 0x00000010L -#define CFG_TFTP_ERR 0x00000020L -#define CFG_DNS_ERROR 0x00000040L -#define CFG_DNS_TIMEOUT 0x00000080L -#define CFG_DNS_IP 0x00000100L -#define CFG_VER_ERR 0x00000200L -#define CFG_CKSUM_ERR 0x00000400L -//#define CFG_TFTP_FILE 0x00000800L -#define CFG_DFLT_GWY 0x00001000L -#define CFG_DUP_IP 0x00002000L -#define CFG_PATCHED 0x00004000L -#define CFG_LINK_DOWN 0x00008000L -#define CFG_FIXED_TFTP 0x00010000L -#define CFG_PROG_ERR 0x00020000L -#define CFG_BOOTP 0x00040000L -#define CFG_DHCP_RELEASE 0x00080000L - - -#ifndef ERROR -#define ERROR (-1) -#endif - -#ifndef PHONE_TICK_TO -#define PHONE_TICK_TO 10 -#endif - - -#endif -#endif diff --git a/libs/sipcc/core/includes/uart.h b/libs/sipcc/core/includes/uart.h deleted file mode 100755 index 30596cf4ea..0000000000 --- a/libs/sipcc/core/includes/uart.h +++ /dev/null @@ -1,119 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UART_H_ -#define _UART_H_ - -#include "cpr_types.h" - - -/* - * Telecaster specific defines - */ -#define SYSCLOCK ((unsigned long)25000000) /* 25 MHZ */ -#define UART_BASE_ADDRESS (UART_16550_REGS *)0xFFFE4000 - -/* - * 16550 register definition - */ -typedef struct { - volatile uint8_t dc; /* RBR/THR */ - volatile uint8_t ier; /* Interrupt Enable Reg */ - volatile uint8_t iir; /* Interrupt ID Reg */ - volatile uint8_t lcr; /* Line Control Reg / FIFO Control Reg */ - volatile uint8_t mcr; /* Modem Control Register */ - volatile uint8_t lsr; /* Line Status Register */ - volatile uint8_t msr; /* Modem Status Register */ - volatile uint8_t scr; /* Scratch Register */ -} UART_16550_REGS; - -/* - * UART register bit symbols - */ -#define UART_IER_MASK 0xF0 -#define IER_RX_IE 0x01 -#define IER_TX_IE 0x02 -#define IER_LS_IE 0x04 -#define IER_MS_IE 0x08 - -#define UART_IIR_RV 0x01 -#define IIR_IPEND 0x01 -#define IIR_MODEM_STAT 0x00 -#define IIR_TX_EMPTY 0x02 -#define IIR_RX_AVAIL 0x04 -#define IIR_RX_LINE_STAT 0x06 -#define IIR_CHAR_TIMOUT 0x0C - -#define UART_FCR_MASK 0x30 -#define FCR_FIFO_EN 0x01 -#define FCR_CLR_RXF 0x02 -#define FCR_CLR_TXF 0x04 -#define FCR_TRIGR_1BYT 0x00 -#define FCR_TRIGR_4BYT 0x40 -#define FCR_TRIGR_8BYT 0x80 -#define FCR_TRIGR_14BYT 0xC0 - -#define LCR_CHR_LEN_5BIT 0x00 -#define LCR_CHR_LEN_6BIT 0x01 -#define LCR_CHR_LEN_7BIT 0x02 -#define LCR_CHR_LEN_8BIT 0x03 -#define LCR_STOP1 0x00 -#define LCR_STOP2 0x04 -#define LCR_PAR_EN 0x08 -#define LCR_PAR_ODD 0x10 -#define LCR_FIX_PAR 0x20 -#define LCR_BRK_CTL 0x40 -#define LCR_DLAB 0x80 - -#define MCR_DTR 0x01 -#define MCR_RTS 0x02 -#define MCR_OUT1 0x04 -#define MCR_OUT2 0x08 -#define MCR_LPBK 0x10 -#define MCR_AUTO_FLW_EN 0x20 - -#define UART_LSR_RV 0x60 -#define LSR_RX_AVAIL 0x01 -#define LSR_OVRUN 0x02 -#define LSR_PAR_ERR 0x04 -#define LSR_FRAM_ERR 0x08 -#define LSR_BRK_INT 0x10 -#define LSR_TX_EMPTY 0x20 -#define LSR_XMITR_EMPTY 0x40 -#define LSR_RX_FIFO_ERR 0x80 - -#define UART_MSR_RV 0x00 -#define MSR_CTS_CHG 0x01 -#define MSR_DSR_CHG 0x02 -#define MSR_TERI 0x04 -#define MSR_CD_CHG 0x08 -#define MSR_CTS_IN 0x10 -#define MSR_DSR_IN 0x20 -#define MSR_RI_IN 0x40 -#define MSR_CD_IN 0x80 - - -#define DATAREADY 0x01 -#define XMITFIFOEMPTY 0x20 - - -#define RXLINESTATUS (3<<1) -#define RXDATAAVAIL (2<<1) -#define CHARTIMEOUT (6<<1) -#define TXEMPTY (1<<1) -#define MODEMSTATUS (0<<1) -#define RXERRORS 0x8E -#define DATAREADY 0x01 -#define XMITFIFOEMPTY 0x20 - - -#define TX_EMPTY 0x01 - -//extern int uart_init(int speed, char *buf, int buf_size); -extern int32_t uart_init(); -extern void uart_flush(int32_t dev); -extern int32_t uart_outc(int8_t c, void *); -extern int32_t uart_outs(int8_t *s, void *); - -#endif diff --git a/libs/sipcc/core/includes/uiapi.h b/libs/sipcc/core/includes/uiapi.h deleted file mode 100644 index 6604264eb1..0000000000 --- a/libs/sipcc/core/includes/uiapi.h +++ /dev/null @@ -1,164 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UIAPI_H_ -#define _UIAPI_H_ - -#include "cpr_types.h" -#include "phone_types.h" -#include "string_lib.h" -#include "vcm.h" -#include "ccapi.h" - -#include "sessionConstants.h" -typedef enum { - evMinEvent = 0, - evOffHook = OFFHOOK, - evOnHook = ONHOOK, - evRingOut = RINGOUT, - evRingIn = RINGIN, - evProceed = PROCEED, - evConnected = CONNECTED, - evHold = HOLD, - evRemHold = REMHOLD, - evResume = RESUME, - evBusy = BUSY, - evReorder = REORDER, - evConference = CONFERENCE, - evRemInUse = REMINUSE, - evCallPreservation = PRESERVATION, - evHoldRevert = HOLDREVERT, - evWhisper = WHISPER, - evWaitingForDigits = WAITINGFORDIGITS, - evCreateOffer = CREATEOFFER, - evCreateAnswer = CREATEANSWER, - evCreateOfferError = CREATEOFFERERROR, - evCreateAnswerError = CREATEANSWERERROR, - evSetLocalDesc = SETLOCALDESC, - evSetRemoteDesc = SETREMOTEDESC, - evSetLocalDescError = SETLOCALDESCERROR, - evSetRemoteDescError = SETREMOTEDESCERROR, - evOnRemoteStreamAdd = REMOTESTREAMADD, - evMaxEvent -} call_events; - -#define MWI_STATUS_YES 1 - -/* call operations : dialing, state change and info related */ -void ui_new_call(call_events event, line_t nLine, callid_t nCallID, - int call_attr, uint16_t call_instance_id, boolean dialed_digits); -void ui_set_call_attr(line_t line_id, callid_t call_id, call_attr_t attr); -void ui_call_info(string_t clgName, string_t clgNumber, string_t altClgNumber, boolean dispClgNumber, - string_t cldName, string_t cldNumber, boolean dispCldNumber, - string_t pOrigCalledNameStr, string_t pOrigCalledNumberStr, - string_t pLastRedirectingNameStr, - string_t pLastRedirectingNumberStr, - calltype_t call_type, - line_t line, callid_t call_id, uint16_t call_instance_id, - cc_security_e call_security, cc_policy_e call_policy); -void ui_cc_capability(line_t line_id, callid_t call_id, - string_t recv_info_list); -void ui_info_received(line_t line_id, callid_t call_id, - const char *info_package, const char *content_type, - const char *message_body); -void ui_update_placed_call_info(line_t line, callid_t call_id, string_t cldName, - string_t cldNumber); -void ui_log_disposition( callid_t nCallID, int logDisp); -void ui_call_state(call_events event, line_t nLine, callid_t nCallID, cc_causes_t cause); -void ui_set_local_hold(line_t line, callid_t call_id); -void ui_delete_last_digit(line_t line_id, callid_t call_id); -void ui_update_label_n_speeddial(line_t line, line_t button_no, string_t - speed_dial, string_t label); -void ui_mnc_reached(line_t line, boolean mnc_reached); - -void ui_call_selected(line_t line_id, callid_t call_id, int selected); -void ui_call_in_preservation(line_t line_id, callid_t call_id); -void ui_update_call_security(line_t line, callid_t call_id, - cc_security_e call_security); -void ui_update_conf_invoked(line_t line, callid_t call_id, - boolean invoked); -void ui_terminate_feature(line_t line, callid_t call_id, - callid_t target_call_id); - -void ui_update_gcid(line_t line, callid_t call_id, char *gcid); -void ui_update_callref(line_t line, callid_t call_id, unsigned int callref); - -/* status line related */ -void ui_set_call_status(string_t pString, line_t line, callid_t callID); -char *ui_get_idle_prompt_string(void); -void ui_set_idle_prompt_string(string_t pString, int prompt); -void ui_set_notification(line_t line, callid_t callID, - char *promptString, int timeout, - boolean notifyProgress, char priority); -void ui_clear_notification(); - -/* softkey manipulation */ -void ui_control_feature(line_t line_id, callid_t call_id, int list[], int len, int enable); -void ui_select_feature_key_set(line_t line_id, callid_t call_id, char *set_name, - int sk_list[], int len); -void ui_control_featurekey_bksp(line_t line_id, callid_t call_id, - boolean enable); - -/* speaker */ -void ui_set_speaker_mode(boolean mode); - -/* mwi */ -void ui_set_mwi(line_t line, boolean status, int type, int newCount, int oldCount, int hpNewCount, int hpOldCount); -void ui_change_mwi_lamp(int status); -boolean ui_line_has_mwi_active(line_t line); - -/* call forward */ -void ui_cfwd_status(line_t line, boolean cfa, char *cfa_number, - boolean lcl_fwd); - -/* registration, stack init related */ -void ui_sip_config_done(void); -void ui_set_sip_registration_state(line_t line, boolean registered); -void ui_reg_all_failed(void); - -void ui_keypad_button(char *digitstr, int direction); - -void ui_offhook(line_t line, callid_t call_id); -void ui_dial_call(line_t line, callid_t call_id, char *to, - char *global_call_id); -int ui_dial_digits(line_t line, char *digitstr); -int ui_dial_dtmf(line_t line, char *digitstr); -void ui_answer_call(line_t line, callid_t call_id); -void ui_disconnect_call(line_t line, callid_t call_id); -int ui_xfer_setup(line_t line, callid_t call_id, char *to, - char *global_call_id, boolean media); -void ui_xfer_complete(line_t line, callid_t call_id, callid_t consult_call_id); -int ui_conf_setup(line_t line, callid_t call_id, char *to, - char *global_call_id); -void ui_conf_complete(line_t line, callid_t call_id, callid_t consult_call_id); -int ui_hold_call(line_t line, callid_t call_id); -void ui_hold_retrieve_call(line_t line, callid_t call_id); -void ui_cfwdall_req(unsigned int line); - -/* Test Interface */ -void ui_execute_uri(char *); - -/* Status Message Interface */ -void ui_log_status_msg(char *msg); - -void ui_init_ccm_conn_status(void); -void ui_update_video_avail (line_t line, callid_t call_id, int avail); -void ui_update_video_offered (line_t line, callid_t call_id, int dir); -void ui_call_stop_ringer(line_t line, callid_t call_id); -void ui_call_start_ringer(vcm_ring_mode_t ringMode, short once, line_t line, callid_t call_id); -void ui_BLF_notification (int request_id, cc_blf_state_t blf_state, int app_id); -void ui_update_media_interface_change(line_t line, callid_t call_id, group_call_event_t event); -void ui_create_offer(call_events event, line_t nLine, callid_t nCallID, - uint16_t call_instance_id, char* sdp); -void ui_create_answer(call_events event, line_t nLine, callid_t nCallID, - uint16_t call_instance_id, char* sdp); -void ui_set_local_description(call_events event, line_t nLine, callid_t nCallID, - uint16_t call_instance_id, char* sdp, cc_int32_t status); -void ui_set_remote_description(call_events event, line_t nLine, callid_t nCallID, - uint16_t call_instance_id, char* sdp, cc_int32_t status); -void ui_on_remote_stream_added(call_events event, line_t nLine, callid_t nCallID, - uint16_t call_instance_id, cc_media_remote_track_table_t media_tracks); - - -#endif diff --git a/libs/sipcc/core/includes/upgrade.h b/libs/sipcc/core/includes/upgrade.h deleted file mode 100644 index 96f2bd987e..0000000000 --- a/libs/sipcc/core/includes/upgrade.h +++ /dev/null @@ -1,37 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UPGRADE_INCLUDED_H -#define _UPGRADE_INCLUDED_H - -#include "cpr_types.h" -#include "phone.h" - -/* - * Telecaster has these extra 32 bytes of data - * in front of the load header. I have no idea what - * they are for, but having a structure makes it easier - * to deal with this as opposed to adding 0x20 to the - * address. - */ -typedef struct -{ - uint8_t vectors[0x20]; - LoadHdr hdr; -} BigLoadHdr; - -/* - * Prototypes for public functions - */ -void upgrade_bootup_init(void); -int upgrade_done(int tftp_rc); -void upgrade_start(const char *fname); -void upgrade_memcpy(void *dst, const void *src, int len); -int upgrade_check(const char *loadid); -int upgrade_validate_app_image(const BigLoadHdr *load); -int upgrade_validate_dsp_image(const DSPLoadHdr *dsp); -void upgrade_erase_dir_storage(void); -void upgrade_write_dir_storage(char *buffer, char *flash, int size); - -#endif /* _UPGRADE_INCLUDED_H */ diff --git a/libs/sipcc/core/includes/util_ios_queue.h b/libs/sipcc/core/includes/util_ios_queue.h deleted file mode 100644 index 98ad646c73..0000000000 --- a/libs/sipcc/core/includes/util_ios_queue.h +++ /dev/null @@ -1,59 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UTIL_IOS_QUEUE_H -#define _UTIL_IOS_QUEUE_H - -/* - * Define the queue data type and a basic enqueue structure - */ - -typedef struct queuetype_ { - void *qhead; /* head of queue */ - void *qtail; /* tail of queue */ - int count; /* possible count */ - int maximum; /* maximum entries */ -} queuetype; - -typedef queuetype *queue_ptr_t; - -typedef struct nexthelper_ -{ - struct nexthelper_ *next; - unsigned char data[4]; -} queue_node, nexthelper, *node_ptr_t; - -typedef enum get_node_status_ { - GET_NODE_FAIL_EMPTY_LIST, - GET_NODE_FAIL_END_OF_LIST, - GET_NODE_SUCCESS -} get_node_status; - -void queue_init(queuetype *q, int maximum); -void *peekqueuehead(queuetype* q); - -/*Functions used by SIP */ -int queryqueuedepth(queuetype const *q); -boolean checkqueue(queuetype *q, void *e); -void *p_dequeue(queuetype *qptr); -void p_enqueue(queuetype *qptr, void *eaddr); -void p_requeue(queuetype *qptr, void *eaddr); -void p_swapqueue(queuetype *qptr, void *enew, void *eold); -void p_unqueue(queuetype *q, void *e); -void p_unqueuenext(queuetype *q, void **prev); -void enqueue(queuetype *qptr, void *eaddr); -void *dequeue(queuetype *qptr); -void unqueue(queuetype *q, void *e); -void requeue(queuetype *qptr, void *eaddr); -void *remqueue(queuetype *qptr, void *eaddr, void *paddr); -void insqueue(queuetype *qptr, void *eaddr, void *paddr); -boolean queueBLOCK(queuetype *qptr); -boolean validqueue(queuetype *qptr, boolean print_message); - -boolean queue_create_init(queue_ptr_t *queue); -void add_list(queue_ptr_t queue, node_ptr_t node); -get_node_status get_node(queue_ptr_t queue, node_ptr_t *node); -void queue_delete(queue_ptr_t queue); - -#endif diff --git a/libs/sipcc/core/includes/util_parse.h b/libs/sipcc/core/includes/util_parse.h deleted file mode 100644 index e3341124a2..0000000000 --- a/libs/sipcc/core/includes/util_parse.h +++ /dev/null @@ -1,12 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UTIL_PARSE_H_ -#define _UTIL_PARSE_H_ - -#include "xml_defs.h" - -XMLToken parse_xml_tokens(char **parseptr, char *value, int maxlen); - -#endif diff --git a/libs/sipcc/core/includes/util_string.h b/libs/sipcc/core/includes/util_string.h deleted file mode 100644 index 04a53d9ecc..0000000000 --- a/libs/sipcc/core/includes/util_string.h +++ /dev/null @@ -1,28 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UTIL_STRING_H_ -#define _UTIL_STRING_H_ - -#include "cpr_types.h" -#include "cpr_socket.h" - -#define EMPTY_STR "" -#define EMPTY_STR_LEN 1 - -boolean is_empty_str(char *str); -void init_empty_str(char *str); - -void ipaddr2dotted(char *addr_str, cpr_ip_addr_t *addr); -uint32_t dotted2ipaddr(const char *addr_str); -int str2ip(const char *str, cpr_ip_addr_t *addr); -void util_ntohl(cpr_ip_addr_t *ip_addr_out, cpr_ip_addr_t *ip_addr_in); -boolean util_compare_ip(cpr_ip_addr_t *ip_add1, cpr_ip_addr_t *ip_addr2); -void util_extract_ip(cpr_ip_addr_t *ip_addr, cpr_sockaddr_storage *from); -uint16_t util_get_port(cpr_sockaddr_storage *sock_storage); -void util_get_ip_using_mode(cpr_ip_addr_t *ip_addr, cpr_ip_mode_e ip_mode, - uint32_t ip4, char *ip6); -boolean util_check_if_ip_valid(cpr_ip_addr_t *ip_addr); - -#endif diff --git a/libs/sipcc/core/includes/www.h b/libs/sipcc/core/includes/www.h deleted file mode 100644 index e5c40b01ea..0000000000 --- a/libs/sipcc/core/includes/www.h +++ /dev/null @@ -1,25 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _WWW_H_ -#define _WWW_H_ - -#define MAXCHARSPERLINE 400 - -typedef struct { - int soc; - unsigned char buf[MAXCHARSPERLINE]; - unsigned char text[MAXCHARSPERLINE]; - int idx, n, clen, send; -} WWWRBuf; - -extern int Connect2WWW(char *hostName); -extern int Connect2WWWIPPort(unsigned long nIPAddr, unsigned short nPort, - char *hostName); -extern void wwwSend(WWWRBuf *wrb, char *fmt, ...); -extern boolean www_proxy_used(int connection); -extern boolean www_socket_open(int connection); -extern void HTTP_Init_ConnTbl(); - -#endif diff --git a/libs/sipcc/core/includes/xml_defs.h b/libs/sipcc/core/includes/xml_defs.h deleted file mode 100644 index b91558f30a..0000000000 --- a/libs/sipcc/core/includes/xml_defs.h +++ /dev/null @@ -1,51 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _XML_DEFS_H_ -#define _XML_DEFS_H_ - -#include "cpr_types.h" - -#define TOK_MAX_LEN (24) - -#define TOK_NONE (0) -#define TOK_PROC (1) -#define TOK_ELEMENT (2) -#define TOK_ATTRIBUTE (3) -#define TOK_CONTENT (4) - -#define XML_START (1199) -#define XML_END (1200) -#define XML_CONTENT (1201) -#define XML_ALL_CONTENT (1202) - -typedef struct XMLTokenStruc { - const int8_t strTok[TOK_MAX_LEN]; - int16_t TokType; - void *pData; // This may be another XMLTable, - // or an array of valid attribute values. -} XMLTokenStruc; - -typedef void (*XmlFunc)(int16_t, void *); - -typedef struct XMLTableStruc { - void (*xml_func)( int16_t TokID, void *pData ); - uint8_t nNumTok; - const XMLTokenStruc *pTok; -} XMLTableStruc; - -typedef enum { - TOK_ERR, - TOK_EOF, /* reached end of the input */ - TOK_LBRACKET, /* "<" */ - TOK_ENDLBRACKET, /* "" */ - TOK_RBRACKET, /* ">" */ - TOK_EQ, /* "=" */ - TOK_STR, /* string on the rhs of = */ - TOK_KEYWORD, /* string on lhs of = */ - TOK_CONTENT_STR -} XMLToken; - -#endif diff --git a/libs/sipcc/core/sdp/ccsdp.c b/libs/sipcc/core/sdp/ccsdp.c deleted file mode 100644 index 585a9549cd..0000000000 --- a/libs/sipcc/core/sdp/ccsdp.c +++ /dev/null @@ -1,326 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "sdp.h" -#include "ccapi.h" - - -const char* ccsdpAttrGetFmtpParamSets(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return NULL; - } - return sdp_attr_get_fmtp_param_sets(sdpp->dest_sdp, level, cap_num, inst_num); -} - -sdp_result_e ccsdpAttrGetFmtpPackMode(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_pack_mode(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAttrGetFmtpLevelAsymmetryAllowed(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_level_asymmetry_allowed(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -const char* ccsdpAttrGetFmtpProfileLevelId (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return NULL; - } - return sdp_attr_get_fmtp_profile_id(sdpp->dest_sdp, level, cap_num, inst_num); -} - - - -sdp_result_e ccsdpAttrGetFmtpMaxMbps (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_mbps(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAttrGetFmtpMaxFs (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_fs(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAttrGetFmtpMaxCpb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_cpb(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAttrGetFmtpMaxBr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32* val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_br(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -int ccsdpGetBandwidthValue (void *sdp_ptr, u16 level, u16 inst_num) - -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_get_bw_value(sdpp->dest_sdp, level, inst_num); -} - -sdp_result_e ccsdpAttrGetFmtpMaxDpb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_dpb(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAddNewAttr (void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e attr_type, u16 *inst_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_add_new_attr(sdpp->src_sdp, level, cap_num, attr_type, inst_num); -} - -sdp_result_e ccsdpAttrSetFmtpPayloadType (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 payload_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_payload_type(sdpp->src_sdp, level, cap_num, inst_num, payload_num); -} - - -sdp_result_e ccsdpAttrSetFmtpPackMode (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 pack_mode) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_pack_mode(sdpp->src_sdp, level, cap_num, inst_num, pack_mode); -} - -sdp_result_e ccsdpAttrSetFmtpLevelAsymmetryAllowed (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 asym_allowed) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_level_asymmetry_allowed(sdpp->src_sdp, level, cap_num, inst_num, asym_allowed); -} - - -sdp_result_e ccsdpAttrSetFmtpProfileLevelId (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, const char *profile_level_id) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_profile_level_id(sdpp->src_sdp, level, cap_num, inst_num, profile_level_id); -} - - -sdp_result_e ccsdpAttrSetFmtpParameterSets (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, const char *parameter_sets) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_parameter_sets(sdpp->src_sdp, level, cap_num, inst_num, parameter_sets); -} - - - -sdp_result_e ccsdpAttrSetFmtpMaxBr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 max_br) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_br(sdpp->src_sdp, level, cap_num, inst_num, max_br); -} - - -sdp_result_e ccsdpAttrSetFmtpMaxMbps (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 max_mbps) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_mbps(sdpp->src_sdp, level, cap_num, inst_num, max_mbps); -} - -sdp_result_e ccsdpAttrSetFmtpMaxFs (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 max_fs) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_fs(sdpp->src_sdp, level, cap_num, inst_num, max_fs); -} - -sdp_result_e ccsdpAttrSetFmtpMaxCpb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 max_cpb) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_cpb(sdpp->src_sdp, level, cap_num, inst_num, max_cpb); -} - -sdp_result_e ccsdpAttrSetFmtpMaxDbp (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 max_dpb) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_dpb(sdpp->src_sdp, level, cap_num, inst_num, max_dpb); -} - - -sdp_result_e ccsdpAttrSetFmtpQcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 qcif) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_qcif(sdpp->src_sdp, level, cap_num, inst_num, qcif); -} - -sdp_result_e ccsdpAttrSetFmtpSqcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 sqcif) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_sqcif(sdpp->src_sdp, level, cap_num, inst_num, sqcif); -} - -sdp_result_e ccsdpAddNewBandwidthLine (void *sdp_ptr, u16 level, sdp_bw_modifier_e bw_modifier, u16 *inst_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_add_new_bw_line(sdpp->src_sdp, level, bw_modifier, inst_num); -} - - -sdp_result_e ccsdpSetBandwidth (void *sdp_ptr, u16 level, u16 inst_num, - sdp_bw_modifier_e bw_modifier, u32 bw_val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_set_bw(sdpp->src_sdp, level, inst_num, bw_modifier, bw_val); -} - -const char * ccsdpCodecName(rtp_ptype ptype) -{ - switch (ptype) - { - case RTP_NONE: return "NONE"; - case RTP_PCMU: return "PCMU"; - case RTP_CELP: return "CELP"; - case RTP_G726: return "G726"; - case RTP_GSM: return "GSM"; - case RTP_G723: return "G723"; - case RTP_DVI4: return "DVI4"; - case RTP_DVI4_II: return "DVI4_II"; - case RTP_LPC: return "LPC"; - case RTP_PCMA: return "PCMA"; - case RTP_G722: return "G722"; - case RTP_G728: return "G728"; - case RTP_G729: return "G729"; - case RTP_JPEG: return "JPEG"; - case RTP_NV: return "NV"; - case RTP_H261: return "H261"; - case RTP_H264_P0: return "H264_P0"; - case RTP_H264_P1: return "H264_P1"; - case RTP_AVT: return "AVT"; - case RTP_L16: return "L16"; - case RTP_H263: return "H263"; - case RTP_ILBC: return "iLBC"; - case RTP_OPUS: return "OPUS"; - case RTP_VP8: return "VP8"; - case RTP_I420: return "I420"; - /* case RTP_ISAC: return "ISAC"; */ - } - return "UNKNOWN"; -} - diff --git a/libs/sipcc/core/sdp/sdp.h b/libs/sipcc/core/sdp/sdp.h deleted file mode 100644 index a7ad11db6e..0000000000 --- a/libs/sipcc/core/sdp/sdp.h +++ /dev/null @@ -1,2010 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SDP_H_ -#define _SDP_H_ - -#include "cc_constants.h" -#include "sdp_os_defs.h" -#include "ccsdp.h" - -/* SDP Defines */ - -/* The following defines are used to indicate params that are specified - * as the choose parameter or parameters that are invalid. These can - * be used where the value required is really a u16, but is represented - * by an int32. - */ -#define SDP_CHOOSE_PARAM (-1) -#define SDP_SESSION_LEVEL 0xFFFF - -#define UNKNOWN_CRYPTO_SUITE "UNKNOWN_CRYPTO_SUITE" -#define AES_CM_128_HMAC_SHA1_32 "AES_CM_128_HMAC_SHA1_32" -#define AES_CM_128_HMAC_SHA1_80 "AES_CM_128_HMAC_SHA1_80" -#define F8_128_HMAC_SHA1_80 "F8_128_HMAC_SHA1_80" - -/* - * SDP_SRTP_MAX_KEY_SIZE_BYTES - * Maximum size for a SRTP Master Key in bytes. - */ -#define SDP_SRTP_MAX_KEY_SIZE_BYTES 16 -/* - * SDP_SRTP_MAX_SALT_SIZE_BYTES - * Maximum size for a SRTP Master Salt in bytes. - */ -#define SDP_SRTP_MAX_SALT_SIZE_BYTES 14 -/* - * SDP_SRTP_MAX_MKI_SIZE_BYTES - * Maximum size for a SRTP Master Key Index in bytes. - */ -#define SDP_SRTP_MAX_MKI_SIZE_BYTES 4 - -/* Max number of characters for Lifetime */ -#define SDP_SRTP_MAX_LIFETIME_BYTES 16 - -#define SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN 0 -#define SDP_SRTP_CRYPTO_SELECTION_FLAGS_UNKNOWN 0 - -/* - * SRTP_CONTEXT_SET_* - * Set a SRTP Context field flag - */ -#define SDP_SRTP_ENCRYPT_MASK 0x00000001 -#define SDP_SRTP_AUTHENTICATE_MASK 0x00000002 -#define SDP_SRTCP_ENCRYPT_MASK 0x00000004 -#define SDP_SRTCP_SSRC_MASK 0x20000000 -#define SDP_SRTCP_ROC_MASK 0x10000000 -#define SDP_SRTCP_KDR_MASK 0x08000000 -#define SDP_SRTCP_KEY_MASK 0x80000000 -#define SDP_SRTCP_SALT_MASK 0x40000000 - -#define SDP_SRTP_CONTEXT_SET_SSRC(cw) ((cw) |= SDP_SRTCP_SSRC_MASK) -#define SDP_SRTP_CONTEXT_SET_ROC(cw) ((cw) |= SDP_SRTCP_ROC_MASK) -#define SDP_SRTP_CONTEXT_SET_KDR(cw) ((cw) |= SDP_SRTCP_KDR_MASK) -#define SDP_SRTP_CONTEXT_SET_MASTER_KEY(cw) ((cw) |= SDP_SRTCP_KEY_MASK) -#define SDP_SRTP_CONTEXT_SET_MASTER_SALT(cw) ((cw) |= SDP_SRTCP_SALT_MASK) -#define SDP_SRTP_CONTEXT_SET_ENCRYPT_AUTHENTICATE(cw) \ - ((cw) |= (SDP_SRTP_ENCRYPT_MASK | SDP_SRTP_AUTHENTICATE_MASK | \ - SDP_SRTCP_ENCRYPT_MASK)) - -#define SDP_SRTP_CONTEXT_RESET_SSRC(cw) ((cw) &= ~(SDP_SRTCP_SSRC_MASK)) -#define SDP_SRTP_CONTEXT_RESET_ROC(cw) ((cw) &= ~(SDP_SRTCP_ROC_MASK)) -#define SDP_SRTP_CONTEXT_RESET_KDR(cw) ((cw) &= ~(SDP_SRTCP_KDR_MASK)) -#define SDP_CONTEXT_RESET_MASTER_KEY(cw) ((cw) &= ~(SDP_SRTCP_KEY_MASK)) -#define SDP_CONTEXT_RESET_MASTER_SALT(cw) ((cw) &= ~(SDP_SRTCP_SALT_MASK)) - -/* SDP Enum Types */ - -typedef enum { - SDP_DEBUG_TRACE, - SDP_DEBUG_WARNINGS, - SDP_DEBUG_ERRORS, - SDP_MAX_DEBUG_TYPES -} sdp_debug_e; - -typedef enum { - SDP_CHOOSE_CONN_ADDR, - SDP_CHOOSE_PORTNUM, - SDP_MAX_CHOOSE_PARAMS -} sdp_choose_param_e; - - -/* Token Lines - these must be in the same order they should - * appear in an SDP. - */ -typedef enum { - SDP_TOKEN_V = 0, - SDP_TOKEN_O, - SDP_TOKEN_S, - SDP_TOKEN_I, - SDP_TOKEN_U, - SDP_TOKEN_E, - SDP_TOKEN_P, - SDP_TOKEN_C, - SDP_TOKEN_B, - SDP_TOKEN_T, - SDP_TOKEN_R, - SDP_TOKEN_Z, - SDP_TOKEN_K, - SDP_TOKEN_A, - SDP_TOKEN_M, - SDP_MAX_TOKENS -} sdp_token_e; - -/* Media Types */ -typedef enum { - SDP_MEDIA_AUDIO = 0, - SDP_MEDIA_VIDEO, - SDP_MEDIA_APPLICATION, - SDP_MEDIA_DATA, - SDP_MEDIA_CONTROL, - SDP_MEDIA_NAS_RADIUS, - SDP_MEDIA_NAS_TACACS, - SDP_MEDIA_NAS_DIAMETER, - SDP_MEDIA_NAS_L2TP, - SDP_MEDIA_NAS_LOGIN, - SDP_MEDIA_NAS_NONE, - SDP_MEDIA_TEXT, - SDP_MEDIA_IMAGE, - SDP_MAX_MEDIA_TYPES, - SDP_MEDIA_UNSUPPORTED, - SDP_MEDIA_INVALID -} sdp_media_e; - - -/* Connection Network Type */ -typedef enum { - SDP_NT_INTERNET = 0, /* 0 -> IP - In SDP "IN" is defined */ - /* to mean "Internet" */ - SDP_NT_ATM, /* 1 -> ATM */ - SDP_NT_FR, /* 2 -> FRAME RELAY */ - SDP_NT_LOCAL, /* 3 -> local */ - SDP_MAX_NETWORK_TYPES, - SDP_NT_UNSUPPORTED, - SDP_NT_INVALID -} sdp_nettype_e; - - -/* Address Type */ -typedef enum { - SDP_AT_IP4 = 0, /* 0 -> IP Version 4 (IP4) */ - SDP_AT_IP6, /* 1 -> IP Version 6 (IP6) */ - SDP_AT_NSAP, /* 2 -> 20 byte NSAP address */ - SDP_AT_EPN, /* 3 -> 32 bytes of endpoint name */ - SDP_AT_E164, /* 4 -> 15 digit decimal number addr */ - SDP_AT_GWID, /* 5 -> Private gw id. ASCII string */ - SDP_MAX_ADDR_TYPES, - SDP_AT_UNSUPPORTED, - SDP_AT_FQDN, - SDP_AT_INVALID -} sdp_addrtype_e; - - -/* Transport Types */ - -#define SDP_MAX_PROFILES 3 - -typedef enum { - SDP_TRANSPORT_RTPAVP = 0, - SDP_TRANSPORT_UDP, - SDP_TRANSPORT_UDPTL, - SDP_TRANSPORT_CES10, - SDP_TRANSPORT_LOCAL, - SDP_TRANSPORT_AAL2_ITU, - SDP_TRANSPORT_AAL2_ATMF, - SDP_TRANSPORT_AAL2_CUSTOM, - SDP_TRANSPORT_AAL1AVP, - SDP_TRANSPORT_UDPSPRT, - SDP_TRANSPORT_RTPSAVP, - SDP_TRANSPORT_TCP, - SDP_TRANSPORT_RTPSAVPF, - SDP_TRANSPORT_SCTPDTLS, - SDP_MAX_TRANSPORT_TYPES, - SDP_TRANSPORT_UNSUPPORTED, - SDP_TRANSPORT_INVALID -} sdp_transport_e; - - -/* Encryption KeyType */ -typedef enum { - SDP_ENCRYPT_CLEAR, /* 0 -> Key given in the clear */ - SDP_ENCRYPT_BASE64, /* 1 -> Base64 encoded key */ - SDP_ENCRYPT_URI, /* 2 -> Ptr to URI */ - SDP_ENCRYPT_PROMPT, /* 3 -> No key included, prompt user */ - SDP_MAX_ENCRYPT_TYPES, - SDP_ENCRYPT_UNSUPPORTED, - SDP_ENCRYPT_INVALID -} sdp_encrypt_type_e; - - -/* Known string payload types */ -typedef enum { - SDP_PAYLOAD_T38, - SDP_PAYLOAD_XTMR, - SDP_PAYLOAD_T120, - SDP_MAX_STRING_PAYLOAD_TYPES, - SDP_PAYLOAD_UNSUPPORTED, - SDP_PAYLOAD_INVALID -} sdp_payload_e; - - -/* Payload type indicator */ -typedef enum { - SDP_PAYLOAD_NUMERIC, - SDP_PAYLOAD_ENUM -} sdp_payload_ind_e; - - -/* Image payload types */ -typedef enum { - SDP_PORT_NUM_ONLY, /* or '$' */ - SDP_PORT_NUM_COUNT, /* / */ - SDP_PORT_VPI_VCI, /* / */ - SDP_PORT_VCCI, /* */ - SDP_PORT_NUM_VPI_VCI, /* // */ - SDP_PORT_VCCI_CID, /* / or '$'/'$' */ - SDP_PORT_NUM_VPI_VCI_CID, /* /// */ - SDP_MAX_PORT_FORMAT_TYPES, - SDP_PORT_FORMAT_INVALID -} sdp_port_format_e; - - -/* Fmtp attribute format Types */ -typedef enum { - SDP_FMTP_NTE, - SDP_FMTP_CODEC_INFO, - SDP_FMTP_MODE, - SDP_FMTP_DATACHANNEL, - SDP_FMTP_UNKNOWN_TYPE, - SDP_FMTP_MAX_TYPE -} sdp_fmtp_format_type_e; - - -/* T.38 Rate Mgmt Types */ -typedef enum { - SDP_T38_LOCAL_TCF, - SDP_T38_TRANSFERRED_TCF, - SDP_T38_UNKNOWN_RATE, - SDP_T38_MAX_RATES -} sdp_t38_ratemgmt_e; - - -/* T.38 udp EC Types */ -typedef enum { - SDP_T38_UDP_REDUNDANCY, - SDP_T38_UDP_FEC, - SDP_T38_UDPEC_UNKNOWN, - SDP_T38_MAX_UDPEC -} sdp_t38_udpec_e; - -/* Bitmaps for manipulating sdp_direction_e */ -typedef enum { - SDP_DIRECTION_FLAG_SEND=0x01, - SDP_DIRECTION_FLAG_RECV=0x02 -} sdp_direction_flag_e; - -/* Media flow direction */ -typedef enum { - SDP_DIRECTION_INACTIVE = 0, - SDP_DIRECTION_SENDONLY = SDP_DIRECTION_FLAG_SEND, - SDP_DIRECTION_RECVONLY = SDP_DIRECTION_FLAG_RECV, - SDP_DIRECTION_SENDRECV = SDP_DIRECTION_FLAG_SEND | SDP_DIRECTION_FLAG_RECV, - SDP_MAX_QOS_DIRECTIONS -} sdp_direction_e; - -#define SDP_DIRECTION_PRINT(arg) \ - (((sdp_direction_e)(arg)) == SDP_DIRECTION_INACTIVE ? "SDP_DIRECTION_INACTIVE " : \ - ((sdp_direction_e)(arg)) == SDP_DIRECTION_SENDONLY ? "SDP_DIRECTION_SENDONLY": \ - ((sdp_direction_e)(arg)) == SDP_DIRECTION_RECVONLY ? "SDP_DIRECTION_RECVONLY ": \ - ((sdp_direction_e)(arg)) == SDP_DIRECTION_SENDRECV ? " SDP_DIRECTION_SENDRECV": "SDP_MAX_QOS_DIRECTIONS") - - -/* QOS Strength tag */ -typedef enum { - SDP_QOS_STRENGTH_OPT, - SDP_QOS_STRENGTH_MAND, - SDP_QOS_STRENGTH_SUCC, - SDP_QOS_STRENGTH_FAIL, - SDP_QOS_STRENGTH_NONE, - SDP_MAX_QOS_STRENGTH, - SDP_QOS_STRENGTH_UNKNOWN -} sdp_qos_strength_e; - - -/* QOS direction */ -typedef enum { - SDP_QOS_DIR_SEND, - SDP_QOS_DIR_RECV, - SDP_QOS_DIR_SENDRECV, - SDP_QOS_DIR_NONE, - SDP_MAX_QOS_DIR, - SDP_QOS_DIR_UNKNOWN -} sdp_qos_dir_e; - -/* QoS Status types */ -typedef enum { - SDP_QOS_LOCAL, - SDP_QOS_REMOTE, - SDP_QOS_E2E, - SDP_MAX_QOS_STATUS_TYPES, - SDP_QOS_STATUS_TYPE_UNKNOWN -} sdp_qos_status_types_e; - -/* QoS Status types */ -typedef enum { - SDP_CURR_QOS_TYPE, - SDP_CURR_UNKNOWN_TYPE, - SDP_MAX_CURR_TYPES -} sdp_curr_type_e; - -/* QoS Status types */ -typedef enum { - SDP_DES_QOS_TYPE, - SDP_DES_UNKNOWN_TYPE, - SDP_MAX_DES_TYPES -} sdp_des_type_e; - -/* QoS Status types */ -typedef enum { - SDP_CONF_QOS_TYPE, - SDP_CONF_UNKNOWN_TYPE, - SDP_MAX_CONF_TYPES -} sdp_conf_type_e; - - -/* Named event range result values. */ -typedef enum { - SDP_NO_MATCH, - SDP_PARTIAL_MATCH, - SDP_FULL_MATCH -} sdp_ne_res_e; - -/* Fmtp attribute parameters for audio/video codec information */ -typedef enum { - - /* mainly for audio codecs */ - SDP_ANNEX_A, /* 0 */ - SDP_ANNEX_B, - SDP_BITRATE, - - /* for video codecs */ - SDP_QCIF, - SDP_CIF, - SDP_MAXBR, - SDP_SQCIF, - SDP_CIF4, - SDP_CIF16, - SDP_CUSTOM, - SDP_PAR, - SDP_CPCF, - SDP_BPP, - SDP_HRD, - SDP_PROFILE, - SDP_LEVEL, - SDP_INTERLACE, - - /* H.264 related */ - SDP_PROFILE_LEVEL_ID, /* 17 */ - SDP_PARAMETER_SETS, - SDP_PACKETIZATION_MODE, - SDP_INTERLEAVING_DEPTH, - SDP_DEINT_BUF_REQ, - SDP_MAX_DON_DIFF, - SDP_INIT_BUF_TIME, - - SDP_MAX_MBPS, - SDP_MAX_FS, - SDP_MAX_CPB, - SDP_MAX_DPB, - SDP_MAX_BR, - SDP_REDUNDANT_PIC_CAP, - SDP_DEINT_BUF_CAP, - SDP_MAX_RCMD_NALU_SIZE, - - SDP_PARAMETER_ADD, - - /* Annexes - begin */ - /* Some require special handling as they don't have token=token format*/ - SDP_ANNEX_D, - SDP_ANNEX_F, - SDP_ANNEX_I, - SDP_ANNEX_J, - SDP_ANNEX_T, - - /* These annexes have token=token format */ - SDP_ANNEX_K, - SDP_ANNEX_N, - SDP_ANNEX_P, - - SDP_MODE, - SDP_LEVEL_ASYMMETRY_ALLOWED, - SDP_MAX_AVERAGE_BIT_RATE, - SDP_USED_TX, - SDP_STEREO, - SDP_USE_IN_BAND_FEC, - SDP_MAX_CODED_AUDIO_BW, - SDP_CBR, - SDP_STREAMS, - SDP_PROTOCOL, - SDP_MAX_FMTP_PARAM, - SDP_FMTP_PARAM_UNKNOWN -} sdp_fmtp_codec_param_e; - -/* Fmtp attribute parameters values for - fmtp attribute parameters which convey codec - information */ - -typedef enum { - SDP_YES, - SDP_NO, - SDP_MAX_FMTP_PARAM_VAL, - SDP_FMTP_PARAM_UNKNOWN_VAL -} sdp_fmtp_codec_param_val_e; - -/* silenceSupp suppPref */ -typedef enum { - SDP_SILENCESUPP_PREF_STANDARD, - SDP_SILENCESUPP_PREF_CUSTOM, - SDP_SILENCESUPP_PREF_NULL, /* "-" */ - SDP_MAX_SILENCESUPP_PREF, - SDP_SILENCESUPP_PREF_UNKNOWN -} sdp_silencesupp_pref_e; - -/* silenceSupp sidUse */ -typedef enum { - SDP_SILENCESUPP_SIDUSE_NOSID, - SDP_SILENCESUPP_SIDUSE_FIXED, - SDP_SILENCESUPP_SIDUSE_SAMPLED, - SDP_SILENCESUPP_SIDUSE_NULL, /* "-" */ - SDP_MAX_SILENCESUPP_SIDUSE, - SDP_SILENCESUPP_SIDUSE_UNKNOWN -} sdp_silencesupp_siduse_e; - -typedef enum { - SDP_MEDIADIR_ROLE_PASSIVE, - SDP_MEDIADIR_ROLE_ACTIVE, - SDP_MEDIADIR_ROLE_BOTH, - SDP_MEDIADIR_ROLE_REUSE, - SDP_MEDIADIR_ROLE_UNKNOWN, - SDP_MAX_MEDIADIR_ROLES, - SDP_MEDIADIR_ROLE_UNSUPPORTED, - SDP_MEDIADIR_ROLE_INVALID -} sdp_mediadir_role_e; - -typedef enum { - SDP_GROUP_ATTR_FID, - SDP_GROUP_ATTR_LS, - SDP_GROUP_ATTR_ANAT, - SDP_MAX_GROUP_ATTR_VAL, - SDP_GROUP_ATTR_UNSUPPORTED -} sdp_group_attr_e; - -typedef enum { - SDP_SRC_FILTER_INCL, - SDP_SRC_FILTER_EXCL, - SDP_MAX_FILTER_MODE, - SDP_FILTER_MODE_NOT_PRESENT -} sdp_src_filter_mode_e; - -typedef enum { - SDP_RTCP_UNICAST_MODE_REFLECTION, - SDP_RTCP_UNICAST_MODE_RSI, - SDP_RTCP_MAX_UNICAST_MODE, - SDP_RTCP_UNICAST_MODE_NOT_PRESENT -} sdp_rtcp_unicast_mode_e; - -/* - * sdp_srtp_fec_order_t - * This type defines the order in which to perform FEC - * (Forward Error Correction) and SRTP Encryption/Authentication. - */ -typedef enum sdp_srtp_fec_order_t_ { - SDP_SRTP_THEN_FEC, /* upon sending perform SRTP then FEC */ - SDP_FEC_THEN_SRTP, /* upon sending perform FEC then SRTP */ - SDP_SRTP_FEC_SPLIT /* upon sending perform SRTP Encryption, - * then FEC, the SRTP Authentication */ -} sdp_srtp_fec_order_t; - - -/* - * sdp_srtp_crypto_suite_t - * Enumeration of the crypto suites supported for MGCP SRTP - * package. - */ -typedef enum sdp_srtp_crypto_suite_t_ { - SDP_SRTP_UNKNOWN_CRYPTO_SUITE = 0, - SDP_SRTP_AES_CM_128_HMAC_SHA1_32, - SDP_SRTP_AES_CM_128_HMAC_SHA1_80, - SDP_SRTP_F8_128_HMAC_SHA1_80, - SDP_SRTP_MAX_NUM_CRYPTO_SUITES -} sdp_srtp_crypto_suite_t; - -/* - * SDP SRTP crypto suite definition parameters - * - * SDP_SRTP__KEY_BYTES - * The size of a master key for in bytes. - * - * SDP_SRTP__SALT_BYTES - * The size of a master salt for in bytes. - */ -#define SDP_SRTP_AES_CM_128_HMAC_SHA1_32_KEY_BYTES 16 -#define SDP_SRTP_AES_CM_128_HMAC_SHA1_32_SALT_BYTES 14 -#define SDP_SRTP_AES_CM_128_HMAC_SHA1_80_KEY_BYTES 16 -#define SDP_SRTP_AES_CM_128_HMAC_SHA1_80_SALT_BYTES 14 -#define SDP_SRTP_F8_128_HMAC_SHA1_80_KEY_BYTES 16 -#define SDP_SRTP_F8_128_HMAC_SHA1_80_SALT_BYTES 14 - -/* SDP Defines */ - -#define SDP_MAX_STRING_LEN 256 /* Max len for SDP string */ -#define SDP_MAX_SHORT_STRING_LEN 12 /* Max len for a short SDP string */ -#define SDP_MAX_PAYLOAD_TYPES 23 /* Max payload types in m= line */ -#define SDP_TOKEN_LEN 2 /* Len of = */ -#define SDP_CURRENT_VERSION 0 /* Current default SDP version */ -#define SDP_MAX_PORT_PARAMS 4 /* Max m= port params - x/x/x/x */ -#define SDP_MIN_DYNAMIC_PAYLOAD 96 /* Min dynamic payload */ -#define SDP_MAX_DYNAMIC_PAYLOAD 127 /* Max dynamic payload */ -#define SDP_MIN_CIF_VALUE 1 /* applies to all QCIF,CIF,CIF4,CIF16,SQCIF */ -#define SDP_MAX_CIF_VALUE 32 /* applies to all QCIF,CIF,CIF4,CIF16,SQCIF */ -#define SDP_MAX_SRC_ADDR_LIST 1 /* Max source addrs for which filter applies */ - - -#define SDP_DEFAULT_PACKETIZATION_MODE_VALUE 0 /* max packetization mode for H.264 */ -#define SDP_MAX_PACKETIZATION_MODE_VALUE 2 /* max packetization mode for H.264 */ - -#define SDP_MAX_LEVEL_ASYMMETRY_ALLOWED_VALUE 1 /* max level asymmetry allowed value for H.264 */ -#define SDP_DEFAULT_LEVEL_ASYMMETRY_ALLOWED_VALUE 1 /* default level asymmetry allowed value for H.264 */ -#define SDP_INVALID_LEVEL_ASYMMETRY_ALLOWED_VALUE 2 /* invalid value for level-asymmetry-allowed param for H.264 */ - - -/* Max number of stream ids that can be grouped together */ -#define SDP_MAX_GROUP_STREAM_ID 10 - - -#define SDP_MAGIC_NUM 0xabcdabcd - -#define SDP_UNSUPPORTED "Unsupported" -#define SDP_MAX_LINE_LEN 256 /* Max len for SDP Line */ - -#define SDP_MAX_PROFILE_VALUE 10 -#define SDP_MAX_LEVEL_VALUE 100 -#define SDP_MIN_PROFILE_LEVEL_VALUE 0 -#define SDP_MAX_TTL_VALUE 255 -#define SDP_MIN_MCAST_ADDR_HI_BIT_VAL 224 -#define SDP_MAX_MCAST_ADDR_HI_BIT_VAL 239 - -/* SDP Enum Types */ - -typedef enum { - SDP_ERR_INVALID_CONF_PTR, - SDP_ERR_INVALID_SDP_PTR, - SDP_ERR_INTERNAL, - SDP_MAX_ERR_TYPES -} sdp_errmsg_e; - -/* SDP Structure Definitions */ - -/* String names of varios tokens */ -typedef struct { - char *name; - u8 strlen; -} sdp_namearray_t; - -/* c= line info */ -typedef struct { - sdp_nettype_e nettype; - sdp_addrtype_e addrtype; - char conn_addr[SDP_MAX_STRING_LEN+1]; - tinybool is_multicast; - u16 ttl; - u16 num_of_addresses; -} sdp_conn_t; - -/* t= line info */ -typedef struct sdp_timespec { - char start_time[SDP_MAX_STRING_LEN+1]; - char stop_time[SDP_MAX_STRING_LEN+1]; - struct sdp_timespec *next_p; -} sdp_timespec_t; - - -/* k= line info */ -typedef struct sdp_encryptspec { - sdp_encrypt_type_e encrypt_type; - char encrypt_key[SDP_MAX_STRING_LEN+1]; -} sdp_encryptspec_t; - - -/* FMTP attribute deals with named events in the range of 0-255 as - * defined in RFC 2833 */ -#define SDP_MIN_NE_VALUE 0 -#define SDP_MAX_NE_VALUES 256 -#define SDP_NE_BITS_PER_WORD ( sizeof(u32) * 8 ) -#define SDP_NE_NUM_BMAP_WORDS ((SDP_MAX_NE_VALUES + SDP_NE_BITS_PER_WORD - 1)/SDP_NE_BITS_PER_WORD ) -#define SDP_NE_BIT_0 ( 0x00000001 ) -#define SDP_NE_ALL_BITS ( 0xFFFFFFFF ) - -#define SDP_DEINT_BUF_REQ_FLAG 0x1 -#define SDP_INIT_BUF_TIME_FLAG 0x2 -#define SDP_MAX_RCMD_NALU_SIZE_FLAG 0x4 -#define SDP_DEINT_BUF_CAP_FLAG 0x8 - -typedef struct sdp_fmtp { - u16 payload_num; - u32 maxval; /* maxval optimizes bmap search */ - u32 bmap[ SDP_NE_NUM_BMAP_WORDS ]; - sdp_fmtp_format_type_e fmtp_format; /* Gives the format type - for FMTP attribute*/ - tinybool annexb_required; - tinybool annexa_required; - - tinybool annexa; - tinybool annexb; - u32 bitrate; - u32 mode; - - /* some OPUS specific fmtp params */ - u32 maxaveragebitrate; - u16 usedtx; - u16 stereo; - u16 useinbandfec; - char maxcodedaudiobandwidth[SDP_MAX_STRING_LEN+1]; - u16 cbr; - - /* some Data Channel specific fmtp params */ - u16 streams; /* Num streams per Data Channel */ - char protocol[SDP_MAX_STRING_LEN+1]; - - /* BEGIN - All Video related FMTP parameters */ - u16 qcif; - u16 cif; - u16 maxbr; - u16 sqcif; - u16 cif4; - u16 cif16; - - u16 custom_x; - u16 custom_y; - u16 custom_mpi; - /* CUSTOM=360,240,4 implies X-AXIS=360, Y-AXIS=240; MPI=4 */ - u16 par_width; - u16 par_height; - /* PAR=12:11 implies par_width=12, par_height=11 */ - - /* CPCF should be a float. IOS does not support float and so it is u16 */ - /* For portable stack, CPCF should be defined as float and the parsing should - * be modified accordingly */ - u16 cpcf; - u16 bpp; - u16 hrd; - - int16 profile; - int16 level; - tinybool is_interlace; - - /* some more H.264 specific fmtp params */ - char profile_level_id[SDP_MAX_STRING_LEN+1]; - char parameter_sets[SDP_MAX_STRING_LEN+1]; - u16 packetization_mode; - u16 level_asymmetry_allowed; - u16 interleaving_depth; - u32 deint_buf_req; - u32 max_don_diff; - u32 init_buf_time; - - u32 max_mbps; - u32 max_fs; - u32 max_cpb; - u32 max_dpb; - u32 max_br; - tinybool redundant_pic_cap; - u32 deint_buf_cap; - u32 max_rcmd_nalu_size; - tinybool parameter_add; - - tinybool annex_d; - - tinybool annex_f; - tinybool annex_i; - tinybool annex_j; - tinybool annex_t; - - /* H.263 codec requires annex K,N and P to have values */ - u16 annex_k_val; - u16 annex_n_val; - - /* Annex P can take one or more values in the range 1-4 . e.g P=1,3 */ - u16 annex_p_val_picture_resize; /* 1 = four; 2 = sixteenth */ - u16 annex_p_val_warp; /* 3 = half; 4=sixteenth */ - - u8 flag; - - /* END - All Video related FMTP parameters */ - -} sdp_fmtp_t; - -/* a=qos|secure|X-pc-qos|X-qos info */ -typedef struct sdp_qos { - sdp_qos_strength_e strength; - sdp_qos_dir_e direction; - tinybool confirm; - sdp_qos_status_types_e status_type; -} sdp_qos_t; - -/* a=curr:qos status_type direction */ -typedef struct sdp_curr { - sdp_curr_type_e type; - sdp_qos_status_types_e status_type; - sdp_qos_dir_e direction; -} sdp_curr_t; - -/* a=des:qos strength status_type direction */ -typedef struct sdp_des { - sdp_des_type_e type; - sdp_qos_strength_e strength; - sdp_qos_status_types_e status_type; - sdp_qos_dir_e direction; -} sdp_des_t; - -/* a=conf:qos status_type direction */ -typedef struct sdp_conf { - sdp_conf_type_e type; - sdp_qos_status_types_e status_type; - sdp_qos_dir_e direction; -} sdp_conf_t; - - -/* a=rtpmap or a=sprtmap info */ -typedef struct sdp_transport_map { - u16 payload_num; - char encname[SDP_MAX_STRING_LEN+1]; - u32 clockrate; - u16 num_chan; -} sdp_transport_map_t; - - -/* a=rtr info */ -typedef struct sdp_rtr { - tinybool confirm; -} sdp_rtr_t; - -/* a=subnet info */ -typedef struct sdp_subnet { - sdp_nettype_e nettype; - sdp_addrtype_e addrtype; - char addr[SDP_MAX_STRING_LEN+1]; - int32 prefix; -} sdp_subnet_t; - - -/* a=X-pc-codec info */ -typedef struct sdp_pccodec { - u16 num_payloads; - ushort payload_type[SDP_MAX_PAYLOAD_TYPES]; -} sdp_pccodec_t; - -/* a=direction info */ -typedef struct sdp_comediadir { - sdp_mediadir_role_e role; - tinybool conn_info_present; - sdp_conn_t conn_info; - u32 src_port; -} sdp_comediadir_t; - - - -/* a=silenceSupp info */ -typedef struct sdp_silencesupp { - tinybool enabled; - tinybool timer_null; - u16 timer; - sdp_silencesupp_pref_e pref; - sdp_silencesupp_siduse_e siduse; - tinybool fxnslevel_null; - u8 fxnslevel; -} sdp_silencesupp_t; - - -/* - * a=mptime info */ -/* Note that an interval value of zero corresponds to - * the "-" syntax on the a= line. - */ -typedef struct sdp_mptime { - u16 num_intervals; - ushort intervals[SDP_MAX_PAYLOAD_TYPES]; -} sdp_mptime_t; - -/* - * a=X-sidin:, a=X-sidout:< val> and a=X-confid: - * Stream Id,ConfID related attributes to be used for audio/video conferencing - * -*/ - -typedef struct sdp_stream_data { - char x_sidin[SDP_MAX_STRING_LEN+1]; - char x_sidout[SDP_MAX_STRING_LEN+1]; - char x_confid[SDP_MAX_STRING_LEN+1]; - sdp_group_attr_e group_attr; /* FID or LS */ - u16 num_group_id; - u16 group_id_arr[SDP_MAX_GROUP_STREAM_ID]; -} sdp_stream_data_t; - -/* - * a=source-filter: - * = ... - * One or more source addresses to apply filter, for one or more connection - * address in unicast/multicast environments - */ -typedef struct sdp_source_filter { - sdp_src_filter_mode_e mode; - sdp_nettype_e nettype; - sdp_addrtype_e addrtype; - char dest_addr[SDP_MAX_STRING_LEN+1]; - u16 num_src_addr; - char src_list[SDP_MAX_SRC_ADDR_LIST+1][SDP_MAX_STRING_LEN+1]; -} sdp_source_filter_t; - -/* - * b=: - * -*/ -typedef struct sdp_bw_data { - struct sdp_bw_data *next_p; - sdp_bw_modifier_e bw_modifier; - int bw_val; -} sdp_bw_data_t; - -/* - * This structure houses a linked list of sdp_bw_data_t instances. Each - * sdp_bw_data_t instance represents one b= line. - */ -typedef struct sdp_bw { - u16 bw_data_count; - sdp_bw_data_t *bw_data_list; -} sdp_bw_t; - -/* Media lines for AAL2 may have more than one transport type defined - * each with its own payload type list. These are referred to as - * profile types instead of transport types. This structure is used - * to handle these multiple profile types. Note: One additional profile - * field is needed because of the way parsing is done. This is not an - * error. */ -typedef struct sdp_media_profiles { - u16 num_profiles; - sdp_transport_e profile[SDP_MAX_PROFILES+1]; - u16 num_payloads[SDP_MAX_PROFILES]; - sdp_payload_ind_e payload_indicator[SDP_MAX_PROFILES][SDP_MAX_PAYLOAD_TYPES]; - u16 payload_type[SDP_MAX_PROFILES][SDP_MAX_PAYLOAD_TYPES]; -} sdp_media_profiles_t; - - -/* - * sdp_srtp_crypto_context_t - * This type is used to hold cryptographic context information. - * - */ - -typedef struct sdp_srtp_crypto_context_t_ { - int32 tag; - unsigned long selection_flags; - sdp_srtp_crypto_suite_t suite; - unsigned char master_key[SDP_SRTP_MAX_KEY_SIZE_BYTES]; - unsigned char master_salt[SDP_SRTP_MAX_SALT_SIZE_BYTES]; - unsigned char master_key_size_bytes; - unsigned char master_salt_size_bytes; - unsigned long ssrc; /* not used */ - unsigned long roc; /* not used */ - unsigned long kdr; /* not used */ - unsigned short seq; /* not used */ - sdp_srtp_fec_order_t fec_order; /* not used */ - unsigned char master_key_lifetime[SDP_SRTP_MAX_LIFETIME_BYTES]; - unsigned char mki[SDP_SRTP_MAX_MKI_SIZE_BYTES]; - u16 mki_size_bytes; - char* session_parameters; -} sdp_srtp_crypto_context_t; - - -/* m= line info and associated attribute list */ -/* Note: Most of the port parameter values are 16-bit values. We set - * the type to int32 so we can return either a 16-bit value or the - * choose value. */ -typedef struct sdp_mca { - sdp_media_e media; - sdp_conn_t conn; - sdp_transport_e transport; - sdp_port_format_e port_format; - int32 port; - int32 sctpport; - int32 num_ports; - int32 vpi; - u32 vci; /* VCI needs to be 32-bit */ - int32 vcci; - int32 cid; - u16 num_payloads; - sdp_payload_ind_e payload_indicator[SDP_MAX_PAYLOAD_TYPES]; - u16 payload_type[SDP_MAX_PAYLOAD_TYPES]; - sdp_media_profiles_t *media_profiles_p; - tinybool sessinfo_found; - sdp_encryptspec_t encrypt; - sdp_bw_t bw; - sdp_attr_e media_direction; /* Either INACTIVE, SENDONLY, - RECVONLY, or SENDRECV */ - u32 mid; - struct sdp_attr *media_attrs_p; - struct sdp_mca *next_p; -} sdp_mca_t; - - -/* generic a= line info */ -typedef struct sdp_attr { - sdp_attr_e type; - union { - tinybool boolean_val; - u32 u32_val; - char string_val[SDP_MAX_STRING_LEN+1]; - char ice_attr[SDP_MAX_STRING_LEN+1]; - sdp_fmtp_t fmtp; - sdp_qos_t qos; - sdp_curr_t curr; - sdp_des_t des; - sdp_conf_t conf; - sdp_transport_map_t transport_map; /* A rtpmap or sprtmap */ - sdp_subnet_t subnet; - sdp_t38_ratemgmt_e t38ratemgmt; - sdp_t38_udpec_e t38udpec; - sdp_pccodec_t pccodec; - sdp_silencesupp_t silencesupp; - sdp_mca_t *cap_p; /* A X-CAP or CDSC attribute */ - sdp_rtr_t rtr; - sdp_comediadir_t comediadir; - sdp_srtp_crypto_context_t srtp_context; - sdp_mptime_t mptime; - sdp_stream_data_t stream_data; - char unknown[SDP_MAX_STRING_LEN+1]; - sdp_source_filter_t source_filter; - } attr; - struct sdp_attr *next_p; -} sdp_attr_t; - -typedef struct sdp_srtp_crypto_suite_list_ { - sdp_srtp_crypto_suite_t crypto_suite_val; - char * crypto_suite_str; - unsigned char key_size_bytes; - unsigned char salt_size_bytes; -} sdp_srtp_crypto_suite_list; - -/* Application configuration options */ -typedef struct sdp_conf_options { - u32 magic_num; - tinybool debug_flag[SDP_MAX_DEBUG_TYPES]; - tinybool version_reqd; - tinybool owner_reqd; - tinybool session_name_reqd; - tinybool timespec_reqd; - tinybool media_supported[SDP_MAX_MEDIA_TYPES]; - tinybool nettype_supported[SDP_MAX_NETWORK_TYPES]; - tinybool addrtype_supported[SDP_MAX_ADDR_TYPES]; - tinybool transport_supported[SDP_MAX_TRANSPORT_TYPES]; - tinybool allow_choose[SDP_MAX_CHOOSE_PARAMS]; - /* Statistics counts */ - u32 num_builds; - u32 num_parses; - u32 num_not_sdp_desc; - u32 num_invalid_token_order; - u32 num_invalid_param; - u32 num_no_resource; - struct sdp_conf_options *next_p; -} sdp_conf_options_t; - - -/* Session level SDP info with pointers to media line info. */ -/* Elements here that can only be one of are included directly. Elements */ -/* that can be more than one are pointers. */ -typedef struct { - char peerconnection[PC_HANDLE_SIZE]; - u32 magic_num; - sdp_conf_options_t *conf_p; - tinybool debug_flag[SDP_MAX_DEBUG_TYPES]; - char debug_str[SDP_MAX_STRING_LEN+1]; - u32 debug_id; - int32 version; /* version is really a u16 */ - char owner_name[SDP_MAX_STRING_LEN+1]; - char owner_sessid[SDP_MAX_STRING_LEN+1]; - char owner_version[SDP_MAX_STRING_LEN+1]; - sdp_nettype_e owner_network_type; - sdp_addrtype_e owner_addr_type; - char owner_addr[SDP_MAX_STRING_LEN+1]; - char sessname[SDP_MAX_STRING_LEN+1]; - tinybool sessinfo_found; - tinybool uri_found; - sdp_conn_t default_conn; - sdp_timespec_t *timespec_p; - sdp_encryptspec_t encrypt; - sdp_bw_t bw; - sdp_attr_t *sess_attrs_p; - - /* Info to help with building capability attributes. */ - u16 cur_cap_num; - sdp_mca_t *cur_cap_p; - /* Info to help parsing X-cpar attrs. */ - u16 cap_valid; - u16 last_cap_inst; - /* Info to help building X-cpar/cpar attrs. */ - sdp_attr_e last_cap_type; - - /* MCA - Media, connection, and attributes */ - sdp_mca_t *mca_p; - ushort mca_count; -} sdp_t; - - -/* Token processing table. */ -typedef struct { - char *name; - sdp_result_e (*parse_func)(sdp_t *sdp_p, u16 level, const char *ptr); - sdp_result_e (*build_func)(sdp_t *sdp_p, u16 level, flex_string *fs); -} sdp_tokenarray_t; - - -/* Attribute processing table. */ -typedef struct { - char *name; - u16 strlen; - sdp_result_e (*parse_func)(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); - sdp_result_e (*build_func)(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -} sdp_attrarray_t; - - -/* Prototypes */ - -/* sdp_config.c */ -extern void *sdp_init_config(void); -extern void sdp_appl_debug(void *config_p, sdp_debug_e debug_type, - tinybool debug_flag); -extern void sdp_require_version(void *config_p, tinybool version_required); -extern void sdp_require_owner(void *config_p, tinybool owner_required); -extern void sdp_require_session_name(void *config_p, - tinybool sess_name_required); -extern void sdp_require_timespec(void *config_p, tinybool timespec_required); -extern void sdp_media_supported(void *config_p, sdp_media_e media_type, - tinybool media_supported); -extern void sdp_nettype_supported(void *config_p, sdp_nettype_e nettype, - tinybool nettype_supported); -extern void sdp_addrtype_supported(void *config_p, sdp_addrtype_e addrtype, - tinybool addrtype_supported); -extern void sdp_transport_supported(void *config_p, sdp_transport_e transport, - tinybool transport_supported); -extern void sdp_allow_choose(void *config_p, sdp_choose_param_e param, - tinybool choose_allowed); - -/* sdp_main.c */ -extern sdp_t *sdp_init_description(const char *peerconnection, void *config_p); -extern void sdp_debug(sdp_t *sdp_ptr, sdp_debug_e debug_type, tinybool debug_flag); -extern void sdp_set_string_debug(sdp_t *sdp_ptr, const char *debug_str); -extern sdp_result_e sdp_parse(sdp_t *sdp_ptr, char **bufp, u16 len); -extern sdp_result_e sdp_build(sdp_t *sdp_ptr, flex_string *fs); -extern sdp_t *sdp_copy(sdp_t *sdp_ptr); -extern sdp_result_e sdp_free_description(sdp_t *sdp_ptr); -extern void sdp_parse_error(const char *peerconnection, const char *format, ...); - -extern const char *sdp_get_result_name(sdp_result_e rc); - - -/* sdp_access.c */ -extern tinybool sdp_version_valid(void *sdp_p); -extern int32 sdp_get_version(void *sdp_p); -extern sdp_result_e sdp_set_version(void *sdp_p, int32 version); - -extern tinybool sdp_owner_valid(void *sdp_p); -extern const char *sdp_get_owner_username(void *sdp_p); -extern const char *sdp_get_owner_sessionid(void *sdp_p); -extern const char *sdp_get_owner_version(void *sdp_p); -extern sdp_nettype_e sdp_get_owner_network_type(void *sdp_p); -extern sdp_addrtype_e sdp_get_owner_address_type(void *sdp_p); -extern const char *sdp_get_owner_address(void *sdp_p); -extern sdp_result_e sdp_set_owner_username(void *sdp_p, const char *username); -extern sdp_result_e sdp_set_owner_sessionid(void *sdp_p, const char *sessid); -extern sdp_result_e sdp_set_owner_version(void *sdp_p, const char *version); -extern sdp_result_e sdp_set_owner_network_type(void *sdp_p, - sdp_nettype_e network_type); -extern sdp_result_e sdp_set_owner_address_type(void *sdp_p, - sdp_addrtype_e address_type); -extern sdp_result_e sdp_set_owner_address(void *sdp_p, const char *address); - -extern tinybool sdp_session_name_valid(void *sdp_p); -extern const char *sdp_get_session_name(void *sdp_p); -extern sdp_result_e sdp_set_session_name(void *sdp_p, const char *sessname); - -extern tinybool sdp_timespec_valid(void *sdp_ptr); -extern const char *sdp_get_time_start(void *sdp_ptr); -extern const char *sdp_get_time_stop(void *sdp_ptr); -sdp_result_e sdp_set_time_start(void *sdp_ptr, const char *start_time); -sdp_result_e sdp_set_time_stop(void *sdp_ptr, const char *stop_time); - -extern tinybool sdp_encryption_valid(void *sdp_ptr, u16 level); -extern sdp_encrypt_type_e sdp_get_encryption_method(void *sdp_ptr, u16 level); -extern const char *sdp_get_encryption_key(void *sdp_ptr, u16 level); -extern sdp_result_e sdp_set_encryption_method(void *sdp_ptr, u16 level, - sdp_encrypt_type_e method); -extern sdp_result_e sdp_set_encryption_key(void *sdp_ptr, u16 level, - const char *key); - -extern tinybool sdp_connection_valid(void *sdp_p, u16 level); -extern tinybool sdp_bw_line_exists(void *sdp_ptr, u16 level, u16 inst_num); -extern tinybool sdp_bandwidth_valid(void *sdp_p, u16 level, u16 inst_num); -extern sdp_nettype_e sdp_get_conn_nettype(void *sdp_p, u16 level); -extern sdp_addrtype_e sdp_get_conn_addrtype(void *sdp_p, u16 level); -extern const char *sdp_get_conn_address(void *sdp_p, u16 level); - -extern tinybool sdp_is_mcast_addr (void *sdp_ptr, u16 level); -extern int32 sdp_get_mcast_ttl(void *sdp_ptr, u16 level); -extern int32 sdp_get_mcast_num_of_addresses(void *sdp_ptr, u16 level); - -extern sdp_result_e sdp_set_conn_nettype(void *sdp_p, u16 level, - sdp_nettype_e nettype); -extern sdp_result_e sdp_set_conn_addrtype(void *sdp_p, u16 level, - sdp_addrtype_e addrtype); -extern sdp_result_e sdp_set_conn_address(void *sdp_p, u16 level, - const char *address); -extern sdp_result_e sdp_set_mcast_addr_fields(void *sdp_ptr, u16 level, - u16 ttl, u16 num_addr); - -extern tinybool sdp_media_line_valid(void *sdp_ptr, u16 level); -extern u16 sdp_get_num_media_lines(void *sdp_ptr); -extern sdp_media_e sdp_get_media_type(void *sdp_ptr, u16 level); -extern sdp_port_format_e sdp_get_media_port_format(void *sdp_ptr, u16 level); -extern int32 sdp_get_media_portnum(void *sdp_ptr, u16 level); -extern int32 sdp_get_media_portcount(void *sdp_ptr, u16 level); -extern int32 sdp_get_media_vpi(void *sdp_ptr, u16 level); -extern u32 sdp_get_media_vci(void *sdp_ptr, u16 level); -extern int32 sdp_get_media_vcci(void *sdp_ptr, u16 level); -extern int32 sdp_get_media_cid(void *sdp_ptr, u16 level); -extern sdp_transport_e sdp_get_media_transport(void *sdp_ptr, u16 level); -extern u16 sdp_get_media_num_profiles(void *sdp_ptr, u16 level); -extern sdp_transport_e sdp_get_media_profile(void *sdp_ptr, u16 level, - u16 profile_num); -extern u16 sdp_get_media_num_payload_types(void *sdp_ptr, u16 level); -extern u16 sdp_get_media_profile_num_payload_types(void *sdp_ptr, u16 level, - u16 profile_num); -extern u32 sdp_get_media_payload_type(void *sdp_ptr, u16 level, - u16 payload_num, sdp_payload_ind_e *indicator); -extern u32 sdp_get_media_profile_payload_type(void *sdp_ptr, u16 level, - u16 prof_num, u16 payload_num, sdp_payload_ind_e *indicator); -extern sdp_result_e sdp_insert_media_line(void *sdp_ptr, u16 level); -extern void sdp_delete_media_line(void *sdp_ptr, u16 level); -extern sdp_result_e sdp_set_media_type(void *sdp_ptr, u16 level, - sdp_media_e media); -extern sdp_result_e sdp_set_media_port_format(void *sdp_ptr, u16 level, - sdp_port_format_e port_format); -extern sdp_result_e sdp_set_media_portnum(void *sdp_ptr, u16 level, - int32 portnum, int32 sctpport); -extern sdp_result_e sdp_set_media_portcount(void *sdp_ptr, u16 level, - int32 num_ports); -extern sdp_result_e sdp_set_media_vpi(void *sdp_ptr, u16 level, int32 vpi); -extern sdp_result_e sdp_set_media_vci(void *sdp_ptr, u16 level, u32 vci); -extern sdp_result_e sdp_set_media_vcci(void *sdp_ptr, u16 level, int32 vcci); -extern sdp_result_e sdp_set_media_cid(void *sdp_ptr, u16 level, int32 cid); -extern sdp_result_e sdp_set_media_transport(void *sdp_ptr, u16 level, - sdp_transport_e transport); -extern sdp_result_e sdp_add_media_profile(void *sdp_ptr, u16 level, - sdp_transport_e profile); -extern sdp_result_e sdp_add_media_payload_type(void *sdp_ptr, u16 level, - u16 payload_type, sdp_payload_ind_e indicator); -extern sdp_result_e sdp_add_media_profile_payload_type(void *sdp_ptr, - u16 level, u16 prof_num, u16 payload_type, - sdp_payload_ind_e indicator); - -/* sdp_attr_access.c */ -extern sdp_result_e sdp_add_new_attr(void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e attr_type, u16 *inst_num); -extern sdp_result_e sdp_copy_attr (void *src_sdp_ptr, void *dst_sdp_ptr, - u16 src_level, u16 dst_level, - u8 src_cap_num, u8 dst_cap_num, - sdp_attr_e src_attr_type, u16 src_inst_num); -extern sdp_result_e sdp_copy_all_attrs(void *src_sdp_ptr, void *dst_sdp_ptr, - u16 src_level, u16 dst_level); -extern sdp_result_e sdp_attr_num_instances(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e attr_type, u16 *num_attr_inst); -extern sdp_result_e sdp_get_total_attrs(void *sdp_ptr, u16 level, u8 cap_num, - u16 *num_attrs); -extern sdp_result_e sdp_get_attr_type(void *sdp_ptr, u16 level, u8 cap_num, - u16 attr_num, sdp_attr_e *attr_type, u16 *inst_num); -extern sdp_result_e sdp_delete_attr(void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e attr_type, u16 inst_num); -extern sdp_result_e sdp_delete_all_attrs(void *sdp_ptr, u16 level, u8 cap_num); -extern tinybool sdp_attr_valid(void *sdp_ptr, sdp_attr_e attr_type, - u16 level, u8 cap_num, u16 inst_num); -extern const char *sdp_attr_get_simple_string(void *sdp_ptr, - sdp_attr_e attr_type, u16 level, u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_set_simple_string(void *sdp_ptr, - sdp_attr_e attr_type, u16 level, - u8 cap_num, u16 inst_num, const char *string_parm); -extern u32 sdp_attr_get_simple_u32(void *sdp_ptr, sdp_attr_e attr_type, - u16 level, u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_set_simple_u32(void *sdp_ptr, - sdp_attr_e attr_type, u16 level, - u8 cap_num, u16 inst_num, u32 num_parm); -extern tinybool sdp_attr_get_simple_boolean(void *sdp_ptr, - sdp_attr_e attr_type, u16 level, u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_set_simple_boolean(void *sdp_ptr, - sdp_attr_e attr_type, u16 level, u8 cap_num, - u16 inst_num, u32 bool_parm); -extern const char* sdp_attr_get_maxprate(void *sdp_ptr, u16 level, - u16 inst_num); -extern sdp_result_e sdp_attr_set_maxprate(void *sdp_ptr, u16 level, - u16 inst_num, const char *string_parm); -extern sdp_t38_ratemgmt_e sdp_attr_get_t38ratemgmt(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_set_t38ratemgmt(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_t38_ratemgmt_e t38ratemgmt); -extern sdp_t38_udpec_e sdp_attr_get_t38udpec(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_set_t38udpec(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_t38_udpec_e t38udpec); -extern sdp_direction_e sdp_get_media_direction(void *sdp_ptr, u16 level, - u8 cap_num); -extern sdp_qos_strength_e sdp_attr_get_qos_strength(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num); -extern sdp_qos_status_types_e sdp_attr_get_qos_status_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num); -extern sdp_qos_dir_e sdp_attr_get_qos_direction(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num); -extern tinybool sdp_attr_get_qos_confirm(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num); -extern sdp_curr_type_e sdp_attr_get_curr_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num); -extern sdp_des_type_e sdp_attr_get_des_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num); -extern sdp_conf_type_e sdp_attr_get_conf_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num); -extern sdp_result_e sdp_attr_set_conf_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - sdp_conf_type_e conf_type); -extern sdp_result_e sdp_attr_set_des_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - sdp_des_type_e des_type); -extern sdp_result_e sdp_attr_set_curr_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - sdp_curr_type_e curr_type); -extern sdp_result_e sdp_attr_set_qos_strength(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - sdp_qos_strength_e strength); -extern sdp_result_e sdp_attr_set_qos_direction(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - sdp_qos_dir_e direction); -extern sdp_result_e sdp_attr_set_qos_status_type(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - sdp_qos_status_types_e status_type); -extern sdp_result_e sdp_attr_set_qos_confirm(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - tinybool confirm); -extern sdp_nettype_e sdp_attr_get_subnet_nettype(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_addrtype_e sdp_attr_get_subnet_addrtype(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern const char *sdp_attr_get_subnet_addr(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_subnet_prefix(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_set_subnet_nettype(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_nettype_e nettype); -extern sdp_result_e sdp_attr_set_subnet_addrtype(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_addrtype_e addrtype); -extern sdp_result_e sdp_attr_set_subnet_addr(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *addr); -extern sdp_result_e sdp_attr_set_subnet_prefix(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - int32 prefix); -extern tinybool sdp_attr_rtpmap_payload_valid(void *sdp_ptr, u16 level, - u8 cap_num, u16 *inst_num, u16 payload_type); -extern u16 sdp_attr_get_rtpmap_payload_type(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern const char *sdp_attr_get_rtpmap_encname(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern u32 sdp_attr_get_rtpmap_clockrate(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern u16 sdp_attr_get_rtpmap_num_chan(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_set_rtpmap_payload_type(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 payload_num); -extern sdp_result_e sdp_attr_set_rtpmap_encname(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, const char *encname); -extern sdp_result_e sdp_attr_set_rtpmap_clockrate(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 clockrate); -extern sdp_result_e sdp_attr_set_rtpmap_num_chan(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 num_chan); -extern tinybool sdp_attr_sprtmap_payload_valid(void *sdp_ptr, u16 level, - u8 cap_num, u16 *inst_num, u16 payload_type); -extern u16 sdp_attr_get_sprtmap_payload_type(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern const char *sdp_attr_get_sprtmap_encname(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern u32 sdp_attr_get_sprtmap_clockrate(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern u16 sdp_attr_get_sprtmap_num_chan(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_set_sprtmap_payload_type(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 payload_num); -extern sdp_result_e sdp_attr_set_sprtmap_encname(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, const char *encname); -extern sdp_result_e sdp_attr_set_sprtmap_clockrate(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 clockrate); -extern sdp_result_e sdp_attr_set_sprtmap_num_chan(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 num_chan); -extern tinybool sdp_attr_fmtp_payload_valid(void *sdp_ptr, u16 level, - u8 cap_num, u16 *inst_num, u16 payload_type); -extern u16 sdp_attr_get_fmtp_payload_type(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_ne_res_e sdp_attr_fmtp_is_range_set(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u8 low_val, u8 high_val); -extern tinybool sdp_attr_fmtp_valid(void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, u16 appl_maxval, u32* evt_array); -extern sdp_result_e sdp_attr_set_fmtp_payload_type(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 payload_num); -extern sdp_result_e sdp_attr_get_fmtp_range(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *bmap); -extern sdp_result_e sdp_attr_set_fmtp_range(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u8 low_val, u8 high_val); -extern sdp_result_e sdp_attr_set_fmtp_bitmap(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *bmap, u32 maxval); -extern sdp_result_e sdp_attr_clear_fmtp_range(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u8 low_val, u8 high_val); -extern sdp_ne_res_e sdp_attr_compare_fmtp_ranges(void *src_sdp_ptr, - void *dst_sdp_ptr, u16 src_level, u16 dst_level, - u8 src_cap_num, u8 dst_cap_num, u16 src_inst_num, - u16 dst_inst_num); -extern sdp_result_e sdp_attr_copy_fmtp_ranges(void *src_sdp_ptr, - void *dst_sdp_ptr, u16 src_level, u16 dst_level, - u8 src_cap_num, u8 dst_cap_num, u16 src_inst_num, - u16 dst_inst_num); -extern sdp_result_e sdp_attr_set_fmtp_annexa (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool annexa); -extern sdp_result_e sdp_attr_set_fmtp_mode(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 mode); -extern u32 sdp_attr_get_fmtp_mode_for_payload_type (void *sdp_ptr, u16 level, - u8 cap_num, u32 payload_type); - -extern sdp_result_e sdp_attr_set_fmtp_annexb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool annexb); - -extern sdp_result_e sdp_attr_set_fmtp_bitrate_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 bitrate); -extern sdp_result_e sdp_attr_set_fmtp_cif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 cif); -extern sdp_result_e sdp_attr_set_fmtp_qcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 qcif); -extern sdp_result_e sdp_attr_set_fmtp_sqcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 sqcif); -extern sdp_result_e sdp_attr_set_fmtp_cif4 (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 cif4); -extern sdp_result_e sdp_attr_set_fmtp_cif16 (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 cif16); -extern sdp_result_e sdp_attr_set_fmtp_maxbr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 maxbr); -extern sdp_result_e sdp_attr_set_fmtp_max_average_bitrate (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 maxaveragebitrate); -extern sdp_result_e sdp_attr_set_fmtp_usedtx (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool usedtx); -extern sdp_result_e sdp_attr_set_fmtp_stereo (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool stereo); -extern sdp_result_e sdp_attr_set_fmtp_useinbandfec (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool useinbandfec); -extern sdp_result_e sdp_attr_set_fmtp_maxcodedaudiobandwidth (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *maxcodedaudiobandwidth); -extern sdp_result_e sdp_attr_set_fmtp_cbr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool cbr); -extern sdp_result_e sdp_attr_set_fmtp_custom (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 custom_x, u16 custom_y, - u16 custom_mpi); -extern sdp_result_e sdp_attr_set_fmtp_par (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 par_width, u16 par_height); -extern sdp_result_e sdp_attr_set_fmtp_bpp (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 bpp); -extern sdp_result_e sdp_attr_set_fmtp_hrd (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 hrd); - -extern sdp_result_e sdp_attr_set_fmtp_h263_num_params (void *sdp_ptr, - int16 level, - u8 cap_num, - u16 inst_num, - int16 profile, - u16 h263_level, - tinybool interlace); - -extern sdp_result_e sdp_attr_set_fmtp_profile_level_id (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - const char *prof_id); - -extern sdp_result_e sdp_attr_set_fmtp_parameter_sets (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - const char *parameter_sets); - -extern sdp_result_e sdp_attr_set_fmtp_deint_buf_req (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 deint_buf_req); - -extern sdp_result_e sdp_attr_set_fmtp_init_buf_time (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 init_buf_time); - -extern sdp_result_e sdp_attr_set_fmtp_max_don_diff (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 max_don_diff); - -extern sdp_result_e sdp_attr_set_fmtp_interleaving_depth (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 interleaving_depth); - -extern sdp_result_e sdp_attr_set_fmtp_pack_mode (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u16 pack_mode); - -extern sdp_result_e sdp_attr_set_fmtp_level_asymmetry_allowed (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u16 level_asymmetry_allowed); - -extern sdp_result_e sdp_attr_set_fmtp_redundant_pic_cap (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - tinybool redundant_pic_cap); - -extern sdp_result_e sdp_attr_set_fmtp_max_mbps (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u32 max_mbps); - -extern sdp_result_e sdp_attr_set_fmtp_max_fs (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u32 max_fs); - -extern sdp_result_e sdp_attr_set_fmtp_max_cpb (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u32 max_cpb); - -extern sdp_result_e sdp_attr_set_fmtp_max_dpb (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u32 max_dpb); - -extern sdp_result_e sdp_attr_set_fmtp_max_br (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u32 max_br); - -extern sdp_result_e sdp_attr_set_fmtp_max_rcmd_nalu_size (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 max_rcmd_nalu_size); - -extern sdp_result_e sdp_attr_set_fmtp_deint_buf_cap (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 deint_buf_cap); - -extern sdp_result_e sdp_attr_set_fmtp_h264_parameter_add (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - tinybool parameter_add); - -extern sdp_result_e sdp_attr_set_fmtp_h261_annex_params (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - tinybool annex_d); - -extern sdp_result_e sdp_attr_set_fmtp_h263_annex_params (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - tinybool annex_f, - tinybool annex_i, - tinybool annex_j, - tinybool annex_t, - u16 annex_k_val, - u16 annex_n_val, - u16 annex_p_val_picture_resize, - u16 annex_p_val_warp); - - -/* get routines */ -extern int32 sdp_attr_get_fmtp_bitrate_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); - -extern int32 sdp_attr_get_fmtp_cif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_qcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_sqcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_cif4 (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_cif16 (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_maxbr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_get_fmtp_max_average_bitrate (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32* val); -extern sdp_result_e sdp_attr_get_fmtp_usedtx (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, tinybool* val); -extern sdp_result_e sdp_attr_get_fmtp_stereo (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, tinybool* val); -extern sdp_result_e sdp_attr_get_fmtp_useinbandfec (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, tinybool* val); -extern char* sdp_attr_get_fmtp_maxcodedaudiobandwidth (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_get_fmtp_cbr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, tinybool* val); -extern sdp_result_e sdp_attr_set_fmtp_streams (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 streams); -extern sdp_result_e sdp_attr_get_fmtp_streams (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32* val); -extern sdp_result_e sdp_attr_get_fmtp_data_channel_protocol (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, char* protocol); -extern sdp_result_e sdp_attr_set_fmtp_data_channel_protocol (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *protocol); -extern int32 sdp_attr_get_fmtp_custom_x (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_custom_y (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_custom_mpi (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_par_width (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_par_height (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_bpp (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_hrd (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_profile (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_level (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern tinybool sdp_attr_get_fmtp_interlace (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern tinybool sdp_attr_get_fmtp_annex_d (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern tinybool sdp_attr_get_fmtp_annex_f (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern tinybool sdp_attr_get_fmtp_annex_i (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern tinybool sdp_attr_get_fmtp_annex_j (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern tinybool sdp_attr_get_fmtp_annex_t (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_annex_k_val (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_annex_n_val (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); - -extern int32 sdp_attr_get_fmtp_annex_p_picture_resize (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern int32 sdp_attr_get_fmtp_annex_p_warp (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); - -/* H.264 codec specific params */ - -extern const char *sdp_attr_get_fmtp_profile_id(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern const char *sdp_attr_get_fmtp_param_sets(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_attr_get_fmtp_pack_mode (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 *val); - -extern sdp_result_e sdp_attr_get_fmtp_level_asymmetry_allowed (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 *val); - -extern sdp_result_e sdp_attr_get_fmtp_interleaving_depth (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 *val); -extern sdp_result_e sdp_attr_get_fmtp_max_don_diff (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val); - -/* The following four H.264 parameters that require special handling as - * the values range from 0 - 4294967295 - */ -extern sdp_result_e sdp_attr_get_fmtp_deint_buf_req (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val); -extern sdp_result_e sdp_attr_get_fmtp_deint_buf_cap (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val); -extern sdp_result_e sdp_attr_get_fmtp_init_buf_time (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val); -extern sdp_result_e sdp_attr_get_fmtp_max_rcmd_nalu_size (void *sdp_ptr, - u16 level, u8 cap_num, - u16 inst_num, u32 *val); - - -extern sdp_result_e sdp_attr_get_fmtp_max_mbps (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val); -extern sdp_result_e sdp_attr_get_fmtp_max_fs (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val); -extern sdp_result_e sdp_attr_get_fmtp_max_cpb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val); -extern sdp_result_e sdp_attr_get_fmtp_max_dpb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val); -extern sdp_result_e sdp_attr_get_fmtp_max_br (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val); -extern tinybool sdp_attr_fmtp_is_redundant_pic_cap (void *sdp_ptr, u16 level, - u8 cap_num, - u16 inst_num); -extern tinybool sdp_attr_fmtp_is_parameter_add (void *sdp_ptr, u16 level, - u8 cap_num, - u16 inst_num); -extern tinybool sdp_attr_fmtp_is_annexa_set (void *sdp_ptr, u16 level, - u8 cap_num, - u16 inst_num); - -extern tinybool sdp_attr_fmtp_is_annexb_set (void *sdp_ptr, u16 level, - u8 cap_num, - u16 inst_num); - -extern sdp_fmtp_format_type_e sdp_attr_fmtp_get_fmtp_format (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num); - -extern u16 sdp_attr_get_pccodec_num_payload_types(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern u16 sdp_attr_get_pccodec_payload_type(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 payload_num); -extern sdp_result_e sdp_attr_add_pccodec_payload_type(void *sdp_ptr, - u16 level, u8 cap_num, - u16 inst_num, u16 payload_type); -extern u16 sdp_attr_get_xcap_first_cap_num(void *sdp_ptr, u16 level, - u16 inst_num); -extern sdp_media_e sdp_attr_get_xcap_media_type(void *sdp_ptr, u16 level, - u16 inst_num); -extern sdp_transport_e sdp_attr_get_xcap_transport_type(void *sdp_ptr, - u16 level, u16 inst_num); -extern u16 sdp_attr_get_xcap_num_payload_types(void *sdp_ptr, u16 level, - u16 inst_num); -extern u16 sdp_attr_get_xcap_payload_type(void *sdp_ptr, u16 level, - u16 inst_num, u16 payload_num, - sdp_payload_ind_e *indicator); -extern sdp_result_e sdp_attr_set_xcap_media_type(void *sdp_ptr, u16 level, - u16 inst_num, sdp_media_e media); -extern sdp_result_e sdp_attr_set_xcap_transport_type(void *sdp_ptr, u16 level, - u16 inst_num, sdp_transport_e transport); -extern sdp_result_e sdp_attr_add_xcap_payload_type(void *sdp_ptr, u16 level, - u16 inst_num, u16 payload_type, - sdp_payload_ind_e indicator); -extern u16 sdp_attr_get_cdsc_first_cap_num(void *sdp_ptr, u16 level, - u16 inst_num); -extern sdp_media_e sdp_attr_get_cdsc_media_type(void *sdp_ptr, u16 level, - u16 inst_num); -extern sdp_transport_e sdp_attr_get_cdsc_transport_type(void *sdp_ptr, - u16 level, u16 inst_num); -extern u16 sdp_attr_get_cdsc_num_payload_types(void *sdp_ptr, u16 level, - u16 inst_num); -extern u16 sdp_attr_get_cdsc_payload_type(void *sdp_ptr, u16 level, - u16 inst_num, u16 payload_num, - sdp_payload_ind_e *indicator); -extern sdp_result_e sdp_attr_set_cdsc_media_type(void *sdp_ptr, u16 level, - u16 inst_num, sdp_media_e media); -extern sdp_result_e sdp_attr_set_cdsc_transport_type(void *sdp_ptr, u16 level, - u16 inst_num, sdp_transport_e transport); -extern sdp_result_e sdp_attr_add_cdsc_payload_type(void *sdp_ptr, u16 level, - u16 inst_num, u16 payload_type, - sdp_payload_ind_e indicator); -extern tinybool sdp_media_dynamic_payload_valid (void *sdp_ptr, u16 payload_type, - u16 m_line); - -extern sdp_result_e sdp_attr_set_rtr_confirm (void *, u16 , \ - u8 ,u16 ,tinybool ); -extern tinybool sdp_attr_get_rtr_confirm (void *, u16, u8, u16); - -extern tinybool sdp_attr_get_silencesupp_enabled(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern u16 sdp_attr_get_silencesupp_timer(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool *null_ind); -extern sdp_silencesupp_pref_e sdp_attr_get_silencesupp_pref(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); -extern sdp_silencesupp_siduse_e sdp_attr_get_silencesupp_siduse(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); -extern u8 sdp_attr_get_silencesupp_fxnslevel(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool *null_ind); -extern sdp_result_e sdp_attr_set_silencesupp_enabled(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool enable); -extern sdp_result_e sdp_attr_set_silencesupp_timer(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 value, - tinybool null_ind); -extern sdp_result_e sdp_attr_set_silencesupp_pref(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_silencesupp_pref_e pref); -extern sdp_result_e sdp_attr_set_silencesupp_siduse(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_silencesupp_siduse_e siduse); -extern sdp_result_e sdp_attr_set_silencesupp_fxnslevel(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u16 value, - tinybool null_ind); - -extern sdp_mediadir_role_e sdp_attr_get_comediadir_role(void *sdp_ptr, - u16 level, u8 cap_num, - u16 inst_num); -extern sdp_result_e sdp_attr_set_comediadir_role(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_mediadir_role_e role); - -extern sdp_result_e sdp_delete_all_media_direction_attrs (void *sdp_ptr, - u16 level); - -extern u16 sdp_attr_get_mptime_num_intervals( - void *sdp_ptr, u16 level, u8 cap_num, u16 inst_num); -extern u16 sdp_attr_get_mptime_interval( - void *sdp_ptr, u16 level, u8 cap_num, u16 inst_num, u16 interval_num); -extern sdp_result_e sdp_attr_add_mptime_interval( - void *sdp_ptr, u16 level, u8 cap_num, u16 inst_num, u16 interval); - - -extern sdp_result_e sdp_delete_bw_line (void *sdp_ptr, u16 level, u16 inst_num); -extern sdp_result_e sdp_copy_all_bw_lines(void *src_sdp_ptr, void *dst_sdp_ptr, - u16 src_level, u16 dst_level); -extern sdp_bw_modifier_e sdp_get_bw_modifier(void *sdp_ptr, u16 level, - u16 inst_num); -extern int32 sdp_get_bw_value(void *sdp_ptr, u16 level, u16 inst_num); -extern int32 sdp_get_num_bw_lines (void *sdp_ptr, u16 level); - -extern sdp_result_e sdp_add_new_bw_line(void *sdp_ptr, u16 level, - sdp_bw_modifier_e bw_modifier, u16 *inst_num); -extern sdp_result_e sdp_set_bw(void *sdp_ptr, u16 level, u16 inst_num, - sdp_bw_modifier_e value, u32 bw_val); - -extern sdp_group_attr_e sdp_get_group_attr(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_set_group_attr(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_group_attr_e value); - -extern const char* sdp_attr_get_x_sidout (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); - -extern sdp_result_e sdp_attr_set_x_sidout (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *sidout); - -extern const char* sdp_attr_get_x_sidin (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); - -extern sdp_result_e sdp_attr_set_x_sidin (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *sidin); - -extern const char* sdp_attr_get_x_confid (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); - -extern sdp_result_e sdp_attr_set_x_confid (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *confid); - -extern sdp_result_e sdp_attr_set_ice_candidate(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, const char *ice_candidate); - -extern u16 sdp_get_group_num_id(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_set_group_num_id(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 group_num_id); - -extern int32 sdp_get_group_id(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 id_num); -extern sdp_result_e sdp_set_group_id (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 group_id); - - -extern int32 sdp_get_mid_value(void *sdp_ptr, u16 level); -extern sdp_result_e sdp_set_mid_value(void *sdp_ptr, u16 level, u32 mid_val); - -extern sdp_result_e sdp_set_source_filter(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_src_filter_mode_e mode, - sdp_nettype_e nettype, - sdp_addrtype_e addrtype, - const char *dest_addr, - const char *src_addr); -extern sdp_result_e sdp_include_new_filter_src_addr(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *src_addr); -extern sdp_src_filter_mode_e sdp_get_source_filter_mode(void *sdp_ptr, - u16 level, u8 cap_num, - u16 inst_num); -extern sdp_result_e sdp_get_filter_destination_attributes(void *sdp_ptr, - u16 level, u8 cap_num, - u16 inst_num, - sdp_nettype_e *nettype, - sdp_addrtype_e *addrtype, - char *dest_addr); -extern int32 sdp_get_filter_source_address_count(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num); -extern sdp_result_e sdp_get_filter_source_address (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 src_addr_id, - char *src_addr); - -extern sdp_result_e sdp_set_rtcp_unicast_mode(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_rtcp_unicast_mode_e mode); -extern sdp_rtcp_unicast_mode_e sdp_get_rtcp_unicast_mode(void *sdp_ptr, - u16 level, u8 cap_num, - u16 inst_num); - -void sdp_crypto_debug(char *buffer, ulong length_bytes); -char * sdp_debug_msg_filter(char *buffer, ulong length_bytes); - -extern int32 -sdp_attr_get_sdescriptions_tag(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); - -extern sdp_srtp_crypto_suite_t -sdp_attr_get_sdescriptions_crypto_suite(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); - -extern const char* -sdp_attr_get_sdescriptions_key(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); - -extern const char* -sdp_attr_get_sdescriptions_salt(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); - -extern const char* -sdp_attr_get_sdescriptions_lifetime(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); - -extern sdp_result_e -sdp_attr_get_sdescriptions_mki(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - const char **mki_value, - u16 *mki_length); - -extern const char* -sdp_attr_get_sdescriptions_session_params(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); - -extern unsigned char -sdp_attr_get_sdescriptions_key_size(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); - -extern unsigned char -sdp_attr_get_sdescriptions_salt_size(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); - -extern unsigned long -sdp_attr_get_srtp_crypto_selection_flags(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num); - -extern sdp_result_e -sdp_attr_set_sdescriptions_tag(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - int32 tag_num); - -extern sdp_result_e -sdp_attr_set_sdescriptions_crypto_suite(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_srtp_crypto_suite_t crypto_suite); - -extern sdp_result_e -sdp_attr_set_sdescriptions_key(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - char *key); - -extern sdp_result_e -sdp_attr_set_sdescriptions_salt(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - char *salt); - -extern sdp_result_e -sdp_attr_set_sdescriptions_lifetime(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - char *lifetime); - -extern sdp_result_e -sdp_attr_set_sdescriptions_mki(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - char *mki_value, - u16 mki_length); - -extern sdp_result_e -sdp_attr_set_sdescriptions_key_size(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - unsigned char key_size); - -extern sdp_result_e -sdp_attr_set_sdescriptions_salt_size(void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - unsigned char salt_size); - -sdp_result_e -sdp_attr_get_ice_attribute (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, - char **out); -sdp_result_e -sdp_attr_set_ice_attribute(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, const char *ice_attrib); - -sdp_result_e -sdp_attr_get_rtcp_mux_attribute (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, - tinybool *rtcp_mux); - -sdp_result_e -sdp_attr_set_rtcp_mux_attribute(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, const tinybool rtcp_mux); - -sdp_result_e -sdp_attr_get_dtls_fingerprint_attribute (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, - char **out); - -sdp_result_e -sdp_attr_set_dtls_fingerprint_attribute(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, const char *dtls_fingerprint); - -#endif /* _SDP_H_ */ diff --git a/libs/sipcc/core/sdp/sdp_access.c b/libs/sipcc/core/sdp/sdp_access.c deleted file mode 100644 index 76251a51f2..0000000000 --- a/libs/sipcc/core/sdp/sdp_access.c +++ /dev/null @@ -1,2847 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "sdp_os_defs.h" -#include "sdp.h" -#include "sdp_private.h" -#include "ccsip_sdp.h" -#include "rtp_defs.h" -#include "CSFLog.h" - -//static const char* logTag = "sdp_access"; - -/* Function: sdp_find_media_level - * Description: Find and return a pointer to the specified media level, - * if it exists. - * Note: This is not an API for the application but an internal - * routine used by the SDP library. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to find. - * Returns: Pointer to the media level or NULL if not found. - */ -sdp_mca_t *sdp_find_media_level (sdp_t *sdp_p, u16 level) -{ - int i; - sdp_mca_t *mca_p = NULL; - - if ((level >= 1) && (level <= sdp_p->mca_count)) { - for (i=1, mca_p = sdp_p->mca_p; - ((i < level) && (mca_p != NULL)); - mca_p = mca_p->next_p, i++) { - - /*sa_ignore EMPTYLOOP*/ - ; /* Do nothing. */ - } - } - - return (mca_p); -} - -/* Function: sdp_version_valid - * Description: Returns true or false depending on whether the version - * set for this SDP is valid. Currently the only valid - * version is 0. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: TRUE or FALSE. - */ -tinybool sdp_version_valid (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (sdp_p->version == SDP_INVALID_VALUE) { - return (FALSE); - } else { - return (TRUE); - } -} - -/* Function: sdp_get_version - * Description: Returns the version value set for the given SDP. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Version value. - */ -int32 sdp_get_version (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - return (sdp_p->version); -} - -/* Function: sdp_set_version - * Description: Sets the value of the version parameter for the v= version - * token line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * version Version to set. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_version (void *sdp_ptr, int32 version) -{ - sdp_t *sdp_p = (sdp_t*)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - sdp_p->version = version; - return (SDP_SUCCESS); -} - -/* Function: sdp_owner_valid - * Description: Returns true or false depending on whether the owner - * token line has been defined for this SDP. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: TRUE or FALSE. - */ -tinybool sdp_owner_valid (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if ((sdp_p->owner_name[0] == '\0') || - (sdp_p->owner_network_type == SDP_NT_INVALID) || - (sdp_p->owner_addr_type == SDP_AT_INVALID) || - (sdp_p->owner_addr[0] == '\0')) { - return (FALSE); - } else { - return (TRUE); - } -} - -/* Function: sdp_get_owner_username - * Description: Returns a pointer to the value of the username parameter - * from the o= owner token line. Value is returned as a - * const ptr and so cannot be modified by the application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Version value. - */ -const char *sdp_get_owner_username (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - return (sdp_p->owner_name); -} - -/* Function: sdp_get_owner_sessionid - * Description: Returns the session id parameter from the o= owner token - * line. Because the value may be larger than 32 bits, this - * parameter is returned as a string, though has been verified - * to be numeric. Value is returned as a const ptr and so - * cannot be modified by the application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Ptr to owner session id or NULL. - */ -const char *sdp_get_owner_sessionid (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - return (sdp_p->owner_sessid); -} - -/* Function: sdp_get_owner_version - * Description: Returns the version parameter from the o= owner token - * line. Because the value may be larger than 32 bits, this - * parameter is returned as a string, though has been verified - * to be numeric. Value is returned as a const ptr and so - * cannot be modified by the application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Ptr to owner version or NULL. - */ -const char *sdp_get_owner_version (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - return (sdp_p->owner_version); -} - -/* Function: sdp_get_owner_network_type - * Description: Returns the network type parameter from the o= owner token - * line. If network type has not been set SDP_NT_INVALID will - * be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Network type or SDP_NT_INVALID. - */ -sdp_nettype_e sdp_get_owner_network_type (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_NT_INVALID); - } - - return (sdp_p->owner_network_type); -} - -/* Function: sdp_get_owner_address_type - * Description: Returns the address type parameter from the o= owner token - * line. If address type has not been set SDP_AT_INVALID will - * be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Address type or SDP_AT_INVALID. - */ -sdp_addrtype_e sdp_get_owner_address_type (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_AT_INVALID); - } - - return (sdp_p->owner_addr_type); -} - -/* Function: sdp_get_owner_address - * Description: Returns the address parameter from the o= owner token - * line. Value is returned as a const ptr and so - * cannot be modified by the application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Ptr to address or NULL. - */ -const char *sdp_get_owner_address (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - return (sdp_p->owner_addr); -} - -/* Function: sdp_set_owner_username - * Description: Sets the value of the username parameter for the o= owner - * token line. The string is copied into the SDP structure - * so application memory will not be referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * username Ptr to the username string. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_owner_username (void *sdp_ptr, const char *username) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - sstrncpy(sdp_p->owner_name, username, sizeof(sdp_p->owner_name)); - return (SDP_SUCCESS); -} - -/* Function: sdp_set_owner_username - * Description: Sets the value of the session id parameter for the o= owner - * token line. The string is copied into the SDP structure - * so application memory will not be referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * sessionid Ptr to the sessionid string. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_owner_sessionid (void *sdp_ptr, const char *sessionid) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - sstrncpy(sdp_p->owner_sessid, sessionid, sizeof(sdp_p->owner_sessid)); - return (SDP_SUCCESS); -} - -/* Function: sdp_set_owner_version - * Description: Sets the value of the version parameter for the o= owner - * token line. The string is copied into the SDP structure - * so application memory will not be referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * version Ptr to the version string. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_owner_version (void *sdp_ptr, const char *version) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - sstrncpy(sdp_p->owner_version, version, sizeof(sdp_p->owner_version)); - return (SDP_SUCCESS); -} - -/* Function: sdp_set_owner_network_type - * Description: Sets the value of the network type parameter for the o= owner - * token line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * network_type Network type for the owner line. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_owner_network_type (void *sdp_ptr, - sdp_nettype_e network_type) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - sdp_p->owner_network_type = network_type; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_owner_address_type - * Description: Sets the value of the address type parameter for the o= owner - * token line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * address_type Address type for the owner line. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_owner_address_type (void *sdp_ptr, - sdp_addrtype_e address_type) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - sdp_p->owner_addr_type = address_type; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_owner_address - * Description: Sets the value of the address parameter for the o= owner - * token line. The string is copied into the SDP structure - * so application memory will not be referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * version Ptr to the version string. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_owner_address (void *sdp_ptr, const char *address) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - sstrncpy(sdp_p->owner_addr, address, sizeof(sdp_p->owner_addr)); - return (SDP_SUCCESS); -} - -/* Function: sdp_session_name_valid - * Description: Returns true or false depending on whether the session name - * s= token line has been defined for this SDP. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: TRUE or FALSE. - */ -tinybool sdp_session_name_valid (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (sdp_p->sessname[0] == '\0') { - return (FALSE); - } else { - return (TRUE); - } -} - -/* Function: sdp_get_session_name - * Description: Returns the session name parameter from the s= session - * name token line. Value is returned as a const ptr and so - * cannot be modified by the application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Ptr to session name or NULL. - */ -const char *sdp_get_session_name (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - return (sdp_p->sessname); -} - -/* Function: sdp_set_session_name - * Description: Sets the value of the session name parameter for the s= - * session name token line. The string is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * sessname Ptr to the session name string. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_session_name (void *sdp_ptr, const char *sessname) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - sstrncpy(sdp_p->sessname, sessname, sizeof(sdp_p->sessname)); - return (SDP_SUCCESS); -} - -/* Function: sdp_timespec_valid - * Description: Returns true or false depending on whether the timespec t= - * token line has been defined for this SDP. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: TRUE or FALSE. - */ -tinybool sdp_timespec_valid (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if ((sdp_p->timespec_p == NULL) || - (sdp_p->timespec_p->start_time == '\0') || - (sdp_p->timespec_p->stop_time == '\0')) { - return (FALSE); - } else { - return (TRUE); - } -} - -/* Function: sdp_get_time_start - * Description: Returns the start time parameter from the t= timespec token - * line. Because the value may be larger than 32 bits, this - * parameter is returned as a string, though has been verified - * to be numeric. Value is returned as a const ptr and so - * cannot be modified by the application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Ptr to start time or NULL. - */ -const char *sdp_get_time_start (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - if (sdp_p->timespec_p != NULL) { - return (sdp_p->timespec_p->start_time); - } else { - return (NULL); - } -} - -/* Function: sdp_get_time_stop - * Description: Returns the stop time parameter from the t= timespec token - * line. Because the value may be larger than 32 bits, this - * parameter is returned as a string, though has been verified - * to be numeric. Value is returned as a const ptr and so - * cannot be modified by the application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Ptr to stop time or NULL. - */ -const char *sdp_get_time_stop (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - if (sdp_p->timespec_p != NULL) { - return (sdp_p->timespec_p->stop_time); - } else { - return (NULL); - } -} - -/* Function: sdp_set_time_start - * Description: Sets the value of the start time parameter for the t= - * timespec token line. The string is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * start_time Ptr to the start time string. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_time_start (void *sdp_ptr, const char *start_time) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_p->timespec_p == NULL) { - sdp_p->timespec_p = (sdp_timespec_t *)SDP_MALLOC(sizeof(sdp_timespec_t)); - if (sdp_p->timespec_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - sdp_p->timespec_p->start_time[0] = '\0'; - sdp_p->timespec_p->stop_time[0] = '\0'; - } - sstrncpy(sdp_p->timespec_p->start_time, start_time, - sizeof(sdp_p->timespec_p->start_time)); - return (SDP_SUCCESS); -} - -/* Function: sdp_set_time_stop - * Description: Sets the value of the stop time parameter for the t= - * timespec token line. The string is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * stop_time Ptr to the stop time string. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_time_stop (void *sdp_ptr, const char *stop_time) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_p->timespec_p == NULL) { - sdp_p->timespec_p = (sdp_timespec_t *)SDP_MALLOC(sizeof(sdp_timespec_t)); - if (sdp_p->timespec_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - sdp_p->timespec_p->start_time[0] = '\0'; - sdp_p->timespec_p->stop_time[0] = '\0'; - } - sstrncpy(sdp_p->timespec_p->stop_time, stop_time, - sizeof(sdp_p->timespec_p->stop_time)); - return (SDP_SUCCESS); -} - -/* Function: sdp_encryption_valid - * Description: Returns true or false depending on whether the encryption k= - * token line has been defined for this SDP at the given level. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the k= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: TRUE or FALSE. - */ -tinybool sdp_encryption_valid (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_encryptspec_t *encrypt_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (level == SDP_SESSION_LEVEL) { - encrypt_p = &(sdp_p->encrypt); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (FALSE); - } - encrypt_p = &(mca_p->encrypt); - } - - if ((encrypt_p->encrypt_type == SDP_ENCRYPT_INVALID) || - ((encrypt_p->encrypt_type != SDP_ENCRYPT_PROMPT) && - (encrypt_p->encrypt_key[0] == '\0'))) { - return (FALSE); - } else { - return (TRUE); - } -} - -/* Function: sdp_get_encryption_method - * Description: Returns the encryption method parameter from the k= - * encryption token line. If encryption method has not been - * set SDP_ENCRYPT_INVALID will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: Encryption method or SDP_ENCRYPT_INVALID. - */ -sdp_encrypt_type_e sdp_get_encryption_method (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_encryptspec_t *encrypt_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_ENCRYPT_INVALID); - } - - if (level == SDP_SESSION_LEVEL) { - encrypt_p = &(sdp_p->encrypt); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_ENCRYPT_INVALID); - } - encrypt_p = &(mca_p->encrypt); - } - - return (encrypt_p->encrypt_type); -} - -/* Function: sdp_get_encryption_key - * Description: Returns a pointer to the encryption key parameter - * from the k= encryption token line. Value is returned as a - * const ptr and so cannot be modified by the application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: Ptr to encryption key or NULL. - */ -const char *sdp_get_encryption_key (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_encryptspec_t *encrypt_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - if (level == SDP_SESSION_LEVEL) { - encrypt_p = &(sdp_p->encrypt); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (NULL); - } - encrypt_p = &(mca_p->encrypt); - } - - return (encrypt_p->encrypt_key); -} - -/* Function: sdp_set_encryption_method - * Description: Sets the value of the encryption method param for the k= - * encryption token line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the k= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * type The encryption type. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_encryption_method (void *sdp_ptr, u16 level, - sdp_encrypt_type_e type) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_encryptspec_t *encrypt_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (level == SDP_SESSION_LEVEL) { - encrypt_p = &(sdp_p->encrypt); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - encrypt_p = &(mca_p->encrypt); - } - - encrypt_p->encrypt_type = type; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_encryption_key - * Description: Sets the value of the encryption key parameter for the k= - * encryption token line. The string is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the k= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * key Ptr to the encryption key string. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_encryption_key (void *sdp_ptr, u16 level, const char *key) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_encryptspec_t *encrypt_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (level == SDP_SESSION_LEVEL) { - encrypt_p = &(sdp_p->encrypt); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - encrypt_p = &(mca_p->encrypt); - } - - sstrncpy(encrypt_p->encrypt_key, key, sizeof(encrypt_p->encrypt_key)); - return (SDP_SUCCESS); -} - -/* Function: sdp_connection_valid - * Description: Returns true or false depending on whether the connection c= - * token line has been defined for this SDP at the given level. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: TRUE or FALSE. - */ -tinybool sdp_connection_valid (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (FALSE); - } - conn_p = &(mca_p->conn); - } - - /*if network type is ATM . then allow c= line without address type - * and address . This is a special case to cover PVC - */ - if (conn_p->nettype == SDP_NT_ATM && - conn_p->addrtype == SDP_AT_INVALID) { - return TRUE; - } - - if ((conn_p->nettype >= SDP_MAX_NETWORK_TYPES) || - (conn_p->addrtype >= SDP_MAX_ADDR_TYPES) || - (conn_p->conn_addr[0] == '\0')) { - return (FALSE); - } else { - return (TRUE); - } -} - -/* Function: sdp_bandwidth_valid - * Description: Returns true or false depending on whether the bandwidth b= - * token line has been defined for this SDP at the given level. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * inst_num instance number of bw line at that level. The first - * instance has a inst_num of 1 and so on. - * Returns: TRUE or FALSE. - */ -tinybool sdp_bandwidth_valid (void *sdp_ptr, u16 level, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_bw_data_t *bw_data_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return FALSE; - } - - bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num); - if (bw_data_p != NULL) { - if ((bw_data_p->bw_modifier < SDP_BW_MODIFIER_AS) || - (bw_data_p->bw_modifier >= SDP_MAX_BW_MODIFIER_VAL)) { - return FALSE; - } else { - return TRUE; - } - } else { - return FALSE; - } -} - -/* - * sdp_bw_line_exists - * - * Description: This api retruns true if there exists a bw line at the - * instance and level specified. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * inst_num instance number of bw line at that level. The first - * instance has a inst_num of 1 and so on. - * Returns: TRUE or FALSE - */ -tinybool sdp_bw_line_exists (void *sdp_ptr, u16 level, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_bw_data_t *bw_data_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return FALSE; - } - - bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num); - if (bw_data_p != NULL) { - return TRUE; - } else { - return FALSE; - } -} - -/* Function: sdp_get_conn_nettype - * Description: Returns the network type parameter from the c= - * connection token line. If network type has not been - * set SDP_NT_INVALID will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: Network type or SDP_NT_INVALID. - */ -sdp_nettype_e sdp_get_conn_nettype (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_NT_INVALID); - } - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_NT_INVALID); - } - conn_p = &(mca_p->conn); - } - - return (conn_p->nettype); -} - -/* Function: sdp_get_conn_addrtype - * Description: Returns the address type parameter from the c= - * connection token line. If address type has not been - * set SDP_AT_INVALID will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: Address type or SDP_AT_INVALID. - */ -sdp_addrtype_e sdp_get_conn_addrtype (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_AT_INVALID); - } - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_AT_INVALID); - } - conn_p = &(mca_p->conn); - } - - return (conn_p->addrtype); -} - -/* Function: sdp_get_conn_address - * Description: Returns a pointer to the address parameter - * from the c= connection token line. Value is returned as a - * const ptr and so cannot be modified by the application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: Ptr to address or NULL. - */ -const char *sdp_get_conn_address (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (NULL); - } - conn_p = &(mca_p->conn); - } - - return (conn_p->conn_addr); -} - -/* Function: sdp_is_mcast_addr - * Description: Returns a boolean to indicate if the addr is multicast in - * the c=line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: TRUE if the addr is multicast, FALSE if not. - */ - -tinybool sdp_is_mcast_addr (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p != NULL) { - conn_p = &(mca_p->conn); - } else { - return (FALSE); - } - } - - if ((conn_p) && (conn_p->is_multicast)) { - return (TRUE); - } else { - return (FALSE); - } -} - -/* Function: sdp_get_mcast_ttl - * Description: Get the time to live(ttl) value for the multicast address - * if present. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: Multicast address - Time to live (ttl) value - */ - -int32 sdp_get_mcast_ttl (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - u16 ttl=0; - - if (sdp_verify_sdp_ptr(sdp_p) != FALSE) { - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p != NULL) { - conn_p = &(mca_p->conn); - } else { - return SDP_INVALID_VALUE; - } - } - } else { - return SDP_INVALID_VALUE; - } - - if (conn_p) { - ttl = conn_p->ttl; - } - return ttl; -} - -/* Function: sdp_get_mcast_num_of_addresses - * Description: Get the number of addresses value for the multicast address - * if present. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: Multicast address - number of addresses value - */ - -int32 sdp_get_mcast_num_of_addresses (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - u16 num_addr = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } else { - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p != NULL) { - conn_p = &(mca_p->conn); - } else { - return (SDP_INVALID_VALUE); - } - } - } - - if (conn_p) { - num_addr = conn_p->num_of_addresses; - } - return num_addr; -} -/* Function: sdp_set_conn_nettype - * Description: Sets the value of the network type parameter for the c= - * connection token line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * nettype Network type for the connection line. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_conn_nettype (void *sdp_ptr, u16 level, - sdp_nettype_e nettype) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - conn_p = &(mca_p->conn); - } - - conn_p->nettype = nettype; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_conn_addrtype - * Description: Sets the value of the address type parameter for the c= - * connection token line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * addrtype Address type for the connection line. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_conn_addrtype (void *sdp_ptr, u16 level, - sdp_addrtype_e addrtype) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - conn_p = &(mca_p->conn); - } - - conn_p->addrtype = addrtype; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_conn_address - * Description: Sets the value of the address parameter for the c= - * connection token line. The string is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * address Ptr to the address string. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_conn_address (void *sdp_ptr, u16 level, - const char *address) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - conn_p = &(mca_p->conn); - } - - sstrncpy(conn_p->conn_addr, address, sizeof(conn_p->conn_addr)); - return (SDP_SUCCESS); -} - -/* Function: sdp_set_mcast_addr_fields - * Description: Sets the value of the ttl and num of addresses for - * a multicast address. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * ttl Time to live (ttl) value. - * num_of_addresses number of addresses - . - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_mcast_addr_fields(void *sdp_ptr, u16 level, - u16 ttl, u16 num_of_addresses) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - conn_p = &(mca_p->conn); - } - - if (conn_p) { - conn_p->is_multicast = TRUE; - if ((conn_p->ttl >0) && (conn_p->ttl <= SDP_MAX_TTL_VALUE)) { - conn_p->ttl = ttl; - } - conn_p->num_of_addresses = num_of_addresses; - } else { - return (SDP_FAILURE); - } - return (SDP_SUCCESS); -} - - -/* Function: sdp_media_line_valid - * Description: Returns true or false depending on whether the specified - * media line m= has been defined for this SDP. The - * SDP_SESSION_LEVEL level is not valid for this check since, - * by definition, this is a media level. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * 1-n specifying a media line level. - * Returns: TRUE or FALSE. - */ -tinybool sdp_media_line_valid (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (FALSE); - } - - /* Validate params for this media line */ - if ((mca_p->media >= SDP_MAX_MEDIA_TYPES) || - (mca_p->port_format >= SDP_MAX_PORT_FORMAT_TYPES) || - (mca_p->transport >= SDP_MAX_TRANSPORT_TYPES) || - (mca_p->num_payloads == 0)) { - return (FALSE); - } else { - return (TRUE); - } -} - -/* Function: sdp_get_num_media_lines - * Description: Returns the number of media lines associated with the SDP. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * Returns: Number of media lines. - */ -u16 sdp_get_num_media_lines (void *sdp_ptr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - return (sdp_p->mca_count); -} - -/* Function: sdp_get_media_type - * Description: Returns the media type parameter from the m= - * media token line. If media type has not been - * set SDP_MEDIA_INVALID will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: Media type or SDP_MEDIA_INVALID. - */ -sdp_media_e sdp_get_media_type (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_MEDIA_INVALID); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_MEDIA_INVALID); - } - - return (mca_p->media); -} - -/* Function: sdp_get_media_port_format - * Description: Returns the port format type associated with the m= - * media token line. If port format type has not been - * set SDP_PORT_FORMAT_INVALID will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: Port format type or SDP_PORT_FORMAT_INVALID. - */ -sdp_port_format_e sdp_get_media_port_format (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_PORT_FORMAT_INVALID); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_PORT_FORMAT_INVALID); - } - - return (mca_p->port_format); -} - -/* Function: sdp_get_media_portnum - * Description: Returns the port number associated with the m= - * media token line. If port number has not been - * set SDP_INVALID_VALUE will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: Port number or SDP_INVALID_VALUE. - */ -int32 sdp_get_media_portnum (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_INVALID_VALUE); - } - - /* Make sure port number is valid for the specified format. */ - if ((mca_p->port_format != SDP_PORT_NUM_ONLY) && - (mca_p->port_format != SDP_PORT_NUM_COUNT) && - (mca_p->port_format != SDP_PORT_NUM_VPI_VCI) && - (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Port num not valid for media line %u", - sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } - - return (mca_p->port); -} - -/* Function: sdp_get_media_portcount - * Description: Returns the port count associated with the m= - * media token line. If port count has not been - * set SDP_INVALID_VALUE will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: Port count or SDP_INVALID_VALUE. - */ -int32 sdp_get_media_portcount (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_INVALID_VALUE); - } - - /* Make sure port number is valid for the specified format. */ - if (mca_p->port_format != SDP_PORT_NUM_COUNT) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Port count not valid for media line %u", - sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } - - return (mca_p->num_ports); -} - -/* Function: sdp_get_media_vpi - * Description: Returns the VPI parameter associated with the m= - * media token line. If VPI has not been set - * SDP_INVALID_VALUE will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: VPI or SDP_INVALID_VALUE. - */ -int32 sdp_get_media_vpi (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_INVALID_VALUE); - } - - /* Make sure port number is valid for the specified format. */ - if ((mca_p->port_format != SDP_PORT_VPI_VCI) && - (mca_p->port_format != SDP_PORT_NUM_VPI_VCI) && - (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s VPI not valid for media line %u", - sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } - - return (mca_p->vpi); -} - -/* Function: sdp_get_media_vci - * Description: Returns the VCI parameter associated with the m= - * media token line. If VCI has not been set - * SDP_INVALID_VALUE will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: VCI or zero. - */ -u32 sdp_get_media_vci (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (0); - } - - /* Make sure port number is valid for the specified format. */ - if ((mca_p->port_format != SDP_PORT_VPI_VCI) && - (mca_p->port_format != SDP_PORT_NUM_VPI_VCI) && - (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s VCI not valid for media line %u", - sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } - - return (mca_p->vci); -} - -/* Function: sdp_get_media_vcci - * Description: Returns the VCCI parameter associated with the m= - * media token line. If VCCI has not been set - * SDP_INVALID_VALUE will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: VCCI or SDP_INVALID_VALUE. - */ -int32 sdp_get_media_vcci (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_INVALID_VALUE); - } - - /* Make sure port number is valid for the specified format. */ - if ((mca_p->port_format != SDP_PORT_VCCI) && - (mca_p->port_format != SDP_PORT_VCCI_CID)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s VCCI not valid for media line %u", - sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } - - return (mca_p->vcci); -} - -/* Function: sdp_get_media_cid - * Description: Returns the CID parameter associated with the m= - * media token line. If CID has not been set - * SDP_INVALID_VALUE will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: CID or SDP_INVALID_VALUE. - */ -int32 sdp_get_media_cid (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_INVALID_VALUE); - } - - /* Make sure port number is valid for the specified format. */ - if ((mca_p->port_format != SDP_PORT_VCCI_CID) && - (mca_p->port_format != SDP_PORT_NUM_VPI_VCI_CID)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CID not valid for media line %u", - sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } - - return (mca_p->cid); -} - -/* Function: sdp_get_media_transport - * Description: Returns the transport type parameter associated with the m= - * media token line. If transport type has not been set - * SDP_TRANSPORT_INVALID will be returned. If the transport - * type is one of the AAL2 variants, the profile routines below - * should be used to access multiple profile types and payload - * lists per m= line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: CID or SDP_TRANSPORT_INVALID. - */ -sdp_transport_e sdp_get_media_transport (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_TRANSPORT_INVALID); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_TRANSPORT_INVALID); - } - - return (mca_p->transport); -} - -/* Function: sdp_get_media_num_profiles - * Description: Returns the number of profiles associated with the m= - * media token line. If the media line is invalid, zero will - * be returned. Application must validate the media line - * before using this routine. Multiple profile types per - * media line is currently only used for AAL2. If the appl - * detects that the transport type is one of the AAL2 types, - * it should use these profile access routines to access the - * profile types and payload list for each. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: Number of profiles or zero. - */ -u16 sdp_get_media_num_profiles (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (0); - } - - if (mca_p->media_profiles_p == NULL) { - return (0); - } else { - return (mca_p->media_profiles_p->num_profiles); - } -} - -/* Function: sdp_get_media_profile - * Description: Returns the specified profile type associated with the m= - * media token line. If the media line or profile number is - * invalid, SDP_TRANSPORT_INVALID will be returned. - * Applications must validate the media line before using this - * routine. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * profile_num The specific profile type number to be retrieved. - * Returns: The profile type or SDP_TRANSPORT_INVALID. - */ -sdp_transport_e sdp_get_media_profile (void *sdp_ptr, u16 level, - u16 profile_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_TRANSPORT_INVALID); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_TRANSPORT_INVALID); - } - - if ((profile_num < 1) || - (profile_num > mca_p->media_profiles_p->num_profiles)) { - return (SDP_TRANSPORT_INVALID); - } else { - return (mca_p->media_profiles_p->profile[profile_num-1]); - } -} - -/* Function: sdp_get_media_num_payload_types - * Description: Returns the number of payload types associated with the m= - * media token line. If the media line is invalid, zero will - * be returned. Application must validate the media line - * before using this routine. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * Returns: Number of payload types or zero. - */ -u16 sdp_get_media_num_payload_types (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (0); - } - - return (mca_p->num_payloads); -} - -/* Function: sdp_get_media_profile_num_payload_types - * Description: Returns the number of payload types associated with the - * specified profile on the m= media token line. If the - * media line or profile number is invalid, zero will - * be returned. Application must validate the media line - * and profile before using this routine. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * profile_num The specific profile number. Will be 1-n. - * Returns: Number of payload types or zero. - */ -u16 sdp_get_media_profile_num_payload_types (void *sdp_ptr, u16 level, - u16 profile_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (0); - } - - if ((profile_num < 1) || - (profile_num > mca_p->media_profiles_p->num_profiles)) { - return (0); - } else { - return (mca_p->media_profiles_p->num_payloads[profile_num-1]); - } -} - -/* Function: sdp_get_media_payload_type - * Description: Returns the payload type of the specified payload for the m= - * media token line. If the media line or payload number is - * invalid, zero will be returned. Application must validate - * the media line before using this routine. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * payload_num Number of the payload type to retrieve. The - * range is (1 - max num payloads). - * indicator Returns the type of payload returned, either - * NUMERIC or ENUM. - * Returns: Payload type or zero. - */ -u32 sdp_get_media_payload_type (void *sdp_ptr, u16 level, u16 payload_num, - sdp_payload_ind_e *indicator) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - uint16_t num_a_lines = 0; - int i; - uint16_t ptype; - uint16_t pack_mode = 0; /*default 0, if remote did not provide any */ - const char *encname = NULL; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (0); - } - - if ((payload_num < 1) || (payload_num > mca_p->num_payloads)) { - return (0); - } - - *indicator = mca_p->payload_indicator[payload_num-1]; - if ((mca_p->payload_type[payload_num-1] >= SDP_MIN_DYNAMIC_PAYLOAD) && - (mca_p->payload_type[payload_num-1] <= SDP_MAX_DYNAMIC_PAYLOAD)) { - /* - * Get number of RTPMAP attributes for the AUDIO line - */ - (void) sdp_attr_num_instances(sdp_p, level, 0, SDP_ATTR_RTPMAP, - &num_a_lines); - /* - * Loop through AUDIO media line RTPMAP attributes. - * NET dynamic payload type will be returned. - */ - for (i = 0; i < num_a_lines; i++) { - ptype = sdp_attr_get_rtpmap_payload_type(sdp_p, level, 0, - (uint16_t) (i + 1)); - if (ptype == mca_p->payload_type[payload_num-1] ) { - encname = sdp_attr_get_rtpmap_encname(sdp_p, level, 0, - (uint16_t) (i + 1)); - if (encname) { - if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_ILBC) == 0) { - return (SET_PAYLOAD_TYPE_WITH_DYNAMIC(ptype, RTP_ILBC)); - } - if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_L16_256K) == 0) { - return (SET_PAYLOAD_TYPE_WITH_DYNAMIC(ptype, RTP_L16)); - } - if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_ISAC) == 0) { - return (SET_PAYLOAD_TYPE_WITH_DYNAMIC(ptype, RTP_ISAC)); - } - if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_OPUS) == 0) { - return (SET_PAYLOAD_TYPE_WITH_DYNAMIC(ptype, RTP_OPUS)); - } - if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_H264) == 0) { - sdp_attr_get_fmtp_pack_mode(sdp_p, level, 0, (uint16_t) (i + 1), &pack_mode); - if (pack_mode == SDP_DEFAULT_PACKETIZATION_MODE_VALUE) { - return (SET_PAYLOAD_TYPE_WITH_DYNAMIC(ptype, RTP_H264_P0)); - } else { - return (SET_PAYLOAD_TYPE_WITH_DYNAMIC(ptype, RTP_H264_P1)); - } - } - if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_VP8) == 0) { - return (SET_PAYLOAD_TYPE_WITH_DYNAMIC(ptype, RTP_VP8)); - } - } - } - } - } - return (mca_p->payload_type[payload_num-1]); -} - -/* Function: sdp_get_media_profile_payload_type - * Description: Returns the payload type of the specified payload for the m= - * media token line. If the media line or payload number is - * invalid, zero will be returned. Application must validate - * the media line before using this routine. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to of the m= media line. Will be 1-n. - * payload_num Number of the payload type to retrieve. The - * range is (1 - max num payloads). - * indicator Returns the type of payload returned, either - * NUMERIC or ENUM. - * Returns: Payload type or zero. - */ -u32 sdp_get_media_profile_payload_type (void *sdp_ptr, u16 level, u16 prof_num, - u16 payload_num, - sdp_payload_ind_e *indicator) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - sdp_media_profiles_t *prof_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (0); - } - - prof_p = mca_p->media_profiles_p; - if ((prof_num < 1) || - (prof_num > prof_p->num_profiles)) { - return (0); - } - - if ((payload_num < 1) || - (payload_num > prof_p->num_payloads[prof_num-1])) { - return (0); - } - - *indicator = prof_p->payload_indicator[prof_num-1][payload_num-1]; - return (prof_p->payload_type[prof_num-1][payload_num-1]); -} - -/* Function: sdp_insert_media_line - * Description: Insert a new media line at the level specified for the - * given SDP. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The new media level to insert. Will be 1-n. - * Returns: SDP_SUCCESS, SDP_NO_RESOURCE, or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_insert_media_line (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - sdp_mca_t *new_mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if ((level < 1) || (level > (sdp_p->mca_count+1))) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Invalid media line (%u) to insert, max is " - "(%u).", sdp_p->debug_str, level, sdp_p->mca_count); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Allocate resource for new media stream. */ - new_mca_p = sdp_alloc_mca(); - if (new_mca_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - - if (level == 1) { - /* We're inserting the first media line */ - new_mca_p->next_p = sdp_p->mca_p; - sdp_p->mca_p = new_mca_p; - } else { - /* Find the pointer to the media stream just prior to where - * we want to insert the new stream. - */ - mca_p = sdp_find_media_level(sdp_p, (u16)(level-1)); - if (mca_p == NULL) { - SDP_FREE(new_mca_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - new_mca_p->next_p = mca_p->next_p; - mca_p->next_p = new_mca_p; - } - - sdp_p->mca_count++; - return (SDP_SUCCESS); -} - -/* Function: sdp_delete_media_line - * Description: Delete the media line at the level specified for the - * given SDP. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to delete. Will be 1-n. - * Returns: SDP_SUCCESS, SDP_NO_RESOURCE, or SDP_INVALID_PARAMETER - */ -void sdp_delete_media_line (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - sdp_mca_t *prev_mca_p = NULL; - sdp_attr_t *attr_p; - sdp_attr_t *next_attr_p; - sdp_bw_t *bw_p; - sdp_bw_data_t *bw_data_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return; - } - - /* If we're not deleting media line 1, then we need a pointer - * to the previous media line so we can relink. */ - if (level == 1) { - mca_p = sdp_find_media_level(sdp_p, level); - } else { - prev_mca_p = sdp_find_media_level(sdp_p, (u16)(level-1)); - if (prev_mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return; - } - mca_p = prev_mca_p->next_p; - } - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return; - } - - /* Delete all attributes from this level. */ - for (attr_p = mca_p->media_attrs_p; attr_p != NULL;) { - next_attr_p = attr_p->next_p; - sdp_free_attr(attr_p); - attr_p = next_attr_p; - } - - /* Delete bw line */ - bw_p = &(mca_p->bw); - bw_data_p = bw_p->bw_data_list; - while (bw_data_p != NULL) { - bw_p->bw_data_list = bw_data_p->next_p; - SDP_FREE(bw_data_p); - bw_data_p = bw_p->bw_data_list; - } - - /* Now relink the media levels and delete the specified one. */ - if (prev_mca_p == NULL) { - sdp_p->mca_p = mca_p->next_p; - } else { - prev_mca_p->next_p = mca_p->next_p; - } - SDP_FREE(mca_p); - sdp_p->mca_count--; - return; -} - -/* Function: sdp_set_media_type - * Description: Sets the value of the media type parameter for the m= - * media token line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * media Media type for the media line. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_type (void *sdp_ptr, u16 level, sdp_media_e media) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->media = media; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_port_format - * Description: Sets the value of the port format parameter for the m= - * media token line. Note that this parameter must be set - * before any of the port type specific parameters. If a - * parameter is not valid according to the port format - * specified, an attempt to set the parameter will fail. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * port_format Media type for the media line. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_port_format (void *sdp_ptr, u16 level, - sdp_port_format_e port_format) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->port_format = port_format; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_portnum - * Description: Sets the value of the port number parameter for the m= - * media token line. If the port number is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * portnum Port number to set. - * sctpport sctp port for application m= line - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_portnum (void *sdp_ptr, u16 level, int32 portnum, int32 sctp_port) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->port = portnum; - mca_p->sctpport = sctp_port; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_portcount - * Description: Sets the value of the port count parameter for the m= - * media token line. If the port count is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * num_ports Port count to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_portcount (void *sdp_ptr, u16 level, - int32 num_ports) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->num_ports = num_ports; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_vpi - * Description: Sets the value of the VPI parameter for the m= - * media token line. If the VPI is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * vpi The VPI value to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_vpi (void *sdp_ptr, u16 level, int32 vpi) -{ - sdp_t *sdp_p = (sdp_t*)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->vpi = vpi; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_vci - * Description: Sets the value of the VCI parameter for the m= - * media token line. If the VCI is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * vci The VCI value to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_vci (void *sdp_ptr, u16 level, u32 vci) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->vci = vci; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_vcci - * Description: Sets the value of the VCCI parameter for the m= - * media token line. If the VCCI is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * vcci The VCCI value to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_vcci (void *sdp_ptr, u16 level, int32 vcci) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->vcci = vcci; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_cid - * Description: Sets the value of the CID parameter for the m= - * media token line. If the CID is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * cid The CID value to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_cid (void *sdp_ptr, u16 level, int32 cid) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->cid = cid; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_transport - * Description: Sets the value of the transport type parameter for the m= - * media token line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * transport The transport type to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_transport (void *sdp_ptr, u16 level, - sdp_transport_e transport) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->transport = transport; - return (SDP_SUCCESS); -} - -/* Function: sdp_add_media_profile - * Description: Add a new profile type for the m= media token line. This is - * used for AAL2 transport/profile types where more than one can - * be specified per media line. All other transport types should - * use the other transport access routines rather than this. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to add the param. Will be 1-n. - * profile The profile type to add. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_add_media_profile (void *sdp_ptr, u16 level, - sdp_transport_e profile) -{ - u16 prof_num; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (mca_p->media_profiles_p == NULL) { - mca_p->media_profiles_p = (sdp_media_profiles_t *) \ - SDP_MALLOC(sizeof(sdp_media_profiles_t)); - if (mca_p->media_profiles_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } else { - mca_p->media_profiles_p->num_profiles = 0; - /* Set the transport type to this first profile type. */ - mca_p->transport = profile; - } - } - - if (mca_p->media_profiles_p->num_profiles >= SDP_MAX_PROFILES) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Max number of media profiles already specified" - " for media level %u", sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - prof_num = mca_p->media_profiles_p->num_profiles++; - mca_p->media_profiles_p->profile[prof_num] = profile; - mca_p->media_profiles_p->num_payloads[prof_num] = 0; - return (SDP_SUCCESS); -} - -/* Function: sdp_add_media_payload_type - * Description: Add a new payload type for the media line at the level - * specified. The new payload type will be added at the end - * of the payload type list. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to add the payload. Will be 1-n. - * payload_type The new payload type. - * indicator Defines the type of payload returned, either - * NUMERIC or ENUM. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_add_media_payload_type (void *sdp_ptr, u16 level, - u16 payload_type, - sdp_payload_ind_e indicator) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (mca_p->num_payloads == SDP_MAX_PAYLOAD_TYPES) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Max number of payload types already defined " - "for media line %u", sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->payload_indicator[mca_p->num_payloads] = indicator; - mca_p->payload_type[mca_p->num_payloads++] = payload_type; - return (SDP_SUCCESS); -} - -/* Function: sdp_add_media_profile_payload_type - * Description: Add a new payload type for the media line at the level - * specified. The new payload type will be added at the end - * of the payload type list. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The media level to add the payload. Will be 1-n. - * prof_num The profile number to add the payload type. - * payload_type The new payload type. - * indicator Defines the type of payload returned, either - * NUMERIC or ENUM. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_add_media_profile_payload_type (void *sdp_ptr, u16 level, - u16 prof_num, u16 payload_type, - sdp_payload_ind_e indicator) -{ - u16 num_payloads; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if ((prof_num < 1) || - (prof_num > mca_p->media_profiles_p->num_profiles)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Invalid profile number (%u) for set profile " - " payload type", sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (mca_p->media_profiles_p->num_payloads[prof_num-1] == - SDP_MAX_PAYLOAD_TYPES) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Max number of profile payload types already " - "defined profile %u on media line %u", - sdp_p->debug_str, prof_num, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Get the current num payloads for this profile, and inc the number - * of payloads at the same time. Then store the new payload type. */ - num_payloads = mca_p->media_profiles_p->num_payloads[prof_num-1]++; - mca_p->media_profiles_p->payload_indicator[prof_num-1][num_payloads] = - indicator; - mca_p->media_profiles_p->payload_type[prof_num-1][num_payloads] = - payload_type; - return (SDP_SUCCESS); -} - -/* - * sdp_find_bw_line - * - * This helper function locates a specific bw line instance given the - * sdp, the level and the instance number of the bw line. - * - * Returns: Pointer to the sdp_bw_data_t instance, or NULL. - */ -sdp_bw_data_t* sdp_find_bw_line (void *sdp_ptr, u16 level, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_bw_t *bw_p; - sdp_bw_data_t *bw_data_p; - sdp_mca_t *mca_p; - int bw_attr_count=0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - if (level == SDP_SESSION_LEVEL) { - bw_p = &(sdp_p->bw); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } - bw_p = &(mca_p->bw); - } - - for (bw_data_p = bw_p->bw_data_list; - bw_data_p != NULL; - bw_data_p = bw_data_p->next_p) { - bw_attr_count++; - if (bw_attr_count == inst_num) { - return bw_data_p; - } - } - - return NULL; -} - -/* - * sdp_copy_all_bw_lines - * - * Appends all the bw lines from the specified level of the orig sdp to the - * specified level of the dst sdp. - * - * Parameters: src_sdp_ptr The source SDP handle. - * dst_sdp_ptr The dest SDP handle. - * src_level The level in the src sdp from where to get the - * attributes. - * dst_level The level in the dst sdp where to put the - * attributes. - * Returns: SDP_SUCCESS Attributes were successfully copied. - */ -sdp_result_e sdp_copy_all_bw_lines (void *src_sdp_ptr, void *dst_sdp_ptr, - u16 src_level, u16 dst_level) -{ - sdp_t *src_sdp_p = (sdp_t *)src_sdp_ptr; - sdp_t *dst_sdp_p = (sdp_t *)dst_sdp_ptr; - sdp_bw_data_t *orig_bw_data_p; - sdp_bw_data_t *new_bw_data_p; - sdp_bw_data_t *bw_data_p; - sdp_bw_t *src_bw_p; - sdp_bw_t *dst_bw_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(src_sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_verify_sdp_ptr(dst_sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - /* Find src bw list */ - if (src_level == SDP_SESSION_LEVEL) { - src_bw_p = &(src_sdp_p->bw); - } else { - mca_p = sdp_find_media_level(src_sdp_p, src_level); - if (mca_p == NULL) { - if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Invalid src media level (%u) for copy all " - "attrs ", src_sdp_p->debug_str, src_level); - } - return (SDP_INVALID_PARAMETER); - } - src_bw_p = &(mca_p->bw); - } - - /* Find dst bw list */ - if (dst_level == SDP_SESSION_LEVEL) { - dst_bw_p = &(dst_sdp_p->bw); - } else { - mca_p = sdp_find_media_level(dst_sdp_p, dst_level); - if (mca_p == NULL) { - if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Invalid dst media level (%u) for copy all " - "attrs ", src_sdp_p->debug_str, dst_level); - } - return (SDP_INVALID_PARAMETER); - } - dst_bw_p = &(mca_p->bw); - } - - orig_bw_data_p = src_bw_p->bw_data_list; - while (orig_bw_data_p) { - /* For ever bw line in the src, allocate a new one for the dst */ - new_bw_data_p = (sdp_bw_data_t*)SDP_MALLOC(sizeof(sdp_bw_data_t)); - if (new_bw_data_p == NULL) { - return (SDP_NO_RESOURCE); - } - new_bw_data_p->next_p = NULL; - new_bw_data_p->bw_modifier = orig_bw_data_p->bw_modifier; - new_bw_data_p->bw_val = orig_bw_data_p->bw_val; - - /* - * Enqueue the sdp_bw_data_t instance at the end of the list of - * sdp_bw_data_t instances. - */ - if (dst_bw_p->bw_data_list == NULL) { - dst_bw_p->bw_data_list = new_bw_data_p; - } else { - for (bw_data_p = dst_bw_p->bw_data_list; - bw_data_p->next_p != NULL; - bw_data_p = bw_data_p->next_p) { - - /*sa_ignore EMPTYLOOP*/ - ; /* Do nothing. */ - } - - bw_data_p->next_p = new_bw_data_p; - } - dst_bw_p->bw_data_count++; - - orig_bw_data_p = orig_bw_data_p->next_p; - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_get_bw_modifier - * Description: Returns the bandwidth modifier parameter from the b= - * line. If no bw modifier has been set , - * SDP_BW_MODIFIER_UNSUPPORTED will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level from which to get the bw modifier. - * inst_num instance number of bw line at that level. The first - * instance has a inst_num of 1 and so on. - * Returns: Valid modifer value or SDP_BW_MODIFIER_UNSUPPORTED. - */ -sdp_bw_modifier_e sdp_get_bw_modifier (void *sdp_ptr, u16 level, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_bw_data_t *bw_data_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_BW_MODIFIER_UNSUPPORTED); - } - - bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num); - - if (bw_data_p) { - return (bw_data_p->bw_modifier); - } else { - return (SDP_BW_MODIFIER_UNSUPPORTED); - } -} - -/* Function: sdp_get_bw_value - * Description: Returns the bandwidth value parameter from the b= - * line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level from which to get the bw value. - * inst_num instance number of bw line at the level. The first - * instance has a inst_num of 1 and so on. - * Returns: A valid numerical bw value or SDP_INVALID_VALUE. - */ -int32 sdp_get_bw_value (void *sdp_ptr, u16 level, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_bw_data_t *bw_data_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num); - - if (bw_data_p) { - return (bw_data_p->bw_val); - } else { - return (SDP_INVALID_VALUE); - } -} - -/* - * sdp_get_num_bw_lines - * - * Returns the number of bw lines are present at a given level. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level at which the count of bw lines is required - * - * Returns: A valid count or SDP_INVALID_VALUE - */ -int32 sdp_get_num_bw_lines (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_bw_t *bw_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - if (level == SDP_SESSION_LEVEL) { - bw_p = &(sdp_p->bw); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } - bw_p = &(mca_p->bw); - } - - return (bw_p->bw_data_count); -} - -/* - * sdp_add_new_bw_line - * - * To specify bandwidth parameters at any level, a bw line must first be - * added at that level using this function. After this addition, you can set - * the properties of the added bw line by using sdp_set_bw(). - * - * Note carefully though, that since there can be multiple instances of bw - * lines at any level, you must specify the instance number when setting - * or getting the properties of a bw line at any level. - * - * This function returns within the inst_num variable, the instance number - * of the created bw_line at that level. The instance number is 1-based. - * For example: - * v=0 #Session Level - * o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4 - * s=SDP Seminar - * c=IN IP4 10.1.0.2 - * t=0 0 - * b=AS:60 # instance number 1 - * b=TIAS:50780 # instance number 2 - * m=audio 1234 RTP/AVP 0 101 102 # 1st Media level - * b=AS:12 # instance number 1 - * b=TIAS:8480 # instance number 2 - * m=audio 1234 RTP/AVP 0 101 102 # 2nd Media level - * b=AS:20 # instance number 1 - * - * Parameters: - * sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to create the bw line. - * bw_modifier The Type of bandwidth, CT, AS or TIAS. - * *inst_num This memory is set with the instance number of the newly - * created bw line instance. - */ -sdp_result_e sdp_add_new_bw_line (void *sdp_ptr, u16 level, sdp_bw_modifier_e bw_modifier, u16 *inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_bw_t *bw_p; - sdp_mca_t *mca_p; - sdp_bw_data_t *new_bw_data_p; - sdp_bw_data_t *bw_data_p = NULL; - - *inst_num = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (level == SDP_SESSION_LEVEL) { - bw_p = &(sdp_p->bw); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - bw_p = &(mca_p->bw); - } - - //see if a bw line already exist for this bw_modifier. - for(bw_data_p = bw_p->bw_data_list; bw_data_p != NULL; bw_data_p = bw_data_p->next_p) { - ++(*inst_num); - if (bw_data_p->bw_modifier == bw_modifier) { - return (SDP_SUCCESS); - } - } - - /* - * Allocate a new sdp_bw_data_t instance and set it's values from the - * input parameters. - */ - new_bw_data_p = (sdp_bw_data_t*)SDP_MALLOC(sizeof(sdp_bw_data_t)); - if (new_bw_data_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - new_bw_data_p->next_p = NULL; - new_bw_data_p->bw_modifier = SDP_BW_MODIFIER_UNSUPPORTED; - new_bw_data_p->bw_val = 0; - - /* - * Enqueue the sdp_bw_data_t instance at the end of the list of - * sdp_bw_data_t instances. - */ - if (bw_p->bw_data_list == NULL) { - bw_p->bw_data_list = new_bw_data_p; - } else { - for (bw_data_p = bw_p->bw_data_list; - bw_data_p->next_p != NULL; - bw_data_p = bw_data_p->next_p) { - - /*sa_ignore EMPTYLOOP*/ - ; /* Do nothing. */ - } - - bw_data_p->next_p = new_bw_data_p; - } - *inst_num = ++bw_p->bw_data_count; - - return (SDP_SUCCESS); -} - -/* - * sdp_delete_bw_line - * - * Deletes the bw line instance at the specified level. - * - * sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to delete the bw line. - * inst_num The instance of the bw line to delete. - */ -sdp_result_e sdp_delete_bw_line (void *sdp_ptr, u16 level, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_bw_t *bw_p; - sdp_mca_t *mca_p; - sdp_bw_data_t *bw_data_p = NULL; - sdp_bw_data_t *prev_bw_data_p = NULL; - int bw_data_count = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (level == SDP_SESSION_LEVEL) { - bw_p = &(sdp_p->bw); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - bw_p = &(mca_p->bw); - } - - bw_data_p = bw_p->bw_data_list; - while (bw_data_p != NULL) { - bw_data_count++; - if (bw_data_count == inst_num) { - break; - } - - prev_bw_data_p = bw_data_p; - bw_data_p = bw_data_p->next_p; - } - - if (bw_data_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s bw line instance %d not found.", - sdp_p->debug_str, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (prev_bw_data_p == NULL) { - bw_p->bw_data_list = bw_data_p->next_p; - } else { - prev_bw_data_p->next_p = bw_data_p->next_p; - } - bw_p->bw_data_count--; - - SDP_FREE(bw_data_p); - return (SDP_SUCCESS); -} - -/* - * sdp_set_bw - * - * Once a bandwidth line is added under a level, this function can be used to - * set the properties of that bandwidth line. - * - * Parameters: - * sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to at which the bw line resides. - * inst_num The instance number of the bw line that is to be set. - * bw_modifier The Type of bandwidth, CT, AS or TIAS. - * bw_val Numerical bandwidth value. - * - * NOTE: Before calling this function to set the bw line, the bw line must - * be added using sdp_add_new_bw_line at the required level. - */ -sdp_result_e sdp_set_bw (void *sdp_ptr, u16 level, u16 inst_num, - sdp_bw_modifier_e bw_modifier, u32 bw_val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_bw_data_t *bw_data_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if ((bw_modifier < SDP_BW_MODIFIER_AS) || - (bw_modifier >= SDP_MAX_BW_MODIFIER_VAL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Invalid bw modifier type: %d.", - sdp_p->debug_str, bw_modifier); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num); - if (bw_data_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s The %u instance of a b= line was not found at level %u.", - sdp_p->debug_str, inst_num, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - bw_data_p->bw_modifier = bw_modifier; - bw_data_p->bw_val = bw_val; - - return (SDP_SUCCESS); -} - -/* Function: sdp_get_mid_value - * Description: Returns the mid value parameter from the a= mid: line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level SDP_MEDIA_LEVEL - * Returns: mid value. - */ -int32 sdp_get_mid_value (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } - return (mca_p->mid); -} - -/* Function: sdp_set_mid_value - * Description: Sets the value of the mid value for the - * a= mid: line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level SDP_MEDIA_LEVEL - * mid_val mid value . - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER -*/ -sdp_result_e sdp_set_mid_value (void *sdp_ptr, u16 level, u32 mid_val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - mca_p->mid = mid_val; - return (SDP_SUCCESS); -} diff --git a/libs/sipcc/core/sdp/sdp_attr.c b/libs/sipcc/core/sdp/sdp_attr.c deleted file mode 100644 index 6d794a2427..0000000000 --- a/libs/sipcc/core/sdp/sdp_attr.c +++ /dev/null @@ -1,4755 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include - -#include "plstr.h" -#include "sdp_os_defs.h" -#include "sdp.h" -#include "sdp_private.h" -#include "sdp_base64.h" -//#include "mozilla/Assertions.h" -#include "CSFLog.h" - -//static const char* logTag = "sdp_attr"; - -/* - * Macro for sdp_build_attr_fmtp - * Adds name-value pair where value is char* - */ -#define FMTP_BUILD_STRING(condition, name, value) \ - if ((condition)) { \ - sdp_append_name_and_string(fs, (name), (value), semicolon); \ - semicolon = TRUE; \ - } - -/* - * Macro for sdp_build_attr_fmtp - * Adds name-value pair where value is unsigned - */ -#define FMTP_BUILD_UNSIGNED(condition, name, value) \ - if ((condition)) { \ - sdp_append_name_and_unsigned(fs, (name), (value), semicolon); \ - semicolon = TRUE; \ - } - -/* - * Macro for sdp_build_attr_fmtp - * Adds flag string on condition - */ -#define FMTP_BUILD_FLAG(condition, name) \ - if ((condition)) { \ - if (semicolon) { \ - flex_string_append(fs, ";"); \ - } \ - flex_string_append(fs, name); \ - semicolon = TRUE; \ - } - -/* - * Helper function for adding nv-pair where value is string. - */ -static void sdp_append_name_and_string(flex_string *fs, - const char *name, - const char *value, - tinybool semicolon) -{ - flex_string_sprintf(fs, "%s%s=%s", - semicolon ? ";" : "", - name, - value); -} - -/* - * Helper function for adding nv-pair where value is unsigned. - */ -static void sdp_append_name_and_unsigned(flex_string *fs, - const char *name, - unsigned int value, - tinybool semicolon) -{ - flex_string_sprintf(fs, "%s%s=%u", - semicolon ? ";" : "", - name, - value); -} - -/* Function: sdp_parse_attribute - * Description: Figure out the type of attribute and call the appropriate - * parsing routine. If parsing errors are encountered, - * warnings will be printed and the attribute will be ignored. - * Unrecognized/invalid attributes do not cause overall parsing - * errors. All errors detected are noted as warnings. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * ptr Pointer to the attribute string to parse. - */ -sdp_result_e sdp_parse_attribute (sdp_t *sdp_p, u16 level, const char *ptr) -{ - int i; - u8 xcpar_flag = FALSE; - sdp_result_e result; - sdp_mca_t *mca_p=NULL; - sdp_attr_t *attr_p; - sdp_attr_t *next_attr_p; - sdp_attr_t *prev_attr_p = NULL; - char tmp[SDP_MAX_STRING_LEN]; - - /* Validate the level */ - if (level != SDP_SESSION_LEVEL) { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - } - - /* Find the attribute type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), ": \t", &result); - if (ptr == NULL) { - sdp_parse_error(sdp_p->peerconnection, - "%s No attribute type specified, parse failed.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (ptr[0] == ':') { - /* Skip the ':' char for parsing attribute parameters. */ - ptr++; - } - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No attribute type specified, parse failed.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - attr_p = (sdp_attr_t *)SDP_MALLOC(sizeof(sdp_attr_t)); - if (attr_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - attr_p->type = SDP_ATTR_INVALID; - attr_p->next_p = NULL; - for (i=0; i < SDP_MAX_ATTR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_attr[i].name, sdp_attr[i].strlen) == 0) { - attr_p->type = (sdp_attr_e)i; - break; - } - } - if (attr_p->type == SDP_ATTR_INVALID) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Unrecognized attribute (%s) ", - sdp_p->debug_str, tmp); - sdp_free_attr(attr_p); - return (SDP_SUCCESS); - } - - /* If this is an X-cpar or cpar attribute, set the flag. The attribute - * type will be changed by the parse. */ - if ((attr_p->type == SDP_ATTR_X_CPAR) || - (attr_p->type == SDP_ATTR_CPAR)) { - xcpar_flag = TRUE; - } - - /* Parse the attribute. */ - result = sdp_attr[attr_p->type].parse_func(sdp_p, attr_p, ptr); - if (result != SDP_SUCCESS) { - sdp_free_attr(attr_p); - /* Return success so the parse won't fail. We don't want to - * fail on errors with attributes but just ignore them. - */ - return (SDP_SUCCESS); - } - - /* If this was an X-cpar/cpar attribute, it was hooked into the X-cap/cdsc - * structure, so we're finished. - */ - if (xcpar_flag == TRUE) { - return (result); - } - - /* Add the attribute in the appropriate place. */ - if (level == SDP_SESSION_LEVEL) { - for (next_attr_p = sdp_p->sess_attrs_p; next_attr_p != NULL; - prev_attr_p = next_attr_p, - next_attr_p = next_attr_p->next_p) { - ; /* Empty for */ - } - if (prev_attr_p == NULL) { - sdp_p->sess_attrs_p = attr_p; - } else { - prev_attr_p->next_p = attr_p; - } - } else { - for (next_attr_p = mca_p->media_attrs_p; next_attr_p != NULL; - prev_attr_p = next_attr_p, - next_attr_p = next_attr_p->next_p) { - ; /* Empty for */ - } - if (prev_attr_p == NULL) { - mca_p->media_attrs_p = attr_p; - } else { - prev_attr_p->next_p = attr_p; - } - } - - return (result); -} - -/* Build all of the attributes defined for the specified level. */ -sdp_result_e sdp_build_attribute (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - sdp_attr_t *attr_p; - sdp_mca_t *mca_p=NULL; - sdp_result_e result; - - if (level == SDP_SESSION_LEVEL) { - attr_p = sdp_p->sess_attrs_p; - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - attr_p = mca_p->media_attrs_p; - } - /* Re-initialize the current capability number for this new level. */ - sdp_p->cur_cap_num = 1; - - /* Build all of the attributes for this level. Note that if there - * is a problem building an attribute, we don't fail but just ignore it.*/ - while (attr_p != NULL) { - if (attr_p->type >= SDP_MAX_ATTR_TYPES) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Invalid attribute type to build (%u)", - sdp_p->debug_str, attr_p->type); - } - } else { - result = sdp_attr[attr_p->type].build_func(sdp_p, attr_p, fs); - - if (result != SDP_SUCCESS) { - CSFLogError(logTag, "%s error building attribute %d", __FUNCTION__, result); - return result; - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built a=%s attribute line", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - } - } - attr_p = attr_p->next_p; - } - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_simple_string (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - - ptr = sdp_getnextstrtok(ptr, attr_p->attr.string_val, - sizeof(attr_p->attr.string_val), " \t", &result); - - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No string token found for %s attribute", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.string_val); - } - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_build_attr_simple_string (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s\r\n", sdp_attr[attr_p->type].name, - attr_p->attr.string_val); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_simple_u32 (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - - attr_p->attr.u32_val = sdp_getnextnumtok(ptr, &ptr, " \t", &result); - - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Numeric token for %s attribute not found", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, %lu", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), attr_p->attr.u32_val); - } - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_build_attr_simple_u32 (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%u\r\n", sdp_attr[attr_p->type].name, - attr_p->attr.u32_val); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_simple_bool (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - - if (sdp_getnextnumtok(ptr, &ptr, " \t", &result) == 0) { - attr_p->attr.boolean_val = FALSE; - } else { - attr_p->attr.boolean_val= TRUE; - } - - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Boolean token for %s attribute not found", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - if (attr_p->attr.boolean_val) { - SDP_PRINT("%s Parsed a=%s, boolean is TRUE", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - } else { - SDP_PRINT("%s Parsed a=%s, boolean is FALSE", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - } - } - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_build_attr_simple_bool (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s\r\n", sdp_attr[attr_p->type].name, - attr_p->attr.boolean_val ? "1" : "0"); - - return SDP_SUCCESS; -} - -/* - * sdp_parse_attr_maxprate - * - * This function parses maxprate attribute lines. The ABNF for this a= - * line is: - * max-p-rate-def = "a" "=" "maxprate" ":" packet-rate CRLF - * packet-rate = 1*DIGIT ["." 1*DIGIT] - * - * Returns: - * SDP_INVALID_PARAMETER - If we are unable to parse the string OR if - * packet-rate is not in the right format as per - * the ABNF. - * - * SDP_SUCCESS - If we are able to successfully parse the a= line. - */ -sdp_result_e sdp_parse_attr_maxprate (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - - ptr = sdp_getnextstrtok(ptr, attr_p->attr.string_val, - sizeof(attr_p->attr.string_val), " \t", &result); - - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No string token found for %s attribute", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (!sdp_validate_maxprate(attr_p->attr.string_val)) { - sdp_parse_error(sdp_p->peerconnection, - "%s is not a valid maxprate value.", - attr_p->attr.string_val); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.string_val); - } - return (SDP_SUCCESS); - } -} - -/* - * sdp_attr_fmtp_no_value - * Helper function for sending the warning when a parameter value is - * missing. - * - */ -static void sdp_attr_fmtp_no_value(sdp_t *sdp, char *param_name) -{ - sdp_parse_error(sdp->peerconnection, - "%s Warning: No %s value specified for fmtp attribute", - sdp->debug_str, param_name); - sdp->conf_p->num_invalid_param++; -} - -/* - * sdp_attr_fmtp_invalid_value - * Helper function for sending the warning when a parameter value is - * incorrect. - * - */ - -static void sdp_attr_fmtp_invalid_value(sdp_t *sdp, char *param_name, - char* param_value) -{ - sdp_parse_error(sdp->peerconnection, - "%s Warning: Invalid %s: %s specified for fmtp attribute", - sdp->debug_str, param_name, param_value); - sdp->conf_p->num_invalid_param++; -} - -/* Note: The fmtp attribute formats currently handled are: - * fmtp: ,... - * fmtp: [annexa=yes/no] [annexb=yes/no] [bitrate=] - * [QCIF =] [CIF =] [MaxBR = ] one or more - * Other FMTP params as per H.263, H.263+, H.264 codec support. - * Note -"value" is a numeric value > 0 and each event is a - * single number or a range separated by a '-'. - * Example: fmtp:101 1,3-15,20 - * Video codecs have annexes that can be listed in the following legal formats: - * a) a=fmtp:34 param1=token;D;I;J;K=1;N=2;P=1,3 - * b) a=fmtp:34 param1=token;D;I;J;K=1;N=2;P=1,3;T - * c) a=fmtp:34 param1=token;D;I;J - * - */ - -sdp_result_e sdp_parse_attr_fmtp (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - u16 i; - u32 mapword; - u32 bmap; - u8 low_val; - u8 high_val; - const char *ptr2; - const char *fmtp_ptr; - sdp_result_e result1 = SDP_SUCCESS; - sdp_result_e result2 = SDP_SUCCESS; - tinybool done = FALSE; - tinybool codec_info_found = FALSE; - sdp_fmtp_t *fmtp_p; - char tmp[SDP_MAX_STRING_LEN]; - char *src_ptr; - char *temp_ptr = NULL; - tinybool flag=FALSE; - char *tok=NULL; - char *temp=NULL; - u16 custom_x=0; - u16 custom_y=0; - u16 custom_mpi=0; - u16 par_height=0; - u16 par_width=0; - u16 cpcf=0; - u16 iter=0; - - ulong l_val = 0; - char* strtok_state; - unsigned long strtoul_result; - char* strtoul_end; - - /* Find the payload type number. */ - attr_p->attr.fmtp.payload_num = (u16)sdp_getnextnumtok(ptr, &ptr, - " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "payload type"); - return SDP_INVALID_PARAMETER; - } - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_UNKNOWN_TYPE; - fmtp_p->parameter_add = TRUE; - fmtp_p->flag = 0; - - /* - * set default value of packetization mode and level-asymmetry-allowed. If - * remote sdp does not specify any value for these two parameters, then the - * default value will be assumed for remote sdp. If remote sdp does specify - * any value for these parameters, then default value will be overridden. - */ - fmtp_p->packetization_mode = 0; - fmtp_p->level_asymmetry_allowed = SDP_DEFAULT_LEVEL_ASYMMETRY_ALLOWED_VALUE; - - /* BEGIN - a typical macro fn to replace '/' with ';' from fmtp line*/ - /* This ugly replacement of '/' with ';' is only done because - * econf/MS client sends in this wierd /illegal format. - * fmtp parameters MUST be separated by ';' - */ - temp_ptr = cpr_strdup(ptr); - if (temp_ptr == NULL) { - return (SDP_FAILURE); - } - fmtp_ptr = src_ptr = temp_ptr; - while (flag == FALSE) { - if (*src_ptr == '\n') { - flag = TRUE; - break; - } - if (*src_ptr == '/') { - *src_ptr =';' ; - } - src_ptr++; - } - /* END */ - /* Once we move to RFC compliant video codec implementations, the above - * patch should be removed */ - while (!done) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "= \t", &result1); - if (result1 == SDP_SUCCESS) { - if (cpr_strncasecmp(tmp, sdp_fmtp_codec_param[1].name, - sdp_fmtp_codec_param[1].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "annexb"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - if (cpr_strncasecmp(tok,sdp_fmtp_codec_param_val[0].name, - sdp_fmtp_codec_param_val[0].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annexb_required = TRUE; - fmtp_p->annexb = TRUE; - } else if (cpr_strncasecmp(tok,sdp_fmtp_codec_param_val[1].name, - sdp_fmtp_codec_param_val[1].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annexb_required = TRUE; - fmtp_p->annexb = FALSE; - } else { - sdp_attr_fmtp_invalid_value(sdp_p, "annexb", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp, sdp_fmtp_codec_param[0].name, - sdp_fmtp_codec_param[0].strlen) == 0) { - - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "annexa"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - if (cpr_strncasecmp(tok,sdp_fmtp_codec_param_val[0].name, - sdp_fmtp_codec_param_val[0].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annexa = TRUE; - fmtp_p->annexa_required = TRUE; - } else if (cpr_strncasecmp(tok,sdp_fmtp_codec_param_val[1].name, - sdp_fmtp_codec_param_val[1].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annexa = FALSE; - fmtp_p->annexa_required = TRUE; - } else { - sdp_attr_fmtp_invalid_value(sdp_p, "annexa", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[2].name, - sdp_fmtp_codec_param[2].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "bitrate"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > UINT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "bitrate", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->bitrate = (u32) strtoul_result; - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[41].name, - sdp_fmtp_codec_param[41].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "mode"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result > UINT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "mode", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_MODE; - fmtp_p->mode = (u32) strtoul_result; - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[3].name, - sdp_fmtp_codec_param[3].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "qcif"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || - strtoul_result < SDP_MIN_CIF_VALUE || strtoul_result > SDP_MAX_CIF_VALUE) { - sdp_attr_fmtp_invalid_value(sdp_p, "qcif", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->qcif = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[4].name, - sdp_fmtp_codec_param[4].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "cif"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || - strtoul_result < SDP_MIN_CIF_VALUE || strtoul_result > SDP_MAX_CIF_VALUE) { - sdp_attr_fmtp_invalid_value(sdp_p, "cif", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->cif = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[5].name, - sdp_fmtp_codec_param[5].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "maxbr"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || - strtoul_result == 0 || strtoul_result > USHRT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "maxbr", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->maxbr = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[6].name, - sdp_fmtp_codec_param[6].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "sqcif"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || - strtoul_result < SDP_MIN_CIF_VALUE || strtoul_result > SDP_MAX_CIF_VALUE) { - sdp_attr_fmtp_invalid_value(sdp_p, "sqcif", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->sqcif = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[7].name, - sdp_fmtp_codec_param[7].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "cif4"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || - strtoul_result < SDP_MIN_CIF_VALUE || strtoul_result > SDP_MAX_CIF_VALUE) { - sdp_attr_fmtp_invalid_value(sdp_p, "cif4", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->cif4 = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[8].name, - sdp_fmtp_codec_param[8].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "cif16"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || - strtoul_result < SDP_MIN_CIF_VALUE || strtoul_result > SDP_MAX_CIF_VALUE) { - sdp_attr_fmtp_invalid_value(sdp_p, "cif16", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->cif16 = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[9].name, - sdp_fmtp_codec_param[9].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "custom"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; temp=PL_strtok_r(tok, ",", &strtok_state); - iter++; - if (temp) { - iter=1; - while (temp != NULL) { - errno = 0; - strtoul_result = strtoul(temp, &strtoul_end, 10); - - if (errno || temp == strtoul_end || strtoul_result > USHRT_MAX){ - custom_x = custom_y = custom_mpi = 0; - break; - } - - if (iter == 1) - custom_x = (u16) strtoul_result; - if (iter == 2) - custom_y = (u16) strtoul_result; - if (iter == 3) - custom_mpi = (u16) strtoul_result; - - temp=PL_strtok_r(NULL, ",", &strtok_state); - iter++; - } - } - - /* custom x,y and mpi values from tmp */ - if (!custom_x || !custom_y || !custom_mpi) { - sdp_attr_fmtp_invalid_value(sdp_p, "x/y/MPI", temp); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->custom_x = custom_x; - fmtp_p->custom_y = custom_y; - fmtp_p->custom_mpi = custom_mpi; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[10].name, - sdp_fmtp_codec_param[10].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "par"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; temp=PL_strtok_r(tok, ":", &strtok_state); - if (temp) { - iter=1; - /* get par width and par height for the aspect ratio */ - while (temp != NULL) { - errno = 0; - strtoul_result = strtoul(temp, &strtoul_end, 10); - - if (errno || temp == strtoul_end || strtoul_result > USHRT_MAX) { - par_width = par_height = 0; - break; - } - - if (iter == 1) - par_width = (u16) strtoul_result; - else - par_height = (u16) strtoul_result; - - temp=PL_strtok_r(NULL, ",", &strtok_state); - iter++; - } - } - if (!par_width || !par_height) { - sdp_attr_fmtp_invalid_value(sdp_p, "par_width or par_height", temp); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->par_width = par_width; - fmtp_p->par_height = par_height; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[11].name, - sdp_fmtp_codec_param[11].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "cpcf"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; temp=PL_strtok_r(tok, ".", &strtok_state); - if ( temp != NULL ) { - errno = 0; - strtoul_result = strtoul(temp, &strtoul_end, 10); - - if (errno || temp == strtoul_end || strtoul_result > USHRT_MAX) { - cpcf = 0; - } else { - cpcf = (u16) strtoul_result; - } - } - - if (!cpcf) { - sdp_attr_fmtp_invalid_value(sdp_p, "cpcf", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->cpcf = cpcf; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[12].name, - sdp_fmtp_codec_param[12].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "bpp"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > USHRT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "bpp", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->bpp = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[13].name, - sdp_fmtp_codec_param[13].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "hrd"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > USHRT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "hrd", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->hrd = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[14].name, - sdp_fmtp_codec_param[14].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "profile"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || - strtoul_result > SDP_MAX_PROFILE_VALUE) { - sdp_attr_fmtp_invalid_value(sdp_p, "profile", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->profile = (short) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[15].name, - sdp_fmtp_codec_param[15].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "level"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || - strtoul_result > SDP_MAX_LEVEL_VALUE) { - sdp_attr_fmtp_invalid_value(sdp_p, "level", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->level = (short) strtoul_result; - codec_info_found = TRUE; - } if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[16].name, - sdp_fmtp_codec_param[16].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->is_interlace = TRUE; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[17].name, - sdp_fmtp_codec_param[17].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "profile_level_id"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - sstrncpy(fmtp_p->profile_level_id , tok, sizeof(fmtp_p->profile_level_id)); - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[18].name, - sdp_fmtp_codec_param[18].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "parameter_sets"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - sstrncpy(fmtp_p->parameter_sets , tok, sizeof(fmtp_p->parameter_sets)); - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[19].name, - sdp_fmtp_codec_param[19].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "packetization_mode"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result > 2) { - sdp_attr_fmtp_invalid_value(sdp_p, "packetization_mode", tok); - sdp_p->conf_p->num_invalid_param++; - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->packetization_mode = (int16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[20].name, - sdp_fmtp_codec_param[20].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "interleaving_depth"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > USHRT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "interleaving_depth", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->interleaving_depth = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[21].name, - sdp_fmtp_codec_param[21].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "deint_buf"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - if (sdp_checkrange(sdp_p, tok, &l_val) == TRUE) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->deint_buf_req = (u32) l_val; - fmtp_p->flag |= SDP_DEINT_BUF_REQ_FLAG; - codec_info_found = TRUE; - } else { - sdp_attr_fmtp_invalid_value(sdp_p, "deint_buf_req", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[22].name, - sdp_fmtp_codec_param[22].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "max_don_diff"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > UINT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "max_don_diff", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->max_don_diff = (u32) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[23].name, - sdp_fmtp_codec_param[23].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "init_buf_time"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - if (sdp_checkrange(sdp_p, tok, &l_val) == TRUE) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->init_buf_time = (u32) l_val; - fmtp_p->flag |= SDP_INIT_BUF_TIME_FLAG; - codec_info_found = TRUE; - } else { - sdp_attr_fmtp_invalid_value(sdp_p, "init_buf_time", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[24].name, - sdp_fmtp_codec_param[24].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "max_mbps"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > UINT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "max_mbps", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->max_mbps = (u32) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[25].name, - sdp_fmtp_codec_param[25].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "max_fs"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > UINT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "max_fs", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->max_fs = (u32) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[26].name, - sdp_fmtp_codec_param[26].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "max_cbp"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > UINT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "max_cpb", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->max_cpb = (u32) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[27].name, - sdp_fmtp_codec_param[27].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "max_dpb"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > UINT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "max_dpb", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->max_dpb = (u32) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[28].name, - sdp_fmtp_codec_param[28].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "max_br"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > UINT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "max_br", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->max_br = (u32) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[29].name, - sdp_fmtp_codec_param[29].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "redundant_pic_cap"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (!errno && tok != strtoul_end && strtoul_result == 1) { - fmtp_p->redundant_pic_cap = TRUE; - } else { - fmtp_p->redundant_pic_cap = FALSE; - } - - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[30].name, - sdp_fmtp_codec_param[30].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "deint_buf_cap"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - if (sdp_checkrange(sdp_p, tok, &l_val) == TRUE) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->deint_buf_cap = (u32) l_val; - fmtp_p->flag |= SDP_DEINT_BUF_CAP_FLAG; - codec_info_found = TRUE; - } else { - sdp_attr_fmtp_invalid_value(sdp_p, "deint_buf_cap", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[31].name, - sdp_fmtp_codec_param[31].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "max_rcmd_nalu_size"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - if (sdp_checkrange(sdp_p, tok, &l_val) == TRUE) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->max_rcmd_nalu_size = (u32) l_val; - fmtp_p->flag |= SDP_MAX_RCMD_NALU_SIZE_FLAG; - codec_info_found = TRUE; - } else { - sdp_attr_fmtp_invalid_value(sdp_p, "max_rcmd_nalu_size", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[32].name, - sdp_fmtp_codec_param[32].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "parameter_add"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result > 1) { - sdp_attr_fmtp_invalid_value(sdp_p, "parameter_add", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (strtoul_result == 1) { - fmtp_p->parameter_add = TRUE; - } else { - fmtp_p->parameter_add = FALSE; - } - - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[33].name, - sdp_fmtp_codec_param[33].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annex_d = TRUE; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[34].name, - sdp_fmtp_codec_param[34].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annex_f = TRUE; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[35].name, - sdp_fmtp_codec_param[35].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annex_i = TRUE; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[36].name, - sdp_fmtp_codec_param[36].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annex_j = TRUE; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[37].name, - sdp_fmtp_codec_param[36].strlen) == 0) { - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annex_t = TRUE; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[38].name, - sdp_fmtp_codec_param[38].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "annex_k"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > USHRT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "annex_k", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annex_k_val = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[39].name, - sdp_fmtp_codec_param[39].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "annex_n"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > USHRT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "annex_n", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annex_n_val = (u16) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[40].name, - sdp_fmtp_codec_param[40].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "annex_p"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - fmtp_p->annex_p_val_picture_resize = 0; - fmtp_p->annex_p_val_warp = 0; - tok = tmp; - tok++; temp=PL_strtok_r(tok, ",", &strtok_state); - if (temp) { - iter=1; - while (temp != NULL) { - errno = 0; - strtoul_result = strtoul(temp, &strtoul_end, 10); - - if (errno || temp == strtoul_end || strtoul_result > USHRT_MAX) { - break; - } - - if (iter == 1) - fmtp_p->annex_p_val_picture_resize = (u16) strtoul_result; - else if (iter == 2) - fmtp_p->annex_p_val_warp = (u16) strtoul_result; - - temp=PL_strtok_r(NULL, ",", &strtok_state); - iter++; - } - } - - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[42].name, - sdp_fmtp_codec_param[42].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "level_asymmetry_allowed"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result > SDP_MAX_LEVEL_ASYMMETRY_ALLOWED_VALUE) { - sdp_attr_fmtp_invalid_value(sdp_p, "level_asymmetry_allowed", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->level_asymmetry_allowed = (int) strtoul_result; - codec_info_found = TRUE; - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[43].name, - sdp_fmtp_codec_param[43].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "maxaveragebitrate"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result == 0 || strtoul_result > UINT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "maxaveragebitrate", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->maxaveragebitrate = (u32) strtoul_result; - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[44].name, - sdp_fmtp_codec_param[44].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "usedtx"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - errno = 0; - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result > 1) { - sdp_attr_fmtp_invalid_value(sdp_p, "usedtx", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->usedtx = (u16) strtoul_result; - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[45].name, - sdp_fmtp_codec_param[45].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "stereo"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - errno = 0; - - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result > 1) { - sdp_attr_fmtp_invalid_value(sdp_p, "stereo", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->stereo = (u16) strtoul_result; - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[46].name, - sdp_fmtp_codec_param[46].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "useinbandfec"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - errno = 0; - - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result > 1) { - sdp_attr_fmtp_invalid_value(sdp_p, "useinbandfec", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->useinbandfec = (u16) strtoul_result; - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[47].name, - sdp_fmtp_codec_param[47].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "maxcodedaudiobandwidth"); - sdp_p->conf_p->num_invalid_param++; - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - sstrncpy(fmtp_p->maxcodedaudiobandwidth , tok, sizeof(fmtp_p->maxcodedaudiobandwidth)); - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[48].name, - sdp_fmtp_codec_param[48].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "cbr"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - errno = 0; - - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result > 1) { - sdp_attr_fmtp_invalid_value(sdp_p, "cbr", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->cbr = (u16) strtoul_result; - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[49].name, - sdp_fmtp_codec_param[49].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "streams"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - errno = 0; - - strtoul_result = strtoul(tok, &strtoul_end, 10); - - if (errno || tok == strtoul_end || strtoul_result > INT_MAX) { - sdp_attr_fmtp_invalid_value(sdp_p, "streams", tok); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - - fmtp_p->fmtp_format = SDP_FMTP_DATACHANNEL; - fmtp_p->streams = (int) strtoul_result; - codec_info_found = TRUE; - - } else if (cpr_strncasecmp(tmp,sdp_fmtp_codec_param[50].name, - sdp_fmtp_codec_param[50].strlen) == 0) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), "; \t", &result1); - if (result1 != SDP_SUCCESS) { - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), " \t", &result1); - if (result1 != SDP_SUCCESS) { - sdp_attr_fmtp_no_value(sdp_p, "protocol"); - SDP_FREE(temp_ptr); - return SDP_INVALID_PARAMETER; - } - } - tok = tmp; - tok++; - fmtp_p->fmtp_format = SDP_FMTP_DATACHANNEL; - sstrncpy(fmtp_p->protocol , tok, sizeof(fmtp_p->protocol)); - codec_info_found = TRUE; - - } else if (fmtp_ptr != NULL && *fmtp_ptr == '\n') { - temp=PL_strtok_r(tmp, ";", &strtok_state); - if (temp) { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Annexes are possibly there for this fmtp %s tmp: %s line\n", - sdp_p->debug_str, fmtp_ptr, tmp); - } - while (temp != NULL) { - if (strchr(temp, 'D') !=NULL) { - attr_p->attr.fmtp.annex_d = TRUE; - } - if (strchr(temp, 'F') !=NULL) { - attr_p->attr.fmtp.annex_f = TRUE; - } - if (strchr(temp, 'I') !=NULL) { - attr_p->attr.fmtp.annex_i = TRUE; - } - if (strchr(temp, 'J') !=NULL) { - attr_p->attr.fmtp.annex_j = TRUE; - } - if (strchr(temp, 'T') !=NULL) { - attr_p->attr.fmtp.annex_t = TRUE; - } - temp=PL_strtok_r(NULL, ";", &strtok_state); - } - } /* if (temp) */ - done = TRUE; - } - fmtp_ptr++; - } else { - done = TRUE; - } - } /* while - done loop*/ - - if (codec_info_found) { - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, payload type %u, bitrate %lu, mode %u QCIF = %u, CIF = %u, MAXBR= %u, SQCIF=%u, CIF4= %u, CIF16=%u, CUSTOM=%u,%u,%u , PAR=%u:%u,CPCF=%u, BPP=%u, HRD=%u \n", - sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.fmtp.payload_num, - attr_p->attr.fmtp.bitrate, - attr_p->attr.fmtp.mode, - attr_p->attr.fmtp.qcif, - attr_p->attr.fmtp.cif, - attr_p->attr.fmtp.maxbr, - attr_p->attr.fmtp.sqcif, - attr_p->attr.fmtp.cif4, - attr_p->attr.fmtp.cif16, - attr_p->attr.fmtp.custom_x,attr_p->attr.fmtp.custom_y, - attr_p->attr.fmtp.custom_mpi, - attr_p->attr.fmtp.par_width, - attr_p->attr.fmtp.par_height, - attr_p->attr.fmtp.cpcf, - attr_p->attr.fmtp.bpp, - attr_p->attr.fmtp.hrd - ); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, payload type %u,PROFILE=%u,LEVEL=%u, INTERLACE - %s", - sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.fmtp.payload_num, - attr_p->attr.fmtp.profile, - attr_p->attr.fmtp.level, - attr_p->attr.fmtp.is_interlace ? "YES":"NO"); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed H.264 attributes: profile-level-id=%s, parameter-sets=%s, packetization-mode=%d level-asymmetry-allowed=%d interleaving-depth=%d deint-buf-req=%lu max-don-diff=%lu, init_buf-time=%lu\n", - sdp_p->debug_str, - attr_p->attr.fmtp.profile_level_id, - attr_p->attr.fmtp.parameter_sets, - attr_p->attr.fmtp.packetization_mode, - attr_p->attr.fmtp.level_asymmetry_allowed, - attr_p->attr.fmtp.interleaving_depth, - attr_p->attr.fmtp.deint_buf_req, - attr_p->attr.fmtp.max_don_diff, - attr_p->attr.fmtp.init_buf_time - ); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("\n%s Parsed H.264 opt attributes: max-mbps=%lu, max-fs=%lu, max-cpb=%lu max-dpb=%lu max-br=%lu redundant-pic-cap=%d, deint-buf-cap=%lu, max-rcmd-nalu-size=%lu , parameter-add=%d\n", - sdp_p->debug_str, - attr_p->attr.fmtp.max_mbps, - attr_p->attr.fmtp.max_fs, - attr_p->attr.fmtp.max_cpb, - attr_p->attr.fmtp.max_dpb, - attr_p->attr.fmtp.max_br, - attr_p->attr.fmtp.redundant_pic_cap, - attr_p->attr.fmtp.deint_buf_cap, - attr_p->attr.fmtp.max_rcmd_nalu_size, - attr_p->attr.fmtp.parameter_add); - - } - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed annexes are : D=%d F=%d I=%d J=%d T=%d, K=%d N=%d P=%d,%d\n", - sdp_p->debug_str, - attr_p->attr.fmtp.annex_d, - attr_p->attr.fmtp.annex_f, attr_p->attr.fmtp.annex_i, - attr_p->attr.fmtp.annex_j, attr_p->attr.fmtp.annex_t, - attr_p->attr.fmtp.annex_k_val, - attr_p->attr.fmtp.annex_n_val, - attr_p->attr.fmtp.annex_p_val_picture_resize, - attr_p->attr.fmtp.annex_p_val_warp); - - } - SDP_FREE(temp_ptr); - return (SDP_SUCCESS); - } else { - done = FALSE; - fmtp_ptr = src_ptr; - tmp[0] = '\0'; - } - - for (i=0; !done; i++) { - fmtp_p->fmtp_format = SDP_FMTP_NTE; - /* Look for comma separated events */ - fmtp_ptr = sdp_getnextstrtok(fmtp_ptr, tmp, sizeof(tmp), ", \t", &result1); - if (result1 != SDP_SUCCESS) { - done = TRUE; - continue; - } - /* Now look for '-' separated range */ - ptr2 = tmp; - low_val = (u8)sdp_getnextnumtok(ptr2, (const char **)&ptr2, - "- \t", &result1); - if (*ptr2 == '-') { - high_val = (u8)sdp_getnextnumtok(ptr2, (const char **)&ptr2, - "- \t", &result2); - } else { - high_val = low_val; - } - - if ((result1 != SDP_SUCCESS) || (result2 != SDP_SUCCESS)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid named events specified for fmtp attribute.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - SDP_FREE(temp_ptr); - return (SDP_INVALID_PARAMETER); - } - - for (i = low_val; i <= high_val; i++) { - mapword = i/SDP_NE_BITS_PER_WORD; - bmap = SDP_NE_BIT_0 << (i%32); - fmtp_p->bmap[mapword] |= bmap; - } - if (high_val > fmtp_p->maxval) { - fmtp_p->maxval = high_val; - } - } - - if (fmtp_p->maxval == 0) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No named events specified for fmtp attribute.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - SDP_FREE(temp_ptr); - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, payload type %u, ", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.fmtp.payload_num); - } - SDP_FREE(temp_ptr); - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_fmtp (sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs) -{ - u16 event_id; - u32 mask; - u32 mapword; - u8 min = 0; - u8 max = 0; - tinybool range_start = FALSE; - tinybool range_end = FALSE; - tinybool semicolon = FALSE; - sdp_fmtp_t *fmtp_p; - - flex_string_sprintf(fs, "a=%s:%u ", - sdp_attr[attr_p->type].name, - attr_p->attr.fmtp.payload_num); - - fmtp_p = &(attr_p->attr.fmtp); - switch (fmtp_p->fmtp_format) { - case SDP_FMTP_MODE: - sdp_append_name_and_unsigned(fs, "mode", fmtp_p->mode, FALSE); - break; - - case SDP_FMTP_CODEC_INFO: - FMTP_BUILD_UNSIGNED(fmtp_p->bitrate > 0, "bitrate", fmtp_p->bitrate) - - FMTP_BUILD_STRING(fmtp_p->annexa_required, - "annexa", (fmtp_p->annexa ? "yes" : "no")) - - FMTP_BUILD_STRING(fmtp_p->annexb_required, - "annexb", (fmtp_p->annexa ? "yes" : "no")) - - FMTP_BUILD_UNSIGNED(fmtp_p->qcif > 0, "QCIF", fmtp_p->qcif) - - FMTP_BUILD_UNSIGNED(fmtp_p->cif > 0, "CIF", fmtp_p->cif) - - FMTP_BUILD_UNSIGNED(fmtp_p->maxbr > 0, "MAXBR", fmtp_p->maxbr) - - FMTP_BUILD_UNSIGNED(fmtp_p->sqcif > 0, "SQCIF", fmtp_p->sqcif) - - FMTP_BUILD_UNSIGNED(fmtp_p->cif4 > 0, "CIF4", fmtp_p->cif4) - - FMTP_BUILD_UNSIGNED(fmtp_p->cif16 > 0, "CIF16", fmtp_p->cif16) - - if ((fmtp_p->custom_x > 0) && (fmtp_p->custom_y > 0) && - (fmtp_p->custom_mpi > 0)) { - flex_string_sprintf(fs, "%sCUSTOM=%u,%u,%u", - semicolon ? ";" : "", - fmtp_p->custom_x, - fmtp_p->custom_y, - fmtp_p->custom_mpi); - - semicolon = TRUE; - } - - if ((fmtp_p->par_height > 0) && (fmtp_p->par_width > 0)) { - flex_string_sprintf(fs, "%sPAR=%u:%u", - semicolon ? ";" : "", - fmtp_p->par_width, - fmtp_p->par_width); - - semicolon = TRUE; - } - - FMTP_BUILD_UNSIGNED(fmtp_p->cpcf > 0, "CPCF", fmtp_p->cpcf) - - FMTP_BUILD_UNSIGNED(fmtp_p->bpp > 0, "BPP", fmtp_p->bpp) - - FMTP_BUILD_UNSIGNED(fmtp_p->hrd > 0, "HRD", fmtp_p->hrd) - - FMTP_BUILD_UNSIGNED(fmtp_p->profile >= 0, "PROFILE", fmtp_p->profile) - - FMTP_BUILD_UNSIGNED(fmtp_p->level >= 0, "LEVEL", fmtp_p->level) - - FMTP_BUILD_FLAG(fmtp_p->is_interlace, "INTERLACE") - - FMTP_BUILD_FLAG(fmtp_p->annex_d, "D") - - FMTP_BUILD_FLAG(fmtp_p->annex_f, "F") - - FMTP_BUILD_FLAG(fmtp_p->annex_i, "I") - - FMTP_BUILD_FLAG(fmtp_p->annex_j, "J") - - FMTP_BUILD_FLAG(fmtp_p->annex_t, "T") - - FMTP_BUILD_UNSIGNED(fmtp_p->annex_k_val > 0, - "K", fmtp_p->annex_k_val) - - FMTP_BUILD_UNSIGNED(fmtp_p->annex_n_val > 0, - "N", fmtp_p->annex_n_val) - - if ((fmtp_p->annex_p_val_picture_resize > 0) && - (fmtp_p->annex_p_val_warp > 0)) { - flex_string_sprintf(fs, "%sP=%d:%d", - semicolon ? ";" : "", - fmtp_p->annex_p_val_picture_resize, - fmtp_p->annex_p_val_warp); - - semicolon = TRUE; - } - - FMTP_BUILD_STRING(strlen(fmtp_p->profile_level_id) > 0, - "profile-level-id", fmtp_p->profile_level_id) - - FMTP_BUILD_STRING(strlen(fmtp_p->parameter_sets) > 0, - "sprop-parameter-sets", fmtp_p->parameter_sets) - - FMTP_BUILD_UNSIGNED( - fmtp_p->packetization_mode < SDP_MAX_PACKETIZATION_MODE_VALUE, - "packetization-mode", fmtp_p->packetization_mode) - - FMTP_BUILD_UNSIGNED( - fmtp_p->level_asymmetry_allowed <= - SDP_MAX_LEVEL_ASYMMETRY_ALLOWED_VALUE, - "level-asymmetry-allowed", fmtp_p->level_asymmetry_allowed) - - FMTP_BUILD_UNSIGNED(fmtp_p->interleaving_depth > 0, - "sprop-interleaving-depth", fmtp_p->interleaving_depth) - - FMTP_BUILD_UNSIGNED(fmtp_p->flag & SDP_DEINT_BUF_REQ_FLAG, - "sprop-deint-buf-req", fmtp_p->deint_buf_req) - - FMTP_BUILD_UNSIGNED(fmtp_p->max_don_diff > 0, - "sprop-max-don-diff", fmtp_p->max_don_diff) - - FMTP_BUILD_UNSIGNED(fmtp_p->flag & SDP_INIT_BUF_TIME_FLAG, - "sprop-init-buf-time", fmtp_p->init_buf_time) - - FMTP_BUILD_UNSIGNED(fmtp_p->max_mbps > 0, - "max-mbps", fmtp_p->max_mbps) - - FMTP_BUILD_UNSIGNED(fmtp_p->max_fs > 0, "max-fs", fmtp_p->max_fs) - - FMTP_BUILD_UNSIGNED(fmtp_p->max_cpb > 0, "max-cpb", fmtp_p->max_cpb) - - FMTP_BUILD_UNSIGNED(fmtp_p->max_dpb > 0, "max-dpb", fmtp_p->max_dpb) - - FMTP_BUILD_UNSIGNED(fmtp_p->max_br > 0, "max-br", fmtp_p->max_br) - - FMTP_BUILD_UNSIGNED(fmtp_p->redundant_pic_cap > 0, - "redundant-pic-cap", fmtp_p->redundant_pic_cap) - - FMTP_BUILD_UNSIGNED(fmtp_p->flag & SDP_DEINT_BUF_CAP_FLAG, - "deint-buf-cap", fmtp_p->deint_buf_cap) - - FMTP_BUILD_UNSIGNED(fmtp_p->flag & SDP_MAX_RCMD_NALU_SIZE_FLAG, - "max-rcmd-naFMTP_BUILD_FLlu-size", fmtp_p->max_rcmd_nalu_size) - - FMTP_BUILD_UNSIGNED(fmtp_p->parameter_add > 0, - "parameter-add", fmtp_p->parameter_add) - - FMTP_BUILD_UNSIGNED(fmtp_p->maxaveragebitrate > 0, - "maxaveragebitrate", fmtp_p->maxaveragebitrate) - - FMTP_BUILD_UNSIGNED(fmtp_p->usedtx <= 1, "usedtx", fmtp_p->usedtx) - - FMTP_BUILD_UNSIGNED(fmtp_p->stereo <= 1, "stereo", fmtp_p->stereo) - - FMTP_BUILD_UNSIGNED(fmtp_p->useinbandfec <= 1, - "useinbandfec", fmtp_p->useinbandfec) - - FMTP_BUILD_STRING(strlen(fmtp_p->maxcodedaudiobandwidth) > 0, - "maxcodedaudiobandwidth", fmtp_p->maxcodedaudiobandwidth) - - FMTP_BUILD_UNSIGNED(fmtp_p->cbr <= 1, "cbr", fmtp_p->cbr) - - break; - - case SDP_FMTP_DATACHANNEL: - FMTP_BUILD_STRING(strlen(fmtp_p->protocol) > 0, - "protocol", fmtp_p->protocol) - - FMTP_BUILD_UNSIGNED(fmtp_p->streams > 0, "streams", fmtp_p->streams) - - break; - - case SDP_FMTP_NTE: - default: - break; - } - - for(event_id = 0, mapword = 0, mask = SDP_NE_BIT_0; - event_id <= fmtp_p->maxval; - event_id++, mapword = event_id/SDP_NE_BITS_PER_WORD ) { - - if (event_id % SDP_NE_BITS_PER_WORD) { - mask <<= 1; - } else { - /* crossed a bitmap word boundary */ - mask = SDP_NE_BIT_0; - if (!range_start && !range_end && !fmtp_p->bmap[mapword]) { - /* no events in this word, skip to the last event id - * in this bitmap word. */ - event_id += SDP_NE_BITS_PER_WORD - 1; - continue; - } - } - - if (fmtp_p->bmap[mapword] & mask) { - if (!range_start) { - range_start = TRUE; - min = max = (u8)event_id; - } else { - max = (u8)event_id; - } - range_end = (max == fmtp_p->maxval); - } else { - /* If we were in the middle of a range, then we've hit the - * end. If we weren't, there is no end to hit. */ - range_end = range_start; - } - - /* If this is the end of the range, print it to the string. */ - if (range_end) { - range_start = range_end = FALSE; - - flex_string_sprintf(fs, "%u", min); - - if (min != max) { - flex_string_sprintf(fs, "-%u", max); - } - - if (max != fmtp_p->maxval) { - flex_string_append(fs, ","); - } - } - } - - flex_string_append(fs, "\r\n"); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_direction (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - /* No parameters to parse. */ - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_direction (sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s\r\n", sdp_get_attr_name(attr_p->type)); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_qos (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - /* Find the strength tag. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No qos strength tag specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.qos.strength = SDP_QOS_STRENGTH_UNKNOWN; - for (i=0; i < SDP_MAX_QOS_STRENGTH; i++) { - if (cpr_strncasecmp(tmp, sdp_qos_strength[i].name, - sdp_qos_strength[i].strlen) == 0) { - attr_p->attr.qos.strength = (sdp_qos_strength_e)i; - } - } - if (attr_p->attr.qos.strength == SDP_QOS_STRENGTH_UNKNOWN) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: QOS strength tag unrecognized (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the qos direction. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No qos direction specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.qos.direction = SDP_QOS_DIR_UNKNOWN; - for (i=0; i < SDP_MAX_QOS_DIR; i++) { - if (cpr_strncasecmp(tmp, sdp_qos_direction[i].name, - sdp_qos_direction[i].strlen) == 0) { - attr_p->attr.qos.direction = (sdp_qos_dir_e)i; - } - } - if (attr_p->attr.qos.direction == SDP_QOS_DIR_UNKNOWN) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: QOS direction unrecognized (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* See if confirm was specified. Defaults to FALSE. */ - attr_p->attr.qos.confirm = FALSE; - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result == SDP_SUCCESS) { - if (cpr_strncasecmp(tmp, "confirm", sizeof("confirm")) == 0) { - attr_p->attr.qos.confirm = TRUE; - } - if (attr_p->attr.qos.confirm == FALSE) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: QOS confirm parameter invalid (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, strength %s, direction %s, confirm %s", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type), - sdp_get_qos_strength_name(attr_p->attr.qos.strength), - sdp_get_qos_direction_name(attr_p->attr.qos.direction), - (attr_p->attr.qos.confirm ? "set" : "not set")); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_qos (sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s %s%s\r\n", sdp_attr[attr_p->type].name, - sdp_get_qos_strength_name(attr_p->attr.qos.strength), - sdp_get_qos_direction_name(attr_p->attr.qos.direction), - attr_p->attr.qos.confirm ? " confirm" : ""); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_curr (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - /* Find the curr type tag. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No curr attr type specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.curr.type = SDP_CURR_UNKNOWN_TYPE; - for (i=0; i < SDP_MAX_CURR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_curr_type[i].name, - sdp_curr_type[i].strlen) == 0) { - attr_p->attr.curr.type = (sdp_curr_type_e)i; - } - } - - if (attr_p->attr.curr.type != SDP_CURR_QOS_TYPE) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Unknown curr type.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Check qos status type */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No curr attr type specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.curr.status_type = SDP_QOS_STATUS_TYPE_UNKNOWN; - for (i=0; i < SDP_MAX_QOS_STATUS_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_qos_status_type[i].name, - sdp_qos_status_type[i].strlen) == 0) { - attr_p->attr.curr.status_type = (sdp_qos_status_types_e)i; - } - } - - - /* Find the qos direction. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No qos direction specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.curr.direction = SDP_QOS_DIR_UNKNOWN; - for (i=0; i < SDP_MAX_QOS_DIR; i++) { - if (cpr_strncasecmp(tmp, sdp_qos_direction[i].name, - sdp_qos_direction[i].strlen) == 0) { - attr_p->attr.curr.direction = (sdp_qos_dir_e)i; - } - } - if (attr_p->attr.curr.direction == SDP_QOS_DIR_UNKNOWN) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: QOS direction unrecognized (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, type %s status type %s, direction %s", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type), - sdp_get_curr_type_name(attr_p->attr.curr.type), - sdp_get_qos_status_type_name(attr_p->attr.curr.status_type), - sdp_get_qos_direction_name(attr_p->attr.curr.direction)); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_curr (sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s %s %s\r\n", - sdp_attr[attr_p->type].name, - sdp_get_curr_type_name(attr_p->attr.curr.type), - sdp_get_qos_status_type_name(attr_p->attr.curr.status_type), - sdp_get_qos_direction_name(attr_p->attr.curr.direction)); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_des (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - /* Find the curr type tag. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No des attr type specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.des.type = SDP_DES_UNKNOWN_TYPE; - for (i=0; i < SDP_MAX_CURR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_des_type[i].name, - sdp_des_type[i].strlen) == 0) { - attr_p->attr.des.type = (sdp_des_type_e)i; - } - } - - if (attr_p->attr.des.type != SDP_DES_QOS_TYPE) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Unknown conf type.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the strength tag. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No qos strength tag specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.des.strength = SDP_QOS_STRENGTH_UNKNOWN; - for (i=0; i < SDP_MAX_QOS_STRENGTH; i++) { - if (cpr_strncasecmp(tmp, sdp_qos_strength[i].name, - sdp_qos_strength[i].strlen) == 0) { - attr_p->attr.des.strength = (sdp_qos_strength_e)i; - } - } - if (attr_p->attr.des.strength == SDP_QOS_STRENGTH_UNKNOWN) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: QOS strength tag unrecognized (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Check qos status type */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No des attr type specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.des.status_type = SDP_QOS_STATUS_TYPE_UNKNOWN; - for (i=0; i < SDP_MAX_QOS_STATUS_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_qos_status_type[i].name, - sdp_qos_status_type[i].strlen) == 0) { - attr_p->attr.des.status_type = (sdp_qos_status_types_e)i; - } - } - - - /* Find the qos direction. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No qos direction specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.des.direction = SDP_QOS_DIR_UNKNOWN; - for (i=0; i < SDP_MAX_QOS_DIR; i++) { - if (cpr_strncasecmp(tmp, sdp_qos_direction[i].name, - sdp_qos_direction[i].strlen) == 0) { - attr_p->attr.des.direction = (sdp_qos_dir_e)i; - } - } - if (attr_p->attr.des.direction == SDP_QOS_DIR_UNKNOWN) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: QOS direction unrecognized (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, type %s strength %s status type %s, direction %s", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type), - sdp_get_des_type_name(attr_p->attr.des.type), - sdp_get_qos_strength_name(attr_p->attr.qos.strength), - sdp_get_qos_status_type_name(attr_p->attr.des.status_type), - sdp_get_qos_direction_name(attr_p->attr.des.direction)); - } - - return (SDP_SUCCESS); -} - - -sdp_result_e sdp_build_attr_des (sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s %s %s %s\r\n", - sdp_attr[attr_p->type].name, - sdp_get_curr_type_name((sdp_curr_type_e)attr_p->attr.des.type), - sdp_get_qos_strength_name(attr_p->attr.des.strength), - sdp_get_qos_status_type_name(attr_p->attr.des.status_type), - sdp_get_qos_direction_name(attr_p->attr.des.direction)); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_conf (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - /* Find the curr type tag. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No conf attr type specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.conf.type = SDP_CONF_UNKNOWN_TYPE; - for (i=0; i < SDP_MAX_CURR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_conf_type[i].name, - sdp_conf_type[i].strlen) == 0) { - attr_p->attr.conf.type = (sdp_conf_type_e)i; - } - } - - if (attr_p->attr.conf.type != SDP_CONF_QOS_TYPE) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Unknown conf type.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Check qos status type */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No conf attr type specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.conf.status_type = SDP_QOS_STATUS_TYPE_UNKNOWN; - for (i=0; i < SDP_MAX_QOS_STATUS_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_qos_status_type[i].name, - sdp_qos_status_type[i].strlen) == 0) { - attr_p->attr.conf.status_type = (sdp_qos_status_types_e)i; - } - } - - - /* Find the qos direction. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No qos direction specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.conf.direction = SDP_QOS_DIR_UNKNOWN; - for (i=0; i < SDP_MAX_QOS_DIR; i++) { - if (cpr_strncasecmp(tmp, sdp_qos_direction[i].name, - sdp_qos_direction[i].strlen) == 0) { - attr_p->attr.conf.direction = (sdp_qos_dir_e)i; - } - } - if (attr_p->attr.conf.direction == SDP_QOS_DIR_UNKNOWN) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: QOS direction unrecognized (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, type %s status type %s, direction %s", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type), - sdp_get_conf_type_name(attr_p->attr.conf.type), - sdp_get_qos_status_type_name(attr_p->attr.conf.status_type), - sdp_get_qos_direction_name(attr_p->attr.conf.direction)); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_conf (sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s %s %s\r\n", - sdp_attr[attr_p->type].name, - sdp_get_conf_type_name(attr_p->attr.conf.type), - sdp_get_qos_status_type_name(attr_p->attr.conf.status_type), - sdp_get_qos_direction_name(attr_p->attr.conf.direction)); - - return SDP_SUCCESS; -} - -/* - * Parse a rtpmap or a sprtmap. Both formats use the same structure - * the only difference being the keyword "rtpmap" vs "sprtmap". The - * rtpmap field in the sdp_attr_t is used to store both mappings. - */ -sdp_result_e sdp_parse_attr_transport_map (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - - attr_p->attr.transport_map.payload_num = 0; - attr_p->attr.transport_map.encname[0] = '\0'; - attr_p->attr.transport_map.clockrate = 0; - attr_p->attr.transport_map.num_chan = 1; - - /* Find the payload type number. */ - attr_p->attr.transport_map.payload_num = - (u16)sdp_getnextnumtok(ptr, &ptr, " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid payload type specified for %s attribute.", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the encoding name. */ - ptr = sdp_getnextstrtok(ptr, attr_p->attr.transport_map.encname, - sizeof(attr_p->attr.transport_map.encname), "/ \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No encoding name specified in %s attribute.", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the clockrate. */ - attr_p->attr.transport_map.clockrate = - sdp_getnextnumtok(ptr, &ptr, "/ \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No clockrate specified for " - "%s attribute, set to default of 8000.", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - attr_p->attr.transport_map.clockrate = 8000; - } - - /* Find the number of channels, if specified. This is optional. */ - if (*ptr == '/') { - /* If a '/' exists, expect something valid beyond it. */ - attr_p->attr.transport_map.num_chan = - (u16)sdp_getnextnumtok(ptr, &ptr, "/ \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid number of channels parameter" - " for rtpmap attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, payload type %u, encoding name %s, " - "clockrate %lu", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.transport_map.payload_num, - attr_p->attr.transport_map.encname, - attr_p->attr.transport_map.clockrate); - if (attr_p->attr.transport_map.num_chan != 1) { - SDP_PRINT("/%u", attr_p->attr.transport_map.num_chan); - } - } - - return (SDP_SUCCESS); -} - -/* - * Build a rtpmap or a sprtmap. Both formats use the same structure - * the only difference being the keyword "rtpmap" vs "sprtmap". The - * rtpmap field in the sdp_attr_t is used for both mappings. - */ -sdp_result_e sdp_build_attr_transport_map (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - if (attr_p->attr.transport_map.num_chan == 1) { - flex_string_sprintf(fs, "a=%s:%u %s/%u\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.transport_map.payload_num, - attr_p->attr.transport_map.encname, - attr_p->attr.transport_map.clockrate); - } else { - flex_string_sprintf(fs, "a=%s:%u %s/%u/%u\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.transport_map.payload_num, - attr_p->attr.transport_map.encname, - attr_p->attr.transport_map.clockrate, - attr_p->attr.transport_map.num_chan); - } - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_subnet (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - char *slash_ptr; - sdp_result_e result; - tinybool type_found = FALSE; - char tmp[SDP_MAX_STRING_LEN]; - - /* Find the subnet network type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No network type specified in subnet attribute.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.subnet.nettype = SDP_NT_UNSUPPORTED; - for (i=0; i < SDP_MAX_NETWORK_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_nettype[i].name, - sdp_nettype[i].strlen) == 0) { - type_found = TRUE; - } - if (type_found == TRUE) { - if (sdp_p->conf_p->nettype_supported[i] == TRUE) { - attr_p->attr.subnet.nettype = (sdp_nettype_e)i; - } - type_found = FALSE; - } - } - if (attr_p->attr.subnet.nettype == SDP_NT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Subnet network type unsupported (%s).", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the subnet address type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No address type specified in subnet attribute.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.subnet.addrtype = SDP_AT_UNSUPPORTED; - for (i=0; i < SDP_MAX_ADDR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_addrtype[i].name, - sdp_addrtype[i].strlen) == 0) { - type_found = TRUE; - } - if (type_found == TRUE) { - if (sdp_p->conf_p->addrtype_supported[i] == TRUE) { - attr_p->attr.subnet.addrtype = (sdp_addrtype_e)i; - } - type_found = FALSE; - } - } - if (attr_p->attr.subnet.addrtype == SDP_AT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Subnet address type unsupported (%s).", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the subnet address. */ - ptr = sdp_getnextstrtok(ptr, attr_p->attr.subnet.addr, - sizeof(attr_p->attr.subnet.addr), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No subnet address specified in " - "subnet attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - slash_ptr = sdp_findchar(attr_p->attr.subnet.addr, "/"); - if (*slash_ptr == '/') { - *slash_ptr++ = '\0'; - /* If the '/' exists, expect a valid prefix to follow. */ - attr_p->attr.subnet.prefix = sdp_getnextnumtok(slash_ptr, - (const char **)&slash_ptr, - " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid subnet prefix specified in " - "subnet attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - } else { - attr_p->attr.subnet.prefix = SDP_INVALID_VALUE; - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, network %s, addr type %s, address %s ", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type), - sdp_get_network_name(attr_p->attr.subnet.nettype), - sdp_get_address_name(attr_p->attr.subnet.addrtype), - attr_p->attr.subnet.addr); - if (attr_p->attr.subnet.prefix != SDP_INVALID_VALUE) { - SDP_PRINT("/%u", (ushort)attr_p->attr.subnet.prefix); - } - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_subnet (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - if (attr_p->attr.subnet.prefix == SDP_INVALID_VALUE) { - flex_string_sprintf(fs, "a=%s:%s %s %s\r\n", - sdp_attr[attr_p->type].name, - sdp_get_network_name(attr_p->attr.subnet.nettype), - sdp_get_address_name(attr_p->attr.subnet.addrtype), - attr_p->attr.subnet.addr); - } else { - flex_string_sprintf(fs, "a=%s:%s %s %s/%u\r\n", - sdp_attr[attr_p->type].name, - sdp_get_network_name(attr_p->attr.subnet.nettype), - sdp_get_address_name(attr_p->attr.subnet.addrtype), - attr_p->attr.subnet.addr, - (ushort)attr_p->attr.subnet.prefix); - } - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_t38_ratemgmt (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - /* Find the rate mgmt. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No t38 rate management specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.t38ratemgmt = SDP_T38_UNKNOWN_RATE; - for (i=0; i < SDP_T38_MAX_RATES; i++) { - if (cpr_strncasecmp(tmp, sdp_t38_rate[i].name, - sdp_t38_rate[i].strlen) == 0) { - attr_p->attr.t38ratemgmt = (sdp_t38_ratemgmt_e)i; - } - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, rate %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - sdp_get_t38_ratemgmt_name(attr_p->attr.t38ratemgmt)); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_t38_ratemgmt (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s\r\n", - sdp_attr[attr_p->type].name, - sdp_get_t38_ratemgmt_name(attr_p->attr.t38ratemgmt)); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_t38_udpec (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - /* Find the udpec. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No t38 udpEC specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.t38udpec = SDP_T38_UDPEC_UNKNOWN; - for (i=0; i < SDP_T38_MAX_UDPEC; i++) { - if (cpr_strncasecmp(tmp, sdp_t38_udpec[i].name, - sdp_t38_udpec[i].strlen) == 0) { - attr_p->attr.t38udpec = (sdp_t38_udpec_e)i; - } - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, udpec %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - sdp_get_t38_udpec_name(attr_p->attr.t38udpec)); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_t38_udpec (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s\r\n", - sdp_attr[attr_p->type].name, - sdp_get_t38_udpec_name(attr_p->attr.t38udpec)); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_pc_codec (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - u16 i; - sdp_result_e result; - - for (i=0; i < SDP_MAX_PAYLOAD_TYPES; i++) { - attr_p->attr.pccodec.payload_type[i] = (ushort)sdp_getnextnumtok(ptr, &ptr, - " \t", &result); - if (result != SDP_SUCCESS) { - break; - } - attr_p->attr.pccodec.num_payloads++; - } - - if (attr_p->attr.pccodec.num_payloads == 0) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No payloads specified for %s attr.", - sdp_p->debug_str, sdp_attr[attr_p->type].name); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, num payloads %u, payloads: ", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type), - attr_p->attr.pccodec.num_payloads); - for (i=0; i < attr_p->attr.pccodec.num_payloads; i++) { - SDP_PRINT("%u ", attr_p->attr.pccodec.payload_type[i]); - } - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_pc_codec (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - int i; - - flex_string_sprintf(fs, "a=%s: ", sdp_attr[attr_p->type].name); - - for (i=0; i < attr_p->attr.pccodec.num_payloads; i++) { - flex_string_sprintf(fs, "%u ", attr_p->attr.pccodec.payload_type[i]); - } - - flex_string_append(fs, "\r\n"); - - return SDP_SUCCESS; -} - - -sdp_result_e sdp_parse_attr_cap (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - u16 i; - sdp_result_e result; - sdp_mca_t *cap_p; - char tmp[SDP_MAX_STRING_LEN]; - - /* Set the capability pointer to NULL for now in case we encounter - * an error in parsing. - */ - attr_p->attr.cap_p = NULL; - /* Set the capability valid flag to FALSE in case we encounter an - * error. If we do, we don't want to process any X-cpar/cpar attributes - * from this point until we process the next valid X-cap/cdsc attr. */ - sdp_p->cap_valid = FALSE; - - /* Allocate resource for new capability. Note that the capability - * uses the same structure used for media lines. - */ - cap_p = sdp_alloc_mca(); - if (cap_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - - /* Find the capability number. We don't need to store this since we - * calculate it for ourselves as we need to. But it must be specified. */ - (void)sdp_getnextnumtok(ptr, &ptr, "/ \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Capability not specified for %s, " - "unable to parse.", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - SDP_FREE(cap_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the media type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No media type specified for %s attribute, " - "unable to parse.", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - SDP_FREE(cap_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - cap_p->media = SDP_MEDIA_UNSUPPORTED; - for (i=0; i < SDP_MAX_MEDIA_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_media[i].name, sdp_media[i].strlen) == 0) { - cap_p->media = (sdp_media_e)i; - break; - } - } - if (cap_p->media == SDP_MEDIA_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Media type unsupported (%s).", - sdp_p->debug_str, tmp); - SDP_FREE(cap_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the transport protocol type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No transport protocol type specified, " - "unable to parse.", sdp_p->debug_str); - SDP_FREE(cap_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - cap_p->transport = SDP_TRANSPORT_UNSUPPORTED; - for (i=0; i < SDP_MAX_TRANSPORT_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_transport[i].name, - sdp_transport[i].strlen) == 0) { - cap_p->transport = (sdp_transport_e)i; - break; - } - } - if (cap_p->transport == SDP_TRANSPORT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Transport protocol type unsupported (%s).", - sdp_p->debug_str, tmp); - SDP_FREE(cap_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find payload formats. AAL2 X-cap lines allow multiple - * transport/profile types per line, so these are handled differently. - */ - if ((cap_p->transport == SDP_TRANSPORT_AAL2_ITU) || - (cap_p->transport == SDP_TRANSPORT_AAL2_ATMF) || - (cap_p->transport == SDP_TRANSPORT_AAL2_CUSTOM)) { - /* Capability processing is not currently defined for AAL2 types - * with multiple profiles. We don't process. */ - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: AAL2 profiles unsupported with " - "%s attributes.", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - SDP_FREE(cap_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - /* Transport is a non-AAL2 type. Parse payloads normally. */ - sdp_parse_payload_types(sdp_p, cap_p, ptr); - if (cap_p->num_payloads == 0) { - SDP_FREE(cap_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - } - - attr_p->attr.cap_p = cap_p; - /* - * This capability attr is valid. We can now handle X-cpar or - * cpar attrs. - */ - sdp_p->cap_valid = TRUE; - sdp_p->last_cap_inst++; - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed %s media type %s, Transport %s, " - "Num payloads %u", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - sdp_get_media_name(cap_p->media), - sdp_get_transport_name(cap_p->transport), - cap_p->num_payloads); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_cap (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - u16 i, j; - sdp_mca_t *cap_p; - sdp_media_profiles_t *profile_p; - - /* Get a pointer to the capability structure. */ - cap_p = attr_p->attr.cap_p; - - if (cap_p == NULL) { - CSFLogError(logTag, "%s Invalid %s attribute, unable to build.", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - /* Return success so build won't fail. */ - return (SDP_SUCCESS); - } - - /* Validate params for this capability line */ - if ((cap_p->media >= SDP_MAX_MEDIA_TYPES) || - (cap_p->transport >= SDP_MAX_TRANSPORT_TYPES)) { - CSFLogDebug(logTag, logTag, "%s Media or transport type invalid for %s " - "attribute, unable to build.", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - /* Return success so build won't fail. */ - return (SDP_SUCCESS); - } - - flex_string_sprintf(fs, "a=%s: %u %s ", sdp_attr[attr_p->type].name, - sdp_p->cur_cap_num, sdp_get_media_name(cap_p->media)); - - /* If the X-cap line has AAL2 profiles, build them differently. */ - if ((cap_p->transport == SDP_TRANSPORT_AAL2_ITU) || - (cap_p->transport == SDP_TRANSPORT_AAL2_ATMF) || - (cap_p->transport == SDP_TRANSPORT_AAL2_CUSTOM)) { - profile_p = cap_p->media_profiles_p; - for (i=0; i < profile_p->num_profiles; i++) { - flex_string_sprintf(fs, "%s", - sdp_get_transport_name(profile_p->profile[i])); - - for (j=0; j < profile_p->num_payloads[i]; j++) { - flex_string_sprintf(fs, " %u", - profile_p->payload_type[i][j]); - } - flex_string_append(fs, " "); - } - - flex_string_append(fs, "\r\n"); - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built m= media line", sdp_p->debug_str); - } - return SDP_SUCCESS; - } - - /* Build the transport name */ - flex_string_sprintf(fs, "%s", sdp_get_transport_name(cap_p->transport)); - - /* Build the format lists */ - for (i=0; i < cap_p->num_payloads; i++) { - if (cap_p->payload_indicator[i] == SDP_PAYLOAD_ENUM) { - flex_string_sprintf(fs, " %s", - sdp_get_payload_name((sdp_payload_e)cap_p->payload_type[i])); - } else { - flex_string_sprintf(fs, " %u", cap_p->payload_type[i]); - } - } - - flex_string_append(fs, "\r\n"); - - /* Increment the current capability number for the next X-cap/cdsc attr. */ - sdp_p->cur_cap_num += cap_p->num_payloads; - sdp_p->last_cap_type = attr_p->type; - - /* Build any X-cpar/cpar attributes associated with this X-cap/cdsc line. */ - return sdp_build_attr_cpar(sdp_p, cap_p->media_attrs_p, fs); -} - - -sdp_result_e sdp_parse_attr_cpar (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - u16 i; - sdp_result_e result; - sdp_mca_t *cap_p; - sdp_attr_t *cap_attr_p = NULL; - sdp_attr_t *prev_attr_p; - char tmp[SDP_MAX_STRING_LEN]; - - /* Make sure we've processed a valid X-cap/cdsc attr prior to this and - * if so, get the cap pointer. */ - if (sdp_p->cap_valid == TRUE) { - sdp_attr_e cap_type; - - if (attr_p->type == SDP_ATTR_CPAR) { - cap_type = SDP_ATTR_CDSC; - } else { - /* Default to X-CAP for everything else */ - cap_type = SDP_ATTR_X_CAP; - } - - if (sdp_p->mca_count == 0) { - cap_attr_p = sdp_find_attr(sdp_p, SDP_SESSION_LEVEL, 0, - cap_type, sdp_p->last_cap_inst); - } else { - cap_attr_p = sdp_find_attr(sdp_p, sdp_p->mca_count, 0, - cap_type, sdp_p->last_cap_inst); - } - } - if ((cap_attr_p == NULL) || (cap_attr_p->attr.cap_p == NULL)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: %s attribute specified with no " - "prior %s attribute", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - (attr_p->type == SDP_ATTR_CPAR)? - (sdp_get_attr_name(SDP_ATTR_CDSC)) : - (sdp_get_attr_name(SDP_ATTR_X_CAP)) ); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* - * Ensure there is no mixed syntax like CDSC followed by X-CPAR - * or X-CAP followed by CPAR. - */ - if (((cap_attr_p->type == SDP_ATTR_CDSC) && - (attr_p->type == SDP_ATTR_X_CPAR)) || - ( (cap_attr_p->type == SDP_ATTR_X_CAP) && - (attr_p->type == SDP_ATTR_CPAR)) ) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: %s attribute inconsistent with " - "prior %s attribute", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - sdp_get_attr_name(cap_attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - cap_p = cap_attr_p->attr.cap_p; - - /* a= is the only token we handle in an X-cpar/cpar attribute. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), "= \t", &result); - - if ((result != SDP_SUCCESS) || (tmp[0] != 'a') || (tmp[1] != '\0')) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid token type (%s) in %s " - "attribute, unable to parse", sdp_p->debug_str, tmp, - sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - /*sa_ignore NO_NULL_CHK - *{ptr is valid since the pointer was checked earlier and the - * function would have exited if NULL.} - */ - if (*ptr == '=') { - ptr++; - } - - /* Find the attribute type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), ": \t", &result); - /*sa_ignore NO_NULL_CHK - *{ptr is valid since the pointer was checked earlier and the - * function would have exited if NULL.} - */ - if (ptr[0] == ':') { - /* Skip the ':' char for parsing attribute parameters. */ - ptr++; - } - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No attribute type specified for %s attribute, unable to parse.", - sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Reset the type of the attribute from X-cpar/cpar to whatever the - * specified type is. */ - attr_p->type = SDP_ATTR_INVALID; - attr_p->next_p = NULL; - for (i=0; i < SDP_MAX_ATTR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_attr[i].name, sdp_attr[i].strlen) == 0) { - attr_p->type = (sdp_attr_e)i; - } - } - if (attr_p->type == SDP_ATTR_INVALID) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Unrecognized attribute (%s) for %s attribute, unable to parse.", - sdp_p->debug_str, tmp, - sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* We don't allow recursion with the capability attributes. */ - if ((attr_p->type == SDP_ATTR_X_SQN) || - (attr_p->type == SDP_ATTR_X_CAP) || - (attr_p->type == SDP_ATTR_X_CPAR) || - (attr_p->type == SDP_ATTR_SQN) || - (attr_p->type == SDP_ATTR_CDSC) || - (attr_p->type == SDP_ATTR_CPAR)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid attribute (%s) for %s" - " attribute, unable to parse.", sdp_p->debug_str, tmp, - sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Parse the attribute. */ - result = sdp_attr[attr_p->type].parse_func(sdp_p, attr_p, ptr); - if (result != SDP_SUCCESS) { - return (result); - } - - /* Hook the attribute into the capability structure. */ - if (cap_p->media_attrs_p == NULL) { - cap_p->media_attrs_p = attr_p; - } else { - for (prev_attr_p = cap_p->media_attrs_p; - prev_attr_p->next_p != NULL; - prev_attr_p = prev_attr_p->next_p) { - ; /* Empty for */ - } - prev_attr_p->next_p = attr_p; - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_cpar (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - sdp_result_e result; - const char *cpar_name; - - /* Determine whether to use cpar or X-cpar */ - if (sdp_p->last_cap_type == SDP_ATTR_CDSC) { - cpar_name = sdp_get_attr_name(SDP_ATTR_CPAR); - } else { - /* - * Default to X-CPAR if anything else. This is the backward - * compatible value. - */ - cpar_name = sdp_get_attr_name(SDP_ATTR_X_CPAR); - } - - while (attr_p != NULL) { - if (attr_p->type >= SDP_MAX_ATTR_TYPES) { - CSFLogDebug(logTag, "%s Invalid attribute type to build (%u)", - sdp_p->debug_str, attr_p->type); - } else { - flex_string_sprintf(fs, "a=%s: ", cpar_name); - - result = sdp_attr[attr_p->type].build_func(sdp_p, attr_p, fs); - - if (result == SDP_SUCCESS) { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built %s a=%s attribute line", - sdp_p->debug_str, cpar_name, - sdp_get_attr_name(attr_p->type)); - } - } - } - attr_p = attr_p->next_p; - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_attr_rtr (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsing a=%s, %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - tmp); - } - /*Default confirm to FALSE. */ - attr_p->attr.rtr.confirm = FALSE; - - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS){ // No confirm tag specified is not an error - return (SDP_SUCCESS); - } else { - /* See if confirm was specified. Defaults to FALSE. */ - if (cpr_strncasecmp(tmp, "confirm", sizeof("confirm")) == 0) { - attr_p->attr.rtr.confirm = TRUE; - } - if (attr_p->attr.rtr.confirm == FALSE) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: RTR confirm parameter invalid (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - tmp); - } - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_build_attr_rtr (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s%s\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.rtr.confirm ? ":confirm" : ""); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_comediadir (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - sdp_result_e result; - tinybool type_found = FALSE; - char tmp[SDP_MAX_STRING_LEN]; - - attr_p->attr.comediadir.role = SDP_MEDIADIR_ROLE_PASSIVE; - attr_p->attr.comediadir.conn_info_present = FALSE; - attr_p->attr.comediadir.conn_info.nettype = SDP_NT_INVALID; - attr_p->attr.comediadir.src_port = 0; - - /* Find the media direction role. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), ": \t", &result); - - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No role parameter specified for " - "comediadir attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.comediadir.role = SDP_MEDIADIR_ROLE_UNSUPPORTED; - for (i=0; i < SDP_MAX_MEDIADIR_ROLES; i++) { - if (cpr_strncasecmp(tmp, sdp_mediadir_role[i].name, - sdp_mediadir_role[i].strlen) == 0) { - type_found = TRUE; - attr_p->attr.comediadir.role = (sdp_mediadir_role_e)i; - break; - } - } - if (attr_p->attr.comediadir.role == SDP_MEDIADIR_ROLE_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid role type specified for " - "comediadir attribute (%s).", sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* If the role is passive, we don't expect any more params. */ - if (attr_p->attr.comediadir.role == SDP_MEDIADIR_ROLE_PASSIVE) { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, passive", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - } - return (SDP_SUCCESS); - } - - /* Find the connection information if present */ - /* parse to get the nettype */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No network type specified in comediadir " - "attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_SUCCESS); /* as the optional parameters are not there */ - } - attr_p->attr.comediadir.conn_info.nettype = SDP_NT_UNSUPPORTED; - for (i=0; i < SDP_MAX_NETWORK_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_nettype[i].name, - sdp_nettype[i].strlen) == 0) { - type_found = TRUE; - } - if (type_found == TRUE) { - if (sdp_p->conf_p->nettype_supported[i] == TRUE) { - attr_p->attr.comediadir.conn_info.nettype = (sdp_nettype_e)i; - } - type_found = FALSE; - } - } - if (attr_p->attr.comediadir.conn_info.nettype == SDP_NT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: ConnInfo in Comediadir: network type " - "unsupported (%s).", sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - } - - /* Find the comedia address type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No address type specified in comediadir" - " attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - } - attr_p->attr.comediadir.conn_info.addrtype = SDP_AT_UNSUPPORTED; - for (i=0; i < SDP_MAX_ADDR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_addrtype[i].name, - sdp_addrtype[i].strlen) == 0) { - type_found = TRUE; - } - if (type_found == TRUE) { - if (sdp_p->conf_p->addrtype_supported[i] == TRUE) { - attr_p->attr.comediadir.conn_info.addrtype = (sdp_addrtype_e)i; - } - type_found = FALSE; - } - } - if (attr_p->attr.comediadir.conn_info.addrtype == SDP_AT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Conninfo address type unsupported " - "(%s).", sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - } - - /* Find the conninfo address. */ - ptr = sdp_getnextstrtok(ptr, attr_p->attr.comediadir.conn_info.conn_addr, - sizeof(attr_p->attr.comediadir.conn_info.conn_addr), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No conninfo address specified in " - "comediadir attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - } - - /* Find the src port info , if any */ - attr_p->attr.comediadir.src_port = sdp_getnextnumtok(ptr, &ptr, " \t", - &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No src port specified in " - "comediadir attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, network %s, addr type %s, address %s " - "srcport %u ", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type), - sdp_get_network_name(attr_p->attr.comediadir.conn_info.nettype), - sdp_get_address_name(attr_p->attr.comediadir.conn_info.addrtype), - attr_p->attr.comediadir.conn_info.conn_addr, - (unsigned int)attr_p->attr.comediadir.src_port); - } - - if (sdp_p->conf_p->num_invalid_param > 0) { - return (SDP_INVALID_PARAMETER); - } - return (SDP_SUCCESS); -} - -sdp_result_e -sdp_build_attr_comediadir (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s\r\n", - sdp_attr[attr_p->type].name, - sdp_get_mediadir_role_name(attr_p->attr.comediadir.role)); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_silencesupp (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - /* Find silenceSuppEnable */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No silenceSupp enable value specified, parse failed.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (cpr_strncasecmp(tmp, "on", sizeof("on")) == 0) { - attr_p->attr.silencesupp.enabled = TRUE; - } else if (cpr_strncasecmp(tmp, "off", sizeof("off")) == 0) { - attr_p->attr.silencesupp.enabled = FALSE; - } else if (cpr_strncasecmp(tmp, "-", sizeof("-")) == 0) { - attr_p->attr.silencesupp.enabled = FALSE; - } else { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: silenceSuppEnable parameter invalid (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find silenceTimer -- u16 or "-" */ - - attr_p->attr.silencesupp.timer = - (u16)sdp_getnextnumtok_or_null(ptr, &ptr, " \t", - &attr_p->attr.silencesupp.timer_null, - &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid timer value specified for " - "silenceSupp attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find suppPref */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No silenceSupp pref specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.silencesupp.pref = SDP_SILENCESUPP_PREF_UNKNOWN; - for (i=0; i < SDP_MAX_SILENCESUPP_PREF; i++) { - if (cpr_strncasecmp(tmp, sdp_silencesupp_pref[i].name, - sdp_silencesupp_pref[i].strlen) == 0) { - attr_p->attr.silencesupp.pref = (sdp_silencesupp_pref_e)i; - } - } - if (attr_p->attr.silencesupp.pref == SDP_SILENCESUPP_PREF_UNKNOWN) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: silenceSupp pref unrecognized (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find sidUse */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No silenceSupp sidUse specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.silencesupp.siduse = SDP_SILENCESUPP_SIDUSE_UNKNOWN; - for (i=0; i < SDP_MAX_SILENCESUPP_SIDUSE; i++) { - if (cpr_strncasecmp(tmp, sdp_silencesupp_siduse[i].name, - sdp_silencesupp_siduse[i].strlen) == 0) { - attr_p->attr.silencesupp.siduse = (sdp_silencesupp_siduse_e)i; - } - } - if (attr_p->attr.silencesupp.siduse == SDP_SILENCESUPP_SIDUSE_UNKNOWN) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: silenceSupp sidUse unrecognized (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find fxnslevel -- u8 or "-" */ - attr_p->attr.silencesupp.fxnslevel = - (u8)sdp_getnextnumtok_or_null(ptr, &ptr, " \t", - &attr_p->attr.silencesupp.fxnslevel_null, - &result); - - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid fxnslevel value specified for " - "silenceSupp attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, enabled %s", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type), - (attr_p->attr.silencesupp.enabled ? "on" : "off")); - if (attr_p->attr.silencesupp.timer_null) { - SDP_PRINT(" timer=-"); - } else { - SDP_PRINT(" timer=%u,", attr_p->attr.silencesupp.timer); - } - SDP_PRINT(" pref=%s, siduse=%s,", - sdp_get_silencesupp_pref_name(attr_p->attr.silencesupp.pref), - sdp_get_silencesupp_siduse_name( - attr_p->attr.silencesupp.siduse)); - if (attr_p->attr.silencesupp.fxnslevel_null) { - SDP_PRINT(" fxnslevel=-"); - } else { - SDP_PRINT(" fxnslevel=%u,", attr_p->attr.silencesupp.fxnslevel); - } - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_silencesupp (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - char temp_timer_string[11]; - char temp_fxnslevel_string[11]; - - if (attr_p->attr.silencesupp.timer_null) { - snprintf(temp_timer_string, sizeof(temp_timer_string), "-"); - } else { - snprintf(temp_timer_string, sizeof(temp_timer_string), "%u", attr_p->attr.silencesupp.timer); - } - - if (attr_p->attr.silencesupp.fxnslevel_null) { - snprintf(temp_fxnslevel_string, sizeof(temp_fxnslevel_string), "-"); - } else { - snprintf(temp_fxnslevel_string, sizeof(temp_fxnslevel_string), "%u", attr_p->attr.silencesupp.fxnslevel); - } - - flex_string_sprintf(fs, "a=%s:%s %s %s %s %s\r\n", - sdp_attr[attr_p->type].name, - (attr_p->attr.silencesupp.enabled ? "on" : "off"), - temp_timer_string, - sdp_get_silencesupp_pref_name(attr_p->attr.silencesupp.pref), - sdp_get_silencesupp_siduse_name(attr_p->attr.silencesupp.siduse), - temp_fxnslevel_string); - - return SDP_SUCCESS; -} - -/* - * sdp_parse_context_crypto_suite - * - * This routine parses the crypto suite pointed to by str, stores the crypto suite value into the - * srtp context suite component of the LocalConnectionOptions pointed to by lco_node_ptr and stores - * pointer to the next crypto parameter in tmp_ptr - */ -tinybool sdp_parse_context_crypto_suite(char * str, sdp_attr_t *attr_p, sdp_t *sdp_p) { - /* - * Three crypto_suites are defined: (Notice no SPACE between "crypto:" and the - * AES_CM_128_HMAC_SHA1_80 - * AES_CM_128_HMAC_SHA1_32 - * F8_128_HMAC_SHA1_80 - */ - - int i; - - /* Check crypto suites */ - for(i=0; iattr.srtp_context.suite = sdp_srtp_crypto_suite_array[i].crypto_suite_val; - attr_p->attr.srtp_context.master_key_size_bytes = - sdp_srtp_crypto_suite_array[i].key_size_bytes; - attr_p->attr.srtp_context.master_salt_size_bytes = - sdp_srtp_crypto_suite_array[i].salt_size_bytes; - return TRUE; /* There is a succesful match so exit */ - } - } - /* couldn't find a matching crypto suite */ - sdp_parse_error(sdp_p->peerconnection, - "%s No Matching crypto suite for SRTP Context(%s)-'X-crypto:v1' expected", - sdp_p->debug_str, str); - - return FALSE; -} - - -sdp_result_e sdp_build_attr_srtpcontext (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ -#define MAX_BASE64_ENCODE_SIZE_BYTES 60 - int output_len = MAX_BASE64_ENCODE_SIZE_BYTES; - int key_size = attr_p->attr.srtp_context.master_key_size_bytes; - int salt_size = attr_p->attr.srtp_context.master_salt_size_bytes; - unsigned char base64_encoded_data[MAX_BASE64_ENCODE_SIZE_BYTES]; - unsigned char base64_encoded_input[MAX_BASE64_ENCODE_SIZE_BYTES]; - base64_result_t status; - - output_len = MAX_BASE64_ENCODE_SIZE_BYTES; - - /* Append master and salt keys */ - bcopy(attr_p->attr.srtp_context.master_key, base64_encoded_input, - key_size ); - bcopy(attr_p->attr.srtp_context.master_salt, - base64_encoded_input + key_size, salt_size ); - - if ((status = base64_encode(base64_encoded_input, key_size + salt_size, - base64_encoded_data, &output_len)) != BASE64_SUCCESS) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Error: Failure to Base64 Encoded data (%s) ", - sdp_p->debug_str, BASE64_RESULT_TO_STRING(status)); - } - return (SDP_INVALID_PARAMETER); - } - - *(base64_encoded_data + output_len) = '\0'; - - flex_string_sprintf(fs, "a=%s:%s inline:%s||\r\n", - sdp_attr[attr_p->type].name, - sdp_srtp_context_crypto_suite[attr_p->attr.srtp_context.suite].name, - base64_encoded_data); - - return SDP_SUCCESS; -} - -/* - * sdp_parse_attr_mptime - * This function parses the a=mptime sdp line. This parameter consists of - * one or more numbers or hyphens ("-"). The first parameter must be a - * number. The number of parameters must match the number of formats specified - * on the m= line. This function is liberal in that it does not match against - * the m= line or require a number for the first parameter. - */ -sdp_result_e sdp_parse_attr_mptime ( - sdp_t *sdp_p, - sdp_attr_t *attr_p, - const char *ptr) -{ - u16 i; /* loop counter for parameters */ - sdp_result_e result; /* value returned by this function */ - tinybool null_ind; /* true if a parameter is "-" */ - - /* - * Scan the input line up to the maximum number of parameters supported. - * Look for numbers or hyphens and store the resulting values. Hyphens - * are stored as zeros. - */ - for (i=0; iattr.mptime.intervals[i] = - (ushort)sdp_getnextnumtok_or_null(ptr,&ptr," \t",&null_ind,&result); - if (result != SDP_SUCCESS) { - break; - } - attr_p->attr.mptime.num_intervals++; - } - - /* - * At least one parameter must be supplied. If not, return an error - * and optionally log the failure. - */ - if (attr_p->attr.mptime.num_intervals == 0) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No intervals specified for %s attr.", - sdp_p->debug_str, sdp_attr[attr_p->type].name); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* - * Here is some debugging code that helps us track what data - * is received and parsed. - */ - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, num intervals %u, intervals: ", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type), - attr_p->attr.mptime.num_intervals); - for (i=0; i < attr_p->attr.mptime.num_intervals; i++) { - SDP_PRINT("%u ", attr_p->attr.mptime.intervals[i]); - } - } - - return SDP_SUCCESS; -} - -/* - * sdp_build_attr_mptime - * This function builds the a=mptime sdp line. It reads the selected attribute - * from the sdp structure. Parameters with a value of zero are replaced by - * hyphens. - */ -sdp_result_e sdp_build_attr_mptime ( - sdp_t *sdp_p, - sdp_attr_t *attr_p, - flex_string *fs) -{ - int i; - - flex_string_sprintf(fs, "a=%s:", sdp_attr[attr_p->type].name); - - /* - * Run the list of mptime parameter values and write each one - * to the sdp line. Replace zeros with hyphens. - */ - for (i=0; i < attr_p->attr.mptime.num_intervals; i++) { - if (i > 0) { - flex_string_append(fs, " "); - } - - if (attr_p->attr.mptime.intervals[i] == 0) { - flex_string_append(fs, "-"); - } else { - flex_string_sprintf(fs, "%u", attr_p->attr.mptime.intervals[i]); - } - } - - flex_string_append(fs, "\r\n"); - - return SDP_SUCCESS; -} - - - -sdp_result_e sdp_parse_attr_x_sidin (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - attr_p->attr.stream_data.x_sidin[0] = '\0'; - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsing a=%s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - } - - /* Find the X-sidin value */ - ptr = sdp_getnextstrtok(ptr, attr_p->attr.stream_data.x_sidin, - sizeof(attr_p->attr.stream_data.x_sidin), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No Stream Id incoming specified for X-sidin attribute.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.stream_data.x_sidin); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_x_sidin (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.stream_data.x_sidin); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_x_sidout (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - attr_p->attr.stream_data.x_sidout[0] = '\0'; - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsing a=%s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - } - - /* Find the X-sidout value */ - ptr = sdp_getnextstrtok(ptr, attr_p->attr.stream_data.x_sidout, - sizeof(attr_p->attr.stream_data.x_sidout), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No Stream Id outgoing specified for X-sidout attribute.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.stream_data.x_sidout); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_x_sidout (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - flex_string_sprintf(fs, "a=%s:%s\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.stream_data.x_sidout); - - return SDP_SUCCESS; -} - - -sdp_result_e sdp_parse_attr_x_confid (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - attr_p->attr.stream_data.x_confid[0] = '\0'; - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsing a=%s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - } - - /* Find the X-confid value */ - ptr = sdp_getnextstrtok(ptr, attr_p->attr.stream_data.x_confid, - sizeof(attr_p->attr.stream_data.x_confid), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No Conf Id incoming specified for " - "X-confid attribute.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.stream_data.x_confid); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_x_confid (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - if (strlen(attr_p->attr.stream_data.x_confid) <= 0) { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s X-confid value is not set. Cannot build a=X-confid line\n", - sdp_p->debug_str); - } - - return SDP_INVALID_PARAMETER; - } - - flex_string_sprintf(fs, "a=%s:%s\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.stream_data.x_confid); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_group (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - char tmp[10]; - int i=0; - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsing a=%s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type)); - } - - /* Find the a=group: < id2> ... values */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No group attribute value specified for " - "a=group line", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - attr_p->attr.stream_data.group_attr = SDP_GROUP_ATTR_UNSUPPORTED; - for (i=0; i < SDP_MAX_GROUP_ATTR_VAL; i++) { - if (cpr_strncasecmp(tmp, sdp_group_attr_val[i].name, - sdp_group_attr_val[i].strlen) == 0) { - attr_p->attr.stream_data.group_attr = (sdp_group_attr_e)i; - break; - } - } - - if (attr_p->attr.stream_data.group_attr == SDP_GROUP_ATTR_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Group attribute type unsupported (%s).", - sdp_p->debug_str, tmp); - } - - - /* - * Scan the input line up after group: to the maximum number - * of id available. - */ - attr_p->attr.stream_data.num_group_id =0; - - for (i=0; iattr.stream_data.group_id_arr[i] = - (u16)sdp_getnextnumtok(ptr,&ptr," \t", &result); - if (result != SDP_SUCCESS) { - break; - } - attr_p->attr.stream_data.num_group_id++; - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s:%s\n", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - sdp_get_group_attr_name (attr_p->attr.stream_data.group_attr)); - for (i=0; i < attr_p->attr.stream_data.num_group_id; i++) { - SDP_PRINT("%s Parsed group line id : %d\n", sdp_p->debug_str, - attr_p->attr.stream_data.group_id_arr[i]); - } - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_group (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - int i; - - flex_string_sprintf(fs, "a=%s:%s", - sdp_attr[attr_p->type].name, - sdp_get_group_attr_name(attr_p->attr.stream_data.group_attr)); - - for (i=0; i < attr_p->attr.stream_data.num_group_id; i++) { - if (attr_p->attr.stream_data.group_id_arr[i] > 0) { - flex_string_sprintf(fs, " %u", - attr_p->attr.stream_data.group_id_arr[i]); - } - } - - flex_string_append(fs, "\r\n"); - - return SDP_SUCCESS; -} - -/* Parse the source-filter attribute - * "a=source-filter:" - * = ... - */ -sdp_result_e sdp_parse_attr_source_filter (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - int i; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - attr_p->attr.source_filter.mode = SDP_FILTER_MODE_NOT_PRESENT; - attr_p->attr.source_filter.nettype = SDP_NT_UNSUPPORTED; - attr_p->attr.source_filter.addrtype = SDP_AT_UNSUPPORTED; - attr_p->attr.source_filter.dest_addr[0] = '\0'; - attr_p->attr.source_filter.num_src_addr = 0; - - /* Find the filter mode */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No src filter attribute value specified for " - "a=source-filter line", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - for (i = 0; i < SDP_MAX_FILTER_MODE; i++) { - if (cpr_strncasecmp(tmp, sdp_src_filter_mode_val[i].name, - sdp_src_filter_mode_val[i].strlen) == 0) { - attr_p->attr.source_filter.mode = (sdp_src_filter_mode_e)i; - break; - } - } - if (attr_p->attr.source_filter.mode == SDP_FILTER_MODE_NOT_PRESENT) { - /* No point continuing */ - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid src filter mode for a=source-filter " - "line", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the network type */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - for (i = 0; i < SDP_MAX_NETWORK_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_nettype[i].name, - sdp_nettype[i].strlen) == 0) { - if (sdp_p->conf_p->nettype_supported[i] == TRUE) { - attr_p->attr.source_filter.nettype = (sdp_nettype_e)i; - } - } - } - if (attr_p->attr.source_filter.nettype == SDP_NT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Network type unsupported " - "(%s) for a=source-filter", sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the address type */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - for (i = 0; i < SDP_MAX_ADDR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_addrtype[i].name, - sdp_addrtype[i].strlen) == 0) { - if (sdp_p->conf_p->addrtype_supported[i] == TRUE) { - attr_p->attr.source_filter.addrtype = (sdp_addrtype_e)i; - } - } - } - if (attr_p->attr.source_filter.addrtype == SDP_AT_UNSUPPORTED) { - if (strncmp(tmp, "*", 1) == 0) { - attr_p->attr.source_filter.addrtype = SDP_AT_FQDN; - } else { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Address type unsupported " - "(%s) for a=source-filter", sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - } - - /* Find the destination addr */ - ptr = sdp_getnextstrtok(ptr, attr_p->attr.source_filter.dest_addr, - sizeof(attr_p->attr.source_filter.dest_addr), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No filter destination address specified for " - "a=source-filter", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the list of source address to apply the filter */ - for (i = 0; i < SDP_MAX_SRC_ADDR_LIST; i++) { - ptr = sdp_getnextstrtok(ptr, attr_p->attr.source_filter.src_list[i], - sizeof(attr_p->attr.source_filter.src_list[i]), " \t", &result); - if (result != SDP_SUCCESS) { - break; - } - attr_p->attr.source_filter.num_src_addr++; - } - if (attr_p->attr.source_filter.num_src_addr == 0) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No source list provided " - "for a=source-filter", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_source_filter (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - int i; - - flex_string_sprintf(fs, "a=%s:%s %s %s %s", - sdp_get_attr_name(attr_p->type), - sdp_get_src_filter_mode_name(attr_p->attr.source_filter.mode), - sdp_get_network_name(attr_p->attr.source_filter.nettype), - sdp_get_address_name(attr_p->attr.source_filter.addrtype), - attr_p->attr.source_filter.dest_addr); - - for (i = 0; i < attr_p->attr.source_filter.num_src_addr; i++) { - flex_string_append(fs, " "); - flex_string_append(fs, attr_p->attr.source_filter.src_list[i]); - } - - flex_string_append(fs, "\r\n"); - - return SDP_SUCCESS; -} - -/* Parse the rtcp-unicast attribute - * "a=rtcp-unicast:" - */ -sdp_result_e sdp_parse_attr_rtcp_unicast (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - u32 i; - char tmp[SDP_MAX_STRING_LEN]; - - attr_p->attr.u32_val = SDP_RTCP_UNICAST_MODE_NOT_PRESENT; - - memset(tmp, 0, sizeof(tmp)); - - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No rtcp unicast mode specified for " - "a=rtcp-unicast line", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - for (i = 0; i < SDP_RTCP_MAX_UNICAST_MODE; i++) { - if (cpr_strncasecmp(tmp, sdp_rtcp_unicast_mode_val[i].name, - sdp_rtcp_unicast_mode_val[i].strlen) == 0) { - attr_p->attr.u32_val = i; - break; - } - } - if (attr_p->attr.u32_val == SDP_RTCP_UNICAST_MODE_NOT_PRESENT) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid rtcp unicast mode for " - "a=rtcp-unicast line", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_attr_rtcp_unicast (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - if (attr_p->attr.u32_val >= SDP_RTCP_MAX_UNICAST_MODE) { - return SDP_INVALID_PARAMETER; - } - - flex_string_sprintf(fs, "a=%s:%s\r\n", - sdp_get_attr_name(attr_p->type), - sdp_get_rtcp_unicast_mode_name((sdp_rtcp_unicast_mode_e)attr_p->attr.u32_val)); - - return SDP_SUCCESS; -} - - -/* - * store_sdescriptions_mki_or_lifetime - * - * Verifies the syntax of the MKI or lifetime parameter and stores - * it in the sdescriptions attribute struct. - * - * Inputs: - * buf - pointer to MKI or lifetime string assumes string is null - * terminated. - * attr_p - pointer to attribute struct - * - * Outputs: - * Return TRUE all is good otherwise FALSE for error. - */ - -tinybool -store_sdescriptions_mki_or_lifetime (char *buf, sdp_attr_t *attr_p) -{ - - tinybool result; - u16 mkiLen; - char mkiValue[SDP_SRTP_MAX_MKI_SIZE_BYTES]; - - /* MKI has a colon */ - if (strstr(buf, ":")) { - result = verify_sdescriptions_mki(buf, mkiValue, &mkiLen); - if (result) { - attr_p->attr.srtp_context.mki_size_bytes = mkiLen; - sstrncpy((char*)attr_p->attr.srtp_context.mki, mkiValue, - SDP_SRTP_MAX_MKI_SIZE_BYTES); - } - - } else { - result = verify_sdescriptions_lifetime(buf); - if (result) { - sstrncpy((char*)attr_p->attr.srtp_context.master_key_lifetime, buf, - SDP_SRTP_MAX_LIFETIME_BYTES); - } - } - - return result; - -} - -/* - * sdp_parse_sdescriptions_key_param - * - * This routine parses the srtp key-params pointed to by str. - * - * key-params = ":" - * key-method = "inline" / key-method-ext [note V9 only supports 'inline'] - * key-info = srtp-key-info - * srtp-key-info = key-salt ["|" lifetime] ["|" mki] - * key-salt = 1*(base64) ; binary key and salt values - * ; concatenated together, and then - * ; base64 encoded [section 6.8 of - * ; RFC2046] - * - * lifetime = ["2^"] 1*(DIGIT) - * mki = mki-value ":" mki-length - * mki-value = 1*DIGIT - * mki-length = 1*3DIGIT ; range 1..128. - * - * Inputs: str - pointer to beginning of key-params and assumes - * null terminated string. - */ - - -tinybool -sdp_parse_sdescriptions_key_param (const char *str, sdp_attr_t *attr_p, - sdp_t *sdp_p) -{ - char buf[SDP_MAX_STRING_LEN], - base64decodeData[SDP_MAX_STRING_LEN]; - const char *ptr; - sdp_result_e result = SDP_SUCCESS; - tinybool keyFound = FALSE; - int len, - keySize, - saltSize; - base64_result_t status; - - ptr = str; - if (cpr_strncasecmp(ptr, "inline:", 7) != 0) { - sdp_parse_error(sdp_p->peerconnection, - "%s Could not find keyword inline", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return FALSE; - } - - /* advance pass the inline key word */ - ptr = ptr + 7; - ptr = sdp_getnextstrtok(ptr, buf, sizeof(buf), "|", &result); - while (result == SDP_SUCCESS) { - /* the fist time this loop executes, the key is gotten */ - if (keyFound == FALSE) { - keyFound = TRUE; - len = SDP_MAX_STRING_LEN; - /* The key is base64 encoded composed of the master key concatenated with the - * master salt. - */ - status = base64_decode((unsigned char *)buf, strlen(buf), - (unsigned char *)base64decodeData, &len); - - if (status != BASE64_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s key-salt error decoding buffer: %s", - sdp_p->debug_str, BASE64_RESULT_TO_STRING(status)); - return FALSE; - } - - keySize = attr_p->attr.srtp_context.master_key_size_bytes; - saltSize = attr_p->attr.srtp_context.master_salt_size_bytes; - - if (len != keySize + saltSize) { - sdp_parse_error(sdp_p->peerconnection, - "%s key-salt size doesn't match: (%d, %d, %d)", - sdp_p->debug_str, len, keySize, saltSize); - return(FALSE); - } - - bcopy(base64decodeData, attr_p->attr.srtp_context.master_key, keySize); - - bcopy(base64decodeData + keySize, - attr_p->attr.srtp_context.master_salt, saltSize); - - /* Used only for MGCP */ - SDP_SRTP_CONTEXT_SET_MASTER_KEY - (attr_p->attr.srtp_context.selection_flags); - SDP_SRTP_CONTEXT_SET_MASTER_SALT - (attr_p->attr.srtp_context.selection_flags); - - } else if (store_sdescriptions_mki_or_lifetime(buf, attr_p) == FALSE) { - return FALSE; - } - - /* if we haven't reached the end of line, get the next token */ - ptr = sdp_getnextstrtok(ptr, buf, sizeof(buf), "|", &result); - } - - /* if we didn't find the key, error out */ - if (keyFound == FALSE) { - sdp_parse_error(sdp_p->peerconnection, - "%s Could not find sdescriptions key", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return FALSE; - } - - return TRUE; - -} - -/* - * sdp_build_attr_sdescriptions - * - * Builds a=crypto line for attribute type SDP_ATTR_SDESCRIPTIONS. - * - * a=crypto:tag 1*WSP crypto-suite 1*WSP key-params - * - * Where key-params = inline: ["|"lifetime] ["|" MKI:length] - * The key and salt is base64 encoded and lifetime and MKI/length are optional. - */ - -sdp_result_e -sdp_build_attr_sdescriptions (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) -{ - - unsigned char base64_encoded_data[MAX_BASE64_STRING_LEN]; - unsigned char base64_encoded_input[MAX_BASE64_STRING_LEN]; - int keySize, - saltSize, - outputLen; - base64_result_t status; - - keySize = attr_p->attr.srtp_context.master_key_size_bytes; - saltSize = attr_p->attr.srtp_context.master_salt_size_bytes; - - /* concatenate the master key + salt then base64 encode it */ - bcopy(attr_p->attr.srtp_context.master_key, - base64_encoded_input, keySize); - - bcopy(attr_p->attr.srtp_context.master_salt, - base64_encoded_input + keySize, saltSize); - - outputLen = MAX_BASE64_STRING_LEN; - status = base64_encode(base64_encoded_input, keySize + saltSize, - base64_encoded_data, &outputLen); - - if (status != BASE64_SUCCESS) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Error: Failure to Base64 Encoded data (%s) ", - sdp_p->debug_str, BASE64_RESULT_TO_STRING(status)); - } - return (SDP_INVALID_PARAMETER); - - } - - base64_encoded_data[outputLen] = 0; - - /* lifetime and MKI parameters are optional. Only inlcude them if - * they were set. - */ - - - if (attr_p->attr.srtp_context.master_key_lifetime[0] != 0 && - attr_p->attr.srtp_context.mki[0] != 0) { - flex_string_sprintf(fs, "a=%s:%d %s inline:%s|%s|%s:%d\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.srtp_context.tag, - sdp_srtp_context_crypto_suite[attr_p->attr.srtp_context.suite].name, - base64_encoded_data, - attr_p->attr.srtp_context.master_key_lifetime, - attr_p->attr.srtp_context.mki, - attr_p->attr.srtp_context.mki_size_bytes); - - return SDP_SUCCESS; - } - - /* if we get here, either lifetime is populated and mki and is not or mki is populated - * and lifetime is not or neither is populated - */ - - if (attr_p->attr.srtp_context.master_key_lifetime[0] != 0) { - flex_string_sprintf(fs, "a=%s:%d %s inline:%s|%s\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.srtp_context.tag, - sdp_srtp_context_crypto_suite[attr_p->attr.srtp_context.suite].name, - base64_encoded_data, - attr_p->attr.srtp_context.master_key_lifetime); - - } else if (attr_p->attr.srtp_context.mki[0] != 0) { - flex_string_sprintf(fs, "a=%s:%d %s inline:%s|%s:%d\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.srtp_context.tag, - sdp_srtp_context_crypto_suite[attr_p->attr.srtp_context.suite].name, - base64_encoded_data, - attr_p->attr.srtp_context.mki, - attr_p->attr.srtp_context.mki_size_bytes); - - } else { - flex_string_sprintf(fs, "a=%s:%d %s inline:%s\r\n", - sdp_attr[attr_p->type].name, - attr_p->attr.srtp_context.tag, - sdp_srtp_context_crypto_suite[attr_p->attr.srtp_context.suite].name, - base64_encoded_data); - - } - - return SDP_SUCCESS; - -} - - -/* - * sdp_parse_attr_srtp - * - * Parses Session Description for Protocol Security Descriptions - * version 2 or version 9. Grammar is of the form: - * - * a=crypto: [] - * - * Note session-params is not supported and will not be parsed. - * Version 2 does not contain a tag. - * - * Inputs: - * sdp_p - pointer to sdp handle - * attr_p - pointer to attribute structure - * ptr - pointer to string to be parsed - * vtype - version type - */ - -sdp_result_e -sdp_parse_attr_srtp (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr, sdp_attr_e vtype) -{ - - char tmp[SDP_MAX_STRING_LEN]; - sdp_result_e result = SDP_FAILURE; - int k = 0; - - /* initialize only the optional parameters */ - attr_p->attr.srtp_context.master_key_lifetime[0] = 0; - attr_p->attr.srtp_context.mki[0] = 0; - - /* used only for MGCP */ - SDP_SRTP_CONTEXT_SET_ENCRYPT_AUTHENTICATE - (attr_p->attr.srtp_context.selection_flags); - - /* get the tag only if we are version 9 */ - if (vtype == SDP_ATTR_SDESCRIPTIONS) { - attr_p->attr.srtp_context.tag = - sdp_getnextnumtok(ptr, &ptr, " \t", &result); - - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Could not find sdescriptions tag", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - - } - } - - /* get the crypto suite */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Could not find sdescriptions crypto suite", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (!sdp_parse_context_crypto_suite(tmp, attr_p, sdp_p)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Unsupported crypto suite", sdp_p->debug_str); - return (SDP_INVALID_PARAMETER); - } - - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Could not find sdescriptions key params", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (!sdp_parse_sdescriptions_key_param(tmp, attr_p, sdp_p)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Failed to parse key-params", sdp_p->debug_str); - return (SDP_INVALID_PARAMETER); - } - - /* if there are session parameters, scan the session parameters - * into tmp until we reach end of line. Currently the sdp parser - * does not parse session parameters but if they are present, - * we store them for the application. - */ - /*sa_ignore NO_NULL_CHK - *{ptr is valid since the pointer was checked earlier and the - * function would have exited if NULL.} - */ - while (*ptr && *ptr != '\n' && *ptr != '\r' && k < SDP_MAX_STRING_LEN) { - tmp[k++] = *ptr++; - } - - if ((k) && (k < SDP_MAX_STRING_LEN)) { - tmp[k] = 0; - attr_p->attr.srtp_context.session_parameters = cpr_strdup(tmp); - } - - return SDP_SUCCESS; - -} - -/* Parses crypto attribute based on the sdescriptions version - * 9 grammar. - * - */ - -sdp_result_e -sdp_parse_attr_sdescriptions (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - - return sdp_parse_attr_srtp(sdp_p, attr_p, ptr, - SDP_ATTR_SDESCRIPTIONS); - -} - -/* Parses X-crypto attribute based on the sdescriptions version - * 2 grammar. - * - */ - -sdp_result_e sdp_parse_attr_srtpcontext (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - - return sdp_parse_attr_srtp(sdp_p, attr_p, ptr, - SDP_ATTR_SRTP_CONTEXT); -} - - -sdp_result_e sdp_build_attr_ice_attr (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) { - flex_string_sprintf(fs, "a=%s\r\n", attr_p->attr.ice_attr); - - return SDP_SUCCESS; -} - - -sdp_result_e sdp_parse_attr_ice_attr (sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr) { - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), "\r\n", &result); - if (result != SDP_SUCCESS){ - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: problem parsing ice attribute ", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* We need the attr= here. This is pretty gross. */ - snprintf(attr_p->attr.ice_attr, sizeof(attr_p->attr.ice_attr), - "%s:%s", sdp_get_attr_name(attr_p->type), tmp); - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, %s", sdp_p->debug_str, sdp_get_attr_name(attr_p->type), tmp); - } - return (SDP_SUCCESS); -} - - -sdp_result_e sdp_parse_attr_fingerprint_attr (sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr) -{ - sdp_result_e result; - - ptr = sdp_getnextstrtok(ptr, attr_p->attr.string_val, sizeof(attr_p->attr.string_val), "\r\n", &result); - - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No string token found for %s attribute", - sdp_p->debug_str, sdp_get_attr_name(attr_p->type)); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed a=%s, %s", sdp_p->debug_str, - sdp_get_attr_name(attr_p->type), - attr_p->attr.string_val); - } - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_build_attr_rtcp_mux_attr (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs) { - flex_string_append(fs, "a=rtcp-mux\r\n"); - - return SDP_SUCCESS; -} - -sdp_result_e sdp_parse_attr_rtcp_mux_attr (sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr) { - attr_p->attr.boolean_val = TRUE; - - return (SDP_SUCCESS); -} diff --git a/libs/sipcc/core/sdp/sdp_attr_access.c b/libs/sipcc/core/sdp/sdp_attr_access.c deleted file mode 100644 index cda2e6b051..0000000000 --- a/libs/sipcc/core/sdp/sdp_attr_access.c +++ /dev/null @@ -1,11872 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "sdp_os_defs.h" -#include "sdp.h" -#include "sdp_private.h" -#include "CSFLog.h" - -//static const char* logTag = "sdp_attr_access"; - -/* Attribute access routines are all defined by the following parameters. - * - * sdp_ptr The SDP handle returned by sdp_init_description. - * level The level the attribute is defined. Can be either - * SDP_SESSION_LEVEL or 0-n specifying a media line level. - * inst_num The instance number of the attribute. Multiple instances - * of a particular attribute may exist at each level and so - * the inst_num determines the particular attribute at that - * level that should be accessed. Note that this is the - * instance number of the specified type of attribute, not the - * overall attribute number at the level. Also note that the - * instance number is 1-based. For example: - * v=0 - * o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4 - * s=SDP Seminar - * c=IN IP4 10.1.0.2 - * t=0 0 - * m=audio 1234 RTP/AVP 0 101 102 - * a=foo 1 - * a=foo 2 - * a=bar 1 # This is instance 1 of attribute bar. - * a=foo 3 # This is instance 3 of attribute foo. - * cap_num Almost all of the attributes may be defined as X-cpar - * parameters (with the exception of X-sqn, X-cap, and X-cpar). - * If the cap_num is set to zero, then the attribute is not - * an X-cpar parameter attribute. If the cap_num is any other - * value, it specifies the capability number that the X-cpar - * attribute is specified for. - */ - -/* Attribute handling: - * - * There are two basic types of attributes handled by the SDP library, - * those defined by a= token lines, and those embedded with a=X-cpar lines. - * The handling for each of these is described here. - * - * Simple (non X-cpar attributes): - * - * Attributes not embedded in a=X-cpar lines are referenced by level and - * instance number. For these attributes the capability number is always - * set to zero. - * - * An application will typically process these attributes in one of two ways. - * With the first method, the application can determine the total number - * of attributes defined at a given level and process them one at a time. - * For each attribute, the application will query the library to find out - * what type of attribute it is and which instance within that type. The - * application can then process this particular attribute referencing it - * by level and instance number. - * - * A second method of processing attributes is for applications to determine - * each type of attribute they are interested in, query the SDP library to - * find out how many of that type of attribute exist at a given level, and - * process each one at a time. - * - * X-cpar attribute processing: - * - * X-cpar attributes can contain embedded attributes. They are associated - * with X-cap attribute lines. An example of X-cap and X-cpar attributes - * found in an SDP is as follows: - * - * v=0 - * o=- 25678 753849 IN IP4 128.96.41.1 - * s=- - * t=0 0 - * c=IN IP4 10.1.0.2 - * m=audio 3456 RTP/AVP 18 96 - * a=rtpmap:96 telephone-event/8000 - * a=fmtp:96 0-15,32-35 - * a=X-sqn: 0 - * a=X-cap: 1 audio RTP/AVP 0 18 96 97 - * a=X-cpar: a=fmtp:96 0-16,32-35 - * a=X-cpar: a=rtpmap:97 X-NSE/8000 - * a=X-cpar: a=fmtp:97 195-197 - * a=X-cap: 5 image udptl t38 - * a=X-cap: 6 application udp X-tmr - * a=X-cap: 7 audio RTP/AVP 100 101 - * a=X-cpar: a=rtpmap:100 g.711/8000 - * a=X-cpar: a=rtpmap:101 g.729/8000 - * - * X-cap attributes can be defined at the SESSION_LEVEL or any media level. - * An X-cap attr is defined by the level and instance number just like - * other attributes. In the example above, X-cap attrs are defined at - * media level 1 and there are four instances at that level. - * - * The X-cpar attributes can also be referenced by level and instance number. - * However, the embedded attribute within an X-cpar attribute must be - * referenced by level, instance number, and capability number. This is - * because the X-cpar attribute is associated with a particular X-cap/ - * capability. - * For all attributes that are not embedded within an X-cpar attribute, the - * cap_num should be referenced as zero. But for X-cpar attributes, the - * cap_num is specified to be one of the capability numbers of the previous - * X-cap line. The number of capabilities specified in an X-cap line is - * equal to the number of payloads. Thus, in this example, the first X-cap - * attr instance specifies capabilities 1-4, the second specifies capability - * 5, the third capability 6, and the fourth capabilities 7-8. - * - * X-cpar attributes can be processed with methods similar to the two - * previously mentioned. For each X-cap attribute, the application can - * use one of two methods to process the X-cpar attributes. First, it - * can query the total number of X-cpar attributes associated with a - * given X-cap attribute. The X-cap attribute is here defined by a level - * and a capability number. In the example above, the total number of - * attributes defined is as follows: - * level 1, cap_num 1 - total attrs: 3 - * level 1, cap_num 5 - total attrs: 0 - * level 1, cap_num 6 - total attrs: 0 - * level 1, cap_num 7 - total attrs: 2 - * - * Note that if the application queried the number of attributes for - * cap_num 2, 3, or 4, it would also return 3 attrs, and for cap_num - * 8 the library would return 2. - * - * Once the application determines the total number of attributes for - * that capability, it can again query the embedded attribute type and - * instance. For example, sdp_get_attr_type would return the following: - * level 1, cap_num 1, attr 1 -> attr type fmtp, instance 1 - * level 1, cap_num 1, attr 2 -> attr type rtpmap, instance 1 - * level 1, cap_num 1, attr 3 -> attr type fmtp, instance 2 - * level 1, cap_num 7, attr 1 -> attr type rtpmap, instance 1 - * level 1, cap_num 7, attr 2 -> attr type rtpmap, instance 2 - * - * The individual embedded attributes can then be accessed by level, - * cap_num, and instance number. - * - * With the second method for handling X-cpar attributes, the application - * determines the types of attributes it is interested in. It can then - * query the SDP library to determine the number of attributes of that - * type found for that level and cap_num, and then process each one at - * a time. e.g., calling sdp_attr_num_instances would give: - * level 1, cap_num 1, attr_type fmtp -> two instances - * level 1, cap_num 1, attr_type rtpmap -> one instance - * level 1, cap_num 7, attr_type fmtp -> zero instances - * level 1, cap_num 7, attr_type rtpmap -> two instances - */ - - -/* Function: sdp_add_new_attr - * Description: Add a new attribute of the specified type at the given - * level and capability level or base attribute if cap_num - * is zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * attr_type The type of attribute to add. - * inst_num Pointer to a u16 in which to return the instance - * number of the newly added attribute. - * Returns: SDP_SUCCESS Attribute was added successfully. - * SDP_NO_RESOURCE No memory avail for new attribute. - * SDP_INVALID_PARAMETER Specified media line is not defined. - */ -sdp_result_e sdp_add_new_attr (void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e attr_type, u16 *inst_num) -{ - u16 i; - sdp_mca_t *mca_p; - sdp_mca_t *cap_p; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_attr_t *new_attr_p; - sdp_attr_t *prev_attr_p=NULL; - sdp_fmtp_t *fmtp_p; - sdp_comediadir_t *comediadir_p; - - *inst_num = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if ((cap_num != 0) && - ((attr_type == SDP_ATTR_X_CAP) || (attr_type == SDP_ATTR_X_CPAR) || - (attr_type == SDP_ATTR_X_SQN) || (attr_type == SDP_ATTR_CDSC) || - (attr_type == SDP_ATTR_CPAR) || (attr_type == SDP_ATTR_SQN))) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid attribute type for X-cpar/cdsc " - "parameter.", sdp_p->debug_str); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Some attributes are valid only under media level */ - if (level == SDP_SESSION_LEVEL) { - switch (attr_type) { - case SDP_ATTR_RTCP: - case SDP_ATTR_LABEL: - return (SDP_INVALID_MEDIA_LEVEL); - - default: - break; - } - } - - new_attr_p = (sdp_attr_t *)SDP_MALLOC(sizeof(sdp_attr_t)); - if (new_attr_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - - new_attr_p->type = attr_type; - new_attr_p->next_p = NULL; - - /* Initialize the new attribute structure */ - if ((new_attr_p->type == SDP_ATTR_X_CAP) || - (new_attr_p->type == SDP_ATTR_CDSC)) { - new_attr_p->attr.cap_p = (sdp_mca_t *)SDP_MALLOC(sizeof(sdp_mca_t)); - if (new_attr_p->attr.cap_p == NULL) { - sdp_free_attr(new_attr_p); - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - } else if (new_attr_p->type == SDP_ATTR_FMTP) { - fmtp_p = &(new_attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_UNKNOWN_TYPE; - // set to invalid value - fmtp_p->packetization_mode = 0xff; - fmtp_p->level_asymmetry_allowed = SDP_INVALID_LEVEL_ASYMMETRY_ALLOWED_VALUE; - fmtp_p->annexb_required = FALSE; - fmtp_p->annexa_required = FALSE; - fmtp_p->maxval = 0; - fmtp_p->bitrate = 0; - fmtp_p->cif = 0; - fmtp_p->qcif = 0; - fmtp_p->profile = SDP_INVALID_VALUE; - fmtp_p->level = SDP_INVALID_VALUE; - fmtp_p->parameter_add = TRUE; - for (i=0; i < SDP_NE_NUM_BMAP_WORDS; i++) { - fmtp_p->bmap[i] = 0; - } - } else if ((new_attr_p->type == SDP_ATTR_RTPMAP) || - (new_attr_p->type == SDP_ATTR_SPRTMAP)) { - new_attr_p->attr.transport_map.num_chan = 1; - } else if (new_attr_p->type == SDP_ATTR_DIRECTION) { - comediadir_p = &(new_attr_p->attr.comediadir); - comediadir_p->role = SDP_MEDIADIR_ROLE_PASSIVE; - comediadir_p->conn_info_present = FALSE; - } else if (new_attr_p->type == SDP_ATTR_MPTIME) { - sdp_mptime_t *mptime = &(new_attr_p->attr.mptime); - mptime->num_intervals = 0; - } - - if (cap_num == 0) { - /* Add a new attribute. */ - if (level == SDP_SESSION_LEVEL) { - if (sdp_p->sess_attrs_p == NULL) { - sdp_p->sess_attrs_p = new_attr_p; - } else { - for (attr_p = sdp_p->sess_attrs_p; - attr_p != NULL; - prev_attr_p = attr_p, attr_p = attr_p->next_p) { - /* Count the num instances of this type. */ - if (attr_p->type == attr_type) { - (*inst_num)++; - } - } - prev_attr_p->next_p = new_attr_p; - } - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_free_attr(new_attr_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (mca_p->media_attrs_p == NULL) { - mca_p->media_attrs_p = new_attr_p; - } else { - for (attr_p = mca_p->media_attrs_p; - attr_p != NULL; - prev_attr_p = attr_p, attr_p = attr_p->next_p) { - /* Count the num instances of this type. */ - if (attr_p->type == attr_type) { - (*inst_num)++; - } - } - prev_attr_p->next_p = new_attr_p; - } - } - } else { - /* Add a new capability attribute - find the capability attr. */ - attr_p = sdp_find_capability(sdp_p, level, cap_num); - if (attr_p == NULL) { - sdp_free_attr(new_attr_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - cap_p = attr_p->attr.cap_p; - if (cap_p->media_attrs_p == NULL) { - cap_p->media_attrs_p = new_attr_p; - } else { - for (attr_p = cap_p->media_attrs_p; - attr_p != NULL; - prev_attr_p = attr_p, attr_p = attr_p->next_p) { - /* Count the num instances of this type. */ - if (attr_p->type == attr_type) { - (*inst_num)++; - } - } - prev_attr_p->next_p = new_attr_p; - } - } - - /* Increment the instance num for the attr just added. */ - (*inst_num)++; - return (SDP_SUCCESS); -} - -/* Function: sdp_copy_attr_fields - * Description: Copy the fields of an attribute based on attr type. - * This is an INTERNAL SDP routine only. It will not copy - * X-Cap, X-Cpar, CDSC, or CPAR attrs. - * Parameters: src_attr_p Ptr to the source attribute. - * dst_attr_p Ptr to the dst attribute. - * Returns: Nothing. - */ -void sdp_copy_attr_fields (sdp_attr_t *src_attr_p, sdp_attr_t *dst_attr_p) -{ - u16 i; - - /* Copy over all the attribute information. */ - dst_attr_p->type = src_attr_p->type; - dst_attr_p->next_p = NULL; - - switch (src_attr_p->type) { - - case SDP_ATTR_BEARER: - case SDP_ATTR_CALLED: - case SDP_ATTR_CONN_TYPE: - case SDP_ATTR_DIALED: - case SDP_ATTR_DIALING: - case SDP_ATTR_FRAMING: - case SDP_ATTR_MAXPRATE: - case SDP_ATTR_LABEL: - sstrncpy(dst_attr_p->attr.string_val, src_attr_p->attr.string_val, - SDP_MAX_STRING_LEN+1); - break; - - case SDP_ATTR_EECID: - case SDP_ATTR_PTIME: - case SDP_ATTR_T38_VERSION: - case SDP_ATTR_T38_MAXBITRATE: - case SDP_ATTR_T38_MAXBUFFER: - case SDP_ATTR_T38_MAXDGRAM: - case SDP_ATTR_X_SQN: - case SDP_ATTR_TC1_PAYLOAD_BYTES: - case SDP_ATTR_TC1_WINDOW_SIZE: - case SDP_ATTR_TC2_PAYLOAD_BYTES: - case SDP_ATTR_TC2_WINDOW_SIZE: - case SDP_ATTR_RTCP: - case SDP_ATTR_MID: - case SDP_ATTR_RTCP_UNICAST: - dst_attr_p->attr.u32_val = src_attr_p->attr.u32_val; - break; - - case SDP_ATTR_T38_FILLBITREMOVAL: - case SDP_ATTR_T38_TRANSCODINGMMR: - case SDP_ATTR_T38_TRANSCODINGJBIG: - case SDP_ATTR_TMRGWXID: - dst_attr_p->attr.boolean_val = src_attr_p->attr.boolean_val; - break; - - case SDP_ATTR_QOS: - case SDP_ATTR_SECURE: - case SDP_ATTR_X_PC_QOS: - case SDP_ATTR_X_QOS: - dst_attr_p->attr.qos.strength = src_attr_p->attr.qos.strength; - dst_attr_p->attr.qos.direction = src_attr_p->attr.qos.direction; - dst_attr_p->attr.qos.confirm = src_attr_p->attr.qos.confirm; - break; - - case SDP_ATTR_CURR: - dst_attr_p->attr.curr.type = src_attr_p->attr.curr.type; - dst_attr_p->attr.curr.direction = src_attr_p->attr.curr.direction; - dst_attr_p->attr.curr.status_type = src_attr_p->attr.curr.status_type; - break; - case SDP_ATTR_DES: - dst_attr_p->attr.des.type = src_attr_p->attr.des.type; - dst_attr_p->attr.des.direction = src_attr_p->attr.des.direction; - dst_attr_p->attr.des.status_type = src_attr_p->attr.des.status_type; - dst_attr_p->attr.des.strength = src_attr_p->attr.des.strength; - break; - - - case SDP_ATTR_CONF: - dst_attr_p->attr.conf.type = src_attr_p->attr.conf.type; - dst_attr_p->attr.conf.direction = src_attr_p->attr.conf.direction; - dst_attr_p->attr.conf.status_type = src_attr_p->attr.conf.status_type; - break; - - case SDP_ATTR_INACTIVE: - case SDP_ATTR_RECVONLY: - case SDP_ATTR_SENDONLY: - case SDP_ATTR_SENDRECV: - /* These attrs have no parameters. */ - break; - - case SDP_ATTR_FMTP: - dst_attr_p->attr.fmtp.payload_num = src_attr_p->attr.fmtp.payload_num; - dst_attr_p->attr.fmtp.maxval = src_attr_p->attr.fmtp.maxval; - dst_attr_p->attr.fmtp.bitrate = src_attr_p->attr.fmtp.bitrate; - dst_attr_p->attr.fmtp.annexa = src_attr_p->attr.fmtp.annexa; - dst_attr_p->attr.fmtp.annexb = src_attr_p->attr.fmtp.annexb; - dst_attr_p->attr.fmtp.qcif = src_attr_p->attr.fmtp.qcif; - dst_attr_p->attr.fmtp.cif = src_attr_p->attr.fmtp.cif; - dst_attr_p->attr.fmtp.sqcif = src_attr_p->attr.fmtp.sqcif; - dst_attr_p->attr.fmtp.cif4 = src_attr_p->attr.fmtp.cif4; - dst_attr_p->attr.fmtp.cif16 = src_attr_p->attr.fmtp.cif16; - dst_attr_p->attr.fmtp.maxbr = src_attr_p->attr.fmtp.maxbr; - dst_attr_p->attr.fmtp.custom_x = src_attr_p->attr.fmtp.custom_x; - dst_attr_p->attr.fmtp.custom_y = src_attr_p->attr.fmtp.custom_y; - dst_attr_p->attr.fmtp.custom_mpi = src_attr_p->attr.fmtp.custom_mpi; - dst_attr_p->attr.fmtp.par_width = src_attr_p->attr.fmtp.par_width; - dst_attr_p->attr.fmtp.par_height = src_attr_p->attr.fmtp.par_height; - dst_attr_p->attr.fmtp.cpcf = src_attr_p->attr.fmtp.cpcf; - dst_attr_p->attr.fmtp.bpp = src_attr_p->attr.fmtp.bpp; - dst_attr_p->attr.fmtp.hrd = src_attr_p->attr.fmtp.hrd; - - dst_attr_p->attr.fmtp.profile = src_attr_p->attr.fmtp.profile; - dst_attr_p->attr.fmtp.level = src_attr_p->attr.fmtp.level; - dst_attr_p->attr.fmtp.is_interlace = src_attr_p->attr.fmtp.is_interlace; - - sstrncpy(dst_attr_p->attr.fmtp.profile_level_id, - src_attr_p->attr.fmtp.profile_level_id, - SDP_MAX_STRING_LEN+1); - sstrncpy(dst_attr_p->attr.fmtp.parameter_sets, - src_attr_p->attr.fmtp.parameter_sets, - SDP_MAX_STRING_LEN+1); - dst_attr_p->attr.fmtp.deint_buf_req = - src_attr_p->attr.fmtp.deint_buf_req; - dst_attr_p->attr.fmtp.max_don_diff = - src_attr_p->attr.fmtp.max_don_diff; - dst_attr_p->attr.fmtp.init_buf_time = - src_attr_p->attr.fmtp.init_buf_time; - dst_attr_p->attr.fmtp.packetization_mode = - src_attr_p->attr.fmtp.packetization_mode; - dst_attr_p->attr.fmtp.flag = - src_attr_p->attr.fmtp.flag; - - dst_attr_p->attr.fmtp.max_mbps = src_attr_p->attr.fmtp.max_mbps; - dst_attr_p->attr.fmtp.max_fs = src_attr_p->attr.fmtp.max_fs; - dst_attr_p->attr.fmtp.max_cpb = src_attr_p->attr.fmtp.max_cpb; - dst_attr_p->attr.fmtp.max_dpb = src_attr_p->attr.fmtp.max_dpb; - dst_attr_p->attr.fmtp.max_br = src_attr_p->attr.fmtp.max_br; - dst_attr_p->attr.fmtp.redundant_pic_cap = - src_attr_p->attr.fmtp.redundant_pic_cap; - dst_attr_p->attr.fmtp.deint_buf_cap = - src_attr_p->attr.fmtp.deint_buf_cap; - dst_attr_p->attr.fmtp.max_rcmd_nalu_size = - src_attr_p->attr.fmtp.max_rcmd_nalu_size; - dst_attr_p->attr.fmtp.interleaving_depth = - src_attr_p->attr.fmtp.interleaving_depth; - dst_attr_p->attr.fmtp.parameter_add = - src_attr_p->attr.fmtp.parameter_add; - - dst_attr_p->attr.fmtp.annex_d = src_attr_p->attr.fmtp.annex_d; - dst_attr_p->attr.fmtp.annex_f = src_attr_p->attr.fmtp.annex_f; - dst_attr_p->attr.fmtp.annex_i = src_attr_p->attr.fmtp.annex_i; - dst_attr_p->attr.fmtp.annex_j = src_attr_p->attr.fmtp.annex_j; - dst_attr_p->attr.fmtp.annex_t = src_attr_p->attr.fmtp.annex_t; - dst_attr_p->attr.fmtp.annex_k_val = src_attr_p->attr.fmtp.annex_k_val; - dst_attr_p->attr.fmtp.annex_n_val = src_attr_p->attr.fmtp.annex_n_val; - dst_attr_p->attr.fmtp.annex_p_val_picture_resize = - src_attr_p->attr.fmtp.annex_p_val_picture_resize; - dst_attr_p->attr.fmtp.annex_p_val_warp = - src_attr_p->attr.fmtp.annex_p_val_warp; - - dst_attr_p->attr.fmtp.annexb_required = - src_attr_p->attr.fmtp.annexb_required; - dst_attr_p->attr.fmtp.annexa_required = - src_attr_p->attr.fmtp.annexa_required; - dst_attr_p->attr.fmtp.fmtp_format - = src_attr_p->attr.fmtp.fmtp_format; - - for (i=0; i < SDP_NE_NUM_BMAP_WORDS; i++) { - dst_attr_p->attr.fmtp.bmap[i] = src_attr_p->attr.fmtp.bmap[i]; - } - break; - - case SDP_ATTR_RTPMAP: - dst_attr_p->attr.transport_map.payload_num = - src_attr_p->attr.transport_map.payload_num; - dst_attr_p->attr.transport_map.clockrate = - src_attr_p->attr.transport_map.clockrate; - dst_attr_p->attr.transport_map.num_chan = - src_attr_p->attr.transport_map.num_chan; - sstrncpy(dst_attr_p->attr.transport_map.encname, - src_attr_p->attr.transport_map.encname, - SDP_MAX_STRING_LEN+1); - break; - - case SDP_ATTR_SUBNET: - dst_attr_p->attr.subnet.nettype = src_attr_p->attr.subnet.nettype; - dst_attr_p->attr.subnet.addrtype = src_attr_p->attr.subnet.addrtype; - dst_attr_p->attr.subnet.prefix = src_attr_p->attr.subnet.prefix; - sstrncpy(dst_attr_p->attr.subnet.addr, src_attr_p->attr.subnet.addr, - SDP_MAX_STRING_LEN+1); - break; - - case SDP_ATTR_T38_RATEMGMT: - dst_attr_p->attr.t38ratemgmt = src_attr_p->attr.t38ratemgmt; - break; - - case SDP_ATTR_T38_UDPEC: - dst_attr_p->attr.t38udpec = src_attr_p->attr.t38udpec; - break; - - case SDP_ATTR_X_PC_CODEC: - dst_attr_p->attr.pccodec.num_payloads = - src_attr_p->attr.pccodec.num_payloads; - for (i=0; i < src_attr_p->attr.pccodec.num_payloads; i++) { - dst_attr_p->attr.pccodec.payload_type[i] = - src_attr_p->attr.pccodec.payload_type[i]; - } - break; - - case SDP_ATTR_DIRECTION: - - dst_attr_p->attr.comediadir.role = - src_attr_p->attr.comediadir.role; - - if (src_attr_p->attr.comediadir.conn_info.nettype) { - dst_attr_p->attr.comediadir.conn_info_present = TRUE; - dst_attr_p->attr.comediadir.conn_info.nettype = - src_attr_p->attr.comediadir.conn_info.nettype; - dst_attr_p->attr.comediadir.conn_info.addrtype = - src_attr_p->attr.comediadir.conn_info.addrtype; - sstrncpy(dst_attr_p->attr.comediadir.conn_info.conn_addr, - src_attr_p->attr.comediadir.conn_info.conn_addr, - SDP_MAX_STRING_LEN+1); - dst_attr_p->attr.comediadir.src_port = - src_attr_p->attr.comediadir.src_port; - } - break; - - case SDP_ATTR_SILENCESUPP: - dst_attr_p->attr.silencesupp.enabled = - src_attr_p->attr.silencesupp.enabled; - dst_attr_p->attr.silencesupp.timer_null = - src_attr_p->attr.silencesupp.timer_null; - dst_attr_p->attr.silencesupp.timer = - src_attr_p->attr.silencesupp.timer; - dst_attr_p->attr.silencesupp.pref = - src_attr_p->attr.silencesupp.pref; - dst_attr_p->attr.silencesupp.siduse = - src_attr_p->attr.silencesupp.siduse; - dst_attr_p->attr.silencesupp.fxnslevel_null = - src_attr_p->attr.silencesupp.fxnslevel_null; - dst_attr_p->attr.silencesupp.fxnslevel = - src_attr_p->attr.silencesupp.fxnslevel; - break; - - case SDP_ATTR_RTR: - dst_attr_p->attr.rtr.confirm = src_attr_p->attr.rtr.confirm; - break; - - case SDP_ATTR_X_SIDIN: - case SDP_ATTR_X_SIDOUT: - case SDP_ATTR_X_CONFID: - sstrncpy(dst_attr_p->attr.stream_data.x_sidin, - src_attr_p->attr.stream_data.x_sidin,SDP_MAX_STRING_LEN+1); - sstrncpy(dst_attr_p->attr.stream_data.x_sidout, - src_attr_p->attr.stream_data.x_sidout,SDP_MAX_STRING_LEN+1); - sstrncpy(dst_attr_p->attr.stream_data.x_confid, - src_attr_p->attr.stream_data.x_confid,SDP_MAX_STRING_LEN+1); - break; - - case SDP_ATTR_GROUP: - dst_attr_p->attr.stream_data.group_attr = - src_attr_p->attr.stream_data.group_attr; - dst_attr_p->attr.stream_data.num_group_id = - src_attr_p->attr.stream_data.num_group_id; - - for (i=0; i < src_attr_p->attr.stream_data.num_group_id; i++) { - dst_attr_p->attr.stream_data.group_id_arr[i] = - src_attr_p->attr.stream_data.group_id_arr[i]; - } - break; - - case SDP_ATTR_SOURCE_FILTER: - dst_attr_p->attr.source_filter.mode = - src_attr_p->attr.source_filter.mode; - dst_attr_p->attr.source_filter.nettype = - src_attr_p->attr.source_filter.nettype; - dst_attr_p->attr.source_filter.addrtype = - src_attr_p->attr.source_filter.addrtype; - sstrncpy(dst_attr_p->attr.source_filter.dest_addr, - src_attr_p->attr.source_filter.dest_addr, - SDP_MAX_STRING_LEN+1); - for (i=0; iattr.source_filter.num_src_addr; ++i) { - sstrncpy(dst_attr_p->attr.source_filter.src_list[i], - src_attr_p->attr.source_filter.src_list[i], - SDP_MAX_STRING_LEN+1); - } - dst_attr_p->attr.source_filter.num_src_addr = - src_attr_p->attr.source_filter.num_src_addr; - break; - - case SDP_ATTR_SRTP_CONTEXT: - case SDP_ATTR_SDESCRIPTIONS: - /* Tag parameter is not valid for version 2 sdescriptions */ - if (src_attr_p->type == SDP_ATTR_SDESCRIPTIONS) { - dst_attr_p->attr.srtp_context.tag = - src_attr_p->attr.srtp_context.tag; - } - - dst_attr_p->attr.srtp_context.selection_flags = - src_attr_p->attr.srtp_context.selection_flags; - - dst_attr_p->attr.srtp_context.suite = src_attr_p->attr.srtp_context.suite; - - dst_attr_p->attr.srtp_context.master_key_size_bytes = - src_attr_p->attr.srtp_context.master_key_size_bytes; - - dst_attr_p->attr.srtp_context.master_salt_size_bytes = - src_attr_p->attr.srtp_context.master_salt_size_bytes; - - bcopy(src_attr_p->attr.srtp_context.master_key, - dst_attr_p->attr.srtp_context.master_key, - SDP_SRTP_MAX_KEY_SIZE_BYTES); - - bcopy(src_attr_p->attr.srtp_context.master_salt, - dst_attr_p->attr.srtp_context.master_salt, - SDP_SRTP_MAX_SALT_SIZE_BYTES); - - - sstrncpy((char*)dst_attr_p->attr.srtp_context.master_key_lifetime, - (char*)src_attr_p->attr.srtp_context.master_key_lifetime, - SDP_SRTP_MAX_LIFETIME_BYTES); - - sstrncpy((char*)dst_attr_p->attr.srtp_context.mki, - (char*)src_attr_p->attr.srtp_context.mki, - SDP_SRTP_MAX_MKI_SIZE_BYTES); - - dst_attr_p->attr.srtp_context.mki_size_bytes = - src_attr_p->attr.srtp_context.mki_size_bytes; - - if (src_attr_p->attr.srtp_context.session_parameters) { - dst_attr_p->attr.srtp_context.session_parameters = - cpr_strdup(src_attr_p->attr.srtp_context.session_parameters); - } - - break; - - default: - break; - } - - return; -} - -/* Function: sdp_copy_attr - * Description: Copy an attribute from one SDP/level to another. A new - * attribute is automatically added to the end of the attr - * list at the dst SDP/level and all parameter values are - * copied. - * Description: Add a new attribute of the specified type at the given - * level and capability level or base attribute if cap_num - * is zero. - * Parameters: src_sdp_ptr The source SDP handle. - * dst_sdp_ptr The dest SDP handle. - * src_level The level of the source attribute. - * dst_level The level of the source attribute. - * src_cap_num The src capability number associated with the - * attribute if any. - * dst_cap_num The dst capability number associated with the - * attribute if any. Note that src and dst - * cap_num must both be zero or both be non-zero. - * src_attr_type The type of source attribute. This cannot - * be SDP_ATTR_X_CAP or SDP_ATTR_X_CPAR. - * src_inst_num The instance number of the source attr. - * Returns: SDP_SUCCESS Attribute was successfully copied. - */ -sdp_result_e sdp_copy_attr (void *src_sdp_ptr, void *dst_sdp_ptr, - u16 src_level, u16 dst_level, - u8 src_cap_num, u8 dst_cap_num, - sdp_attr_e src_attr_type, u16 src_inst_num) -{ - u16 i; - sdp_mca_t *mca_p; - sdp_mca_t *cap_p; - sdp_t *src_sdp_p = (sdp_t *)src_sdp_ptr; - sdp_t *dst_sdp_p = (sdp_t *)dst_sdp_ptr; - sdp_attr_t *attr_p; - sdp_attr_t *new_attr_p; - sdp_attr_t *prev_attr_p; - sdp_attr_t *src_attr_p; - - if (sdp_verify_sdp_ptr(src_sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - /* Make sure if one is a capability attribute, then both are. */ - if (((src_cap_num == 0) && (dst_cap_num != 0)) || - ((src_cap_num != 0) && (dst_cap_num == 0))) { - src_sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Cannot copy X_CAP/CDSC attributes directly using this routine. - * You also can't copy X_CPAR/CPAR attributes by specifying them directly, - * but you can copy them by giving the corresponding cap_num. */ - if ((src_attr_type == SDP_ATTR_X_CAP) || - (src_attr_type == SDP_ATTR_X_CPAR) || - (src_attr_type == SDP_ATTR_CDSC) || - (src_attr_type == SDP_ATTR_CPAR)) { - src_sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - src_attr_p = sdp_find_attr(src_sdp_p, src_level, src_cap_num, - src_attr_type, src_inst_num); - if (src_attr_p == NULL) { - if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Error: Source attribute for copy not found.", - src_sdp_p->debug_str); - } - src_sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - new_attr_p = (sdp_attr_t *)SDP_MALLOC(sizeof(sdp_attr_t)); - if (new_attr_p == NULL) { - src_sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - - /* Copy over all the attribute information. */ - new_attr_p->type = src_attr_type; - new_attr_p->next_p = NULL; - - switch (src_attr_type) { - - case SDP_ATTR_BEARER: - case SDP_ATTR_CALLED: - case SDP_ATTR_CONN_TYPE: - case SDP_ATTR_DIALED: - case SDP_ATTR_DIALING: - case SDP_ATTR_FRAMING: - case SDP_ATTR_MAXPRATE: - case SDP_ATTR_LABEL: - sstrncpy(new_attr_p->attr.string_val, src_attr_p->attr.string_val, - SDP_MAX_STRING_LEN+1); - break; - - case SDP_ATTR_EECID: - case SDP_ATTR_PTIME: - case SDP_ATTR_T38_VERSION: - case SDP_ATTR_T38_MAXBITRATE: - case SDP_ATTR_T38_MAXBUFFER: - case SDP_ATTR_T38_MAXDGRAM: - case SDP_ATTR_X_SQN: - case SDP_ATTR_TC1_PAYLOAD_BYTES: - case SDP_ATTR_TC1_WINDOW_SIZE: - case SDP_ATTR_TC2_PAYLOAD_BYTES: - case SDP_ATTR_TC2_WINDOW_SIZE: - case SDP_ATTR_RTCP: - case SDP_ATTR_MID: - case SDP_ATTR_RTCP_UNICAST: - new_attr_p->attr.u32_val = src_attr_p->attr.u32_val; - break; - - case SDP_ATTR_T38_FILLBITREMOVAL: - case SDP_ATTR_T38_TRANSCODINGMMR: - case SDP_ATTR_T38_TRANSCODINGJBIG: - case SDP_ATTR_TMRGWXID: - new_attr_p->attr.boolean_val = src_attr_p->attr.boolean_val; - break; - - case SDP_ATTR_QOS: - case SDP_ATTR_SECURE: - case SDP_ATTR_X_PC_QOS: - case SDP_ATTR_X_QOS: - new_attr_p->attr.qos.strength = src_attr_p->attr.qos.strength; - new_attr_p->attr.qos.direction = src_attr_p->attr.qos.direction; - new_attr_p->attr.qos.confirm = src_attr_p->attr.qos.confirm; - break; - - case SDP_ATTR_CURR: - new_attr_p->attr.curr.type = src_attr_p->attr.curr.type; - new_attr_p->attr.curr.direction = src_attr_p->attr.curr.direction; - new_attr_p->attr.curr.status_type = src_attr_p->attr.curr.status_type; - break; - case SDP_ATTR_DES: - new_attr_p->attr.des.type = src_attr_p->attr.des.type; - new_attr_p->attr.des.direction = src_attr_p->attr.des.direction; - new_attr_p->attr.des.status_type = src_attr_p->attr.des.status_type; - new_attr_p->attr.des.strength = src_attr_p->attr.des.strength; - break; - - case SDP_ATTR_CONF: - new_attr_p->attr.conf.type = src_attr_p->attr.conf.type; - new_attr_p->attr.conf.direction = src_attr_p->attr.conf.direction; - new_attr_p->attr.conf.status_type = src_attr_p->attr.conf.status_type; - break; - - case SDP_ATTR_INACTIVE: - case SDP_ATTR_RECVONLY: - case SDP_ATTR_SENDONLY: - case SDP_ATTR_SENDRECV: - /* These attrs have no parameters. */ - break; - - case SDP_ATTR_FMTP: - new_attr_p->attr.fmtp.payload_num = src_attr_p->attr.fmtp.payload_num; - new_attr_p->attr.fmtp.maxval = src_attr_p->attr.fmtp.maxval; - new_attr_p->attr.fmtp.bitrate = src_attr_p->attr.fmtp.bitrate; - new_attr_p->attr.fmtp.annexa = src_attr_p->attr.fmtp.annexa; - new_attr_p->attr.fmtp.annexb = src_attr_p->attr.fmtp.annexb; - new_attr_p->attr.fmtp.cif = src_attr_p->attr.fmtp.cif; - new_attr_p->attr.fmtp.qcif = src_attr_p->attr.fmtp.qcif; - new_attr_p->attr.fmtp.sqcif = src_attr_p->attr.fmtp.qcif; - new_attr_p->attr.fmtp.cif4 = src_attr_p->attr.fmtp.cif4; - new_attr_p->attr.fmtp.cif16 = src_attr_p->attr.fmtp.cif16; - new_attr_p->attr.fmtp.maxbr = src_attr_p->attr.fmtp.maxbr; - new_attr_p->attr.fmtp.custom_x = src_attr_p->attr.fmtp.custom_x; - new_attr_p->attr.fmtp.custom_y = src_attr_p->attr.fmtp.custom_y; - new_attr_p->attr.fmtp.custom_mpi = src_attr_p->attr.fmtp.custom_mpi; - new_attr_p->attr.fmtp.par_width = src_attr_p->attr.fmtp.par_width; - new_attr_p->attr.fmtp.par_height = src_attr_p->attr.fmtp.par_height; - new_attr_p->attr.fmtp.cpcf = src_attr_p->attr.fmtp.cpcf; - new_attr_p->attr.fmtp.bpp = src_attr_p->attr.fmtp.bpp; - new_attr_p->attr.fmtp.hrd = src_attr_p->attr.fmtp.hrd; - new_attr_p->attr.fmtp.profile = src_attr_p->attr.fmtp.profile; - new_attr_p->attr.fmtp.level = src_attr_p->attr.fmtp.level; - new_attr_p->attr.fmtp.is_interlace = src_attr_p->attr.fmtp.is_interlace; - - sstrncpy(new_attr_p->attr.fmtp.profile_level_id, - src_attr_p->attr.fmtp.profile_level_id, - SDP_MAX_STRING_LEN+1); - sstrncpy(new_attr_p->attr.fmtp.parameter_sets, - src_attr_p->attr.fmtp.parameter_sets, - SDP_MAX_STRING_LEN+1); - new_attr_p->attr.fmtp.deint_buf_req = - src_attr_p->attr.fmtp.deint_buf_req; - new_attr_p->attr.fmtp.max_don_diff = - src_attr_p->attr.fmtp.max_don_diff; - new_attr_p->attr.fmtp.init_buf_time = - src_attr_p->attr.fmtp.init_buf_time; - new_attr_p->attr.fmtp.packetization_mode = - src_attr_p->attr.fmtp.packetization_mode; - new_attr_p->attr.fmtp.flag = - src_attr_p->attr.fmtp.flag; - - new_attr_p->attr.fmtp.max_mbps = src_attr_p->attr.fmtp.max_mbps; - new_attr_p->attr.fmtp.max_fs = src_attr_p->attr.fmtp.max_fs; - new_attr_p->attr.fmtp.max_cpb = src_attr_p->attr.fmtp.max_cpb; - new_attr_p->attr.fmtp.max_dpb = src_attr_p->attr.fmtp.max_dpb; - new_attr_p->attr.fmtp.max_br = src_attr_p->attr.fmtp.max_br; - new_attr_p->attr.fmtp.redundant_pic_cap = - src_attr_p->attr.fmtp.redundant_pic_cap; - new_attr_p->attr.fmtp.deint_buf_cap = - src_attr_p->attr.fmtp.deint_buf_cap; - new_attr_p->attr.fmtp.max_rcmd_nalu_size = - src_attr_p->attr.fmtp.max_rcmd_nalu_size; - new_attr_p->attr.fmtp.interleaving_depth = - src_attr_p->attr.fmtp.interleaving_depth; - new_attr_p->attr.fmtp.parameter_add = - src_attr_p->attr.fmtp.parameter_add; - - new_attr_p->attr.fmtp.annex_d = src_attr_p->attr.fmtp.annex_d; - new_attr_p->attr.fmtp.annex_f = src_attr_p->attr.fmtp.annex_f; - new_attr_p->attr.fmtp.annex_i = src_attr_p->attr.fmtp.annex_i; - new_attr_p->attr.fmtp.annex_j = src_attr_p->attr.fmtp.annex_j; - new_attr_p->attr.fmtp.annex_t = src_attr_p->attr.fmtp.annex_t; - new_attr_p->attr.fmtp.annex_k_val = src_attr_p->attr.fmtp.annex_k_val; - new_attr_p->attr.fmtp.annex_n_val = src_attr_p->attr.fmtp.annex_n_val; - new_attr_p->attr.fmtp.annex_p_val_picture_resize = - src_attr_p->attr.fmtp.annex_p_val_picture_resize; - new_attr_p->attr.fmtp.annex_p_val_warp = - src_attr_p->attr.fmtp.annex_p_val_warp; - - new_attr_p->attr.fmtp.annexb_required = - src_attr_p->attr.fmtp.annexb_required; - new_attr_p->attr.fmtp.annexa_required = - src_attr_p->attr.fmtp.annexa_required; - new_attr_p->attr.fmtp.fmtp_format - = src_attr_p->attr.fmtp.fmtp_format; - - for (i=0; i < SDP_NE_NUM_BMAP_WORDS; i++) { - new_attr_p->attr.fmtp.bmap[i] = src_attr_p->attr.fmtp.bmap[i]; - } - break; - - case SDP_ATTR_RTPMAP: - new_attr_p->attr.transport_map.payload_num = - src_attr_p->attr.transport_map.payload_num; - new_attr_p->attr.transport_map.clockrate = - src_attr_p->attr.transport_map.clockrate; - new_attr_p->attr.transport_map.num_chan = - src_attr_p->attr.transport_map.num_chan; - sstrncpy(new_attr_p->attr.transport_map.encname, - src_attr_p->attr.transport_map.encname, - SDP_MAX_STRING_LEN+1); - break; - - case SDP_ATTR_SUBNET: - new_attr_p->attr.subnet.nettype = src_attr_p->attr.subnet.nettype; - new_attr_p->attr.subnet.addrtype = src_attr_p->attr.subnet.addrtype; - new_attr_p->attr.subnet.prefix = src_attr_p->attr.subnet.prefix; - sstrncpy(new_attr_p->attr.subnet.addr, src_attr_p->attr.subnet.addr, - SDP_MAX_STRING_LEN+1); - break; - - case SDP_ATTR_T38_RATEMGMT: - new_attr_p->attr.t38ratemgmt = src_attr_p->attr.t38ratemgmt; - break; - - case SDP_ATTR_T38_UDPEC: - new_attr_p->attr.t38udpec = src_attr_p->attr.t38udpec; - break; - - case SDP_ATTR_X_PC_CODEC: - new_attr_p->attr.pccodec.num_payloads = - src_attr_p->attr.pccodec.num_payloads; - for (i=0; i < src_attr_p->attr.pccodec.num_payloads; i++) { - new_attr_p->attr.pccodec.payload_type[i] = - src_attr_p->attr.pccodec.payload_type[i]; - } - break; - - case SDP_ATTR_DIRECTION: - - new_attr_p->attr.comediadir.role = - src_attr_p->attr.comediadir.role; - - if (src_attr_p->attr.comediadir.conn_info.nettype) { - new_attr_p->attr.comediadir.conn_info_present = TRUE; - new_attr_p->attr.comediadir.conn_info.nettype = - src_attr_p->attr.comediadir.conn_info.nettype; - new_attr_p->attr.comediadir.conn_info.addrtype = - src_attr_p->attr.comediadir.conn_info.addrtype; - sstrncpy(new_attr_p->attr.comediadir.conn_info.conn_addr, - src_attr_p->attr.comediadir.conn_info.conn_addr, - SDP_MAX_STRING_LEN+1); - new_attr_p->attr.comediadir.src_port = - src_attr_p->attr.comediadir.src_port; - } - break; - - - case SDP_ATTR_SILENCESUPP: - new_attr_p->attr.silencesupp.enabled = - src_attr_p->attr.silencesupp.enabled; - new_attr_p->attr.silencesupp.timer_null = - src_attr_p->attr.silencesupp.timer_null; - new_attr_p->attr.silencesupp.timer = - src_attr_p->attr.silencesupp.timer; - new_attr_p->attr.silencesupp.pref = - src_attr_p->attr.silencesupp.pref; - new_attr_p->attr.silencesupp.siduse = - src_attr_p->attr.silencesupp.siduse; - new_attr_p->attr.silencesupp.fxnslevel_null = - src_attr_p->attr.silencesupp.fxnslevel_null; - new_attr_p->attr.silencesupp.fxnslevel = - src_attr_p->attr.silencesupp.fxnslevel; - break; - - case SDP_ATTR_MPTIME: - new_attr_p->attr.mptime.num_intervals = - src_attr_p->attr.mptime.num_intervals; - for (i=0; i < src_attr_p->attr.mptime.num_intervals; i++) { - new_attr_p->attr.mptime.intervals[i] = - src_attr_p->attr.mptime.intervals[i]; - } - break; - - case SDP_ATTR_X_SIDIN: - case SDP_ATTR_X_SIDOUT: - case SDP_ATTR_X_CONFID: - sstrncpy(new_attr_p->attr.stream_data.x_sidin, - src_attr_p->attr.stream_data.x_sidin,SDP_MAX_STRING_LEN+1); - sstrncpy(new_attr_p->attr.stream_data.x_sidout, - src_attr_p->attr.stream_data.x_sidout,SDP_MAX_STRING_LEN+1); - sstrncpy(new_attr_p->attr.stream_data.x_confid, - src_attr_p->attr.stream_data.x_confid,SDP_MAX_STRING_LEN+1); - break; - - case SDP_ATTR_GROUP: - new_attr_p->attr.stream_data.group_attr = - src_attr_p->attr.stream_data.group_attr; - new_attr_p->attr.stream_data.num_group_id = - src_attr_p->attr.stream_data.num_group_id; - - for (i=0; i < src_attr_p->attr.stream_data.num_group_id; i++) { - new_attr_p->attr.stream_data.group_id_arr[i] = - src_attr_p->attr.stream_data.group_id_arr[i]; - } - break; - - case SDP_ATTR_SOURCE_FILTER: - new_attr_p->attr.source_filter.mode = - src_attr_p->attr.source_filter.mode; - new_attr_p->attr.source_filter.nettype = - src_attr_p->attr.source_filter.nettype; - new_attr_p->attr.source_filter.addrtype = - src_attr_p->attr.source_filter.addrtype; - sstrncpy(new_attr_p->attr.source_filter.dest_addr, - src_attr_p->attr.source_filter.dest_addr, - SDP_MAX_STRING_LEN+1); - for (i=0; iattr.source_filter.num_src_addr; ++i) { - sstrncpy(new_attr_p->attr.source_filter.src_list[i], - src_attr_p->attr.source_filter.src_list[i], - SDP_MAX_STRING_LEN+1); - } - new_attr_p->attr.source_filter.num_src_addr = - src_attr_p->attr.source_filter.num_src_addr; - break; - - case SDP_ATTR_SRTP_CONTEXT: - case SDP_ATTR_SDESCRIPTIONS: - /* Tag parameter is only valid for version 9 sdescriptions */ - if (src_attr_type == SDP_ATTR_SDESCRIPTIONS) { - new_attr_p->attr.srtp_context.tag = - src_attr_p->attr.srtp_context.tag; - } - - new_attr_p->attr.srtp_context.suite = - src_attr_p->attr.srtp_context.suite; - - new_attr_p->attr.srtp_context.selection_flags = - src_attr_p->attr.srtp_context.selection_flags; - - new_attr_p->attr.srtp_context.master_key_size_bytes = - src_attr_p->attr.srtp_context.master_key_size_bytes; - - new_attr_p->attr.srtp_context.master_salt_size_bytes = - src_attr_p->attr.srtp_context.master_salt_size_bytes; - - bcopy(src_attr_p->attr.srtp_context.master_key, - new_attr_p->attr.srtp_context.master_key, - SDP_SRTP_MAX_KEY_SIZE_BYTES); - - bcopy(src_attr_p->attr.srtp_context.master_salt, - new_attr_p->attr.srtp_context.master_salt, - SDP_SRTP_MAX_SALT_SIZE_BYTES); - - - sstrncpy((char*)new_attr_p->attr.srtp_context.master_key_lifetime, - (char*)src_attr_p->attr.srtp_context.master_key_lifetime, - SDP_SRTP_MAX_LIFETIME_BYTES); - - sstrncpy((char*)new_attr_p->attr.srtp_context.mki, - (char*)src_attr_p->attr.srtp_context.mki, - SDP_SRTP_MAX_MKI_SIZE_BYTES); - - new_attr_p->attr.srtp_context.mki_size_bytes = - src_attr_p->attr.srtp_context.mki_size_bytes; - - if (src_attr_p->attr.srtp_context.session_parameters) { - new_attr_p->attr.srtp_context.session_parameters = - cpr_strdup(src_attr_p->attr.srtp_context.session_parameters); - } - - break; - - default: - break; - } - - if (src_cap_num == 0) { - if (dst_level == SDP_SESSION_LEVEL) { - if (dst_sdp_p->sess_attrs_p == NULL) { - dst_sdp_p->sess_attrs_p = new_attr_p; - } else { - for (prev_attr_p = dst_sdp_p->sess_attrs_p; - prev_attr_p->next_p != NULL; - prev_attr_p = prev_attr_p->next_p) { - ; /* Empty for */ - } - prev_attr_p->next_p = new_attr_p; - } - } else { - mca_p = sdp_find_media_level(dst_sdp_p, dst_level); - if (mca_p == NULL) { - sdp_free_attr(new_attr_p); - src_sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (mca_p->media_attrs_p == NULL) { - mca_p->media_attrs_p = new_attr_p; - } else { - for (prev_attr_p = mca_p->media_attrs_p; - prev_attr_p->next_p != NULL; - prev_attr_p = prev_attr_p->next_p) { - ; /* Empty for */ - } - prev_attr_p->next_p = new_attr_p; - } - } - } else { - /* Add a new capability attribute - find the capability attr. */ - attr_p = sdp_find_capability(dst_sdp_p, dst_level, dst_cap_num); - if (attr_p == NULL) { - sdp_free_attr(new_attr_p); - src_sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - cap_p = attr_p->attr.cap_p; - if (cap_p->media_attrs_p == NULL) { - cap_p->media_attrs_p = new_attr_p; - } else { - for (prev_attr_p = cap_p->media_attrs_p; - prev_attr_p->next_p != NULL; - prev_attr_p = prev_attr_p->next_p) { - ; /* Empty for */ - } - prev_attr_p->next_p = new_attr_p; - } - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_copy_all_attrs - * Description: Copy all attributes from one SDP/level to another. - * Parameters: src_sdp_ptr The source SDP handle. - * dst_sdp_ptr The dest SDP handle. - * src_level The level of the source attributes. - * dst_level The level of the source attributes. - * Returns: SDP_SUCCESS Attributes were successfully copied. - */ -sdp_result_e sdp_copy_all_attrs (void *src_sdp_ptr, void *dst_sdp_ptr, - u16 src_level, u16 dst_level) -{ - int i; - sdp_mca_t *mca_p = NULL; - sdp_t *src_sdp_p = (sdp_t *)src_sdp_ptr; - sdp_t *dst_sdp_p = (sdp_t *)dst_sdp_ptr; - sdp_mca_t *src_cap_p; - sdp_mca_t *dst_cap_p; - sdp_attr_t *src_attr_p; - sdp_attr_t *dst_attr_p; - sdp_attr_t *new_attr_p; - sdp_attr_t *src_cap_attr_p; - sdp_attr_t *dst_cap_attr_p; - sdp_attr_t *new_cap_attr_p; - - if (sdp_verify_sdp_ptr(src_sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_verify_sdp_ptr(dst_sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - /* Find src attribute list. */ - if (src_level == SDP_SESSION_LEVEL) { - src_attr_p = src_sdp_p->sess_attrs_p; - } else { - mca_p = sdp_find_media_level(src_sdp_p, src_level); - if (mca_p == NULL) { - if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Invalid src media level (%u) for copy all " - "attrs ", src_sdp_p->debug_str, src_level); - } - return (SDP_INVALID_PARAMETER); - } - src_attr_p = mca_p->media_attrs_p; - } - - /* Find dst attribute list. */ - if (dst_level == SDP_SESSION_LEVEL) { - dst_attr_p = dst_sdp_p->sess_attrs_p; - } else { - mca_p = sdp_find_media_level(dst_sdp_p, dst_level); - if (mca_p == NULL) { - if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Invalid dst media level (%u) for copy all " - "attrs ", src_sdp_p->debug_str, dst_level); - } - return (SDP_INVALID_PARAMETER); - } - dst_attr_p = mca_p->media_attrs_p; - } - - /* Now find the end of the dst attr list. This is where we will - * add new attributes. */ - while ((dst_attr_p != NULL) && (dst_attr_p->next_p != NULL)) { - dst_attr_p = dst_attr_p->next_p; - } - - /* For each src attribute, allocate a new dst attr and copy the info */ - while (src_attr_p != NULL) { - - /* Allocate the new attr. */ - new_attr_p = (sdp_attr_t *)SDP_MALLOC(sizeof(sdp_attr_t)); - if (new_attr_p == NULL) { - src_sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - - if ((src_attr_p->type != SDP_ATTR_X_CAP) && - (src_attr_p->type != SDP_ATTR_CDSC)) { - /* Simple attr type - copy over all the attr info. */ - sdp_copy_attr_fields(src_attr_p, new_attr_p); - } else { - /* X-cap/cdsc attrs must be handled differently. Allocate an - * mca structure and copy over any X-cpar/cdsc attrs. */ - - new_attr_p->attr.cap_p = - (sdp_mca_t *)SDP_MALLOC(sizeof(sdp_mca_t)); - if (new_attr_p->attr.cap_p == NULL) { - sdp_free_attr(new_attr_p); - return (SDP_NO_RESOURCE); - } - - new_attr_p->type = src_attr_p->type; - - src_cap_p = src_attr_p->attr.cap_p; - dst_cap_p = new_attr_p->attr.cap_p; - - dst_cap_p->media = src_cap_p->media; - dst_cap_p->conn.nettype = src_cap_p->conn.nettype; - dst_cap_p->conn.addrtype = src_cap_p->conn.addrtype; - sstrncpy(dst_cap_p->conn.conn_addr, src_cap_p->conn.conn_addr, - SDP_MAX_LINE_LEN+1); - dst_cap_p->transport = src_cap_p->transport; - dst_cap_p->port_format = src_cap_p->port_format; - dst_cap_p->port = src_cap_p->port; - dst_cap_p->num_ports = src_cap_p->num_ports; - dst_cap_p->vpi = src_cap_p->vpi; - dst_cap_p->vci = src_cap_p->vci; - dst_cap_p->vcci = src_cap_p->vcci; - dst_cap_p->cid = src_cap_p->cid; - dst_cap_p->num_payloads = src_cap_p->num_payloads; - dst_cap_p->mid = src_cap_p->mid; - - for (i=0; i < SDP_MAX_PAYLOAD_TYPES; i++) { - new_attr_p->attr.cap_p->payload_indicator[i] = - src_attr_p->attr.cap_p->payload_indicator[i]; - new_attr_p->attr.cap_p->payload_type[i] = - src_attr_p->attr.cap_p->payload_type[i]; - } - - src_cap_attr_p = src_attr_p->attr.cap_p->media_attrs_p; - dst_cap_attr_p = NULL; - - /* Copy all of the X-cpar/cpar attrs from the src. */ - while (src_cap_attr_p != NULL) { - - new_cap_attr_p = (sdp_attr_t *)SDP_MALLOC(sizeof(sdp_attr_t)); - if (new_cap_attr_p == NULL) { - sdp_free_attr (new_attr_p); - return (SDP_NO_RESOURCE); - } - - /* Copy X-cpar/cpar attribute info. */ - sdp_copy_attr_fields(src_cap_attr_p, new_cap_attr_p); - - /* Now add the new X-cpar/cpar attr in the right place. */ - if (dst_cap_attr_p == NULL) { - new_attr_p->attr.cap_p->media_attrs_p = new_cap_attr_p; - dst_cap_attr_p = new_cap_attr_p; - } else { - dst_cap_attr_p->next_p = new_cap_attr_p; - dst_cap_attr_p = new_cap_attr_p; - } - - /* Move to the next X-cpar/cpar attr. */ - src_cap_attr_p = src_cap_attr_p->next_p; - } - - } - - /* New add the new base attr at the correct place. */ - if (dst_attr_p == NULL) { - if (dst_level == SDP_SESSION_LEVEL) { - dst_sdp_p->sess_attrs_p = new_attr_p; - dst_attr_p = dst_sdp_p->sess_attrs_p; - } else { - mca_p->media_attrs_p = new_attr_p; - dst_attr_p = mca_p->media_attrs_p; - } - } else { - dst_attr_p->next_p = new_attr_p; - dst_attr_p = dst_attr_p->next_p; - } - - /* Now move on to the next src attr. */ - src_attr_p = src_attr_p->next_p; - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_num_instances - * Description: Get the number of attributes of the specified type at - * the given level and capability level. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * attr_type The type of attribute to add. - * num_attr_inst Pointer to a u16 in which to return the - * number of attributes. - * Returns: SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified media line is not defined. - */ -sdp_result_e sdp_attr_num_instances (void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e attr_type, u16 *num_attr_inst) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_result_e rc; - static char fname[] = "attr_num_instances"; - - *num_attr_inst = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - rc = sdp_find_attr_list(sdp_p, level, cap_num, &attr_p, fname); - if (rc == SDP_SUCCESS) { - /* Found the attr list. Count the number of attrs of the given - * type at this level. */ - for (; attr_p != NULL; attr_p = attr_p->next_p) { - if (attr_p->type == attr_type) { - (*num_attr_inst)++; - } - } - - } - - return (rc); -} - - -/* Function: sdp_get_total_attrs - * Description: Get the total number of attributes at the given level and - * capability level. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * num_attrs Pointer to a u16 in which to return the - * number of attributes. - * Returns: SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified media line is not defined. - */ -sdp_result_e sdp_get_total_attrs (void *sdp_ptr, u16 level, u8 cap_num, - u16 *num_attrs) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_result_e rc; - static char fname[] = "get_total_attrs"; - - *num_attrs = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - rc = sdp_find_attr_list(sdp_p, level, cap_num, &attr_p, fname); - if (rc == SDP_SUCCESS) { - /* Found the attr list. Count the total number of attrs - * at this level. */ - for (; attr_p != NULL; attr_p = attr_p->next_p) { - (*num_attrs)++; - } - - } - - return (rc); -} - - -/* Function: sdp_get_attr_type - * Description: Given an overall attribute number at a specified level, i.e., - * attr number is not specific to the type of attribute, return - * the attribute type and the instance number of that particular - * type of attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * attr_num Attribute number to retrieve. This is an overall - * attribute number over all attrs at this level. - * Range is (1 - max attrs at this level). - * Returns: SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified media line is not defined. - */ -sdp_result_e sdp_get_attr_type (void *sdp_ptr, u16 level, u8 cap_num, - u16 attr_num, sdp_attr_e *attr_type, u16 *inst_num) -{ - int i; - u16 attr_total_count=0; - u16 attr_count[SDP_MAX_ATTR_TYPES]; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_result_e rc; - static char fname[] = "get_attr_type"; - - *attr_type = SDP_ATTR_INVALID; - *inst_num = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (attr_num < 1) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s, invalid attr num specified (%u) at level %u", - sdp_p->debug_str, fname, attr_num, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - for (i=0; i < SDP_MAX_ATTR_TYPES; i++) { - attr_count[i] = 0; - } - - rc = sdp_find_attr_list(sdp_p, level, cap_num, &attr_p, fname); - if (rc == SDP_SUCCESS) { - /* Found the attr list. Now find the particular attribute - * at the given level. */ - for (; attr_p != NULL; attr_p = attr_p->next_p) { - attr_count[attr_p->type]++; - if (++attr_total_count == attr_num) { - *attr_type = attr_p->type; - *inst_num = attr_count[attr_p->type]; - break; - } - } - - } - - return (rc); -} - - -/* Internal routine to free the memory associated with an attribute. - * Certain attributes allocate additional memory. Free this and then - * free the attribute itself. - * Note that this routine may be called at any point (i.e., may be - * called due to a failure case) and so the additional memory - * associated with an attribute may or may not have been already - * allocated. This routine should check this carefully. - */ -void sdp_free_attr (sdp_attr_t *attr_p) -{ - sdp_mca_t *cap_p; - sdp_attr_t *cpar_p; - sdp_attr_t *next_cpar_p; - - /* If this is an X-cap/cdsc attr, free the cap_p structure and - * all X-cpar/cpar attributes. */ - if ((attr_p->type == SDP_ATTR_X_CAP) || - (attr_p->type == SDP_ATTR_CDSC)) { - cap_p = attr_p->attr.cap_p; - if (cap_p != NULL) { - for (cpar_p = cap_p->media_attrs_p; cpar_p != NULL;) { - next_cpar_p = cpar_p->next_p; - sdp_free_attr(cpar_p); - cpar_p = next_cpar_p; - } - SDP_FREE(cap_p); - } - } else if ((attr_p->type == SDP_ATTR_SDESCRIPTIONS) || - (attr_p->type == SDP_ATTR_SRTP_CONTEXT)) { - SDP_FREE(attr_p->attr.srtp_context.session_parameters); - } - - /* Now free the actual attribute memory. */ - SDP_FREE(attr_p); - -} - - -/* Function: sdp_delete_attr - * Description: Delete the specified attribute from the SDP structure. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * attr_type The type of attribute to delete. - * inst_num The instance num of the attribute to delete. - * Returns: SDP_SUCCESS Attribute was deleted successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_delete_attr (void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e attr_type, u16 inst_num) -{ - u16 attr_count=0; - sdp_mca_t *mca_p; - sdp_mca_t *cap_p; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_attr_t *prev_attr_p = NULL; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (cap_num == 0) { - /* Find and delete the specified instance. */ - if (level == SDP_SESSION_LEVEL) { - for (attr_p = sdp_p->sess_attrs_p; attr_p != NULL; - prev_attr_p = attr_p, attr_p = attr_p->next_p) { - if (attr_p->type == attr_type) { - attr_count++; - if (attr_count == inst_num) { - break; - } - } - } - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Delete attribute (%s) instance %d not " - "found.", sdp_p->debug_str, - sdp_get_attr_name(attr_type), inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (prev_attr_p == NULL) { - sdp_p->sess_attrs_p = attr_p->next_p; - } else { - prev_attr_p->next_p = attr_p->next_p; - } - sdp_free_attr(attr_p); - } else { /* Attr is at a media level */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - for (attr_p = mca_p->media_attrs_p; attr_p != NULL; - prev_attr_p = attr_p, attr_p = attr_p->next_p) { - if (attr_p->type == attr_type) { - attr_count++; - if (attr_count == inst_num) { - break; - } - } - } - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Delete attribute (%s) instance %d " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(attr_type), inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (prev_attr_p == NULL) { - mca_p->media_attrs_p = attr_p->next_p; - } else { - prev_attr_p->next_p = attr_p->next_p; - } - sdp_free_attr(attr_p); - } /* Attr is at a media level */ - } else { - /* Attr is a capability X-cpar/cpar attribute, find the capability. */ - attr_p = sdp_find_capability(sdp_p, level, cap_num); - if (attr_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - cap_p = attr_p->attr.cap_p; - /* Now find the specific attribute to delete. */ - for (attr_p = cap_p->media_attrs_p; attr_p != NULL; - prev_attr_p = attr_p, attr_p = attr_p->next_p) { - if (attr_p->type == attr_type) { - attr_count++; - if (attr_count == inst_num) { - break; - } - } - } - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Delete X-cpar/cpar attribute (%s) cap_num %u, " - "instance %d not found.", sdp_p->debug_str, - sdp_get_attr_name(attr_type), cap_num, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (prev_attr_p == NULL) { - cap_p->media_attrs_p = attr_p->next_p; - } else { - prev_attr_p->next_p = attr_p->next_p; - } - sdp_free_attr(attr_p); - } - - return (SDP_SUCCESS); -} - - -/* Function: sdp_delete_all_attrs - * Description: Delete all attributes at the specified level from - * the SDP structure. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * Returns: SDP_SUCCESS Attributes were deleted successfully. - */ -sdp_result_e sdp_delete_all_attrs (void *sdp_ptr, u16 level, u8 cap_num) -{ - sdp_mca_t *mca_p; - sdp_mca_t *cap_p; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_attr_t *next_attr_p = NULL; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (cap_num == 0) { - if (level == SDP_SESSION_LEVEL) { - attr_p = sdp_p->sess_attrs_p; - while (attr_p != NULL) { - next_attr_p = attr_p->next_p; - sdp_free_attr(attr_p); - attr_p = next_attr_p; - } - sdp_p->sess_attrs_p = NULL; - } else { /* Attr is at a media level */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p = mca_p->media_attrs_p; - while (attr_p != NULL) { - next_attr_p = attr_p->next_p; - sdp_free_attr(attr_p); - attr_p = next_attr_p; - } - mca_p->media_attrs_p = NULL; - } - } else { - /* Attr is a capability X-cpar/cpar attribute, find the capability. */ - attr_p = sdp_find_capability(sdp_p, level, cap_num); - if (attr_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - cap_p = attr_p->attr.cap_p; - /* Now find the specific attribute to delete. */ - attr_p = cap_p->media_attrs_p; - while (attr_p != NULL) { - next_attr_p = attr_p->next_p; - sdp_free_attr(attr_p); - attr_p = next_attr_p; - } - cap_p->media_attrs_p = NULL; - } - - return (SDP_SUCCESS); -} - - -/* Function: sdp_find_attr_list - * Description: Find the attribute list for the specified level and cap_num. - * Note: This is not an API for the application but an internal - * routine used by the SDP library. - * Parameters: sdp_p Pointer to the SDP to search. - * level The level to check for the attribute list. - * cap_num The capability number associated with the - * attribute list. If none, should be zero. - * attr_p Pointer to the attr list pointer. Will be - * filled in on return if successful. - * fname String function name calling this routine. - * Use for printing debug. - * Returns: SDP_SUCCESS - * SDP_INVALID_MEDIA_LEVEL - * SDP_INVALID_CAPABILITY - * SDP_FAILURE - */ -sdp_result_e sdp_find_attr_list (sdp_t *sdp_p, u16 level, u8 cap_num, - sdp_attr_t **attr_p, char *fname) -{ - sdp_mca_t *mca_p; - sdp_mca_t *cap_p; - sdp_attr_t *cap_attr_p; - - /* Initialize the attr pointer. */ - *attr_p = NULL; - - if (cap_num == 0) { - /* Find attribute list at the specified level. */ - if (level == SDP_SESSION_LEVEL) { - *attr_p = sdp_p->sess_attrs_p; - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - *attr_p = mca_p->media_attrs_p; - } - } else { - /* Find the attr list for the capability specified. */ - cap_attr_p = sdp_find_capability(sdp_p, level, cap_num); - if (cap_attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s, invalid capability %u at " - "level %u specified.", sdp_p->debug_str, fname, - cap_num, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_CAPABILITY); - } - cap_p = cap_attr_p->attr.cap_p; - *attr_p = cap_p->media_attrs_p; - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_find_attr - * Description: Find the specified attribute in an SDP structure. - * Note: This is not an API for the application but an internal - * routine used by the SDP library. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * attr_type The type of attribute to find. - * inst_num The instance num of the attribute to delete. - * Range should be (1 - max num insts of this - * particular type of attribute at this level). - * Returns: Pointer to the attribute or NULL if not found. - */ -sdp_attr_t *sdp_find_attr (sdp_t *sdp_p, u16 level, u8 cap_num, - sdp_attr_e attr_type, u16 inst_num) -{ - u16 attr_count=0; - sdp_mca_t *mca_p; - sdp_mca_t *cap_p; - sdp_attr_t *attr_p; - - if (inst_num < 1) { - return (NULL); - } - - if (cap_num == 0) { - if (level == SDP_SESSION_LEVEL) { - for (attr_p = sdp_p->sess_attrs_p; attr_p != NULL; - attr_p = attr_p->next_p) { - if (attr_p->type == attr_type) { - attr_count++; - if (attr_count == inst_num) { - return (attr_p); - } - } - } - } else { /* Attr is at a media level */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (NULL); - } - for (attr_p = mca_p->media_attrs_p; attr_p != NULL; - attr_p = attr_p->next_p) { - if (attr_p->type == attr_type) { - attr_count++; - if (attr_count == inst_num) { - return (attr_p); - } - } - } - } /* Attr is at a media level */ - } else { - /* Attr is a capability X-cpar/cpar attribute. */ - attr_p = sdp_find_capability(sdp_p, level, cap_num); - if (attr_p == NULL) { - return (NULL); - } - cap_p = attr_p->attr.cap_p; - /* Now find the specific attribute. */ - for (attr_p = cap_p->media_attrs_p; attr_p != NULL; - attr_p = attr_p->next_p) { - if (attr_p->type == attr_type) { - attr_count++; - if (attr_count == inst_num) { - return (attr_p); - } - } - } - } - - return (NULL); -} - -/* Function: sdp_find_capability - * Description: Find the specified capability attribute in an SDP structure. - * Note: This is not an API for the application but an internal - * routine used by the SDP library. - * Parameters: sdp_p The SDP handle. - * level The level to check for the capability. - * cap_num The capability number to locate. - * Returns: Pointer to the capability attribute or NULL if not found. - */ -sdp_attr_t *sdp_find_capability (sdp_t *sdp_p, u16 level, u8 cap_num) -{ - u8 cur_cap_num=0; - sdp_mca_t *mca_p; - sdp_mca_t *cap_p; - sdp_attr_t *attr_p; - - if (level == SDP_SESSION_LEVEL) { - for (attr_p = sdp_p->sess_attrs_p; attr_p != NULL; - attr_p = attr_p->next_p) { - if ((attr_p->type == SDP_ATTR_X_CAP) || - (attr_p->type == SDP_ATTR_CDSC)) { - cap_p = attr_p->attr.cap_p; - cur_cap_num += cap_p->num_payloads; - if (cap_num <= cur_cap_num) { - /* This is the right capability */ - return (attr_p); - } - } - } - } else { /* Capability is at a media level */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (NULL); - } - for (attr_p = mca_p->media_attrs_p; attr_p != NULL; - attr_p = attr_p->next_p) { - if ((attr_p->type == SDP_ATTR_X_CAP) || - (attr_p->type == SDP_ATTR_CDSC)) { - cap_p = attr_p->attr.cap_p; - cur_cap_num += cap_p->num_payloads; - if (cap_num <= cur_cap_num) { - /* This is the right capability */ - return (attr_p); - } - } - } - } - - /* We didn't find the specified capability. */ - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Unable to find specified capability (level %u, " - "cap_num %u).", sdp_p->debug_str, level, cap_num); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); -} - -/* Function: sdp_attr_valid(void *sdp_ptr) - * Description: Returns true or false depending on whether the specified - * instance of the given attribute has been defined at the - * given level. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * attr_type The attribute type to validate. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: TRUE or FALSE. - */ -tinybool sdp_attr_valid (void *sdp_ptr, sdp_attr_e attr_type, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num) == NULL) { - return (FALSE); - } else { - return (TRUE); - } -} - -/* Function: sdp_attr_get_simple_string - * Description: Returns a pointer to a string attribute parameter. This - * routine can only be called for attributes that have just - * one string parameter. The value is returned as a const - * ptr and so cannot be modified by the application. If the - * given attribute is not defined, NULL will be returned. - * Attributes with a simple string parameter currently include: - * bearer, called, connection_type, dialed, dialing, direction - * and framing. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * attr_type The simple string attribute type. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Pointer to the parameter value. - */ -const char *sdp_attr_get_simple_string (void *sdp_ptr, sdp_attr_e attr_type, - u16 level, u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - if ((attr_type != SDP_ATTR_BEARER) && - (attr_type != SDP_ATTR_CALLED) && - (attr_type != SDP_ATTR_CONN_TYPE) && - (attr_type != SDP_ATTR_DIALED) && - (attr_type != SDP_ATTR_DIALING) && - (attr_type != SDP_ATTR_FRAMING) && - (attr_type != SDP_ATTR_X_SIDIN) && - (attr_type != SDP_ATTR_X_SIDOUT)&& - (attr_type != SDP_ATTR_X_CONFID) && - (attr_type != SDP_ATTR_LABEL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute type is not a simple string (%s)", - sdp_p->debug_str, sdp_get_attr_name(attr_type)); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(attr_type), - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } else { - return (attr_p->attr.string_val); - } -} - -/* Function: sdp_attr_set_simple_string - * Description: Sets the value of a string attribute parameter. This - * routine can only be called for attributes that have just - * one string parameter. The string is copied into the SDP - * structure so application memory will not be referenced by - * the SDP library. - * Attributes with a simple string parameter currently include: - * bearer, called, connection_type, dialed, dialing, and - * framing. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * attr_type The simple string attribute type. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * string_parm Ptr to new string value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_simple_string (void *sdp_ptr, sdp_attr_e attr_type, - u16 level, u8 cap_num, - u16 inst_num, const char *string_parm) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if ((attr_type != SDP_ATTR_BEARER) && - (attr_type != SDP_ATTR_CALLED) && - (attr_type != SDP_ATTR_CONN_TYPE) && - (attr_type != SDP_ATTR_DIALED) && - (attr_type != SDP_ATTR_DIALING) && - (attr_type != SDP_ATTR_FRAMING) && - (attr_type != SDP_ATTR_X_SIDIN) && - (attr_type != SDP_ATTR_X_SIDOUT)&& - (attr_type != SDP_ATTR_X_CONFID) && - (attr_type != SDP_ATTR_LABEL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute type is not a simple string (%s)", - sdp_p->debug_str, sdp_get_attr_name(attr_type)); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(attr_type), - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - sstrncpy(attr_p->attr.string_val, string_parm, - sizeof(attr_p->attr.string_val)); - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_simple_u32 - * Description: Returns an unsigned 32-bit attribute parameter. This - * routine can only be called for attributes that have just - * one u32 parameter. If the given attribute is not defined, - * zero will be returned. There is no way for the application - * to determine if zero is the actual value or the attribute - * wasn't defined, so the application must use the - * sdp_attr_valid function to determine this. - * Attributes with a simple u32 parameter currently include: - * eecid, ptime, T38FaxVersion, T38maxBitRate, T38FaxMaxBuffer, - * T38FaxMaxDatagram, X-sqn, TC1PayloadBytes, TC1WindowSize, - * TC2PayloadBytes, TC2WindowSize, rtcp. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * attr_type The simple u32 attribute type. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: u32 parameter value. - */ -u32 sdp_attr_get_simple_u32 (void *sdp_ptr, sdp_attr_e attr_type, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - if ((attr_type != SDP_ATTR_EECID) && - (attr_type != SDP_ATTR_PTIME) && - (attr_type != SDP_ATTR_MAXPTIME) && - (attr_type != SDP_ATTR_T38_VERSION) && - (attr_type != SDP_ATTR_T38_MAXBITRATE) && - (attr_type != SDP_ATTR_T38_MAXBUFFER) && - (attr_type != SDP_ATTR_T38_MAXDGRAM) && - (attr_type != SDP_ATTR_X_SQN) && - (attr_type != SDP_ATTR_TC1_PAYLOAD_BYTES) && - (attr_type != SDP_ATTR_TC1_WINDOW_SIZE) && - (attr_type != SDP_ATTR_TC2_PAYLOAD_BYTES) && - (attr_type != SDP_ATTR_TC2_WINDOW_SIZE) && - (attr_type != SDP_ATTR_RTCP) && - (attr_type != SDP_ATTR_MID) && - (attr_type != SDP_ATTR_FRAMERATE)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute type is not a simple u32 (%s)", - sdp_p->debug_str, sdp_get_attr_name(attr_type)); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(attr_type), - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.u32_val); - } -} - -/* Function: sdp_attr_set_simple_u32 - * Description: Sets the value of an unsigned 32-bit attribute parameter. - * This routine can only be called for attributes that have just - * one u32 parameter. - * Attributes with a simple u32 parameter currently include: - * eecid, ptime, T38FaxVersion, T38maxBitRate, T38FaxMaxBuffer, - * T38FaxMaxDatagram, X-sqn, TC1PayloadBytes, TC1WindowSize, - * TC2PayloadBytes, TC2WindowSize, rtcp. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * attr_type The simple u32 attribute type. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * num_parm New u32 parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_simple_u32 (void *sdp_ptr, sdp_attr_e attr_type, - u16 level, u8 cap_num, u16 inst_num, u32 num_parm) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if ((attr_type != SDP_ATTR_EECID) && - (attr_type != SDP_ATTR_PTIME) && - (attr_type != SDP_ATTR_MAXPTIME) && - (attr_type != SDP_ATTR_T38_VERSION) && - (attr_type != SDP_ATTR_T38_MAXBITRATE) && - (attr_type != SDP_ATTR_T38_MAXBUFFER) && - (attr_type != SDP_ATTR_T38_MAXDGRAM) && - (attr_type != SDP_ATTR_X_SQN) && - (attr_type != SDP_ATTR_TC1_PAYLOAD_BYTES) && - (attr_type != SDP_ATTR_TC1_WINDOW_SIZE) && - (attr_type != SDP_ATTR_TC2_PAYLOAD_BYTES) && - (attr_type != SDP_ATTR_TC2_WINDOW_SIZE) && - (attr_type != SDP_ATTR_RTCP) && - (attr_type != SDP_ATTR_MID) && - (attr_type != SDP_ATTR_FRAMERATE)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute type is not a simple u32 (%s)", - sdp_p->debug_str, sdp_get_attr_name(attr_type)); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(attr_type), - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.u32_val = num_parm; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_get_simple_boolean - * Description: Returns a boolean attribute parameter. This - * routine can only be called for attributes that have just - * one boolean parameter. If the given attribute is not defined, - * FALSE will be returned. There is no way for the application - * to determine if FALSE is the actual value or the attribute - * wasn't defined, so the application must use the - * sdp_attr_valid function to determine this. - * Attributes with a simple boolean parameter currently include: - * T38FaxFillBitRemoval, T38FaxTranscodingMMR, - * T38FaxTranscodingJBIG, and TMRGwXid. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * attr_type The simple boolean attribute type. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Boolean value. - */ -tinybool sdp_attr_get_simple_boolean (void *sdp_ptr, sdp_attr_e attr_type, - u16 level, u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if ((attr_type != SDP_ATTR_T38_FILLBITREMOVAL) && - (attr_type != SDP_ATTR_T38_TRANSCODINGMMR) && - (attr_type != SDP_ATTR_T38_TRANSCODINGJBIG) && - (attr_type != SDP_ATTR_TMRGWXID)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute type is not a simple boolean (%s)", - sdp_p->debug_str, sdp_get_attr_name(attr_type)); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(attr_type), - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.boolean_val); - } -} - -/* Function: sdp_attr_set_simple_boolean - * Description: Sets the value of a boolean attribute parameter. - * This routine can only be called for attributes that have just - * one boolean parameter. - * Attributes with a simple boolean parameter currently include: - * T38FaxFillBitRemoval, T38FaxTranscodingMMR, - * T38FaxTranscodingJBIG, and TMRGwXid. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * attr_type The simple boolean attribute type. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * bool_parm New boolean parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_simple_boolean (void *sdp_ptr, sdp_attr_e attr_type, - u16 level, u8 cap_num, - u16 inst_num, u32 bool_parm) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if ((attr_type != SDP_ATTR_T38_FILLBITREMOVAL) && - (attr_type != SDP_ATTR_T38_TRANSCODINGMMR) && - (attr_type != SDP_ATTR_T38_TRANSCODINGJBIG) && - (attr_type != SDP_ATTR_TMRGWXID)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute type is not a simple boolean (%s)", - sdp_p->debug_str, sdp_get_attr_name(attr_type)); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(attr_type), - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.boolean_val = (tinybool)bool_parm; - return (SDP_SUCCESS); - } -} - -/* - * sdp_attr_get_maxprate - * - * This function is used by the application layer to get the packet-rate - * within the maxprate attribute. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to set. - * - * Returns a pointer to a constant char array that stores the packet-rate, - * OR null if the attribute does not exist. - */ -const char* -sdp_attr_get_maxprate (void *sdp_ptr, u16 level, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_MAXPRATE, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(SDP_ATTR_MAXPRATE), - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } else { - return (attr_p->attr.string_val); - } -} - -/* - * sdp_attr_set_maxprate - * - * This function is used by the application layer to set the packet rate of - * the maxprate attribute line appropriately. The maxprate attribute is - * defined as follows: - * - * max-p-rate-def = "a" "=" "maxprate" ":" packet-rate CRLF - * packet-rate = 1*DIGIT ["." 1*DIGIT] - * - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to set. - * string_parm A string that contains the value of packet-rate - * that needs to be advertised. - * - * Note that we use a string to set the packet-rate, so the application layer - * must format a string, as per the packet-rate format and pass it to this - * function. - * - * The decision to use a string to communicate the packet-rate was - * made because some operating systems do not support floating point - * operations. - * - * Returns: - * SDP_INVALID_SDP_PTR - If an invalid sdp handle is passed in. - * SDP_INVALID_PARAMETER - If the maxprate attribute is not defined at the - * specified level OR if the packet-rate is not - * formatted correctly in string_parm. - * SDP_SUCCESS - If we are successfully able to set the maxprate attribute. - */ -sdp_result_e -sdp_attr_set_maxprate (void *sdp_ptr, u16 level, u16 inst_num, - const char *string_parm) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_MAXPRATE, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(SDP_ATTR_MAXPRATE), - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (!sdp_validate_maxprate(string_parm)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s is not a valid maxprate value.", string_parm); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - sstrncpy(attr_p->attr.string_val, string_parm, - sizeof(attr_p->attr.string_val)); - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_t38ratemgmt - * Description: Returns the value of the t38ratemgmt attribute - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_T38_UNKNOWN_RATE is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Ratemgmt value. - */ -sdp_t38_ratemgmt_e sdp_attr_get_t38ratemgmt (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_T38_UNKNOWN_RATE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_T38_RATEMGMT, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s t38ratemgmt attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_T38_UNKNOWN_RATE); - } else { - return (attr_p->attr.t38ratemgmt); - } -} - -/* Function: sdp_attr_set_t38ratemgmt - * Description: Sets the value of the t38ratemgmt attribute parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * t38ratemgmt New t38ratemgmt parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_t38ratemgmt (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_t38_ratemgmt_e t38ratemgmt) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_T38_RATEMGMT, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s t38ratemgmt attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.t38ratemgmt = t38ratemgmt; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_get_t38udpec - * Description: Returns the value of the t38udpec attribute - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_T38_UDPEC_UNKNOWN is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: UDP EC value. - */ -sdp_t38_udpec_e sdp_attr_get_t38udpec (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_T38_UDPEC_UNKNOWN); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_T38_UDPEC, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s t38udpec attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_T38_UDPEC_UNKNOWN); - } else { - return (attr_p->attr.t38udpec); - } -} - -/* Function: sdp_attr_set_t38udpec - * Description: Sets the value of the t38ratemgmt attribute parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * t38udpec New t38udpec parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_t38udpec (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_t38_udpec_e t38udpec) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_T38_UDPEC, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s t38udpec attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.t38udpec = t38udpec; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_get_media_direction - * Description: Determines the direction defined for a given level. The - * direction will be inactive, sendonly, recvonly, or sendrecv - * as determined by the last of these attributes specified at - * the given level. If none of these attributes are specified, - * the direction will be sendrecv by default. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * Returns: An SDP direction enum value. - */ -sdp_direction_e sdp_get_media_direction (void *sdp_ptr, u16 level, - u8 cap_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - sdp_attr_t *attr_p; - sdp_direction_e direction = SDP_DIRECTION_SENDRECV; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (direction); - } - - if (cap_num == 0) { - /* Find the pointer to the attr list for this level. */ - if (level == SDP_SESSION_LEVEL) { - attr_p = sdp_p->sess_attrs_p; - } else { /* Attr is at a media level */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (direction); - } - attr_p = mca_p->media_attrs_p; - } - - /* Scan for direction oriented attributes. Last one wins. */ - for (; attr_p != NULL; attr_p = attr_p->next_p) { - if (attr_p->type == SDP_ATTR_INACTIVE) { - direction = SDP_DIRECTION_INACTIVE; - } else if (attr_p->type == SDP_ATTR_SENDONLY) { - direction = SDP_DIRECTION_SENDONLY; - } else if (attr_p->type == SDP_ATTR_RECVONLY) { - direction = SDP_DIRECTION_RECVONLY; - } else if (attr_p->type == SDP_ATTR_SENDRECV) { - direction = SDP_DIRECTION_SENDRECV; - } - } - } else { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid cap_num for media direction.", - sdp_p->debug_str); - } - } - - return (direction); -} - -/* - * sdp_delete_all_media_direction_attrs - * - * Deletes all the media direction attributes from a given SDP level. - * Media direction attributes include: - * a=sendonly - * a=recvonly - * a=sendrecv - * a=inactive - * - * This function can be used in conjunction with sdp_add_new_attr, to ensure - * that there is only one direction attribute per level. - * It can also be used to delete all attributes when the client wants to - * advertise the default direction, i.e. a=sendrecv. - */ -sdp_result_e sdp_delete_all_media_direction_attrs (void *sdp_ptr, u16 level) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_mca_t *mca_p; - sdp_attr_t *attr_p; - sdp_attr_t *prev_attr_p = NULL; - sdp_attr_t *tmp_attr_p = NULL; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - /* Find the pointer to the attr list for this level. */ - if (level == SDP_SESSION_LEVEL) { - attr_p = sdp_p->sess_attrs_p; - while (attr_p != NULL) { - if ((attr_p->type == SDP_ATTR_INACTIVE) || - (attr_p->type == SDP_ATTR_SENDONLY) || - (attr_p->type == SDP_ATTR_RECVONLY) || - (attr_p->type == SDP_ATTR_SENDRECV)) { - - tmp_attr_p = attr_p; - - if (prev_attr_p == NULL) { - sdp_p->sess_attrs_p = attr_p->next_p; - } else { - prev_attr_p->next_p = attr_p->next_p; - } - attr_p = attr_p->next_p; - - sdp_free_attr(tmp_attr_p); - } else { - prev_attr_p = attr_p; - attr_p = attr_p->next_p; - } - } - } else { /* Attr is at a media level */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_INVALID_MEDIA_LEVEL); - } - - attr_p = mca_p->media_attrs_p; - while (attr_p != NULL) { - if ((attr_p->type == SDP_ATTR_INACTIVE) || - (attr_p->type == SDP_ATTR_SENDONLY) || - (attr_p->type == SDP_ATTR_RECVONLY) || - (attr_p->type == SDP_ATTR_SENDRECV)) { - - tmp_attr_p = attr_p; - - if (prev_attr_p == NULL) { - mca_p->media_attrs_p = attr_p->next_p; - } else { - prev_attr_p->next_p = attr_p->next_p; - } - attr_p = attr_p->next_p; - - sdp_free_attr(tmp_attr_p); - } else { - prev_attr_p = attr_p; - attr_p = attr_p->next_p; - } - } - } - - return (SDP_SUCCESS); -} - -/* Since there are four different attribute names which all have the same - * qos parameters, all of these attributes are accessed through this same - * set of APIs. To distinguish between specific attributes, the application - * must also pass the attribute type. The attribute must be one of: - * SDP_ATTR_QOS, SDP_ATTR_SECURE, SDP_ATTR_X_PC_QOS, and SDP_ATTR_X_QOS. - */ -tinybool sdp_validate_qos_attr (sdp_attr_e qos_attr) -{ - if ((qos_attr == SDP_ATTR_QOS) || - (qos_attr == SDP_ATTR_SECURE) || - (qos_attr == SDP_ATTR_X_PC_QOS) || - (qos_attr == SDP_ATTR_X_QOS) || - (qos_attr == SDP_ATTR_CURR) || - (qos_attr == SDP_ATTR_DES) || - (qos_attr == SDP_ATTR_CONF)){ - return (TRUE); - } else { - return (FALSE); - } -} - -/* Function: sdp_attr_get_qos_strength - * Description: Returns the value of the qos attribute strength - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_QOS_STRENGTH_UNKNOWN is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: Qos strength value. - */ -sdp_qos_strength_e sdp_attr_get_qos_strength (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_QOS_STRENGTH_UNKNOWN); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified for" - "get qos strength.", sdp_p->debug_str); - } - return (SDP_QOS_STRENGTH_UNKNOWN); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_QOS_STRENGTH_UNKNOWN); - } else { - switch (qos_attr) { - case SDP_ATTR_QOS: - return (attr_p->attr.qos.strength); - case SDP_ATTR_DES: - return (attr_p->attr.des.strength); - default: - return SDP_QOS_STRENGTH_UNKNOWN; - - } - } -} - -/* Function: sdp_attr_get_qos_direction - * Description: Returns the value of the qos attribute direction - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_QOS_DIR_UNKNOWN is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: Qos direction value. - */ -sdp_qos_dir_e sdp_attr_get_qos_direction (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_QOS_DIR_UNKNOWN); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for get qos direction.", sdp_p->debug_str); - } - return (SDP_QOS_DIR_UNKNOWN); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_QOS_DIR_UNKNOWN); - } else { - switch (qos_attr) { - case SDP_ATTR_QOS: - return (attr_p->attr.qos.direction); - case SDP_ATTR_CURR: - return (attr_p->attr.curr.direction); - case SDP_ATTR_DES: - return (attr_p->attr.des.direction); - case SDP_ATTR_CONF: - return (attr_p->attr.conf.direction); - default: - return SDP_QOS_DIR_UNKNOWN; - - } - } -} - -/* Function: sdp_attr_get_qos_status_type - * Description: Returns the value of the qos attribute status_type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_QOS_STATUS_TYPE_UNKNOWN is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: Qos direction value. - */ -sdp_qos_status_types_e sdp_attr_get_qos_status_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_QOS_STATUS_TYPE_UNKNOWN); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for get qos status_type.", sdp_p->debug_str); - } - return (SDP_QOS_STATUS_TYPE_UNKNOWN); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_QOS_STATUS_TYPE_UNKNOWN); - } else { - switch (qos_attr) { - case SDP_ATTR_CURR: - return (attr_p->attr.curr.status_type); - case SDP_ATTR_DES: - return (attr_p->attr.des.status_type); - case SDP_ATTR_CONF: - return (attr_p->attr.conf.status_type); - default: - return SDP_QOS_STATUS_TYPE_UNKNOWN; - - } - } -} - -/* Function: sdp_attr_get_qos_confirm - * Description: Returns the value of the qos attribute confirm - * parameter specified for the given attribute. Returns TRUE if - * the confirm parameter is specified. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: Boolean value. - */ -tinybool sdp_attr_get_qos_confirm (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for get qos confirm.", sdp_p->debug_str); - } - return (FALSE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.qos.confirm); - } -} - -/* Function: sdp_attr_set_qos_strength - * Description: Sets the qos strength value for the specified qos attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * strength New qos strength parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_qos_strength (void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e qos_attr, u16 inst_num, - sdp_qos_strength_e strength) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for set qos strength.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - switch (qos_attr) { - case SDP_ATTR_QOS: - attr_p->attr.qos.strength = strength; - return (SDP_SUCCESS); - case SDP_ATTR_DES: - attr_p->attr.des.strength = strength; - return (SDP_SUCCESS); - default: - return (SDP_FAILURE); - - } - } -} - -/* Function: sdp_attr_get_curr_type - * Description: Returns the value of the curr attribute status_type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_CURR_UNKNOWN_TYPE is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: Curr type value. - */ -sdp_curr_type_e sdp_attr_get_curr_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_CURR_UNKNOWN_TYPE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_CURR_UNKNOWN_TYPE); - } else { - return (attr_p->attr.curr.type); - } -} - -/* Function: sdp_attr_get_des_type - * Description: Returns the value of the des attribute status_type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_DES_UNKNOWN_TYPE is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: DES type value. - */ -sdp_des_type_e sdp_attr_get_des_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_DES_UNKNOWN_TYPE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_DES_UNKNOWN_TYPE); - } else { - return (attr_p->attr.des.type); - } -} - -/* Function: sdp_attr_get_conf_type - * Description: Returns the value of the des attribute status_type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_CONF_UNKNOWN_TYPE is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: CONF type value. - */ -sdp_conf_type_e sdp_attr_get_conf_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_CONF_UNKNOWN_TYPE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_CONF_UNKNOWN_TYPE); - } else { - return (attr_p->attr.conf.type); - } -} - -/* Function: sdp_attr_set_curr_type - * Description: Returns the value of the curr attribute status_type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_CURR_UNKNOWN_TYPE is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_curr_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - sdp_curr_type_e curr_type) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid curr attribute specified " - "for set curr type.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.curr.type = curr_type; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_des_type - * Description: Sets the value of the des attribute type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_DES_UNKNOWN_TYPE is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_des_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - sdp_des_type_e des_type) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid des attribute specified " - "for set des type.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.des.type = des_type; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_set_conf_type - * Description: Sets the value of the conf attribute type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_CONF_UNKNOWN_TYPE is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_conf_type (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e qos_attr, u16 inst_num, - sdp_conf_type_e conf_type) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid conf attribute specified " - "for set conf type.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.conf.type = conf_type; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_qos_direction - * Description: Sets the qos direction value for the specified qos attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * direction New qos direction parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_qos_direction (void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e qos_attr, u16 inst_num, - sdp_qos_dir_e direction) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for set qos direction.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - switch (qos_attr) { - case SDP_ATTR_QOS: - attr_p->attr.qos.direction = direction; - return (SDP_SUCCESS); - case SDP_ATTR_CURR: - attr_p->attr.curr.direction = direction; - return (SDP_SUCCESS); - case SDP_ATTR_DES: - attr_p->attr.des.direction = direction; - return (SDP_SUCCESS); - case SDP_ATTR_CONF: - attr_p->attr.conf.direction = direction; - return (SDP_SUCCESS); - default: - return (SDP_FAILURE); - - } - } -} - -/* Function: sdp_attr_set_qos_status_type - * Description: Sets the qos status_type value for the specified qos attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * direction New qos direction parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_qos_status_type (void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e qos_attr, u16 inst_num, - sdp_qos_status_types_e status_type) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for set qos status_type.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - switch (qos_attr) { - case SDP_ATTR_CURR: - attr_p->attr.curr.status_type = status_type; - return (SDP_SUCCESS); - case SDP_ATTR_DES: - attr_p->attr.des.status_type = status_type; - return (SDP_SUCCESS); - case SDP_ATTR_CONF: - attr_p->attr.conf.status_type = status_type; - return (SDP_SUCCESS); - default: - return (SDP_FAILURE); - - } - } -} - -/* Function: sdp_attr_set_qos_confirm - * Description: Sets the qos confirm value for the specified qos attribute. - * If this parameter is TRUE, the confirm parameter will be - * specified when the SDP description is built. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * confirm New qos confirm parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_qos_confirm (void *sdp_ptr, u16 level, u8 cap_num, - sdp_attr_e qos_attr, u16 inst_num, - tinybool qos_confirm) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for set qos confirm.", sdp_p->debug_str); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.qos.confirm = qos_confirm; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_get_subnet_nettype - * Description: Returns the value of the subnet attribute network type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_NT_INVALID is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Nettype value. - */ -sdp_nettype_e sdp_attr_get_subnet_nettype (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_NT_INVALID); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_NT_INVALID); - } else { - return (attr_p->attr.subnet.nettype); - } -} - -/* Function: sdp_attr_get_subnet_addrtype - * Description: Returns the value of the subnet attribute address type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_AT_INVALID is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Addrtype value. - */ -sdp_addrtype_e sdp_attr_get_subnet_addrtype (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_AT_INVALID); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_AT_INVALID); - } else { - return (attr_p->attr.subnet.addrtype); - } -} - -/* Function: sdp_attr_get_subnet_addr - * Description: Returns the value of the subnet attribute address - * parameter specified for the given attribute. If the given - * attribute is not defined, NULL is returned. Value is - * returned as a const ptr and so cannot be modified by the - * application. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Pointer to address or NULL. - */ -const char *sdp_attr_get_subnet_addr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } else { - return (attr_p->attr.subnet.addr); - } -} - -/* Function: sdp_attr_get_subnet_prefix - * Description: Returns the value of the subnet attribute prefix - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_INVALID_PARAM is returned. - * Note that this is value is defined to be (-2) and is - * different from the return code SDP_INVALID_PARAMETER. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Prefix value or SDP_INVALID_PARAM. - */ -int32 sdp_attr_get_subnet_prefix (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.subnet.prefix); - } -} - -/* Function: sdp_attr_set_subnet_nettype - * Description: Sets the value of the subnet attribute nettype parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * nettype The network type for the attribute. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_subnet_nettype (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_nettype_e nettype) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.subnet.nettype = nettype; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_subnet_addrtype - * Description: Sets the value of the subnet attribute addrtype parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * addrtype The address type for the attribute. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_subnet_addrtype (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_addrtype_e sdp_addrtype) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.subnet.addrtype = sdp_addrtype; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_subnet_addr - * Description: Sets the value of the subnet attribute addr parameter - * for the given attribute. The address is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * addr Ptr to the address string for the attribute. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_subnet_addr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *addr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - sstrncpy(attr_p->attr.subnet.addr, addr, - sizeof(attr_p->attr.subnet.addr)) ; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_subnet_prefix - * Description: Sets the value of the subnet attribute prefix parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * prefix Prefix value for the attribute. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_subnet_prefix (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - int32 prefix) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.subnet.prefix = prefix; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_rtpmap_payload_valid - * Description: Returns true or false depending on whether an rtpmap - * attribute was specified with the given payload value - * at the given level. If it was, the instance number of - * that attribute is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number of the attribute - * found is returned via this param. - * Returns: TRUE or FALSE. - */ -tinybool sdp_attr_rtpmap_payload_valid (void *sdp_ptr, u16 level, u8 cap_num, - u16 *inst_num, u16 payload_type) -{ - u16 i; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - u16 num_instances; - - *inst_num = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (sdp_attr_num_instances(sdp_ptr, level, cap_num, - SDP_ATTR_RTPMAP, &num_instances) != SDP_SUCCESS) { - return (FALSE); - } - - for (i=1; i <= num_instances; i++) { - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, i); - if ((attr_p != NULL) && - (attr_p->attr.transport_map.payload_num == payload_type)) { - *inst_num = i; - return (TRUE); - } - } - - return (FALSE); -} - -/* Function: sdp_attr_get_rtpmap_payload_type - * Description: Returns the value of the rtpmap attribute payload type - * parameter specified for the given attribute. If the given - * attribute is not defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Payload type value. - */ -u16 sdp_attr_get_rtpmap_payload_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.transport_map.payload_num); - } -} - -/* Function: sdp_attr_get_rtpmap_encname - * Description: Returns a pointer to the value of the encoding name - * parameter specified for the given attribute. Value is - * returned as a const ptr and so cannot be modified by the - * application. If the given attribute is not defined, NULL - * will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Codec value or SDP_CODEC_INVALID. - */ -const char *sdp_attr_get_rtpmap_encname (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } else { - return (attr_p->attr.transport_map.encname); - } -} - -/* Function: sdp_attr_get_rtpmap_clockrate - * Description: Returns the value of the rtpmap attribute clockrate - * parameter specified for the given attribute. If the given - * attribute is not defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Clockrate value. - */ -u32 sdp_attr_get_rtpmap_clockrate (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.transport_map.clockrate); - } -} - -/* Function: sdp_attr_get_rtpmap_num_chan - * Description: Returns the value of the rtpmap attribute num_chan - * parameter specified for the given attribute. If the given - * attribute is not defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Number of channels param or zero. - */ -u16 sdp_attr_get_rtpmap_num_chan (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.transport_map.num_chan); - } -} - -/* Function: sdp_attr_set_rtpmap_payload_type - * Description: Sets the value of the rtpmap attribute payload type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * payload_num New payload type value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_rtpmap_payload_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 payload_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.transport_map.payload_num = payload_num; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_rtpmap_encname - * Description: Sets the value of the rtpmap attribute encname parameter - * for the given attribute. String is copied into SDP memory. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * encname Ptr to string encoding name. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_rtpmap_encname (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, const char *encname) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (encname) { - sstrncpy(attr_p->attr.transport_map.encname, encname, - sizeof(attr_p->attr.transport_map.encname)); - } - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_ice_attribute - * Description: Returns the value of an ice attribute at a given level - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * ice_attrib Returns an ice attrib string - * Returns: - * SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_SDP_PTR SDP pointer invalid - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e sdp_attr_get_ice_attribute (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, - char **out) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, sdp_attr, inst_num); - if (attr_p != NULL) { - *out = attr_p->attr.ice_attr; - return (SDP_SUCCESS); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s ice attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - return (SDP_FAILURE); -} - -/* Function: sdp_attr_set_ice_attribute - * Description: Sets the value of an ice attribute parameter - * String is copied into SDP memory. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to set the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * ice_attrib ice attribute string to set - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_ice_attribute(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, const char *ice_attrib) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, sdp_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s ice attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (!ice_attrib) { - return (SDP_INVALID_PARAMETER); - } - - sstrncpy(attr_p->attr.ice_attr, ice_attrib, sizeof(attr_p->attr.ice_attr)); - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_rtcp_mux_attribute - * Description: Returns the value of an rtcp-mux attribute at a given level - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * rtcp_mux Returns an rtcp-mux attrib bool - * Returns: - * SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_SDP_PTR SDP pointer invalid - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_get_rtcp_mux_attribute (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, - tinybool *rtcp_mux) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, sdp_attr, inst_num); - if (attr_p != NULL) { - *rtcp_mux = attr_p->attr.boolean_val; - return (SDP_SUCCESS); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtcp-mux attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - return (SDP_FAILURE); -} - -/* Function: sdp_attr_set_rtcp_mux_attribute - * Description: Sets the value of an rtcp_mux attribute parameter - * String is copied into SDP memory. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to set the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * rtcp_mux rtcp-mux attribute bool to set - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_rtcp_mux_attribute(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, const tinybool rtcp_mux) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, sdp_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtcp-mux attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - attr_p->attr.boolean_val = rtcp_mux; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_dtls_fingerprint_attribute - * Description: Returns the value of dtls fingerprint attribute at a given level - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * dtls_fingerprint Returns an dtls fingerprint attrib string - * Returns: - * SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_SDP_PTR SDP pointer invalid - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_get_dtls_fingerprint_attribute (void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, - char **out) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, sdp_attr, inst_num); - if (attr_p != NULL) { - *out = attr_p->attr.string_val; - return (SDP_SUCCESS); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s dtls fingerprint attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - return (SDP_FAILURE); -} - -/* Function: sdp_attr_set_dtls_fingerprint_attribute - * Description: Sets the value of a dtls fingerprint attribute parameter - * String is copied into SDP memory. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to set the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * dtls_fingerprint fingerprint attribute string to set - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_dtls_fingerprint_attribute(void *sdp_ptr, u16 level, - u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, const char *dtls_fingerprint) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, sdp_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s dtls fingerprint attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (!dtls_fingerprint) { - return (SDP_INVALID_PARAMETER); - } - - sstrncpy(attr_p->attr.string_val, dtls_fingerprint, sizeof(attr_p->attr.string_val)); - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_rtpmap_clockrate - * Description: Sets the value of the rtpmap attribute clockrate parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * clockrate New clockrate value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_rtpmap_clockrate (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 clockrate) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.transport_map.clockrate = clockrate; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_rtpmap_num_chan - * Description: Sets the value of the rtpmap attribute num_chan parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * num_chan New number of channels value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_rtpmap_num_chan (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 num_chan) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.transport_map.num_chan = num_chan; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_sprtmap_payload_valid - * Description: Returns true or false depending on whether an sprtmap - * attribute was specified with the given payload value - * at the given level. If it was, the instance number of - * that attribute is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number of the attribute - * found is returned via this param. - * Returns: TRUE or FALSE. - */ -tinybool sdp_attr_sprtmap_payload_valid (void *sdp_ptr, u16 level, u8 cap_num, - u16 *inst_num, u16 payload_type) -{ - u16 i; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - u16 num_instances; - - *inst_num = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (sdp_attr_num_instances(sdp_ptr, level, cap_num, - SDP_ATTR_SPRTMAP, &num_instances) != SDP_SUCCESS) { - return (FALSE); - } - - for (i=1; i <= num_instances; i++) { - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, i); - if ((attr_p != NULL) && - (attr_p->attr.transport_map.payload_num == payload_type)) { - *inst_num = i; - return (TRUE); - } - } - - return (FALSE); -} - -/* Function: sdp_attr_get_sprtmap_payload_type - * Description: Returns the value of the sprtmap attribute payload type - * parameter specified for the given attribute. If the given - * attribute is not defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Payload type value. - */ -u16 sdp_attr_get_sprtmap_payload_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s sprtmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.transport_map.payload_num); - } -} - -/* Function: sdp_attr_get_sprtmap_encname - * Description: Returns a pointer to the value of the encoding name - * parameter specified for the given attribute. Value is - * returned as a const ptr and so cannot be modified by the - * application. If the given attribute is not defined, NULL - * will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Codec value or SDP_CODEC_INVALID. - */ -const char *sdp_attr_get_sprtmap_encname (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s sprtmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } else { - return (attr_p->attr.transport_map.encname); - } -} - -/* Function: sdp_attr_get_sprtmap_clockrate - * Description: Returns the value of the sprtmap attribute clockrate - * parameter specified for the given attribute. If the given - * attribute is not defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Clockrate value. - */ -u32 sdp_attr_get_sprtmap_clockrate (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s sprtmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.transport_map.clockrate); - } -} - -/* Function: sdp_attr_get_sprtmap_num_chan - * Description: Returns the value of the sprtmap attribute num_chan - * parameter specified for the given attribute. If the given - * attribute is not defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Number of channels param or zero. - */ -u16 sdp_attr_get_sprtmap_num_chan (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s sprtmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.transport_map.num_chan); - } -} - -/* Function: sdp_attr_set_sprtmap_payload_type - * Description: Sets the value of the sprtmap attribute payload type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * payload_num New payload type value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_sprtmap_payload_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 payload_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s sprtmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.transport_map.payload_num = payload_num; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_sprtmap_encname - * Description: Sets the value of the sprtmap attribute encname parameter - * for the given attribute. String is copied into SDP memory. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * encname Ptr to string encoding name. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_sprtmap_encname (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, const char *encname) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s sprtmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - sstrncpy(attr_p->attr.transport_map.encname, encname, - sizeof(attr_p->attr.transport_map.encname)); - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_sprtmap_clockrate - * Description: Sets the value of the sprtmap attribute clockrate parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * clockrate New clockrate value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_sprtmap_clockrate (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 clockrate) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s sprtmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.transport_map.clockrate = clockrate; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_sprtmap_num_chan - * Description: Sets the value of the sprtmap attribute num_chan parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * num_chan New number of channels value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_sprtmap_num_chan (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 num_chan) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SPRTMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s sprtmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.transport_map.num_chan = num_chan; - return (SDP_SUCCESS); - } -} - -/* Note: The fmtp attribute formats currently handled are: - * fmtp: ,... - * fmtp: [annexa=yes/no] [annexb=yes/no] [bitrate=] - * where "value" is a numeric value > 0 - * where each event is a single number or a range separated - * by a '-'. - * Example: fmtp:101 1,3-15,20 - */ - -/* Function: tinybool sdp_attr_fmtp_valid(void *sdp_ptr) - * Description: Returns true or false depending on whether an fmtp - * attribute was specified with the given payload value - * at the given level. If it was, the instance number of - * that attribute is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: TRUE or FALSE. - */ -tinybool sdp_attr_fmtp_payload_valid (void *sdp_ptr, u16 level, u8 cap_num, - u16 *inst_num, u16 payload_type) -{ - u16 i; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - u16 num_instances; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if (sdp_attr_num_instances(sdp_ptr, level, cap_num, - SDP_ATTR_FMTP, &num_instances) != SDP_SUCCESS) { - return (FALSE); - } - - for (i=1; i <= num_instances; i++) { - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, i); - if ((attr_p != NULL) && - (attr_p->attr.fmtp.payload_num == payload_type)) { - *inst_num = i; - return (TRUE); - } - } - - return (FALSE); -} - -/* Function: sdp_attr_get_fmtp_payload_type - * Description: Returns the value of the fmtp attribute payload type - * parameter specified for the given attribute. If the given - * attribute is not defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Payload type value. - */ -u16 sdp_attr_get_fmtp_payload_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.fmtp.payload_num); - } -} - - -/* Function: sdp_attr_fmtp_is_range_set - * Description: Determines if a range of events is set in an fmtp attribute. - * The overall range for events is 0-255. - * This will return either FULL_MATCH, PARTIAL_MATCH, or NO_MATCH - * depending on whether all, some, or none of the specified - * events are defined. If the given attribute is not defined, - * NO_MATCH will be returned. It is up to the appl to verify - * the validity of the attribute before calling this routine. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * low_val Low value of the range. Range is 0-255. - * high_val High value of the range. - * Returns: SDP_FULL_MATCH, SDP_PARTIAL_MATCH, SDP_NO_MATCH - */ -sdp_ne_res_e sdp_attr_fmtp_is_range_set (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, u8 low_val, u8 high_val) -{ - u16 i; - u32 mapword; - u32 bmap; - u32 num_vals = 0; - u32 num_vals_set = 0; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_NO_MATCH); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_NO_MATCH); - } - - fmtp_p = &(attr_p->attr.fmtp); - for (i = low_val; i <= high_val; i++) { - num_vals++; - mapword = i/SDP_NE_BITS_PER_WORD; - bmap = SDP_NE_BIT_0 << (i%32); - if (fmtp_p->bmap[ mapword ] & bmap) { - num_vals_set++; - } - } - - if (num_vals == num_vals_set) { - return (SDP_FULL_MATCH); - } else if (num_vals_set == 0) { - return (SDP_NO_MATCH); - } else { - return (SDP_PARTIAL_MATCH); - } -} - -/* Function: sdp_attr_fmtp_valid - * Description: Determines the validity of the events in the fmtp. - * The overall range for events is 0-255. - * The user passes an event list with valid events supported by Appl. - * This routine will do a simple AND comparison and report the result. - * - * This will return TRUE if ftmp events are valid, and FALSE otherwise. - * It is up to the appl to verify the validity of the attribute - * before calling this routine. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * appl_maxval Max event value supported by Appl. Range is 0-255. - * evt_array Bitmap containing events supported by application. - * Returns: TRUE, FALSE - */ -tinybool -sdp_attr_fmtp_valid(void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, u16 appl_maxval, u32* evt_array) -{ - u16 i; - u32 mapword; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return FALSE; - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return FALSE; - } - - fmtp_p = &(attr_p->attr.fmtp); - - /* Do quick test. If application max value is lower than fmtp's then error */ - if (fmtp_p->maxval > appl_maxval) - return FALSE; - - /* Ok, events are within range. Now check that only - * allowed events have been received - */ - mapword = appl_maxval/SDP_NE_BITS_PER_WORD; - for (i=0; ibmap[i] & ~(evt_array[i])) { - /* Remote SDP is requesting events not supported by Application */ - return FALSE; - } - } - return TRUE; -} - -/* Function: sdp_attr_set_fmtp_payload_type - * Description: Sets the value of the fmtp attribute payload type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * payload_type New payload type value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_payload_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 payload_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.fmtp.payload_num = payload_num; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_fmtp_bitmap - * Description: Set a range of named events for an fmtp attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * bmap The 8 word data array holding the bitmap - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_attr_set_fmtp_bitmap(void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *bmap, u32 maxval) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->maxval = maxval; - memcpy(fmtp_p->bmap, bmap, SDP_NE_NUM_BMAP_WORDS * sizeof(u32) ); - - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_fmtp_range - * Description: Get a range of named events for an fmtp attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * bmap The 8 word data array holding the bitmap - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_attr_get_fmtp_range (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, u32 *bmap) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - memcpy(bmap, fmtp_p->bmap, SDP_NE_NUM_BMAP_WORDS * sizeof(u32) ); - - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_range - * Description: Set a range of named events for an fmtp attribute. The low - * value specified must be <= the high value. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * low_val The low value of the range. Range is 0-255. - * high_val The high value of the range. May be == low. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_attr_set_fmtp_range (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, u8 low_val, u8 high_val) -{ - u16 i; - u32 mapword; - u32 bmap; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - for (i = low_val; i <= high_val; i++) { - mapword = i/SDP_NE_BITS_PER_WORD; - bmap = SDP_NE_BIT_0 << (i%32); - fmtp_p->bmap[ mapword ] |= bmap; - } - if (high_val > fmtp_p->maxval) { - fmtp_p->maxval = high_val; - } - fmtp_p->fmtp_format = SDP_FMTP_NTE; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_clear_fmtp_range - * Description: Clear a range of named events for an fmtp attribute. The low - * value specified must be <= the high value. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * low_val The low value of the range. Range is 0-255 - * high_val The high value of the range. May be == low. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_attr_clear_fmtp_range (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, u8 low_val, u8 high_val) -{ - u16 i; - u32 mapword; - u32 bmap; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - for (i = low_val; i <= high_val; i++) { - mapword = i/SDP_NE_BITS_PER_WORD; - bmap = SDP_NE_BIT_0 << (i%32); - fmtp_p->bmap[ mapword ] &= ~bmap; - } - if (high_val > fmtp_p->maxval) { - fmtp_p->maxval = high_val; - } - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_compare_fmtp_ranges - * Description: Compare the named events set of two fmtp attributes. If all - * events are the same (either set or not), FULL_MATCH will be - * returned. If no events match, NO_MATCH will be returned. - * Otherwise PARTIAL_MATCH will be returned. If either attr is - * invalid, NO_MATCH will be returned. - * Parameters: src_sdp_ptr The SDP handle returned by sdp_init_description. - * dst_sdp_ptr The SDP handle returned by sdp_init_description. - * src_level The level of the src fmtp attribute. - * dst_level The level to the dst fmtp attribute. - * src_cap_num The capability number of the src attr. - * dst_cap_num The capability number of the dst attr. - * src_inst_numh The attribute instance of the src attr. - * dst_inst_numh The attribute instance of the dst attr. - * Returns: SDP_FULL_MATCH, SDP_PARTIAL_MATCH, SDP_NO_MATCH. - */ -sdp_ne_res_e sdp_attr_compare_fmtp_ranges (void *src_sdp_ptr,void *dst_sdp_ptr, - u16 src_level, u16 dst_level, - u8 src_cap_num, u8 dst_cap_num, - u16 src_inst_num, u16 dst_inst_num) -{ - u16 i,j; - u32 bmap; - u32 num_vals_match = 0; - sdp_t *src_sdp_p = (sdp_t *)src_sdp_ptr; - sdp_t *dst_sdp_p = (sdp_t *)dst_sdp_ptr; - sdp_attr_t *src_attr_p; - sdp_attr_t *dst_attr_p; - sdp_fmtp_t *src_fmtp_p; - sdp_fmtp_t *dst_fmtp_p; - - if ((sdp_verify_sdp_ptr(src_sdp_p) == FALSE) || - (sdp_verify_sdp_ptr(dst_sdp_p) == FALSE)) { - return (SDP_NO_MATCH); - } - - src_attr_p = sdp_find_attr(src_sdp_p, src_level, src_cap_num, - SDP_ATTR_FMTP, src_inst_num); - dst_attr_p = sdp_find_attr(dst_sdp_p, dst_level, dst_cap_num, - SDP_ATTR_FMTP, dst_inst_num); - if ((src_attr_p == NULL) || (dst_attr_p == NULL)) { - if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s source or destination fmtp attribute for " - "compare not found.", src_sdp_p->debug_str); - } - src_sdp_p->conf_p->num_invalid_param++; - return (SDP_NO_MATCH); - } - - src_fmtp_p = &(src_attr_p->attr.fmtp); - dst_fmtp_p = &(dst_attr_p->attr.fmtp); - for (i = 0; i < SDP_NE_NUM_BMAP_WORDS; i++) { - for (j = 0; j < SDP_NE_BITS_PER_WORD; j++) { - bmap = SDP_NE_BIT_0 << j; - if ((src_fmtp_p->bmap[i] & bmap) && (dst_fmtp_p->bmap[i] & bmap)) { - num_vals_match++; - } else if ((!(src_fmtp_p->bmap[i] & bmap)) && - (!(dst_fmtp_p->bmap[i] & bmap))) { - num_vals_match++; - } - } - } - - if (num_vals_match == (SDP_NE_NUM_BMAP_WORDS * SDP_NE_BITS_PER_WORD)) { - return (SDP_FULL_MATCH); - } else if (num_vals_match == 0) { - return (SDP_NO_MATCH); - } else { - return (SDP_PARTIAL_MATCH); - } -} - -/* Function: sdp_attr_copy_fmtp_ranges - * Description: Copy the named events set for one fmtp attribute to another. - * Parameters: src_sdp_ptr The SDP handle returned by sdp_init_description. - * dst_sdp_ptr The SDP handle returned by sdp_init_description. - * src_level The level of the src fmtp attribute. - * dst_level The level to the dst fmtp attribute. - * src_cap_num The capability number of the src attr. - * dst_cap_num The capability number of the dst attr. - * src_inst_numh The attribute instance of the src attr. - * dst_inst_numh The attribute instance of the dst attr. - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_attr_copy_fmtp_ranges (void *src_sdp_ptr, void *dst_sdp_ptr, - u16 src_level, u16 dst_level, - u8 src_cap_num, u8 dst_cap_num, - u16 src_inst_num, u16 dst_inst_num) -{ - u16 i; - sdp_t *src_sdp_p = (sdp_t *)src_sdp_ptr; - sdp_t *dst_sdp_p = (sdp_t *)dst_sdp_ptr; - sdp_attr_t *src_attr_p; - sdp_attr_t *dst_attr_p; - sdp_fmtp_t *src_fmtp_p; - sdp_fmtp_t *dst_fmtp_p; - - if ((sdp_verify_sdp_ptr(src_sdp_p) == FALSE) || - (sdp_verify_sdp_ptr(dst_sdp_p) == FALSE)) { - return (SDP_INVALID_SDP_PTR); - } - - src_attr_p = sdp_find_attr(src_sdp_p, src_level, src_cap_num, - SDP_ATTR_FMTP, src_inst_num); - dst_attr_p = sdp_find_attr(dst_sdp_p, dst_level, dst_cap_num, - SDP_ATTR_FMTP, dst_inst_num); - if ((src_attr_p == NULL) || (dst_attr_p == NULL)) { - if (src_sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s source or destination fmtp attribute for " - "copy not found.", src_sdp_p->debug_str); - } - src_sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - src_fmtp_p = &(src_attr_p->attr.fmtp); - dst_fmtp_p = &(dst_attr_p->attr.fmtp); - dst_fmtp_p->maxval = src_fmtp_p->maxval; - for (i = 0; i < SDP_NE_NUM_BMAP_WORDS; i++) { - dst_fmtp_p->bmap[i] = src_fmtp_p->bmap[i]; - } - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_annexa - * Description: Sets the value of the fmtp attribute annexa type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * annexa It is either yes or no. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_annexa (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool annexa) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annexa_required = TRUE; - fmtp_p->annexa = annexa; - - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_annexb - * Description: Sets the value of the fmtp attribute annexb type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * annexb It is either yes or no. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_annexb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool annexb) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->annexb_required = TRUE; - fmtp_p->annexb = annexb; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_fmtp_mode - * Description: Gets the value of the fmtp attribute mode parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * payload_type payload type. - * Returns: mode value - */ -u32 sdp_attr_get_fmtp_mode_for_payload_type (void *sdp_ptr, u16 level, - u8 cap_num, u32 payload_type) -{ - u16 num_a_lines = 0; - int i; - sdp_t *sdp_p = sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - /* - * Get number of FMTP attributes for the AUDIO line - */ - (void) sdp_attr_num_instances(sdp_p, level, cap_num, SDP_ATTR_FMTP, - &num_a_lines); - for (i = 0; i < num_a_lines; i++) { - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, (uint16_t) (i + 1)); - if ((attr_p != NULL) && - (attr_p->attr.fmtp.payload_num == (u16)payload_type)) { - if (attr_p->attr.fmtp.fmtp_format == SDP_FMTP_MODE) { - return attr_p->attr.fmtp.mode; - } - } - } - return 0; -} - -/* Function: sdp_attr_set_fmtp_mode - * Description: Sets the value of the fmtp attribute mode type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * mode in milli seconds - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_mode (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 mode) -{ - sdp_t *sdp_p = sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_MODE; - fmtp_p->mode = mode; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_bitrate_type - * Description: Sets the value of the fmtp attribute bitrate type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * bitrate Sets the bitrate value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_bitrate_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 bitrate) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (bitrate <= 0) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->bitrate = bitrate; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_cif - * Description: Sets the value of the fmtp attribute cif parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * cif Sets the CIF value for a video codec - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_cif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 cif) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if ((cif < SDP_MIN_CIF_VALUE) || ( cif > SDP_MAX_CIF_VALUE)) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->cif = cif; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_qcif - * Description: Sets the value of the fmtp attribute qcif parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * qcif Sets the QCIF value for a video codec - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_qcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 qcif) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if ((qcif < SDP_MIN_CIF_VALUE) || ( qcif > SDP_MAX_CIF_VALUE)) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->qcif = qcif; - return (SDP_SUCCESS); -} -/* Function: sdp_attr_set_fmtp_sqcif - * Description: Sets the value of the fmtp attribute sqcif parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * sqcif Sets the SQCIF value for a video codec - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_sqcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 sqcif) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if ((sqcif < SDP_MIN_CIF_VALUE) || (sqcif > SDP_MAX_CIF_VALUE)) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->sqcif = sqcif; - return (SDP_SUCCESS); -} - - -/* Function: sdp_attr_set_fmtp_cif4 - * Description: Sets the value of the fmtp attribute cif4 parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * sqcif Sets the cif4 value for a video codec - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_cif4 (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 cif4) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if ((cif4 < SDP_MIN_CIF_VALUE) || (cif4 > SDP_MAX_CIF_VALUE)) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->cif4 = cif4; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_cif16 - * Description: Sets the value of the fmtp attribute cif16 parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * cif16 Sets the cif16 value for a video codec - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_fmtp_cif16 (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 cif16) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if ((cif16 < SDP_MIN_CIF_VALUE) || (cif16 > SDP_MAX_CIF_VALUE)) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->cif16 = cif16; - return (SDP_SUCCESS); -} - - -/* Function: sdp_attr_set_fmtp_maxbr - * Description: Sets the value of the fmtp attribute maxbr parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * MAXBR Sets the MAXBR value for a video codec - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. -*/ - -sdp_result_e sdp_attr_set_fmtp_maxbr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 maxbr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (maxbr <= 0) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->maxbr = maxbr; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_custom - * Description: Sets the value of the fmtp attribute custom parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * CUSTOM Sets the CUSTOM value for a video codec - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. -*/ - -sdp_result_e sdp_attr_set_fmtp_custom (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 custom_x, u16 custom_y, u16 custom_mpi) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if ((custom_x <= 0) || (custom_y <= 0) || (custom_mpi <= 0)) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->custom_x = custom_x; - fmtp_p->custom_y = custom_y; - fmtp_p->custom_mpi = custom_mpi; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_par - * Description: Sets the value of the fmtp attribute PAR parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * PAR Sets the PAR width/height value - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. -*/ - -sdp_result_e sdp_attr_set_fmtp_par (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 par_width, u16 par_height) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if ((par_width <= 0) || (par_height <= 0)) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->par_width = par_width; - fmtp_p->par_height = par_height; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_cpcf - * Description: Sets the value of the fmtp attribute CPCF parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * CPCF Sets the CPCF value - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. -*/ - -sdp_result_e sdp_attr_set_fmtp_cpcf (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 cpcf) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (cpcf <= 0) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->cpcf = cpcf; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_bpp - * Description: Sets the value of the fmtp attribute BPP parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * BPP Sets the BPP value - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. -*/ - -sdp_result_e sdp_attr_set_fmtp_bpp (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 bpp) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (bpp <= 0) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->bpp = bpp; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_fmtp_hrd - * Description: Sets the value of the fmtp attribute HRD parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * HRD Sets the HRD value - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e sdp_attr_set_fmtp_hrd (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 hrd) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (hrd <= 0) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->hrd = hrd; - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_h263_num_params (void *sdp_ptr, int16 level, - u8 cap_num, u16 inst_num, - int16 profile, - u16 h263_level, - tinybool interlace) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if ((profile >= SDP_MIN_PROFILE_LEVEL_VALUE) && - (profile <= SDP_MAX_PROFILE_VALUE)) { - fmtp_p->profile = profile; - } - - if ((level >= SDP_MIN_PROFILE_LEVEL_VALUE) && - (level <= SDP_MAX_LEVEL_VALUE)) { - fmtp_p->level = h263_level; - } - - if (interlace) { - fmtp_p->is_interlace = TRUE; - } else { - fmtp_p->is_interlace = FALSE; - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_profile_level_id (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *profile_level_id) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - if (profile_level_id) { - sstrncpy(fmtp_p->profile_level_id, profile_level_id, - SDP_MAX_STRING_LEN+1); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_parameter_sets (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *parameter_sets) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - if (parameter_sets) { - sstrncpy(fmtp_p->parameter_sets, parameter_sets, SDP_MAX_STRING_LEN+1); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_pack_mode (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 pack_mode) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (pack_mode > SDP_MAX_PACKETIZATION_MODE_VALUE) { - return (SDP_INVALID_PARAMETER); - } - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->packetization_mode = pack_mode; - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_level_asymmetry_allowed (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 asym_allowed) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->level_asymmetry_allowed = asym_allowed; - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_deint_buf_req (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 deint_buf_req) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->deint_buf_req = deint_buf_req; - fmtp_p->flag |= SDP_DEINT_BUF_REQ_FLAG; - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_init_buf_time (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 init_buf_time) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->init_buf_time = init_buf_time; - fmtp_p->flag |= SDP_INIT_BUF_TIME_FLAG; - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_max_don_diff (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 max_don_diff) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->max_don_diff = max_don_diff; - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_interleaving_depth (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 interleaving_depth) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->interleaving_depth = interleaving_depth; - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_redundant_pic_cap (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool redundant_pic_cap) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (redundant_pic_cap > 1) { - return (SDP_FAILURE); - } else { - fmtp_p->redundant_pic_cap = redundant_pic_cap; - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_attr_set_fmtp_max_mbps (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 max_mbps) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (max_mbps > 0) { - fmtp_p->max_mbps = max_mbps; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } -} - -sdp_result_e sdp_attr_set_fmtp_max_fs (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 max_fs) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (max_fs > 0) { - fmtp_p->max_fs = max_fs; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } -} - -sdp_result_e sdp_attr_set_fmtp_max_br (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 max_br) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (max_br > 0) { - fmtp_p->max_br = max_br; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } -} - -sdp_result_e sdp_attr_set_fmtp_max_average_bitrate (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 maxaveragebitrate) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (maxaveragebitrate > 0) { - fmtp_p->maxaveragebitrate = maxaveragebitrate; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } -} - -/* Function: sdp_attr_get_fmtp_max_average_bitrate - * Description: Gets the value of the fmtp attribute- maxaveragebitrate parameter for the OPUS codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: max-br value. - */ - -sdp_result_e sdp_attr_get_fmtp_max_average_bitrate (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32* val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, 1); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.maxaveragebitrate; - return (SDP_SUCCESS); - } -} - - -sdp_result_e sdp_attr_set_fmtp_usedtx (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool usedtx) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (usedtx == TRUE) { - fmtp_p->usedtx = 1; - } else { - fmtp_p->usedtx = 0; - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_fmtp_usedtx - * Description: Gets the value of the fmtp attribute- usedtx parameter for the OPUS codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: usedtx value. - */ - -sdp_result_e sdp_attr_get_fmtp_usedtx (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, tinybool* val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = (tinybool)attr_p->attr.fmtp.usedtx; - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_attr_set_fmtp_stereo (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool stereo) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (stereo == TRUE) { - fmtp_p->stereo = 1; - } else { - fmtp_p->stereo = 0; - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_fmtp_usedtx - * Description: Gets the value of the fmtp attribute- usedtx parameter for the OPUS codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: stereo value. - */ - -sdp_result_e sdp_attr_get_fmtp_stereo (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, tinybool* val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = (tinybool)attr_p->attr.fmtp.stereo; - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_attr_set_fmtp_useinbandfec (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool useinbandfec) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (useinbandfec == TRUE) { - fmtp_p->useinbandfec = 1; - } else { - fmtp_p->useinbandfec = 0; - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_fmtp_useinbandfec - * Description: Gets the value of the fmtp attribute useinbandfec parameter for the OPUS codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: useinbandfec value. - */ - -sdp_result_e sdp_attr_get_fmtp_useinbandfec (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, tinybool* val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = (tinybool)attr_p->attr.fmtp.useinbandfec; - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_attr_set_fmtp_maxcodedaudiobandwidth (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *maxcodedaudiobandwidth) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - if (maxcodedaudiobandwidth) { - sstrncpy(fmtp_p->maxcodedaudiobandwidth, maxcodedaudiobandwidth, - SDP_MAX_STRING_LEN+1); - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_fmtp_maxcodedaudiobandwidth - * Description: Gets the value of the fmtp attribute maxcodedaudiobandwidth parameter for OPUS codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: maxcodedaudiobandwidth value. - */ -char* sdp_attr_get_fmtp_maxcodedaudiobandwidth (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.fmtp.maxcodedaudiobandwidth); - } -} - -sdp_result_e sdp_attr_set_fmtp_cbr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool cbr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (cbr == TRUE) { - fmtp_p->cbr = 1; - } else { - fmtp_p->cbr = 0; - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_fmtp_cbr - * Description: Gets the value of the fmtp attribute cbr parameter for the OPUS codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: cbr value. - */ - -sdp_result_e sdp_attr_get_fmtp_cbr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, tinybool* val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = (tinybool)attr_p->attr.fmtp.cbr; - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_attr_get_fmtp_streams (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32* val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (!attr_p) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.streams; - return (SDP_SUCCESS); - } -} - -sdp_result_e sdp_attr_set_fmtp_streams (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 streams) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (!attr_p) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_DATACHANNEL; - - if (streams > 0) { - fmtp_p->streams = streams; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } -} - -sdp_result_e sdp_attr_set_fmtp_data_channel_protocol (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *protocol) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (!attr_p) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_DATACHANNEL; - if (protocol) { - sstrncpy(fmtp_p->protocol, protocol, - SDP_MAX_STRING_LEN+1); - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_get_fmtp_data_channel_protocol (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, char* protocol) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (!attr_p) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - sstrncpy(protocol, attr_p->attr.fmtp.protocol, SDP_MAX_STRING_LEN+1); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_max_cpb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 max_cpb) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (max_cpb > 0) { - fmtp_p->max_cpb = max_cpb; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } -} - -sdp_result_e sdp_attr_set_fmtp_max_dpb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 max_dpb) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - if (max_dpb > 0) { - fmtp_p->max_dpb = max_dpb; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } -} - -sdp_result_e sdp_attr_set_fmtp_max_rcmd_nalu_size (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 max_rcmd_nalu_size) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->max_rcmd_nalu_size = max_rcmd_nalu_size; - fmtp_p->flag |= SDP_MAX_RCMD_NALU_SIZE_FLAG; - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_deint_buf_cap (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 deint_buf_cap) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->deint_buf_cap = deint_buf_cap; - fmtp_p->flag |= SDP_DEINT_BUF_CAP_FLAG; - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_h264_parameter_add (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool parameter_add) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - fmtp_p->parameter_add = parameter_add; - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_h261_annex_params (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool annex_d) { - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - fmtp_p->annex_d = annex_d; - return (SDP_SUCCESS); -} - -sdp_result_e sdp_attr_set_fmtp_h263_annex_params (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool annex_f, - tinybool annex_i, - tinybool annex_j, - tinybool annex_t, - u16 annex_k_val, - u16 annex_n_val, - u16 annex_p_val_picture_resize, - u16 annex_p_val_warp) - -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_fmtp_t *fmtp_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - fmtp_p = &(attr_p->attr.fmtp); - fmtp_p->fmtp_format = SDP_FMTP_CODEC_INFO; - - fmtp_p->annex_f = annex_f; - fmtp_p->annex_i = annex_i; - fmtp_p->annex_j = annex_j; - fmtp_p->annex_t = annex_t; - - fmtp_p->annex_k_val = annex_k_val; - fmtp_p->annex_n_val = annex_n_val; - - fmtp_p->annex_p_val_picture_resize = annex_p_val_picture_resize; - fmtp_p->annex_p_val_warp = annex_p_val_warp; - - return (SDP_SUCCESS); -} - - - -/* Function: sdp_attr_fmtp_is_annexb_set - * Description: Gives the value of the fmtp attribute annexb type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * - * - * Returns: TRUE or FALSE. - */ -tinybool sdp_attr_fmtp_is_annexb_set (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.fmtp.annexb); - } -} - -/* Function: sdp_attr_fmtp_is_annexa_set - * Description: Gives the value of the fmtp attribute annexa type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * - * - * Returns: TRUE or FALSE. - */ -tinybool sdp_attr_fmtp_is_annexa_set (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.fmtp.annexa); - } -} - -/* Function: sdp_attr_get_fmtp_bitrate_type - * Description: Gets the value of the fmtp attribute bitrate type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Bitrate type value. - */ -int32 sdp_attr_get_fmtp_bitrate_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.bitrate); - } -} - -/* Function: sdp_attr_get_fmtp_qcif - * Description: Gets the value of the fmtp attribute QCIF type parameter - * for a given Video codec. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: QCIF value. - */ -int32 sdp_attr_get_fmtp_qcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.qcif); - } -} -/* Function: sdp_attr_get_fmtp_cif - * Description: Gets the value of the fmtp attribute CIF type parameter - * for a given Video codec. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: CIF value. - */ -int32 sdp_attr_get_fmtp_cif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.cif); - } -} - - -/* Function: sdp_attr_get_fmtp_sqcif - * Description: Gets the value of the fmtp attribute sqcif type parameter - * for a given Video codec. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: sqcif value. - */ -int32 sdp_attr_get_fmtp_sqcif (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.sqcif); - } -} - -/* Function: sdp_attr_get_fmtp_cif4 - * Description: Gets the value of the fmtp attribute CIF4 type parameter - * for a given Video codec. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: CIF4 value. - */ -int32 sdp_attr_get_fmtp_cif4 (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.cif4); - } -} - -/* Function: sdp_attr_get_fmtp_cif16 - * Description: Gets the value of the fmtp attribute CIF16 type parameter - * for a given Video codec. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: CIF16 value. - */ - -int32 sdp_attr_get_fmtp_cif16 (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.cif16); - } -} - - -/* Function: sdp_attr_get_fmtp_maxbr - * Description: Gets the value of the fmtp attribute MAXBR type parameter - * for a given Video codec. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: MAXBR value. - */ -int32 sdp_attr_get_fmtp_maxbr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.maxbr); - } -} - -/* Function: sdp_attr_get_fmtp_custom_x - * Description: Gets the value of the fmtp attribute CUSTOM type parameter - * for a given Video codec. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: CUSTOM x value. - */ - -int32 sdp_attr_get_fmtp_custom_x (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.custom_x); - } -} -/* Function: sdp_attr_get_fmtp_custom_y - * Description: Gets the value of the fmtp attribute custom_y type parameter - * for a given Video codec. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: CUSTOM Y-AXIS value. - */ - -int32 sdp_attr_get_fmtp_custom_y (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.custom_y); - } -} - -/* Function: sdp_attr_get_fmtp_custom_mpi - * Description: Gets the value of the fmtp attribute CUSTOM type parameter - * for a given Video codec. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: CUSTOM MPI value. - */ - -int32 sdp_attr_get_fmtp_custom_mpi (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.custom_mpi); - } -} - -/* Function: sdp_attr_get_fmtp_par_width - * Description: Gets the value of the fmtp attribute PAR (width) parameter - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: PAR - width value. - */ -int32 sdp_attr_get_fmtp_par_width (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.par_width); - } -} - -/* Function: sdp_attr_get_fmtp_par_height - * Description: Gets the value of the fmtp attribute PAR (height) parameter - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: PAR - height value. - */ -int32 sdp_attr_get_fmtp_par_height (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.par_height); - } -} - -/* Function: sdp_attr_get_fmtp_cpcf - * Description: Gets the value of the fmtp attribute- CPCF parameter - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: CPCF value. - */ -int32 sdp_attr_get_fmtp_cpcf (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.cpcf); - } -} - -/* Function: sdp_attr_get_fmtp_bpp - * Description: Gets the value of the fmtp attribute- BPP parameter - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: BPP value. - */ -int32 sdp_attr_get_fmtp_bpp (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.bpp); - } -} - -/* Function: sdp_attr_get_fmtp_hrd - * Description: Gets the value of the fmtp attribute- HRD parameter - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: HRD value. - */ -int32 sdp_attr_get_fmtp_hrd (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.hrd); - } -} - -/* Function: sdp_attr_get_fmtp_profile - * Description: Gets the value of the fmtp attribute- PROFILE parameter - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: PROFILE value. - */ -int32 sdp_attr_get_fmtp_profile (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.profile); - } -} - -/* Function: sdp_attr_get_fmtp_level - * Description: Gets the value of the fmtp attribute- LEVEL parameter - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: LEVEL value. - */ -int32 sdp_attr_get_fmtp_level (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.level); - } -} - -/* Function: sdp_attr_get_fmtp_interlace - * Description: Checks if INTERLACE parameter is set. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: TRUE if INTERLACE is present and FALSE if INTERLACE is absent. - */ -tinybool sdp_attr_get_fmtp_interlace (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return FALSE; - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return FALSE; - } else { - return (attr_p->attr.fmtp.is_interlace); - } -} - -/* Function: sdp_attr_get_fmtp_pack_mode - * Description: Gets the value of the fmtp attribute- packetization-mode parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: packetization-mode value in the range 0 - 2. - */ - -sdp_result_e sdp_attr_get_fmtp_pack_mode (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 *val) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.packetization_mode; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_fmtp_level_asymmetry_allowed - * Description: Gets the value of the fmtp attribute- level-asymmetry-allowed parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: level asymmetry allowed value (0 or 1). - */ - -sdp_result_e sdp_attr_get_fmtp_level_asymmetry_allowed (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 *val) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.level_asymmetry_allowed; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_fmtp_profile_id - * Description: Gets the value of the fmtp attribute- profile-level-id parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: profile-level-id value. - */ -const char* sdp_attr_get_fmtp_profile_id (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.fmtp.profile_level_id); - } -} - -/* Function: sdp_attr_get_fmtp_param_sets - * Description: Gets the value of the fmtp attribute- parameter-sets parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: parameter-sets value. - */ -const char* sdp_attr_get_fmtp_param_sets (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.fmtp.parameter_sets); - } -} - -/* Function: sdp_attr_get_fmtp_interleaving_depth - * Description: Gets the value of the fmtp attribute- interleaving_depth parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: interleaving_depth value - */ - -sdp_result_e sdp_attr_get_fmtp_interleaving_depth (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16* val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.interleaving_depth; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_fmtp_deint_buf_req - * Description: Gets the value of the fmtp attribute- deint-buf-req parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: deint-buf-req value. - */ - -sdp_result_e sdp_attr_get_fmtp_deint_buf_req (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (attr_p->attr.fmtp.flag & SDP_DEINT_BUF_REQ_FLAG) { - *val = attr_p->attr.fmtp.deint_buf_req; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } - } -} - -/* Function: sdp_attr_get_fmtp_max_don_diff - * Description: Gets the value of the fmtp attribute- max-don-diff parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: max-don-diff value. - */ -sdp_result_e sdp_attr_get_fmtp_max_don_diff (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.max_don_diff; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_fmtp_init_buf_time - * Description: Gets the value of the fmtp attribute- init-buf-time parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: init-buf-time value. - */ -sdp_result_e sdp_attr_get_fmtp_init_buf_time (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (attr_p->attr.fmtp.flag & SDP_INIT_BUF_TIME_FLAG) { - *val = attr_p->attr.fmtp.init_buf_time; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } - } -} - -/* Function: sdp_attr_get_fmtp_max_mbps - * Description: Gets the value of the fmtp attribute- max-mbps parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: max-mbps value. - */ - -sdp_result_e sdp_attr_get_fmtp_max_mbps (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.max_mbps; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_fmtp_max_fs - * Description: Gets the value of the fmtp attribute- max-fs parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: max-fs value. - */ - -sdp_result_e sdp_attr_get_fmtp_max_fs (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.max_fs; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_fmtp_max_cpb - * Description: Gets the value of the fmtp attribute- max-cpb parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: max-cpb value. - */ - -sdp_result_e sdp_attr_get_fmtp_max_cpb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.max_cpb; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_fmtp_max_dpb - * Description: Gets the value of the fmtp attribute- max-dpb parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: max-dpb value. - */ - -sdp_result_e sdp_attr_get_fmtp_max_dpb (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32 *val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.max_dpb; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_get_fmtp_max_br - * Description: Gets the value of the fmtp attribute- max-br parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: max-br value. - */ - -sdp_result_e sdp_attr_get_fmtp_max_br (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u32* val) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - *val = attr_p->attr.fmtp.max_br; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_fmtp_is_redundant_pic_cap - * Description: Gets the value of the fmtp attribute- redundant_pic_cap parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: redundant-pic-cap value. - */ -tinybool sdp_attr_fmtp_is_redundant_pic_cap (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.fmtp.redundant_pic_cap); - } -} - -/* Function: sdp_attr_get_fmtp_deint_buf_cap - * Description: Gets the value of the fmtp attribute- deint-buf-cap parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: deint-buf-cap value. - */ - -sdp_result_e sdp_attr_get_fmtp_deint_buf_cap (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (attr_p->attr.fmtp.flag & SDP_DEINT_BUF_CAP_FLAG) { - *val = attr_p->attr.fmtp.deint_buf_cap; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } - } -} - -/* Function: sdp_attr_get_fmtp_max_rcmd_nalu_size - * Description: Gets the value of the fmtp attribute- max-rcmd-nalu-size parameter for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: max-rcmd-nalu-size value. - */ -sdp_result_e sdp_attr_get_fmtp_max_rcmd_nalu_size (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u32 *val) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (attr_p->attr.fmtp.flag & SDP_MAX_RCMD_NALU_SIZE_FLAG) { - *val = attr_p->attr.fmtp.max_rcmd_nalu_size; - return (SDP_SUCCESS); - } else { - return (SDP_FAILURE); - } - } -} - -/* Function: sdp_attr_fmtp_is_parameter_add - * Description: Gets the value of the fmtp attribute- parameter-add for H.264 codec - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: TRUE/FALSE ( parameter-add is boolean) - */ -tinybool sdp_attr_fmtp_is_parameter_add (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.fmtp.parameter_add); - } -} - -/****** Following functions are get routines for Annex values - * For each Annex support, the get routine will return the boolean TRUE/FALSE - * Some Annexures for Video codecs have values defined . In those cases, - * (e.g Annex K, P ) , the return values are not boolean. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Annex value - */ - -tinybool sdp_attr_get_fmtp_annex_d (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.fmtp.annex_d); - } -} - -tinybool sdp_attr_get_fmtp_annex_f (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.fmtp.annex_f); - } -} - -tinybool sdp_attr_get_fmtp_annex_i (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.fmtp.annex_i); - } -} - -tinybool sdp_attr_get_fmtp_annex_j (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.fmtp.annex_j); - } -} - -tinybool sdp_attr_get_fmtp_annex_t (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.fmtp.annex_t); - } -} - -int32 sdp_attr_get_fmtp_annex_k_val (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.annex_k_val); - } -} - -int32 sdp_attr_get_fmtp_annex_n_val (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.annex_n_val); - } -} - -int32 sdp_attr_get_fmtp_annex_p_picture_resize (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.annex_p_val_picture_resize); - } -} - -int32 sdp_attr_get_fmtp_annex_p_warp (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - return (attr_p->attr.fmtp.annex_p_val_warp); - } -} - -/* Function: sdp_attr_fmtp_get_fmtp_format - * Description: Gives the value of the fmtp attribute fmtp_format - * type parameter - * for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * - * - * Returns: Enum type sdp_fmtp_format_type_e - */ -sdp_fmtp_format_type_e sdp_attr_fmtp_get_fmtp_format (void *sdp_ptr, - u16 level, u8 cap_num, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_FMTP_UNKNOWN_TYPE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_FMTP, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s fmtp attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_FMTP_UNKNOWN_TYPE); - } else { - return (attr_p->attr.fmtp.fmtp_format); - } -} - -/* Function: sdp_attr_get_pccodec_num_payload_types - * Description: Returns the number of payload types specified for the - * given X-pc-codec attribute. If the given attribute is not - * defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Number of payload types. - */ -u16 sdp_attr_get_pccodec_num_payload_types (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_X_PC_CODEC, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-pc-codec attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.pccodec.num_payloads); - } -} - -/* Function: sdp_attr_get_pccodec_payload_type - * Description: Returns the value of the specified payload type for the - * given X-pc-codec attribute. If the given attribute is not - * defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * payload_num The payload number to get. Range is (1 - - * max num payloads). - * Returns: Payload type. - */ -u16 sdp_attr_get_pccodec_payload_type (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, u16 payload_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_X_PC_CODEC, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-pc-codec attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - if ((payload_num < 1) || - (payload_num > attr_p->attr.pccodec.num_payloads)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-pc-codec attribute, level %u instance %u, " - "invalid payload number %u requested.", - sdp_p->debug_str, level, inst_num, payload_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - return (attr_p->attr.pccodec.payload_type[payload_num-1]); - } - } -} - -/* Function: sdp_attr_add_pccodec_payload_type - * Description: Add a new value to the list of payload types specified for - * the given X-pc-codec attribute. The payload type will be - * added to the end of the list so these values should be added - * in the order they will be displayed within the attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * payload_type The payload type to add. - * Returns: SDP_SUCCESS Payload type was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_add_pccodec_payload_type (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 payload_type) -{ - u16 payload_num; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_X_PC_CODEC, - inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-pc-codec attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - payload_num = attr_p->attr.pccodec.num_payloads++; - attr_p->attr.pccodec.payload_type[payload_num] = payload_type; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_xcap_first_cap_num - * Description: Gets the first capability number valid for the specified - * X-cap attribute instance. If the capability is not - * defined, zero is returned. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the capability. - * inst_num The X-cap instance number to check. - * Returns: Capability number or zero. - */ -u16 sdp_attr_get_xcap_first_cap_num (void *sdp_ptr, u16 level, u16 inst_num) -{ - u16 cap_num=1; - u16 attr_count=0; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - if (level == SDP_SESSION_LEVEL) { - for (attr_p = sdp_p->sess_attrs_p; attr_p != NULL; - attr_p = attr_p->next_p) { - if (attr_p->type == SDP_ATTR_X_CAP) { - attr_count++; - if (attr_count == inst_num) { - return (cap_num); - } else { - cap_num += attr_p->attr.cap_p->num_payloads; - } - } - } - } else { /* Capability is at a media level */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (0); - } - for (attr_p = mca_p->media_attrs_p; attr_p != NULL; - attr_p = attr_p->next_p) { - if (attr_p->type == SDP_ATTR_X_CAP) { - attr_count++; - if (attr_count == inst_num) { - return (cap_num); - } else { - cap_num += attr_p->attr.cap_p->num_payloads; - } - } - } - } /* Attr is at a media level */ - - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-cap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); -} - -/* Function: sdp_attr_get_xcap_media_type - * Description: Returns the media type specified for the given X-cap - * attribute. If the given attribute is not defined, - * SDP_MEDIA_INVALID is returned. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * Returns: Media type or SDP_MEDIA_INVALID. - */ -sdp_media_e sdp_attr_get_xcap_media_type (void *sdp_ptr, u16 level, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cap_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_MEDIA_INVALID); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-cap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_MEDIA_INVALID); - } else { - cap_p = attr_p->attr.cap_p; - return (cap_p->media); - } -} - -/* Function: sdp_attr_get_xcap_transport_type - * Description: Returns the transport type specified for the given X-cap - * attribute. If the given attribute is not defined, - * SDP_TRANSPORT_INVALID is returned. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * Returns: Media type or SDP_TRANSPORT_INVALID. - */ -sdp_transport_e sdp_attr_get_xcap_transport_type (void *sdp_ptr, u16 level, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cap_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_TRANSPORT_INVALID); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, - inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-cap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_TRANSPORT_INVALID); - } else { - cap_p = attr_p->attr.cap_p; - return (cap_p->transport); - } -} - -/* Function: sdp_attr_get_xcap_num_payload_types - * Description: Returns the number of payload types associated with the - * specified X-cap attribute. If the attribute is invalid, - * zero will be returned. Application must validate the - * attribute line before using this routine. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Number of payload types or zero. - */ -u16 sdp_attr_get_xcap_num_payload_types (void *sdp_ptr, u16 level, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cap_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-cap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - cap_p = attr_p->attr.cap_p; - return (cap_p->num_payloads); - } -} - -/* Function: sdp_attr_get_xcap_payload_type - * Description: Returns the payload type of the specified payload for the - * X-cap attribute line. If the attr line or payload number is - * invalid, zero will be returned. Application must validate - * the X-cap attr before using this routine. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * payload_num The payload number to retrieve. Range is - * (1 - max num payloads). - * Returns: Payload type or zero. - */ -u16 sdp_attr_get_xcap_payload_type (void *sdp_ptr, u16 level, - u16 inst_num, u16 payload_num, - sdp_payload_ind_e *indicator) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cap_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-cap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - cap_p = attr_p->attr.cap_p; - if ((payload_num < 1) || - (payload_num > cap_p->num_payloads)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-cap attribute, level %u instance %u, " - "payload num %u invalid.", sdp_p->debug_str, - level, inst_num, payload_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - *indicator = cap_p->payload_indicator[payload_num-1]; - return (cap_p->payload_type[payload_num-1]); - } - } -} - - -/* Function: sdp_attr_set_xcap_media_type - * Description: Sets the value of the media type parameter for the X-cap - * attribute line. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * media Media type for the X-cap attribute. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_attr_set_xcap_media_type (void *sdp_ptr, u16 level, - u16 inst_num, sdp_media_e media) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cap_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-cap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - cap_p = attr_p->attr.cap_p; - cap_p->media = media; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_xcap_transport_type - * Description: Sets the value of the transport type parameter for the X-cap - * attribute line. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * transport Transport type for the X-cap attribute. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_attr_set_xcap_transport_type(void *sdp_ptr, u16 level, - u16 inst_num, - sdp_transport_e transport) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cap_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-cap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - cap_p = attr_p->attr.cap_p; - cap_p->transport = transport; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_add_xcap_payload_type - * Description: Add a new payload type for the X-cap attribute line - * specified. The new payload type will be added at the end - * of the payload type list. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * payload_type The new payload type. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_attr_add_xcap_payload_type(void *sdp_ptr, u16 level, - u16 inst_num, u16 payload_type, - sdp_payload_ind_e indicator) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cap_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_X_CAP, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-cap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - cap_p = attr_p->attr.cap_p; - cap_p->payload_indicator[cap_p->num_payloads] = indicator; - cap_p->payload_type[cap_p->num_payloads++] = payload_type; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_get_cdsc_first_cap_num - * Description: Gets the first capability number valid for the specified - * CDSC attribute instance. If the capability is not - * defined, zero is returned. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the capability. - * inst_num The CDSC instance number to check. - * Returns: Capability number or zero. - */ -u16 sdp_attr_get_cdsc_first_cap_num(void *sdp_ptr, u16 level, u16 inst_num) -{ - u16 cap_num=1; - u16 attr_count=0; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *mca_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - if (level == SDP_SESSION_LEVEL) { - for (attr_p = sdp_p->sess_attrs_p; attr_p != NULL; - attr_p = attr_p->next_p) { - if (attr_p->type == SDP_ATTR_CDSC) { - attr_count++; - if (attr_count == inst_num) { - return (cap_num); - } else { - cap_num += attr_p->attr.cap_p->num_payloads; - } - } - } - } else { /* Capability is at a media level */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (0); - } - for (attr_p = mca_p->media_attrs_p; attr_p != NULL; - attr_p = attr_p->next_p) { - if (attr_p->type == SDP_ATTR_CDSC) { - attr_count++; - if (attr_count == inst_num) { - return (cap_num); - } else { - cap_num += attr_p->attr.cap_p->num_payloads; - } - } - } - } /* Attr is at a media level */ - - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CDSC attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); -} - -/* Function: sdp_attr_get_cdsc_media_type - * Description: Returns the media type specified for the given CDSC - * attribute. If the given attribute is not defined, - * SDP_MEDIA_INVALID is returned. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * Returns: Media type or SDP_MEDIA_INVALID. - */ -sdp_media_e sdp_attr_get_cdsc_media_type(void *sdp_ptr, u16 level, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cdsc_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_MEDIA_INVALID); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CDSC attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_MEDIA_INVALID); - } else { - cdsc_p = attr_p->attr.cap_p; - return (cdsc_p->media); - } -} - -/* Function: sdp_attr_get_cdsc_transport_type - * Description: Returns the transport type specified for the given CDSC - * attribute. If the given attribute is not defined, - * SDP_TRANSPORT_INVALID is returned. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * Returns: Media type or SDP_TRANSPORT_INVALID. - */ -sdp_transport_e sdp_attr_get_cdsc_transport_type(void *sdp_ptr, u16 level, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cdsc_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_TRANSPORT_INVALID); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, - inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CDSC attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_TRANSPORT_INVALID); - } else { - cdsc_p = attr_p->attr.cap_p; - return (cdsc_p->transport); - } -} - -/* Function: sdp_attr_get_cdsc_num_payload_types - * Description: Returns the number of payload types associated with the - * specified CDSC attribute. If the attribute is invalid, - * zero will be returned. Application must validate the - * attribute line before using this routine. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Number of payload types or zero. - */ -u16 sdp_attr_get_cdsc_num_payload_types (void *sdp_ptr, u16 level, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cdsc_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CDSC attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - cdsc_p = attr_p->attr.cap_p; - return (cdsc_p->num_payloads); - } -} - -/* Function: sdp_attr_get_cdsc_payload_type - * Description: Returns the payload type of the specified payload for the - * CDSC attribute line. If the attr line or payload number is - * invalid, zero will be returned. Application must validate - * the CDSC attr before using this routine. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * payload_num The payload number to retrieve. Range is - * (1 - max num payloads). - * Returns: Payload type or zero. - */ -u16 sdp_attr_get_cdsc_payload_type (void *sdp_ptr, u16 level, - u16 inst_num, u16 payload_num, - sdp_payload_ind_e *indicator) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cdsc_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CDSC attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - cdsc_p = attr_p->attr.cap_p; - if ((payload_num < 1) || - (payload_num > cdsc_p->num_payloads)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CDSC attribute, level %u instance %u, " - "payload num %u invalid.", sdp_p->debug_str, - level, inst_num, payload_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - *indicator = cdsc_p->payload_indicator[payload_num-1]; - return (cdsc_p->payload_type[payload_num-1]); - } - } -} - -/* Function: sdp_attr_set_cdsc_media_type - * Description: Sets the value of the media type parameter for the CDSC - * attribute line. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * media Media type for the CDSC attribute. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_attr_set_cdsc_media_type (void *sdp_ptr, u16 level, - u16 inst_num, sdp_media_e media) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cdsc_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CDSC attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - cdsc_p = attr_p->attr.cap_p; - cdsc_p->media = media; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_set_cdsc_transport_type - * Description: Sets the value of the transport type parameter for the CDSC - * attribute line. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * transport Transport type for the CDSC attribute. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_attr_set_cdsc_transport_type (void *sdp_ptr, u16 level, - u16 inst_num, sdp_transport_e transport) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cdsc_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CDSC attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - cdsc_p = attr_p->attr.cap_p; - cdsc_p->transport = transport; - return (SDP_SUCCESS); -} - -/* Function: sdp_attr_add_cdsc_payload_type - * Description: Add a new payload type for the CDSC attribute line - * specified. The new payload type will be added at the end - * of the payload type list. - * Note: cap_num is not specified. It must be zero. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to check. - * payload_type The new payload type. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_attr_add_cdsc_payload_type (void *sdp_ptr, u16 level, - u16 inst_num, u16 payload_type, - sdp_payload_ind_e indicator) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - sdp_mca_t *cdsc_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_CDSC, inst_num); - if ((attr_p == NULL) || (attr_p->attr.cap_p == NULL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s CDSC attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - cdsc_p = attr_p->attr.cap_p; - cdsc_p->payload_indicator[cdsc_p->num_payloads] = indicator; - cdsc_p->payload_type[cdsc_p->num_payloads++] = payload_type; - return (SDP_SUCCESS); -} - -/* Function: sdp_media_dynamic_payload_valid - * Description: Checks if the dynamic payload type passed in is defined - * on the media line m_line - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * payload_type Payload type to be checked - * - * Returns: TRUE or FALSE. Returns TRUE if payload type is defined on the - * media line, else returns FALSE - */ - -tinybool sdp_media_dynamic_payload_valid (void *sdp_ptr, u16 payload_type, - u16 m_line) -{ - u16 p_type,m_ptype; - ushort num_payload_types; - sdp_payload_ind_e ind; - tinybool payload_matches = FALSE; - tinybool result = TRUE; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - if ((payload_type < SDP_MIN_DYNAMIC_PAYLOAD) || - (payload_type > SDP_MAX_DYNAMIC_PAYLOAD)) { - return FALSE; - } - - num_payload_types = - sdp_get_media_num_payload_types(sdp_p, m_line); - - for(p_type=1; p_type <=num_payload_types;p_type++){ - - m_ptype = (u16)sdp_get_media_payload_type(sdp_p, - m_line, p_type, &ind); - if (payload_type == m_ptype) { - payload_matches = TRUE; - break; - } - - } - - if (!payload_matches) { - return FALSE; - } - - return (result); - -} - -/* Function: sdp_attr_set_rtr_confirm - * Description: Sets the rtr confirm value a= rtr:confirm. - * If this parameter is TRUE, the confirm parameter will be - * specified when the SDP description is built. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * confirm New qos confirm parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_rtr_confirm (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, - tinybool confirm) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTR, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(SDP_ATTR_RTR), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.rtr.confirm = confirm; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_rtr_confirm - * Description: Returns the value of the rtr attribute confirm - * parameter specified for the given attribute. Returns TRUE if - * the confirm parameter is specified. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Boolean value. - */ -tinybool sdp_attr_get_rtr_confirm (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTR, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(SDP_ATTR_RTR), level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.rtr.confirm); - } -} - - - -sdp_mediadir_role_e sdp_attr_get_comediadir_role (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_MEDIADIR_ROLE_UNKNOWN); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_DIRECTION, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Comediadir role attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_MEDIADIR_ROLE_UNKNOWN); - } else { - return (attr_p->attr.comediadir.role); - } -} - -/* Function: sdp_attr_set_comediadir_role - * Description: Sets the value of the comediadir role parameter - * for the direction attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * comediadir_role The role of the comedia direction attribute - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_comediadir_role (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_mediadir_role_e comediadir_role) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_DIRECTION, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Comediadir role attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.comediadir.role = comediadir_role; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_silencesupp_enabled - * Description: Returns the value of the silencesupp attribute enable - * parameter specified for the given attribute. Returns TRUE if - * the confirm parameter is specified. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Boolean value. - */ -tinybool sdp_attr_get_silencesupp_enabled (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (FALSE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silenceSuppEnable attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (FALSE); - } else { - return (attr_p->attr.silencesupp.enabled); - } -} - -/* Function: sdp_attr_get_silencesupp_timer - * Description: Returns the value of the silencesupp attribute timer - * parameter specified for the given attribute. null_ind - * is set to TRUE if no value was specified, but instead the - * null "-" value was specified. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: 16-bit timer value - * boolean null_ind - */ -u16 sdp_attr_get_silencesupp_timer (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool *null_ind) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silenceTimer attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - *null_ind = attr_p->attr.silencesupp.timer_null; - return (attr_p->attr.silencesupp.timer); - } -} - -/* Function: sdp_attr_get_silencesupp_pref - * Description: Sets the silencesupp supppref value - * If this parameter is TRUE, the confirm parameter will be - * specified when the SDP description is built. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * confirm New qos confirm parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_silencesupp_pref_e sdp_attr_get_silencesupp_pref (void *sdp_ptr, - u16 level, u8 cap_num, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_SILENCESUPP_PREF_UNKNOWN); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silence suppPref attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_SILENCESUPP_PREF_UNKNOWN); - } else { - return (attr_p->attr.silencesupp.pref); - } -} - -/* Function: sdp_attr_get_silencesupp_siduse - * Description: Returns the value of the silencesupp attribute siduse - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_QOS_STRENGTH_UNKNOWN is - * returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: silencesupp siduse enum. - */ -sdp_silencesupp_siduse_e sdp_attr_get_silencesupp_siduse (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_SILENCESUPP_SIDUSE_UNKNOWN); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silence sidUse attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_SILENCESUPP_SIDUSE_UNKNOWN); - } else { - return (attr_p->attr.silencesupp.siduse); - } -} - -/* Function: sdp_attr_get_silencesupp_fxnslevel - * Description: Returns the value of the silencesupp attribute fxns - * (fixed noise) parameter specified for the given attribute. - * null_ind is set to TRUE if no value was specified, - * but instead the null "-" value was specified. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: 7-bit fxns value - * boolean null_ind - */ -u8 sdp_attr_get_silencesupp_fxnslevel (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool *null_ind) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silence fxnslevel attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - *null_ind = attr_p->attr.silencesupp.fxnslevel_null; - return (attr_p->attr.silencesupp.fxnslevel); - } -} - -/* Function: sdp_attr_set_silencesupp_enabled - * Description: Sets the silencesupp enable value - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * confirm New silencesupp enable parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_silencesupp_enabled (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - tinybool enable) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silenceSuppEnable attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.silencesupp.enabled = enable; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_silencesupp_timer - * Description: Sets the silencesupp timer value - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * value New silencesupp timer parameter. - * null_ind if TRUE, timer value is set to "-" instead of - * the 16 bit numeric value - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_silencesupp_timer (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 value, tinybool null_ind) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silenceTimer attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.silencesupp.timer = value; - attr_p->attr.silencesupp.timer_null = null_ind; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_silencesupp_pref - * Description: Sets the silencesupp supppref value - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * pref New silencesupp supppref parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_silencesupp_pref (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_silencesupp_pref_e pref) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silence SuppPref attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.silencesupp.pref = pref; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_silencesupp_siduse - * Description: Sets the silencesupp supppref value - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * siduse New silencesupp siduse parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_silencesupp_siduse (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_silencesupp_siduse_e siduse) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silence sidUse attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.silencesupp.siduse = siduse; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_silencesupp_fxnslevel - * Description: Sets the silencesupp timer value - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * value New silencesupp timer parameter. - * null_ind if TRUE, timer value is set to "-" instead of - * the 16 bit numeric value - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_silencesupp_fxnslevel (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 value, tinybool null_ind) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SILENCESUPP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s silenceTimer attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.silencesupp.fxnslevel = (u8)value; - attr_p->attr.silencesupp.fxnslevel_null = null_ind; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_get_mptime_num_intervals - * Description: Returns the number of intervals specified for the - * given mptime attribute. If the given attribute is not - * defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Number of intervals. - */ -u16 sdp_attr_get_mptime_num_intervals ( - void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num) { - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return 0; - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_MPTIME, inst_num); - if (attr_p != NULL) { - return attr_p->attr.mptime.num_intervals; - } - - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s mptime attribute, level %u instance %u not found.", - sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return 0; -} - -/* Function: sdp_attr_get_mptime_interval - * Description: Returns the value of the specified interval for the - * given mptime attribute. If the given attribute is not - * defined, zero is returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * interval_num The interval number to get. Range is (1 - - * max num payloads). - * Returns: Interval. - */ -u16 sdp_attr_get_mptime_interval ( - void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u16 interval_num) { - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return 0; - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_MPTIME, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s mptime attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return 0; - } - - if ((interval_num<1) || (interval_num>attr_p->attr.mptime.num_intervals)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s mptime attribute, level %u instance %u, " - "invalid interval number %u requested.", - sdp_p->debug_str, level, inst_num, interval_num); - } - sdp_p->conf_p->num_invalid_param++; - return 0; - } - - return attr_p->attr.mptime.intervals[interval_num-1]; -} - -/* Function: sdp_attr_add_mptime_interval - * Description: Add a new value to the list of intervals specified for - * the given mptime attribute. The interval will be - * added to the end of the list so these values should be added - * in the order they will be displayed within the attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * mp_interval The interval to add. - * Returns: SDP_SUCCESS Interval was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - * SDP_INVALID_SDP_PTR Supplied SDP pointer is invalid - */ -sdp_result_e sdp_attr_add_mptime_interval ( - void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - u16 mp_interval) { - - u16 interval_num; - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_SDP_PTR; - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_MPTIME, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s mptime attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - - interval_num = attr_p->attr.mptime.num_intervals; - if (interval_num>=SDP_MAX_PAYLOAD_TYPES) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s mptime attribute, level %u instance %u " - "exceeds maximum length.", - sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - - attr_p->attr.mptime.intervals[interval_num] = mp_interval; - ++attr_p->attr.mptime.num_intervals; - return SDP_SUCCESS; -} - - - -/* Function: sdp_get_group_attr - * Description: Returns the attribute parameter from the a=group:<> - * line. If no attrib has been set , - * SDP_GROUP_ATTR_UNSUPPORTED will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level SDP_SESSION_LEVEL - * Returns: Valid attrib value or SDP_GROUP_ATTR_UNSUPPORTED. - */ -sdp_group_attr_e sdp_get_group_attr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_GROUP_ATTR_UNSUPPORTED); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_GROUP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Group (a= group line) attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_GROUP_ATTR_UNSUPPORTED); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Stream data group attr field is :%s ", - sdp_p->debug_str, - sdp_get_group_attr_name(attr_p->attr.stream_data.group_attr) ); - } - return (attr_p->attr.stream_data.group_attr); - } -} - -/* Function: sdp_set_group_attr - * Description: Sets the value of the group attribute for the - * a=group: line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level SDP_SESSION_LEVEL - * group_attr group attribute value ( LS/FID ). - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER/SDP_INVALID_SDP_PTR -*/ - -sdp_result_e sdp_set_group_attr (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_group_attr_e group_attr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_GROUP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Group attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.stream_data.group_attr = group_attr; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_get_group_num_id - * Description: Returns the number of ids from the a=group:<> line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level SDP_SESSION_LEVEL - * Returns: Num of group ids present or 0 if there is an error. - */ -u16 sdp_get_group_num_id (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (0); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_GROUP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s a=group level attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (0); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Stream data group attr - num of ids is :%d ", - sdp_p->debug_str, - attr_p->attr.stream_data.num_group_id); - } - } - return (attr_p->attr.stream_data.num_group_id); -} - -/* Function: sdp_set_group_num_id - * Description: Sets the number og group ids that would be added on - * a=group: ...line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level SDP_SESSION_LEVEL - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER/SDP_INVALID_SDP_PTR - * Note: The application must call this API to set the number of group - * ids to be provided before actually setting the group ids on - * the a=group line. -*/ - -sdp_result_e sdp_set_group_num_id (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 group_num_id) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_GROUP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Group attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else if ((group_num_id == 0) || (group_num_id > SDP_MAX_GROUP_STREAM_ID)){ - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Number of group id value provided - %u is invalid\n", - sdp_p->debug_str, group_num_id); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.stream_data.num_group_id = group_num_id; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_get_group_id - * Description: Returns the number of ids from the a=group:<> line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level SDP_SESSION_LEVEL - * id_num Number of the id to retrieve. The range is (1 - - * SDP_MAX_GROUP_STREAM_ID) - * Returns: Value of the group id at the index specified or - * SDP_INVALID_VALUE if an error - */ -int32 sdp_get_group_id (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, u16 id_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_GROUP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s a=group level attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Stream data group attr - num of ids is :%d ", - sdp_p->debug_str, - attr_p->attr.stream_data.num_group_id); - } - if ((id_num < 1) || (id_num > attr_p->attr.stream_data.num_group_id)) { - return (SDP_INVALID_VALUE); - } - } - return (attr_p->attr.stream_data.group_id_arr[id_num-1]); -} - -/* Function: sdp_set_group_id - * Description: Sets the number og group ids that would be added on - * a=group: ...line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level SDP_SESSION_LEVEL - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER/SDP_INVALID_SDP_PTR -*/ - -sdp_result_e sdp_set_group_id (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - u16 group_id) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - u16 num_group_id; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_GROUP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Group attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - num_group_id = attr_p->attr.stream_data.num_group_id; - if (num_group_id == SDP_MAX_GROUP_STREAM_ID) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Max number of Group Ids already defined " - "for this group line %u", sdp_p->debug_str, level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.stream_data.group_id_arr[num_group_id] = group_id; - attr_p->attr.stream_data.num_group_id++; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_x_sidin - * Description: Returns the attribute parameter from the a=X-sidin:<> - * line. If no attrib has been set NULL will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level media level index - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Pointer to sidin or NULL. - */ -const char* sdp_attr_get_x_sidin (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_X_SIDIN, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-sidin attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Stream X-sidin attr field is :%s ", - sdp_p->debug_str, - attr_p->attr.stream_data.x_sidin); - } - return (attr_p->attr.stream_data.x_sidin); - } -} - -/* Function: sdp_attr_set_x_sidin - * Description: Sets the value of the X-sidin parameter - * for the given attribute. The address is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * sidin Ptr to the sidin string - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_x_sidin (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *sidin) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_X_SIDIN, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-sidin attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - sstrncpy(attr_p->attr.stream_data.x_sidin, sidin, - sizeof(attr_p->attr.stream_data.x_sidin)) ; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_x_sidout - * Description: Returns the attribute parameter from the a=X-sidout:<> - * line. If no attrib has been set NULL will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level media level index - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Pointer to sidout or NULL. - */ -const char* sdp_attr_get_x_sidout (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_X_SIDOUT, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-sidout attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Stream X-sidout attr field is :%s ", - sdp_p->debug_str, - attr_p->attr.stream_data.x_sidout); - } - return (attr_p->attr.stream_data.x_sidout); - } -} - -/* Function: sdp_attr_set_x_sidout - * Description: Sets the value of the x-sidout parameter - * for the given attribute. The address is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * sidout Ptr to the sidout string. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_x_sidout (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *sidout) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_X_SIDOUT, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-sidout attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - sstrncpy(attr_p->attr.stream_data.x_sidout, sidout, - sizeof(attr_p->attr.stream_data.x_sidout)) ; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_get_x_confid - * Description: Returns the attribute parameter from the a=X-confid:<> - * line. If no attrib has been set NULL will be returned. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level media level index - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Pointer to confid or NULL. - */ -const char* sdp_attr_get_x_confid (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (NULL); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_X_CONFID, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-confid attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (NULL); - } else { - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Stream X-confid attr field is :%s ", - sdp_p->debug_str, - attr_p->attr.stream_data.x_confid); - } - return (attr_p->attr.stream_data.x_confid); - } -} - -/* Function: sdp_attr_set_x_confid - * Description: Sets the value of the X-confid parameter - * for the given attribute. The address is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * confid Ptr to the confid string. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_x_confid (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char *confid) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_X_CONFID, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s X-confid attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - sstrncpy(attr_p->attr.stream_data.x_confid, confid, - sizeof(attr_p->attr.stream_data.x_confid)) ; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_set_source_filter - * Description: Sets the value of the source filter attribute for the - * a=source-filter: line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level SDP_SESSION_LEVEL/Media level - * mode Filter-mode (incl/excl) - * nettype Network type - * addrtype Address type of the destination - * dest_addr Destination unicast/multicast address - * (ip-addr/ fqdn/ *) - * src_addr One of the source address to which the filter - * applies, i.e. process/drop the packets. - * (More source addresses are added using - * sdp_include_new_filter_src_addr) - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER/SDP_INVALID_SDP_PTR - */ -sdp_result_e -sdp_set_source_filter (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, sdp_src_filter_mode_e mode, - sdp_nettype_e nettype, sdp_addrtype_e addrtype, - const char *dest_addr, const char *src_addr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - u16 index; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SOURCE_FILTER, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Source filter attribute, level %u instance %u " - "not found", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.source_filter.mode = mode; - attr_p->attr.source_filter.nettype = nettype; - attr_p->attr.source_filter.addrtype = addrtype; - sstrncpy(attr_p->attr.source_filter.dest_addr, dest_addr, - SDP_MAX_STRING_LEN+1); - if (src_addr) { - index = attr_p->attr.source_filter.num_src_addr; - sstrncpy(attr_p->attr.source_filter.src_list[index], - src_addr,SDP_MAX_STRING_LEN+1); - /* Increment source list count if the api was invoked for - * first time or else we're basically replacing the index 0 - * element in src-list. - */ - ++attr_p->attr.source_filter.num_src_addr; - SDP_PRINT("%s Source address (%s) number %d added to source filter", - sdp_p->debug_str,src_addr, - attr_p->attr.source_filter.num_src_addr); - - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_include_new_filter_src_addr - * Description: Adds source addresses to the list to which the filter applies - * This is to be invoked only as follow-up to - * sdp_set_source_filter() to include more source addresses - * Parameters: sdp_ptr The SDP handle to which the filter attributes - * were added using sdp_set_source_filter - * level SDP_SESSION_LEVEL/Media level - * src_addr Source address to be added to the list - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER/SDP_INVALID_SDP_PTR - */ - -sdp_result_e -sdp_include_new_filter_src_addr (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, const char *src_addr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SOURCE_FILTER, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Source filter attribute, level %u instance %u " - "not found", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (attr_p->attr.source_filter.num_src_addr >= SDP_MAX_SRC_ADDR_LIST) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Max number of source addresses included for " - "filter for the instance %u", sdp_p->debug_str, - inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_FAILURE); - } - sstrncpy(attr_p->attr.source_filter.src_list[ - attr_p->attr.source_filter.num_src_addr], - src_addr, SDP_MAX_STRING_LEN+1); - ++attr_p->attr.source_filter.num_src_addr; - - return (SDP_SUCCESS); -} - -/* Function: sdp_get_source_filter_mode - * Description: Gets the filter mode in internal representation - * Parameters: sdp_ptr The SDP handle which contains the attributes - * level SDP_SESSION_LEVEL/m-line number - * inst_num The attribute instance number - * Returns: Filter mode (incl/excl/not present) - */ -sdp_src_filter_mode_e -sdp_get_source_filter_mode (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_FILTER_MODE_NOT_PRESENT); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SOURCE_FILTER, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Source filter attribute, level %u, " - "instance %u not found", sdp_p->debug_str, - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_FILTER_MODE_NOT_PRESENT); - } - return (attr_p->attr.source_filter.mode); -} - -/* Function: sdp_get_filter_destination_attributes - * Description: Gets the destination address parameters - * Parameters: Network type (optional), destination address type - * (optional), and destination address (mandatory) variables - * which gets updated. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER/SDP_INVALID_SDP_PTR - */ -sdp_result_e -sdp_get_filter_destination_attributes (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, sdp_nettype_e *nettype, - sdp_addrtype_e *addrtype, - char *dest_addr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SOURCE_FILTER, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Source filter attribute, level %u instance %u " - "not found", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (nettype) { - *nettype = attr_p->attr.source_filter.nettype; - } - if (addrtype) { - *addrtype = attr_p->attr.source_filter.addrtype; - } - sstrncpy(dest_addr, attr_p->attr.source_filter.dest_addr, - SDP_MAX_STRING_LEN+1); - - return (SDP_SUCCESS); -} - -/* Function: sdp_get_filter_source_address_count - * Description: Gets the number of source addresses in the list - * Parameters: sdp_ptr The SDP handle which contains the attributes - * level SDP_SESSION_LEVEL/m-line number - * inst_num The attribute instance number - * Returns: Source-list count - */ - -int32 -sdp_get_filter_source_address_count (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_VALUE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SOURCE_FILTER, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Source filter attribute, level %u instance %u " - "not found", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_VALUE); - } - return (attr_p->attr.source_filter.num_src_addr); -} - -/* Function: sdp_get_filter_source_address - * Description: Gets one of the source address that is indexed by the user - * Parameters: sdp_ptr The SDP handle which contains the attributes - * level SDP_SESSION_LEVEL/m-line number - * inst_num The attribute instance number - * src_addr_id User provided index (value in range between - * 0 to (SDP_MAX_SRC_ADDR_LIST-1) which obtains - * the source addr corresponding to it. - * src_addr The user provided variable which gets updated - * with source address corresponding to the index - */ -sdp_result_e -sdp_get_filter_source_address (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, u16 src_addr_id, - char *src_addr) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - src_addr[0] = '\0'; - - if (src_addr_id >= SDP_MAX_SRC_ADDR_LIST) { - return (SDP_INVALID_PARAMETER); - } - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SOURCE_FILTER, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Source filter attribute, level %u instance %u " - "not found", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - if (src_addr_id >= attr_p->attr.source_filter.num_src_addr) { - return (SDP_INVALID_PARAMETER); - } - sstrncpy(src_addr, attr_p->attr.source_filter.src_list[src_addr_id], - SDP_MAX_STRING_LEN+1); - - return (SDP_SUCCESS); -} - -sdp_result_e -sdp_set_rtcp_unicast_mode (void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num, sdp_rtcp_unicast_mode_e mode) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - if (mode >= SDP_RTCP_MAX_UNICAST_MODE) { - return (SDP_INVALID_PARAMETER); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_RTCP_UNICAST, inst_num); - - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s RTCP Unicast attribute, level %u instance %u " - "not found", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p->attr.u32_val = mode; - - return (SDP_SUCCESS); -} - -sdp_rtcp_unicast_mode_e -sdp_get_rtcp_unicast_mode(void *sdp_ptr, u16 level, u8 cap_num, - u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_RTCP_UNICAST_MODE_NOT_PRESENT); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_RTCP_UNICAST, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s RTCP Unicast attribute, level %u, " - "instance %u not found", sdp_p->debug_str, - level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_RTCP_UNICAST_MODE_NOT_PRESENT); - } - return ((sdp_rtcp_unicast_mode_e)attr_p->attr.u32_val); -} - - -/* Function: sdp_attr_get_sdescriptions_tag - * Description: Returns the value of the sdescriptions tag - * parameter specified for the given attribute. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: Tag value or SDP_INVALID_VALUE (-2) if error encountered. - */ - -int32 -sdp_attr_get_sdescriptions_tag (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_VALUE; - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute tag, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_VALUE; - } else { - return attr_p->attr.srtp_context.tag; - } -} - -/* Function: sdp_attr_get_sdescriptions_crypto_suite - * Description: Returns the value of the sdescriptions crypto suite - * parameter specified for the given attribute. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, return the suite. If it's not, - * try to find the version 9. This assumes you cannot have both - * versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: SDP_SRTP_UNKNOWN_CRYPTO_SUITE is returned if an error was - * encountered otherwise the crypto suite is returned. - */ - -sdp_srtp_crypto_suite_t -sdp_attr_get_sdescriptions_crypto_suite (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_SRTP_UNKNOWN_CRYPTO_SUITE; - } - - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - - if (attr_p == NULL) { - /* There's no version 2 so now try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute suite, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_SRTP_UNKNOWN_CRYPTO_SUITE; - } - } - - return attr_p->attr.srtp_context.suite; - -} - -/* Function: sdp_attr_get_sdescriptions_key - * Description: Returns the value of the sdescriptions master key - * parameter specified for the given attribute. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, return the key. If it's not, - * try to find the version 9. This assumes you cannot have both - * versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: NULL if error encountered or master key salt string - */ - -const char* -sdp_attr_get_sdescriptions_key (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return NULL; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - - if (attr_p == NULL) { - /* Couldn't find version 2 now try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute key, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return NULL; - } - } - - return (char*)attr_p->attr.srtp_context.master_key; -} - - -/* Function: sdp_attr_get_sdescriptions_salt - * Description: Returns the value of the sdescriptions master salt - * parameter specified for the given attribute. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, return the salt. If it's not, - * try to find the version 9. This assumes you cannot have both - * versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: NULL if error encountered or master key salt string - */ - -const char* -sdp_attr_get_sdescriptions_salt (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return NULL; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - - if (attr_p == NULL) { - /* Couldn't find version 2 now try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute salt, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return NULL; - } - } - - return (char*) attr_p->attr.srtp_context.master_salt; - -} - - - -/* Function: sdp_attr_get_sdescriptions_lifetime - * Description: Returns the value of the sdescriptions lifetime - * parameter specified for the given attribute.Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, return the lifetime. If it's - * not, try to find the version 9. This assumes you cannot have - * both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: NULL if error encountered or lifetime string - */ - -const char* -sdp_attr_get_sdescriptions_lifetime (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return NULL; - } - - /* Try version 2 first. */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - - if (attr_p == NULL) { - /* Couldn't find version 2 now try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute lifetime, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return NULL; - } - } - - return (char*)attr_p->attr.srtp_context.master_key_lifetime; - -} - -/* Function: sdp_attr_get_sdescriptions_mki - * Description: Returns the value of the sdescriptions MKI value and length - * parameter of the specified attribute instance. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, return the MKI. If it's - * not, try to find version 9. This assumes you cannot have - * both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * mki_value application provided pointer that on exit - * is set to the MKI value string if one exists. - * mki_length application provided pointer that on exit - * is set to the MKI length if one exists. - * Returns: SDP_SUCCESS no errors encountered otherwise sdp error - * based upon the specific error. - */ - -sdp_result_e -sdp_attr_get_sdescriptions_mki (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - const char **mki_value, - u16 *mki_length) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - *mki_value = NULL; - *mki_length = 0; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_SDP_PTR; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - - if (attr_p == NULL) { - /* Couldn't find version 2 now try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute MKI, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - } - - *mki_value = (char*)attr_p->attr.srtp_context.mki; - *mki_length = attr_p->attr.srtp_context.mki_size_bytes; - return SDP_SUCCESS; - -} - - -/* Function: sdp_attr_get_sdescriptions_session_params - * Description: Returns the unparsed session parameters string. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, return session parameters. If - * it's not, try to find version 9. This assumes you cannot have - * both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: NULL if no session parameters were received in the sdp, - * otherwise returns a pointer to the start of the session - * parameters string. Note that the calling function should - * not free the returned pointer. - */ - -const char* -sdp_attr_get_sdescriptions_session_params (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return NULL; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - - if (attr_p == NULL) { - /* Couldn't find version 2 try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute session params, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return NULL; - } - } - - return attr_p->attr.srtp_context.session_parameters; -} - - -/* Function: sdp_attr_get_sdescriptions_key_size - * Description: Returns the master key size. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, return key size. If - * it's not, try to find version 9. This assumes you cannot have - * both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: 0 (SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN) if error was - * encountered, otherwise key size. - */ - -unsigned char -sdp_attr_get_sdescriptions_key_size (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - - if (attr_p == NULL) { - /* Couldn't find version 2 now try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute MKI, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN; - } - } - - return attr_p->attr.srtp_context.master_key_size_bytes; - -} - - -/* Function: sdp_attr_get_sdescriptions_salt_size - * Description: Returns the salt key size. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, return salt size. If - * it's not, try to find version 9. This assumes you cannot have - * both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: 0 (SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN) if error was - * encountered, otherwise salt size. - */ - -unsigned char -sdp_attr_get_sdescriptions_salt_size (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - - if (attr_p == NULL) { - /* Couldn't find version 2 now try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute MKI, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_SDESCRIPTIONS_KEY_SIZE_UNKNOWN; - } - } - - return attr_p->attr.srtp_context.master_salt_size_bytes; - -} - - -/* Function: sdp_attr_get_srtp_crypto_selection_flags - * Description: Returns the selection flags. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, return selection flags. If - * it's not, try to find version 9. This assumes you cannot have - * both versions in the same SDP. - * Currently only necessary for MGCP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * Returns: 0 (SDP_SRTP_CRYPTO_SELECTION_FLAGS_UNKNOWN) if error was - * encountered, otherwise selection flags. - */ - -unsigned long -sdp_attr_get_srtp_crypto_selection_flags (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num) -{ - - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_SRTP_CRYPTO_SELECTION_FLAGS_UNKNOWN; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - - if (attr_p == NULL) { - /* Couldn't find version 2 now try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute MKI, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_SRTP_CRYPTO_SELECTION_FLAGS_UNKNOWN; - } - } - - return attr_p->attr.srtp_context.selection_flags; - -} - - - -/* Function: sdp_attr_set_sdescriptions_tag - * Description: Sets the sdescriptions tag parameter - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * tag_num tag - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e -sdp_attr_set_sdescriptions_tag (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - int32 tag_num) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute tag, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.srtp_context.tag = tag_num; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_set_sdescriptions_crypto_suite - * Description: Sets the sdescriptions crypto suite parameter. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, it will set the crypto suite - * for version 2. If it's not, try to find version 9. This assumes - * you cannot have both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * crypto_suite crypto suite - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e -sdp_attr_set_sdescriptions_crypto_suite (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - sdp_srtp_crypto_suite_t crypto_suite) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - int i; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_SDP_PTR; - } - - /* Try to find version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - if (attr_p == NULL) { - - /* Version 2 not found, try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute suite, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - } - - attr_p->attr.srtp_context.suite = crypto_suite; - for (i=0; i < SDP_SRTP_MAX_NUM_CRYPTO_SUITES; i++) { - /* For the specified crypto suite, get the size of the - * key and salt. - */ - if (sdp_srtp_crypto_suite_array[i].crypto_suite_val == - crypto_suite) { - - attr_p->attr.srtp_context.master_key_size_bytes = - sdp_srtp_crypto_suite_array[i].key_size_bytes; - - attr_p->attr.srtp_context.master_salt_size_bytes = - sdp_srtp_crypto_suite_array[i].salt_size_bytes; - - } - } - - return SDP_SUCCESS; - -} - - -/* Function: sdp_attr_set_sdescriptions_key - * Description: Sets the sdescriptions key parameter. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, it will set the key for - * version 2. If it's not, try to find version 9. This assumes - * you cannot have both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * key buffer containing the key assumes null terminated - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e -sdp_attr_set_sdescriptions_key (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - char *key) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_SDP_PTR; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - if (attr_p == NULL) { - /* Couldn't find version 2 try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute key, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - - } - - bcopy(key, attr_p->attr.srtp_context.master_key, - SDP_SRTP_MAX_KEY_SIZE_BYTES); - - return SDP_SUCCESS; - -} - - -/* Function: sdp_attr_set_sdescriptions_salt - * Description: Sets the sdescriptions salt parameter. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, it will set the salt for - * version 2. If it's not, try to find version 9. This assumes - * you cannot have both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * salt buffer containing the salt assumes null terminated - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e -sdp_attr_set_sdescriptions_salt (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - char *salt) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_SDP_PTR; - } - - /* Try to find version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - if (attr_p == NULL) { - /* Couldn't find version 2, try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp attribute salt, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - } - - bcopy(salt, attr_p->attr.srtp_context.master_salt, - SDP_SRTP_MAX_SALT_SIZE_BYTES); - - return SDP_SUCCESS; -} - - -/* Function: sdp_attr_set_sdescriptions_lifetime - * Description: Sets the sdescriptions lifetime parameter. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, it will set the lifetime for - * version 2. If it's not, try to find version 9. This assumes - * you cannot have both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * lifetime buffer containing the lifetime assumes null terminated - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e -sdp_attr_set_sdescriptions_lifetime (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - char *lifetime) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_SDP_PTR; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - if (attr_p == NULL) { - /* Couldn't find version 2, try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp lifetime attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - - } - - sstrncpy((char*)attr_p->attr.srtp_context.master_key_lifetime, lifetime, - SDP_SRTP_MAX_LIFETIME_BYTES); - return SDP_SUCCESS; - -} - - -/* Function: sdp_attr_set_sdescriptions_mki - * Description: Sets the sdescriptions mki parameter compose of the MKI - * value and length. Note that this is a common api for both - * version 2 and version 9 sdescriptions. It has no knowledge - * which version is being used so it will first try to find if - * a version 2 sdescriptions attribute is present. If it is, it will - * set the lifetime for version 2. If it's not, try to find version 9. - * This assumes you cannot have both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * mki_value buffer containing the mki value. Assumes null - * terminated buffer. - * mki_length length of the MKI - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e -sdp_attr_set_sdescriptions_mki (void *sdp_ptr, u16 level, - u8 cap_num, u16 inst_num, - char *mki_value, - u16 mki_length) -{ - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_SDP_PTR; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - if (attr_p == NULL) { - /* Couldn't find version 2, try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp MKI attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - } - - sstrncpy((char*)attr_p->attr.srtp_context.mki, mki_value, - SDP_SRTP_MAX_MKI_SIZE_BYTES); - attr_p->attr.srtp_context.mki_size_bytes = mki_length; - return SDP_SUCCESS; - -} - - -/* Function: sdp_attr_set_sdescriptions_key_size - * Description: Sets the sdescriptions key size parameter. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, it will set the key for - * version 2. If it's not, try to find version 9. This assumes - * you cannot have both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * key_size key size - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e -sdp_attr_set_sdescriptions_key_size (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - unsigned char key_size) - -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_SDP_PTR; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - if (attr_p == NULL) { - /* Couldn't find version 2, try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp MKI attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - } - - attr_p->attr.srtp_context.master_key_size_bytes = key_size; - return SDP_SUCCESS; - -} - - -/* Function: sdp_attr_set_sdescriptions_key_size - * Description: Sets the sdescriptions salt size parameter. Note that - * this is a common api for both version 2 and version 9 - * sdescriptions. It has no knowledge which version is being - * used so it will first try to find if a version 2 sdescriptions - * attribute is present. If it is, it will set the salt for - * version 2. If it's not, try to find version 9. This assumes - * you cannot have both versions in the same SDP. - * - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * salt_size salt size - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e -sdp_attr_set_sdescriptions_salt_size (void *sdp_ptr, - u16 level, - u8 cap_num, - u16 inst_num, - unsigned char salt_size) -{ - - sdp_t *sdp_p = (sdp_t *)sdp_ptr; - sdp_attr_t *attr_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return SDP_INVALID_SDP_PTR; - } - - /* Try version 2 first */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SRTP_CONTEXT, inst_num); - if (attr_p == NULL) { - /* Couldn't find version 2, try version 9 */ - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SDESCRIPTIONS, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s srtp MKI attribute, level %u instance %u " - "not found.", sdp_p->debug_str, level, inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - } - - attr_p->attr.srtp_context.master_salt_size_bytes = salt_size; - return SDP_SUCCESS; - -} - diff --git a/libs/sipcc/core/sdp/sdp_base64.c b/libs/sipcc/core/sdp/sdp_base64.c deleted file mode 100644 index 0cef82166d..0000000000 --- a/libs/sipcc/core/sdp/sdp_base64.c +++ /dev/null @@ -1,394 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "sdp_base64.h" - -/* - * Local definitions for Base64 to Raw table entries. - */ -#define INVALID_CHAR 0xFF /* Character not in supported Base64 set */ -#define WHITE_SPACE 0xFE /* Space, tab, newline, etc character */ -#define PADDING 0xFD /* The character '=' */ - -#define PAD_CHAR '=' /* The character '=' */ - -/* Maximum length of a base64 encoded line */ -#define MAX_BASE64_LINE_LENGTH 76 - -/* - * base64_result_table - * String table for translating base64 error codes into human - * understanable strings. - */ -char *base64_result_table[BASE64_RESULT_MAX] = -{ - "Base64 successful", - "Base64 Buffer Overrun", - "Base64 Bad Data", - "Base64 Bad Padding", - "Base64 Bad Block Size" -}; - -/* - * base64_to_raw_table - * Heart of the Base64 decoding algorithm. Lookup table to convert - * the Base64 characters into their specified representative values. - * Invalid characters are marked with 0xFF, white space characters - * are marked with 0xFE, and the special pading character is marked - * with 0xFD. - */ -unsigned char base64_to_raw_table[128] = -{ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, /* 0-9 */ - 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 10-19 */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 20-29 */ - 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 30-39 */ - 0xFF, 0xFF, 0xFF, 62, 0xFF, 0xFF, 0xFF, 63, 52, 53, /* 40-49 */ - 54, 55, 56, 57, 58, 59, 60, 61, 0xFF, 0xFF, /* 50-59 */ - 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, /* 60-69 */ - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70-79 */ - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80-89 */ - 25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 26, 27, 28, /* 90-99 */ - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */ - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */ - 49, 50, 51, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF /* 120-127 */ -}; - -unsigned char raw_to_base64_table[64] = -{ - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0-9 */ - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */ - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20-29 */ - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30-39 */ - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', /* 40-49 */ - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 50-59 */ - '8', '9', '+', '/' /* 60-63 */ -}; - -/* - * base64_encode_size_bytes - * - * DESCRIPTION - * Estimates the size of buffer required for holding the result of - * encoding data of size raw_size_bytes. - * - * PARAMETERS - * raw_size_bytes = Estimated size of the un-encoded data in bytes. - * - * RETURN VALUE - * The size of destination buffer to use for encoding in bytes. - */ -int base64_est_encode_size_bytes (int raw_size_bytes) -{ - int length; - - /* - * Find the number of bytes needed to represent the data - * using a 4/3 expansion ratio. That result must be - * rounded to the next higher multiple of four to account - * for padding. Then add in a term to account for any '\n's - * added. - */ - length = ((((raw_size_bytes * 4 + 2)/ 3) + 3) & ~(0x3)) + - raw_size_bytes / MAX_BASE64_LINE_LENGTH; - - return length; -} - -/* - * base64_decode_size_bytes - * - * DESCRIPTION - * Estimates the size of buffer required for holding the result of - * decoding data of size base64_size_bytes. - * - * PARAMETERS - * base64_size_bytes = Estimated size of the Base64 data in bytes. - * - * RETURN VALUE - * The size of destination buffer to use for decoding in bytes. - */ -int base64_est_decode_size_bytes (int base64_size_bytes) -{ - int length; - - length = (base64_size_bytes * 3 + 3) / 4; - return length; -} - -/* - * base64_encode - * - * DESCRIPTION - * Encode data pointed to by src into the buffer pointer to by dest - * using the Base64 algorithm. - * - * NOTE: No trailing '\n' character will be added. - * - * NOTE: As per specification, '\n' will be placed every 76 chars. - * - * PARAMETERS - * src = Pointer to the raw data to base64 encode. - * src_bytes = The number of bytes in the src buffer to encode. - * dest = Pointer to the destination buffer where the converted data - * will reside when complete. - * dest_bytes = Initially holds the size of the destination buffer - * but at completion holds the number of bytes converted. - * - * RETURN VALUE - * base64_success if the buffer was successfully converted, the - * appropriate error code otherwise. - * - * The dest parameter holds the converted data. - * - * The dest_bytes parameter holds the actual number of bytes converted. - */ -base64_result_t base64_encode(unsigned char *src, int src_bytes, unsigned char *dest, int *dest_bytes) -{ - int i, j=0; - int line_count = 0; - unsigned char index; /* index into base64 lookup table */ - int smax = src_bytes-2; /* only do full multiples of 3 */ - int dmax = *dest_bytes; /* destination maximum */ - - *dest_bytes = 0; - - /* Do full groups. Base64 must be done in blocks of 3 src bytes */ - for (i=0; i=MAX_BASE64_LINE_LENGTH) { - if (j> 2) & 0x3F; - dest[j++] = raw_to_base64_table[index]; - - /* bottom 2 bits of first word, high 4 bits of second word */ - index = ((src[i] << 4) & 0x30) | ((src[i+1] >> 4) & 0x0F); - dest[j++] = raw_to_base64_table[index]; - - /* bottom 4 bits of second word, high 2 bits of third word */ - index = ((src[i+1] << 2) & 0x3C) | ((src[i+2] >> 6) & 0x03); - dest[j++] = raw_to_base64_table[index]; - - /* bottom 6 bits of third word */ - index = src[i+2] & 0x3F; - dest[j++] = raw_to_base64_table[index]; - } else { - return BASE64_BUFFER_OVERRUN; - } - } - - /* Check to see if any more work must be done */ - if (i=MAX_BASE64_LINE_LENGTH) { - if (jdmax) { - /* No room left in output buffer! */ - return BASE64_BUFFER_OVERRUN; - } - - /* Find mapping of upper 6 bits */ - index = (src[i] >> 2) & 0x3F; - dest[j++] = raw_to_base64_table[index]; - - /* check for another stragler */ - if ((i+1)> 4) & 0x0F); - dest[j++] = raw_to_base64_table[index]; - - /* bottom 4 bits of second word */ - index = (src[i+1] << 2) & 0x3C; - dest[j++] = raw_to_base64_table[index]; - dest[j++] = PAD_CHAR; - } else { - /* bottom 2 bits of first word */ - index = (src[i] << 4) & 0x30; - dest[j++] = raw_to_base64_table[index]; - dest[j++] = PAD_CHAR; - dest[j++] = PAD_CHAR; - } - } - - *dest_bytes = j; - - return BASE64_SUCCESS; -} - -/* - * base64_decode - * - * DESCRIPTION - * Decode data pointed to by src into the buffer pointer to by dest - * using the Base64 algorithm. - * - * PARAMETERS - * src = Pointer to the Base64 data to decode. - * src_bytes = The number of bytes in the src buffer to decode. - * dest = Pointer to the destination buffer where the converted data - * will reside when complete. - * dest_bytes = Initially holds the size of the destination buffer - * but at completion holds the number of bytes converted. - * - * RETURN VALUE - * base64_success if the buffer was successfully converted, the - * appropriate error code otherwise. - * - * The dest parameter holds the converted data. - * - * The dest_bytes parameter holds the actual number of bytes converted. - */ -base64_result_t base64_decode(unsigned char *src, int src_bytes, unsigned char *dest, int *dest_bytes) -{ - int i, j = 0; - int sindex = 0; /* Current NON-whitespace source - * index */ - int pad_count=0; /* Number of padding characters - * encountered */ - int dest_size_bytes = *dest_bytes; /* Save size of destination buffer */ - unsigned char cindex; /* The current Base64 character to - * process */ - unsigned char val; /* The value of the current Base64 - * character */ - - *dest_bytes = 0; - - for (i=0; i> 4; - - if (j=src_bytes) || - (base64_to_raw_table[src[i+1]] != PADDING)) { - return BASE64_BUFFER_OVERRUN; - } - } - break; - case 2: - /* Fill Bottom 4 bits */ - dest[j++] |= val >> 2; - - if (j=src_bytes) || - (base64_to_raw_table[src[i+1]] != PADDING)) { - return BASE64_BUFFER_OVERRUN; - } - } - break; - case 3: - /* - * No need to check for overrun here since the - * previous case was already checked. If another - * group is present then case 0 will check again. - */ - - /* Fill Bottom 6 bits */ - dest[j++] |= val; - break; - } - sindex++; - } - - /* Check length for multiple of 3 bytes */ - if (((j + pad_count)% 3) != 0) { - return BASE64_BAD_BLOCK_SIZE; - } - - /* Save off the number of bytes converted */ - *dest_bytes = j; - - return BASE64_SUCCESS; -} diff --git a/libs/sipcc/core/sdp/sdp_base64.h b/libs/sipcc/core/sdp/sdp_base64.h deleted file mode 100644 index e264245b72..0000000000 --- a/libs/sipcc/core/sdp/sdp_base64.h +++ /dev/null @@ -1,42 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SDP_BASE64_H_ -#define _SDP_BASE64_H_ - -/* - * base64_result_t - * Enumeration of the result codes for Base64 conversion. - */ -typedef enum base64_result_t_ { - BASE64_INVALID=-1, - BASE64_SUCCESS=0, - BASE64_BUFFER_OVERRUN, - BASE64_BAD_DATA, - BASE64_BAD_PADDING, - BASE64_BAD_BLOCK_SIZE, - BASE64_RESULT_MAX -} base64_result_t; - -#define MAX_BASE64_STRING_LEN 60 - -/* Result code string table */ -extern char *base64_result_table[]; - -/* - * BASE64_RESULT_TO_STRING - * Macro to convert a Base64 result code into a human readable string. - */ -#define BASE64_RESULT_TO_STRING(_result) (((_result)>=0 && (_result)magic_num == SDP_MAGIC_NUM)) { - return (TRUE); - } else { - CSFLogError(logTag, "SDP: Invalid Config pointer."); - return (FALSE); - } -} - -/* Function: void *sdp_init_config() - * Description: Initialize SDP configuration structure with the - * following defaults: - * All debug levels turned OFF. - * All token lines required per RFC2327. - * No media types supported. - * No network types supported. - * No address types supported. - * No transport types supported. - * Parameters: None. - * Returns: A handle for the configuration as a void ptr. - */ -sdp_conf_options_t sdp_config_options; -void *sdp_init_config () -{ - int i; - sdp_conf_options_t *conf_p; - - conf_p = & sdp_config_options; - - /* Initialize magic number. */ - conf_p->magic_num = SDP_MAGIC_NUM; - - /* Set default debug flags. */ - conf_p->debug_flag[SDP_DEBUG_TRACE] = FALSE; - conf_p->debug_flag[SDP_DEBUG_WARNINGS] = FALSE; - conf_p->debug_flag[SDP_DEBUG_ERRORS] = FALSE; - - /* Set required lines flags. Note: Only need to set those that */ - /* are questionable. Most lines aren't required by default. */ - conf_p->version_reqd = TRUE; - conf_p->owner_reqd = TRUE; - conf_p->session_name_reqd = TRUE; - conf_p->timespec_reqd = TRUE; - - /* No media types supported by default. */ - for (i=0; i < SDP_MAX_MEDIA_TYPES; i++) { - conf_p->media_supported[i] = FALSE; - } - - /* No network types supported by default. */ - for (i=0; i < SDP_MAX_NETWORK_TYPES; i++) { - conf_p->nettype_supported[i] = FALSE; - } - - /* No address types supported by default. */ - for (i=0; i < SDP_MAX_ADDR_TYPES; i++) { - conf_p->addrtype_supported[i] = FALSE; - } - - /* No transport types supported by default. */ - for (i=0; i < SDP_MAX_TRANSPORT_TYPES; i++) { - conf_p->transport_supported[i] = FALSE; - } - - /* No choose parameters allowed by default. */ - for (i=0; i < SDP_MAX_CHOOSE_PARAMS; i++) { - conf_p->allow_choose[i] = FALSE; - } - - /* Initialize statistics counts */ - conf_p->num_parses = 0; - conf_p->num_builds = 0; - conf_p->num_not_sdp_desc = 0; - conf_p->num_invalid_token_order = 0; - conf_p->num_invalid_param = 0; - conf_p->num_no_resource = 0; - - return (conf_p); -} - - -/* Function: void sdp_appl_debug(void *config_p, sdp_debug_e debug_type, - * tinybool my_bool); - * Description: Define the default type of debug for the application. - * Valid debug types are ERRORS, WARNINGS, and TRACE. Each - * debug type can be turned on/off individually. The - * default debug level can be redefined at any time. - * Parameters: conf_p The config handle returned by sdp_init_config. - * debug_type Specifies the debug type being enabled/disabled. - * debug_flag Defines whether the debug should be enabled or not. - * Returns: Nothing. - */ -void sdp_appl_debug (void *config_p, sdp_debug_e debug_type, - tinybool debug_flag) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - if (debug_type < SDP_MAX_DEBUG_TYPES) { - conf_p->debug_flag[debug_type] = debug_flag; - } -} - - -/* Functions: void sdp_require_version - * void sdp_require_owner - * void sdp_require_session_name - * void sdp_require_timespec - * Description: These functions allow the application to not require several - * of the tokens that are specifically required by RFC 2327. - * Parameters: conf_p The config handle returned by sdp_init_config. - * version_required TRUE or FALSE whether the token should - * be required. - * Returns: Nothing. - */ -void sdp_require_version (void *config_p, tinybool version_required) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - conf_p->version_reqd = version_required; -} - -void sdp_require_owner (void *config_p, tinybool owner_required) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - conf_p->owner_reqd = owner_required; -} - -void sdp_require_session_name (void *config_p, tinybool sess_name_required) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - conf_p->session_name_reqd = sess_name_required; -} - -void sdp_require_timespec (void *config_p, tinybool timespec_required) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - conf_p->timespec_reqd = timespec_required; -} - - -/* Function: sdp_media_supported - * Description: These functions allow the application to specify which - * media types it supports. The application must set any/all - * as required. No media types are supported by default. - * Parameters: config_p The config handle returned by sdp_init_config. - * nettype The network type for which support is being set. - * media_supported TRUE or FALSE whether the support is provided. - * Returns: Nothing. - */ -void sdp_media_supported (void *config_p, sdp_media_e media_type, - tinybool media_supported) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - conf_p->media_supported[media_type] = media_supported; -} - - -/* Function: sdp_nettype_supported - * Description: This function allows the application to specify which - * network types it supports. The application must set - * any/all as required. No network types are supported by - * default. - * Parameters: config_p The config handle returned by sdp_init_config. - * nettype The network type for which support is being set. - * nettype_supported TRUE or FALSE whether the support is - * provided. - * Returns: Nothing. - */ -void sdp_nettype_supported (void *config_p, sdp_nettype_e nettype, - tinybool nettype_supported) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - conf_p->nettype_supported[nettype] = nettype_supported; -} - - -/* Function: sdp_addrtype_supported - * Description: This function allows the application to specify which - * address types it supports. The application must set - * any/all as required. No address types are supported by - * default. - * Parameters: config_p The config handle returned by sdp_init_config. - * addrtype The address type for which support is being set. - * addrtype_supported TRUE or FALSE whether the support is - * provided. - * Returns: Nothing. - */ -void sdp_addrtype_supported (void *config_p, sdp_addrtype_e addrtype, - tinybool addrtype_supported) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - conf_p->addrtype_supported[addrtype] = addrtype_supported; -} - - -/* Function: sdp_transport_supported - * Description: This function allows the application to specify which - * transport types it supports. The application must set - * any/all as required. No transport types are supported - * by default. - * Parameters: config_p The config handle returned by sdp_init_config. - * transport The transport type for which support is being set. - * transport_supported TRUE or FALSE whether the support is - * provided. - * Returns: Nothing. - */ -void sdp_transport_supported (void *config_p, sdp_transport_e transport, - tinybool transport_supported) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - conf_p->transport_supported[transport] = transport_supported; -} - - -/* Function: sdp_allow_choose - * Description: These functions allow the CHOOSE parameter `$' to be - * specified in place of certain parameters. - * Parameters: config_p The config handle returned by sdp_init_config. - * param The param that may or may not be CHOOSE. - * choose_allowed TRUE or FALSE whether the CHOOSE parameter - * should be allowed. - * Returns: Nothing. - */ -void sdp_allow_choose (void *config_p, sdp_choose_param_e param, tinybool choose_allowed) -{ - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return; - } - - if (param < SDP_MAX_CHOOSE_PARAMS) { - conf_p->allow_choose[param] = choose_allowed; - } -} diff --git a/libs/sipcc/core/sdp/sdp_main.c b/libs/sipcc/core/sdp/sdp_main.c deleted file mode 100644 index f63857a7d7..0000000000 --- a/libs/sipcc/core/sdp/sdp_main.c +++ /dev/null @@ -1,1463 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "sdp_os_defs.h" -#include "sdp.h" -#include "sdp_private.h" -#include "CSFLog.h" - -//static const char* logTag = "sdp_main"; - -/* Note: These *must* be in the same order as the enum types. */ -const sdp_tokenarray_t sdp_token[SDP_MAX_TOKENS] = -{ - {"v=", sdp_parse_version, sdp_build_version }, - {"o=", sdp_parse_owner, sdp_build_owner }, - {"s=", sdp_parse_sessname, sdp_build_sessname }, - {"i=", sdp_parse_sessinfo, sdp_build_sessinfo }, - {"u=", sdp_parse_uri, sdp_build_uri }, - {"e=", sdp_parse_email, sdp_build_email }, - {"p=", sdp_parse_phonenum, sdp_build_phonenum }, - {"c=", sdp_parse_connection, sdp_build_connection }, - {"b=", sdp_parse_bandwidth, sdp_build_bandwidth }, - {"t=", sdp_parse_timespec, sdp_build_timespec }, - {"r=", sdp_parse_repeat_time, sdp_build_repeat_time }, - {"z=", sdp_parse_timezone_adj, sdp_build_timezone_adj }, - {"k=", sdp_parse_encryption, sdp_build_encryption }, - {"a=", sdp_parse_attribute, sdp_build_attribute }, - {"m=", sdp_parse_media, sdp_build_media } -}; - - -/* Note: These *must* be in the same order as the enum types. */ -const sdp_attrarray_t sdp_attr[SDP_MAX_ATTR_TYPES] = -{ - {"bearer", sizeof("bearer"), - sdp_parse_attr_simple_string, sdp_build_attr_simple_string }, - {"called", sizeof("called"), - sdp_parse_attr_simple_string, sdp_build_attr_simple_string }, - {"connection_type", sizeof("connection_type"), - sdp_parse_attr_simple_string, sdp_build_attr_simple_string }, - {"dialed", sizeof("dialed"), - sdp_parse_attr_simple_string, sdp_build_attr_simple_string }, - {"dialing", sizeof("dialing"), - sdp_parse_attr_simple_string, sdp_build_attr_simple_string }, - {"direction", sizeof("direction"), - sdp_parse_attr_comediadir, sdp_build_attr_comediadir }, - {"eecid", sizeof("eecid"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"fmtp", sizeof("fmtp"), - sdp_parse_attr_fmtp, sdp_build_attr_fmtp }, - {"framing", sizeof("framing"), - sdp_parse_attr_simple_string, sdp_build_attr_simple_string }, - {"inactive", sizeof("inactive"), - sdp_parse_attr_direction, sdp_build_attr_direction }, - {"ptime", sizeof("ptime"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"qos", sizeof("qos"), - sdp_parse_attr_qos, sdp_build_attr_qos }, - {"curr", sizeof("curr"), - sdp_parse_attr_curr, sdp_build_attr_curr }, - {"des", sizeof("des"), - sdp_parse_attr_des, sdp_build_attr_des}, - {"conf", sizeof("conf"), - sdp_parse_attr_conf, sdp_build_attr_conf}, - {"recvonly", sizeof("recvonly"), - sdp_parse_attr_direction, sdp_build_attr_direction }, - {"rtpmap", sizeof("rtpmap"), - sdp_parse_attr_transport_map, sdp_build_attr_transport_map }, - {"secure", sizeof("secure"), - sdp_parse_attr_qos, sdp_build_attr_qos }, - {"sendonly", sizeof("sendonly"), - sdp_parse_attr_direction, sdp_build_attr_direction }, - {"sendrecv", sizeof("sendrecv"), - sdp_parse_attr_direction, sdp_build_attr_direction }, - {"subnet", sizeof("subnet"), - sdp_parse_attr_subnet, sdp_build_attr_subnet }, - {"T38FaxVersion", sizeof("T38FaxVersion"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"T38MaxBitRate", sizeof("T38MaxBitRate"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"T38FaxFillBitRemoval", sizeof("T38FaxFillBitRemoval"), - sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool }, - {"T38FaxTranscodingMMR", sizeof("T38FaxTranscodingMMR"), - sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool }, - {"T38FaxTranscodingJBIG", sizeof("T38FaxTranscodingJBIG"), - sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool }, - {"T38FaxRateManagement", sizeof("T38FaxRateManagement"), - sdp_parse_attr_t38_ratemgmt, sdp_build_attr_t38_ratemgmt }, - {"T38FaxMaxBuffer", sizeof("T38FaxMaxBuffer"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"T38FaxMaxDatagram", sizeof("T38FaxMaxDatagram"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"T38FaxUdpEC", sizeof("T38FaxUdpEC"), - sdp_parse_attr_t38_udpec, sdp_build_attr_t38_udpec }, - {"X-cap", sizeof("X-cap"), - sdp_parse_attr_cap, sdp_build_attr_cap }, - {"X-cpar", sizeof("X-cpar"), - sdp_parse_attr_cpar, sdp_build_attr_cpar }, - {"X-pc-codec", sizeof("X-pc-codec"), - sdp_parse_attr_pc_codec, sdp_build_attr_pc_codec }, - {"X-pc-qos", sizeof("X-pc-qos"), - sdp_parse_attr_qos, sdp_build_attr_qos }, - {"X-qos", sizeof("X-qos"), - sdp_parse_attr_qos, sdp_build_attr_qos }, - {"X-sqn", sizeof("X-sqn"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"TMRGwXid", sizeof("TMRGwXid"), - sdp_parse_attr_simple_bool, sdp_build_attr_simple_bool }, - {"TC1PayloadBytes", sizeof("TC1PayloadBytes"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"TC1WindowSize", sizeof("TC1WindowSize"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"TC2PayloadBytes", sizeof("TC2PayloadBytes"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"TC2WindowSize", sizeof("TC2WindowSize"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"rtcp", sizeof("rtcp"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"rtr", sizeof("rtr"), - sdp_parse_attr_rtr, sdp_build_attr_rtr}, - {"silenceSupp", sizeof("silenceSupp"), - sdp_parse_attr_silencesupp, sdp_build_attr_silencesupp }, - {"X-crypto", sizeof("X-crypto"), - sdp_parse_attr_srtpcontext, sdp_build_attr_srtpcontext }, - {"mptime", sizeof("mptime"), - sdp_parse_attr_mptime, sdp_build_attr_mptime }, - {"X-sidin", sizeof("X-sidin"), - sdp_parse_attr_x_sidin, sdp_build_attr_x_sidin }, - {"X-sidout", sizeof("X-sidout"), - sdp_parse_attr_x_sidout, sdp_build_attr_x_sidout }, - {"X-confid", sizeof("X-confid"), - sdp_parse_attr_x_confid, sdp_build_attr_x_confid }, - {"group", sizeof("group"), - sdp_parse_attr_group, sdp_build_attr_group }, - {"mid", sizeof("mid"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"source-filter", sizeof("source-filter"), - sdp_parse_attr_source_filter, sdp_build_source_filter}, - {"rtcp-unicast", sizeof("rtcp-unicast"), - sdp_parse_attr_rtcp_unicast, sdp_build_attr_rtcp_unicast}, - {"maxprate", sizeof("maxprate"), - sdp_parse_attr_maxprate, sdp_build_attr_simple_string}, - {"sqn", sizeof("sqn"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"cdsc", sizeof("cdsc"), - sdp_parse_attr_cap, sdp_build_attr_cap }, - {"cpar", sizeof("cpar"), - sdp_parse_attr_cpar, sdp_build_attr_cpar }, - {"sprtmap", sizeof("sprtmap"), - sdp_parse_attr_transport_map, sdp_build_attr_transport_map }, - {"crypto", sizeof("crypto"), - sdp_parse_attr_sdescriptions, sdp_build_attr_sdescriptions }, - {"label", sizeof("label"), - sdp_parse_attr_simple_string, sdp_build_attr_simple_string }, - {"framerate", sizeof("framerate"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32 }, - {"candidate", sizeof("candidate"), - sdp_parse_attr_ice_attr, sdp_build_attr_ice_attr }, - {"ice-ufrag", sizeof("ice-ufrag"), - sdp_parse_attr_ice_attr, sdp_build_attr_ice_attr }, - {"ice-pwd", sizeof("ice-pwd"), - sdp_parse_attr_ice_attr, sdp_build_attr_ice_attr}, - {"rtcp-mux", sizeof("rtcp-mux"), - sdp_parse_attr_rtcp_mux_attr, sdp_build_attr_rtcp_mux_attr}, - {"fingerprint", sizeof("fingerprint"), - sdp_parse_attr_fingerprint_attr, sdp_build_attr_simple_string}, - {"maxptime", sizeof("maxptime"), - sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32} -}; - -/* Note: These *must* be in the same order as the enum types. */ -const sdp_namearray_t sdp_media[SDP_MAX_MEDIA_TYPES] = -{ - {"audio", sizeof("audio")}, - {"video", sizeof("video")}, - {"application", sizeof("application")}, - {"data", sizeof("data")}, - {"control", sizeof("control")}, - {"nas/radius", sizeof("nas/radius")}, - {"nas/tacacs", sizeof("nas/tacacs")}, - {"nas/diameter", sizeof("nas/diameter")}, - {"nas/l2tp", sizeof("nas/l2tp")}, - {"nas/login", sizeof("nas/login")}, - {"nas/none", sizeof("nas/none")}, - {"image", sizeof("image")}, - {"text", sizeof("text")} -}; - - -/* Note: These *must* be in the same order as the enum types. */ -const sdp_namearray_t sdp_nettype[SDP_MAX_NETWORK_TYPES] = -{ - {"IN", sizeof("IN")}, - {"ATM", sizeof("ATM")}, - {"FR", sizeof("FR")}, - {"LOCAL", sizeof("LOCAL")} -}; - - -/* Note: These *must* be in the same order as the enum types. */ -const sdp_namearray_t sdp_addrtype[SDP_MAX_ADDR_TYPES] = -{ - {"IP4", sizeof("IP4")}, - {"IP6", sizeof("IP6")}, - {"NSAP", sizeof("NSAP")}, - {"EPN", sizeof("EPN")}, - {"E164", sizeof("E164")}, - {"GWID", sizeof("GWID")} -}; - - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_transport[SDP_MAX_TRANSPORT_TYPES] = -{ - {"RTP/AVP", sizeof("RTP/AVP")}, - {"udp", sizeof("udp")}, - {"udptl", sizeof("udptl")}, - {"ces10", sizeof("ces10")}, - {"LOCAL", sizeof("LOCAL")}, - {"AAL2/ITU", sizeof("AAL2/ITU")}, - {"AAL2/ATMF", sizeof("AAL2/ATMF")}, - {"AAL2/custom", sizeof("AAL2/custom")}, - {"AAL1/AVP", sizeof("AAL1/AVP")}, - {"udpsprt", sizeof("udpsprt")}, - {"RTP/SAVP", sizeof("RTP/SAVP")}, - {"tcp", sizeof("tcp")}, - {"RTP/SAVPF", sizeof("RTP/SAVPF")}, - {"SCTP/DTLS", sizeof("SCTP/DTLS")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_encrypt[SDP_MAX_ENCRYPT_TYPES] = -{ - {"clear", sizeof("clear")}, - {"base64", sizeof("base64")}, - {"uri", sizeof("uri")}, - {"prompt", sizeof("prompt")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_payload[SDP_MAX_STRING_PAYLOAD_TYPES] = -{ - {"t38", sizeof("t38")}, - {"X-tmr", sizeof("X-tmr")}, - {"T120", sizeof("T120")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_t38_rate[SDP_T38_MAX_RATES] = -{ - {"localTCF", sizeof("localTCF")}, - {"transferredTCF", sizeof("transferredTCF")}, - {"unknown", sizeof("unknown")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_t38_udpec[SDP_T38_MAX_UDPEC] = -{ - {"t38UDPRedundancy", sizeof("t38UDPRedundancy")}, - {"t38UDPFEC", sizeof("t38UDPFEC")}, - {"unknown", sizeof("unknown")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_qos_strength[SDP_MAX_QOS_STRENGTH] = -{ - {"optional", sizeof("optional")}, - {"mandatory", sizeof("mandatory")}, - {"success", sizeof("success")}, - {"failure", sizeof("failure")}, - {"none", sizeof("none")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_qos_status_type[SDP_MAX_QOS_STATUS_TYPES] = -{ - {"local", sizeof("local")}, - {"remote", sizeof("remote")}, - {"e2e", sizeof("e2e")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_curr_type[SDP_MAX_CURR_TYPES] = -{ - {"qos", sizeof("qos")}, - {"unknown", sizeof("unknown")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_des_type[SDP_MAX_DES_TYPES] = -{ - {"qos", sizeof("qos")}, - {"unknown", sizeof("unknown")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_conf_type[SDP_MAX_CONF_TYPES] = -{ - {"qos", sizeof("qos")}, - {"unknown", sizeof("unknown")} -}; -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_qos_direction[SDP_MAX_QOS_DIR] = -{ - {"send", sizeof("send")}, - {"recv", sizeof("recv")}, - {"sendrecv", sizeof("sendrecv")}, - {"none", sizeof("none")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_silencesupp_pref[SDP_MAX_SILENCESUPP_PREF] = { - {"standard", sizeof("standard")}, - {"custom", sizeof("custom")}, - {"-", sizeof("-")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_silencesupp_siduse[SDP_MAX_SILENCESUPP_SIDUSE] = { - {"No SID", sizeof("No SID")}, - {"Fixed Noise", sizeof("Fixed Noise")}, - {"Sampled Noise", sizeof("Sampled Noise")}, - {"-", sizeof("-")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_mediadir_role[SDP_MAX_MEDIADIR_ROLES] = -{ - {"passive", sizeof("passive")}, - {"active", sizeof("active")}, - {"both", sizeof("both")}, - {"reuse", sizeof("reuse")}, - {"unknown", sizeof("unknown")} -}; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_fmtp_codec_param[SDP_MAX_FMTP_PARAM] = -{ - {"annexa", sizeof("annexa")}, /* 0 */ - {"annexb", sizeof("annexb")}, /* 1 */ - {"bitrate", sizeof("bitrate")}, /* 2 */ - {"QCIF", sizeof("QCIF")}, /* 3 */ - {"CIF", sizeof("CIF")}, /* 4 */ - {"MAXBR", sizeof("MAXBR")}, /* 5 */ - {"SQCIF", sizeof("SQCIF")}, /* 6 */ - {"CIF4", sizeof("CIF4")}, /* 7 */ - {"CIF16", sizeof("CIF16")}, /* 8 */ - {"CUSTOM", sizeof("CUSTOM")}, /* 9 */ - {"PAR", sizeof("PAR")}, /* 10 */ - {"CPCF", sizeof("CPCF")}, /* 11 */ - {"BPP", sizeof("BPP")}, /* 12 */ - {"HRD", sizeof("HRD")}, /* 13 */ - {"PROFILE", sizeof("PROFILE")}, /* 14 */ - {"LEVEL", sizeof("LEVEL")}, /* 15 */ - {"INTERLACE", sizeof("INTERLACE")}, /* 16 */ - - /* H.264 related */ - {"profile-level-id", sizeof("profile-level-id")}, /* 17 */ - {"sprop-parameter-sets", sizeof("sprop-parameter-sets")}, /* 18 */ - {"packetization-mode", sizeof("packetization-mode")}, /* 19 */ - {"sprop-interleaving-depth", sizeof("sprop-interleaving-depth")}, /* 20 */ - {"sprop-deint-buf-req", sizeof("sprop-deint-buf-req")}, /* 21 */ - {"sprop-max-don-diff", sizeof("sprop-max-don-diff")}, /* 22 */ - {"sprop-init-buf-time", sizeof("sprop-init-buf-time")}, /* 23 */ - - {"max-mbps", sizeof("max-mbps")}, /* 24 */ - {"max-fs", sizeof("max-fs")}, /* 25 */ - {"max-cpb", sizeof("max-cpb")}, /* 26 */ - {"max-dpb", sizeof("max-dpb")}, /* 27 */ - {"max-br", sizeof("max-br")}, /* 28 */ - {"redundant-pic-cap", sizeof("redundant-pic-cap")}, /* 29 */ - {"deint-buf-cap", sizeof("deint-buf-cap")}, /* 30 */ - {"max-rcmd-nalu-size", sizeof("max-rcmd_nali-size")}, /* 31 */ - {"parameter-add", sizeof("parameter-add")}, /* 32 */ - - /* Annexes - require special handling */ - {"D", sizeof("D")}, /* 33 */ - {"F", sizeof("F")}, /* 34 */ - {"I", sizeof("I")}, /* 35 */ - {"J", sizeof("J")}, /* 36 */ - {"T", sizeof("T")}, /* 37 */ - {"K", sizeof("K")}, /* 38 */ - {"N", sizeof("N")}, /* 39 */ - {"P", sizeof("P")}, /* 40 */ - - {"mode", sizeof("mode")}, /* 41 */ - {"level-asymmetry-allowed", sizeof("level-asymmetry-allowed")}, /* 42 */ - {"maxaveragebitrate", sizeof("maxaveragebitrate")}, /* 43 */ - {"usedtx", sizeof("usedtx")}, /* 44 */ - {"stereo", sizeof("stereo")}, /* 45 */ - {"useinbandfec", sizeof("useinbandfec")}, /* 46 */ - {"maxcodedaudiobandwidth", sizeof("maxcodedaudiobandwidth")}, /* 47 */ - {"cbr", sizeof("cbr")}, /* 48 */ - {"streams", sizeof("streams")}, /* 49 */ - {"protocol", sizeof("protocol")} /* 50 */ - -} ; - -/* Note: These *must* be in the same order as the enum type. */ -const sdp_namearray_t sdp_fmtp_codec_param_val[SDP_MAX_FMTP_PARAM_VAL] = -{ - {"yes", sizeof("yes")}, - {"no", sizeof("no")} -}; - -const sdp_namearray_t sdp_bw_modifier_val[SDP_MAX_BW_MODIFIER_VAL] = -{ - {"AS", sizeof("AS")}, - {"CT", sizeof("CT")}, - {"TIAS", sizeof("TIAS")} -}; - -const sdp_namearray_t sdp_group_attr_val[SDP_MAX_GROUP_ATTR_VAL] = -{ - {"FID", sizeof("FID")}, - {"LS", sizeof("LS")}, - {"ANAT", sizeof("ANAT")} -}; - -const sdp_namearray_t sdp_srtp_context_crypto_suite[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] = -{ - {"UNKNOWN_CRYPTO_SUITE", sizeof("UNKNOWN_CRYPTO_SUITE")}, - {"AES_CM_128_HMAC_SHA1_32", sizeof("AES_CM_128_HMAC_SHA1_32")}, - {"AES_CM_128_HMAC_SHA1_80", sizeof("AES_CM_128_HMAC_SHA1_80")}, - {"F8_128_HMAC_SHA1_80", sizeof("F8_128_HMAC_SHA1_80")} -}; - -/* Maintain the same order as defined in typedef sdp_src_filter_mode_e */ -const sdp_namearray_t sdp_src_filter_mode_val[SDP_MAX_FILTER_MODE] = -{ - {"incl", sizeof("incl")}, - {"excl", sizeof("excl")} -}; - -/* Maintain the same order as defined in typdef sdp_rtcp_unicast_mode_e */ -const sdp_namearray_t sdp_rtcp_unicast_mode_val[SDP_RTCP_MAX_UNICAST_MODE] = -{ - {"reflection", sizeof("reflection")}, - {"rsi", sizeof("rsi")} -}; - -/* Maintain same order as defined in typedef sdp_srtp_crypto_suite_t */ -const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] = -{ - {SDP_SRTP_UNKNOWN_CRYPTO_SUITE, UNKNOWN_CRYPTO_SUITE, 0, 0}, - {SDP_SRTP_AES_CM_128_HMAC_SHA1_32, AES_CM_128_HMAC_SHA1_32, - SDP_SRTP_AES_CM_128_HMAC_SHA1_32_KEY_BYTES, - SDP_SRTP_AES_CM_128_HMAC_SHA1_32_SALT_BYTES}, - {SDP_SRTP_AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_80, - SDP_SRTP_AES_CM_128_HMAC_SHA1_80_KEY_BYTES, - SDP_SRTP_AES_CM_128_HMAC_SHA1_80_SALT_BYTES}, - {SDP_SRTP_F8_128_HMAC_SHA1_80, F8_128_HMAC_SHA1_80, - SDP_SRTP_F8_128_HMAC_SHA1_80_KEY_BYTES, - SDP_SRTP_F8_128_HMAC_SHA1_80_SALT_BYTES} -}; - -const char* sdp_result_name[SDP_MAX_RC] = - {"SDP_SUCCESS", - "SDP_FAILURE", - "SDP_INVALID_SDP_PTR", - "SDP_NOT_SDP_DESCRIPTION", - "SDP_INVALID_TOKEN_ORDERING", - "SDP_INVALID_PARAMETER", - "SDP_INVALID_MEDIA_LEVEL", - "SDP_INVALID_CAPABILITY", - "SDP_NO_RESOURCE", - "SDP_UNRECOGNIZED_TOKEN", - "SDP_NULL_BUF_PTR", - "SDP_POTENTIAL_SDP_OVERFLOW"}; - -const char *sdp_get_result_name ( sdp_result_e rc ) -{ - if (rc >= SDP_MAX_RC) { - return ("Invalid SDP result code"); - } else { - return (sdp_result_name[rc]); - } -} - -const char *sdp_get_attr_name ( sdp_attr_e attr_type ) -{ - if (attr_type >= SDP_MAX_ATTR_TYPES) { - return ("Invalid attribute type"); - } else { - return (sdp_attr[attr_type].name); - } -} - -const char *sdp_get_media_name ( sdp_media_e media_type ) -{ - if (media_type == SDP_MEDIA_UNSUPPORTED) { - return (SDP_UNSUPPORTED); - } else if (media_type >= SDP_MAX_MEDIA_TYPES) { - return ("Invalid media type"); - } else { - return (sdp_media[media_type].name); - } -} - -const char *sdp_get_network_name ( sdp_nettype_e network_type ) -{ - if (network_type == SDP_NT_UNSUPPORTED) { - return (SDP_UNSUPPORTED); - } else if (network_type >= SDP_MAX_NETWORK_TYPES) { - return ("Invalid network type"); - } else { - return (sdp_nettype[network_type].name); - } -} - -const char *sdp_get_address_name ( sdp_addrtype_e addr_type ) -{ - if (addr_type == SDP_AT_UNSUPPORTED) { - return (SDP_UNSUPPORTED); - } else if (addr_type >= SDP_MAX_ADDR_TYPES) { - if (addr_type == SDP_AT_FQDN) { - return ("*"); - } else { - return ("Invalid address type"); - } - } else { - return (sdp_addrtype[addr_type].name); - } -} - -const char *sdp_get_transport_name ( sdp_transport_e transport_type ) -{ - if (transport_type == SDP_TRANSPORT_UNSUPPORTED) { - return (SDP_UNSUPPORTED); - } else if (transport_type >= SDP_MAX_TRANSPORT_TYPES) { - return ("Invalid transport type"); - } else { - return (sdp_transport[transport_type].name); - } -} - -const char *sdp_get_encrypt_name ( sdp_encrypt_type_e encrypt_type ) -{ - if (encrypt_type == SDP_ENCRYPT_UNSUPPORTED) { - return (SDP_UNSUPPORTED); - } else if (encrypt_type >= SDP_MAX_ENCRYPT_TYPES) { - return ("Invalid encryption type"); - } else { - return (sdp_encrypt[encrypt_type].name); - } -} - -const char *sdp_get_payload_name ( sdp_payload_e payload ) -{ - if (payload == SDP_PAYLOAD_UNSUPPORTED) { - return (SDP_UNSUPPORTED); - } else if (payload >= SDP_MAX_STRING_PAYLOAD_TYPES) { - return ("Invalid payload type"); - } else { - return (sdp_payload[payload].name); - } -} - -const char *sdp_get_t38_ratemgmt_name ( sdp_t38_ratemgmt_e rate ) -{ - if (rate >= SDP_T38_MAX_RATES) { - return ("Invalid rate"); - } else { - return (sdp_t38_rate[rate].name); - } -} - -const char *sdp_get_t38_udpec_name ( sdp_t38_udpec_e udpec ) -{ - if (udpec >= SDP_T38_MAX_UDPEC) { - return ("Invalid udpec"); - } else { - return (sdp_t38_udpec[udpec].name); - } -} - -const char *sdp_get_qos_strength_name ( sdp_qos_strength_e strength ) -{ - if (strength >= SDP_MAX_QOS_STRENGTH) { - return ("Invalid qos strength"); - } else { - return (sdp_qos_strength[strength].name); - } -} - -const char *sdp_get_qos_direction_name ( sdp_qos_dir_e direction ) -{ - if (direction >= SDP_MAX_QOS_DIR) { - return ("Invalid qos direction"); - } else { - return (sdp_qos_direction[direction].name); - } -} - -const char *sdp_get_qos_status_type_name ( sdp_qos_status_types_e status_type ) -{ - if (status_type >= SDP_MAX_QOS_STATUS_TYPES) { - return ("Invalid qos status type"); - } else { - return (sdp_qos_status_type[status_type].name); - } -} - -const char *sdp_get_curr_type_name (sdp_curr_type_e curr_type ) -{ - if (curr_type >= SDP_MAX_CURR_TYPES) { - return ("Invalid curr type"); - } else { - return (sdp_curr_type[curr_type].name); - } -} - -const char *sdp_get_des_type_name (sdp_des_type_e des_type ) -{ - if (des_type >= SDP_MAX_DES_TYPES) { - return ("Invalid des type"); - } else { - return (sdp_des_type[des_type].name); - } -} - -const char *sdp_get_conf_type_name (sdp_conf_type_e conf_type ) -{ - if (conf_type >= SDP_MAX_CONF_TYPES) { - return ("Invalid conf type"); - } else { - return (sdp_conf_type[conf_type].name); - } -} - -const char *sdp_get_silencesupp_pref_name (sdp_silencesupp_pref_e pref) -{ - if (pref >= SDP_MAX_SILENCESUPP_PREF) { - return ("Invalid silencesupp pref"); - } else { - return (sdp_silencesupp_pref[pref].name); - } -} - -const char *sdp_get_silencesupp_siduse_name (sdp_silencesupp_siduse_e siduse) -{ - if (siduse >= SDP_MAX_SILENCESUPP_SIDUSE) { - return ("Invalid silencesupp siduse"); - } else { - return (sdp_silencesupp_siduse[siduse].name); - } -} - -const char *sdp_get_mediadir_role_name (sdp_mediadir_role_e role) -{ - if (role >= SDP_MEDIADIR_ROLE_UNKNOWN) { - return ("Invalid media direction role"); - } else { - return (sdp_mediadir_role[role].name); - } -} - - -const char *sdp_get_bw_modifier_name (sdp_bw_modifier_e bw_modifier_type) -{ - if (bw_modifier_type == SDP_BW_MODIFIER_UNSUPPORTED) { - return (SDP_UNSUPPORTED); - } else if (bw_modifier_type < SDP_BW_MODIFIER_AS || - bw_modifier_type >= SDP_MAX_BW_MODIFIER_VAL) { - return ("Invalid bw modifier type"); - } else { - return (sdp_bw_modifier_val[bw_modifier_type].name); - } -} - -const char *sdp_get_group_attr_name (sdp_group_attr_e group_attr_type) -{ - if (group_attr_type == SDP_GROUP_ATTR_UNSUPPORTED) { - return (SDP_UNSUPPORTED); - } else if (group_attr_type >= SDP_MAX_GROUP_ATTR_VAL) { - return ("Invalid a=group: attribute type"); - } else { - return (sdp_group_attr_val[group_attr_type].name); - } -} - -const char *sdp_get_src_filter_mode_name (sdp_src_filter_mode_e type) -{ - if (type >= SDP_MAX_FILTER_MODE) { - return ("Invalid source filter mode"); - } else { - return (sdp_src_filter_mode_val[type].name); - } -} - -const char *sdp_get_rtcp_unicast_mode_name (sdp_rtcp_unicast_mode_e type) -{ - if (type >= SDP_RTCP_MAX_UNICAST_MODE) { - return ("Invalid rtcp unicast mode"); - } else { - return (sdp_rtcp_unicast_mode_val[type].name); - } -} - -/* Function: sdp_verify_sdp_ptr - * Description: Verify the SDP pointer is valid by checking for - * the SDP magic number. If not valid, display an error. - * Note that we can't keep a statistic of this because we - * track stats inside the config structure which is stored - * in the SDP structure. - * Parameters: sdp_p The SDP structure handle. - * Returns: TRUE or FALSE. - */ -inline tinybool sdp_verify_sdp_ptr (sdp_t *sdp_p) -{ - if ((sdp_p != NULL) && (sdp_p->magic_num == SDP_MAGIC_NUM)) { - return (TRUE); - } else { - CSFLogError(logTag, "SDP: Invalid SDP pointer."); - return (FALSE); - } -} - -/* Function: sdp_init_description - * Description: Allocates a new SDP structure that can be used for either - * parsing or building an SDP description. This routine - * saves the config pointer passed in the SDP structure so - * SDP will know how to parse/build based on the options defined. - * An SDP structure must be allocated before parsing or building - * since the handle must be passed to these routines. - * Parameters: config_p The config handle returned by sdp_init_config - * Returns: A handle for a new SDP structure as a void ptr. -*/ -sdp_t *sdp_init_description (const char *peerconnection, void *config_p) -{ - int i; - sdp_t *sdp_p; - sdp_conf_options_t *conf_p = (sdp_conf_options_t *)config_p; - - if (sdp_verify_conf_ptr(conf_p) == FALSE) { - return (NULL); - } - - sdp_p = (sdp_t *)SDP_MALLOC(sizeof(sdp_t)); - if (sdp_p == NULL) { - return (NULL); - } - - sstrncpy(sdp_p->peerconnection, peerconnection, sizeof(sdp_p->peerconnection)); - - /* Initialize magic number. */ - sdp_p->magic_num = SDP_MAGIC_NUM; - - sdp_p->conf_p = conf_p; - sdp_p->version = SDP_CURRENT_VERSION; - sdp_p->owner_name[0] = '\0'; - sdp_p->owner_sessid[0] = '\0'; - sdp_p->owner_version[0] = '\0'; - sdp_p->owner_network_type = SDP_NT_INVALID; - sdp_p->owner_addr_type = SDP_AT_INVALID; - sdp_p->owner_addr[0] = '\0'; - sdp_p->sessname[0] = '\0'; - sdp_p->sessinfo_found = FALSE; - sdp_p->uri_found = FALSE; - - sdp_p->default_conn.nettype = SDP_NT_INVALID; - sdp_p->default_conn.addrtype = SDP_AT_INVALID; - sdp_p->default_conn.conn_addr[0] = '\0'; - sdp_p->default_conn.is_multicast = FALSE; - sdp_p->default_conn.ttl = 0; - sdp_p->default_conn.num_of_addresses = 0; - - sdp_p->bw.bw_data_count = 0; - sdp_p->bw.bw_data_list = NULL; - - sdp_p->timespec_p = NULL; - sdp_p->sess_attrs_p = NULL; - sdp_p->mca_p = NULL; - sdp_p->mca_count = 0; - - /* Set default debug flags from application config. */ - for (i=0; i < SDP_MAX_DEBUG_TYPES; i++) { - sdp_p->debug_flag[i] = conf_p->debug_flag[i]; - } - - return (sdp_p); -} - - -/* Function: void sdp_debug(sdp_t *sdp_p, sdp_debug_e debug_type, - * tinybool my_bool); - * Description: Define the type of debug for this particular SDP structure. - * By default, each SDP description has the settings that are - * set for the application. - * Valid debug types are ERRORS, WARNINGS, and TRACE. Each - * debug type can be turned on/off individually. The - * debug level can be redefined at any time. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * debug_type Specifies the debug type being enabled/disabled. - * my_bool Defines whether the debug should be enabled or not. - * Returns: Nothing. - */ -void sdp_debug (sdp_t *sdp_p, sdp_debug_e debug_type, tinybool debug_flag) -{ - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return; - } - - if (debug_type < SDP_MAX_DEBUG_TYPES) { - sdp_p->debug_flag[debug_type] = debug_flag; - } -} - - -/* Function: void sdp_set_string_debug(sdp_t *sdp_p, char *debug_str) - * Description: Define a string to be associated with all debug output - * for this SDP. The string will be copied into the SDP - * structure and so the library will not be dependent on - * the application's memory for this string. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * debug_str Pointer to a string that should be printed out - * with every debug msg. - * Returns: Nothing. - */ -void sdp_set_string_debug (sdp_t *sdp_p, const char *debug_str) -{ - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return; - } - - sstrncpy(sdp_p->debug_str, debug_str, sizeof(sdp_p->debug_str)); -} - - -/* Function: sdp_validate_sdp - * Description: Validate an SDP structure. - * Parameters: sdp_p The SDP handle of the struct to validate. - * Returns: A result value indicating if the validation was successful. - * If not, what type of error was encountered. - */ -sdp_result_e sdp_validate_sdp (sdp_t *sdp_p) -{ - int i; - u16 num_media_levels; - - /* Need to validate c= info is specified at session level or - * at all m= levels. - */ - if (sdp_connection_valid((void *)sdp_p, SDP_SESSION_LEVEL) == FALSE) { - num_media_levels = sdp_get_num_media_lines((void *)sdp_p); - for (i=1; i <= num_media_levels; i++) { - if (sdp_connection_valid((void *)sdp_p, (unsigned short)i) == FALSE) { - sdp_parse_error(sdp_p->peerconnection, - "%s c= connection line not specified for " - "every media level, validation failed.", - sdp_p->debug_str); - return (SDP_FAILURE); - } - } - } - - /* Validate required lines were specified */ - if ((sdp_owner_valid((void *)sdp_p) == FALSE) && - (sdp_p->conf_p->owner_reqd == TRUE)) { - sdp_parse_error(sdp_p->peerconnection, - "%s o= owner line not specified, validation failed.", - sdp_p->debug_str); - return (SDP_FAILURE); - } - - if ((sdp_session_name_valid((void *)sdp_p) == FALSE) && - (sdp_p->conf_p->session_name_reqd == TRUE)) { - sdp_parse_error(sdp_p->peerconnection, - "%s s= session name line not specified, validation failed.", - sdp_p->debug_str); - return (SDP_FAILURE); - } - - if ((sdp_timespec_valid((void *)sdp_p) == FALSE) && - (sdp_p->conf_p->timespec_reqd == TRUE)) { - sdp_parse_error(sdp_p->peerconnection, - "%s t= timespec line not specified, validation failed.", - sdp_p->debug_str); - return (SDP_FAILURE); - } - - return (SDP_SUCCESS); -} - -/* Function: sdp_parse - * Description: Parse an SDP description in the specified buffer. - * Parameters: sdp_p The SDP handle returned by sdp_init_description - * bufp Pointer to the buffer containing the SDP - * description to parse. - * len The length of the buffer. - * Returns: A result value indicating if the parse was successful and - * if not, what type of error was encountered. The - * information from the parse is stored in the sdp_p structure. - */ -sdp_result_e sdp_parse (sdp_t *sdp_p, char **bufp, u16 len) -{ - u8 i; - u16 cur_level = SDP_SESSION_LEVEL; - char *ptr; - char *next_ptr = NULL; - char *line_end; - sdp_token_e last_token = SDP_TOKEN_V; - sdp_result_e result=SDP_SUCCESS; - tinybool parse_done = FALSE; - tinybool end_found = FALSE; - tinybool first_line = TRUE; - tinybool unrec_token = FALSE; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if ((bufp == NULL) || (*bufp == NULL)) { - return (SDP_NULL_BUF_PTR); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Trace SDP Parse:", sdp_p->debug_str); - } - - next_ptr = *bufp; - sdp_p->conf_p->num_parses++; - - /* Initialize the last valid capability instance to zero. Used - * to help in parsing X-cpar attrs. */ - sdp_p->cap_valid = FALSE; - sdp_p->last_cap_inst = 0; - - /* We want to try to find the end of the SDP description, even if - * we find a parsing error. - */ - while (!end_found) { - /* If the last char of this line goes beyond the end of the buffer, - * we don't parse it. - */ - ptr = next_ptr; - line_end = sdp_findchar(ptr, "\n"); - if (line_end >= (*bufp + len)) { - sdp_parse_error(sdp_p->peerconnection, - "%s End of line beyond end of buffer.", - sdp_p->debug_str); - end_found = TRUE; - break; - } - - /* Print the line if we're tracing. */ - if ((parse_done == FALSE) && - (sdp_p->debug_flag[SDP_DEBUG_TRACE])) { - SDP_PRINT("%s ", sdp_p->debug_str); - - SDP_PRINT("%*s", line_end - ptr, ptr); - - } - - /* Find out which token this line has, if any. */ - for (i=0; i < SDP_MAX_TOKENS; i++) { - if (strncmp(ptr, sdp_token[i].name, SDP_TOKEN_LEN) == 0) { - break; - } - } - if (i == SDP_MAX_TOKENS) { - /* See if the second char on the next line is an '=' char. - * If so, we note this as an unrecognized token line. */ - if (ptr[1] == '=') { - unrec_token = TRUE; - } - if (first_line == TRUE) { - sdp_parse_error(sdp_p->peerconnection, - "%s Attempt to parse text not recognized as " - "SDP text, parse fails.", sdp_p->debug_str); - /* If we haven't already printed out the line we - * were trying to parse, do it now. - */ - if (!sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s ", sdp_p->debug_str); - SDP_PRINT("%*s", line_end - ptr, ptr); - } - sdp_p->conf_p->num_not_sdp_desc++; - return (SDP_NOT_SDP_DESCRIPTION); - } else { - end_found = TRUE; - break; - } - } - - /* This is the beginning of a new SDP description. */ - if ((first_line != TRUE) && (i == SDP_TOKEN_V)) { - end_found = TRUE; - break; - } - - /* Advance the next ptr to one char beyond the end of the line. */ - next_ptr = line_end + 1; - if (next_ptr >= (*bufp + len)) { - end_found = TRUE; - } - - /* If we've finished parsing and are just looking for the end of - * the SDP description, we don't need to do anything else here. - */ - if (parse_done == TRUE) { - continue; - } - - /* Only certain tokens are valid at the media level. */ - if (cur_level != SDP_SESSION_LEVEL) { - if ((i != SDP_TOKEN_I) && (i != SDP_TOKEN_C) && - (i != SDP_TOKEN_B) && (i != SDP_TOKEN_K) && - (i != SDP_TOKEN_A) && (i != SDP_TOKEN_M)) { - sdp_p->conf_p->num_invalid_token_order++; - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid token %s found at media level", - sdp_p->debug_str, sdp_token[i].name); - continue; - } - } - - /* Verify the token ordering. */ - if (first_line == TRUE) { - if (i != SDP_TOKEN_V) { - if (sdp_p->conf_p->version_reqd == TRUE) { - sdp_parse_error(sdp_p->peerconnection, - "%s First line not v=, parse fails", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_token_order++; - result = SDP_INVALID_TOKEN_ORDERING; - parse_done = TRUE; - } else { - last_token = (sdp_token_e)i; - } - } else { - last_token = (sdp_token_e)i; - } - first_line = FALSE; - } else { - if (i < last_token) { - sdp_p->conf_p->num_invalid_token_order++; - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Invalid token ordering detected, " - "token %s found after token %s", sdp_p->debug_str, - sdp_token[i].name, sdp_token[last_token].name); - } - } - - /* Finally parse the line. */ - ptr += SDP_TOKEN_LEN; - result = sdp_token[i].parse_func(sdp_p, cur_level, (const char *)ptr); - last_token = (sdp_token_e)i; - if (last_token == SDP_TOKEN_M) { - if (cur_level == SDP_SESSION_LEVEL) { - cur_level = 1; - } else { - cur_level++; - } - /* The token ordering can start again at i= */ - last_token = (sdp_token_e)(SDP_TOKEN_I - 1); - } - if (result != SDP_SUCCESS) { - parse_done = TRUE; - } - - /* Skip the new line char at the end of this line and see if - * this is the end of the buffer. - */ - if ((line_end + 1) == (*bufp + len)) { - end_found = TRUE; - } - } - - /* If we found no valid lines, return an error. */ - if (first_line == TRUE) { - sdp_p->conf_p->num_not_sdp_desc++; - return (SDP_NOT_SDP_DESCRIPTION); - } - - /* If no errors were found yet, validate the overall sdp. */ - if (result == SDP_SUCCESS) { - result = sdp_validate_sdp(sdp_p); - } - /* Return the pointer where we left off. */ - *bufp = next_ptr; - /* If the SDP is valid, but the next line following was an - * unrecognized = line, indicate this on the return. */ - if ((result == SDP_SUCCESS) && (unrec_token == TRUE)) { - return (SDP_UNRECOGNIZED_TOKEN); - } else { - return (result); - } -} - - -/* Function: sdp_build - * Description: Build an SDP description in the specified buffer based - * on the information in the given SDP structure. - * Parameters: sdp_p The SDP handle returned by sdp_init_description - * fs A flex_string where the SDP description should be built. - * Returns: A result value indicating if the build was successful and - * if not, what type of error was encountered - e.g., - * description was too long for the given buffer. - */ -sdp_result_e sdp_build (sdp_t *sdp_p, flex_string *fs) -{ - int i, j; - sdp_result_e result = SDP_SUCCESS; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - if (!fs) { - return (SDP_NULL_BUF_PTR); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Trace SDP Build:", sdp_p->debug_str); - } - - sdp_p->conf_p->num_builds++; - - for (i=0; ((i < SDP_TOKEN_M) && - (result == SDP_SUCCESS)); i++) { - result = sdp_token[i].build_func(sdp_p, SDP_SESSION_LEVEL, fs); - /* ok not to check buffer space (yet) as the if() checks it */ - } - /* If the session level was ok, build the media lines. */ - if (result == SDP_SUCCESS) { - for (i=1; ((i <= sdp_p->mca_count) && - (result == SDP_SUCCESS)); i++) { - result = sdp_token[SDP_TOKEN_M].build_func(sdp_p, (u16)i, fs); - - /* ok not to check buffer space (yet) as the for() checks it */ - for (j=SDP_TOKEN_I; - ((j < SDP_TOKEN_M) && (result == SDP_SUCCESS)); - j++) { - if ((j == SDP_TOKEN_U) || (j == SDP_TOKEN_E) || - (j == SDP_TOKEN_P) || (j == SDP_TOKEN_T) || - (j == SDP_TOKEN_R) || (j == SDP_TOKEN_Z)) { - /* These tokens not valid at media level. */ - continue; - } - result = sdp_token[j].build_func(sdp_p, (u16)i, fs); - /* ok not to check buffer space (yet) as the for() checks it */ - } - } - } - - return (result); -} - -/* Function: sdp_copy - * Description: Create a new SDP structure that is an exact copy of the - * one passed in. - * Parameters: orig_sdp_p The SDP handle of the SDP to be copied. - * Returns: A handle for a new SDP structure as a void ptr. -*/ -sdp_t *sdp_copy (sdp_t *orig_sdp_p) -{ - int i, j; - u16 cur_level; - sdp_result_e rc; - sdp_t *new_sdp_p; - sdp_timespec_t *cur_time_p = NULL; - sdp_timespec_t *orig_time_p = NULL; - sdp_mca_t *orig_mca_p = NULL; - sdp_mca_t *new_mca_p = NULL; - sdp_mca_t *dst_mca_p = NULL; - sdp_media_profiles_t *src_media_profile_p; - sdp_media_profiles_t *dst_media_profile_p; - - if (orig_sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Copy SDP:", orig_sdp_p->debug_str); - } - - if (sdp_verify_sdp_ptr(orig_sdp_p) == FALSE) { - return (NULL); - } - - new_sdp_p = (sdp_t *)SDP_MALLOC(sizeof(sdp_t)); - if (new_sdp_p == NULL) { - return (NULL); - } - - sstrncpy(new_sdp_p->peerconnection, orig_sdp_p->peerconnection, - sizeof(new_sdp_p->peerconnection)); - - /* Initialize magic number. */ - new_sdp_p->magic_num = orig_sdp_p->magic_num; - - new_sdp_p->conf_p = orig_sdp_p->conf_p; - new_sdp_p->version = orig_sdp_p->version; - sstrncpy(new_sdp_p->owner_name, orig_sdp_p->owner_name, - SDP_MAX_LINE_LEN+1); - sstrncpy(new_sdp_p->owner_sessid, orig_sdp_p->owner_sessid, - SDP_MAX_LINE_LEN+1); - sstrncpy(new_sdp_p->owner_version, orig_sdp_p->owner_version, - SDP_MAX_LINE_LEN+1); - new_sdp_p->owner_network_type = orig_sdp_p->owner_network_type; - new_sdp_p->owner_addr_type = orig_sdp_p->owner_addr_type; - sstrncpy(new_sdp_p->owner_addr, orig_sdp_p->owner_addr, - SDP_MAX_LINE_LEN+1); - sstrncpy(new_sdp_p->sessname, orig_sdp_p->sessname, - SDP_MAX_LINE_LEN+1); - new_sdp_p->sessinfo_found = orig_sdp_p->sessinfo_found; - new_sdp_p->uri_found = orig_sdp_p->uri_found; - - new_sdp_p->default_conn.nettype = orig_sdp_p->default_conn.nettype; - new_sdp_p->default_conn.addrtype = orig_sdp_p->default_conn.addrtype; - sstrncpy(new_sdp_p->default_conn.conn_addr, - orig_sdp_p->default_conn.conn_addr, - SDP_MAX_LINE_LEN+1); - - new_sdp_p->default_conn.is_multicast = - orig_sdp_p->default_conn.is_multicast; - new_sdp_p->default_conn.ttl = orig_sdp_p->default_conn.ttl; - new_sdp_p->default_conn.num_of_addresses - = orig_sdp_p->default_conn.num_of_addresses; - new_sdp_p->encrypt.encrypt_type = orig_sdp_p->encrypt.encrypt_type; - sstrncpy(new_sdp_p->encrypt.encrypt_key, - orig_sdp_p->encrypt.encrypt_key, SDP_MAX_LINE_LEN+1); - - /* Copy all session level bw lines. */ - rc = sdp_copy_all_bw_lines(orig_sdp_p, new_sdp_p, - SDP_SESSION_LEVEL, SDP_SESSION_LEVEL); - if (rc != SDP_SUCCESS) { - sdp_free_description(new_sdp_p); - return (NULL); - } - - /* Copy timespec structures. */ - orig_time_p = orig_sdp_p->timespec_p; - while (orig_time_p != NULL) { - if (cur_time_p == NULL) { - new_sdp_p->timespec_p = \ - (sdp_timespec_t *)SDP_MALLOC(sizeof(sdp_timespec_t)); - cur_time_p = new_sdp_p->timespec_p; - } else { - cur_time_p->next_p = \ - (sdp_timespec_t *)SDP_MALLOC(sizeof(sdp_timespec_t)); - cur_time_p = cur_time_p->next_p; - } - if (cur_time_p == NULL) { - sdp_free_description(new_sdp_p); - return (NULL); - } - sstrncpy(cur_time_p->start_time, orig_time_p->start_time, - SDP_MAX_LINE_LEN+1); - sstrncpy(cur_time_p->stop_time, orig_time_p->stop_time, - SDP_MAX_LINE_LEN+1); - cur_time_p->next_p = NULL; - - /* Move to next time structure. */ - orig_time_p = orig_time_p->next_p; - } - - /* Copy all session attributes. */ - rc = sdp_copy_all_attrs(orig_sdp_p, new_sdp_p, - SDP_SESSION_LEVEL, SDP_SESSION_LEVEL); - if (rc != SDP_SUCCESS) { - sdp_free_description(new_sdp_p); - return (NULL); - } - - - /* Now copy each media level with its parameters and all - * corresponding attrs. */ - orig_mca_p = orig_sdp_p->mca_p; - new_mca_p = NULL; - cur_level = 0; - while (orig_mca_p != NULL) { - cur_level++; - - /* Allocate and link in a new media level. */ - new_mca_p = sdp_alloc_mca(); - if (new_mca_p == NULL) { - sdp_free_description(new_sdp_p); - return (NULL); - } - if (dst_mca_p == NULL) { - new_sdp_p->mca_p = new_mca_p; - } else { - dst_mca_p->next_p = new_mca_p; - } - dst_mca_p = new_mca_p; - new_sdp_p->mca_count++; - - /* Copy all the media level parameters. */ - dst_mca_p->media = orig_mca_p->media; - dst_mca_p->conn.nettype = orig_mca_p->conn.nettype; - dst_mca_p->conn.addrtype = orig_mca_p->conn.addrtype; - sstrncpy(dst_mca_p->conn.conn_addr, orig_mca_p->conn.conn_addr, - SDP_MAX_LINE_LEN+1); - - dst_mca_p->conn.is_multicast = orig_mca_p->conn.is_multicast; - dst_mca_p->conn.ttl = orig_mca_p->conn.ttl; - dst_mca_p->conn.num_of_addresses = orig_mca_p->conn.num_of_addresses; - - dst_mca_p->transport = orig_mca_p->transport; - dst_mca_p->port_format = orig_mca_p->port_format; - dst_mca_p->port = orig_mca_p->port; - dst_mca_p->num_ports = orig_mca_p->num_ports; - dst_mca_p->vpi = orig_mca_p->vpi; - dst_mca_p->vci = orig_mca_p->vci; - dst_mca_p->vcci = orig_mca_p->vcci; - dst_mca_p->cid = orig_mca_p->cid; - dst_mca_p->num_payloads = orig_mca_p->num_payloads; - - for (i=0; i < SDP_MAX_PAYLOAD_TYPES; i++) { - dst_mca_p->payload_indicator[i] = orig_mca_p->payload_indicator[i]; - dst_mca_p->payload_type[i] = orig_mca_p->payload_type[i]; - } - - dst_mca_p->sessinfo_found = orig_mca_p->sessinfo_found; - dst_mca_p->encrypt.encrypt_type = orig_mca_p->encrypt.encrypt_type; - sstrncpy(dst_mca_p->encrypt.encrypt_key, - orig_mca_p->encrypt.encrypt_key, SDP_MAX_LINE_LEN+1); - dst_mca_p->media_direction = orig_mca_p->media_direction; - - /* Now copy all the media level bw lines over. */ - rc = sdp_copy_all_bw_lines(orig_sdp_p, new_sdp_p, cur_level, cur_level); - if (rc != SDP_SUCCESS) { - sdp_free_description(new_sdp_p); - return (NULL); - } - - dst_mca_p->mid = orig_mca_p->mid; - - if (orig_mca_p->media_profiles_p != NULL) { - src_media_profile_p = orig_mca_p->media_profiles_p; - dst_mca_p->media_profiles_p = (sdp_media_profiles_t *) - SDP_MALLOC(sizeof(sdp_media_profiles_t)); - dst_media_profile_p = dst_mca_p->media_profiles_p; - if (dst_media_profile_p == NULL) { - sdp_free_description(new_sdp_p); - return (NULL); - } - - dst_media_profile_p->num_profiles = - src_media_profile_p->num_profiles; - for (i=0; i < SDP_MAX_PROFILES; i++) { - dst_media_profile_p->profile[i] = - src_media_profile_p->profile[i]; - dst_media_profile_p->num_payloads[i] = - src_media_profile_p->num_payloads[i]; - for (j=0; j < SDP_MAX_PAYLOAD_TYPES; j++) { - dst_media_profile_p->payload_indicator[i][j] = - src_media_profile_p->payload_indicator[i][j]; - dst_media_profile_p->payload_type[i][j] = - src_media_profile_p->payload_type[i][j]; - - } - } - } - - /* Now copy all the media level attrs over. */ - (void)sdp_copy_all_attrs(orig_sdp_p, new_sdp_p, cur_level, cur_level); - - /* Now move to the next media level. */ - orig_mca_p = orig_mca_p->next_p; - } - - - /* Set default debug flags from application config. */ - for (i=0; i < SDP_MAX_DEBUG_TYPES; i++) { - new_sdp_p->debug_flag[i] = orig_sdp_p->debug_flag[i]; - } - - return (new_sdp_p); -} - -/* Function: sdp_free_description - * Description: Free an SDP description and all memory associated with it. - * Parameters: sdp_p The SDP handle returned by sdp_init_description - * Returns: A result value indicating if the free was successful and - * if not, what type of error was encountered - e.g., sdp_p - * was invalid and didn't point to an SDP structure. -*/ -sdp_result_e sdp_free_description (sdp_t *sdp_p) -{ - sdp_timespec_t *time_p, *next_time_p; - sdp_attr_t *attr_p, *next_attr_p; - sdp_mca_t *mca_p, *next_mca_p; - sdp_bw_t *bw_p; - sdp_bw_data_t *bw_data_p; - - if (sdp_verify_sdp_ptr(sdp_p) == FALSE) { - return (SDP_INVALID_SDP_PTR); - } - - /* Free any timespec structures - should be only one since - * this is all we currently support. - */ - time_p = sdp_p->timespec_p; - while (time_p != NULL) { - next_time_p = time_p->next_p; - SDP_FREE(time_p); - time_p = next_time_p; - } - - bw_p = &(sdp_p->bw); - bw_data_p = bw_p->bw_data_list; - while (bw_data_p != NULL) { - bw_p->bw_data_list = bw_data_p->next_p; - SDP_FREE(bw_data_p); - bw_data_p = bw_p->bw_data_list; - } - - /* Free any session attr structures */ - attr_p = sdp_p->sess_attrs_p; - while (attr_p != NULL) { - next_attr_p = attr_p->next_p; - sdp_free_attr(attr_p); - attr_p = next_attr_p; - } - - /* Free any mca structures */ - mca_p = sdp_p->mca_p; - while (mca_p != NULL) { - next_mca_p = mca_p->next_p; - - /* Free any media attr structures */ - attr_p = mca_p->media_attrs_p; - while (attr_p != NULL) { - next_attr_p = attr_p->next_p; - sdp_free_attr(attr_p); - attr_p = next_attr_p; - } - - /* Free the media profiles struct if allocated. */ - if (mca_p->media_profiles_p != NULL) { - SDP_FREE(mca_p->media_profiles_p); - } - - bw_p = &(mca_p->bw); - bw_data_p = bw_p->bw_data_list; - while (bw_data_p != NULL) { - bw_p->bw_data_list = bw_data_p->next_p; - SDP_FREE(bw_data_p); - bw_data_p = bw_p->bw_data_list; - } - - SDP_FREE(mca_p); - mca_p = next_mca_p; - } - - SDP_FREE(sdp_p); - - return (SDP_SUCCESS); -} - -/* - * sdp_parse_error - * Send SDP parsing errors to log and up to peerconnection - */ -void sdp_parse_error(const char *peerconnection, const char *format, ...) { - va_list ap; - - /* TODO - report error up to PeerConnection here */ - - va_start(ap, format); - CSFLogErrorV("SDP Parse", format, ap); - va_end(ap); -} diff --git a/libs/sipcc/core/sdp/sdp_os_defs.h b/libs/sipcc/core/sdp/sdp_os_defs.h deleted file mode 100644 index 2f04b6f6e4..0000000000 --- a/libs/sipcc/core/sdp/sdp_os_defs.h +++ /dev/null @@ -1,33 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SDP_OS_DEFS_H_ -#define _SDP_OS_DEFS_H_ - - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "phone_debug.h" - - -#define SDP_PRINT buginf -#define SDP_MALLOC(x) cpr_calloc(1, (x)) -#define SDP_FREE cpr_free - -typedef uint8_t tinybool; -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint16_t uint16; -typedef uint32_t u32; -typedef uint32_t uint32; -typedef int32_t int32; -typedef int16_t int16; -typedef unsigned short ushort; -typedef unsigned long ulong; -#define inline - - -#endif /* _SDP_OS_DEFS_H_ */ diff --git a/libs/sipcc/core/sdp/sdp_private.h b/libs/sipcc/core/sdp/sdp_private.h deleted file mode 100644 index 90634d4b8b..0000000000 --- a/libs/sipcc/core/sdp/sdp_private.h +++ /dev/null @@ -1,311 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SDP_PRIVATE_H_ -#define _SDP_PRIVATE_H_ - - -#include "sdp.h" - -extern const sdp_attrarray_t sdp_attr[]; -extern const sdp_namearray_t sdp_media[]; -extern const sdp_namearray_t sdp_nettype[]; -extern const sdp_namearray_t sdp_addrtype[]; -extern const sdp_namearray_t sdp_transport[]; -extern const sdp_namearray_t sdp_encrypt[]; -extern const sdp_namearray_t sdp_payload[]; -extern const sdp_namearray_t sdp_t38_rate[]; -extern const sdp_namearray_t sdp_t38_udpec[]; -extern const sdp_namearray_t sdp_qos_strength[]; -extern const sdp_namearray_t sdp_qos_direction[]; -extern const sdp_namearray_t sdp_qos_status_type[]; -extern const sdp_namearray_t sdp_curr_type[]; -extern const sdp_namearray_t sdp_des_type[]; -extern const sdp_namearray_t sdp_conf_type[]; -extern const sdp_namearray_t sdp_mediadir_role[]; -extern const sdp_namearray_t sdp_fmtp_codec_param[]; -extern const sdp_namearray_t sdp_fmtp_codec_param_val[]; -extern const sdp_namearray_t sdp_silencesupp_pref[]; -extern const sdp_namearray_t sdp_silencesupp_siduse[]; -extern const sdp_namearray_t sdp_srtp_context_crypto_suite[]; -extern const sdp_namearray_t sdp_bw_modifier_val[]; -extern const sdp_namearray_t sdp_group_attr_val[]; -extern const sdp_namearray_t sdp_src_filter_mode_val[]; -extern const sdp_namearray_t sdp_rtcp_unicast_mode_val[]; - -extern const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[]; -/* Function Prototypes */ - -/* sdp_access.c */ -extern sdp_mca_t *sdp_find_media_level(sdp_t *sdp_p, u16 level); -extern sdp_bw_data_t* sdp_find_bw_line (void *sdp_ptr, u16 level, u16 inst_num); - -/* sdp_attr.c */ -extern sdp_result_e sdp_parse_attribute(sdp_t *sdp_p, u16 level, - const char *ptr); -extern sdp_result_e sdp_parse_attr_simple_string(sdp_t *sdp_p, - sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_simple_string(sdp_t *sdp_p, - sdp_attr_t *attr_p, flex_string *fs); -extern sdp_result_e sdp_parse_attr_simple_u32(sdp_t *sdp_p, - sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_simple_u32(sdp_t *sdp_p, - sdp_attr_t *attr_p, flex_string *fs); -extern sdp_result_e sdp_parse_attr_simple_bool(sdp_t *sdp_p, - sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_simple_bool(sdp_t *sdp_p, - sdp_attr_t *attr_p, flex_string *fs); -extern sdp_result_e sdp_parse_attr_maxprate(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_parse_attr_fmtp(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_fmtp(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_direction(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_direction(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_qos(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_qos(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_curr(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_curr (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_des(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_des (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_conf(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_conf (sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_transport_map(sdp_t *sdp_p, - sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_transport_map(sdp_t *sdp_p, - sdp_attr_t *attr_p, flex_string *fs); -extern sdp_result_e sdp_parse_attr_subnet(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_subnet(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_t38_ratemgmt(sdp_t *sdp_p, - sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_t38_ratemgmt(sdp_t *sdp_p, - sdp_attr_t *attr_p, flex_string *fs); -extern sdp_result_e sdp_parse_attr_t38_udpec(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_t38_udpec(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_cap(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_cap(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_cpar(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_cpar(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_pc_codec(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_pc_codec(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_xcap(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_xcap(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_xcpar(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_xcpar(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_rtr(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_rtr(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_comediadir(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_comediadir(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_silencesupp(sdp_t *sdp_p, - sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_silencesupp(sdp_t *sdp_p, - sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_srtpcontext(sdp_t *sdp_p, - sdp_attr_t *attr_p, - const char *ptr); -extern sdp_result_e sdp_build_attr_srtpcontext(sdp_t *sdp_p, - sdp_attr_t *attr_p, - flex_string *fs); -extern sdp_result_e sdp_parse_attr_mptime( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_mptime( - sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); - -extern sdp_result_e sdp_parse_attr_x_sidin( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_x_sidin( - sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); - -extern sdp_result_e sdp_parse_attr_x_sidout( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_x_sidout( - sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); - -extern sdp_result_e sdp_parse_attr_x_confid( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_x_confid( - sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); - -extern sdp_result_e sdp_parse_attr_group( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_group( - sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); - -extern sdp_result_e sdp_parse_attr_source_filter( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_source_filter( - sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); - -extern sdp_result_e sdp_parse_attr_rtcp_unicast( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_build_attr_rtcp_unicast( - sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); - -extern sdp_result_e sdp_build_attr_ice_attr ( - sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); -extern sdp_result_e sdp_parse_attr_ice_attr ( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); - -extern sdp_result_e sdp_build_attr_rtcp_mux_attr ( - sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); -extern sdp_result_e sdp_parse_attr_rtcp_mux_attr ( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); -extern sdp_result_e sdp_parse_attr_fingerprint_attr ( - sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); - -/* sdp_attr_access.c */ -extern void sdp_free_attr(sdp_attr_t *attr_p); -extern sdp_result_e sdp_find_attr_list(sdp_t *sdp_p, u16 level, u8 cap_num, - sdp_attr_t **attr_p, char *fname); -extern sdp_attr_t *sdp_find_attr(sdp_t *sdp_p, u16 level, u8 cap_num, - sdp_attr_e attr_type, u16 inst_num); -extern sdp_attr_t *sdp_find_capability(sdp_t *sdp_p, u16 level, u8 cap_num); - -/* sdp_config.c */ -extern tinybool sdp_verify_conf_ptr(sdp_conf_options_t *conf_p); - -/* sdp_main.c */ -extern const char *sdp_get_attr_name(sdp_attr_e attr_type); -extern const char *sdp_get_media_name(sdp_media_e media_type); -extern const char *sdp_get_network_name(sdp_nettype_e network_type); -extern const char *sdp_get_address_name(sdp_addrtype_e addr_type); -extern const char *sdp_get_transport_name(sdp_transport_e transport_type); -extern const char *sdp_get_encrypt_name(sdp_encrypt_type_e encrypt_type); -extern const char *sdp_get_payload_name(sdp_payload_e payload); -extern const char *sdp_get_t38_ratemgmt_name(sdp_t38_ratemgmt_e rate); -extern const char *sdp_get_t38_udpec_name(sdp_t38_udpec_e udpec); -extern const char *sdp_get_qos_strength_name(sdp_qos_strength_e strength); -extern const char *sdp_get_qos_direction_name(sdp_qos_dir_e direction); -extern const char *sdp_get_qos_status_type_name(sdp_qos_status_types_e status_type); -extern const char *sdp_get_curr_type_name(sdp_curr_type_e curr_type); -extern const char *sdp_get_des_type_name(sdp_des_type_e des_type); -extern const char *sdp_get_conf_type_name(sdp_conf_type_e conf_type); -extern const char *sdp_get_mediadir_role_name (sdp_mediadir_role_e role); -extern const char *sdp_get_silencesupp_pref_name(sdp_silencesupp_pref_e pref); -extern const char *sdp_get_silencesupp_siduse_name(sdp_silencesupp_siduse_e - siduse); - -extern const char *sdp_get_bw_modifier_name(sdp_bw_modifier_e bw_modifier); -extern const char *sdp_get_group_attr_name(sdp_group_attr_e group_attr); -extern const char *sdp_get_src_filter_mode_name(sdp_src_filter_mode_e type); -extern const char *sdp_get_rtcp_unicast_mode_name(sdp_rtcp_unicast_mode_e type); - -extern tinybool sdp_verify_sdp_ptr(sdp_t *sdp_p); - - -/* sdp_tokens.c */ -extern sdp_result_e sdp_parse_version(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_version(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_owner(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_owner(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_sessname(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_sessname(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_sessinfo(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_sessinfo(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_uri(sdp_t *sdp_p, u16 token, const char *ptr); -extern sdp_result_e sdp_build_uri(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_email(sdp_t *sdp_p, u16 token, const char *ptr); -extern sdp_result_e sdp_build_email(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_phonenum(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_phonenum(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_connection(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_connection(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_bandwidth(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_bandwidth(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_timespec(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_timespec(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_repeat_time(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_repeat_time(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_timezone_adj(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_timezone_adj(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_encryption(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_encryption(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_media(sdp_t *sdp_p, u16 token, const char *ptr); -extern sdp_result_e sdp_build_media(sdp_t *sdp_p, u16 token, flex_string *fs); -extern sdp_result_e sdp_parse_attribute(sdp_t *sdp_p, u16 token, - const char *ptr); -extern sdp_result_e sdp_build_attribute(sdp_t *sdp_p, u16 token, flex_string *fs); - -extern void sdp_parse_payload_types(sdp_t *sdp_p, sdp_mca_t *mca_p, - const char *ptr); -extern sdp_result_e sdp_parse_multiple_profile_payload_types(sdp_t *sdp_p, - sdp_mca_t *mca_p, - const char *ptr); -extern sdp_result_e -sdp_parse_attr_sdescriptions(sdp_t *sdp_p, sdp_attr_t *attr_p, - const char *ptr); - -extern sdp_result_e -sdp_build_attr_sdescriptions(sdp_t *sdp_p, sdp_attr_t *attr_p, - flex_string *fs); - - -/* sdp_utils.c */ -extern sdp_mca_t *sdp_alloc_mca(void); -extern tinybool sdp_validate_maxprate(const char *string_parm); -extern char *sdp_findchar(const char *ptr, char *char_list); -extern const char *sdp_getnextstrtok(const char *str, char *tokenstr, unsigned tokenstr_len, - const char *delim, sdp_result_e *result); -extern u32 sdp_getnextnumtok(const char *str, const char **str_end, - const char *delim, sdp_result_e *result); -extern u32 sdp_getnextnumtok_or_null(const char *str, const char **str_end, - const char *delim, tinybool *null_ind, - sdp_result_e *result); -extern tinybool sdp_getchoosetok(const char *str, const char **str_end, - const char *delim, sdp_result_e *result); - -extern -tinybool verify_sdescriptions_mki(char *buf, char *mkiVal, u16 *mkiLen); - -extern -tinybool verify_sdescriptions_lifetime(char *buf); - -/* sdp_services_xxx.c */ -extern void sdp_dump_buffer(char *_ptr, int _size_bytes); - -tinybool sdp_checkrange(sdp_t *sdp, char *num, ulong* lval); - -#endif /* _SDP_PRIVATE_H_ */ diff --git a/libs/sipcc/core/sdp/sdp_services_unix.c b/libs/sipcc/core/sdp/sdp_services_unix.c deleted file mode 100755 index 79787eb2b5..0000000000 --- a/libs/sipcc/core/sdp/sdp_services_unix.c +++ /dev/null @@ -1,63 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "sdp_os_defs.h" -#include "sdp.h" -#include "sdp_private.h" - - -/******************************************************************/ -/* Required Platform Routines */ -/* */ -/* These routines are called from the common SDP code. */ -/* They must be provided for each platform. */ -/* */ -/******************************************************************/ - -#if 0 -void sdp_log_errmsg (sdp_errmsg_e errmsg, char *str) -{ - switch (errmsg) { - - case SDP_ERR_INVALID_CONF_PTR: - SDP_ERROR("\nSDP: Invalid Config pointer (%s).", str); - break; - - case SDP_ERR_INVALID_SDP_PTR: - SDP_ERROR("\nSDP: Invalid SDP pointer (%s).", str); - break; - - case SDP_ERR_INTERNAL: - SDP_ERROR("\nSDP: Internal error (%s).", str); - break; - - default: - break; - } -} -#endif - -/* - * sdp_dump_buffer - * - * Utility to send _size_bytes of data from the string - * pointed to by _ptr to the buginf function. This may make - * multiple buginf calls if the buffer is too large for buginf. - */ -void sdp_dump_buffer (char * _ptr, int _size_bytes) -{ - buginf_msg(_ptr); -} - -/******************************************************************/ -/* */ -/* Platform Specific Routines */ -/* */ -/* These routines are only used in this particular platform. */ -/* They are called from the required platform specific */ -/* routines provided below, not from the common SDP code. */ -/* */ -/******************************************************************/ - -/* There are currently no platform specific routines required. */ diff --git a/libs/sipcc/core/sdp/sdp_services_win32.c b/libs/sipcc/core/sdp/sdp_services_win32.c deleted file mode 100755 index 79787eb2b5..0000000000 --- a/libs/sipcc/core/sdp/sdp_services_win32.c +++ /dev/null @@ -1,63 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "sdp_os_defs.h" -#include "sdp.h" -#include "sdp_private.h" - - -/******************************************************************/ -/* Required Platform Routines */ -/* */ -/* These routines are called from the common SDP code. */ -/* They must be provided for each platform. */ -/* */ -/******************************************************************/ - -#if 0 -void sdp_log_errmsg (sdp_errmsg_e errmsg, char *str) -{ - switch (errmsg) { - - case SDP_ERR_INVALID_CONF_PTR: - SDP_ERROR("\nSDP: Invalid Config pointer (%s).", str); - break; - - case SDP_ERR_INVALID_SDP_PTR: - SDP_ERROR("\nSDP: Invalid SDP pointer (%s).", str); - break; - - case SDP_ERR_INTERNAL: - SDP_ERROR("\nSDP: Internal error (%s).", str); - break; - - default: - break; - } -} -#endif - -/* - * sdp_dump_buffer - * - * Utility to send _size_bytes of data from the string - * pointed to by _ptr to the buginf function. This may make - * multiple buginf calls if the buffer is too large for buginf. - */ -void sdp_dump_buffer (char * _ptr, int _size_bytes) -{ - buginf_msg(_ptr); -} - -/******************************************************************/ -/* */ -/* Platform Specific Routines */ -/* */ -/* These routines are only used in this particular platform. */ -/* They are called from the required platform specific */ -/* routines provided below, not from the common SDP code. */ -/* */ -/******************************************************************/ - -/* There are currently no platform specific routines required. */ diff --git a/libs/sipcc/core/sdp/sdp_token.c b/libs/sipcc/core/sdp/sdp_token.c deleted file mode 100644 index 89e3df66df..0000000000 --- a/libs/sipcc/core/sdp/sdp_token.c +++ /dev/null @@ -1,1763 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "sdp_os_defs.h" -#include "sdp.h" -#include "sdp_private.h" -#include "configmgr.h" -#include "prot_configmgr.h" -#include "ccapi.h" -#include "CSFLog.h" - -//static const char *logTag = "sdp_token"; - -#define MCAST_STRING_LEN 4 - - -sdp_result_e sdp_parse_version (sdp_t *sdp_p, u16 level, const char *ptr) -{ - sdp_result_e result = SDP_FAILURE; - - sdp_p->version = (u16)sdp_getnextnumtok(ptr, &ptr, " \t", &result); - if ((result != SDP_SUCCESS) || (sdp_p->version != SDP_CURRENT_VERSION)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Invalid version (%lu) found, parse failed.", - sdp_p->debug_str, sdp_p->version); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse version line successful, version %u", - sdp_p->debug_str, (u16)sdp_p->version); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_version (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - if (sdp_p->version == SDP_INVALID_VALUE) { - if (sdp_p->conf_p->version_reqd == TRUE) { - CSFLogError(logTag, "%s Invalid version for v= line, " - "build failed.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - /* v= line is not required. */ - return (SDP_SUCCESS); - } - } - - flex_string_sprintf(fs, "v=%u\r\n", (u16)sdp_p->version); - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built v= version line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_owner (sdp_t *sdp_p, u16 level, const char *ptr) -{ - int i; - char *tmpptr; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - - if (sdp_p->owner_name[0] != '\0') { - sdp_p->conf_p->num_invalid_token_order++; - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: More than one o= line specified.", - sdp_p->debug_str); - } - - /* Find the owner name. */ - ptr = sdp_getnextstrtok(ptr, sdp_p->owner_name, sizeof(sdp_p->owner_name), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No owner name specified for o=.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the owner session id. This is a numeric field but is - * stored as a string since it may be 64 bit. - */ - ptr = sdp_getnextstrtok(ptr, sdp_p->owner_sessid, sizeof(sdp_p->owner_sessid), " \t", &result); - if (result == SDP_SUCCESS) { - /* Make sure the sessid is numeric, even though we store it as - * a string. - */ - (void)sdp_getnextnumtok(sdp_p->owner_sessid, - (const char **)&tmpptr, " \t",&result); - } - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Invalid owner session id specified for o=.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the owner version. */ - ptr = sdp_getnextstrtok(ptr, sdp_p->owner_version, sizeof(sdp_p->owner_version), " \t", &result); - if (result == SDP_SUCCESS) { - /* Make sure the version is numeric, even though we store it as - * a string. - */ - (void)sdp_getnextnumtok(sdp_p->owner_version, - (const char **)&tmpptr," \t",&result); - } - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Invalid owner version specified for o=.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the owner network type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No owner network type specified for o=.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - sdp_p->owner_network_type = SDP_NT_UNSUPPORTED; - for (i=0; i < SDP_MAX_NETWORK_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_nettype[i].name, - sdp_nettype[i].strlen) == 0) { - if (sdp_p->conf_p->nettype_supported[i] == TRUE) { - sdp_p->owner_network_type = (sdp_nettype_e)i; - } - } - } - if (sdp_p->owner_network_type == SDP_NT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Owner network type unsupported (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the owner address type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No owner address type specified for o=.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - sdp_p->owner_addr_type = SDP_AT_UNSUPPORTED; - for (i=0; i < SDP_MAX_ADDR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_addrtype[i].name, - sdp_addrtype[i].strlen) == 0) { - if (sdp_p->conf_p->addrtype_supported[i] == TRUE) { - sdp_p->owner_addr_type = (sdp_addrtype_e)i; - } - } - } - if ((sdp_p->owner_addr_type == SDP_AT_UNSUPPORTED) && - (sdp_p->owner_network_type != SDP_NT_ATM)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Owner address type unsupported (%s)", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the owner address. */ - ptr = sdp_getnextstrtok(ptr, sdp_p->owner_addr, sizeof(sdp_p->owner_addr), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No owner address specified.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse owner: name %s, session id %s, version %s", - sdp_p->debug_str, sdp_p->owner_name, sdp_p->owner_sessid, - sdp_p->owner_version); - SDP_PRINT("%s network %s, address type %s, " - "address %s", sdp_p->debug_str, - sdp_get_network_name(sdp_p->owner_network_type), - sdp_get_address_name(sdp_p->owner_addr_type), - sdp_p->owner_addr); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_owner (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - if ((sdp_p->owner_name[0] == '\0') || - (sdp_p->owner_network_type >= SDP_MAX_NETWORK_TYPES) || - (sdp_p->owner_addr_type >= SDP_MAX_ADDR_TYPES) || - (sdp_p->owner_addr[0] == '\0')) { - - if((sdp_p->owner_network_type == SDP_NT_ATM) && - (sdp_p->owner_addr_type == SDP_AT_INVALID)) { - flex_string_sprintf(fs, "o=%s %s %s %s - -\r\n", - sdp_p->owner_name, sdp_p->owner_sessid, - sdp_p->owner_version, - sdp_get_network_name(sdp_p->owner_network_type)); - } - - if (sdp_p->conf_p->owner_reqd == TRUE) { - CSFLogError(logTag, "%s Invalid params for o= owner line, " - "build failed.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - /* o= line is not required. */ - return (SDP_SUCCESS); - } - } - - flex_string_sprintf(fs, "o=%s %s %s %s %s %s\r\n", - sdp_p->owner_name, sdp_p->owner_sessid, - sdp_p->owner_version, - sdp_get_network_name(sdp_p->owner_network_type), - sdp_get_address_name(sdp_p->owner_addr_type), - sdp_p->owner_addr); - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built o= owner line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_sessname (sdp_t *sdp_p, u16 level, const char *ptr) -{ - int str_len; - char *endptr; - - if (sdp_p->sessname[0] != '\0') { - sdp_p->conf_p->num_invalid_token_order++; - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: More than one s= line specified.", - sdp_p->debug_str); - } - - endptr = sdp_findchar(ptr, "\r\n"); - if (ptr == endptr) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No session name specified.", - sdp_p->debug_str); - } - str_len = MIN(endptr - ptr, SDP_MAX_STRING_LEN); - sstrncpy(sdp_p->sessname, ptr, str_len+1); - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse session name, %s", - sdp_p->debug_str, sdp_p->sessname); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_sessname (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - if (sdp_p->sessname[0] == '\0') { - if (sdp_p->conf_p->session_name_reqd == TRUE) { - CSFLogError(logTag, "%s No param defined for s= session name line, " - "build failed.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - /* s= line is not required. */ - return (SDP_SUCCESS); - } - } - - flex_string_sprintf(fs, "s=%s\r\n", sdp_p->sessname); - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built s= session name line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -/* We don't want to store the session info, but we do want to validate - * that at most one i= line exists at each level and if the line exists - * there should be a parameter. - */ -sdp_result_e sdp_parse_sessinfo (sdp_t *sdp_p, u16 level, const char *ptr) -{ - char *endptr; - sdp_mca_t *mca_p; - - if (level == SDP_SESSION_LEVEL) { - if (sdp_p->sessinfo_found == TRUE) { - sdp_p->conf_p->num_invalid_token_order++; - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: More than one i= line specified.", - sdp_p->debug_str); - } - sdp_p->sessinfo_found = TRUE; - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - if (mca_p->sessinfo_found == TRUE) { - sdp_p->conf_p->num_invalid_token_order++; - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: More than one i= line specified" - " for media line %d.", sdp_p->debug_str, level); - } - mca_p->sessinfo_found = TRUE; - } - - endptr = sdp_findchar(ptr, "\n"); - if (ptr == endptr) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No session info specified.", - sdp_p->debug_str); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed session info line.", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_sessinfo (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - /* Build session info line not supported. */ - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_uri (sdp_t *sdp_p, u16 level, const char *ptr) -{ - char *endptr; - - if (sdp_p->uri_found == TRUE) { - sdp_p->conf_p->num_invalid_token_order++; - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: More than one u= line specified.", - sdp_p->debug_str); - } - sdp_p->uri_found = TRUE; - - endptr = sdp_findchar(ptr, "\n"); - if (ptr == endptr) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No URI info specified.", sdp_p->debug_str); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed URI line.", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_uri (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - /* Build URI line not supported. */ - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_email (sdp_t *sdp_p, u16 level, const char *ptr) -{ - char *endptr; - - endptr = sdp_findchar(ptr, "\n"); - if (ptr == endptr) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No email info specified.", sdp_p->debug_str); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse email line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_email (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - /* Build email line not supported. */ - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_phonenum (sdp_t *sdp_p, u16 level, const char *ptr) -{ - char *endptr; - - endptr = sdp_findchar(ptr, "\n"); - if (ptr == endptr) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No phone number info specified.", - sdp_p->debug_str); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse phone number line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_phonenum (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - /* Build phone number line not supported. */ - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_connection (sdp_t *sdp_p, u16 level, const char *ptr) -{ - int i; - const char *slash_ptr; - sdp_result_e result; - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - char tmp[SDP_MAX_STRING_LEN]; - char mcast_str[MCAST_STRING_LEN]; - int mcast_bits; - unsigned long strtoul_result; - char *strtoul_end; - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - conn_p = &(mca_p->conn); - } - - /* See if the c= line is already defined at this level. We don't - * currently support multihoming and so we only support one c= at - * each level. - */ - if (conn_p->nettype != SDP_NT_INVALID) { - sdp_p->conf_p->num_invalid_token_order++; - sdp_parse_error(sdp_p->peerconnection, - "%s c= line specified twice at same level, " - "parse failed.", sdp_p->debug_str); - return (SDP_INVALID_TOKEN_ORDERING); - } - - /* Find the connection network type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No connection network type specified for c=.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - conn_p->nettype = SDP_NT_UNSUPPORTED; - for (i=0; i < SDP_MAX_NETWORK_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_nettype[i].name, - sdp_nettype[i].strlen) == 0) { - if (sdp_p->conf_p->nettype_supported[i] == TRUE) { - conn_p->nettype = (sdp_nettype_e)i; - } - } - } - if (conn_p->nettype == SDP_NT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Connection network type unsupported " - "(%s) for c=.", sdp_p->debug_str, tmp); - } - - /* Find the connection address type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - if (conn_p->nettype == SDP_NT_ATM) { - /* If the nettype is ATM, addr type and addr are not reqd */ - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse connection: network %s", sdp_p->debug_str, - sdp_get_network_name(conn_p->nettype)); - } - return (SDP_SUCCESS); - } else { - sdp_parse_error(sdp_p->peerconnection, - "%s No connection address type specified for " - "c=.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - } - conn_p->addrtype = SDP_AT_UNSUPPORTED; - for (i=0; i < SDP_MAX_ADDR_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_addrtype[i].name, - sdp_addrtype[i].strlen) == 0) { - if (sdp_p->conf_p->addrtype_supported[i] == TRUE) { - conn_p->addrtype = (sdp_addrtype_e)i; - } - } - } - if (conn_p->addrtype == SDP_AT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Connection address type unsupported " - "(%s) for c=.", sdp_p->debug_str, tmp); - } - - /* Find the connection address. */ - ptr = sdp_getnextstrtok(ptr, conn_p->conn_addr, sizeof(conn_p->conn_addr), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No connection address specified for c=.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - /* We currently only support addrs containing '/'s for EPN addrs. - * For other addrs this would indicate multicast addrs. */ - /* Multicast host group addresses are defined to be the IP addresses - * whose high-order four bits are 1110, giving an address range from - * 224.0.0.0 through 239.255.255.255 - */ - /* multicast addr check */ - sstrncpy (mcast_str, conn_p->conn_addr, MCAST_STRING_LEN); - - errno = 0; - strtoul_result = strtoul(mcast_str, &strtoul_end, 10); - - if (errno || mcast_str == strtoul_end || strtoul_result > 255) { - sdp_parse_error(sdp_p->peerconnection, - "%s Error parsing address %s for mcast.", - sdp_p->debug_str, mcast_str); - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - - - mcast_bits = (int) strtoul_result; - if ((mcast_bits >= SDP_MIN_MCAST_ADDR_HI_BIT_VAL ) && - (mcast_bits <= SDP_MAX_MCAST_ADDR_HI_BIT_VAL)) { - SDP_PRINT("%s Parsed to be a multicast address with mcast bits %d", - sdp_p->debug_str, mcast_bits); - conn_p->is_multicast = TRUE; - } - - if (conn_p->addrtype != SDP_AT_EPN) { - slash_ptr = sdp_findchar(conn_p->conn_addr, "/"); - if (slash_ptr[0] != '\0') { - if (conn_p->is_multicast) { - SDP_PRINT("%s A multicast address with slash %s", - sdp_p->debug_str, conn_p->conn_addr); - slash_ptr++; - slash_ptr = sdp_getnextstrtok(slash_ptr, tmp, sizeof(tmp), "/", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No ttl value specified for this multicast addr with a slash", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - errno = 0; - strtoul_result = strtoul(tmp, &strtoul_end, 10); - - if (errno || tmp == strtoul_end || conn_p->ttl > SDP_MAX_TTL_VALUE) { - sdp_parse_error(sdp_p->peerconnection, - "%s Invalid TTL: Value must be in the range 0-255 ", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - conn_p->ttl = (int) strtoul_result; - - /* search for num of addresses */ - /*sa_ignore NO_NULL_CHK - {ptr is valid since the pointer was checked earlier and the - function would have exited if NULL.}*/ - slash_ptr = sdp_findchar(slash_ptr, "/"); - if (slash_ptr != NULL && - slash_ptr[0] != '\0') { - SDP_PRINT("%s Found a num addr field for multicast addr %s ", - sdp_p->debug_str,slash_ptr); - slash_ptr++; - - errno = 0; - strtoul_result = strtoul(slash_ptr, &strtoul_end, 10); - - if (errno || slash_ptr == strtoul_end || strtoul_result == 0) { - sdp_parse_error(sdp_p->peerconnection, - "%s Invalid Num of addresses: Value must be > 0 ", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return SDP_INVALID_PARAMETER; - } - - conn_p->num_of_addresses = (int) strtoul_result; - } - } else { - sdp_p->conf_p->num_invalid_param++; - SDP_PRINT("%s Only multicast addresses allowed with slashes", - sdp_p->debug_str); - return (SDP_INVALID_PARAMETER); - } - } - } - - /* See if the address is the choose param and if it's allowed. */ - if ((sdp_p->conf_p->allow_choose[SDP_CHOOSE_CONN_ADDR] == FALSE) && - (strcmp(conn_p->conn_addr, "$") == 0)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Choose parameter for connection " - "address specified but not allowed.", sdp_p->debug_str); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse connection: network %s, address type %s, " - "address %s ttl= %d num of addresses = %d", - sdp_p->debug_str, - sdp_get_network_name(conn_p->nettype), - sdp_get_address_name(conn_p->addrtype), - conn_p->conn_addr, conn_p->ttl, conn_p->num_of_addresses); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_connection (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - sdp_mca_t *mca_p; - sdp_conn_t *conn_p; - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - conn_p = &(mca_p->conn); - } - - if((conn_p->nettype == SDP_NT_ATM ) && - (conn_p->addrtype == SDP_AT_INVALID)) { - /*allow c= line to be built without address type and address fields - * This is a special case for ATM PVC*/ - flex_string_sprintf(fs, "c=%s\r\n", - sdp_get_network_name(conn_p->nettype)); - return SDP_SUCCESS; - } - if ((conn_p->nettype >= SDP_MAX_NETWORK_TYPES) || - (conn_p->addrtype >= SDP_MAX_ADDR_TYPES) || - (conn_p->conn_addr[0] == '\0')) { - /* Connection info isn't set - don't need to build the token. */ - return (SDP_SUCCESS); - } - - if (conn_p->is_multicast) { - if (conn_p->num_of_addresses > 1) { - flex_string_sprintf(fs, "c=%s %s %s/%d/%d\r\n", - sdp_get_network_name(conn_p->nettype), - sdp_get_address_name(conn_p->addrtype), - conn_p->conn_addr, conn_p->ttl, - conn_p->num_of_addresses); - } else { - flex_string_sprintf(fs, "c=%s %s %s/%d\r\n", - sdp_get_network_name(conn_p->nettype), - sdp_get_address_name(conn_p->addrtype), - conn_p->conn_addr, conn_p->ttl); - } - } else { - - flex_string_sprintf(fs, "c=%s %s %s\r\n", - sdp_get_network_name(conn_p->nettype), - sdp_get_address_name(conn_p->addrtype), - conn_p->conn_addr); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built c= connection line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -/* - * sdp_parse_bandwidth - * - * This function parses a bandwidth field. The parsing is done in accordance - * to the following ABNF: - * - * bandwidth-fields = *("b=" bwtype ":" bandwidth CRLF) - * bwtype = 1*(alpha-numeric) - * bandwidth = 1*(DIGIT) - * - * It currently supports three types of valid bwtypes - AS, CT and TIAS - */ -sdp_result_e sdp_parse_bandwidth (sdp_t *sdp_p, u16 level, const char *ptr) -{ - int i; - sdp_mca_t *mca_p; - sdp_bw_t *bw_p; - sdp_bw_data_t *bw_data_p; - sdp_bw_data_t *new_bw_data_p; - sdp_result_e result; - char tmp[SDP_MAX_STRING_LEN]; - sdp_bw_modifier_e bw_modifier = SDP_BW_MODIFIER_UNSUPPORTED; - int bw_val = 0; - - if (level == SDP_SESSION_LEVEL) { - bw_p = &(sdp_p->bw); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - bw_p = &(mca_p->bw); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse bandwidth line", sdp_p->debug_str); - } - - /* Find the bw type (AS, CT or TIAS) */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), ":", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No bandwidth type specified for b= ", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - for (i=0; i < SDP_MAX_BW_MODIFIER_VAL; i++) { - if (cpr_strncasecmp(tmp, sdp_bw_modifier_val[i].name, - sdp_bw_modifier_val[i].strlen) == 0) { - bw_modifier = (sdp_bw_modifier_e)i; - break; - } - } - - if (bw_modifier == SDP_BW_MODIFIER_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Error: BW Modifier type unsupported (%s).", - sdp_p->debug_str, tmp); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Find the BW type value */ - /*sa_ignore NO_NULL_CHK - {ptr is valid since the pointer was checked earlier and the - function would have exited if NULL.}*/ - if (*ptr == ':') { - ptr++; - bw_val = sdp_getnextnumtok(ptr, &ptr, " \t", &result); - if ((result != SDP_SUCCESS)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Error: No BW Value specified ", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - } - - /* - * Allocate a new sdp_bw_data_t instance and set it's values from the - * input parameters. - */ - new_bw_data_p = (sdp_bw_data_t*)SDP_MALLOC(sizeof(sdp_bw_data_t)); - if (new_bw_data_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_NO_RESOURCE); - } - new_bw_data_p->next_p = NULL; - new_bw_data_p->bw_modifier = bw_modifier; - new_bw_data_p->bw_val = bw_val; - - /* - * Enqueue the sdp_bw_data_t instance at the end of the list of - * sdp_bw_data_t instances. - */ - if (bw_p->bw_data_list == NULL) { - bw_p->bw_data_list = new_bw_data_p; - } else { - for (bw_data_p = bw_p->bw_data_list; - bw_data_p->next_p != NULL; - bw_data_p = bw_data_p->next_p) { - ; // Empty For - } - bw_data_p->next_p = new_bw_data_p; - } - bw_p->bw_data_count++; - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed bw type %s, value %d", sdp_p->debug_str, - sdp_get_bw_modifier_name(new_bw_data_p->bw_modifier), - new_bw_data_p->bw_val); - } - - return (SDP_SUCCESS); -} - -/* - * sdp_build_bandwidth - * - * Builds *all* the bandwith lines for the specified level. - */ -sdp_result_e sdp_build_bandwidth (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - sdp_bw_t *bw_p; - sdp_bw_data_t *bw_data_p; - sdp_mca_t *mca_p; - - if (level == SDP_SESSION_LEVEL) { - bw_p = &(sdp_p->bw); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - bw_p = &(mca_p->bw); - } - - bw_data_p = bw_p->bw_data_list; - while (bw_data_p) { - flex_string_sprintf(fs, "b=%s:%d\r\n", - sdp_get_bw_modifier_name(bw_data_p->bw_modifier), - bw_data_p->bw_val); - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built b=%s:%d bandwidth line", sdp_p->debug_str, - sdp_get_bw_modifier_name(bw_data_p->bw_modifier), - bw_data_p->bw_val); - } - - bw_data_p = bw_data_p->next_p; - } - - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_timespec (sdp_t *sdp_p, u16 level, const char *ptr) -{ - char *tmpptr; - sdp_result_e result; - sdp_timespec_t *timespec_p; - sdp_timespec_t *next_timespec_p; - - timespec_p = (sdp_timespec_t *)SDP_MALLOC(sizeof(sdp_timespec_t)); - if (timespec_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - - /* Validate start and stop times. */ - ptr = sdp_getnextstrtok(ptr, timespec_p->start_time, sizeof(timespec_p->start_time), " \t", &result); - if (result == SDP_SUCCESS) { - /* Make sure the start_time is numeric, even though we store it as - * a string. - */ - (void)sdp_getnextnumtok(timespec_p->start_time, - (const char **)&tmpptr, " \t", &result); - } - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Invalid timespec start time specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - SDP_FREE(timespec_p); - return (SDP_INVALID_PARAMETER); - } - - ptr = sdp_getnextstrtok(ptr, timespec_p->stop_time, sizeof(timespec_p->stop_time), " \t", &result); - if (result == SDP_SUCCESS) { - /* Make sure the start_time is numeric, even though we store it as - * a string. - */ - (void)sdp_getnextnumtok(timespec_p->stop_time, - (const char **)&tmpptr, " \t", &result); - } - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s Invalid timespec stop time specified.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - SDP_FREE(timespec_p); - return (SDP_INVALID_PARAMETER); - } - - /* Link the new timespec in to the end of the list. */ - if (sdp_p->timespec_p == NULL) { - sdp_p->timespec_p = timespec_p; - } else { - next_timespec_p = sdp_p->timespec_p; - while (next_timespec_p->next_p != NULL) { - next_timespec_p = next_timespec_p->next_p; - } - next_timespec_p->next_p = timespec_p; - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed timespec line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_timespec (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - if ((sdp_p->timespec_p == NULL) || - (sdp_p->timespec_p->start_time == '\0') || - (sdp_p->timespec_p->stop_time == '\0')) { - if (sdp_p->conf_p->timespec_reqd == TRUE) { - CSFLogError(logTag, "%s Invalid params for t= time spec line, " - "build failed.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - /* t= line not required. */ - return (SDP_SUCCESS); - } - } - - /* Note: We only support one t= line currently. */ - flex_string_sprintf(fs, "t=%s %s\r\n", sdp_p->timespec_p->start_time, - sdp_p->timespec_p->stop_time); - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built t= timespec line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_repeat_time (sdp_t *sdp_p, u16 level, const char *ptr) -{ - char *endptr; - - endptr = sdp_findchar(ptr, "\n"); - if (ptr == endptr) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No repeat time parameters " - "specified.", sdp_p->debug_str); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parsed repeat time line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_repeat_time (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - /* Build repeat time line not supported. */ - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_timezone_adj (sdp_t *sdp_p, u16 level, const char *ptr) -{ - char *endptr; - - endptr = sdp_findchar(ptr, "\n"); - if (ptr == endptr) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No timezone parameters specified.", - sdp_p->debug_str); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse timezone adustment line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_timezone_adj (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - /* Build timezone adjustment line not supported. */ - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_encryption (sdp_t *sdp_p, u16 level, const char *ptr) -{ - int i; - sdp_result_e result; - sdp_encryptspec_t *encrypt_p; - sdp_mca_t *mca_p; - char tmp[SDP_MAX_STRING_LEN]; - - if (level == SDP_SESSION_LEVEL) { - encrypt_p = &(sdp_p->encrypt); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - encrypt_p = &(mca_p->encrypt); - } - encrypt_p->encrypt_key[0] = '\0'; - - /* Find the encryption type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), ":", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No encryption type specified for k=.", - sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - encrypt_p->encrypt_type = SDP_ENCRYPT_UNSUPPORTED; - for (i=0; i < SDP_MAX_ENCRYPT_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_encrypt[i].name, - sdp_encrypt[i].strlen) == 0) { - encrypt_p->encrypt_type = (sdp_encrypt_type_e)i; - break; - } - } - if (encrypt_p->encrypt_type == SDP_ENCRYPT_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Encryption type unsupported (%s).", - sdp_p->debug_str, tmp); - } - - /* Find the encryption key. */ - encrypt_p->encrypt_key[0] = '\0'; - /*sa_ignore NO_NULL_CHK - {ptr is valid since the pointer was checked earlier and the - function would have exited if NULL.}*/ - if (*ptr == ':') - ptr++; - if (encrypt_p->encrypt_type != SDP_ENCRYPT_PROMPT) { - ptr = sdp_getnextstrtok(ptr, encrypt_p->encrypt_key, sizeof(encrypt_p->encrypt_key), " \t", &result); - if ((result != SDP_SUCCESS) && - ((encrypt_p->encrypt_type == SDP_ENCRYPT_CLEAR) || - (encrypt_p->encrypt_type == SDP_ENCRYPT_BASE64) || - (encrypt_p->encrypt_type == SDP_ENCRYPT_URI))) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No encryption key specified " - "as required.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Parse encryption type %s, key %s", sdp_p->debug_str, - sdp_get_encrypt_name(encrypt_p->encrypt_type), - encrypt_p->encrypt_key); - } - return (SDP_SUCCESS); -} - -/* If the encryption info is valid, we build it. Else skip it. */ -sdp_result_e sdp_build_encryption (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - sdp_encryptspec_t *encrypt_p; - sdp_mca_t *mca_p; - - if (level == SDP_SESSION_LEVEL) { - encrypt_p = &(sdp_p->encrypt); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - encrypt_p = &(mca_p->encrypt); - } - - if ((encrypt_p->encrypt_type >= SDP_MAX_ENCRYPT_TYPES) || - ((encrypt_p->encrypt_type != SDP_ENCRYPT_PROMPT) && - (encrypt_p->encrypt_key[0] == '\0'))) { - /* Encryption info isn't set - don't need to build the token. */ - return (SDP_SUCCESS); - } - - flex_string_sprintf(fs, "k=%s", - sdp_get_encrypt_name(encrypt_p->encrypt_type)); - - if (encrypt_p->encrypt_type == SDP_ENCRYPT_PROMPT) { - /* There is no key to print. */ - flex_string_sprintf(fs, "\r\n"); - } else { - flex_string_sprintf(fs, ":%s\r\n", encrypt_p->encrypt_key); - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built k= encryption line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_parse_media (sdp_t *sdp_p, u16 level, const char *ptr) -{ - u16 i; - u16 num_port_params=0; - int32 num[SDP_MAX_PORT_PARAMS]; - tinybool valid_param = FALSE; - sdp_result_e result; - sdp_mca_t *mca_p; - sdp_mca_t *next_mca_p; - char tmp[SDP_MAX_STRING_LEN]; - char port[SDP_MAX_STRING_LEN]; - const char *port_ptr; - int32 sctp_port; - - /* Allocate resource for new media stream. */ - mca_p = sdp_alloc_mca(); - if (mca_p == NULL) { - sdp_p->conf_p->num_no_resource++; - return (SDP_NO_RESOURCE); - } - - /* Find the media type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No media type specified, parse failed.", - sdp_p->debug_str); - SDP_FREE(mca_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - mca_p->media = SDP_MEDIA_UNSUPPORTED; - for (i=0; i < SDP_MAX_MEDIA_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_media[i].name, - sdp_media[i].strlen) == 0) { - mca_p->media = (sdp_media_e)i; - } - } - if (mca_p->media == SDP_MEDIA_UNSUPPORTED) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Media type unsupported (%s).", - sdp_p->debug_str, tmp); - } - - /* Find the port token parameters, but don't process it until - * we determine the transport protocol as that determines what - * port number formats are valid. - */ - ptr = sdp_getnextstrtok(ptr, port, sizeof(port), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No port specified in m= media line, " - "parse failed.", sdp_p->debug_str); - SDP_FREE(mca_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - port_ptr = port; - for (i=0; i < SDP_MAX_PORT_PARAMS; i++) { - if (sdp_getchoosetok(port_ptr, &port_ptr, "/ \t", &result) == TRUE) { - num[i] = SDP_CHOOSE_PARAM; - } else { - num[i] = sdp_getnextnumtok(port_ptr, (const char **)&port_ptr, - "/ \t", &result); - if (result != SDP_SUCCESS) { - break; - } - } - num_port_params++; - } - - /* Find the transport protocol type. */ - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No transport protocol type specified, " - "parse failed.", sdp_p->debug_str); - SDP_FREE(mca_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - mca_p->transport = SDP_TRANSPORT_UNSUPPORTED; - for (i=0; i < SDP_MAX_TRANSPORT_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_transport[i].name, - sdp_transport[i].strlen) == 0) { - mca_p->transport = (sdp_transport_e)i; - break; - } - } - if (mca_p->transport == SDP_TRANSPORT_UNSUPPORTED) { - /* If we don't recognize or don't support the transport type, - * just store the first num as the port. - */ - mca_p->port = num[0]; - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Transport protocol type unsupported " - "(%s).", sdp_p->debug_str, tmp); - } - - /* Check for each of the possible port formats according to the - * type of transport protocol specified. - */ - valid_param = FALSE; - switch (num_port_params) { - case 1: - if ((mca_p->transport == SDP_TRANSPORT_RTPAVP) || - (mca_p->transport == SDP_TRANSPORT_RTPSAVP) || - (mca_p->transport == SDP_TRANSPORT_RTPSAVPF) || - (mca_p->transport == SDP_TRANSPORT_UDP) || - (mca_p->transport == SDP_TRANSPORT_TCP) || - (mca_p->transport == SDP_TRANSPORT_UDPTL) || - (mca_p->transport == SDP_TRANSPORT_UDPSPRT) || - (mca_p->transport == SDP_TRANSPORT_LOCAL) || - (mca_p->transport == SDP_TRANSPORT_SCTPDTLS)) { - /* Port format is simply . Make sure that either - * the choose param is allowed or that the choose value - * wasn't specified. - */ - if ((sdp_p->conf_p->allow_choose[SDP_CHOOSE_PORTNUM]) || - (num[0] != SDP_CHOOSE_PARAM)) { - mca_p->port = num[0]; - mca_p->port_format = SDP_PORT_NUM_ONLY; - valid_param = TRUE; - } - } else if (mca_p->transport == SDP_TRANSPORT_AAL1AVP) { - /* Port format is simply , choose param is not allowed. - */ - if (num[0] != SDP_CHOOSE_PARAM) { - mca_p->vcci = num[0]; - mca_p->port_format = SDP_PORT_VCCI; - valid_param = TRUE; - } - } else if ((mca_p->transport == SDP_TRANSPORT_AAL2_ITU) || - (mca_p->transport == SDP_TRANSPORT_AAL2_ATMF) || - (mca_p->transport == SDP_TRANSPORT_AAL2_CUSTOM)) { - /* Port format is simply , and choose param is allowed, - * according to AAL2 definitions. - */ - mca_p->port = num[0]; - mca_p->port_format = SDP_PORT_NUM_ONLY; - valid_param = TRUE; - } - break; - case 2: - if ((mca_p->transport == SDP_TRANSPORT_RTPAVP) || - (mca_p->transport == SDP_TRANSPORT_RTPSAVP) || - (mca_p->transport == SDP_TRANSPORT_RTPSAVPF) || - (mca_p->transport == SDP_TRANSPORT_UDP) || - (mca_p->transport == SDP_TRANSPORT_LOCAL)) { - /* Port format is /. Make sure choose - * params were not specified. - */ - if ((num[0] != SDP_CHOOSE_PARAM) && - (num[1] != SDP_CHOOSE_PARAM)) { - mca_p->port = num[0]; - mca_p->num_ports = num[1]; - mca_p->port_format = SDP_PORT_NUM_COUNT; - valid_param = TRUE; - } - } else if (mca_p->transport == SDP_TRANSPORT_UDPTL) { - /* Port format is /. Make sure choose - * params were not specified. For UDPTL, only "1" may - * be specified for number of ports. - */ - if ((num[0] != SDP_CHOOSE_PARAM) && - (num[1] == 1)) { - mca_p->port = num[0]; - mca_p->num_ports = 1; - mca_p->port_format = SDP_PORT_NUM_COUNT; - valid_param = TRUE; - } - } else if (mca_p->transport == SDP_TRANSPORT_CES10) { - /* Port format is /. Make sure choose - * params were not specified. - */ - if ((num[0] != SDP_CHOOSE_PARAM) && - (num[1] != SDP_CHOOSE_PARAM)) { - mca_p->vpi = num[0]; - mca_p->vci = num[1]; - mca_p->port_format = SDP_PORT_VPI_VCI; - valid_param = TRUE; - } - } else if ((mca_p->transport == SDP_TRANSPORT_AAL2_ITU) || - (mca_p->transport == SDP_TRANSPORT_AAL2_ATMF) || - (mca_p->transport == SDP_TRANSPORT_AAL2_CUSTOM)) { - /* Port format is either / or $/$. If one - * param is '$' the other must be also. The choose params - * are allowed by default and don't need to be allowed - * through the appl config. - */ - if (((num[0] != SDP_CHOOSE_PARAM) && - (num[1] != SDP_CHOOSE_PARAM)) || - ((num[0] == SDP_CHOOSE_PARAM) && - (num[1] == SDP_CHOOSE_PARAM))) { - mca_p->vcci = num[0]; - mca_p->cid = num[1]; - mca_p->port_format = SDP_PORT_VCCI_CID; - valid_param = TRUE; - } - } - break; - case 3: - if (mca_p->transport == SDP_TRANSPORT_AAL1AVP) { - /* Port format is //. Make sure choose - * params were not specified. - */ - if ((num[0] != SDP_CHOOSE_PARAM) && - (num[1] != SDP_CHOOSE_PARAM) && - (num[2] != SDP_CHOOSE_PARAM)) { - mca_p->port = num[0]; - mca_p->vpi = num[1]; - mca_p->vci = num[2]; - mca_p->port_format = SDP_PORT_NUM_VPI_VCI; - valid_param = TRUE; - } - } - break; - case 4: - if ((mca_p->transport == SDP_TRANSPORT_AAL2_ITU) || - (mca_p->transport == SDP_TRANSPORT_AAL2_ATMF) || - (mca_p->transport == SDP_TRANSPORT_AAL2_CUSTOM)) { - /* Port format is ///. Make sure choose - * params were not specified. - */ - if ((num[0] != SDP_CHOOSE_PARAM) && - (num[1] != SDP_CHOOSE_PARAM) && - (num[2] != SDP_CHOOSE_PARAM) && - (num[3] != SDP_CHOOSE_PARAM)) { - mca_p->port = num[0]; - mca_p->vpi = num[1]; - mca_p->vci = num[2]; - mca_p->cid = num[3]; - mca_p->port_format = SDP_PORT_NUM_VPI_VCI_CID; - valid_param = TRUE; - } - } - break; - } - if (valid_param == FALSE) { - sdp_parse_error(sdp_p->peerconnection, - "%s Invalid port format (%s) specified for transport " - "protocol (%s), parse failed.", sdp_p->debug_str, - port, sdp_get_transport_name(mca_p->transport)); - sdp_p->conf_p->num_invalid_param++; - SDP_FREE(mca_p); - return (SDP_INVALID_PARAMETER); - } - - /* Find payload formats. AAL2 media lines allow multiple - * transport/profile types per line, so these are handled differently. */ - if ((mca_p->transport == SDP_TRANSPORT_AAL2_ITU) || - (mca_p->transport == SDP_TRANSPORT_AAL2_ATMF) || - (mca_p->transport == SDP_TRANSPORT_AAL2_CUSTOM)) { - - if (sdp_parse_multiple_profile_payload_types(sdp_p, mca_p, ptr) != - SDP_SUCCESS) { - sdp_p->conf_p->num_invalid_param++; - SDP_FREE(mca_p); - return (SDP_INVALID_PARAMETER); - } - } else { - /* Transport is a non-AAL2 type. Parse payloads normally. */ - sdp_parse_payload_types(sdp_p, mca_p, ptr); - } - - /* Parse SCTP/DTLS port */ - if (mca_p->transport == SDP_TRANSPORT_SCTPDTLS) { - ptr = sdp_getnextstrtok(ptr, port, sizeof(port), " \t", &result); - if (result != SDP_SUCCESS) { - sdp_parse_error(sdp_p->peerconnection, - "%s No sctp port specified in m= media line, " - "parse failed.", sdp_p->debug_str); - SDP_FREE(mca_p); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - port_ptr = port; - - if (sdp_getchoosetok(port_ptr, &port_ptr, "/ \t", &result)) { - sctp_port = SDP_CHOOSE_PARAM; - } else { - sctp_port = sdp_getnextnumtok(port_ptr, (const char **)&port_ptr, - "/ \t", &result); - if (result != SDP_SUCCESS) { - return (SDP_INVALID_PARAMETER); - } - mca_p->sctpport = sctp_port; - } - } - - /* Media line params are valid. Add it into the SDP. */ - sdp_p->mca_count++; - if (sdp_p->mca_p == NULL) { - sdp_p->mca_p = mca_p; - } else { - for (next_mca_p = sdp_p->mca_p; next_mca_p->next_p != NULL; - next_mca_p = next_mca_p->next_p) { - ; // Empty For - } - next_mca_p->next_p = mca_p; - } - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - - SDP_PRINT("%s Parsed media type %s, ", sdp_p->debug_str, - sdp_get_media_name(mca_p->media)); - switch (mca_p->port_format) { - case SDP_PORT_NUM_ONLY: - SDP_PRINT("Port num %ld, ", mca_p->port); - break; - - case SDP_PORT_NUM_COUNT: - SDP_PRINT("Port num %ld, count %ld, ", - mca_p->port, mca_p->num_ports); - break; - case SDP_PORT_VPI_VCI: - SDP_PRINT("VPI/VCI %ld/%lu, ", mca_p->vpi, mca_p->vci); - break; - case SDP_PORT_VCCI: - SDP_PRINT("VCCI %ld, ", mca_p->vcci); - break; - case SDP_PORT_NUM_VPI_VCI: - SDP_PRINT("Port %ld, VPI/VCI %ld/%lu, ", mca_p->port, - mca_p->vpi, mca_p->vci); - break; - case SDP_PORT_VCCI_CID: - SDP_PRINT("VCCI %ld, CID %ld, ", mca_p->vcci, mca_p->cid); - break; - case SDP_PORT_NUM_VPI_VCI_CID: - SDP_PRINT("Port %ld, VPI/VCI %ld/%lu, CID %ld, ", mca_p->port, - mca_p->vpi, mca_p->vci, mca_p->cid); - break; - default: - SDP_PRINT("Port format not valid, "); - break; - } - - if ((mca_p->transport >= SDP_TRANSPORT_AAL2_ITU) && - (mca_p->transport <= SDP_TRANSPORT_AAL2_CUSTOM)) { - for (i=0; i < mca_p->media_profiles_p->num_profiles; i++) { - SDP_PRINT("Profile %s, Num payloads %u ", - sdp_get_transport_name(mca_p->media_profiles_p->profile[i]), - mca_p->media_profiles_p->num_payloads[i]); - } - } else { - SDP_PRINT("Transport %s, Num payloads %u", - sdp_get_transport_name(mca_p->transport), - mca_p->num_payloads); - } - } - return (SDP_SUCCESS); -} - -sdp_result_e sdp_build_media (sdp_t *sdp_p, u16 level, flex_string *fs) -{ - int i, j; - sdp_mca_t *mca_p; - tinybool invalid_params=FALSE; - sdp_media_profiles_t *profile_p; - - /* Find the right media line */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_FAILURE); - } - - /* Validate params for this media line */ - if ((mca_p->media >= SDP_MAX_MEDIA_TYPES) || - (mca_p->port_format >= SDP_MAX_PORT_FORMAT_TYPES) || - (mca_p->transport >= SDP_MAX_TRANSPORT_TYPES)) { - invalid_params = TRUE; - } - - if (invalid_params == TRUE) { - CSFLogError(logTag, "%s Invalid params for m= media line, " - "build failed.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - /* Build the media type */ - flex_string_sprintf(fs, "m=%s ", sdp_get_media_name(mca_p->media)); - - /* Build the port based on the specified port format */ - if (mca_p->port_format == SDP_PORT_NUM_ONLY) { - if (mca_p->port == SDP_CHOOSE_PARAM) { - flex_string_sprintf(fs, "$ "); - } else { - flex_string_sprintf(fs, "%u ", (u16)mca_p->port); - } - } else if (mca_p->port_format == SDP_PORT_NUM_COUNT) { - flex_string_sprintf(fs, "%u/%u ", (u16)mca_p->port, - (u16)mca_p->num_ports); - } else if (mca_p->port_format == SDP_PORT_VPI_VCI) { - flex_string_sprintf(fs, "%u/%u ", - (u16)mca_p->vpi, (u16)mca_p->vci); - } else if (mca_p->port_format == SDP_PORT_VCCI) { - flex_string_sprintf(fs, "%u ", (u16)mca_p->vcci); - } else if (mca_p->port_format == SDP_PORT_NUM_VPI_VCI) { - flex_string_sprintf(fs, "%u/%u/%u ", (u16)mca_p->port, - (u16)mca_p->vpi, (u16)mca_p->vci); - } else if (mca_p->port_format == SDP_PORT_VCCI_CID) { - if ((mca_p->vcci == SDP_CHOOSE_PARAM) && - (mca_p->cid == SDP_CHOOSE_PARAM)) { - flex_string_sprintf(fs, "$/$ "); - } else if ((mca_p->vcci == SDP_CHOOSE_PARAM) || - (mca_p->cid == SDP_CHOOSE_PARAM)) { - /* If one is set but not the other, this is an error. */ - CSFLogError(logTag, "%s Invalid params for m= port parameter, " - "build failed.", sdp_p->debug_str); - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - flex_string_sprintf(fs, "%u/%u ", - (u16)mca_p->vcci, (u16)mca_p->cid); - } - } else if (mca_p->port_format == SDP_PORT_NUM_VPI_VCI_CID) { - flex_string_sprintf(fs, "%u/%u/%u/%u ", (u16)mca_p->port, - (u16)mca_p->vpi, (u16)mca_p->vci, (u16)mca_p->cid); - } - - /* If the media line has AAL2 profiles, build them differently. */ - if ((mca_p->transport == SDP_TRANSPORT_AAL2_ITU) || - (mca_p->transport == SDP_TRANSPORT_AAL2_ATMF) || - (mca_p->transport == SDP_TRANSPORT_AAL2_CUSTOM)) { - profile_p = mca_p->media_profiles_p; - for (i=0; i < profile_p->num_profiles; i++) { - flex_string_sprintf(fs, "%s", - sdp_get_transport_name(profile_p->profile[i])); - - for (j=0; j < profile_p->num_payloads[i]; j++) { - flex_string_sprintf(fs, " %u", - profile_p->payload_type[i][j]); - } - flex_string_sprintf(fs, " "); - } - flex_string_sprintf(fs, "\n"); - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built m= media line", sdp_p->debug_str); - } - return (SDP_SUCCESS); - } - - /* Build the transport name */ - flex_string_sprintf(fs, "%s", - sdp_get_transport_name(mca_p->transport)); - - if(mca_p->transport != SDP_TRANSPORT_SCTPDTLS) { - - /* Build the format lists */ - for (i=0; i < mca_p->num_payloads; i++) { - if (mca_p->payload_indicator[i] == SDP_PAYLOAD_ENUM) { - flex_string_sprintf(fs, " %s", - sdp_get_payload_name((sdp_payload_e)mca_p->payload_type[i])); - } else { - flex_string_sprintf(fs, " %u", mca_p->payload_type[i]); - } - } - } else { - /* Add port to SDP if transport is SCTP/DTLS */ - flex_string_sprintf(fs, " %u ", (u32)mca_p->sctpport); - } - - flex_string_sprintf(fs, "\r\n"); - - if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) { - SDP_PRINT("%s Built m= media line", sdp_p->debug_str); - } - return (SDP_SUCCESS); -} - - -/* Function: sdp_parse_payload_types - * Description: Parse a list of payload types. The list may be part of - * a media line or part of a capability line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * mca_p The mca structure the payload types should be - * added to. - * ptr The pointer to the list of payloads. - * Returns: Nothing. - */ -void sdp_parse_payload_types (sdp_t *sdp_p, sdp_mca_t *mca_p, const char *ptr) -{ - u16 i; - u16 num_payloads; - sdp_result_e result; - tinybool valid_payload; - char tmp[SDP_MAX_STRING_LEN]; - char *tmp2; - - for (num_payloads = 0; (num_payloads < SDP_MAX_PAYLOAD_TYPES); ) { - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - /* If there are no more payload types, we're finished */ - break; - } - mca_p->payload_type[num_payloads] = (u16)sdp_getnextnumtok(tmp, - (const char **)&tmp2, - " \t", &result); - if (result == SDP_SUCCESS) { - if ((mca_p->media == SDP_MEDIA_IMAGE) && - (mca_p->transport == SDP_TRANSPORT_UDPTL)) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Numeric payload type not " - "valid for media %s with transport %s.", - sdp_p->debug_str, - sdp_get_media_name(mca_p->media), - sdp_get_transport_name(mca_p->transport)); - } else { - mca_p->payload_indicator[num_payloads] = SDP_PAYLOAD_NUMERIC; - mca_p->num_payloads++; - num_payloads++; - } - continue; - } - - valid_payload = FALSE; - for (i=0; i < SDP_MAX_STRING_PAYLOAD_TYPES; i++) { - if (cpr_strncasecmp(tmp, sdp_payload[i].name, - sdp_payload[i].strlen) == 0) { - valid_payload = TRUE; - break; - } - } - if (valid_payload == TRUE) { - /* We recognized the payload type. Make sure it - * is valid for this media line. */ - valid_payload = FALSE; - if ((mca_p->media == SDP_MEDIA_IMAGE) && - (mca_p->transport == SDP_TRANSPORT_UDPTL) && - (i == SDP_PAYLOAD_T38)) { - valid_payload = TRUE; - } else if ((mca_p->media == SDP_MEDIA_APPLICATION) && - (mca_p->transport == SDP_TRANSPORT_UDP) && - (i == SDP_PAYLOAD_XTMR)) { - valid_payload = TRUE; - } else if ((mca_p->media == SDP_MEDIA_APPLICATION) && - (mca_p->transport == SDP_TRANSPORT_TCP) && - (i == SDP_PAYLOAD_T120)) { - valid_payload = TRUE; - } - - if (valid_payload == TRUE) { - mca_p->payload_indicator[num_payloads] = SDP_PAYLOAD_ENUM; - mca_p->payload_type[num_payloads] = i; - mca_p->num_payloads++; - num_payloads++; - } else { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Payload type %s not valid for " - "media %s with transport %s.", - sdp_p->debug_str, - sdp_get_payload_name((sdp_payload_e)i), - sdp_get_media_name(mca_p->media), - sdp_get_transport_name(mca_p->transport)); - } - } else { - /* Payload type wasn't recognized. */ - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Payload type " - "unsupported (%s).", sdp_p->debug_str, tmp); - } - } - if (mca_p->num_payloads == 0) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No payload types specified.", - sdp_p->debug_str); - } -} - - -/* Function: sdp_parse_multiple_profile_payload_types - * Description: Parse a list of payload types. The list may be part of - * a media line or part of a capability line. - * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. - * mca_p The mca structure the payload types should be - * added to. - * ptr The pointer to the list of payloads. - * Returns: Nothing. - */ -sdp_result_e sdp_parse_multiple_profile_payload_types (sdp_t *sdp_p, - sdp_mca_t *mca_p, - const char *ptr) -{ - u16 i; - u16 prof; - u16 payload; - sdp_result_e result; - sdp_media_profiles_t *profile_p; - char tmp[SDP_MAX_STRING_LEN]; - char *tmp2; - - /* If the transport type is any of the AAL2 formats, then we - * need to look for multiple AAL2 profiles and their associated - * payload lists. */ - mca_p->media_profiles_p = (sdp_media_profiles_t *) \ - SDP_MALLOC(sizeof(sdp_media_profiles_t)); - if (mca_p->media_profiles_p == NULL) { - sdp_p->conf_p->num_no_resource++; - SDP_FREE(mca_p); - return (SDP_NO_RESOURCE); - } - profile_p = mca_p->media_profiles_p; - /* Set the first profile to the one already detected. */ - profile_p->num_profiles = 1; - prof = 0; - payload = 0; - profile_p->profile[prof] = mca_p->transport; - profile_p->num_payloads[prof] = 0; - - /* Now find the payload type lists and any other profile types */ - while (TRUE) { - ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result); - if (result != SDP_SUCCESS) { - /* If there are no more payload types, we're finished */ - break; - } - - /* See if the next token is a new profile type. */ - if (prof < SDP_MAX_PROFILES) { - profile_p->profile[prof+1] = SDP_TRANSPORT_UNSUPPORTED; - for (i=SDP_TRANSPORT_AAL2_ITU; - i <= SDP_TRANSPORT_AAL2_CUSTOM; i++) { - if (cpr_strncasecmp(tmp, sdp_transport[i].name, - sdp_transport[i].strlen) == 0) { - profile_p->profile[prof+1] = (sdp_transport_e)i; - break; - } - } - /* If we recognized the profile type, start looking for the - * next payload list. */ - if (profile_p->profile[prof+1] != SDP_TRANSPORT_UNSUPPORTED) { - /* Now reset the payload counter for the next profile type. */ - payload = 0; - prof++; - profile_p->num_profiles++; - if (prof < SDP_MAX_PROFILES) { - profile_p->num_payloads[prof] = 0; - } - continue; - } - } - - /* This token must be a payload type. Make sure there aren't - * too many payload types. */ - if (payload >= SDP_MAX_PAYLOAD_TYPES) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Too many payload types " - "found, truncating.", sdp_p->debug_str); - continue; - } - - /* See if the payload type is numeric. */ - if (prof < SDP_MAX_PROFILES && payload < SDP_MAX_PAYLOAD_TYPES) { - profile_p->payload_type[prof][payload] = (u16)sdp_getnextnumtok(tmp, - (const char **)&tmp2, - " \t", &result); - if (result == SDP_SUCCESS) { - profile_p->payload_indicator[prof][payload] = SDP_PAYLOAD_NUMERIC; - profile_p->num_payloads[prof]++; - payload++; - continue; - } - } - - /* No string payload types are currently valid for the AAL2 - * transport types. This support can be added when needed. */ - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: Unsupported payload type " - "found (%s).", sdp_p->debug_str, tmp); - } - for (i=0; i < profile_p->num_profiles; i++) { - /* Make sure we have payloads for each profile type. */ - if (profile_p->num_payloads[i] == 0) { - sdp_parse_error(sdp_p->peerconnection, - "%s Warning: No payload types specified " - "for AAL2 profile %s.", sdp_p->debug_str, - sdp_get_transport_name(profile_p->profile[i])); - } - } - return (SDP_SUCCESS); -} diff --git a/libs/sipcc/core/sdp/sdp_utils.c b/libs/sipcc/core/sdp/sdp_utils.c deleted file mode 100644 index b9e534fbfa..0000000000 --- a/libs/sipcc/core/sdp/sdp_utils.c +++ /dev/null @@ -1,773 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include "sdp_os_defs.h" -#include "sdp.h" -#include "sdp_private.h" -#include "CSFLog.h" - -#define MKI_BUF_LEN 4 - -//static const char* logTag = "sdp_utils"; - -sdp_mca_t *sdp_alloc_mca () { - sdp_mca_t *mca_p; - - /* Allocate resource for new media stream. */ - mca_p = (sdp_mca_t *)SDP_MALLOC(sizeof(sdp_mca_t)); - if (mca_p == NULL) { - return (NULL); - } - /* Initialize mca structure */ - mca_p->media = SDP_MEDIA_INVALID; - mca_p->conn.nettype = SDP_NT_INVALID; - mca_p->conn.addrtype = SDP_AT_INVALID; - mca_p->conn.conn_addr[0] = '\0'; - mca_p->conn.is_multicast = FALSE; - mca_p->conn.ttl = 0; - mca_p->conn.num_of_addresses = 0; - mca_p->transport = SDP_TRANSPORT_INVALID; - mca_p->port = SDP_INVALID_VALUE; - mca_p->num_ports = SDP_INVALID_VALUE; - mca_p->vpi = SDP_INVALID_VALUE; - mca_p->vci = 0; - mca_p->vcci = SDP_INVALID_VALUE; - mca_p->cid = SDP_INVALID_VALUE; - mca_p->num_payloads = 0; - mca_p->sessinfo_found = FALSE; - mca_p->encrypt.encrypt_type = SDP_ENCRYPT_INVALID; - mca_p->media_attrs_p = NULL; - mca_p->next_p = NULL; - mca_p->mid = 0; - mca_p->bw.bw_data_count = 0; - mca_p->bw.bw_data_list = NULL; - - return (mca_p); -} - -/* - * next_token - * - * copy token param with chars from str until null, cr, lf, or one of the delimiters is found. - * delimiters at the beginning will be skipped. - * The pointer *string_of_tokens is moved forward to the next token on sucess. - * - */ -static sdp_result_e next_token(const char **string_of_tokens, char *token, unsigned token_max_len, const char *delim) -{ - int flag2moveon = 0; - const char *str = *string_of_tokens; - char *token_start = token; - const char *next_delim; - - if (!string_of_tokens || !*string_of_tokens || !token || !delim) { - return SDP_FAILURE; - } - - /* Locate front of token, skipping any delimiters */ - for ( ; ((*str != '\0') && (*str != '\n') && (*str != '\r')); str++) { - flag2moveon = 1; /* Default to move on unless we find a delimiter */ - for (next_delim=delim; *next_delim; next_delim++) { - if (*str == *next_delim) { - flag2moveon = 0; - break; - } - } - if( flag2moveon ) { - break; /* We're at the beginning of the token */ - } - } - - /* Make sure there's really a token present. */ - if ((*str == '\0') || (*str == '\n') || (*str == '\r')) { - return SDP_FAILURE; - } - - /* Now locate end of token */ - flag2moveon = 0; - - while (((token-token_start) < token_max_len - 1) && - (*str != '\0') && (*str != '\n') && (*str != '\r')) { - for (next_delim=delim; *next_delim; next_delim++) { - if (*str == *next_delim) { - flag2moveon = 1; - break; - } - } - if( flag2moveon ) { - break; - } else { - *token++ = *str++; - } - } - - /* mark end of token */ - *token = '\0'; - - /* set the string of tokens to the next token */ - *string_of_tokens = str; - - return SDP_SUCCESS; -} - -/* - * verify_sdescriptions_mki - * - * Verifies the syntax of the MKI parameter. - * - * mki = mki-value ":" mki-length - * mki-value = 1*DIGIT - * mki-length = 1*3DIGIT ; range 1..128 - * - * Inputs: - * buf - ptr to start of MKI string assumes NULL - * terminated string - * mkiValue - buffer to store the MKI value, assumes calling - * function has provided memory for this. - * mkiLen - integer to store the MKI length - * - * Outputs: - * Returns TRUE if syntax is correct and stores the - * MKI value in mkiVal and stores the length in mkiLen. - * Returns FALSE otherwise. - */ - -tinybool -verify_sdescriptions_mki (char *buf, char *mkiVal, u16 *mkiLen) -{ - - char *ptr, - mkiValBuf[SDP_SRTP_MAX_MKI_SIZE_BYTES], - mkiLenBuf[MKI_BUF_LEN]; - int idx = 0; - unsigned long strtoul_result; - char *strtoul_end; - - ptr = buf; - /* MKI must begin with a digit */ - if (!ptr || (!isdigit((int) *ptr))) { - return FALSE; - } - - /* scan until we reach a non-digit or colon */ - while (*ptr) { - if (*ptr == ':') { - /* terminate the MKI value */ - mkiValBuf[idx] = 0; - ptr++; - break; - } else if ((isdigit((int) *ptr) && (idx < SDP_SRTP_MAX_MKI_SIZE_BYTES-1))) { - mkiValBuf[idx++] = *ptr; - } else { - return FALSE; - } - - ptr++; - } - - /* there has to be a mki length */ - if (*ptr == 0) { - return FALSE; - } - - idx = 0; - - /* verify the mki length (max 3 digits) */ - while (*ptr) { - if (isdigit((int) *ptr) && (idx < 3)) { - mkiLenBuf[idx++] = *ptr; - } else { - return FALSE; - } - - ptr++; - } - - mkiLenBuf[idx] = 0; - - errno = 0; - strtoul_result = strtoul(mkiLenBuf, &strtoul_end, 10); - - /* mki len must be between 1..128 */ - if (errno || mkiLenBuf == strtoul_end || strtoul_result < 1 || strtoul_result > 128) { - *mkiLen = 0; - return FALSE; - } - - *mkiLen = (u16) strtoul_result; - sstrncpy(mkiVal, mkiValBuf, MKI_BUF_LEN); - - return TRUE; -} - -/* - * verify_srtp_lifetime - * - * Verifies the Lifetime parameter syntax. - * - * lifetime = ["2^"] 1*(DIGIT) - * - * Inputs: - * buf - pointer to start of lifetime string. Assumes string is - * NULL terminated. - * Outputs: - * Returns TRUE if syntax is correct. Returns FALSE otherwise. - */ - -tinybool -verify_sdescriptions_lifetime (char *buf) -{ - - char *ptr; - tinybool tokenFound = FALSE; - - ptr = buf; - if (!ptr || *ptr == 0) { - return FALSE; - } - - while (*ptr) { - if (*ptr == '^') { - if (tokenFound) { - /* make sure we don't have multiple ^ */ - return FALSE; - } else { - tokenFound = TRUE; - /* Lifetime is in power of 2 format, make sure first and second - * chars are 2^ - */ - - if (buf[0] != '2' || buf[1] != '^') { - return FALSE; - } - } - } else if (!isdigit((int) *ptr)) { - return FALSE; - } - - ptr++; - - } - - /* Make sure if the format is 2^ that there is a number after the ^. */ - if (tokenFound) { - if (strlen(buf) <= 2) { - return FALSE; - } - } - - return TRUE; -} - - -/* - * sdp_validate_maxprate - * - * This function validates that the string passed in is of the form: - * packet-rate = 1*DIGIT ["." 1*DIGIT] - */ -tinybool -sdp_validate_maxprate(const char *string_parm) -{ - tinybool retval = FALSE; - - if (string_parm && (*string_parm)) { - while (isdigit((int)*string_parm)) { - string_parm++; - } - - if (*string_parm == '.') { - string_parm++; - while (isdigit((int)*string_parm)) { - string_parm++; - } - } - - if (*string_parm == '\0') { - retval = TRUE; - } else { - retval = FALSE; - } - } - - return retval; -} - -char *sdp_findchar (const char *ptr, char *char_list) -{ - int i; - - for (;*ptr != '\0'; ptr++) { - for (i=0; char_list[i] != '\0'; i++) { - if (*ptr == char_list[i]) { - return ((char *)ptr); - } - } - } - return ((char *)ptr); -} - -/* Locate the next token in a line. The delim characters are passed in - * as a param. The token also will not go past a new line char or the - * end of the string. Skip any delimiters before the token. - */ -const char *sdp_getnextstrtok (const char *str, char *tokenstr, unsigned tokenstr_len, - const char *delim, sdp_result_e *result) -{ - const char *token_list = str; - - if (!str || !tokenstr || !delim || !result) { - if (result) { - *result = SDP_FAILURE; - } - return str; - } - - *result = next_token(&token_list, tokenstr, tokenstr_len, delim); - - return token_list; -} - - - -/* Locate the next null ("-") or numeric token in a string. The delim - * characters are passed in as a param. The token also will not go past - * a new line char or the end of the string. Skip any delimiters before - * the token. - */ -u32 sdp_getnextnumtok_or_null (const char *str, const char **str_end, - const char *delim, tinybool *null_ind, - sdp_result_e *result) -{ - const char *token_list = str; - char temp_token[SDP_MAX_STRING_LEN]; - char *strtoul_end; - unsigned long numval; - - *null_ind = FALSE; - - if (!str || !str_end || !delim || !null_ind || !result) { - if (result) { - *result = SDP_FAILURE; - } - return 0; - } - - *result = next_token(&token_list, temp_token, sizeof(temp_token), delim); - - if (*result != SDP_SUCCESS) { - return 0; - } - - /* First see if its the null char ("-") */ - if (temp_token[0] == '-') { - *null_ind = TRUE; - *result = SDP_SUCCESS; - *str_end = str; - return 0; - } - - errno = 0; - numval = strtoul(temp_token, &strtoul_end, 10); - - if (errno || strtoul_end == temp_token || numval > UINT_MAX) { - *result = SDP_FAILURE; - return 0; - } - - *result = SDP_SUCCESS; - *str_end = token_list; - return (u32) numval; -} - - -/* Locate the next numeric token in a string. The delim characters are - * passed in as a param. The token also will not go past a new line char - * or the end of the string. Skip any delimiters before the token. - */ -u32 sdp_getnextnumtok (const char *str, const char **str_end, - const char *delim, sdp_result_e *result) -{ - const char *token_list = str; - char temp_token[SDP_MAX_STRING_LEN]; - char *strtoul_end; - unsigned long numval; - - if (!str || !str_end || !delim || !result) { - if (result) { - *result = SDP_FAILURE; - } - return 0; - } - - *result = next_token(&token_list, temp_token, sizeof(temp_token), delim); - - if (*result != SDP_SUCCESS) { - return 0; - } - - errno = 0; - numval = strtoul(temp_token, &strtoul_end, 10); - - if (errno || strtoul_end == temp_token || numval > UINT_MAX) { - *result = SDP_FAILURE; - return 0; - } - - *result = SDP_SUCCESS; - *str_end = token_list; - return (u32) numval; -} - - -/* See if the next token in a string is the choose character. The delim - * characters are passed in as a param. The check also will not go past - * a new line char or the end of the string. Skip any delimiters before - * the token. - */ -tinybool sdp_getchoosetok (const char *str, const char **str_end, - const char *delim, sdp_result_e *result) -{ - const char *b; - int flag2moveon; - - if ((str == NULL) || (str_end == NULL)) { - *result = SDP_FAILURE; - return(FALSE); - } - - /* Locate front of token, skipping any delimiters */ - for ( ; ((*str != '\0') && (*str != '\n') && (*str != '\r')); str++) { - flag2moveon = 1; /* Default to move on unless we find a delimiter */ - for (b=delim; *b; b++) { - if (*str == *b) { - flag2moveon = 0; - break; - } - } - if( flag2moveon ) { - break; /* We're at the beginning of the token */ - } - } - - /* Make sure there's really a token present. */ - if ((*str == '\0') || (*str == '\n') || (*str == '\r')) { - *result = SDP_FAILURE; - *str_end = (char *)str; - return(FALSE); - } - - /* See if the token is '$' followed by a delimiter char or end of str. */ - if (*str == '$') { - str++; - if ((*str == '\0') || (*str == '\n') || (*str == '\r')) { - *result = SDP_SUCCESS; - /* skip the choose char in the string. */ - *str_end = (char *)(str+1); - return(TRUE); - } - for (b=delim; *b; b++) { - if (*str == *b) { - *result = SDP_SUCCESS; - /* skip the choose char in the string. */ - *str_end = (char *)(str+1); - return(TRUE); - } - } - } - - /* If the token was not '$' followed by a delim, token is not choose */ - *result = SDP_SUCCESS; - *str_end = (char *)str; - return(FALSE); - -} - -/* - * SDP Crypto Utility Functions. - * - * First a few common definitions. - */ - -/* - * Constants - * - * crypto_string = The string used to identify the start of sensative - * crypto data. - * - * inline_string = The string used to identify the start of key/salt - * crypto data. - * - * star_string = The string used to overwrite sensative data. - * - * '*_strlen' = The length of '*_string' in bytes (not including '\0') - */ -static const char crypto_string[] = "X-crypto:"; -static const int crypto_strlen = sizeof(crypto_string) - 1; -static const char inline_string[] = "inline:"; -static const int inline_strlen = sizeof(inline_string) - 1; -/* 40 characters is the current maximum for a Base64 encoded key/salt */ -static const char star_string[] = "****************************************"; -static const int star_strlen = sizeof(star_string) - 1; - -/* - * MIN_CRYPTO_STRING_SIZE_BYTES = This value defines the minimum - * size of a string that could contain a key/salt. This value - * is used to skip out of parsing when there is no reasonable - * assumption that sensative data will be found. The general - * format of a SRTP Key Salt in SDP looks like: - * - * X-crypto: inline:|| - * - * if and is at least - * one character and one space is used before the "inline:", - * then this translates to a size of (aligned by collumn from - * the format shown above): - * - * 9+ 1+ 1+7+ 1+ 2 = 21 - * - */ -#define MIN_CRYPTO_STRING_SIZE_BYTES 21 - -/* - * Utility macros - * - * CHAR_IS_WHITESPACE = macro to determine if the passed _test_char - * is whitespace. - * - * SKIP_WHITESPACE = Macro to advance _cptr to the next non-whitespace - * character. _cptr will not be advanced past _max_cptr. - * - * FIND_WHITESPACE = Macro to advance _cptr until whitespace is found. - * _cptr will not be advanced past _max_cptr. - */ -#define CHAR_IS_WHITESPACE(_test_char) \ - ((((_test_char)==' ')||((_test_char)=='\t'))?1:0) - -#define SKIP_WHITESPACE(_cptr, _max_cptr) \ - while ((_cptr)<=(_max_cptr)) { \ - if (!CHAR_IS_WHITESPACE(*(_cptr))) break; \ - (_cptr)++; \ - } - -#define FIND_WHITESPACE(_cptr, _max_cptr) \ - while ((_cptr)<=(_max_cptr)) { \ - if (CHAR_IS_WHITESPACE(*(_cptr))) break; \ - (_cptr)++; \ - } - -/* Function: sdp_crypto_debug - * Description: Check the passed buffer for sensitive data that should - * not be output (such as SRTP Master Key/Salt) and output - * the buffer as debug. Sensitive data will be replaced - * with the '*' character(s). This function may be used - * to display very large buffers so this function ensures - * that buginf is not overloaded. - * Parameters: buffer pointer to the message buffer to filter. - * length_bytes size of message buffer in bytes. - * Returns: Nothing. - */ -void sdp_crypto_debug (char *buffer, ulong length_bytes) -{ - char *current, *start; - char *last = buffer + length_bytes; - int result; - - /* - * For SRTP Master Key/Salt has the form: - * X-crypto: inline:|| - * Where is the data to elide (filter). - */ - for (start=current=buffer; - current<=last-MIN_CRYPTO_STRING_SIZE_BYTES; - current++) { - if ((*current == 'x') || (*current == 'X')) { - result = cpr_strncasecmp(current, crypto_string, crypto_strlen); - if (!result) { - current += crypto_strlen; - if (current > last) break; - - /* Skip over crypto suite name */ - FIND_WHITESPACE(current, last); - - /* Skip over whitespace */ - SKIP_WHITESPACE(current, last); - - /* identify inline keyword */ - result = cpr_strncasecmp(current, inline_string, inline_strlen); - if (!result) { - int star_count = 0; - - current += inline_strlen; - if (current > last) break; - - sdp_dump_buffer(start, current - start); - - /* Hide sensitive key/salt data */ - while (current<=last) { - if (*current == '|' || *current == '\n') { - /* Done, print the stars */ - while (star_count > star_strlen) { - /* - * This code is only for the case where - * too much base64 data was supplied - */ - sdp_dump_buffer((char*)star_string, star_strlen); - star_count -= star_strlen; - } - sdp_dump_buffer((char*)star_string, star_count); - break; - } else { - star_count++; - current++; - } - } - /* Update start pointer */ - start=current; - } - } - } - } - - if (last > start) { - /* Display remainder of buffer */ - sdp_dump_buffer(start, last - start); - } -} - -/* - * sdp_debug_msg_filter - * - * DESCRIPTION - * Check the passed message buffer for sensitive data that should - * not be output (such as SRTP Master Key/Salt). Sensitive data - * will be replaced with the '*' character(s). - * - * PARAMETERS - * buffer: pointer to the message buffer to filter. - * - * length_bytes: size of message buffer in bytes. - * - * RETURN VALUE - * The buffer modified. - */ -char * sdp_debug_msg_filter (char *buffer, ulong length_bytes) -{ - char *current; - char *last = buffer + length_bytes; - int result; - - SDP_PRINT("\n%s:%d: Eliding sensitive data from debug output", - __FILE__, __LINE__); - /* - * For SRTP Master Key/Salt has the form: - * X-crypto: inline:|| - * Where is the data to elide (filter). - */ - for (current=buffer; - current<=last-MIN_CRYPTO_STRING_SIZE_BYTES; - current++) { - if ((*current == 'x') || (*current == 'X')) { - result = cpr_strncasecmp(current, crypto_string, crypto_strlen); - if (!result) { - current += crypto_strlen; - if (current > last) break; - - /* Skip over crypto suite name */ - FIND_WHITESPACE(current, last); - - /* Skip over whitespace */ - SKIP_WHITESPACE(current, last); - - /* identify inline keyword */ - result = cpr_strncasecmp(current, inline_string, inline_strlen); - if (!result) { - current += inline_strlen; - if (current > last) break; - - /* Hide sensitive key/salt data */ - while (current<=last) { - if (*current == '|' || *current == '\n') { - /* Done */ - break; - } else { - *current = '*'; - current++; - } - } - } - } - } - } - - return buffer; -} - - -/* Function: sdp_checkrange - * Description: This checks the range of a ulong value to make sure its - * within the range of 0 and 4Gig. stroul cannot be used since - * for values greater greater than 4G, stroul will either wrap - * around or return ULONG_MAX. - * Parameters: sdp_p Pointer to the sdp structure - * num The number to check the range for - * u_val This variable get populated with the ulong value - * if the number is within the range. - * Returns: tinybool - returns TRUE if the number passed is within the - * range, FALSE otherwise - */ -tinybool sdp_checkrange (sdp_t *sdp_p, char *num, ulong *u_val) -{ - ulong l_val; - char *endP = NULL; - *u_val = 0; - - if (!num || !*num) { - return FALSE; - } - - if (*num == '-') { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s ERROR: Parameter value is a negative number: %s", - sdp_p->debug_str, num); - } - return FALSE; - } - - l_val = strtoul(num, &endP, 10); - if (*endP == '\0') { - - if (l_val > 4294967295UL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s ERROR: Parameter value: %s is greater than 4294967295", - sdp_p->debug_str, num); - } - return FALSE; - } - - if (l_val == 4294967295UL) { - /* - * On certain platforms where ULONG_MAX is equivalent to - * 4294967295, strtoul will return ULONG_MAX even if the the - * value of the string is greater than 4294967295. To detect - * that scenario we make an explicit check here. - */ - if (strcmp("4294967295", num)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s ERROR: Parameter value: %s is greater than 4294967295", - sdp_p->debug_str, num); - } - return FALSE; - } - } - } - *u_val = l_val; - return TRUE; -} - -#undef CHAR_IS_WHITESPACE -#undef SKIP_WHITESPACE -#undef FIND_WHITESPACE diff --git a/libs/sipcc/core/sipstack/ccsip_callinfo.c b/libs/sipcc/core/sipstack/ccsip_callinfo.c deleted file mode 100644 index c76afd86a5..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_callinfo.c +++ /dev/null @@ -1,677 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include - -#include "ccsip_callinfo.h" -#include "ccsip_protocol.h" -#include "ccsip_core.h" -#include "cpr_string.h" -#include "cpr_strings.h" -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_memory.h" -#include "cpr_stdlib.h" -#include "phone_debug.h" - - -#define FEAT_STRING_SIZE 80 - -/* - * which_feature - * - * Description: - * - * A quick determination of the feature based on the string. - */ -static cc_call_info_e -which_feature (char *feat_string_p) -{ - if (cpr_strcasecmp(feat_string_p, SIP_CI_HOLD_STR) == 0) - return CC_FEAT_HOLD; - - if (cpr_strcasecmp(feat_string_p, SIP_CI_RESUME_STR) == 0) - return CC_FEAT_RESUME; - - if (cpr_strcasecmp(feat_string_p, SIP_CI_BARGE_STR) == 0) - return CC_FEAT_BARGE; - - if (cpr_strcasecmp(feat_string_p, SIP_CI_CBARGE_STR) == 0) - return CC_FEAT_CBARGE; - - if (cpr_strcasecmp(feat_string_p, SIP_CI_CALL_INFO_STR) == 0) - return CC_FEAT_CALLINFO; - - return CC_FEAT_NONE; -} - -/* - * parse_call_info_parm - * - * Description: - * - * Parse potential callinfo feature parms. - */ -static void -parse_call_info_parm (char *parm_p, cc_call_info_data_t * feature_data_p) -{ - static const char fname[] = "parse_call_info_parm"; - char *temp_p; - uint16_t instance_id; - unsigned long strtoul_result; - char *strtoul_end; - - if (!parm_p) - return; - - while (parm_p) { - parm_p++; - SKIP_LWS(parm_p); - - if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY, - sizeof(SIP_CI_SECURITY) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_SECURITY) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - feature_data_p->call_info_feat_data.feature_flag |= CC_SECURITY; - if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_UNKNOWN, - sizeof(SIP_CI_SECURITY_UNKNOWN) - 1)) { - feature_data_p->call_info_feat_data.security = CC_SECURITY_UNKNOWN; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_AUTH, - sizeof(SIP_CI_SECURITY_AUTH) - 1)) { - feature_data_p->call_info_feat_data.security = CC_SECURITY_AUTHENTICATED; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_ENCRYPTED, - sizeof(SIP_CI_SECURITY_ENCRYPTED) - 1)) { - feature_data_p->call_info_feat_data.security = CC_SECURITY_ENCRYPTED; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_SECURITY_NOT_AUTH, - sizeof(SIP_CI_SECURITY_NOT_AUTH) - 1)) { - feature_data_p->call_info_feat_data.security = CC_SECURITY_NOT_AUTHENTICATED; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Unknown security" - " value %s\n", fname, parm_p); - feature_data_p->call_info_feat_data.security = CC_SECURITY_UNKNOWN; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_POLICY, - sizeof(SIP_CI_POLICY) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_POLICY) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - feature_data_p->call_info_feat_data.feature_flag |= CC_POLICY; - if (!cpr_strncasecmp(parm_p, SIP_CI_POLICY_CHAPERONE , - sizeof(SIP_CI_POLICY_CHAPERONE) - 1)) { - feature_data_p->call_info_feat_data.policy = CC_POLICY_CHAPERONE; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_POLICY_UNKNOWN, - sizeof(SIP_CI_POLICY_UNKNOWN) - 1)) { - feature_data_p->call_info_feat_data.policy = CC_POLICY_UNKNOWN; - } else { - CCSIP_DEBUG_ERROR("%s ERROR: Unknown policy" - " value %s\n", fname, parm_p) ; - feature_data_p->call_info_feat_data.policy = CC_POLICY_UNKNOWN; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_ORIENTATION, - sizeof(SIP_CI_ORIENTATION) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_ORIENTATION) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - feature_data_p->call_info_feat_data.feature_flag |= CC_ORIENTATION; - if (!cpr_strncasecmp(parm_p, SIP_CI_ORIENTATION_FROM, - sizeof(SIP_CI_ORIENTATION_FROM) - 1)) { - feature_data_p->call_info_feat_data.orientation = CC_ORIENTATION_FROM; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_ORIENTATION_TO, - sizeof(SIP_CI_ORIENTATION_TO) - 1)) { - feature_data_p->call_info_feat_data.orientation = CC_ORIENTATION_TO; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Unknown orientation info" - " value %s\n", fname, parm_p); - feature_data_p->call_info_feat_data.orientation = CC_ORIENTATION_NONE; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE, - sizeof(SIP_CI_UI_STATE) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_UI_STATE) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - feature_data_p->call_info_feat_data.feature_flag |= CC_UI_STATE; - if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE_RINGOUT, - sizeof(SIP_CI_UI_STATE_RINGOUT) - 1)) { - feature_data_p->call_info_feat_data.ui_state = CC_UI_STATE_RINGOUT; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE_CONNECTED, - sizeof(SIP_CI_UI_STATE_CONNECTED) - 1)) { - feature_data_p->call_info_feat_data.ui_state = CC_UI_STATE_CONNECTED; - } else if (!cpr_strncasecmp(parm_p, SIP_CI_UI_STATE_BUSY, - sizeof(SIP_CI_UI_STATE_BUSY) - 1)) { - feature_data_p->call_info_feat_data.ui_state = CC_UI_STATE_BUSY; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Unknown call state" - " value %s\n", fname, parm_p); - /* Unknown value, ignore the call state */ - feature_data_p->call_info_feat_data.feature_flag &= - ~(CC_UI_STATE); - feature_data_p->call_info_feat_data.ui_state = - CC_UI_STATE_NONE; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_CALL_INSTANCE, - sizeof(SIP_CI_CALL_INSTANCE) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_CALL_INSTANCE) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - int idx=0; - char tempbuf[4]; - - feature_data_p->call_info_feat_data.feature_flag |= CC_CALL_INSTANCE; - /* Initialized the call instance id, just in case */ - feature_data_p->call_info_feat_data.caller_id.call_instance_id - = 0; - /* Parse instance id from line */ - temp_p = parm_p; - while (isdigit((int) *parm_p)&&idx<3) { - tempbuf[idx++] = *parm_p++; - } - tempbuf[idx] = 0; - if (idx == 0) { - /* Did not find any digit after "call_instance=" */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "no digits found for" - " call_instance parameter.\n", fname); - feature_data_p->call_info_feat_data.feature_flag &= - ~(CC_CALL_INSTANCE); - break; - } else { - errno = 0; - strtoul_result = strtoul(tempbuf, &strtoul_end, 10); - - if (errno || tempbuf == strtoul_end || strtoul_result > USHRT_MAX) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "parse error for call_instance_id: %s", - __FUNCTION__, tempbuf); - strtoul_result = 0; - } - - feature_data_p->call_info_feat_data.caller_id.call_instance_id = - (uint16_t) strtoul_result; - } - } else { - break; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_PRIORITY, - sizeof(SIP_CI_PRIORITY) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_PRIORITY) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - temp_p = parm_p; - if ((!cpr_strncasecmp(parm_p, SIP_CI_PRIORITY_URGENT, - sizeof(SIP_CI_PRIORITY_URGENT) - 1)) || - (!cpr_strncasecmp(parm_p, SIP_CI_PRIORITY_EMERGENCY, - sizeof(SIP_CI_PRIORITY_EMERGENCY) - 1))) { - feature_data_p->call_info_feat_data.priority = CC_CALL_PRIORITY_URGENT; - } // otherwise, it will be defaulted to normal priority - else { - errno = 0; - strtoul_result = strtoul(temp_p, &strtoul_end, 10); - - if (errno || temp_p == strtoul_end || strtoul_result > MAX_INSTANCES) { - /* - * Call instance ID should not exceed max instances - * or calls. - */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "invalid call_instance" - " value %u\n", fname, (unsigned) strtoul_result); - feature_data_p->call_info_feat_data.feature_flag &= - ~(CC_CALL_INSTANCE); - } else { - instance_id = (uint16_t) strtoul_result; - feature_data_p->call_info_feat_data.caller_id.call_instance_id = instance_id; - } - } - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_GCID, - sizeof(SIP_CI_GCID) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_GCID) - 1; - SKIP_LWS(parm_p); - memset(feature_data_p->call_info_feat_data.global_call_id, 0, CC_GCID_LEN); - if (*parm_p) { - temp_p = strchr(parm_p, SEMI_COLON); - if (temp_p) { - unsigned int length = ((temp_p - parm_p)call_info_feat_data.global_call_id, parm_p, length); - } else { - // No Semicolon found this could be the last parameter - sstrncpy(feature_data_p->call_info_feat_data.global_call_id, parm_p, CC_GCID_LEN); - } - feature_data_p->call_info_feat_data.global_call_id[CC_GCID_LEN-1] = 0; - } - } else if (!cpr_strncasecmp(parm_p, SIP_CI_DUSTINGCALL, - sizeof(SIP_CI_DUSTINGCALL) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_DUSTINGCALL) - 1; - SKIP_LWS(parm_p); - feature_data_p->call_info_feat_data.dusting = TRUE; - } - - parm_p = strchr(parm_p, SEMI_COLON); - } -} - -/* - * parse_gen_parm - * - * Description: - * - * Parse feature parms where the only expected parm is the purpose. - */ -static void -parse_gen_parm (char *parm_p, cc_call_info_data_t * feature_data_p) -{ - if (!parm_p) - return; - - while (parm_p) { - parm_p++; - SKIP_LWS(parm_p); - - if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC, - sizeof(SIP_CI_GENERIC) - 1)) { - parm_p = parm_p + sizeof(SIP_CI_GENERIC) - 1; - SKIP_LWS(parm_p); - - if (*parm_p) { - if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC_ICON, - sizeof(SIP_CI_GENERIC_ICON) - 1)) { - feature_data_p->purpose = CC_PURPOSE_ICON; - } else { - if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC_INFO, - sizeof(SIP_CI_GENERIC_INFO) - 1)) { - feature_data_p->purpose = CC_PURPOSE_INFO; - } else { - if (!cpr_strncasecmp(parm_p, SIP_CI_GENERIC_CARD, - sizeof(SIP_CI_GENERIC_CARD) - 1)) { - feature_data_p->purpose = CC_PURPOSE_CARD; - } - } - } - } - } else { - break; - } - parm_p = strchr(parm_p, SEMI_COLON); - } -} - -/* - * set_parm_defaults - * - * Description: - * - * A quick determination of the feature based on the string. - */ -static void -set_parm_defaults (cc_call_info_t *call_info_p) -{ - switch (call_info_p->type) { - case CC_FEAT_HOLD: - case CC_FEAT_RESUME: - case CC_FEAT_NONE: - call_info_p->data.hold_resume_reason = CC_REASON_NONE; - break; - - case CC_FEAT_BARGE: - case CC_FEAT_CBARGE: - call_info_p->data.purpose = CC_PURPOSE_NONE; - break; - - case CC_FEAT_CALLINFO: - call_info_p->data.call_info_feat_data.policy = CC_POLICY_NONE; - call_info_p->data.call_info_feat_data.security = CC_SECURITY_NONE; - call_info_p->data.call_info_feat_data.orientation = CC_ORIENTATION_NONE; - call_info_p->data.call_info_feat_data.ui_state = CC_UI_STATE_NONE; - call_info_p->data.call_info_feat_data.priority = CC_CALL_PRIORITY_NORMAL; - call_info_p->data.call_info_feat_data.global_call_id[0] = 0; - call_info_p->data.call_info_feat_data.dusting = FALSE; - break; - - default: - break; - } - -} - -/* - * ccsip_decode_call_info_hdr - * - * Description: - * - * Main method which decodes a single call info header and stores the - * related parms. - * - * Example Input: - * --------------- - * ; reason= conference - * ; seCuRity=unsecure; orienTation= to - */ -static void -ccsip_decode_call_info_hdr (const char *call_info_hdr_p, - cc_call_info_t *call_info_p) -{ - char *ptr = NULL; - char *laq_ptr = NULL; - char *raq_ptr = NULL; - boolean ret_val = FALSE; - char feat_string[FEAT_STRING_SIZE]; - - memset(feat_string, '\0', sizeof(feat_string)); - - /* - * call_info_hdr_p and call_info_p are verified by caller so they - * are not checked here. - */ - - ptr = laq_ptr = strchr(call_info_hdr_p, LAQUOT); - raq_ptr = strchr(call_info_hdr_p, RAQUOT); - - // Parse out the remotecc string and the feature string. - if (laq_ptr && raq_ptr) { - ptr++; - - // Verify the remotecc string. - if (!cpr_strncasecmp(ptr, URN_REMOTECC, sizeof(URN_REMOTECC) - 1)) { - ptr += sizeof(URN_REMOTECC) - 1; - sstrncpy(feat_string, ptr, raq_ptr - ptr + 1); - - // Which feature do we have in this header? - call_info_p->type = which_feature(feat_string); - - if (call_info_p->type != CC_FEAT_NONE) { - ret_val = TRUE; - set_parm_defaults(call_info_p); - } - } - } - - if (!ret_val) { - return; - } - - if (!(ptr = strchr(raq_ptr, SEMI_COLON))) { - return; - } - - switch (call_info_p->type) { - case CC_FEAT_CALLINFO: - parse_call_info_parm(ptr, &call_info_p->data); - break; - default: - parse_gen_parm(ptr, &call_info_p->data); - } -} - -/* - * ccsip_encode_call_info_hdr - * - * Description: - * - * Encode the call info header using the passed in feature id and - * feature specific data. - * - * The miscParms parameter will usually be null. It exists in case - * you want to toss in an additional string parm without using the - * encoding mechanism. An example would be "extraParm= text". - * - * Remember to delete the store in the return parm. It is the - * caller's responsibility. - */ -char * -ccsip_encode_call_info_hdr (cc_call_info_t *call_info_p, - const char *misc_parms_p) -{ - static const char *fname = "ccsip_encode_call_info_hdr"; - char *header; - - header = (char *) cpr_malloc(MAX_SIP_HEADER_LENGTH); - if (!header) { - return NULL; - } - - if (!call_info_p) { - cpr_free(header); - return NULL; - } - - snprintf(header, MAX_SIP_HEADER_LENGTH, "<%s", URN_REMOTECC); - - switch (call_info_p->type) { - case CC_FEAT_HOLD: - case CC_FEAT_RESUME: - if (call_info_p->type == CC_FEAT_HOLD) { - sstrncat(header, SIP_CI_HOLD_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - } else { - sstrncat(header, SIP_CI_RESUME_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - } - sstrncat(header, ">", MAX_SIP_HEADER_LENGTH - strlen(header)); - - switch (call_info_p->data.hold_resume_reason) { - case CC_REASON_NONE: - case CC_REASON_INTERNAL: - case CC_REASON_SWAP: - break; - case CC_REASON_XFER: - sstrncat(header, "; reason= ", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, SIP_CI_HOLD_REASON_XFER, - MAX_SIP_HEADER_LENGTH - strlen(header)); - break; - case CC_REASON_CONF: - sstrncat(header, "; reason= ", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, SIP_CI_HOLD_REASON_CONF, - MAX_SIP_HEADER_LENGTH - strlen(header)); - break; - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "unsupported hold_resume_reason\n", - fname); - cpr_free(header); - return NULL; - } - - /* Add swap information */ - if (call_info_p->data.call_info_feat_data.swap == TRUE) { - sstrncat(header, "; operation= swap", - MAX_SIP_HEADER_LENGTH - strlen(header)); - } - - if (call_info_p->data.call_info_feat_data.protect == TRUE) { - sstrncat(header, "; protect= true; noholdreversion", - MAX_SIP_HEADER_LENGTH - strlen(header)); - } - - break; - - case CC_FEAT_INIT_CALL: - /* Add global call id here */ - if (call_info_p->data.initcall.gcid[0] != '\0') { - sstrncat(header, "callinfo>; gci= ", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, call_info_p->data.initcall.gcid, - MAX_SIP_HEADER_LENGTH - strlen(header)); - } else { - cpr_free(header); - return NULL; - } - /* Add the monitor mode here if it exists */ - if (call_info_p->data.initcall.monitor_mode != CC_MONITOR_NONE) { - sstrncat(header, "; mode=", - MAX_SIP_HEADER_LENGTH - strlen(header)); - - switch (call_info_p->data.initcall.monitor_mode) { - - case CC_MONITOR_SILENT : - sstrncat(header, SIP_CI_SILENT_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - break; - - case CC_MONITOR_COACHING : - sstrncat(header, SIP_CI_COACHING_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - break; - - default: - break; - } - } - break; - - case CC_FEAT_TOGGLE_TO_WHISPER_COACHING: - sstrncat(header, "callinfo>", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, "; mode=", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, SIP_CI_COACHING_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - - break; - - case CC_FEAT_TOGGLE_TO_SILENT_MONITORING: - sstrncat(header, "callinfo>", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, "; mode=", - MAX_SIP_HEADER_LENGTH - strlen(header)); - sstrncat(header, SIP_CI_SILENT_STR, - MAX_SIP_HEADER_LENGTH - strlen(header)); - - break; - - default: - cpr_free(header); - return NULL; - } - - - if (misc_parms_p) { - sstrncat(header, misc_parms_p, - MAX_SIP_HEADER_LENGTH - strlen(header)); - } - sstrncat(header, "\0", MAX_SIP_HEADER_LENGTH - strlen(header)); - return (header); -} - -/* - * ccsip_free_call_info_header - * - * Description: - * - * Frees the memory allocated to a call info structure. - */ -void -ccsip_free_call_info_header (cc_call_info_t *call_info_p) -{ - if(call_info_p->type == CC_FEAT_CALLINFO) { - - } - cpr_free(call_info_p); -} - -/* - * ccsip_process_call_info_header - * - * Description: - * - * Checks if there is a call info header in the provided SIP message. If there is, - * the call info in the CCB is cleared and the new call info is parsed into the - * CCB call info structure. - */ -void -ccsip_process_call_info_header (sipMessage_t *request_p, ccsipCCB_t *ccb) -{ - char *call_info_hdrs[MAX_CALL_INFO_HEADERS]; - uint16_t num_call_info_headers; - int i = 0; - - if (!ccb) { - return; - } - - if (ccb->in_call_info) { - ccsip_free_call_info_header(ccb->in_call_info); - ccb->in_call_info = NULL; - } - - if (!request_p) { - return; - } - - memset(call_info_hdrs, 0, MAX_CALL_INFO_HEADERS * sizeof(char *)); - - num_call_info_headers = sippmh_get_num_particular_headers(request_p, - SIP_HEADER_CALL_INFO, - SIP_HEADER_CALL_INFO, - call_info_hdrs, - MAX_CALL_INFO_HEADERS); - - if (num_call_info_headers > 0) { - ccb->in_call_info = (cc_call_info_t *) - cpr_calloc(1, sizeof(cc_call_info_t)); - if (ccb->in_call_info) { - - ccb->in_call_info->data.call_info_feat_data.feature_flag = 0; - - // Parse each Call-Info header - for (i = 0; i < MAX_CALL_INFO_HEADERS; i++) { - if (call_info_hdrs[i]) { - ccsip_decode_call_info_hdr(call_info_hdrs[i], ccb->in_call_info); - } - } - - } else { - ccb->in_call_info = NULL; - } - } - -} - -/* - * ccsip_store_call_info - * - * Description: Used for storing call_info received from GSM - * - * Store specified call info structure in ccb. - */ -void -ccsip_store_call_info (cc_call_info_t *call_info_p, ccsipCCB_t *ccb) -{ - if (!ccb) { - return; - } - - if (ccb->out_call_info) { - ccsip_free_call_info_header(ccb->out_call_info); - ccb->out_call_info = NULL; - } - - if (call_info_p->type != CC_FEAT_NONE) { - ccb->out_call_info = (cc_call_info_t *) - cpr_malloc(sizeof(cc_call_info_t)); - if (ccb->out_call_info) { - memcpy(ccb->out_call_info, call_info_p, sizeof(cc_call_info_t)); - } else { - ccb->out_call_info = NULL; - } - } -} diff --git a/libs/sipcc/core/sipstack/ccsip_cc.c b/libs/sipcc/core/sipstack/ccsip_cc.c deleted file mode 100755 index 0a97efcc8b..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_cc.c +++ /dev/null @@ -1,305 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "ccapi.h" -#include "string_lib.h" -#include "ccsip_pmh.h" -#include "ccsip_messaging.h" - -/* - * Function: sip_cc_mv_msg_body_to_cc_msg - * - * Parameters: cc_msg - pointer to cc_msgbody_info structure to - * move the content from the SIP body msg. to. - * sip_msg - pointer to sipMessage_t structure of the source - * body. - * - * Description: This routine moves the body parts from sipMessage_t to - * CCAPI body msg. Once the content is moved, - * the all pointers from the sipMessage_t structure, - * will be NULL so that they are not own by SIP stack. - * The destination of the msg. needs to free the - * memory for of the parts. - * - * Returns: N/A - * - */ -void sip_cc_mv_msg_body_to_cc_msg (cc_msgbody_info_t *cc_msg, - sipMessage_t *sip_msg) -{ - int i; - uint32_t num_parts = 0; - cc_msgbody_t *part; - - if (cc_msg == NULL) { - /* destination to move msg. to */ - return; - } - if (sip_msg == NULL) { - /* No SIP message to move from, set number of part to zero */ - cc_msg->num_parts = 0; - return; - } - - part = &cc_msg->parts[0]; - for (i = 0; (i < sip_msg->num_body_parts) && - (i < CC_MAX_BODY_PARTS); i++) { - if ((sip_msg->mesg_body[i].msgBody != NULL) && - (sip_msg->mesg_body[i].msgLength)) { - /* Body */ - part->body = sip_msg->mesg_body[i].msgBody; - part->body_length = sip_msg->mesg_body[i].msgLength; - sip_msg->mesg_body[i].msgBody = NULL; - - /* Content type */ - part->content_type = - sip2cctype(sip_msg->mesg_body[i].msgContentTypeValue); - /* Disposition */ - part->content_disposition.disposition = - sip2ccdisp(sip_msg->mesg_body[i].msgContentDisp); - part->content_disposition.required_handling = - sip_msg->mesg_body[i].msgRequiredHandling; - /* Content ID */ - part->content_id = sip_msg->mesg_body[i].msgContentId; - sip_msg->mesg_body[i].msgContentId = NULL; - - /* Next part */ - part++; - num_parts++; - } - } - /* Set the number of parts */ - cc_msg->num_parts = num_parts; -} - -/* - * Function: sip_cc_create_cc_msg_body_from_sip_msg - * - * Parameters: cc_msg - pointer to cc_msgbody_info structure to - * store the content of the SIP body msg. - * sip_msg - pointer to sipMessage_t structure of the source - * body. - * - * Description: This routine creates the cc_msgbody_info_t content - * from the SIP message. The original msg. body in the - * SIP message remains in the SIP message. - * - * Returns: TRUE - success - * FALSE - fail. - * - */ -boolean sip_cc_create_cc_msg_body_from_sip_msg (cc_msgbody_info_t *cc_msg, - sipMessage_t *sip_msg) -{ - int i, len; - uint32_t num_parts = 0; - cc_msgbody_t *part; - boolean status = TRUE; - - if (cc_msg == NULL) { - /* destination to move msg. to */ - return (FALSE); - } - - if (sip_msg == NULL) { - /* No SIP message to move from, set number of part to zero */ - cc_msg->num_parts = 0; - return (FALSE); - } - - memset(cc_msg, 0, sizeof(cc_msgbody_info_t)); - part = &cc_msg->parts[0]; - for (i = 0; (i < sip_msg->num_body_parts) && - (i < CC_MAX_BODY_PARTS) ; i++) { - if ((sip_msg->mesg_body[i].msgBody != NULL) && - (sip_msg->mesg_body[i].msgLength)) { - /* Body */ - part->body = (char *) cpr_malloc(sip_msg->mesg_body[i].msgLength); - if (part->body != NULL) { - part->body_length = sip_msg->mesg_body[i].msgLength; - memcpy(part->body, - sip_msg->mesg_body[i].msgBody, - sip_msg->mesg_body[i].msgLength); - } else { - /* Unable to allocate memory for msg. body */ - status = FALSE; - break; - } - - /* Content type */ - part->content_type = - sip2cctype(sip_msg->mesg_body[i].msgContentTypeValue); - /* Disposition */ - part->content_disposition.disposition = - sip2ccdisp(sip_msg->mesg_body[i].msgContentDisp); - part->content_disposition.required_handling = - sip_msg->mesg_body[i].msgRequiredHandling; - - /* Content ID */ - if (sip_msg->mesg_body[i].msgContentId != NULL) { - /* Get length of the msgContentID with NULL */ - len = strlen(sip_msg->mesg_body[i].msgContentId) + 1; - part->content_id = (char *) cpr_malloc(len); - if (part->content_id != NULL) { - memcpy(part->content_id, - sip_msg->mesg_body[i].msgContentId, - len); - } else { - /* Unable to allocate allocate memory for content ID */ - status = FALSE; - break; - } - } else { - /* No content ID */ - part->content_id = NULL; - } - /* Next part */ - part++; - num_parts++; - } - } - /* Set the number of parts */ - cc_msg->num_parts = num_parts; - - if (!status) { - /* - * Faied for some reason, free the resources that mighe be - * created before failure - */ - cc_free_msg_body_parts(cc_msg); - } - return (status); -} - -void sip_cc_setup (callid_t call_id, line_t line, - string_t calling_name, string_t calling_number, string_t alt_calling_number, - boolean display_calling_number, - string_t called_name, string_t called_number, - boolean display_called_number, - string_t orig_called_name, string_t orig_called_number, - string_t last_redirect_name, string_t last_redirect_number, - cc_call_type_e call_type, - cc_alerting_type alert_info, - vcm_ring_mode_t alerting_ring, - vcm_tones_t alerting_tone, cc_call_info_t *call_info_p, - boolean replaces, string_t recv_info_list, sipMessage_t *sip_msg) -{ - cc_caller_id_t caller_id; - cc_msgbody_info_t cc_body_info; - - caller_id.calling_name = calling_name; - caller_id.calling_number = calling_number; - caller_id.alt_calling_number = alt_calling_number; - caller_id.display_calling_number = display_calling_number; - caller_id.called_name = called_name; - caller_id.called_number = called_number; - caller_id.display_called_number = display_called_number; - caller_id.last_redirect_name = last_redirect_name; - caller_id.last_redirect_number = last_redirect_number; - caller_id.orig_called_name = orig_called_name; - caller_id.orig_called_number = orig_called_number; - caller_id.orig_rpid_number = strlib_empty(); - caller_id.call_type = call_type; - - /* Move the SIP body parts to the CCAPI msg. body information block */ - sip_cc_mv_msg_body_to_cc_msg(&cc_body_info, sip_msg); - -// Check with CraigB - cc_setup(CC_SRC_SIP, call_id, line, &caller_id, alert_info, - alerting_ring, alerting_tone, NULL, call_info_p, replaces, - recv_info_list, &cc_body_info); -} - - -#ifdef REMOVED_UNUSED_FUNCTION -void sip_cc_setup_ack (callid_t call_id, line_t line, - cc_msgbody_info_t *msg_body) -{ - cc_setup_ack(CC_SRC_SIP, call_id, line, NULL, msg_body); -} -#endif - -void sip_cc_proceeding (callid_t call_id, line_t line) -{ - cc_proceeding(CC_SRC_SIP, call_id, line, NULL); -} - -void sip_cc_alerting (callid_t call_id, line_t line, - sipMessage_t *sip_msg, int inband) -{ - cc_msgbody_info_t cc_body_info; - - /* Move the SIP body parts to the CCAPI msg. body information block */ - sip_cc_mv_msg_body_to_cc_msg(&cc_body_info, sip_msg); - - cc_alerting(CC_SRC_SIP, call_id, line, NULL, &cc_body_info, - (boolean)inband); -} - - -void sip_cc_connected (callid_t call_id, line_t line, string_t recv_info_list, sipMessage_t *sip_msg) -{ - cc_msgbody_info_t cc_body_info; - - /* Move the SIP body parts to the CCAPI msg. body information block */ - sip_cc_mv_msg_body_to_cc_msg(&cc_body_info, sip_msg); - - cc_connected(CC_SRC_SIP, call_id, line, NULL, recv_info_list, &cc_body_info); -} - - -void sip_cc_connected_ack (callid_t call_id, line_t line, - sipMessage_t *sip_msg) -{ - cc_msgbody_info_t cc_body_info; - - /* Move the SIP body parts to the CCAPI msg. body information block */ - sip_cc_mv_msg_body_to_cc_msg(&cc_body_info, sip_msg); - - cc_connected_ack(CC_SRC_SIP, call_id, line, NULL, &cc_body_info); -} - - -void sip_cc_release (callid_t call_id, line_t line, cc_causes_t cause, - const char *dialstring) -{ - cc_release(CC_SRC_SIP, call_id, line, cause, dialstring, NULL); -} - - -void sip_cc_release_complete (callid_t call_id, line_t line, cc_causes_t cause) -{ - cc_release_complete(CC_SRC_SIP, call_id, line, cause, NULL); -} - - -void sip_cc_feature (callid_t call_id, line_t line, cc_features_t feature, void *data) -{ - cc_feature(CC_SRC_SIP, call_id, line, feature, (cc_feature_data_t *)data); -} - - -void sip_cc_feature_ack (callid_t call_id, line_t line, cc_features_t feature, - void *data, cc_causes_t cause) -{ - cc_feature_ack(CC_SRC_SIP, call_id, line, feature, (cc_feature_data_t *)data, cause); -} - - -void sip_cc_mwi (callid_t call_id, line_t line, boolean on, int type, - int newCount, int oldCount, int hpNewCount, int hpOldCount) -{ - cc_mwi(CC_SRC_SIP, call_id, line, on, type, newCount, oldCount, hpNewCount, hpOldCount); -} - -void sip_cc_options (callid_t call_id, line_t line, sipMessage_t *pSipMessage) -{ - cc_options_sdp_req(CC_SRC_SIP, call_id, line, pSipMessage); -} - -void sip_cc_audit (callid_t call_id, line_t line, boolean apply_ringout) -{ - cc_audit_sdp_req(CC_SRC_SIP, call_id, line, apply_ringout); -} diff --git a/libs/sipcc/core/sipstack/ccsip_common_util.c b/libs/sipcc/core/sipstack/ccsip_common_util.c deleted file mode 100644 index 170bd98e4d..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_common_util.c +++ /dev/null @@ -1,260 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_in.h" -#include "ccsip_common_cb.h" -#include "sip_common_transport.h" -#include "prot_configmgr.h" -#include "ccsip_register.h" -#include "util_string.h" - -/** - * This function will set dest ip and port in common control block of SCB and PCB. - * - * @param[in] cb_p - pointer to the header control block. - * - * @return none - * - * @pre (cb_p != NULL) - */ -void ccsip_common_util_set_dest_ipaddr_port (ccsip_common_cb_t *cb_p) -{ - char addr[MAX_IPADDR_STR_LEN]; - - if (cb_p->dest_sip_addr.type == CPR_IP_ADDR_INVALID) { - sipTransportGetPrimServerAddress(cb_p->dn_line, addr); - dns_error_code = sipTransportGetServerAddrPort(addr, - &cb_p->dest_sip_addr, - (uint16_t *)&cb_p->dest_sip_port, - &cb_p->SRVhandle, - FALSE); - if (dns_error_code == 0) { - util_ntohl(&(cb_p->dest_sip_addr), &(cb_p->dest_sip_addr)); - } else { - sipTransportGetServerIPAddr(&(cb_p->dest_sip_addr), cb_p->dn_line); - } - - cb_p->dest_sip_port = ((dns_error_code == 0) && (cb_p->dest_sip_port)) ? - ntohs((uint16_t)cb_p->dest_sip_port) : - (sipTransportGetPrimServerPort(cb_p->dn_line)); - } -} - -/** - * This function will set source ip in common control block of SCB and PCB. - * - * @param[in] cb_p - pointer to the header control block. - * - * @return none - * - * @pre (cb_p != NULL) - */ -void ccsip_common_util_set_src_ipaddr (ccsip_common_cb_t *cb_p) -{ - int nat_enable = 0; - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&(cb_p->src_addr)); - } else { - sip_config_get_nat_ipaddr(&(cb_p->src_addr)); - } -} - -/* - * This function will set retry settings in common control block of SCB and PCB. - * - * Description: Based on transport used, determines the value to be - * used to set either TimerE or TimerF - * 1. For reliable tranport: we SHOULD start timer F (= 64*T1), - * no retransmits are required. - * 2. To prevent retransmits for TCP/TLS, we set scbp->retx_counter - * to Max value. - * 3. For unreliable tranport: we SHOULD start timer E (= T1), - * retransmits are required. - * This routine must only be invoked before sending a request for - * the first time with valid args. - * - * @param[in] cb_p - pointer to header control block. - * @param[out] timeout_p - returns the value to be used to set a timer. - * - * @return none - * - * @pre (cb_p != NULL) and (timeout_p != NULL) - */ -void ccsip_common_util_set_retry_settings (ccsip_common_cb_t *cb_p, int *timeout_p) -{ - uint32_t max_retx = 0; - const char *transport = NULL; - - *timeout_p = 0; - cb_p->retx_flag = TRUE; - config_get_value(CFGID_TIMER_T1, timeout_p, sizeof(*timeout_p)); - - transport = sipTransportGetTransportType(cb_p->dn_line, TRUE, NULL); - if (transport) { - if (strcmp(transport, "UDP") == 0) { - cb_p->retx_counter = 0; - } else { - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - cb_p->retx_counter = max_retx; - (*timeout_p) = (64 * (*timeout_p)); - } - } -} - - -/** - * This function will generate authorization header value. - * - * @param[in] pSipMessage - pointer to sipMessage_t - * @param[in] cb_p - pointer to header control block. - * @param[in] rsp_method - response method - * @param[in] response_code - response code - * @param[in] uri - uri - * - * @return TRUE if it is successful. - * - * @pre (cb_p != NULL) and (pSipMessage != NULL) and (rsp_method != NULL) and (uri != NULL) - */ -boolean ccsip_common_util_generate_auth (sipMessage_t *pSipMessage, ccsip_common_cb_t *cb_p, - const char *rsp_method, int response_code, char *uri) -{ - static const char fname[] = "ccsip_common_util_generate_auth"; - const char *authenticate = NULL; - credentials_t credentials; - sip_authen_t *sip_authen = NULL; - char *author_str = NULL; - - if (!(cb_p->authen.cred_type & CRED_LINE)) { - cb_p->authen.cred_type |= CRED_LINE; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "configured credentials for line %d not accepeted. Verify the config\n", - fname, cb_p->dn_line); - return FALSE; - } - - /* - * get authname & password from configuration. - */ - cred_get_line_credentials(cb_p->dn_line, &credentials, - sizeof(credentials.id), - sizeof(credentials.pw)); - /* - * Extract Authenticate/Proxy-Authenticate header from the message. - */ - authenticate = sippmh_get_header_val(pSipMessage, AUTH_HDR(response_code), NULL); - if (authenticate == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%s header missing in the %d response\n", - fname, AUTH_HDR_STR(response_code), response_code); - return FALSE; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authenticate header %s = %s\n", DEB_F_PREFIX_ARGS(SIP_AUTH, fname), AUTH_HDR_STR(response_code), authenticate); - /* - * Parse Authenticate header. - */ - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%s:%s header formatted incorrectly in the %d response\n", - fname, AUTH_HDR_STR(response_code), authenticate, response_code); - return FALSE; - } - cb_p->authen.new_flag = FALSE; - cb_p->authen.cnonce[0] = '\0'; - /* - * Generate Authorization string. - */ - if (sipSPIGenerateAuthorizationResponse(sip_authen, - uri, - rsp_method, - credentials.id, - credentials.pw, - &author_str, - &(cb_p->authen.nc_count), - NULL) == TRUE) { - - if (cb_p->authen.authorization != NULL) { - cpr_free(cb_p->authen.authorization); - cb_p->authen.authorization = NULL; - } - - if (cb_p->authen.sip_authen != NULL) { - sippmh_free_authen(cb_p->authen.sip_authen); - cb_p->authen.sip_authen = NULL; - } - - cb_p->authen.authorization = (char *) - cpr_malloc(strlen(author_str) * sizeof(char) + 1); - - /* - * Cache the Authorization header so that it can be - * used for later requests - */ - if (cb_p->authen.authorization != NULL) { - memcpy(cb_p->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - cb_p->authen.status_code = response_code; - cb_p->authen.sip_authen = sip_authen; - } - - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Authorization header build unsuccessful\n", fname); - sippmh_free_authen(sip_authen); - return FALSE; - } - return TRUE; -} - -/** - * This function will extract user part from sip From header. - * - * @param[in] pSipMessage - pointer to sipMessage_t - * @param[out] entity - pointer to user buffer. - * - * @return void - * - * @pre (pSipMessage != NULL) and (entity != NULL) - */ -void ccsip_util_get_from_entity (sipMessage_t *pSipMessage, char *entity) -{ - const char *sip_from = NULL; - sipLocation_t *from_loc = NULL; - - sip_from = sippmh_get_cached_header_val(pSipMessage, FROM); - if (sip_from != NULL) { - from_loc = sippmh_parse_from_or_to((char *) sip_from, TRUE); - if ((from_loc) && (from_loc->genUrl->schema == URL_TYPE_SIP) && (from_loc->genUrl->u.sipUrl->user)) { - sstrncpy(entity, from_loc->genUrl->u.sipUrl->user, CC_MAX_DIALSTRING_LEN); - } - } - if (from_loc) { - sippmh_free_location(from_loc); - } -} - -/** - * This function will extract user part from sip URL. - * - * @param[in] url - pointer to URL - * @param[out] user - pointer to user buffer. - * - * @return void - * - * @pre (url != NULL) and (user != NULL) - */ -void ccsip_util_extract_user (char *url, char *user) -{ - genUrl_t *genUrl = NULL; - - genUrl = sippmh_parse_url(url, TRUE); - if (genUrl != NULL) { - sstrncpy(user, genUrl->u.sipUrl->user, CC_MAX_DIALSTRING_LEN); - sippmh_genurl_free(genUrl); - } -} diff --git a/libs/sipcc/core/sipstack/ccsip_core.c b/libs/sipcc/core/sipstack/ccsip_core.c deleted file mode 100644 index e0807b30f0..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_core.c +++ /dev/null @@ -1,12298 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_in.h" -#include "cpr_rand.h" - -#include "ccsip_core.h" -#include "text_strings.h" -#include "util_string.h" -#include "ccsip_messaging.h" -#include "ccsip_platform_udp.h" -#include "ccsip_platform.h" -#include "ccsip_macros.h" -#include "ccsip_pmh.h" -#include "ccsip_spi_utils.h" -#include "phone_debug.h" -#include "ccsip_register.h" -#include "ccsip_credentials.h" -#include "ccsip_callinfo.h" -#include "ccsip_cc.h" -#include "ccsip_task.h" -#include "config.h" -#include "string_lib.h" -#include "dialplan.h" -#include "fsm.h" -#include "sip_interface_regmgr.h" -#include "ccsip_subsmanager.h" -#include "ccsip_publish.h" -#include "sdp.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "rtp_defs.h" -#include "uiapi.h" -#include "text_strings.h" -#include "platform_api.h" -#include "misc_util.h" - - -/* - * OS specific hooks - */ - -extern void sip_platform_handle_service_control_notify(sipServiceControl_t *scp); -extern uint32_t IPNameCk(char *name, char *addr_error); - - -#define ADD_TO_ARP_CACHE(dest_sip_addr) -#define UNBIND_UDP_ICMP_HANDLER(udp_id) - - -extern boolean sip_mode_quiet; - -extern void ccsip_debug_init(void); -extern void shutdownCCAck(int action); -void ccsip_remove_wlan_classifiers(void); - -#define USECALLMANAGER_LEN 14 -/* - * Needed to parse the alert-info header - */ -//CPR TODO: need reference for -extern const char *tone_names[]; -const char *ring_names[] = { - "Bellcore-dr1", - "Bellcore-dr2", - "Bellcore-dr3", - "Bellcore-dr4", - "Bellcore-dr5" -}; - - -/* Forward function declarations */ -static int sip_sm_request_check_and_store(ccsipCCB_t *ccb, sipMessage_t *request, - sipMethod_t request_method, - boolean midcall, - uint16_t *request_check_reason_code, - char *request_check_reason_phrase, - boolean store_invite); -void sip_sm_update_to_from_on_callsetup_finalresponse(ccsipCCB_t *ccb, - sipMessage_t *response); -void sip_sm_update_contact_recordroute(ccsipCCB_t *ccb, sipMessage_t *response, - int response_code, boolean midcall); -static boolean ccsip_set_replace_info(ccsipCCB_t *ccb, cc_setup_t * setup); -static boolean ccsip_handle_cc_select_event(sipSMEvent_t *sip_sm_event); -static boolean ccsip_handle_cc_b2bjoin_event(sipSMEvent_t *sip_sm_event); -static void ccsip_set_join_info(ccsipCCB_t *ccb, cc_setup_t * setup); -static boolean ccsip_get_join_info(ccsipCCB_t *ccb, sipMessage_t *request); -static char *ccsip_find_preallocated_sip_call_id(line_t dn_line); -static void ccsip_free_preallocated_sip_call_id(line_t dn_line); -static boolean ccsip_handle_cc_hook_event(sipSMEvent_t *sip_sm_event); - -extern cc_int32_t dnsGetHostByName (const char *hname, cpr_ip_addr_t *ipaddr_ptr, cc_int32_t timeout, cc_int32_t retries); - -//CPR TODO: need reference for -extern char *Basic_is_phone_forwarded(line_t line); - -/* External Declarations */ -extern sipPlatformUITimer_t sipPlatformUISMTimers[]; -extern sipGlobal_t sip; -extern sipCallHistory_t gCallHistory[]; - -/* Globals */ -int dns_error_code; // Global DNS error code value -uint16_t server_caps = 0; // Server capabilities -boolean sip_reg_all_failed; - -ccsipGlobInfo_t gGlobInfo; -sipCallHistory_t gCallHistory[MAX_TEL_LINES]; - -typedef struct { - int16_t sipValidEvent; - int16_t actionIndex; -} subStateEvent_t; - -#define MAX_STATE_EVENTS 13 -typedef struct { - int16_t sipState; - subStateEvent_t validEvent[MAX_STATE_EVENTS]; -} sipSMfunctable_t; - -static char *preAllocatedSipCallID[MAX_REG_LINES] = { NULL }; -static char *preAllocatedTag[MAX_REG_LINES] = { NULL }; -boolean g_disable_mass_reg_debug_print = FALSE; - -static const sipSMfunctable_t g_sip_table[SIP_STATE_END - SIP_STATE_BASE + 1] = -{ - /* - * SIP_STATE_IDLE - */ - { SIP_STATE_IDLE, - { - /* E_SIP_INVITE ccsip_handle_idle_ev_sip_invite, */ - {E_SIP_INVITE, H_IDLE_EV_SIP_INVITE}, - /* E_CC_SETUP ccsip_handle_idle_ev_cc_setup, */ - {E_CC_SETUP, H_IDLE_EV_CC_SETUP}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE ccsip_handle_default_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_EV_CC_FEATURE}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_SENT_INVITE - */ - {SIP_STATE_SENT_INVITE, - { - /* E_SIP_1xx ccsip_handle_sentinvite_ev_sip_1xx, */ - {E_SIP_1xx, H_SENTINVITE_EV_SIP_1XX}, - /* E_SIP_2xx ccsip_handle_sentinvite_ev_sip_2xx, */ - {E_SIP_2xx, H_SENTINVITE_EV_SIP_2XX}, - /* E_SIP_3xx ccsip_handle_sentinvite_ev_sip_3xx */ - {E_SIP_3xx, H_SENTINVITE_EV_SIP_3XX}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentinvite_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTINVITE_EV_SIP_FXX}, - /* E_CC_RELEASE ccsip_handle_disconnect_local_early */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL_EARLY}, - /* E_SIP_INV_EXPIRES_TIMER ccsip_handle_disconnect_local_early */ - {E_SIP_INV_EXPIRES_TIMER, H_DISCONNECT_LOCAL_EARLY}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - /* - * SIP_STATE_SENT_INVITE_CONNECTED - */ - {SIP_STATE_SENT_INVITE_CONNECTED, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_CONNECTED_ACK ccsip_handle_sentinviteconnected_ev_cc_connected_ack, */ - {E_CC_CONNECTED_ACK, H_SENTINVITECONNECTED_EV_CC_CONNECTED_ACK}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RECV_INVITE - */ - {SIP_STATE_RECV_INVITE, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_CANCEL ccsip_handle_disconnect_remote, */ - {E_SIP_CANCEL, H_DISCONNECT_REMOTE}, - /* E_CC_SETUP_ACK ccsip_handle_recvinvite_ev_cc_setup_ack, */ - {E_CC_SETUP_ACK, H_RECVINVITE_EV_CC_SETUP_ACK}, - /* E_CC_PROCEEDING ccsip_handle_recvinvite_ev_cc_proceeding, */ - {E_CC_PROCEEDING, H_RECVINVITE_EV_CC_PROCEEDING}, - /* E_CC_ALERTING ccsip_handle_recvinvite_ev_cc_alerting, */ - {E_CC_ALERTING, H_RECVINVITE_EV_CC_ALERTING}, - /* E_CC_CONNECTED ccsip_handle_recvinvite_ev_cc_connected, */ - {E_CC_CONNECTED, H_RECVINVITE_EV_CC_CONNECTED}, - /* E_CC_RELEASE ccsip_handle_disconnect_local_unanswered, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL_UNANSWERED}, - /* E_SIP_INV_LOCALEXPIRES_TIMER ccsip_handle_localexpires_timer */ - {E_SIP_INV_LOCALEXPIRES_TIMER, H_HANDLE_LOCALEXPIRES_TIMER}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY} - - /* Initializing any events which are not used to Invalid events */ - } - }, - - /* - * SIP_STATE_RECV_INVITE_PROCEEDING - */ - {SIP_STATE_RECV_INVITE_PROCEEDING, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_CANCEL ccsip_handle_disconnect_remote */ - {E_SIP_CANCEL, H_DISCONNECT_REMOTE}, - /* E_CC_ALERTING ccsip_handle_recvinvite_ev_cc_alerting, */ - {E_CC_ALERTING, H_RECVINVITE_EV_CC_ALERTING}, - /* E_CC_CONNECTED ccsip_handle_recvinvite_ev_cc_connected, */ - {E_CC_CONNECTED, H_RECVINVITE_EV_CC_CONNECTED}, - /* E_CC_RELEASE ccsip_handle_disconnect_local_unanswered, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL_UNANSWERED}, - /* E_SIP_INV_LOCALEXPIRES_TIMER ccsip_handle_localexpires_timer */ - {E_SIP_INV_LOCALEXPIRES_TIMER, H_HANDLE_LOCALEXPIRES_TIMER}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RECV_INVITE_ALERTING - */ - {SIP_STATE_RECV_INVITE_ALERTING, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_CANCEL ccsip_handle_disconnect_remote, */ - {E_SIP_CANCEL, H_DISCONNECT_REMOTE}, - /* E_CC_CONNECTED ccsip_handle_recvinvite_ev_cc_connected, */ - {E_CC_CONNECTED, H_RECVINVITE_EV_CC_CONNECTED}, - /* E_CC_RELEASE ccsip_handle_disconnect_local_unanswered, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL_UNANSWERED}, - /* E_SIP_INV_LOCALEXPIRES_TIMER ccsip_handle_localexpires_timer */ - {E_SIP_INV_LOCALEXPIRES_TIMER, H_HANDLE_LOCALEXPIRES_TIMER}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_SIP_2xx ccsip_handle_recvinvite_ev_sip_2xx */ - {E_SIP_2xx, H_RECVINVITE_EV_SIP_2XX}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentinvite_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTINVITE_EV_SIP_FXX}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RECV_INVITE_CONNECTED - */ - {SIP_STATE_RECV_INVITE_CONNECTED, - { - /* E_SIP_ACK ccsip_handle_recvinvite_ev_sip_ack, */ - {E_SIP_ACK, H_RECVINVITE_EV_SIP_ACK}, - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_SIP_UPDATE ccsip_handle_early_ev_sip_update */ - {E_SIP_UPDATE, H_EARLY_EV_SIP_UPDATE}, - /* E_SIP_UPDATE_RESPONSE ccsip_handle_early_ev_sip_update_response */ - {E_SIP_UPDATE_RESPONSE, H_EARLY_EV_SIP_UPDATE_RESPONSE}, - /* E_CC_UPDATE ccsip_handle_early_ev_cc_feature */ - {E_CC_FEATURE, H_EARLY_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_early_ev_cc_feature_ack */ - {E_CC_FEATURE_ACK, H_EARLY_EV_CC_FEATURE_ACK}, - /* E_SIP_INV_EXPIRES_TIMER ccsip_handle_recvinvite_ev_expires_timer */ - {E_SIP_INV_EXPIRES_TIMER, H_RECVINVITE_SENTOK_NO_SIP_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - /* - * SIP_STATE_ACTIVE - */ - {SIP_STATE_ACTIVE, - { - /* E_SIP_INVITE ccsip_handle_active_ev_sip_invite, */ - {E_SIP_INVITE, H_ACTIVE_EV_SIP_INVITE}, - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_2xx ccsip_handle_active_2xx, */ - {E_SIP_2xx, H_ACTIVE_2xx}, - /* E_SIP_REFER ccsip_handle_refer_sip_message, */ - {E_SIP_REFER, H_REFER_SIP_MESSAGE}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentinvite_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTINVITE_EV_SIP_FXX}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_CC_FEATURE ccsip_handle_active_ev_cc_feature, */ - {E_CC_FEATURE, H_ACTIVE_EV_CC_FEATURE}, - /* E_CC_FEATURE_ACK ccsip_handle_active_ev_cc_feature_ack, */ - {E_CC_FEATURE_ACK, H_ACTIVE_EV_CC_FEATURE_ACK}, - /* E_SIP_UPDATE ccsip_handle_active_ev_sip_update */ - {E_SIP_UPDATE, H_CONFIRM_EV_SIP_UPDATE}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_SENT_MIDCALL_INVITE - */ - {SIP_STATE_SENT_MIDCALL_INVITE, - { - /* E_SIP_INVITE ccsip_handle_active_ev_sip_invite, */ - {E_SIP_INVITE, H_ACTIVE_EV_SIP_INVITE}, - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_SIP_2xx ccsip_handle_sentinvite_midcall_ev_sip_2xx, */ - {E_SIP_2xx, H_SENTINVITE_MIDCALL_EV_SIP_2XX}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentinvite_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTINVITE_EV_SIP_FXX}, - /* E_SIP_INV_EXPIRES_TIMER ccsip_handle_disconnect_local */ - {E_SIP_INV_EXPIRES_TIMER, H_DISCONNECT_LOCAL}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_CC_FEATURE ccsip_handle_sentinvite_midcall_ev_cc_feature, */ - {E_CC_FEATURE, H_SENTINVITE_MIDCALL_EV_CC_FEATURE}, - /* E_SIP_UPDATE ccsip_handle_active_ev_sip_update */ - {E_SIP_UPDATE, H_CONFIRM_EV_SIP_UPDATE}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING - */ - {SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_RELEASE ccsip_handle_disconnect_media_change, */ - {E_CC_RELEASE, H_DISCONNECT_MEDIA_CHANGE}, - /* E_CC_FEATURE_ACK ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack, */ - {E_CC_FEATURE_ACK, H_RECVMIDCALLINVITE_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE, ccsip_handle_default_recvreq_ack_pending_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - /* - * SIP_STATE_RECV_MIDCALLINVITE_SIPACK_PENDING - */ - {SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING, - { - /* E_SIP_ACK ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack, */ - {E_SIP_ACK, H_RECVMIDCALLINVITE_SIPACKPENDING_EV_SIP_ACK}, - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_RELEASE ccsip_handle_disconnect_local, */ - {E_CC_RELEASE, H_DISCONNECT_LOCAL}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE, ccsip_handle_default_recvreq_ack_pending_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - /* - * SIP_STATE_RELEASE - */ - {SIP_STATE_RELEASE, - { - /* E_SIP_BYE, ccsip_handle_release_ev_sip_bye */ - {E_SIP_BYE, H_BYE_RELEASE}, - /* E_SIP_ACK ccsip_handle_recv_error_response_ev_sip_ack, */ - {E_SIP_ACK, H_RECV_ERR_EV_SIP_ACK}, - /* E_SIP_INVITE ccsip_handle_sentbye_recvd_invite, */ - {E_SIP_INVITE, H_SENTBYE_EV_SIP_INVITE}, - /* E_SIP_1xx ccsip_handle_sentbye_ev_sip_1xx, */ - {E_SIP_1xx, H_SENTBYE_EV_SIP_1XX}, - /* E_SIP_2xx ccsip_handle_sentbye_ev_sip_2xx, */ - {E_SIP_2xx, H_SENTBYE_EV_SIP_2XX}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentbye_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTBYE_EV_SIP_FXX}, - /* E_SIP_SUPERVISION_DISCONNECT_TIMER - * ccsip_handle_sendbye_ev_supervision_disconnect, */ - {E_SIP_SUPERVISION_DISCONNECT_TIMER, H_SENTBYE_SUPERVISION_DISCONNECT_TIMER}, - /* E_CC_RELEASE_COMPLETE, ccsip_handle_release_complete, */ - {E_CC_RELEASE_COMPLETE, H_RELEASE_COMPLETE}, - /* E_SIP_UPDATE ccsip_handle_sentbye_recvd_invite, */ - {E_SIP_UPDATE, H_SENTBYE_EV_SIP_INVITE}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE ccsip_handle_release_ev_cc_feature, */ - {E_CC_FEATURE, H_RELEASE_EV_CC_FEATURE}, - /* E_CC_RELEASE, ccsip_handle_release_ev_release, */ - {E_CC_RELEASE, H_RELEASE_EV_RELEASE}, - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - /* - * SIP_STATE_BLIND_XFER_PENDING, - */ - - {SIP_STATE_BLIND_XFER_PENDING, - { - /* E_SIP_BYE, ccsip_handle_release_ev_sip_bye */ - {E_SIP_BYE, H_BYE_RELEASE}, - /* E_SIP_2xx ccsip_handle_sentblindntfy_ev_sip_2xx, */ - {E_SIP_2xx, H_SENT_BLINDNTFY}, - /* E_SIP_FAILURE_RESPONSE ccsip_handle_sentbye_ev_sip_fxx, */ - {E_SIP_FAILURE_RESPONSE, H_SENTBYE_EV_SIP_FXX}, - /* E_CC_FEATURE ccsip_handle_send_blind_notify, */ - {E_CC_FEATURE, H_BLIND_NOTIFY}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - - } - }, - - {SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING, - { - /* E_SIP_TIMER, ccsip_handle_default_sip_timer */ - {E_SIP_TIMER, H_DEFAULT_SIP_TIMER}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE ccsip_handle_default_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_EV_CC_FEATURE}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - {SIP_STATE_SENT_OOD_REFER, - { - {E_SIP_1xx, H_OOD_REFER_RESPONSE_EV_SIP_1xx}, - {E_SIP_2xx, H_OOD_REFER_RESPONSE_EV_SIP_2xx}, - {E_SIP_3xx, H_OOD_REFER_RESPONSE_EV_SIP_fxx}, - {E_SIP_FAILURE_RESPONSE, H_OOD_REFER_RESPONSE_EV_SIP_fxx}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - - {SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING, - { - /* E_SIP_BYE ccsip_handle_disconnect_remote, */ - {E_SIP_BYE, H_DISCONNECT_REMOTE}, - /* E_CC_RELEASE ccsip_handle_disconnect_media_change, */ - {E_CC_RELEASE, H_DISCONNECT_MEDIA_CHANGE}, - /* E_CC_FEATURE_ACK ccsip_handle_recvupdatenewmedia_ccfeatureackpending_ev_cc_feature_ack, */ - {E_CC_FEATURE_ACK, H_RECVUPDATEMEDIA_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK}, - /* E_SIP_NOTIFY ccsip_handle_unsolicited_notify */ - {E_SIP_NOTIFY, H_EV_SIP_UNSOLICITED_NOTIFY}, - /* E_CC_FEATURE, ccsip_handle_default_recvreq_ack_pending_ev_cc_feature */ - {E_CC_FEATURE, H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE}, - /* E_CC_INFO ccsip_handle_ev_cc_info */ - {E_CC_INFO, H_EV_CC_INFO}, - - /* Initializing any events which are not used to Invalid events */ - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT}, - {H_INVALID_EVENT, H_DEFAULT} - } - }, - -}; - -static const sipSMEventActionFn_t - gSIPHandlerTable[SIPSPI_EV_INDEX_END - SIPSPI_EV_INDEX_BASE + 1] = { - - /*0*//* H_IDLE_EV_SIP_INVITE, */ - ccsip_handle_idle_ev_sip_invite, - - /*1*//* H_IDLE_EV_CC_SETUP, */ - ccsip_handle_idle_ev_cc_setup, - - /*2*//* H_SENTINVITE_EV_SIP_1XX, */ - ccsip_handle_sentinvite_ev_sip_1xx, - - /*3*//* H_SENTINVITE_EV_SIP_2XX, */ - ccsip_handle_sentinvite_ev_sip_2xx, - - /*4*//* H_SENTINVITE_EV_SIP_FXX, */ - ccsip_handle_sentinvite_ev_sip_fxx, - - /*5*//* H_DISCONNECT_LOCAL_EARLY, */ - ccsip_handle_disconnect_local_early, - - /*6*//* H_DISCONNECT_REMOTE, */ - ccsip_handle_disconnect_remote, - - /*7*//* H_SENTINVITECONNECTED_EV_CC_CONNECTED_ACK, */ - ccsip_handle_sentinviteconnected_ev_cc_connected_ack, - - /*8*//* H_DISCONNECT_LOCAL, */ - ccsip_handle_disconnect_local, - - /*9*//* H_RECVINVITE_EV_CC_SETUP_ACK, */ - ccsip_handle_recvinvite_ev_cc_setup_ack, - - /*10*//* H_RECVINVITE_EV_CC_PROCEEDING, */ - ccsip_handle_recvinvite_ev_cc_proceeding, - - /*11*//* H_RECVINVITE_EV_CC_ALERTING, */ - ccsip_handle_recvinvite_ev_cc_alerting, - - /*12*//* H_RECVINVITE_EV_CC_CONNECTED, */ - ccsip_handle_recvinvite_ev_cc_connected, - - /*13*//* H_DISCONNECT_LOCAL_UNANSWERED, */ - ccsip_handle_disconnect_local_unanswered, - - /*14*//* H_RECVINVITE_EV_SIP_ACK, */ - ccsip_handle_recvinvite_ev_sip_ack, - - /*15*//* H_ACTIVE_EV_SIP_INVITE, */ - ccsip_handle_active_ev_sip_invite, - - /*16*//* H_ACTIVE_EV_CC_FEATURE, */ - ccsip_handle_active_ev_cc_feature, - - /*17*//* H_ACCEPT_2XX, */ - ccsip_handle_accept_2xx, - - /*18*//* H_REFER_SIP_MESSAGE, */ - ccsip_handle_refer_sip_message, - - /*19*//* H_ACTIVE_EV_CC_FEATURE_ACK, */ - ccsip_handle_active_ev_cc_feature_ack, - - /*20*//* H_SENTINVITE_MIDCALL_EV_SIP_2XX, */ - ccsip_handle_sentinvite_midcall_ev_sip_2xx, - - /*21*//* H_SENTINVITE_MIDCALL_EV_CC_FEATURE, */ - ccsip_handle_sentinvite_midcall_ev_cc_feature, - - /*22*//* H_RECVMIDCALLINVITE_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK */ - ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack, - - /*23*//* H_RECVMIDCALLINVITE__SIPACKPENDING_EV_SIP_ACK, */ - ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack, - - /*24*//* H_DEFAULT_SIP_MESSAGE, */ - ccsip_handle_default_sip_message, - - /*25*//* H_DEFAULT_SIP_RESPONSE, */ - ccsip_handle_default_sip_response, - - /*26*//* H_DEFAULT, */ - ccsip_handle_default, - - /*27*//* H_SIP_INV_EXPIRES_TIMER */ - ccsip_handle_disconnect_local_early, - - /*28*//* H_SIP_OPTIONS, */ - ccsip_handle_process_in_call_options_request, - - /*29*//* H_SENTINVITE_EV_SIP_3XX, */ - ccsip_handle_sentinvite_ev_sip_3xx, - - /*30*//*H_RECV_ERR_EV_SIP_ACK */ - ccsip_handle_recv_error_response_ev_sip_ack, - - /*31*//*H_SENTBYE_EV_SIP_2XX */ - ccsip_handle_sentbye_ev_sip_2xx, - - /*32*//*H_SENTBYE_EV_SIP_1XX */ - ccsip_handle_sentbye_ev_sip_1xx, - - /*33*//*H_SENTBYE_EV_SIP_FXX */ - ccsip_handle_sentbye_ev_sip_fxx, - - /*34*//*H_SENTBYE_EV_SIP_INVITE */ - ccsip_handle_sentbye_recvd_invite, - - /*35*//*H_SENTBYE_SUPERVISION_DISCONNECT_TIMER */ - ccsip_handle_sendbye_ev_supervision_disconnect, - - /*36*//*H_RELEASE_COMPLETE */ - ccsip_handle_release_complete, - - /*37*//*H_ACTIVE_2xx */ - ccsip_handle_active_2xx, - - /*38*//*H_BLIND_NOTIFY */ - ccsip_handle_send_blind_notify, - - /*39*//*H_SENT_BLINDNTFY */ - ccsip_handle_sentblindntfy_ev_sip_2xx, - - /*40*//*H_BYE_RELEASE, */ - ccsip_handle_release_ev_sip_bye, - - /*41*//*H_HANDLE_LOCALEXPIRES_TIMER, */ - ccsip_handle_localexpires_timer, - - /*42*//*H_DEFAULT_SIP_TIMER */ - ccsip_handle_default_sip_timer, - - /*43*//*H_EARLY_EV_SIP_UPDATE */ - ccsip_handle_early_ev_sip_update, - - /*44*//*H_EARLY_EV_SIP_UPDATE_RESPONSE */ - ccsip_handle_early_ev_sip_update_response, - - /*45*//*H_EARLY_EV_CC_FEATURE */ - ccsip_handle_early_ev_cc_feature, - - /*46*//*H_EARLY_EV_CC_FEATURE_ACK */ - ccsip_handle_early_ev_cc_feature_ack, - - /*47*//*H_CONFIRM_EV_SIP_UPDATE */ - ccsip_handle_active_ev_sip_update, - - /*48*//*H_RECVUPDATEMEDIA_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK */ - ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack, - - /*49*//*H_SIP_GLARE_AVOIDANCE_TIMER */ - ccsip_handle_timer_glare_avoidance, - - /*50*//*H_RECVINVITE_SENTOK_NO_SIP_ACK */ - ccsip_handle_recvinvite_ev_expires_timer, - - /*51*//*H_EV_SIP_UNSOLICITED_NOTIFY */ - ccsip_handle_unsolicited_notify, - - /*52*//*H_RECVINVITE_EV_SIP_2XX, */ - ccsip_handle_recvinvite_ev_sip_2xx, - - /*53*//*H_ICMP_UNREACHABLE, */ - ccsip_handle_icmp_unreachable, - - /*54*//*H_DISCONNECT_MEDIA_CHANGE, */ - ccsip_handle_disconnect_media_change, - - /*55*//*H_DEFAULT_EV_CC_FEATURE, */ - ccsip_handle_default_ev_cc_feature, - - /*56*//*H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE */ - ccsip_handle_default_recvreq_ack_pending_ev_cc_feature, - - /*57*//*H_OOD_REFER_RESPONSE_EV_SIP_1xx */ - ccsip_handle_sent_ood_refer_ev_sip_1xx, - - /*58*//*H_OOD_REFER_RESPONSE_EV_SIP_2xx */ - ccsip_handle_sent_ood_refer_ev_sip_2xx, - - /*59*//*H_OOD_REFER_RESPONSE_EV_SIP_fxx */ - ccsip_handle_sent_ood_refer_ev_sip_fxx, - - /*60*//* H_RELEASE_EV_CC_FEATURE, */ - ccsip_handle_release_ev_cc_feature, - - /*61*//* H_EV_CC_INFO, */ - ccsip_handle_ev_cc_info, - - /*62*//* H_RELEASE_EV_RELEASE, */ - ccsip_handle_release_ev_release, -}; - -static uint32_t get_callref(const char *tag) { - int32_t i, callref = 0; - const char * ref; - - for ( i = (strlen(tag)-1); i >= 0; i--) { - ref = &tag[i]; - if ( *ref == '-' ) { - sscanf ( ref, "-%d", &callref); - break; - } - } - return callref; -} - -sipSMAction_t -get_handler_index (sipSMStateType_t isipsmstate, sipSMEventType_t isipsmevent) -{ - int16_t i; - - if ((isipsmstate < SIP_STATE_BASE) || (isipsmstate > SIP_STATE_END) || - (isipsmevent < SIPSPI_EV_BASE) || (isipsmevent > SIPSPI_EV_END)) { - buginf("\nvalue of event passed isipsmevent=%d value of state = %d, " - "SIP_STATE_BASE = %d, SIP_STATE_END = %d, SIPSPI_EV_BASE = %d," - " SIPSPI_EV_END = %d", - isipsmstate, isipsmevent, SIP_STATE_BASE, SIP_STATE_END, - SIPSPI_EV_BASE, SIPSPI_EV_END); - - return H_INVALID_EVENT; - } - - for (i = 0; i < MAX_STATE_EVENTS; i++) { - if (g_sip_table[isipsmstate].validEvent[i].sipValidEvent == (int16_t)isipsmevent) { - return ((sipSMAction_t) g_sip_table[isipsmstate].validEvent[i].actionIndex); - } - } - switch (isipsmevent) { - case E_SIP_INVITE: - case E_SIP_UPDATE: - case E_SIP_ACK: - case E_SIP_BYE: - case E_SIP_REFER: - case E_SIP_CANCEL: - return H_DEFAULT_SIP_MESSAGE; - case E_SIP_1xx: - case E_SIP_2xx: - case E_SIP_3xx: - case E_SIP_FAILURE_RESPONSE: - return H_DEFAULT_SIP_RESPONSE; - case E_SIP_TIMER: - return H_DEFAULT_SIP_TIMER; - - case E_SIP_OPTIONS: - return H_SIP_OPTIONS; - - case E_SIP_GLARE_AVOIDANCE_TIMER: - return H_SIP_GLARE_AVOIDANCE_TIMER; - - case E_SIP_ICMP_UNREACHABLE: - return H_ICMP_UNREACHABLE; - - default: - break; - } - return H_DEFAULT; -} - - -void -sip_sm_change_state (ccsipCCB_t *ccb, sipSMStateType_t new_state) -{ - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Change state %s -> %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, "sip_sm_change_state"), - sip_util_state2string(ccb->state), - sip_util_state2string(new_state)); - - if (ccb->state == SIP_STATE_RELEASE && - new_state == SIP_STATE_IDLE) { - /* Just add call marker in the log */ - DEF_DEBUG("===================================================\n"); - } - - /* - * If we are moving out of SIP_STATE_RELEASE, then stop the - * supervision timer if it has been started - */ - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - } - - ccb->state = new_state; - - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_start(SUPERVISION_DISCONNECT_TIMEOUT, - ccb->index); - } -} - -/* - * Function: sip_util_extract_sdp() - * - * Parameters: ccb - The current call control block - * message - The sip message to parse - * - * Description: This routine parses the indicated message for SDP. - * - * Returns: sip_sdp_status_t - An enum which contains several return codes - * - * Note: The SIP_SDP_DNS_FAIL will not be returned from this - * function because GSM also handles DNS look up. The rest of - * this module should still check for the SIP_SDP_DNS_FAIL value - * for the return code of this function. They should be kept just - * in case that there is a need for SIP to check DNS for some - * reason in the future. - */ -static sipsdp_status_t -sip_util_extract_sdp (ccsipCCB_t *ccb, sipMessage_t *message) -{ - const char *fname = "sip_util_extract_sdp"; - // const char *content_type; - uint8_t content_type = 0; - int content_length = 0; - cc_sdp_t *sip_msg_sdp = NULL; - u16 i = 0; - sipsdp_status_t retval = SIP_SDP_NOT_PRESENT; - char *sdp_data = NULL; // message->mesg_body; - uint16_t num_m_lines; - - /* - * Check to see if SDP is present in this message - */ - // Go through the different body types to see if there is an - // SDP body - if (message->num_body_parts == 0) { - content_length = 0; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"\nmultipart/mixed No SDP Found!\n", DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - } else { - for (i = 0; i < message->num_body_parts; i++) { - if (message->mesg_body[i].msgContentTypeValue == - SIP_CONTENT_TYPE_SDP_VALUE) { - content_type = SIP_CONTENT_TYPE_SDP_VALUE; - content_length = message->mesg_body[i].msgLength; - sdp_data = message->mesg_body[i].msgBody; - break; - } - } - } - - /* - * Check for content - */ - if ((content_type != SIP_CONTENT_TYPE_SDP_VALUE) || - (content_length <= 0)) { - /* there is no SDP content or no content */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), ccb->index, - ccb->dn_line, fname, "No SDP"); - return (SIP_SDP_NOT_PRESENT); - } - - /* - * Allocate a SDP buffer to work with (only destination buffer is needed). - * - * Here we are handing in an empty string to designate that we are not - * in the context of a peerconnection object - */ - sipsdp_src_dest_create("", CCSIP_DEST_SDP_BIT, &sip_msg_sdp); - if ((sip_msg_sdp == NULL) || (sip_msg_sdp->dest_sdp == NULL)) { - /* Unable to get SDP */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SDP_CREATE_BUF_ERROR), - fname); - return (SIP_SDP_ERROR); - } - /* - * Pasrse the SDP body - */ - if (sdp_parse(sip_msg_sdp->dest_sdp, &sdp_data, - (uint16_t)content_length) != SDP_SUCCESS) { - /* unable to parse the SDP */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_PARSE_SDP_ERROR), fname); - - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT, &sip_msg_sdp); - return (SIP_SDP_ERROR); - } - - /* - * Verify that there are media lines present - */ - num_m_lines = sdp_get_num_media_lines(sip_msg_sdp->dest_sdp); - if (num_m_lines == 0) { - /* No media lines in the SDP body */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Process SDP, no media"); - retval = SIP_SDP_NO_MEDIA; - } else { - /* There is at least a media line in the SDP */ - retval = SIP_SDP_SUCCESS; - - /* - * Check to see if the sdp->session_id and version_id are - * the same. If they are, it could be a session audit. - * In most cases, this is handled the same as - * SIP_SDP_SUCCESS. - */ - if (sip_msg_sdp->dest_sdp) { - const char *new_session_id = NULL; - const char *new_version_id = NULL; - - new_session_id = sdp_get_owner_sessionid(sip_msg_sdp->dest_sdp); - new_version_id = sdp_get_owner_version(sip_msg_sdp->dest_sdp); - - if ((ccb->old_session_id) && (ccb->old_version_id) && - (new_session_id) && (new_version_id)) { - if ((!(strcmp(ccb->old_session_id, new_session_id))) && - (!(strcmp(ccb->old_version_id, new_version_id)))) { - retval = SIP_SDP_SESSION_AUDIT; - } - } - - if (ccb->old_session_id != NULL) { - cpr_free(ccb->old_session_id); - ccb->old_session_id = NULL; - } - if (ccb->old_version_id != NULL) { - cpr_free(ccb->old_version_id); - ccb->old_version_id = NULL; - } - if ((new_session_id) && (new_version_id)) { - ccb->old_session_id = cpr_strdup(new_session_id); - ccb->old_version_id = cpr_strdup(new_version_id); - } - } - } - /* free the SDP buffer */ - sipsdp_src_dest_free(CCSIP_DEST_SDP_BIT, &sip_msg_sdp); - return (retval); -} - -/* - * Function: ccsip_save_local_msg_body - * - * Parameters: ccb - The pointer to ccsipCCB to save message body sent - * by GSM. - * msg_body - pointer to a new msg body to be saved. - * - * Description: This routine saves the message bodies sent by GSM via CCAPI. - * If there is a previous message, the previous messages will - * be freed before the current one is saved. - * - * Returns: void - * - */ -static void -ccsip_save_local_msg_body (ccsipCCB_t *ccb, cc_msgbody_info_t *msg_body) -{ - if ((msg_body == NULL) || (msg_body->num_parts == 0)) { - return; - } - - /* - * Move the new bodies to the local_msg_body, the previous - * msg. bodies will be freed by the move function - */ - cc_mv_msg_body_parts(&ccb->local_msg_body, msg_body); -} - -/* - * Function: sip_redirect - * - * Parameters: ccb, response to invite request, status code of - * response. - * - * Description: Will create a new invite with contact information - * received in Redirection response to previous invite - * Will clear up the call if all the contacts have been - * used and no 2xx final response has been received. - * - * Returns: - * - */ -void -sip_redirect (ccsipCCB_t *ccb, sipMessage_t *response, uint16_t status_code) -{ - const char *fname = "sip_redirect"; - sipRedirectInfo_t *redirect_info; - const char *contact; - sipLocation_t *sipLocation; - sipUrl_t *pContactURL = NULL; - char *diversion[MAX_DIVERSION_HEADERS]; - char *str_temp = NULL; - char ui_str[STATUS_LINE_MAX_LEN]; - int i = 0; - boolean sent_invite = FALSE; - cpr_ip_addr_t cc_remote_ipaddr; - uint16_t diversion_count, cc_diversion_count, max_headers; - size_t to_length; - char tmp_str[STATUS_LINE_MAX_LEN]; - char stored_to_header[MAX_SIP_URL_LENGTH]; - char *temp = NULL; - - - CPR_IP_ADDR_INIT(cc_remote_ipaddr); - - while (!sent_invite) { - if (ccb->redirect_info == NULL) { - - /* Redirected for the first time allocating redirect_info */ - redirect_info = (sipRedirectInfo_t *) - cpr_malloc(sizeof(sipRedirectInfo_t)); - if (redirect_info == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "malloc(redirect_info)"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - redirect_info->sipContact = NULL; - redirect_info->next_choice = 0; - ccb->redirect_info = redirect_info; - } else { - redirect_info = ccb->redirect_info; - } - - /* - * Now we are clearing the record-route information since we - * want redirected invite to use contact header. New transaction - * will start now and that will be using new record-route information, - * if any. - */ - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - - if (redirect_info->next_choice >= SIP_MAX_LOCATIONS) { - /* Exhausted all Choices */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Exhausted all Contacts"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - - if ((status_code >= SIP_RED_MULT_CHOICES && - status_code <= SIP_RED_USE_PROXY) && - (ccb->first_pass_3xx == TRUE)) { - /* 300, 301, 302 and 305 must have contact header */ - - /* - * We have already initialized the redirect_info with the - * contact info once, so the next time through the loop - * skip this part. - */ - ccb->first_pass_3xx = FALSE; - - if ((platGetPhraseText(STR_INDEX_CALL_REDIRECTED, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - memset(ui_str, 0, sizeof(ui_str)); - snprintf(ui_str, sizeof(ui_str), "%s (in %d)", - tmp_str, status_code); - ui_set_call_status(ui_str, ccb->dn_line, ccb->gsm_id); - } - - if (redirect_info->sipContact) { - /* Delete previously stored contact */ - sippmh_free_contact(redirect_info->sipContact); - redirect_info->sipContact = NULL; - } - - contact = sippmh_get_cached_header_val(response, CONTACT); - redirect_info->sipContact = sippmh_parse_contact(contact); - if ((redirect_info->sipContact == NULL) - || (contact == NULL)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_contact()"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - /* - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = redirect_info->sipContact; - */ - - sipLocation = redirect_info->sipContact->locations[0]; - redirect_info->next_choice = 1; - - //if we are a part of a transfer we are going to need this. - //save the Contact value returned in 30x as the AOR for - //value to be populated in a later REFER's Refer-To - ccb->sip_referTo = strlib_update(ccb->sip_referTo, contact); - - } else { - /* We should try next location in previous Contact */ - - if ((redirect_info->sipContact == NULL) || - (redirect_info->next_choice >= - redirect_info->sipContact->num_locations)) { - /* Exhausted all Choices */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Exhausted all Contacts"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - sipLocation = redirect_info->sipContact->locations - [redirect_info->next_choice++]; - } - - /* - * Get the CC-Diversion parameter (if any). - */ - for (i = 0; i < MAX_DIVERSION_HEADERS; i++) { - diversion[i] = NULL; - } - /* - * We need to to compliment to old CC-Diversion and CC_Redirect. - * We will either be getting CC_Diversion or Diversion or - * CC_Redirect, which are all basically same. - * - * So instead of changing it on the parser level I would prefer - * to do it at SIP level. The following code first looks for - * Diversion then looks for CC_Diversion and then at last - * priority looks for CC_Redirect - */ - diversion_count = sippmh_get_num_particular_headers(response, - SIP_HEADER_DIVERSION, - SIP_HEADER_DIVERSION, - diversion, MAX_DIVERSION_HEADERS); - max_headers = MAX_DIVERSION_HEADERS - diversion_count; - cc_diversion_count = sippmh_get_num_particular_headers(response, - SIP_HEADER_CC_DIVERSION, - SIP_HEADER_CC_DIVERSION, - &diversion[diversion_count], - max_headers); - max_headers = MAX_DIVERSION_HEADERS - diversion_count - cc_diversion_count; - (void) sippmh_get_num_particular_headers(response, - SIP_HEADER_CC_REDIRECT, - SIP_HEADER_CC_REDIRECT, - &diversion[diversion_count + cc_diversion_count], - max_headers); - for (i = 0; i < MAX_DIVERSION_HEADERS; i++) { - if (diversion[i]) { - int len = 0; - - len = strlen(diversion[i]); - if (ccb->diversion[i]) { - cpr_free(ccb->diversion[i]); - ccb->diversion[i] = NULL; - } - ccb->diversion[i] = (char *) cpr_malloc(len + 2); - if (ccb->diversion[i]) { - sstrncpy(ccb->diversion[i], diversion[i], len + 1); - } else { - CCSIP_DEBUG_ERROR(DEB_L_C_F_PREFIX"No memory left;" - "Ignoring CC-Diversion header #%d %d\n", - ccb->dn_line, ccb->gsm_id, fname, - ccb->index, i + 1); - } - } - } - - /* - * Ignore TEL URLs so loop through until we hit SIP URL. - */ - while ((sipLocation) && - (redirect_info->next_choice < SIP_MAX_LOCATIONS) && - (sipLocation->genUrl->schema != URL_TYPE_SIP)) { - sipLocation = redirect_info->sipContact->locations - [redirect_info->next_choice++]; - } - - if (!sipLocation) { - /* Exhausted all Choices */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Exhausted all Contacts"); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - - pContactURL = sipLocation->genUrl->u.sipUrl; - - /* - * Initially, set the port to the port contained in the ContactURL. Then - * do a DNS Lookup on the host. If we get a new port in the response, we - * will use that when building the Request URI. - */ - ccb->dest_sip_port = pContactURL->port; - - if (!pContactURL->port_present) { - /* Set the IP-level destination ipaddr and port in the ccb */ - dns_error_code = sipTransportGetServerAddrPort(pContactURL->host, - &cc_remote_ipaddr, - (uint16_t *) &ccb->dest_sip_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(pContactURL->host, &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code == 0) { - util_ntohl(&(ccb->dest_sip_addr), &cc_remote_ipaddr); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportGetServerAddrPort or dnsGetHostByName()"); - - /* - * If DNS Lookup fails and there are more contacts, loop back up and try the next one. - * If we're out of contacts, then just release the call. - */ - if (redirect_info->next_choice < SIP_MAX_LOCATIONS) { - continue; - } else { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - return; - } - - /* - * Get rid of transaction block for the ccb, we may have - * tried previous proxy in the Contact list - */ - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - - /* - * Make new Req-URI and To values - */ - - temp = strstr(ccb->sip_to, ";tag"); - to_length = (temp != NULL) ? (strlen(ccb->sip_to) - strlen(temp)) : MAX_SIP_URL_LENGTH; - if (to_length < MAX_SIP_URL_LENGTH) { - sstrncpy(stored_to_header, ccb->sip_to, to_length + 1); - } else { - sstrncpy(stored_to_header, ccb->sip_to, MAX_SIP_URL_LENGTH); - } - - str_temp = strlib_open(ccb->sip_to, MAX_SIP_URL_LENGTH); - snprintf(str_temp, MAX_SIP_URL_LENGTH, "%s", stored_to_header); - ccb->sip_to = strlib_close(str_temp); - - if (pContactURL->maddr) { - if (pContactURL->user) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - "sip:%s%s%s@%s:%d;maddr=%s%s", - pContactURL->user, - (pContactURL->password ? ":" : ""), - (pContactURL->password ? pContactURL->password : ""), - pContactURL->host, - ccb->dest_sip_port, - pContactURL->maddr, - (pContactURL->is_phone ? ";user=phone" : "")); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - pContactURL->is_phone ? "sip:%s:%d;maddr=%s;user=phone" - : "sip:%s:%d;maddr=%s", - pContactURL->host, ccb->dest_sip_port, - pContactURL->maddr); - } - } else { - if (pContactURL->user) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - "sip:%s%s%s@%s:%d%s", - pContactURL->user, - (pContactURL->password ? ":" : ""), - (pContactURL->password ? pContactURL->password : ""), - pContactURL->host, - ccb->dest_sip_port, - (pContactURL->is_phone ? ";user=phone" : "")); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - pContactURL->is_phone ? "sip:%s:%d;user=phone" : "sip:%s:%d", - pContactURL->host, ccb->dest_sip_port); - } - } - - - ccb->ReqURIOriginal = strlib_update(ccb->ReqURIOriginal, ccb->ReqURI); - - ccb->sip_to_tag = strlib_update(ccb->sip_to_tag, ""); // Removing To Tag - ccb->authen.cred_type = 0; - - ccb->last_recv_request_cseq = 0; - ccb->last_recv_request_cseq_method = sipMethodInvalid; - - /* - * Send out a new INVITE - */ - if (sipSPISendInvite(ccb, SIP_INVITE_TYPE_REDIRECTED, FALSE) == TRUE) { - sent_invite = TRUE; - } else { - status_code = SIP_1XX_TRYING; - } - } - return; - -} - -/* - * Function: parseAlertingHeader - * - * Parameters: ccb: call control block - * header: The Alert-Info header - * - * Description: Parses the alert-info header to - * determine if the value is a known - * internal ringer or tone. - * - * Note: Defaults to inside ring so that is what will be - * played if any errors are encountered - * during processing or if the header is not a - * recognized value. - * - */ -void -parseAlertingHeader (ccsipCCB_t *ccb, const char *header) -{ - char alertHeader[MAX_SIP_URL_LENGTH]; - char *pAlertHeader; - char *input = NULL; - unsigned int counter = 0; - - /* - * Since alertHeader is a const char and - * we need to modify it, copy the header - * into a char * Easier to do this than - * modify SIP core to pass around a char * - */ - sstrncpy(alertHeader, header, MAX_SIP_URL_LENGTH); - pAlertHeader = alertHeader; - - /* - * Check for malformed url. - * Is opening < present? - */ - if (*pAlertHeader == '<') { - pAlertHeader++; - - /* Eat any leading white space */ - while (isspace((int)*pAlertHeader)) { - pAlertHeader++; - } - - /* Is trailing > present? */ - input = pAlertHeader; - pAlertHeader = strchr(input, '>'); - if (pAlertHeader != NULL) { - /* - * Overwrite > with NULL to terminate - * ringer name - */ - *pAlertHeader = NUL; - - /* - * Check input against the list of - * internal ringers. The bellcore - * ringers were added to the end of - * the ringer list so add the offset - * to match them up correctly - */ - for (counter = 0; counter <= VCM_BELLCORE_MAX - VCM_RING_OFFSET; counter++) { - if (strstr(input, ring_names[counter]) != NULL) { - ccb->alert_info = ALERTING_RING; - ccb->alerting_ring = (vcm_ring_mode_t) (counter + - VCM_RING_OFFSET); - return; - } - } - - /* - * Check input against the list of internal - * tones. - */ - for (counter = 0; counter < VCM_MAX_DIALTONE; counter++) { - if (strstr(input, tone_names[counter]) != NULL) { - ccb->alert_info = ALERTING_TONE; - ccb->alerting_tone = (vcm_tones_t) counter; - return; - } - } - } - } - - /* - * Error case. Malformed URL, external tone/ring pattern - * or unknown internal tone/ring pattern. Mimic old - * behavior. - */ - ccb->alert_info = ALERTING_OLD; - ccb->alerting_ring = VCM_INSIDE_RING; -} - -/* - * Function: ccsip_is_special_name_to_mask_display_number - * - * Parameters: name - name to be checked for special string. - * - * Description: The function checks the given name whether it matches - * a special display name or not. It is used to determined - * whether its associated number should be displayed or not. - * - * Return: TRUE - the given name is a special name. - * FALSE - the given name is not a special name. - */ -boolean -ccsip_is_special_name_to_mask_display_number (const char *name) -{ - const char *special_string; - - if (name == NULL) { - /* No name given ? */ - return (FALSE); - } - /* - * Check for special name such as Conference or Barge. The CCM may - * sends string that is longer than the key words to match. Compare - * exactly (not even including NULL character). - */ - special_string = platform_get_phrase_index_str(UI_CONFERENCE); - if ((cpr_strncasecmp(name, special_string, strlen(special_string)) == 0) || - (cpr_strncasecmp(name, CONFERENCE_STR, CONFERENCE_STR_LEN) == 0)) { - return (TRUE); - } - - /* - * The Barge 2 byte code is not in the phrase index table currently. Just - * use the define value. - */ - if (cpr_strncasecmp(name, INDEX_STR_BARGE, 2) == 0) { - return (TRUE); - } - - /* - * Detect private display name for restricted call party number. - */ - if (cpr_strncasecmp(name, INDEX_STR_PRIVATE, 2) == 0) { - return (TRUE); - } - - /* - * Detect monitoring display number. - */ - if (cpr_strncasecmp(name, INDEX_STR_MONITORING, 2) == 0) { - return (TRUE); - } - - /* - * Detect coaching display number. - */ - if (cpr_strncasecmp(name, INDEX_STR_COACHING, 2) == 0) { - return (TRUE); - } - - return (FALSE); -} - - -/* - * Function: unescape_UserInfo - * - * Parameters: esc_str: input escaped string containing "userinfo@host" or "userinfo" - * unesc_str: output unescaped string with escape chars unescaped - * unesc_str_len: length of unescaped string - * Description: Parses the input string to check if escaped chars are present and - * unescape them. - * Return: TRUE if escaped input exists and unescaped in output. Else FALSE. - * - * Note: -memory must be allocated by caller and freed as needed by caller. This - * function expects enough space for the string. - * -CSCsz30816: This function previously unescapes only up to @ and returns - * the unescaped data (along with the un-inspected host data). However, - * various usages in the code calls this with possible input string of - * "userinfo@host" or "userinfo" where "userinfo" could contain '@' which - * correctly needs not be escaped. Since the input is flexible as described, - * we've changed to escape the entire input string although the - * host portion, when present, should never has an escaped character anyway. - */ - -static boolean -unescape_UserInfo (const char *esc_str, char *unesc_str, - unsigned int unesc_str_len) -{ - char *user_info; - - /* Look for esc char % in the provided string */ - user_info = strpbrk(esc_str, "%"); - - if (user_info) { - if (unesc_str_len > strlen(esc_str)) { - unesc_str_len = strlen(esc_str); - } - sippmh_convertEscCharToChar(esc_str, unesc_str_len, unesc_str); - return TRUE; - } - - return (FALSE); -} - -/* - * Function: ccsip_identify_best_rpid - * - * Parameters: ccb: call control block - * calling: boolean value indicating if message is a - * request or response. - * - * Returns: boolean indicating if screened RPID found. - * - * Description: Identify the "best" Remote-Party-Id - * The top-most screened Remote-Party-ID header - * takes precedence. If none are screened, just - * use the top-most Remote-Party-Id header. - */ -static boolean -ccsip_identify_best_rpid (ccsipCCB_t *ccb, boolean request) -{ - unsigned int j; - sipRemotePartyId_t *rpid; - - ccb->best_rpid = ccb->rpid_info->rpid[0]; - - if (!ccb->best_rpid) { - return FALSE; - } - - for (j = 0; j < ccb->rpid_info->num_rpid; j++) { - rpid = ccb->rpid_info->rpid[j]; - if (rpid && - // screen check is disabled so that mid call party updates can be displayed - //rpid->screen && - //!cpr_strncasecmp(rpid->screen, SCREEN_YES, strlen(SCREEN_YES)) && - rpid->loc->genUrl->schema == URL_TYPE_SIP) { - /* party_type check is disabled so that the phone is more liberal in what it accepts for RPID */ - /* - * If RPID in a request, party must be set to calling. - * If RPID in a response, party must be set to called - */ - //if (rpid->party_type) { - // if ((request && (!cpr_strncasecmp(rpid->party_type, PARTY_TYPE_CALLING, - // strlen(PARTY_TYPE_CALLING)))) || - // (!request && (!cpr_strncasecmp(rpid->party_type, PARTY_TYPE_CALLED, - // strlen(PARTY_TYPE_CALLED))))) - // { - ccb->best_rpid = rpid; - return TRUE; - // } - //} - } - } - return FALSE; -} - -static void -ccsip_phrase_specifier (int16_t phrase, string_t * string, uint16_t len) -{ - char *temp_str; - char tmp_str[STATUS_LINE_MAX_LEN]; - - temp_str = strlib_open(*string, len); - if (temp_str) { - if (phrase == STR_INDEX_ANONYMOUS_SPACE) { - if ((platGetPhraseText(STR_INDEX_ANONYMOUS_SPACE, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - sstrncpy(temp_str, tmp_str, len); - } - } else { - sstrncpy(temp_str, platform_get_phrase_index_str(phrase), len); - } - } - *string = strlib_close(temp_str); -} - -/* - * Function: ccsip_check_set_privacy_screen - * - * Parameters: - * name : name returned here based on privacy and screen - * number : number returned here based on privacy and screen - * input_name: input name - * input_num: input number - * privacy: privacy - * screen: screen information - * connected_party: indicates that name/number are of the - * called/calling party - * - * Returns: TRUE if Number should be private - * - * Description: This function checkes privacy and screen information - * and based on that name and number parameter is calculated. - * - * Note: To align with SCCP display the number is not displayed if - * it is private. The Java UI code does not display anything - * if the string is an empty string. So at the beginning of - * the function set the number to "" and only update the number - * string if the number is to be displayed. In the case where - * the name and number represent the calling or called party, - * we need to provide the number to GSM in the event that this - * is the consultative call leg of an xfer. The xfer state machine - * requires a DN in order to complete the xfer. The connected_party - * boolean indicates whether the name/number are from the - * called or calling party. - */ -static boolean -ccsip_check_set_privacy_screen (string_t *name, string_t *number, - char *input_name, char *input_num, - char *privacy, char *screen, - boolean connected_party) -{ - char *name_str; - boolean number_private = FALSE; - - /* Initialize to empty required by UI */ - *name = strlib_update(*name, ""); - - *number = strlib_update(*number, ""); - - if (!privacy || cpr_strncasecmp(privacy, PRIVACY_FULL, sizeof(PRIVACY_FULL)) == 0) { - /* Ignore screen parameter now - * (cpr_strcasecmp(screen, SCREEN_NO) == 0)) { - */ - ccsip_phrase_specifier(UI_PRIVATE, name, MAX_SIP_DISPLAYNAME_LENGTH); - if (connected_party) { - /* - * name/number from connected party. number is required. - */ - ccsip_phrase_specifier(STR_INDEX_ANONYMOUS_SPACE, number, - MAX_SIP_URL_LENGTH * 2); - } - return TRUE; - } - - if (cpr_strncasecmp(privacy, PRIVACY_URI, sizeof(PRIVACY_URI)) == 0) { - - if ((input_name != NULL) && (*input_name != NUL)) { - *name = strlib_update(*name, input_name); - } else { - ccsip_phrase_specifier(UI_UNKNOWN, name, MAX_SIP_DISPLAYNAME_LENGTH); - } - if (connected_party) { - /* - * name/number from connected party. number is required. - */ - ccsip_phrase_specifier(STR_INDEX_ANONYMOUS_SPACE, number, - MAX_SIP_URL_LENGTH * 2); - } - number_private = TRUE; - } else if (cpr_strncasecmp(privacy, PRIVACY_NAME, sizeof(PRIVACY_NAME)) == 0) { - - if (input_num) { - *number = strlib_update(*number, input_num); - } - ccsip_phrase_specifier(UI_PRIVATE, name, MAX_SIP_DISPLAYNAME_LENGTH); - - } else { - - if ((input_name != NULL) && (*input_name != NUL)) { - *name = strlib_update(*name, input_name); - } else { - if (!input_num || (*input_num == NUL)) { - ccsip_phrase_specifier(UI_UNKNOWN, name, MAX_SIP_DISPLAYNAME_LENGTH); - } - } - - if (input_num) { - *number = strlib_update(*number, input_num); - } - } - - name_str = strlib_open(*name, MAX_SIP_DISPLAYNAME_LENGTH); - if (name_str) { - sip_sm_dequote_string(name_str, MAX_SIP_DISPLAYNAME_LENGTH); - } - *name = strlib_close(name_str); - return number_private; -} - -/* - * Function: ccsip_parse_diversion_header - * - * Parameters: ccb: call control block - * msg: SIP message to examine for RPID header - * - * Returns: boolean - * - * Description: Diversion header is used when the call is forwarded to this - * number. There are 2 different items that are extracted from diversion - * header, 1) originally called party 2) last redirecting party. - * On the Screen originally called party is shown as "By:.." and - * last redirecting party is shown as "From:..." - */ -static boolean -ccsip_parse_diversion_header (ccsipCCB_t *ccb, sipMessage_t *msg) -{ - char *diversion_headers[MAX_DIVERSION_HEADERS]; - unsigned int diversion_count; - sipDiversion_t *diversion_header; - - /* - * Free up previous diversion header info. - */ - sippmh_free_diversion_info(ccb->div_info); - - ccb->div_info = (sipDiversionInfo_t *) - cpr_malloc(sizeof(sipDiversionInfo_t)); - - if (!ccb->div_info) { - return FALSE; - } - - memset(ccb->div_info, 0, sizeof(sipDiversionInfo_t)); - memset(diversion_headers, 0, MAX_DIVERSION_HEADERS * sizeof(char *)); - - ccb->div_info->last_redirect_name = strlib_empty(); - ccb->div_info->last_redirect_number = strlib_empty(); - ccb->div_info->orig_called_name = strlib_empty(); - ccb->div_info->orig_called_number = strlib_empty(); - - - diversion_count = sippmh_get_num_particular_headers(msg, - SIP_HEADER_DIVERSION, - SIP_HEADER_DIVERSION, - diversion_headers, - MAX_DIVERSION_HEADERS); - - if (diversion_count < 1) { - return FALSE; - } - - ccb->call_type = CC_CALL_FORWARDED; - - /* We need 1st and last diversion headers only */ - diversion_header = sippmh_parse_diversion(diversion_headers[0], SIP_HEADER_DIVERSION); - - if (diversion_header) { - (void) ccsip_check_set_privacy_screen(&(ccb->div_info->last_redirect_name), - &(ccb->div_info->last_redirect_number), - diversion_header->locations->name, - diversion_header->locations->genUrl->u.sipUrl->user, - diversion_header->privacy, - diversion_header->screen, FALSE); - - sippmh_free_diversion(diversion_header); - } - - /* Parse last diversion header */ - diversion_header = sippmh_parse_diversion(diversion_headers[diversion_count - 1], - SIP_HEADER_DIVERSION); - - if (diversion_header) { - (void) ccsip_check_set_privacy_screen(&(ccb->div_info->orig_called_name), - &(ccb->div_info->orig_called_number), - diversion_header->locations->name, - diversion_header->locations->genUrl->u.sipUrl->user, - diversion_header->privacy, - diversion_header->screen, FALSE); - - sippmh_free_diversion(diversion_header); - } - - return TRUE; -} - -/* - * Function: ccsip_parse_rpid - * - * Parameters: ccb: call control block - * msg: SIP message to examine for RPID header - * - * Returns: boolean - * - * Description: Gets number of RPID headers from the SIP message, - * parses each RPID header, and sets the parsed RPID - * header into the CCB. - */ -static boolean -ccsip_parse_rpid (ccsipCCB_t *ccb, sipMessage_t *msg) -{ - char *rpid_headers[MAX_REMOTE_PARTY_ID_HEADERS]; - unsigned int rpid_line_count; - const char *rpid_str = NULL; - unsigned int j; - - /* - * Free up the previous RPID info and its associated data before, - * parsing a new one. - */ - sippmh_free_remote_party_id_info(ccb->rpid_info); - ccb->best_rpid = NULL; - ccb->rpid_info = (sipRemotePartyIdInfo_t *) - cpr_malloc(sizeof(sipRemotePartyIdInfo_t)); - if (!ccb->rpid_info) { - return FALSE; - } - - /* Parse Remote-Party-ID */ - memset(ccb->rpid_info, 0, sizeof(sipRemotePartyIdInfo_t)); - memset(rpid_headers, 0, MAX_REMOTE_PARTY_ID_HEADERS * sizeof(char *)); - - rpid_line_count = sippmh_get_num_particular_headers(msg, - SIP_HEADER_REMOTE_PARTY_ID, - SIP_HEADER_REMOTE_PARTY_ID, - rpid_headers, - MAX_REMOTE_PARTY_ID_HEADERS); - - if (rpid_line_count < 1) { - return FALSE; - } - - for (j = 0; (j < rpid_line_count) && (j < MAX_REMOTE_PARTY_ID_HEADERS); j++) { - rpid_str = rpid_headers[j]; - if ((rpid_str) && (rpid_str[0])) { - ccb->rpid_info->rpid[j] = sippmh_parse_remote_party_id(rpid_str); - } - } - ccb->rpid_info->num_rpid = rpid_line_count; - return TRUE; -} - - -/* - * Function: ccsip_set_url_domain - * - * Parameters: host: domain name from SIP header to be checked - * callingNumber: calling number to receive appended domain - * calledNumber: the called (destination) number - * line: line used for outbound call. 0 if inbound call. - * - * Returns: string_t: The updated calling number string - * - * Description: Determines if host string received in a SIP URL should - * be appended to the calling number for UI display and - * storage in the missed/received calls directory. - * Domain from the receive SIP URL will be appended to the - * calling number under the following conditions. - * 1. Received domain is FQDN and receiving line's proxy address - * is a dotted ip address. - * 2. Received domain is FQDN and receiving line's proxy address - * is a FQDN that differs from the received domain. - * 3. If received domain is dotted ip, it is NOT appended to - * the calling number under any condtion. - * - */ -static string_t ccsip_set_url_domain (char *host, string_t callingNumber, string_t calledNumber, line_t line) -{ - char *target; - char addr_error; - uint32_t address; - char buffer[MAX_SIP_URL_LENGTH]; - boolean include_domain = FALSE; - - if (host == NULL) { - return callingNumber; - } - - /* - * First check if host is dotted ip. - */ - address = IPNameCk(host, &addr_error); - if (!address) { - /* - * Host is not a dotted ip. Treat as a domain name. - * Validate the domain name and then compare the domain name - * to what is configured for the line. - */ - target = cpr_strdup(host); - if (target != NULL) { - if (sipSPI_validate_hostname(target)) { - /* - * Get proxy address config for the receiving line. Need to first determine - * the line based on the called number. - */ - if (line == 0) { - /* - * Incoming call, line needs to be dermined based on the called number. - * Otherwise, this is an outbound call and the line was provided by GSM. - */ - line = sip_config_get_line_by_called_number(1, calledNumber); - } - - if (line == 0) { - /* - * Line not found based on called number. This call will be released by - * GSM. Use full URL until release occurs. - */ - include_domain = TRUE; - } else { - buffer[0] = '\0'; - config_get_line_string(CFGID_PROXY_ADDRESS, buffer, line, MAX_SIP_URL_LENGTH); - address = IPNameCk(buffer, &addr_error); - if (address) { - /* Configured domain is dotted ip. */ - include_domain = TRUE; - } else { - if (strncmp(host, buffer, MAX_SIP_URL_LENGTH) != 0) { - /* - * Configured domain differs from received domain - */ - include_domain = TRUE; - } - } - } - if (include_domain == TRUE) { - callingNumber = strlib_append(callingNumber, "@"); - callingNumber = strlib_append(callingNumber, host); - } - } - cpr_free(target); - } - } - return callingNumber; -} - -/* - * Function: ccsip_set_alt_callback_number - * - * Parameters: ccb: call control block - * - * Returns: char *: pointer to alt_callback_number. - * - * Description: Checks to see the x-cisco-callback-number params - * Copies the value to ccb->altCallingNumber - * - * assumes ccb->best_rpid->loc->genUrl valid - */ - -void ccsip_set_alt_callback_number(ccsipCCB_t *ccb) -{ - int param_idx=0; - char *ptr; - - while ( (ptr = ccb->best_rpid->loc->genUrl->other_params[param_idx++]) != NULL ) - { - if ( ! strncasecmp ( ptr, RPID_CALLBACK, RPID_CALLBACK_LEN)) { - ccb->altCallingNumber = - strlib_update(ccb->altCallingNumber, ptr + RPID_CALLBACK_LEN); - return; - } - } - - ccb->altCallingNumber = strlib_update(ccb->altCallingNumber, ""); -} - -/* - * Function: ccsip_set_caller_id_from_rpid - * - * Parameters: ccb: call control block - * calling: boolean value indicating if message is a - * request or response. - * display_enabled: boolean indicating if callerid is blocked. - * - * Returns: boolean: TRUE indicates call id was obtained from RPID. - * - * Description: Determines if RPID support is enabled. If so, uses utilities - * to parse out the RPID header(s) and identifies the best - * RPID header to use for UI updates. Depending on the direction - * of the call (inbound or outbound) and the RPID parameter - * settings (privacy, screen), sets the calling/called display - * name and number of the CCB based on the RPID. - */ -static boolean -ccsip_set_caller_id_from_rpid (ccsipCCB_t *ccb, boolean request, boolean update_ccb, boolean *display_enabled) -{ - int rpid_flag = RPID_DISABLED; - char *sip_rpid_user = NULL; - char *pUser = NULL; - string_t *name; - string_t *number; - boolean display_number = TRUE; - boolean private_num = FALSE; - line_t line = 0; - - - *display_enabled = TRUE; - - /* If RPID is not enabled in config, return */ - config_get_value(CFGID_REMOTE_PARTY_ID, &rpid_flag, sizeof(rpid_flag)); - if (rpid_flag == RPID_DISABLED) { - return FALSE; - } - - /* If a screened RPID is not found, return */ - if (!ccsip_identify_best_rpid(ccb, request)) { - return FALSE; - } - - if (ccb->flags & INCOMING) { - name = &ccb->callingDisplayName; - number = &ccb->callingNumber; - } else { - name = &ccb->calledDisplayedName; - number = &ccb->calledNumber; - line = ccb->dn_line; - } - - sip_rpid_user = ccb->best_rpid->loc->genUrl->u.sipUrl->user; - - pUser = sippmh_parse_user(sip_rpid_user); - if (pUser) { - sip_rpid_user = pUser; - } - - private_num = ccsip_check_set_privacy_screen(name, number, - ccb->best_rpid->loc->name, - sip_rpid_user, - ccb->best_rpid->privacy, - ccb->best_rpid->screen, - TRUE); - - /* - * This check is used to determine if the calling/called number should be displayed. - * This is true in 2 cases.If privacy=full or privacy=uri. We do not currently check - * for privacy=name. - */ - if (private_num) { - /* - * Need to distinguish between privacy=uri and privacy=full - */ - if (cpr_strncasecmp(ccb->best_rpid->privacy, PRIVACY_FULL, sizeof(PRIVACY_FULL)) == 0) { - /* - * This is used for anonymous call block - */ - *display_enabled = display_number = FALSE; - } else { - /* - * Just used for blocking the calling/called number display - */ - display_number = FALSE; - } - } - - /* - * Update the alt Calling number if received in the RPID - */ - if ( (!private_num) ) - { - ccsip_set_alt_callback_number(ccb); - } - - /* - * Append host portion of url if needed. If in CCM mode, skip this step. - * We hardcode to check line 1. If line 1 is in CCM mode, all lines are CCM mode. - */ - if (sip_regmgr_get_cc_mode(1) == REG_MODE_NON_CCM) { - *number = ccsip_set_url_domain(ccb->best_rpid->loc->genUrl->u.sipUrl->host, *number, - ccb->calledNumber, line); - } - - if (pUser) { - cpr_free(pUser); - } - - - if (update_ccb) { - if (ccb->flags & INCOMING) { - ccb->displayCallingNumber = display_number; - } else { - ccb->displayCalledNumber = display_number; - } - } - - return TRUE; -} -/* - * Function: ccsip_send_callinfo - * - * Parameters: ccb: call control block - * update_caller_id: boolean indicates caller ID updating. - * delay_update: indicates that the call info. event sent - * to GSM to update UI can be delayed. - * - * Returns: void - * - * Description: The internal function used to send GSM call info. - */ -static void -ccsip_send_callinfo (ccsipCCB_t *ccb, boolean update_caller_id, - boolean delay_update) -{ - cc_feature_data_t data; - char unescape_str_temp[MAX_SIP_URL_LENGTH]; - const char *name; - const char *number; - const char *altNumber = strlib_empty(); - boolean display_number; - - if (!ccb->in_call_info) { - data.call_info.feature_flag = 0; - data.call_info.security = CC_SECURITY_UNKNOWN; - data.call_info.policy = CC_POLICY_UNKNOWN; - if (ccb->flags & INCOMING) { - data.call_info.orientation = CC_ORIENTATION_FROM; - } else { - data.call_info.orientation = CC_ORIENTATION_TO; - } - data.call_info.ui_state = CC_UI_STATE_NONE; - data.call_info.dusting = FALSE; - data.call_info.global_call_id[0] = 0; - } else { - cc_feature_data_call_info_t *feat_data = &ccb->in_call_info->data.call_info_feat_data; - - data.call_info.feature_flag = feat_data->feature_flag; - data.call_info.security = feat_data->security; - data.call_info.policy = feat_data->policy; - data.call_info.orientation = feat_data->orientation; - data.call_info.ui_state = feat_data->ui_state; - data.call_info.caller_id.call_instance_id = feat_data->caller_id.call_instance_id; - data.call_info.dusting = feat_data->dusting; - sstrncpy(data.call_info.global_call_id, - ccb->in_call_info->data.call_info_feat_data.global_call_id, CC_GCID_LEN); - } - - data.call_info.caller_id.orig_rpid_number = strlib_empty(); - if (!update_caller_id) { - data.call_info.feature_flag &= ~CC_CALLER_ID; - data.call_info.caller_id.called_name = strlib_empty(); - data.call_info.caller_id.called_number = strlib_empty(); - data.call_info.caller_id.calling_name = strlib_empty(); - data.call_info.caller_id.calling_number = strlib_empty(); - data.call_info.caller_id.alt_calling_number = strlib_empty(); - } else { - data.call_info.feature_flag |= CC_CALLER_ID; - if (ccb->flags & INCOMING) { - /* Convert escaped userinfo in the URL to unescaped form */ - if (unescape_UserInfo(ccb->callingDisplayName, unescape_str_temp, - MAX_SIP_URL_LENGTH)) { - ccb->callingDisplayName = strlib_update(ccb->callingDisplayName, - unescape_str_temp); - } - if (unescape_UserInfo(ccb->callingNumber, unescape_str_temp, - MAX_SIP_URL_LENGTH)) { - ccb->callingNumber = strlib_update(ccb->callingNumber, - unescape_str_temp); - } - name = ccb->callingDisplayName; - number = ccb->callingNumber; - strlib_free(altNumber); - altNumber = ccb->altCallingNumber; - display_number = ccb->displayCallingNumber; - } else { - /* Convert escaped userinfo in the URL to unescaped form */ - if (unescape_UserInfo(ccb->calledDisplayedName, unescape_str_temp, - MAX_SIP_URL_LENGTH)) { - ccb->calledDisplayedName = strlib_update(ccb->calledDisplayedName, - unescape_str_temp); - } - if (unescape_UserInfo(ccb->calledNumber, unescape_str_temp, - MAX_SIP_URL_LENGTH)) { - ccb->calledNumber = strlib_update(ccb->calledNumber, - unescape_str_temp); - } - name = ccb->calledDisplayedName; - number = ccb->calledNumber; - display_number = ccb->displayCalledNumber; - } - - if (data.call_info.orientation == CC_ORIENTATION_FROM) { - data.call_info.caller_id.calling_name = name; - data.call_info.caller_id.calling_number = number; - data.call_info.caller_id.alt_calling_number = altNumber; - data.call_info.caller_id.display_calling_number = display_number; - - data.call_info.caller_id.called_name = strlib_empty(); - data.call_info.caller_id.called_number = strlib_empty(); - data.call_info.caller_id.display_called_number = FALSE; - } else { - data.call_info.caller_id.called_name = name; - data.call_info.caller_id.called_number = number; - data.call_info.caller_id.display_called_number = display_number; - - data.call_info.caller_id.calling_name = strlib_empty(); - data.call_info.caller_id.calling_number = strlib_empty(); - data.call_info.caller_id.alt_calling_number = strlib_empty(); - data.call_info.caller_id.display_calling_number = FALSE; - if(ccb->best_rpid != NULL && ccb->best_rpid->loc->genUrl->u.sipUrl->user != NULL) - data.call_info.caller_id.orig_rpid_number = (const char *) ccb->best_rpid->loc->genUrl->u.sipUrl->user; - } - } - - /* Include diversion information - * Note that a valid ccb->div_info pointer here does not indicate that call is of - * type Forward. It simply means a call to parse diversion header had been made. - */ - if (ccb->div_info) { - data.call_info.caller_id.last_redirect_name = ccb->div_info->last_redirect_name; - data.call_info.caller_id.last_redirect_number = ccb->div_info->last_redirect_number; - data.call_info.caller_id.orig_called_name = ccb->div_info->orig_called_name; - data.call_info.caller_id.orig_called_number = ccb->div_info->orig_called_number; - } else { - data.call_info.caller_id.last_redirect_name = strlib_empty(); - data.call_info.caller_id.last_redirect_number = strlib_empty(); - data.call_info.caller_id.orig_called_name = strlib_empty(); - data.call_info.caller_id.orig_called_number = strlib_empty(); - } - data.call_info.caller_id.call_type = ccb->call_type; - - /* Set UP update delay flag */ - data.call_info.feature_flag &= ~(CC_DELAY_UI_UPDATE); - if (delay_update) { - data.call_info.feature_flag |= CC_DELAY_UI_UPDATE; - } - data.call_info.callref = ccb->callref; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_CALLINFO, &data); -} - -/* - * Function: ccsip_update_callinfo - * - * Parameters: ccb: call control block - * msg: SIP message to examine for RPID - * calling: boolean value indicating if message is a - * request or response. - * delay_update: indicates that the call info. event sent - * to GSM to update UI can be delayed. - * - * Returns: void - * - * Description: Utility function used by the various SIP state handlers - * to pull RPID and callinfo data from a received SIP message and set the - * call info fields (called/calling name and number fields, security, - * orientation, ui-state) of the CCB. A call info feature indication - * is sent to the GSM to update the phone UI display. - */ -static void -ccsip_update_callinfo (ccsipCCB_t *ccb, sipMessage_t *msg, boolean check_rpid, - boolean request, boolean delay_update) -{ - boolean update_caller_id = FALSE; - boolean display_number = TRUE; - - if (!msg) { - return; - } - - if (check_rpid) { - if (ccsip_parse_rpid(ccb, msg)) { - if (ccsip_set_caller_id_from_rpid(ccb, request, TRUE, &display_number)) { - update_caller_id = TRUE; - } - } - } - - ccsip_process_call_info_header(msg, ccb); - - ccsip_send_callinfo(ccb, update_caller_id, delay_update); -} - -/* - * Function: ccsip_check_display_validity - * - * Parameters: ccb: call control block - * reuqest: sip message - * - * Returns: boolean - * True - Display valid - * False - Display not valid - * - * Description: Check if anonymous call block feature is enabled - * against privacy settings received in the RPID and - * make a decision if the call can continue - */ -static boolean -ccsip_check_display_validity(ccsipCCB_t *ccb, sipMessage_t *request) -{ - int temp = 0; - boolean display_number = TRUE; - /* - * Check for Anonymous call blocking. If low bit is set, - * then do not allow call. Note that we must allow both upper and lowercase - * ANON strings, hence the use of strcasestr - */ - config_get_value(CFGID_ANONYMOUS_CALL_BLOCK, &temp, sizeof(temp)); - if (temp & 1) { - if (ccsip_parse_rpid(ccb, request)) { - if (ccsip_set_caller_id_from_rpid(ccb, TRUE, FALSE, &display_number)) { - if (!display_number) { - return FALSE; - } - } - } - } - return TRUE; -} -/* - * - ***** SIP_STATE_IDLE - * - */ -void -ccsip_handle_idle_ev_sip_invite (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "idle_ev_sip_invite"; - char *callingDisplayNameTemp; - char *sip_to_tag_temp; - char *sip_to_temp; - sipMessage_t *request; - const char *from = NULL; - const char *to = NULL; - const char *callID = NULL; - const char *contact = NULL; - const char *record_route = NULL; - const char *expires = NULL; - const char *alert_info = NULL, *allow = NULL; - const char *require = NULL, *supported = NULL; - char *replaceshdr = NULL; - sipReplaces_t *replaces_t = NULL; - sipLocation_t *to_loc = NULL; - sipLocation_t *from_loc = NULL; - sipUrl_t *sipFromUrl = NULL; - sipUrl_t *sipToUrl = NULL; - uint32_t local_expires_timeout = 0; - int delta = 0; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - uint32_t gmt_time; - uint32_t diff_time; - int32_t gmt_rc; - callid_t cc_call_id = CC_NO_CALL_ID; - ccsipCCB_t *refererccb = NULL; - ccsipCCB_t *replaces_ccb = NULL; - line_t dn_line; - sipsdp_status_t sdp_status; - boolean check_send_487 = FALSE; - char unescape_str_temp[MAX_SIP_URL_LENGTH]; - boolean display_number = FALSE; - string_t recv_info_list = strlib_empty(); - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodInvite, FALSE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - ccb->flags |= INCOMING; - - /* To: and From: header */ - from = sippmh_get_cached_header_val(request, FROM); - ccb->sip_from = strlib_update(ccb->sip_from, from); - to = sippmh_get_cached_header_val(request, TO); - ccb->sip_to = strlib_update(ccb->sip_to, to); - - /* CallID: header */ - callID = sippmh_get_cached_header_val(request, CALLID); - sstrncpy(ccb->sipCallID, callID, sizeof(ccb->sipCallID)); - - /* Require: header */ - require = sippmh_get_cached_header_val(request, REQUIRE); - if (require) { - char *unsupported_tokens = NULL; - - ccb->required_tags = sippmh_parse_supported_require(require, - &unsupported_tokens); - - if (unsupported_tokens != NULL) { - ccb->sip_unsupported = strlib_update(ccb->sip_unsupported, - unsupported_tokens); - cpr_free(unsupported_tokens); - } - - if (ccb->required_tags & (~(SUPPORTED_TAGS))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unsupported Require Header in INVITE\n", fname); - ccb->sip_require = strlib_update(ccb->sip_require, require); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_EXTENSION, - SIP_CLI_ERR_EXTENSION_PHRASE, - 0, NULL, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - } - - /* Supported: header */ - supported = sippmh_get_cached_header_val(request, SUPPORTED); - if (supported) { - ccb->supported_tags = sippmh_parse_supported_require(supported, NULL); - } - - /* Allow: header */ - allow = sippmh_get_header_val(request, SIP_HEADER_ALLOW, NULL); - if (allow) { - ccb->allow_methods = sippmh_parse_allow_header(allow); - } - - /* Contact: header */ - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - - if ((ccb->contact_info == NULL) || // contact in msg, parse error - (sipSPICheckContact(contact) < 0)) { // If contact is invalid - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPICheckContact()"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD, - ccb); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - } - - /* Record-Route: header */ - record_route = sippmh_get_cached_header_val(request, RECORD_ROUTE); - if (record_route) { - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - } - ccb->record_route_info = sippmh_parse_record_route(record_route); - if (ccb->record_route_info == NULL) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_record_route()"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_RECORD_ROUTE, - ccb); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - } - // Save received URI in ReqURIOriginal - ccb->ReqURIOriginal = strlib_update(ccb->ReqURIOriginal, ccb->ReqURI); - - /* Parse RPID header */ - (void) ccsip_parse_rpid(ccb, request); - - - /* Parse Diversion header */ - (void) ccsip_parse_diversion_header(ccb, request); - - /* - * Parse From - */ - from_loc = sippmh_parse_from_or_to((char *)ccb->sip_from, TRUE); - if (!from_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - if (from_loc->tag && (strlen(from_loc->tag) >= MAX_SIP_TAG_LENGTH)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "Length of From Tag"); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - sippmh_free_location(from_loc); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - if (from_loc->genUrl->schema == URL_TYPE_SIP) { - sipFromUrl = from_loc->genUrl->u.sipUrl; - } - - /* - * Parse To - */ - to_loc = sippmh_parse_from_or_to((char *)ccb->sip_to, TRUE); - if (!to_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - sippmh_free_location(from_loc); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - if (to_loc->genUrl->schema == URL_TYPE_SIP) { - sipToUrl = to_loc->genUrl->u.sipUrl; - } - // Check/Generate tags - if (to_loc->tag) { - /* ccb->sip_to_tag = strlib_update(ccb->sip_to_tag, - * sip_sm_purify_tag(to_loc->tag)); - */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Initial invite with to_tag"); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, - FALSE, /* no SDP */ TRUE /* reTx */); - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - } else { - sip_to_tag_temp = strlib_open(ccb->sip_to_tag, MAX_SIP_TAG_LENGTH); - if (sip_to_tag_temp) { - sip_util_make_tag(sip_to_tag_temp); - } - ccb->sip_to_tag = strlib_close(sip_to_tag_temp); - - sip_to_temp = strlib_open(ccb->sip_to, MAX_SIP_URL_LENGTH); - if (sip_to_temp) { - sstrncat(sip_to_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - if (ccb->sip_to_tag) { - sstrncat(sip_to_temp, ccb->sip_to_tag, - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - } - } - ccb->sip_to = strlib_close(sip_to_temp); - } - - if (from_loc->tag) { - ccb->sip_from_tag = strlib_update(ccb->sip_from_tag, - sip_sm_purify_tag(from_loc->tag)); - ccb->callref = get_callref(ccb->sip_from_tag); - } - - if (ccb->ReqURI) { - ccb->calledNumber = strlib_update(ccb->calledNumber, ccb->ReqURI); - } else if (sipToUrl) { - if (sipToUrl->user) { - char *pUser = NULL; - - pUser = sippmh_parse_user(sipToUrl->user); - if (pUser && (pUser[0] != '\0')) { - ccb->calledNumber = strlib_update(ccb->calledNumber, pUser); - cpr_free(pUser); - } else { - /* An error occurred, copy the whole thing.. */ - ccb->calledNumber = strlib_update(ccb->calledNumber, - sipToUrl->user); - if (pUser) - cpr_free(pUser); - } - } - } - - /* - * Make sure we have a valid called_number. - */ - if ((ccb->calledNumber == NULL) || (ccb->calledNumber[0] == '\0')) { - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_NOT_FOUND, - SIP_CLI_ERR_NOT_FOUND_PHRASE, - 0, NULL, ccb); - - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - ccb->wait_for_ack = FALSE; - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - return; - } - - if (!ccsip_set_caller_id_from_rpid(ccb, TRUE, TRUE, &display_number)) { - if (sipFromUrl) { - if (sipFromUrl->user) { - char *pUser; - - pUser = sippmh_parse_user(sipFromUrl->user); - if (pUser) { - ccb->callingNumber = strlib_update(ccb->callingNumber, pUser); - cpr_free(pUser); - } else { - /* An error occurred, copy the whole thing.. */ - ccb->callingNumber = strlib_update(ccb->callingNumber, sipFromUrl->user); - } - if (from_loc->genUrl->schema == URL_TYPE_SIP && - sipFromUrl->host && - ccb->callingNumber && - sip_regmgr_get_cc_mode(1) == REG_MODE_NON_CCM) { - /* - * If we have a host name, calling number, and are not in CCM mode, - * check to see if the domain should be appended to the calling number - * for display to the user. - */ - ccb->callingNumber = ccsip_set_url_domain(sipFromUrl->host, ccb->callingNumber, - ccb->calledNumber, 0); - } - } else { - ccb->callingNumber = strlib_update(ccb->callingNumber, - "Unknown Number"); - } - } - - if (from_loc->name) { - callingDisplayNameTemp = strlib_open(ccb->callingDisplayName, - MAX_SIP_DISPLAYNAME_LENGTH); - if (callingDisplayNameTemp) { - sstrncpy(callingDisplayNameTemp, from_loc->name, - MAX_SIP_DISPLAYNAME_LENGTH); - sip_sm_dequote_string(callingDisplayNameTemp, MAX_SIP_DISPLAYNAME_LENGTH); - } - ccb->callingDisplayName = strlib_close(callingDisplayNameTemp); - - } else { - char *pUser; - - pUser = NULL; - if (sipFromUrl) { - pUser = sippmh_parse_user(sipFromUrl->user); - } - - if (pUser) { - ccb->callingDisplayName = strlib_update(ccb->callingDisplayName, - pUser); - cpr_free(pUser); - } else { - /* An error occurred, copy the whole thing.. */ - if (sipFromUrl) { - if (sipFromUrl->user) { - ccb->callingDisplayName = strlib_update(ccb->callingDisplayName, - sipFromUrl->user); - } - } - } - } - } - - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - - // If there is a Replace aheader then it must be a Transfer request - // Store the call_id of the other call so that we can release the call when - // we get 200 OK on consultation call - (void) sippmh_get_num_particular_headers(request, SIP_HEADER_REPLACES, - NULL, &replaceshdr, MAX_REPLACES_HEADERS); - ccb->wastransferred = FALSE; - - - dn_line = ccb->dn_line; - - if ((Basic_is_phone_forwarded(dn_line) == NULL) && NULL != replaceshdr) { - char tempreplace[MAX_SIP_URL_LENGTH]; - boolean is_previous_call_id = FALSE; - line_t previous_call_index = 0; - - memset(tempreplace, 0, MAX_SIP_URL_LENGTH); - sstrncpy(tempreplace, "Replaces=", sizeof(tempreplace)); - sstrncat(tempreplace, replaceshdr, (sizeof(tempreplace) - sizeof("Replaces="))); - replaces_t = sippmh_parse_replaces(tempreplace, FALSE); - if (NULL != replaces_t) { - //Check if a call exists that matches the callid, to and from tags found in the replaces header - if ((cpr_strcasecmp(replaces_t->toTag, ccb->sip_to_tag)==0 - && cpr_strcasecmp(replaces_t->fromTag, ccb->sip_from_tag)==0 - && cpr_strcasecmp(replaces_t->callid, ccb->sipCallID)==0) || - ((refererccb = sip_sm_get_ccb_by_callid(replaces_t->callid)) != NULL - && cpr_strcasecmp(replaces_t->toTag, refererccb->sip_to_tag) == 0 - && cpr_strcasecmp(replaces_t->fromTag, refererccb->sip_from_tag) == 0)) { - ccb->sipxfercallid = strlib_update(ccb->sipxfercallid, replaces_t->callid); - sippmh_free_replaces(replaces_t); - ccb->wastransferred = TRUE; - check_send_487 = TRUE; - } else { - is_previous_call_id = sip_sm_is_previous_call_id(replaces_t->callid, - &previous_call_index); - replaces_ccb = sip_sm_get_ccb_by_callid(replaces_t->callid); - if (replaces_ccb != NULL && replaces_ccb->state == SIP_STATE_RELEASE) { - is_previous_call_id = TRUE; - CCSIP_DEBUG_STATE("%s: Replaces Header, matching call found. \n", fname); - } - if (is_previous_call_id) { - // The Callid refers to a previous call - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Replaces Header, Callid refers to a previous call"); - sipSPISendInviteResponse(ccb, SIP_FAIL_DECLINE, - SIP_FAIL_DECLINE_PHRASE, - 0, NULL, - FALSE, /* no SDP */ TRUE /* reTx */); - - } else { - // Could not find a matching call. If the CFWD is disabled - // send back the error. If it is enabled, it will be processed - // below. - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Replaces Header, No matching call found"); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, - FALSE, /* no SDP */ TRUE /* reTx */); - } - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sippmh_free_replaces(replaces_t); - return; - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Bad Replaces Header, Ending transferred call"); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REPLACES, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - } - } - - /* - * Extract SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_OFFER_RECEIVED; - break; - - case SIP_SDP_DNS_FAIL: - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", - FALSE, FALSE); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - case SIP_SDP_ERROR: - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SDP_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - case SIP_SDP_NO_MEDIA: - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SDP_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - - case SIP_SDP_NOT_PRESENT: - default: - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Waiting for SDP in ACK\n", DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - break; - } - - - /* see if we are forwarded to another location */ - if (Basic_is_phone_forwarded(dn_line)) { - size_t escaped_char_str_len = 8; - char pDiversionStr[MAX_SIP_URL_LENGTH]; - int len = 0; - int blocking; - boolean private_flag = FALSE; - char line_name[MAX_LINE_NAME_SIZE]; - char display_name[MAX_LINE_NAME_SIZE]; - char src_addr_str[MAX_IPADDR_STR_LEN]; - - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Call forwarded, sending redirect"); - - ccb->dn_line = dn_line; - /* - * If Caller ID Blocking is OFF or emergency route is ON, - * set private to TRUE. Otherwise, FALSE. - */ - config_get_value(CFGID_CALLERID_BLOCKING, &blocking, sizeof(blocking)); - if ((blocking & 1) && (ccb->routeMode != RouteEmergency)) { - private_flag = TRUE; - } - - /* - * Diversion Header format: - * "display_name" ;reason=unconditional; - * privacy="full" or "off";screen=yes - */ - config_get_string((CFGID_LINE_NAME + ccb->dn_line - 1), line_name, sizeof(line_name)); - sip_config_get_display_name(ccb->dn_line, display_name, sizeof(display_name)); - ipaddr2dotted(src_addr_str, &ccb->src_addr); - snprintf(pDiversionStr, MAX_SIP_URL_LENGTH, "\"%s\" ;reason=unconditional;privacy=%s;screen=yes", - src_addr_str, (private_flag ? "full" : "off")); - - len = strlen(pDiversionStr); - ccb->diversion[0] = (char *) cpr_malloc(len + 1); - - if (ccb->diversion[0]) { - sstrncpy(ccb->diversion[0], pDiversionStr, len + 1); - } else { - CCSIP_DEBUG_ERROR(DEB_L_C_F_PREFIX "No memory left; %d" - "Can not create CC-Diversion header for CFWDAll\n", - ccb->dn_line, ccb->gsm_id, fname, ccb->index); - } - sipSPISendInviteResponse302(ccb); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - /* - * Start Local Expires timer - */ - expires = sippmh_get_header_val(request, SIP_HEADER_EXPIRES, NULL); - config_get_value(CFGID_TIMER_INVITE_EXPIRES, &local_expires_timeout, - sizeof(local_expires_timeout)); - if (expires) { -//CPR TODO: need reference for - gmt_rc = gmt_string_to_seconds((char *)expires, (unsigned long *)&gmt_time); - if (gmt_rc != -1) { - // We only want to update the expires timeout if it is lower - // than our predefined threshold. We don't want to allow people - // to keep us hung up for infinite periods of time - if (gmt_rc == 1) { - // We got a numeric entry in the expires field - if (gmt_time < local_expires_timeout) { - local_expires_timeout = gmt_time; - } -//CPR TODO: need reference for - } else if (diff_current_time(gmt_time, (unsigned long *) &diff_time) == 0) { - // We got a GMT string in the expires field - if (diff_time < local_expires_timeout) { - local_expires_timeout = diff_time; - } - } - } - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Using config timer_expires"); - } - - if (local_expires_timeout > 0) { - config_get_value(CFGID_TIMER_T1, &delta, sizeof(delta)); - delta = (2 * delta) / 1000; - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Starting INVITE Local Expires %d" - "timer (%d sec)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, local_expires_timeout + delta); - /* - * Add delta to the Expires timer so that the callee gives the - * caller a chance to send out the CANCEL message before sending - * out a 408 INVITE response. - */ - (void) sip_platform_localexpires_timer_start((local_expires_timeout + delta) * 1000, - ccb->index, &(ccb->dest_sip_addr), - (uint16_t) ccb->dest_sip_port); - } - - /* check for alert-info in header */ - alert_info = sippmh_get_header_val(request, SIP_HEADER_ALERT_INFO, NULL); - ccb->alert_info = ALERTING_NONE; - if (alert_info) { - parseAlertingHeader(ccb, alert_info); - } - - /* check for and process call-info in header */ - ccsip_process_call_info_header(request, ccb); - - /* - * Parse join info if it exists and get - * the gsm id for the join target call - */ - if (ccsip_get_join_info(ccb, request) == FALSE) { - /* - * There was something wrong with the joinhdr - * or join target call is not active - */ - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - sipSPISendInviteResponse100(ccb, TRUE); - - /* Inform CSM */ - cc_call_id = cc_get_new_call_id(); - ccb->gsm_id = cc_call_id; - // send XFER Request - if (ccb->wastransferred) { - refererccb = sip_sm_get_ccb_by_callid(ccb->sipxfercallid); - if (NULL != refererccb) { - cc_feature_data_t data; - - data.xfer.method = CC_XFER_METHOD_REFER; - data.xfer.cause = CC_CAUSE_XFER_REMOTE; - data.xfer.target_call_id = cc_call_id; - data.xfer.dialstring[0] = '\0'; - sip_cc_feature(refererccb->gsm_id, refererccb->dn_line, - CC_FEATURE_XFER, (void *) &data); - } - } - - if (refererccb == NULL) { - dn_line = ccb->dn_line; - } else { - dn_line = refererccb->dn_line; - } - - /* Convert escaped userinfo in the URL to unescaped form */ - if (unescape_UserInfo(ccb->calledNumber, unescape_str_temp, MAX_SIP_URL_LENGTH)) { - ccb->calledNumber = strlib_update(ccb->calledNumber, unescape_str_temp); - } - - if (unescape_UserInfo(ccb->callingNumber, unescape_str_temp, MAX_SIP_URL_LENGTH)) { - ccb->callingNumber = strlib_update(ccb->callingNumber, unescape_str_temp); - } - - if (unescape_UserInfo(ccb->callingDisplayName, unescape_str_temp, MAX_SIP_URL_LENGTH)) { - ccb->callingDisplayName = strlib_update(ccb->callingDisplayName, unescape_str_temp); - } - - if (unescape_UserInfo(ccb->altCallingNumber, unescape_str_temp, MAX_SIP_URL_LENGTH)) { - ccb->altCallingNumber = strlib_update(ccb->altCallingNumber, unescape_str_temp); - } - - /* Info Package stuff */ - ccsip_parse_send_info_header(request, &recv_info_list); - - - - if (ccb->wastransferred) { - sip_cc_setup(cc_call_id, dn_line, - ccb->callingDisplayName, - ccb->callingNumber, - ccb->altCallingNumber, - ccb->displayCallingNumber, - ccb->calledDisplayedName, - ccb->calledNumber, - ccb->displayCalledNumber, - ccb->div_info->orig_called_name, - ccb->div_info->orig_called_number, - ccb->div_info->last_redirect_name, - ccb->div_info->last_redirect_number, - ccb->call_type, - ccb->alert_info, ccb->alerting_ring, - ccb->alerting_tone, ccb->in_call_info, TRUE, - recv_info_list, request); - } else { - sip_cc_setup(cc_call_id, dn_line, - ccb->callingDisplayName, - ccb->callingNumber, - ccb->altCallingNumber, - ccb->displayCallingNumber, - ccb->calledDisplayedName, - ccb->calledNumber, - ccb->displayCalledNumber, - ccb->div_info->orig_called_name, - ccb->div_info->orig_called_number, - ccb->div_info->last_redirect_name, - ccb->div_info->last_redirect_number, - ccb->call_type, - ccb->alert_info, ccb->alerting_ring, - ccb->alerting_tone, ccb->in_call_info, FALSE, - recv_info_list, request); - } - - strlib_free(recv_info_list); - - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE); - - if (check_send_487) { - /* check to see if we need to send a 487 back to original Invite - * that replaces this call. If it is not connected yet, send the - * 487 and release the call to GSM. - */ - ccsipCCB_t *other_ccb; - - other_ccb = sip_sm_get_ccb_by_callid(ccb->sipxfercallid); - if ((other_ccb != NULL) && - ((other_ccb->state >= SIP_STATE_RECV_INVITE) && - (other_ccb->state < SIP_STATE_RECV_INVITE_CONNECTED))) { - sipSPISendInviteResponse(other_ccb, SIP_CLI_ERR_REQ_CANCEL, - SIP_CLI_ERR_REQ_CANCEL_PHRASE, 0, NULL, - FALSE /* no SDP */ , TRUE /* reTx */); - sip_cc_release(other_ccb->gsm_id, other_ccb->dn_line, - CC_CAUSE_NORMAL, NULL); - other_ccb->wait_for_ack = TRUE; - sip_sm_change_state(other_ccb, SIP_STATE_RELEASE); - } - } -} - -/* - * This function is called when one of the following occurs: - * - * 1) Attempting to send out an INVITE and for whatever reason - * the call to get the IP address for the main proxy fails. - * 2) An ICMP unreachable event is received and there are no - * more DNS entries for the main proxy. - * 3) Retries have been exhausted on the main proxy and there - * are no more DNS entries for the main proxy. - */ -boolean -ccsip_attempt_backup_proxy (ccsipCCB_t *ccb) -{ - char ip_addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t ipaddr; - int tempPort = 0; - char tmp_str[STATUS_LINE_MAX_LEN]; - - CPR_IP_ADDR_INIT(ipaddr); - /* - * Get IPAddress and Port for backup proxy - */ - sipTransportGetBkupServerAddress(&ipaddr, ccb->dn_line, ip_addr_str); - if (util_check_if_ip_valid(&ipaddr)) { - util_ntohl(&(ccb->dest_sip_addr), &ipaddr); - - /* - * If the Proxy Backup Port isn't contained in the - * config table, use the PROXYN port instead. - */ - tempPort = sipTransportGetBkupServerPort(ccb->dn_line); - if (tempPort != 0) { - ccb->dest_sip_port = tempPort; - } else { - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - - ccb->proxySelection = SIP_PROXY_BACKUP; - - /* Note counter must be at least 2 or better to work as directed - * This count is decremented by one on each successful response to - * an invite. If we receive backup_active successful responses to - * an invite go back to the max retry count on the main or primary proxy. - * Why 12 you ask. Depending on the number of SIP messages received per - * call this equates to maybe 4 phone calls before going back to - * the full re-try count on the primary/main proxy. - */ - gGlobInfo.backup_active = 12; - - /* - * Let user know we have failed over to backup proxy - */ - if ((platGetPhraseText(STR_INDEX_PROXY_UNAVAIL, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1)) == CPR_SUCCESS) { - ui_set_call_status(tmp_str, ccb->dn_line, ccb->gsm_id); - } - return (TRUE); - } - - return (FALSE); -} - -/** - * This fucntion sends mid-call INVITE. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] hold_initiated boolean indicating whther this is - * a mid-call INVITE for HOLD feature. - * - * @pre (ccb not_eq NULL) - * - * @return true or false - */ -boolean -send_resume_or_hold_request (ccsipCCB_t *ccb, boolean hold_initiated) -{ - ccb->authen.cred_type = 0; - ccb->authen.new_flag = TRUE; - ccb->hold_initiated = hold_initiated; - if (sipSPISendInviteMidCall(ccb, FALSE /* doesn't expire */) != TRUE) { - return FALSE; - } - /* Pre-fill the ARP table */ - ADD_TO_ARP_CACHE(ccb->dest_sip_addr); - return TRUE; -} - -void -ccsip_handle_idle_ev_cc_setup (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "idle_ev_cc_setup"; - char *dialString; - char *referred_by_blind; - uint32_t dialStringLength = 0; - char *calledNumberTemp; - char *outputString = NULL; - uint32_t usernameLength = 0; - char *hostnameString = NULL; - uint32_t hostnameLength = 0; - char proxy_ipaddr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t proxy_ipaddr; - - char *extraString = NULL; - uint32_t extraLength = 0; - uint32_t n = 0; - static char dialtranslate[MAX_SIP_URL_LENGTH]; - char temp[MAX_IPADDR_STR_LEN]; - char line_name[MAX_LINE_NAME_SIZE]; - int port; - boolean sendInvite = FALSE; - char *tmpPtr = NULL; - cpr_ip_type ip_type = CPR_IP_ADDR_IPV4; - boolean replace = FALSE; - - CPR_IP_ADDR_INIT(proxy_ipaddr); - - ccb->gsm_id = event->u.cc_msg->msg.setup.call_id; - ccb->dn_line = event->u.cc_msg->msg.setup.line; - - /* - * Handlle replace info if there is any before taking in any - * dial string. - */ - if (ccsip_is_replace_setup(event->u.cc_msg->msg.setup.replaces)) { - replace = TRUE; - if (!ccsip_set_replace_info(ccb, &event->u.cc_msg->msg.setup)) { - /* The replace info failed */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"ignore setup, no replace info for" - " replace setup request\n", DEB_F_PREFIX_ARGS(SIP_REP, fname)); - return; - } - } - - ccsip_set_join_info(ccb, &event->u.cc_msg->msg.setup); - - dialString = (char *) event->u.cc_msg->msg.setup.caller_id.called_number; - referred_by_blind = event->u.cc_msg->msg.setup.redirect.redirects[0].number; - dialStringLength = strlen(dialString); - if ((0 == dialStringLength) && !replace) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No Digits to dial", fname); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } else if (!dialStringLength && replace) { - dialString = (char *) event->u.cc_msg->msg.setup.caller_id.calling_number; - dialStringLength = strlen(dialString); - } - - /* - * Save away what they sent us so that we can display it to them later - * - * Note: Currently only dialString which is obtained from - * event->u.cc_msg->msg.setup.caller_id.called_number is needed - * by SIP stack. Make a duplicate copy of the field. If more - * fields are needed from the caller_id from the setup msg. - * then the better use of the cc_mv_caller_id() API to move - * caller IDs from the setup to local storage is more efficient. - */ - ccb->calledDisplayedName = strlib_update(ccb->calledDisplayedName, - dialString); - - memset(proxy_ipaddr_str, 0, MAX_IPADDR_STR_LEN); - memset(temp, 0, sizeof(temp)); - - - sip_util_get_new_call_id(ccb); - ccb->featuretype = CC_FEATURE_NONE; - /* - * Get the listen port from the Transport Interface - * instead of the direct config. - */ - ccb->local_port = sipTransportGetListenPort(ccb->dn_line, ccb); - - /* - * Normalize the name. This means adding u.cc_msg->msg.setup.redirect.redirects[0].number[0] != '\0') { - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, - referred_by_blind); - ccb->blindtransferred = TRUE; - } - if (event->u.cc_msg->msg.setup.redirect.redirects[0].number[0] != '\0') { - strlib_free(event->u.cc_msg->msg.setup.redirect.redirects[0].number); - } - - /* - * See if the string needs to be rewritten by applying the dial template - */ - ccb->routeMode = RouteDefault; - -#define CAST_N (int32_t *) - - (void) MatchDialTemplate(ccb->calledDisplayedName, ccb->dn_line, CAST_N & n, dialtranslate, - sizeof(dialtranslate), (RouteMode *) & (ccb->routeMode), NULL); - dialString = dialtranslate; - dialStringLength = strlen(dialString); - - /* - * Throw away any display name part before LAQUOT(<), if there is one - * Ex: "Test Test" - Display string is "Test Test" - * Ex: Test Test - Display string is "Test Test" - * Ex: - No Display string - * Ex: sip:31@172.18.192.230 - No Display string - * Ex: 31@172.18.192.230 - No Display string - * - * the last two examples have no LAQUOT and RAQUOT in them - * - */ - - tmpPtr = strchr(dialString, '<'); - if (tmpPtr) { - dialString = tmpPtr; - dialStringLength = strlen(dialString); - } - - /* - * Throw away any part of 0) && (dialString[0] == '<')) { - dialString++; - dialStringLength--; - } - - /* - * For the SIP: part, we have to have 4 characters - */ - if (!cpr_strncasecmp(dialString, "sip:", 4)) { - dialStringLength -= 4; - dialString += 4; - } - - /* - * Parse the remainder of the string looking for the host name - */ - for (n = 0; n <= dialStringLength; n++) { - /* - * If we hit the end of the string without encountering a ; or > - * then we want to put the entire string into the user name if - * no host name was encountered or if we found a '@' along the - * way we want to put the residual into the host name - */ - if (n == dialStringLength) { - if (hostnameString == NULL) { - usernameLength = n; - } else { - hostnameLength = n - usernameLength - 1; //Accounts for @ - } - } else if ((dialString[n] == '@') && (hostnameString == NULL)) { - /* - * We encountered an @ separator for the host name, so take - * everything before the @ and put it into the user name - */ - usernameLength = n; - hostnameString = dialString + n + 1; - } else if ((dialString[n] == ';') || (dialString[n] == '>')) { - /* - * We hit the separator character (; or >). Take what we have - * seen and append it to the host name (if we already saw the @) - * or to the user name if not - */ - if (hostnameString == NULL) { - usernameLength = n; - } else { - hostnameLength = n - usernameLength - 1; // Accounts for @ - } - extraString = dialString + n; - extraLength = dialStringLength - n; - break; - } - } - /* - * At this point we have - * usernameLength - Number of characters in the user name - * starting from dialString[0] - * hostnameString - NULL if no @ was encountered, otherwise it - * points to the start of the host name string - * hostnameLength - 0 if no host name characters were encountered - * extraString - Points to any extra parameters - * extraLength - number of extra parameter characters - */ - switch (ccb->routeMode) { - case RouteEmergency:{ - /* - * If we have failed over to the backup we need - * to not reselect the emergency proxy - */ - if (ccb->proxySelection != SIP_PROXY_BACKUP) { - // Get the Emergency Proxy - sipTransportGetEmerServerAddress(ccb->dn_line, proxy_ipaddr_str); - if (hostnameLength == 0) { - hostnameString = proxy_ipaddr_str; - hostnameLength = strlen(proxy_ipaddr_str); - } - if (proxy_ipaddr_str[0]) { - if (!str2ip((const char *)proxy_ipaddr_str, &proxy_ipaddr)) { - /* Fill in address and port in CCB */ - util_ntohl(&(ccb->dest_sip_addr), &proxy_ipaddr); - /* - * If the Proxy Emergency Port isn't contained in the - * config table, use the PROXYN port instead. - */ - port = sipTransportGetEmerServerPort(ccb->dn_line); - if (port) { - ccb->dest_sip_port = (uint32_t)port; - } else { - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - break; - } - } - } - // Otherwise Emergency proxy is not in configuration follow thru. Let - // static analysis know this is intentional - /*FALLTHROUGH*/} - default: - ip_type = sipTransportGetPrimServerAddress(ccb->dn_line, temp); - if (hostnameLength == 0) { - hostnameString = temp; - hostnameLength = strlen(hostnameString); - } - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr),ccb->dn_line); - if (util_check_if_ip_valid(&(ccb->dest_sip_addr))) { - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Unable to reach proxy, attempting backup.\n", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - if (!ccsip_attempt_backup_proxy(ccb)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Attempt to reach backup proxy failed.\n", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"INVITE will be broadcast.\n", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - } - } - } - - /* Pre-fill the ARP table */ - ADD_TO_ARP_CACHE(ccb->dest_sip_addr); - - /* - * Construct the actual dial out string - */ - calledNumberTemp = strlib_open(ccb->calledNumber, (MAX_SIP_URL_LENGTH * 2)); - outputString = calledNumberTemp; - sstrncpy(outputString, " - */ - outputString[extraLength] = 0; - /* - * If there was no > in what they gave us, put one in for them - */ - if (strchr(outputString, '>') == NULL) { - outputString[extraLength++] = '>'; - } - outputString += extraLength; - } else { - *outputString++ = '>'; - } - /* - * Null terminate the string for good measure and note how long it is - */ - *outputString = 0; - ccb->calledNumber = strlib_close(calledNumberTemp); - if (ccb->calledNumber) { - ccb->calledNumberLen = (uint16_t) strlen(ccb->calledNumber); - } - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"All digits collected. Placing the call\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, sizeof(line_name)); - ccb->callingNumber = strlib_update(ccb->callingNumber, line_name); - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"SIPSM %d: Setup\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), ccb->index); - - /* Copy the call-info into the CCB */ - ccsip_store_call_info(&event->u.cc_msg->msg.setup.call_info, ccb); - - /* Send INVITE */ - - /* Save the GSM's msg. bodies for future used */ - ccsip_save_local_msg_body(ccb, &event->u.cc_msg->msg.setup.msg_body); - - /* - * CC_REDIRECT_REASON_DEFLECTION shows that this is an attended transfer - */ - // Note that the extra body parts will be automatically deleted - if (event->u.cc_msg->msg.setup.redirect.redirects[0].redirect_reason - == CC_REDIRECT_REASON_DEFLECTION) { - sendInvite = sipSPISendInvite(ccb, SIP_INVITE_TYPE_TRANSFER, TRUE); - } else { - sendInvite = sipSPISendInvite(ccb, SIP_INVITE_TYPE_NORMAL, TRUE); - } - - if (sendInvite == TRUE) { - sip_sm_change_state(ccb, SIP_STATE_SENT_INVITE); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPISendInvite failed", fname); - if (event->u.cc_msg->msg.setup.redirect.redirects[0].redirect_reason - == CC_REDIRECT_REASON_DEFLECTION) { - /* - * Sending replaces invite for attended transfer has failed. - * Clean up here because a release complete from GSM - * is not guaranteed here like in the case of pre-mature - * attended transfer request. A cause value of normal - * causes GSM to clean up the UI as well. - */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL, NULL); - sip_sm_call_cleanup(ccb); - } else { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - - } - -} - - -/* - * - ***** SIP_STATE_SENT_INVITE - * - */ -void -ccsip_handle_sentinvite_ev_sip_1xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentinvite_ev_sip_1xx"; - sipMessage_t *response; - sipRespLine_t *respLine; - int status_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - /* - * Update the Tags here so that they will be correct if - * the user transfers a ringing call. - */ - sip_sm_200and300_update(ccb, response, status_code); - - sip_decrement_backup_active_count(ccb); - - /* Mark the CCB as having received a 1xx response */ - ccb->flags |= RECD_1xx; - - if (status_code != SIP_1XX_TRYING) { - /* Reset credentials flag since INVITE was successfully processed */ - ccb->authen.cred_type = 0; - } - - switch (status_code) { - - case SIP_1XX_TRYING: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), ccb->index, - ccb->dn_line, fname, sip_util_state2string(ccb->state), - "SIP 100 TRYING"); - /* - * Update connected party info from RPID and Call-Info header. - * Do not delay call info update to UI with proceeding. There is - * no media event with the proceeding that can cause UI update - * automatically. - */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - free_sip_message(response); - sip_cc_proceeding(ccb->gsm_id, ccb->dn_line); - return; - - case SIP_1XX_RINGING: - { - sipsdp_status_t sdp_status; - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s <- SIP 180 RINGING\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - - /* check for alert-info in header. - * Commented out until DSP upgrade - alert_info = sippmh_get_header_val(request, SIP_HEADER_ALERT_INFO, - NULL); - ccb->alert_info = ALERTING_NONE; - if (alert_info) { - parseAlertingHeader(ccb, alert_info); - } - */ - sdp_status = sip_util_extract_sdp(ccb, response); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_IDLE; - /* ccsip_update_callinfo needs to occur before cc_alerting */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, TRUE); - sip_cc_alerting(ccb->gsm_id, ccb->dn_line, response, TRUE); - break; - - case SIP_SDP_NOT_PRESENT: - /* ccsip_update_callinfo needs to occur before cc_alerting */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, TRUE); - sip_cc_alerting(ccb->gsm_id, ccb->dn_line, NULL, 0); - break; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_NO_MEDIA: - case SIP_SDP_ERROR: - default: - sipSPISendCancel(ccb); - free_sip_message(response); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - /* - * Update connected party info from RPID and Call-Info header. - * The call update to UI can be delayed due to altert processing - * can potentially manipulate media or port. - */ - free_sip_message(response); - return; - - } /* case SIP_1XX_RINGING */ - case SIP_1XX_SESSION_PROGRESS: - { - sipsdp_status_t sdp_status; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), ccb->index, - ccb->dn_line, fname, sip_util_state2string(ccb->state), - "SIP 183 IN BAND SESSION PROGRESS"); - - sdp_status = sip_util_extract_sdp(ccb, response); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_IDLE; - break; - - case SIP_SDP_NOT_PRESENT: - // In this case no SDP is present in the 183 message. - // Call flows exist where a callee may send 183 with no SDP and - // the right way to handle it is to remain in the same state. - // DDTS for reference is CSCdu17240 - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - free_sip_message(response); - return; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_NO_MEDIA: - case SIP_SDP_ERROR: - default: - sipSPISendCancel(ccb); - free_sip_message(response); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - /* - * Update connected party info from RPID and Call-Info header. - * The call update to UI can be delayed due to altert processing - * can potentially manipulate media or port. - */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, TRUE); - sip_cc_alerting(ccb->gsm_id, ccb->dn_line, response, TRUE); - - /*UI-STATE tag with value of "BUSY" is being sent to indicate the busy line - *and to support callback feature. GSM needs to be informed so it can - *trigger the LSM to transition to BUSY state and display appropriate - *softkeys. - */ - if ((ccb->in_call_info) && - (ccb->in_call_info->data.call_info_feat_data.feature_flag & CC_UI_STATE) && - (ccb->in_call_info->data.call_info_feat_data.ui_state == CC_UI_STATE_BUSY)) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"DETECTED UI_STATE=BUSY IN 183.\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_UI_STATE_BUSY, NULL); - } - free_sip_message(response); - return; - } /* case SIP_1XX_SESSION_PROGRESS */ - - case SIP_1XX_CALL_FWD: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s <- SIP 181 CALL IS BEING" - "FORWARDED\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - free_sip_message(response); - sip_cc_proceeding(ccb->gsm_id, ccb->dn_line); - return; - - case SIP_1XX_QUEUED: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s <- SIP 182 QUEUED\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - free_sip_message(response); - sip_cc_proceeding(ccb->gsm_id, ccb->dn_line); - return; - - default: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s <- SIP BAD 1xx\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - free_sip_message(response); - return; - } -} - - -void -ccsip_handle_sentinvite_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentinvite_ev_sip_2xx"; - sipMessage_t *response; - const char *contact = NULL; - sipsdp_status_t sdp_status; - string_t recv_info_list = strlib_empty(); - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Check if this is an INVITE response */ - if (!sip_sm_is_invite_response(response)) { - sipMethod_t method = sipMethodInvalid; - int response_code = 0; - - // If this is a 202 response to a REFER, we should handle it separately - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - - if (response_code == SIP_ACCEPTED && method == sipMethodRefer) { - ccsip_handle_accept_2xx(ccb, event); - return; - } - free_sip_message(response); - clean_method_request_trx(ccb, method, TRUE); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - - /* - * Record the "tag=" parameter. - * Update To/From (to capture tag). Also Contact, and Record-Route - */ - sip_sm_200and300_update(ccb, response, SIP_STATUS_SUCCESS); - - /* Reset credentials flag since INVITE was successfully processed */ - ccb->authen.cred_type = 0; - - sip_decrement_backup_active_count(ccb); - (void) sip_platform_expires_timer_stop(ccb->index); - /* Check Contact header */ - contact = sippmh_get_cached_header_val(response, CONTACT); - if (contact) { - if (sipSPICheckContact(contact) < 0) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPICheckContact()"); - free_sip_message(response); - ccb->authen.cred_type = 0; - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - return; - } - } - - /* Extract destination SDP and related fields */ - sdp_status = sip_util_extract_sdp(ccb, response); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_IDLE; - break; - - case SIP_SDP_NOT_PRESENT: - break; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_NO_MEDIA: - case SIP_SDP_ERROR: - default: - /* First Ack and then send Bye to the far end */ - if (sipSPISendAck(ccb, response) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - free_sip_message(response); - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - if (ccb->wastransferred) { - /* - * The referred call was implicitly subscribed for the - * notification. Since we get the Error from target we - * need to send this notify to transferor - */ - cc_feature_data_t data; - - data.notify.cause = CC_CAUSE_ERROR; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *) &data); - } - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - /* - * Parse the diversion header which could be present, as in case of - * Auto Pick up - */ - ccsip_parse_diversion_header (ccb, response); - - /* Info Package stuff */ - ccsip_parse_send_info_header(response, &recv_info_list); - - /* - * Update connected party info from RPID and Call-Info header. - * The call update to UI can be delayed due to connected processing - * manipulates media or port. - */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, TRUE); - sip_cc_connected(ccb->gsm_id, ccb->dn_line, recv_info_list, response); - - strlib_free(recv_info_list); - - /* Deallocate the memory for the response */ - free_sip_message(response); - sip_sm_change_state(ccb, SIP_STATE_SENT_INVITE_CONNECTED); - - /* - * The referred call was implicitely subscribed for the notification. - * Since we get the 200 OK from target we need to send this notify - * to transferor. So make a feature request to the GSM - */ - if ((ccb->wastransferred) || (ccb->blindtransferred == TRUE)) { - cc_feature_data_t data; - - data.notify.cause = CC_CAUSE_OK; - data.notify.cause_code = SIP_SUCCESS_SETUP; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = - sip_sm_get_blind_xfereror_ccb_by_gsm_id(ccb->gsm_id); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *) &data); - strlib_free(ccb->sipxfercallid); - ccb->sipxfercallid = strlib_empty(); - } else if (ccb->flags & SENT_INVITE_REPLACE) { - strlib_free(ccb->sipxfercallid); - ccb->sipxfercallid = strlib_empty(); - } -} - - -/* - * - ***** SIP_STATE_RELEASING - * - */ - -void -ccsip_handle_sentbye_recvd_invite (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sipMessage_t *request; - - /* Unpack the event */ - request = event->u.pSipMessage; - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, 0, NULL, NULL); - free_sip_message(request); -} - -void -ccsip_handle_release_complete (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "release_complete"; - - if (ccb->blind_xfer_call_id == CC_NO_CALL_ID) { - if (!ccb->wait_for_ack) { - if ((ccb->flags & RECD_BYE) && (ccb->last_request)) { - (void) sipSPISendByeOrCancelResponse(ccb, ccb->last_request, sipMethodBye); - ccb->flags &= ~RECD_BYE; - } - if (!(sip_platform_msg_timer_outstanding_get(ccb->index))) { - sip_sm_call_cleanup(ccb); - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"INFO: waiting for Invite Response Ack " - "before clearing call\n", DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - /* - * Restart the disconnect timer. Call to start will also stop - * the timer if it is currently running. - */ - (void) sip_platform_supervision_disconnect_timer_start( - SUPERVISION_DISCONNECT_TIMEOUT, ccb->index); - } - } else { - /* - * Wait for the transfered call to finish and then we have - * to send Notify for the transferred call to the transferror. - * HACK to please customer. - */ - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - sip_sm_change_state(ccb, SIP_STATE_BLIND_XFER_PENDING); - } -} - -void -ccsip_handle_sentbye_ev_sip_1xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentbye_ev_sip_1xx"; - sipMessage_t *response; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Check if this is an BYE/CANCEL response */ - if (!sip_sm_is_bye_or_cancel_response(response)) { - if (sip_sm_is_invite_response(response)) { - // It could be an INVITE response if user opted to end the call - // before we received a 1xx from the remote end - // Send the deferred CANCEL now - if (ccb->flags & SEND_CANCEL) { - sipSPISendCancel(ccb); - } - } - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - /* - * Restart the disconnect timer. Call to start will also stop - * the timer if it is currently running. - */ - (void) sip_platform_supervision_disconnect_timer_start( - SUPERVISION_DISCONNECT_TIMEOUT, ccb->index); - free_sip_message(response); -} - -void -ccsip_handle_sentbye_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentbye_ev_sip_2xx"; - sipMessage_t *response; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Check if this is not a response to either CANCEL or BYE */ - if (!sip_sm_is_bye_or_cancel_response(response)) { - /* Check if this is an INVITE response */ - - //Check if the response to an INVITE and we have sent out a CANCEL - if (sip_sm_is_invite_response(response) && - (get_method_request_trx_index(ccb, sipMethodCancel, TRUE) != -1)) { - /* - * We have an outgoing CANCEL and 200 OK(INVITE) cross on the wire. - * - * We may have sent a CANCEL and around the same time, - * UAS may have responded with a 200 OK(INVITE) and - * so the CANCEL and 200 OK(INVITE) cross on the wire. - * So, the CANCEL is now useless. - * - * Actions: - * send ACK to satisfy 200 OK(INVITE) - * send BYE to initiate hangup since CANCEL is now useless - */ - char *to_tag, *sip_to_temp; - - to_tag = strstr(ccb->sip_to,";tag"); - /* - * Add the to_tag to the Ack and Bye message if it is not - * already present. - */ - if (!to_tag) { - sip_to_temp = strlib_open(ccb->sip_to, MAX_SIP_URL_LENGTH); - if (sip_to_temp) { - sstrncat(sip_to_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - if (ccb->sip_to_tag) { - sstrncat(sip_to_temp, ccb->sip_to_tag, - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - } - } - ccb->sip_to = strlib_close(sip_to_temp); - } - - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - sipSPISendBye(ccb, NULL, NULL); - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX" %d %s Cross-over situation CANCEL/200 OK(INVITE).\n", - DEB_L_C_F_PREFIX_ARGS(SIP_ACK, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - } else { - //This 200 OK is not related to BYE, CANCEL, nor INVITE - //We still need to account for it remove the transaction - sipMethod_t method = sipMethodInvalid; - - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - - clean_method_request_trx(ccb, method, TRUE); - } - - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - (void) sip_platform_expires_timer_stop(ccb->index); - if (!ccb->send_delayed_bye) { - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - } - - if (!ccb->wait_for_ack) { - sip_sm_call_cleanup(ccb); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"INFO: waiting for Invite Response Ack " - "before clearing call\n", DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - /* - * Restart the disconnect timer. Call to start will also stop - * the timer if it is currently running. - */ - (void) sip_platform_supervision_disconnect_timer_start( - SUPERVISION_DISCONNECT_TIMEOUT, ccb->index); - } - free_sip_message(response); -} - - -/* - * Just respond to the Bye in the Release state. - */ -void -ccsip_handle_release_ev_sip_bye (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "blindxfr_ev_sip_bye"; - sipMessage_t *request; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMethod_t method = sipMethodInvalid; - - memset(request_check_reason_phrase, 0, SIP_WARNING_LENGTH); - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* Request check and store */ - sipGetRequestMethod(request, &method); - if (sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - (void) sipSPISendByeOrCancelResponse(ccb, request, sipMethodBye); -} - - -void -ccsip_handle_sentblindntfy_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sipMessage_t *response; - - /* Unpack the event */ - response = event->u.pSipMessage; - (void) sip_platform_expires_timer_stop(ccb->index); - - if (ccb->flags & FINAL_NOTIFY) { - sip_sm_call_cleanup(ccb); - } else { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - } - - free_sip_message(response); -} - - -void -ccsip_handle_sendbye_ev_supervision_disconnect (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - - (void) sip_platform_expires_timer_stop(ccb->index); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - sip_sm_call_cleanup(ccb); -} - -/** - * - * Handler for SIP_STATE_RELEASE features. Currently only CANCEL feature is - * supported in this state. - * - * @param line, ccb, event - * - * @return void - * - * @pre (event not NULL) - */ -/* - * SIP_STATE_RELEASE - */ -void -ccsip_handle_release_ev_cc_feature (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "release_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - cc_feature_name(feature_type)); - - switch (feature_type) { - case CC_FEATURE_CANCEL: - break; - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - break; - } -} - -/** - * - * Handler for event RELEASE at SIP_STATE_RELEASE. - * sipstack is waiting for RELEASE_COMPLETE from gsm, but it got RELEASE from gsm. - * so we know that gsm also want to release the call. - * to avoid defects like CSCtg46399, we need to send RELEASE_COMPLETE to both sipstack & gsm, - * then sipstack & gsm will not wait for each other, and the call can be cleared on both sides. - * - */ -void -ccsip_handle_release_ev_release (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "release_ev_release"; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - "sipstack at SIP_STATE_RELEASE received a RELEASE event from gsm"); - - /* send RELEASE_COMPLETE to sipstack */ - ccsip_handle_release_complete(ccb, event); - - /* send RELEASE_COMPLETE to gsm */ - ccsip_handle_sendbye_ev_supervision_disconnect(ccb, event); -} - - -void -ccsip_handle_recv_error_response_ev_sip_ack (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - sipMessage_t *response; - - /* Unpack the event */ - response = event->u.pSipMessage; - - ccb->wait_for_ack = FALSE; - - if (ccb->send_delayed_bye) { - // If we need to send a bye, do it now. Do not change state. Clean up - // the CCB once we receive the OK for the BYE - sipSPISendBye(ccb, NULL, NULL); - } else { - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - sip_sm_call_cleanup(ccb); - } - - free_sip_message(response); -} - -void -ccsip_handle_sentbye_ev_sip_fxx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentbye_ev_sip_fxx"; - sipMessage_t *response; - sipRespLine_t *respLine = NULL; - int status_code = 0; - const char *authenticate = NULL; - credentials_t credentials; - sip_authen_t *sip_authen = NULL; - char *author_str = NULL; - boolean good_authorization = FALSE; - const char *rsp_method = NULL; - char *alsoString = NULL; - sipMethod_t method = sipMethodInvalid; - enum { - INVALID, - RESP_OF_BYE, - RESP_OF_CANCEL, - RESP_OF_NOTIFY, - RESP_OF_INVITE - } resp_type = INVALID; - - /* Unpack the event */ - response = event->u.pSipMessage; - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - switch (method) { - case sipMethodInvite: - resp_type = RESP_OF_INVITE; - rsp_method = SIP_METHOD_INVITE; - break; - case sipMethodBye: - resp_type = RESP_OF_BYE; - rsp_method = SIP_METHOD_BYE; - break; - case sipMethodCancel: - resp_type = RESP_OF_CANCEL; - rsp_method = SIP_METHOD_CANCEL; - break; - case sipMethodNotify: - resp_type = RESP_OF_NOTIFY; - rsp_method = SIP_METHOD_NOTIFY; - break; - default: - resp_type = INVALID; - break; - } - - if (INVALID == resp_type) { - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - if (ccb->state == SIP_STATE_BLIND_XFER_PENDING) { - /* Got an error Response for Notify Message - * Just clean up at this point. - */ - sip_sm_call_cleanup(ccb); - } - return; - } - - sip_decrement_backup_active_count(ccb); - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - - if ((strcmp(rsp_method, SIP_METHOD_INVITE) == 0) && - (status_code == SIP_SERV_ERR_INTERNAL)) { - /* - * This is likely a late arriving 500 response to INVITE. - * We are already in the releasing stage of the call having - * sent a CANCEL that crossed with the 500 response. - * Just ACK the 500 and return. - */ - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Acking delayed 500 response to INVITE " - "request\n", DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - return; - } - - - switch (status_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, AUTH_BUGINF(status_code)); - - if (cred_get_credentials_r(ccb, &credentials) == FALSE) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"retries exceeded: %d/%d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->authen.cred_type, MAX_RETRIES_401); - - free_sip_message(response); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR); - sip_sm_call_cleanup(ccb); - return; - } - - authenticate = sippmh_get_header_val(response, AUTH_HDR(status_code), NULL); - if (authenticate != NULL) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Authenticate header %s= %s\n", DEB_F_PREFIX_ARGS(SIP_STATE, fname), - AUTH_HDR_STR(status_code), authenticate); - ccb->retx_counter = 0; - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen) { - ccb->authen.new_flag = FALSE; - ccb->authen.cnonce[0] = '\0'; - if (sipSPIGenerateAuthorizationResponse(sip_authen, ccb->ReqURI, - rsp_method, credentials.id, - credentials.pw, - &author_str, - &(ccb->authen.nc_count), - ccb)) - { - good_authorization = TRUE; - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - if (ccb->authen.sip_authen != NULL) { - sippmh_free_authen(ccb->authen.sip_authen); - ccb->authen.sip_authen = NULL; - } - ccb->authen.authorization = (char *) - cpr_malloc(strlen(author_str) * sizeof(char) + 1); - - /* - * Cache the Authorization header so that it can be used for - * later requests - */ - if (ccb->authen.authorization != NULL) { - sstrncpy(ccb->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - ccb->authen.status_code = status_code; - ccb->authen.sip_authen = sip_authen; - } - - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Authorization header " - "build unsuccessful\n", fname); - } - /* - * CSCds70538 - * Do not free the sip_authen structure if the Authorization - * build was successful. We will need these values to generate - * an Authorization header for the BYE response - */ - if (good_authorization == FALSE) { - sippmh_free_authen(sip_authen); - } - } - if (strcmp(rsp_method, SIP_METHOD_BYE) == 0) { - clean_method_request_trx(ccb, sipMethodBye, TRUE); - if (ccb->referto[0]) { - alsoString = (char *) cpr_malloc(MAX_SIP_URL_LENGTH); - if (!alsoString) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "malloc(also string)"); - sipSPISendBye(ccb, NULL, NULL); - return; - } - sstrncpy(alsoString, ccb->referto, MAX_SIP_URL_LENGTH); - sipSPISendBye(ccb, alsoString, NULL); - cpr_free(alsoString); - return; - } - /* Send BYE message */ - sipSPISendBye(ccb, NULL, NULL); - } else if (strcmp(rsp_method, SIP_METHOD_CANCEL) == 0){ - sipSPISendCancel(ccb); - } else { - (void) sipSPISendNotify(ccb, ccb->xfer_status); - } - - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"401/407 response missing " - "Authenticate\n", fname); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR); - sip_sm_call_cleanup(ccb); - } - free_sip_message(response); - return; - - - case SIP_CLI_ERR_LOOP_DETECT: - case SIP_CLI_ERR_BUSY_HERE: - case SIP_CLI_ERR_MANY_HOPS: - case SIP_CLI_ERR_AMBIGUOUS: - case SIP_CLI_ERR_REQ_CANCEL: - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - - (void) sip_platform_expires_timer_stop(ccb->index); - if (!ccb->send_delayed_bye) { - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - } - - if (!ccb->wait_for_ack) { - sip_sm_call_cleanup(ccb); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"waiting for Invite Response Ack " - "before clearing call\n", DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - /* - * Restart the disconnect timer. Call to start will also stop - * the timer if it is currently running. - */ - (void) sip_platform_supervision_disconnect_timer_start( - SUPERVISION_DISCONNECT_TIMEOUT, ccb->index); - } - - free_sip_message(response); - return; - - case SIP_SERV_ERR_NOT_IMPLEM: - /* It's an error response to a notify. rfc3515 tells us: - * Terminating a subscription, - * either by explicitly unsubscribing or rejecting NOTIFY, is not an - * indication that the referenced request should be withdrawn or - * abandoned. - */ - - if (strcmp (rsp_method,SIP_METHOD_NOTIFY) == 0){ - //ignore error - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Ignoring NOTIFY error. But clean up " - "transaction.\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - - if (ccb->flags & FINAL_NOTIFY) { - sip_sm_call_cleanup(ccb); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Ignoring NOTIFY error. but " - "cleaning up call.\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } - free_sip_message(response); - return; - } - /*FALLTHROUGH*/ - - default: - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR); - sip_sm_call_cleanup(ccb); - free_sip_message(response); - return; - } -} - -/* - * Function: ccsip_handle_sentinvite_ev_sip_3xx - * - * Parameters: CCB and the event - * - * Description: Sends ack for 3xx events and appropriate invite - * - * Returns: void - * - */ -void -ccsip_handle_sentinvite_ev_sip_3xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentinvite_ev_sip_3xx"; - sipMessage_t *response; - sipRespLine_t *respLine; - uint16_t status_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - - sip_decrement_backup_active_count(ccb); - - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - switch (status_code) { - case SIP_RED_MULT_CHOICES /* 300 */: - case SIP_RED_MOVED_PERM /* 301 */: - case SIP_RED_MOVED_TEMP /* 302 */: - case SIP_RED_USE_PROXY /* 305 */: - /* - * Record the "tag=" parameter. - * Update To/From (to capture tag). Also Contact, and Record-Route - */ - sip_sm_update_to_from_on_callsetup_finalresponse(ccb, response); - sip_sm_update_contact_recordroute(ccb, response, status_code, - FALSE /* not midcall */); - - /* - * Send ACK to the original INVITE destination or to the address - * specified by the Record-Route - */ - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - - /* Reset credentials flag before attempting redirect */ - ccb->authen.cred_type = 0; - ccb->first_pass_3xx = TRUE; - sip_redirect(ccb, response, status_code); - - break; - default: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d %d unsupported\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, status_code); - break; - } - - free_sip_message(response); -} - -void -handle_error_for_state (ccsipCCB_t *ccb, int status_code) -{ - ccsipCCB_t *referccb = NULL; - cc_causes_t fail_reason = CC_CAUSE_MIN; - - if (ccb->state == SIP_STATE_SENT_INVITE) { - if (status_code == SIP_CLI_ERR_BUSY_HERE) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_BUSY, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if (status_code == SIP_SERV_ERR_UNAVAIL) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_CONGESTION, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if (status_code == SIP_CLI_ERR_NOT_AVAIL) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_TEMP_NOT_AVAILABLE, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if ((status_code == SIP_CLI_ERR_MEDIA) || - (status_code == SIP_CLI_ERR_NOT_ACCEPT_HERE) || - (status_code == SIP_FAIL_NOT_ACCEPT)) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_PAYLOAD_MISMATCH, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if (status_code == SIP_SERV_ERR_INTERNAL) { - // This is used to indicate a successful cfwdall interaction - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_REMOTE_SERVER_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - - } else if (((status_code == SIP_CLI_ERR_BAD_REQ) || - (status_code == SIP_CLI_ERR_CALLEG)) && - (ccb->wastransferred)) { - /* clean up here because a release complete from GSM - * is not guaranteed here like in the case of pre-mature - * attended transfer request. A cause value of normal - * causes GSM to clean up the UI as well. - */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL, NULL); - sip_sm_call_cleanup(ccb); - } else if (status_code == SIP_CLI_ERR_NOT_FOUND) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NOT_FOUND, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } else if (status_code == SIP_CLI_ERR_REQ_CANCEL) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NO_USER_ANS, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } else { - /* - * This should take care of miscellaneous errors including 400 - * bad request when its not a transfer. No special handling is - * done in case of 491 SIP_CLI_ERR_REQ_PENDING as that error is - * treated like any other 4xx in this state - */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - if (ccb->blindtransferred == TRUE) { - cc_feature_data_t data; - - data.notify.cause = CC_CAUSE_ERROR; - data.notify.cause_code = status_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = sip_sm_get_blind_xfereror_ccb_by_gsm_id(ccb->gsm_id); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *) &data); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - - /* make sure to send the Notify if we are in a transfer - * scenario. This way the transferor can cleanup properly. - */ - if (ccb->wastransferred) { - referccb = sip_sm_get_target_call_by_gsm_id(ccb->gsm_id); - if (referccb != NULL) { - ccb->flags |= FINAL_NOTIFY; - (void) sipSPISendNotify(referccb, status_code); - ccb->xfer_status = status_code; - } - } - } else if (ccb->state == SIP_STATE_ACTIVE) { - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NONE, NULL, - CC_CAUSE_ERROR); - } else if (ccb->state == SIP_STATE_SENT_MIDCALL_INVITE) { - if (status_code == SIP_CLI_ERR_BUSY_HERE) { - fail_reason = CC_CAUSE_BUSY; - } else if ((status_code == SIP_CLI_ERR_MEDIA) || - (status_code == SIP_CLI_ERR_NOT_ACCEPT_HERE) || - (status_code == SIP_FAIL_NOT_ACCEPT)) { - fail_reason = CC_CAUSE_PAYLOAD_MISMATCH; - } else if (status_code == SIP_CLI_ERR_REQ_PENDING) { - // The other side has sent us a 491. We will let GSM handle this error and - // we shall fall back to the state we were in prior to being in any of the - // states. These are: - fail_reason = CC_CAUSE_REQUEST_PENDING; - } else if (status_code == SIP_SERV_ERR_UNAVAIL) { - fail_reason = CC_CAUSE_SERV_ERR_UNAVAIL; - } else { - fail_reason = CC_CAUSE_ERROR; - } - - /* ack the feature */ - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, NULL, - fail_reason); - if (status_code == SIP_CLI_ERR_REQ_TIMEOUT) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } else { - /* Other error goes back to active, let GSM decide */ - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - } - } else if (ccb->state == SIP_STATE_BLIND_XFER_PENDING) { - if (status_code == SIP_CLI_ERR_REQ_TIMEOUT) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - } - if (ccb->wastransferred) { - /* - * The referred call was implicitely subscribed for the notification. - * Since we get the Error from target we need to send this notify - * to transferor. - */ - cc_feature_data_t data; - - data.notify.cause = fail_reason; - data.notify.cause_code = status_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *)&data); - } -} - - -void -ccsip_handle_sentinvite_ev_sip_fxx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sentinvite_ev_sip_fxx"; - sipMessage_t *response; - sipRespLine_t *respLine = NULL; - uint16_t status_code = 0; - const char *authenticate = NULL; - credentials_t credentials; - sip_authen_t *sip_authen = NULL; - char *author_str = NULL; - boolean good_authorization = FALSE; - sipMethod_t method = sipMethodInvalid; - const char *rsp_method = NULL; - - enum { - INVALID, - RESP_OF_INVITE, - RESP_OF_REFER, - RESP_OF_NOTIFY - } resp_type = INVALID; - - response = event->u.pSipMessage; - - /* Check if this is an INVITE response */ - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - switch (method) { - case sipMethodInvite: - resp_type = RESP_OF_INVITE; - rsp_method = SIP_METHOD_INVITE; - - /* Stop the expires timer started to await this response */ - (void) sip_platform_expires_timer_stop(ccb->index); - - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - break; - case sipMethodRefer: - resp_type = RESP_OF_REFER; - rsp_method = SIP_METHOD_REFER; - break; - case sipMethodNotify: - resp_type = RESP_OF_NOTIFY; - rsp_method = SIP_METHOD_NOTIFY; - break; - default: - resp_type = INVALID; - break; - } - - if (INVALID == resp_type) { - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - /* - * Update the Tags here so that they will be correct if - * the user transfers a ringing call. - */ - sip_sm_200and300_update(ccb, response, status_code); - - // If the resp_type is RESP_OF_REFER and the feature type is one of the - // extendedrefer features, and the reason code is not a failure of authentication - // then indicate the error condition back to GSM - if (resp_type == RESP_OF_REFER) { - switch (ccb->featuretype) { - case CC_FEATURE_B2BCONF: - case CC_FEATURE_SELECT: - case CC_FEATURE_CANCEL: - if (status_code != SIP_CLI_ERR_UNAUTH && status_code != SIP_CLI_ERR_PROXY_REQD) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Received error response for ext refer\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, NULL, - CC_CAUSE_ERROR); - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - free_sip_message(response); - return; - } - /*FALLTHROUGH*/ - default: - break; - } - } - - sip_decrement_backup_active_count(ccb); - - switch (status_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"SIP_CLI_ERR_PROXY_REQD: %d: %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, AUTH_BUGINF(status_code)); - - /* Send ACK */ - if (method == sipMethodInvite) { - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - } - - if (cred_get_credentials_r(ccb, &credentials) == FALSE) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"retries exceeded: %d/%d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->authen.cred_type, MAX_RETRIES_401); - /* - * Retries exceeded for 40X could be due to remote end - * not responding to our Request, and while we are retrying, - * proxy could ask us to reauthenticate. So, we may exceed - * retries for credentials due to some other reason than just - * auth failure, but we do not care. status_code is passed. - */ - - handle_error_for_state(ccb, status_code); - free_sip_message(response); - return; - } - - authenticate = sippmh_get_header_val(response, AUTH_HDR(status_code), - NULL); - if (authenticate != NULL) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Authenticate header %s= %s\n", DEB_F_PREFIX_ARGS(SIP_AUTH, fname), - AUTH_HDR_STR(status_code), authenticate); - - ccb->retx_counter = 0; - - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen) { - ccb->authen.new_flag = FALSE; - /* We are sure at this point that it is either a response of - * INVITE or REFER and nothing else - */ - ccb->authen.cnonce[0] = '\0'; - ccb->authen.nc_count = 0; // New nonce, hence reset - if (sipSPIGenerateAuthorizationResponse(sip_authen, - ccb->ReqURI, - rsp_method, - credentials.id, - credentials.pw, - &author_str, - &(ccb->authen.nc_count), ccb)) { - - good_authorization = TRUE; - - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - - if (ccb->authen.sip_authen != NULL) { - sippmh_free_authen(ccb->authen.sip_authen); - ccb->authen.sip_authen = NULL; - } - - ccb->authen.authorization = (char *) cpr_malloc(strlen(author_str) * - sizeof(char) + 1); - - /* - * Cache the Authorization header so that it can be used for - * later requests - */ - if (ccb->authen.authorization != NULL) { - sstrncpy(ccb->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - ccb->authen.status_code = status_code; - ccb->authen.sip_authen = sip_authen; - } - - /* tell GSM we are trying */ - if (ccb->state == SIP_STATE_SENT_INVITE) { - sip_cc_proceeding(ccb->gsm_id, ccb->dn_line); - } - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Authorization header " - "build unsuccessful\n", fname); - } - /* - * CSCds70538 - * Do not free the sip_authen structure if the Authorization - * build was successful. We will need these values to generate - * an Authorization header for the BYE response - */ - if (good_authorization == FALSE) { - sippmh_free_authen(sip_authen); - } - } - - switch (resp_type) { - case RESP_OF_REFER: - /* We do not need to inform about this error to GSM */ - // Delete the previous transaction block - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - - { - boolean refer_sent = FALSE; - - switch (ccb->featuretype) { - case CC_FEATURE_B2BCONF: - case CC_FEATURE_SELECT: - case CC_FEATURE_CANCEL: - break; - default: - break; - } - - if (refer_sent) { - break; - } - } - - if (sipSPISendRefer(ccb, (char *) ccb->sip_referTo, SIP_REF_XFER) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPISendRefer Failed"); - } - break; - - case RESP_OF_INVITE: - if (ccb->state == SIP_STATE_SENT_INVITE) { - // Since we need to start a new Dialog we should clear - // any previous record route info - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - - (void) sipSPISendInviteMidCall(ccb, TRUE /* does expire */); - } else { - (void) sipSPISendInviteMidCall(ccb, FALSE /* doesn't expire */); - } - break; - case RESP_OF_NOTIFY: - // Delete the previous transaction block - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - if (sipSPISendNotify(ccb, ccb->xfer_status) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPISendNotify Failed"); - } - break; - default: - break; - } - } else { - if ((ccb->redirect_info != NULL) - && (method == sipMethodInvite) - && (ccb->state == SIP_STATE_SENT_INVITE)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"401/407 response missing " - "Authenticate, redirecting to next add.\n", fname); - sip_redirect(ccb, response, status_code); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"401/407 response missing " - "Authenticate\n", fname); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Clearing call\n", fname); - // Delete the previous transaction block - clean_method_request_trx(ccb, method, TRUE); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - } - - free_sip_message(response); - return; - - case SIP_CLI_ERR_NOT_ALLOWED: - case SIP_SERV_ERR_NOT_IMPLEM: - if (RESP_OF_REFER == resp_type) { - /* Error occurred on the target end so need to inform transferror */ - /* - * Since REFER method is not implemented at far side we got - * this error, at this point we need to switch to BYE/ALSO - * method. It is assumed that BYE/ALSO will be successful; - * otherwise, any way this call will be disconnected without - * any notification to the enduser which is normal if you - * use BYE/ALSO anyway. So fill up the cause as CC_CAUSE_OK - * and mimic as if transfer is done through BYE/ALSO and - * have GSM to disconnect and post us a disconnect local with - * also string - */ - cc_feature_data_t data; - - // Delete the previous transaction block - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - - ccb->referto = strlib_update(ccb->referto, ccb->sip_referTo); - data.notify.cause = CC_CAUSE_OK; - data.notify.cause_code = status_code; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_BYE; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *) &data); - } - if (method == sipMethodInvite) { - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - if ((ccb->redirect_info != NULL) && - (ccb->state == SIP_STATE_SENT_INVITE)) { - sip_redirect(ccb, response, status_code); - } else { - handle_error_for_state(ccb, status_code); - } - } - - if (method == sipMethodNotify) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - } - free_sip_message(response); - break; - - case SIP_CLI_ERR_REQ_PENDING: - if (method == sipMethodInvite) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d Glare detected!\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index); - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - // The other side has detected a glare condition - - // Need to inform GSM and let it take appropriate action - handle_error_for_state(ccb, status_code); - /* - * The glare condition handling is now handled by GSM so do not need - * to set the glare timers in the stack... - if (ccb->flags & INCOMING) { - // We did not initiate this call, so set timer between 0 and 2000ms - sip_platform_glare_avoidance_timer_start(cpr_rand()%2000, - ccb->index); - } else { - // We initiated this call, so set the timer between 2100 and 4000ms - sip_platform_glare_avoidance_timer_start(cpr_rand()%2000+2100, - ccb->index); - } - */ - } - - if (method == sipMethodNotify) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - } - - free_sip_message(response); - break; - - default: - if (method == sipMethodInvite) { - sipSPISendFailureResponseAck(ccb, response, FALSE, 0); - - if ((ccb->redirect_info != NULL) - && (ccb->state == SIP_STATE_SENT_INVITE)) { - sip_redirect(ccb, response, status_code); - } else { - handle_error_for_state(ccb, status_code); - } - - } else if (method == sipMethodRefer) { - ccsipCCB_t *other_ccb; - - /* - * The Transfer has failed. If the call being transferred is in the - * "Ringing" state, send a Cancel to the Proxy to tear down the call - * and free up the CCB. - */ - // Delete the previous transaction block - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - - other_ccb = sip_sm_get_ccb_by_target_call_id(ccb->con_call_id); - if ((other_ccb != NULL) && - (other_ccb->state == SIP_STATE_SENT_INVITE)) { - sipSPISendCancel(other_ccb); - sip_cc_release(other_ccb->gsm_id, other_ccb->dn_line, - CC_CAUSE_NORMAL, NULL); - sip_sm_change_state(other_ccb, SIP_STATE_RELEASE); - } - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, CC_FEATURE_XFER, - NULL, CC_CAUSE_ERROR); - - } else if (method == sipMethodNotify) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - } else { - handle_error_for_state(ccb, status_code); - } - free_sip_message(response); - } - -} - - - -/* - * - ***** SIP_STATE_SENT_INVITE_CONNECTED - * - */ -void -ccsip_handle_sentinviteconnected_ev_cc_connected_ack (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sentinviteconnected_ev_cc_connected_ack"; - - /* - * Do not support sending out any body in the ACK. - * Send ACK. - */ - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - /* - * Reset the number of retires we have for authentication - * back to 0 because at this point, if the proxy required - * authentication, our ACK with our credentials must have - * succeeded - */ -// ccb->authen.retries_401_407 = 0; - - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); -} - - -/* - * - ***** SIP_STATE_RECV_INVITE - ***** SIP_STATE_RECV_INVITE_PROCEEDING - ***** SIP_STATE_RECV_INVITE_ALERTING - ***** SIP_STATE_RECV_INVITE_CONNECTED - * - */ -void -ccsip_handle_recvinvite_ev_cc_setup_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE); - ccb->dn_line = event->u.cc_msg->msg.setup_ack.line; -} - - -void -ccsip_handle_recvinvite_ev_cc_proceeding (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_cc_proceeding"; - - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - sip_util_event2string(event->type)); - - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE_PROCEEDING); -} - - -void -ccsip_handle_recvinvite_ev_cc_alerting (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sipSPISendInviteResponse180(ccb); - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE_ALERTING); -} - - -void -ccsip_handle_recvinvite_ev_cc_connected (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_cc_connected"; - int timer_h, timer_t1 = 500; - - (void) sip_platform_localexpires_timer_stop(ccb->index); - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"SIPSM %d: connected\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), ccb->index); - - /* Send 200 OK */ - ccsip_save_local_msg_body(ccb, &event->u.cc_msg->msg.connected.msg_body); - sipSPISendInviteResponse200(ccb); - - // Start the INVITE Expires timer so that if we don't get an ACK we - // can release the call. Note that this timer is being reused. - config_get_value(CFGID_TIMER_T1, &timer_t1, sizeof(timer_t1)); - timer_h = 64 * timer_t1; - - if (sip_platform_expires_timer_start(timer_h, ccb->index, NULL, 0) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), fname, - "sip_platform_expires_timer_start(ACK Timer)"); - } - - sip_sm_change_state(ccb, SIP_STATE_RECV_INVITE_CONNECTED); -} - -// The handler below is called when we sent a 200OK for a received INVITE -// but never received an ACK -void -ccsip_handle_recvinvite_ev_expires_timer (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_expires_timer"; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Sent 200OK but received no ACK\n", - DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - - // Stop the retry timer, if any - sip_platform_msg_timer_stop(ccb->index); - - // Send a BYE to the other side and change state to release - // and send release complete to GSM - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); -} - -void -ccsip_handle_recvinvite_ev_sip_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_sip_ack"; - sipMessage_t *request; - boolean no_media = FALSE; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipsdp_status_t sdp_status; - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodAck, FALSE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - free_sip_message(request); - return; - } - // Stop the expires timer - (void) sip_platform_expires_timer_stop(ccb->index); - - ccb->authen.cred_type = 0; - - /* - * Extract SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - if (ccb->oa_state != OA_OFFER_SENT) { - /* - * Received an offer SDP in an ACK. - */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Received OFFER SDP in ACK, releasing call"); - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - return; - } else { - ccb->oa_state = OA_IDLE; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Using the SDP in INVITE\n", - DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - } - break; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_ERROR: - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - return; - - case SIP_SDP_NO_MEDIA: - case SIP_SDP_NOT_PRESENT: - default: - no_media = TRUE; - if (ccb->oa_state == OA_OFFER_SENT) { - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } else { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Using the SDP in INVITE\n", - DEB_F_PREFIX_ARGS(SIP_ACK, fname)); - } - } - - /* - * Update connected party info from RPID and Call-Info header. - * Received ACK from the remote, media manipulation may occur. Defer - * call information update. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, TRUE); - - if (no_media) { - sip_cc_connected_ack(ccb->gsm_id, ccb->dn_line, NULL); - } else { - sip_cc_connected_ack(ccb->gsm_id, ccb->dn_line, request); - } - - // Add code to send BYE the transferee - if (ccb->wastransferred) { - ccsipCCB_t *refererccb = NULL; - cc_feature_data_t data; - - refererccb = sip_sm_get_ccb_by_callid(ccb->sipxfercallid); - if (NULL != refererccb) { - data.notify.cause = CC_CAUSE_OK; - data.notify.cause_code = 200; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(refererccb->gsm_id, refererccb->dn_line, - CC_FEATURE_NOTIFY, (void *) &data); - } - strlib_free(ccb->sipxfercallid); - ccb->sipxfercallid = strlib_empty(); - } - - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); -} - -// Handle a 2xx received in this state. Could be a 202 for a REFER we sent -// out while in this state -void -ccsip_handle_recvinvite_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "recvinvite_ev_sip_2xx"; - sipMessage_t *response; - sipMethod_t method = sipMethodInvalid; - int response_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Check if this is a REFER response */ - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - return; - } - if (response_code == SIP_ACCEPTED && method == sipMethodRefer) { - ccsip_handle_accept_2xx(ccb, event); - return; - } - free_sip_message(response); - clean_method_request_trx(ccb, method, TRUE); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, sip_util_state2string(ccb->state)); -} - -void -ccsip_handle_disconnect_local (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "disconnect_local"; - char *alsoString = NULL; - - - /* - * If we arrived here from the SENT_INVITE_CONNECTED state, - * send an ACK for the 200 we received. - */ - if (ccb->state == SIP_STATE_SENT_INVITE_CONNECTED) { - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - } - // If we have sent an OK but not yet received the ACK, we should wait - // until it arrives before sending the BYE - if (ccb->state == SIP_STATE_RECV_INVITE_CONNECTED) { - // Stop the expires timer to receive ACK - (void) sip_platform_expires_timer_stop(ccb->index); - ccb->wait_for_ack = TRUE; - ccb->send_delayed_bye = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - return; - } - - if (ccb->referto[0]) { - alsoString = (char *) cpr_malloc(MAX_SIP_URL_LENGTH); - if (alsoString == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "malloc(also string)"); - } else { - sstrncpy(alsoString, ccb->referto, MAX_SIP_URL_LENGTH); - } - } - - /* Send BYE message */ - ccb->authen.cred_type = 0; - - sipSPISendBye(ccb, alsoString, NULL); - if (ccb->state == SIP_STATE_SENT_MIDCALL_INVITE) { - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_RESP_TIMEOUT, NULL); - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "MIDCALL INVITE TMR EXPIRED"); - } else { - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - } -} - - -void -ccsip_handle_disconnect_media_change (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_disconnect_media_change"; - int code; - char *phrase; - char *alsoString = NULL; - cc_causes_t cause = CC_CAUSE_NORMAL; - - cause = event->u.cc_msg->msg.release.cause; - if (cause == CC_CAUSE_NO_MEDIA || cause == CC_CAUSE_PAYLOAD_MISMATCH) { - /* - * Send Invite Response with correct cause message - */ - code = ccsip_cc_to_sip_cause(cause, &phrase); - if (ccb->state == SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING) { - sipSPISendInviteResponse(ccb, (uint16_t) code, phrase, 0, NULL, - FALSE /* no SDP */, TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - ccb->send_delayed_bye = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - return; - } else { - (void) sipSPISendUpdateResponse(ccb, FALSE, cause, FALSE); - } - } - - if (ccb->referto[0]) { - alsoString = (char *) cpr_malloc(MAX_SIP_URL_LENGTH); - if (alsoString == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, "malloc(also string)"); - } else { - sstrncpy(alsoString, ccb->referto, MAX_SIP_URL_LENGTH); - } - } - - /* Send BYE message */ - ccb->authen.cred_type = 0; - sipSPISendBye(ccb, alsoString, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); -} - -void -ccsip_handle_disconnect_local_early (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "disconnect_local_early"; - - /* - * Note that event.type should always be checked prior to dereferencing. Failure - * to check the event type can cause non-deterministic behavior when dereferencing - * the event structure. - */ - - /* - * Check for special case early attended transfer release. - */ - if (event->type == E_CC_RELEASE) { - if (event->u.cc_msg->msg.release.cause == CC_CAUSE_NO_USER_RESP) { - ccb->early_transfer = TRUE; - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "No action, Early Attended Transfer"); - return; - } - } - - /* Send CANCEL message only if we have recd at least a 1xx message in - * response to our INVITE. If not, we will mark the CCB and send it only - * when a 1xx is received - or if not - not at all - */ - if (ccb->flags & RECD_1xx) { - sipSPISendCancel(ccb); - } else { - // Defer the CANCEL - Note we'll move to the RELEASE state even if we - // defer the CANCEL - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Received CC disconnect without 1xx from far side\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Stopping retx timer"); - sip_platform_msg_timer_stop(ccb->index); - ccb->flags |= SEND_CANCEL; - } - - if (ccb->blindtransferred == TRUE) { - cc_feature_data_t data; - - data.notify.cause = CC_CAUSE_OK; - data.notify.cause_code = SIP_CLI_ERR_REQ_CANCEL; - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.method = CC_XFER_METHOD_REFER; - data.notify.blind_xferror_gsm_id = sip_sm_get_blind_xfereror_ccb_by_gsm_id(ccb->gsm_id); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, (void *)&data); - } else if (ccb->wastransferred) { - /* The call was a transfer and we are ending it before - * we connect. GSM has already cleaned up the transfer - * data blocks for this when it received the END_CALL - * message from UI. We still need to send the NOTIFY - * message to the transferor, so we will send it from - * here. - */ - ccsipCCB_t *referccb = NULL; - - referccb = sip_sm_get_target_call_by_gsm_id(ccb->gsm_id); - if (referccb != NULL) { - ccb->flags |= FINAL_NOTIFY; - (void) sipSPISendNotify(referccb, SIP_CLI_ERR_REQ_CANCEL); - ccb->xfer_status = SIP_CLI_ERR_REQ_CANCEL; - } - } - - if (event->type == E_SIP_INV_EXPIRES_TIMER) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - } else { - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - } - - sip_sm_change_state(ccb, SIP_STATE_RELEASE); -} - -void -ccsip_handle_localexpires_timer (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - /* Send 486 error */ - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_BUSY_HERE, - SIP_CLI_ERR_BUSY_HERE_PHRASE, - 0, NULL, FALSE, /* no SDP */ TRUE /* reTx */); - - /* tell GSM to cleanup */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL, NULL); - - sip_sm_change_state(ccb, SIP_STATE_RELEASE); -} - -static void -ccsip_cc_to_warning (cc_causes_t cause, char **warning_phrase, - uint16_t *warning_code) -{ - switch (cause) { - - case CC_CAUSE_PAYLOAD_MISMATCH: - *warning_phrase = SIP_WARN_INCOMPAT_MEDIA_FORMAT_PHRASE; - *warning_code = SIP_WARN_INCOMPAT_MEDIA_FORMAT; - break; - - case CC_CAUSE_NO_MEDIA: - *warning_phrase = SIP_WARN_MEDIA_TYPE_UNAVAIL_PHRASE; - *warning_code = SIP_WARN_MEDIA_TYPE_UNAVAIL; - break; - - default: - *warning_phrase = NULL; - *warning_code = 0; - } - -} - - -int -ccsip_cc_to_sip_cause (cc_causes_t cause, char **phrase) -{ - switch (cause) { - - case CC_CAUSE_OK: - *phrase = SIP_SUCCESS_SETUP_PHRASE; - return SIP_SUCCESS_SETUP; - - case CC_CAUSE_ERROR: - *phrase = SIP_CLI_ERR_BAD_REQ_PHRASE; - return SIP_CLI_ERR_BAD_REQ; - - case CC_CAUSE_UNASSIGNED_NUM: - *phrase = SIP_CLI_ERR_NOT_FOUND_PHRASE; - return SIP_CLI_ERR_NOT_FOUND; - - case CC_CAUSE_NO_RESOURCE: - *phrase = SIP_SERV_ERR_INTERNAL_PHRASE; - return SIP_SERV_ERR_INTERNAL; - - case CC_CAUSE_BUSY: - *phrase = SIP_CLI_ERR_BUSY_HERE_PHRASE; - return SIP_CLI_ERR_BUSY_HERE; - - case CC_CAUSE_ANONYMOUS: - *phrase = SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE; - return SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED; - - case CC_CAUSE_INVALID_NUMBER: - *phrase = SIP_CLI_ERR_ADDRESS_PHRASE; - return SIP_CLI_ERR_ADDRESS; - - case CC_CAUSE_PAYLOAD_MISMATCH: - *phrase = SIP_CLI_ERR_NOT_ACCEPT_HERE_PHRASE; - return SIP_CLI_ERR_NOT_ACCEPT_HERE; - - case CC_CAUSE_NO_REPLACE_CALL: - *phrase = SIP_CLI_ERR_CALLEG_PHRASE; - return SIP_CLI_ERR_CALLEG; - - case CC_CAUSE_REQUEST_PENDING: - *phrase = SIP_CLI_ERR_REQ_PENDING_PHRASE; - return SIP_CLI_ERR_REQ_PENDING; - - default: - *phrase = SIP_CLI_ERR_BAD_REQ_PHRASE; - return SIP_CLI_ERR_BAD_REQ; - } -} - -void -ccsip_handle_disconnect_local_unanswered (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - int code; - char *phrase; - uint16_t warning_code = 0; - char *warning_phrase = NULL; - - ccb->dn_line = event->u.cc_msg->msg.release.line; - code = ccsip_cc_to_sip_cause(event->u.cc_msg->msg.release.cause, &phrase); - - ccsip_cc_to_warning(event->u.cc_msg->msg.release.cause, &warning_phrase, &warning_code); - - /* Send Invite Response with correct cause message */ - sipSPISendInviteResponse(ccb, (uint16_t)code, phrase, warning_code, - warning_phrase, - FALSE /*no SDP */ , TRUE /*reTx */ ); - - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - ccb->wait_for_ack = TRUE; - sip_sm_change_state(ccb, SIP_STATE_RELEASE); -} - - -void -ccsip_handle_disconnect_remote (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "disconnect_remote"; - sipMessage_t *request; - sipMessage_t *store_invite_req; - const char *alsoString = NULL, *reasonHdr=NULL; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMethod_t method = sipMethodInvalid; - cc_causes_t cause = CC_CAUSE_NORMAL; - - memset(request_check_reason_phrase, 0, SIP_WARNING_LENGTH); - - /* Unpack the event */ - request = event->u.pSipMessage; - store_invite_req = ccb->last_request; - - sipGetRequestMethod(request, &method); - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, TRUE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - // Stop the expires timer - (void) sip_platform_expires_timer_stop(ccb->index); - - //Check if this BYE is for the original call (between - //transferor and transferee) in attended transfer scenario. - if (ccb->con_call_id != CC_NO_CALL_ID) { - //Transferee has received a BYE - //from the transferor. Two scenarios are possible: - //1. BYE is received after receiving the 2xx/4xx/5xx/6xx for the - // consultative call. Therefore, setting wasTransferred flag - // to FALSE has no impact. - //2. BYE is received before receiving the 2xx/4xx/5xx/6xx for the - // consultative call. - // Therefore, setting wastransferred flag - // to FALSE, results in not sending the final NOTIFY - // after receiving 2xx/4xx/5xx/6xx from the target. - ccsipCCB_t *other_ccb; - - other_ccb = sip_sm_get_ccb_by_target_call_id(ccb->con_call_id); - if (other_ccb) { - other_ccb->wastransferred = FALSE; - strlib_free(other_ccb->sipxfercallid); - other_ccb->sipxfercallid = strlib_empty(); - } - } - - - /* - * Detect whether this is a Call Transfer by checking - * for the presence of the "Also:" header - */ - alsoString = sippmh_get_header_val(request, SIP_HEADER_ALSO, NULL); - if (alsoString) { - cc_feature_data_t data; - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d Far end requested Call Transfer, " - "destination=<%s>\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, alsoString); - sstrncpy(data.xfer.dialstring, alsoString, strlen(alsoString) + 1); - data.xfer.cause = CC_CAUSE_XFER_REMOTE; - data.xfer.method = CC_XFER_METHOD_BYE; - data.xfer.target_call_id = CC_NO_CALL_ID; - ccb->referto = strlib_update(ccb->referto, alsoString); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_XFER, (void *)&data); - (void) sipSPISendByeOrCancelResponse(ccb, request, sipMethodBye); - free_sip_message(store_invite_req); - return; - } else { - /* Send BYE response message */ - if (event->type == E_SIP_BYE) { - /* - * We want to wait for release_complete from GSM before sending - * the 200 OK out, in order to collect call_stats - */ - ccb->flags |= RECD_BYE; - } else { - (void) sipSPISendByeOrCancelResponse(ccb, request, sipMethodCancel); - // if the reason header contains a reason code of 200 - // we should pass this forward to gsm - reasonHdr = sippmh_get_header_val(request, SIP_HEADER_REASON, NULL); - if ( reasonHdr && strcasestr(reasonHdr, "cause=200;") ) { - cause = CC_SIP_CAUSE_ANSWERED_ELSEWHERE; - } - } - - if (SIP_SM_CALL_SETUP_RESPONDING(ccb) || - ccb->state == SIP_STATE_RECV_INVITE || - ccb->state == SIP_STATE_RECV_INVITE_CONNECTED) { - /* - * Store invite request into ccb before sending 487. This is a - * temporary solution and should be removed in Moonpie - */ - sipGetRequestMethod(store_invite_req, &method); - if (sip_sm_request_check_and_store(ccb, store_invite_req, method, - TRUE, &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - free_sip_message(store_invite_req); - return; - } - sipSPISendInviteResponse(ccb, 487, SIP_CLI_ERR_REQ_CANCEL_PHRASE, 0, - NULL, FALSE, /* no SDP */ TRUE /* reTx */); - ccb->wait_for_ack = TRUE; - } else { - free_sip_message(store_invite_req); - } - - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - sip_cc_release(ccb->gsm_id, ccb->dn_line, cause, NULL); - } -} - -/* E_SIP_REFER */ -void -ccsip_handle_refer_sip_message (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "refer_sip_message"; - sipMessage_t *request; - const char *contact = NULL; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMethod_t method = sipMethodInvalid; - cc_feature_data_t data; - char *referToString[MAX_REFER_TO_HEADERS] = { NULL }; - char *referByString; - sipReferTo_t *referto = NULL; - sipReplaces_t *replaces_t = NULL; - int noOfReferTo = 0; - int noOfReferBy = 0; - char tempreferto[MAX_SIP_URL_LENGTH]; - int rpid_flag = RPID_DISABLED; - char tempreferby[MAX_SIP_URL_LENGTH]; - char *semi_token = NULL; - int rcode; - sipContact_t *contact_info = NULL; - - memset(tempreferto, 0, MAX_SIP_URL_LENGTH); - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* transfer method if attended or blind */ - ccb->featuretype = CC_FEATURE_BLIND_XFER; // Default is Blind - - sipGetRequestMethod(request, &method); - - // Check if we are already processing a previously received REFER - if (get_method_request_trx_index(ccb, method, FALSE) > -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received REFER while processing an old one!\n", fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_REQ_PENDING, - SIP_CLI_ERR_REQ_PENDING_PHRASE, - 0, NULL, NULL); - free_sip_message(request); - return; - } - - - /* Request check and store */ - rcode = sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE); - if (rcode < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - - if (rcode == -2) { // trx malloc error - (void) sipSPISendErrorResponse(request, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - } else { - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - } - free_sip_message(request); - return; - } - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - if (sipSPICheckContact(contact) < 0) { // If contact is invalid - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPICheckContact()"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD, - ccb); - return; - } - contact_info = sippmh_parse_contact(contact); - if (contact_info && contact_info->num_locations > 1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received REFER with multiple contacts!\n", fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_AMBIGUOUS, - SIP_CLI_ERR_AMBIGUOUS_PHRASE, - SIP_WARN_MISC, - SIP_WARN_REFER_AMBIGUOUS_PHRASE, - ccb); - sippmh_free_contact(contact_info); - return; - } - if (contact_info) { - sippmh_free_contact(contact_info); - } - } else { // If No contact header - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD, - ccb); - return; - } - - /* - * Update connected party info from RPID and Call-Info header. - * Handing REFER, do not defer call information update. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - - // Store Refer Information such as Call_id and to-tag - // If replace is present then it must be attended transfer - noOfReferTo = sippmh_get_num_particular_headers(request, SIP_HEADER_REFER_TO, - SIP_C_HEADER_REFER_TO, - referToString, MAX_REFER_TO_HEADERS); - - if (noOfReferTo == 1) { - referto = sippmh_parse_refer_to(referToString[0]); - } - - if ((noOfReferTo == 0) || (noOfReferTo > 1) || (referto == NULL)) { - - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "Incorrect number of Refer-To headers and/or value.\n"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO, - ccb); - - if (referto) { - cpr_free(referto); - } - return; - } - - sipSPIGenerateTargetUrl(referto->targetUrl, tempreferto); - ccb->sip_referTo = strlib_update(ccb->sip_referTo, tempreferto); - if (referto->sip_replaces_hdr != NULL) { - char tempreplace[MAX_SIP_URL_LENGTH]; - - memset(tempreplace, 0, MAX_SIP_URL_LENGTH); - sstrncpy(tempreplace, "Replaces=", sizeof(tempreplace)); - sstrncat(tempreplace, referto->sip_replaces_hdr, (sizeof(tempreplace) - sizeof("Replaces="))); - replaces_t = sippmh_parse_replaces(tempreplace, FALSE); - if (NULL != replaces_t) { - ccb->sipxfercallid = strlib_update(ccb->sipxfercallid, replaces_t->callid); - if (ccb->sipxfercallid) { - ccb->sipxfercallid = strlib_append(ccb->sipxfercallid, ";to-tag="); - if (ccb->sipxfercallid) { - ccb->sipxfercallid = strlib_append(ccb->sipxfercallid, replaces_t->toTag); - } - if (ccb->sipxfercallid) { - ccb->sipxfercallid = strlib_append(ccb->sipxfercallid, ";from-tag="); - } - if (ccb->sipxfercallid) { - ccb->sipxfercallid = strlib_append(ccb->sipxfercallid, replaces_t->fromTag); - } - } - ccb->featuretype = CC_FEATURE_XFER; - sippmh_free_replaces(replaces_t); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "replaces header in referto missing callid or to/from tags"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO, - ccb); - sippmh_free_refer_to(referto); - return; - } - } -#ifdef SIP_ACC_CONT - if (referto->sip_acc_cont != NULL) { - // attach the new string to the ccb... - // Note: This doesn't currently generate any header, but the hook - // is here if we need it later. - if (ccb->refer_acc_cont != NULL) { - cpr_free(ccb->refer_acc_cont); - ccb->refer_acc_cont = NULL; - } - ccb->refer_acc_cont = cpr_strdup(referto->sip_acc_cont); - } -#endif - - if (referto->sip_proxy_auth != NULL) { - if (ccb->refer_proxy_auth != NULL) { - // if there was already one of these, toss it out - cpr_free(ccb->refer_proxy_auth); - ccb->refer_proxy_auth = NULL; - } - // attach the new string to the ccb... - ccb->refer_proxy_auth = cpr_strdup(referto->sip_proxy_auth); - } - - noOfReferBy = sippmh_get_num_particular_headers(request, - SIP_HEADER_REFERRED_BY, - SIP_C_HEADER_REFERRED_BY, - &referByString, - MAX_REFER_BY_HEADERS); - - if (noOfReferBy == 0) { - - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Missing referred by header\n"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_BY, - ccb); - sippmh_free_refer_to(referto); - return; - } - - if (noOfReferTo > 1 || noOfReferBy > 1) { - - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Multiple referto or refer by headers found in message"); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER, - ccb); - sippmh_free_refer_to(referto); - return; - } - - config_get_value(CFGID_REMOTE_PARTY_ID, &rpid_flag, sizeof(rpid_flag)); - - if ((rpid_flag == RPID_ENABLED) && (ccb->best_rpid) - && (cpr_strcasecmp(ccb->best_rpid->privacy, PRIVACY_OFF) != 0)) { - snprintf(tempreferby, MAX_SIP_URL_LENGTH, "\"%s\" ", - SIP_HEADER_ANONYMOUS_STR, - ccb->best_rpid->loc->genUrl->u.sipUrl->user, - ccb->best_rpid->loc->genUrl->u.sipUrl->host); - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, tempreferby); - } else { - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, referByString); - } - - sstrncpy(data.xfer.dialstring, referToString[0], sizeof(data.xfer.dialstring)); - semi_token = strchr(data.xfer.dialstring, '?'); - if (semi_token) { - *semi_token++ = '>'; - *semi_token = 0; - } - if (data.xfer.dialstring[0] != '<') { - semi_token = strchr(data.xfer.dialstring, '>'); - if (semi_token) { - *semi_token = 0; - } - } - - /* Convert the escapeed userino part, if any to unescaped format */ - if (unescape_UserInfo(data.xfer.dialstring, tempreferto, MAX_SIP_URL_LENGTH)) { - memset(data.xfer.dialstring, 0, CC_MAX_DIALSTRING_LEN); - sstrncpy(data.xfer.dialstring, tempreferto, CC_MAX_DIALSTRING_LEN); - } - - data.xfer.method = CC_XFER_METHOD_REFER; - data.xfer.target_call_id = CC_NO_CALL_ID; - data.xfer.cause = CC_CAUSE_XFER_REMOTE; - if (ccb->featuretype == CC_FEATURE_BLIND_XFER) { - sstrncpy(data.xfer.referred_by, ccb->sip_referredBy, - MAX_SIP_URL_LENGTH); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_BLIND_XFER, - (void *) &data); - } else { - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_XFER, - (void *) &data); - } - sippmh_free_refer_to(referto); -} - -void -ccsip_handle_process_in_call_options_request (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_process_in_call_options_request"; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMessage_t *request; - sipMethod_t method = sipMethodInvalid; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Processing within-dialog OPTIONS request\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - - /* Unpack the event */ - request = event->u.pSipMessage; - - ccb->featuretype = CC_FEATURE_NONE; - - /* Request check and store */ - sipGetRequestMethod(request, &method); - if (sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - // fixed CSCsi68191: The ccb->last_request and event->u.pSipMessage pointed to same memory address. - // Set last_request to NULL to avoid double deletion of memory, which is freed by - // gsm event of OPTION ACK later. - ccb->last_request = NULL; - sip_cc_options(ccb->gsm_id, ccb->dn_line, event->u.pSipMessage); -} - -void -ccsip_handle_ev_cc_answer_options_request (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_ev_cc_answer_options_request"; - cc_options_sdp_ack_t *options_sdp_ack; - - options_sdp_ack = (cc_options_sdp_ack_t *) event->u.cc_msg; - - if (!ccb) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Processing OPTIONS (out of dialog) " - "request(GSM has responded)\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - (void) sipSPIsendNonActiveOptionResponse((sipMessage_t *) options_sdp_ack->pMessage, - &options_sdp_ack->msg_body); - - //since there is no call and therefore no ccb, we must free - //the SIP OPTIONS message here. - free_sip_message((sipMessage_t *)options_sdp_ack->pMessage); - options_sdp_ack->pMessage = NULL; - } else { - //Since there is a ccb, the SIP OPTIONS message will be freed - //in sip_sm_call_cleanup() after the call is done. - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Processing OPTIONS (in dialog) " - "request(GSM has responded)\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - - // Must save sdp from gsm to ccb before building the response - ccsip_save_local_msg_body(ccb, &options_sdp_ack->msg_body); - (void) sipSPISendOptionResponse(ccb, event->u.pSipMessage); - } -} - -void -ccsip_handle_ev_cc_answer_audit_request (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - cc_audit_sdp_ack_t *audit_ack; - - - audit_ack = (cc_audit_sdp_ack_t *) event->u.cc_msg; - /* - * Use the new sdp generated by the gsm and free the old copy. - */ - ccsip_save_local_msg_body(ccb, &audit_ack->msg_body); - sipSPISendInviteResponse200(ccb); -} - -int -sip_sm_process_event (sipSMEvent_t *pEvent) -{ - const char *fname = "sip_sm_process_event"; - ccsipCCB_t *ccb; - sipSMAction_t event_handler = H_INVALID_EVENT; - - ccb = pEvent->ccb; - if (!ccb) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccb is null. Unable to process event " - "<%d>\n", fname, pEvent->type); - return (-1); - } - - /* Unbind UDP ICMP response handler */ - UNBIND_UDP_ICMP_HANDLER(ccb->udpId); - - /* - * ccb->index is an unsigned type and TEL_CCB_START is zero, - * so just check the end condition - */ - if ((int) (ccb->index) > TEL_CCB_END) { - // We got an illegal line for our SIP SM - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"illegal line number: %d\n", - fname, ccb->index); - return (-1); - } - - if (!sip_config_check_line(ccb->dn_line)) { - // We got an illegal DN for our SIP SM - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"illegal directory number: %d\n", - fname, ccb->dn_line); - return (-1); - } - - if ((event_handler = get_handler_index(ccb->state, pEvent->type)) - != H_INVALID_EVENT) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Processing SM event: %d: --0x%08lx--%21s: %s <- %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, EVENT_ACTION_SM(event_handler), - "", sip_util_state2string(ccb->state), - sip_util_event2string(pEvent->type)); - - EVENT_ACTION_SM(event_handler) (ccb, pEvent); - } else { - /* Invalid State/Event pair */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"illegal state/event pair: " - "(%d <-- %d)\n", fname, ccb->state, pEvent->type); - return (-1); - } - - return (0); -} - - -/** - * - * Extract the k factor stats sent by GSM and store a ptr on ccb - * - * @param pCCMsg - msg from GSM - * @param ccb - ccb for this call - * - * @return nothing - */ -void -sip_extract_kfactor_stats (cc_msg_t *pCCMsg, ccsipCCB_t *ccb) -{ - if (pCCMsg->msg.release.msg_id == CC_MSG_RELEASE) { - ccb->kfactor_ptr = &pCCMsg->msg.release.kfactor; - } else if (pCCMsg->msg.release_complete.msg_id == CC_MSG_RELEASE_COMPLETE) { - ccb->kfactor_ptr = &pCCMsg->msg.release_complete.kfactor; - } else if ((pCCMsg->msg.feature.msg_id == CC_MSG_FEATURE) || - (pCCMsg->msg.feature.msg_id == CC_MSG_FEATURE_ACK)) { - if (pCCMsg->msg.feature.feature_id == CC_FEATURE_HOLD) { - ccb->kfactor_ptr = &pCCMsg->msg.feature.data.hold.kfactor; - } else if (pCCMsg->msg.feature.feature_id == CC_FEATURE_MEDIA) { - ccb->kfactor_ptr = &pCCMsg->msg.feature.data.resume.kfactor; - } else { - ccb->kfactor_ptr = NULL; - } - } else { - ccb->kfactor_ptr = NULL; - } -} -int -sip_sm_process_cc_event (cprBuffer_t buf) -{ - const char *fname = "sip_sm_process_cc_event"; - sipSMEvent_t sip_sm_event; - line_t idx = 0; - sipSMAction_t event_handler = H_INVALID_EVENT; - cc_msg_t *pCCMsg = (cc_msg_t *) buf; - - memset(&sip_sm_event, 0, sizeof(sipSMEvent_t)); - - sip_sm_event.u.cc_msg = pCCMsg; - sip_sm_event.type = sip_util_ccevent2sipccevent(pCCMsg->msg.setup.msg_id); - if (pCCMsg->msg.setup.msg_id == CC_MSG_SETUP) { - sip_sm_event.ccb = sip_sm_get_ccb_next_available(&idx); - if (!sip_sm_event.ccb) { - sip_cc_release(pCCMsg->msg.setup.call_id, pCCMsg->msg.setup.line, - CC_CAUSE_ERROR, NULL); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No free lines available\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } - } else if (pCCMsg->msg.setup.msg_id == CC_MSG_OPTIONS_ACK) { - /* - * Process the out of dialogue and in dialogue option ack - * (local sdp built by the gsm) - */ - sip_sm_event.ccb = sip_sm_get_ccb_by_gsm_id(pCCMsg->msg.setup.call_id); - ccsip_handle_ev_cc_answer_options_request(sip_sm_event.ccb, &sip_sm_event); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return (SIP_OK); - } else if (ccsip_handle_cc_select_event(&sip_sm_event)) { - /* - * The select feature has been handled. - */ - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } else if (ccsip_handle_cc_b2bjoin_event(&sip_sm_event)) { - /* - * The b2bjoin feature has been handled. - */ - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } else if (ccsip_handle_cc_hook_event(&sip_sm_event) == TRUE) { - /* - * The hook event has been handled. - */ - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } else { - sip_sm_event.ccb = sip_sm_get_ccb_by_gsm_id(pCCMsg->msg.setup.call_id); - if (!sip_sm_event.ccb) { - // If there is no associated CCB, this could be an - // Out of Dialog feature request - if (pCCMsg->msg.setup.msg_id == CC_MSG_FEATURE) { - // Call function to process an OOD Feature - // OOD features are handled by the sub/not API - // If unsuccessful processing - sip_cc_release(pCCMsg->msg.setup.call_id, pCCMsg->msg.setup.line, - CC_CAUSE_ERROR, NULL); - } else if (pCCMsg->msg.setup.msg_id == CC_MSG_RELEASE) { - sip_cc_release_complete(pCCMsg->msg.setup.call_id, - pCCMsg->msg.setup.line, CC_CAUSE_ERROR); - } else { - sip_cc_release(pCCMsg->msg.setup.call_id, pCCMsg->msg.setup.line, - CC_CAUSE_ERROR, NULL); - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No ccb with matching gsm_id = <%d>\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname), - pCCMsg->msg.setup.call_id); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } - } - - if (pCCMsg->msg.setup.msg_id == CC_MSG_AUDIT_ACK) { - /* - * Process the in dialogue audit ack - * (local sdp built by the gsm) - */ - ccsip_handle_ev_cc_answer_audit_request(sip_sm_event.ccb, &sip_sm_event); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return (SIP_OK); - } - - /* CSCds88133: ReTx timers cancelled prematurely */ - if (sip_sm_event.ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) { - /* RAC FIXME - Don't like this... */ - line_t line_index = (line_t) -1; - - sip_sm_event.ccb = sip_sm_get_ccb_next_available(&line_index); - if (!sip_sm_event.ccb) { - if (pCCMsg->msg.setup.msg_id == CC_MSG_RELEASE) { - sip_cc_release_complete(pCCMsg->msg.setup.call_id, - pCCMsg->msg.setup.line, CC_CAUSE_ERROR); - } else { - sip_cc_release(pCCMsg->msg.setup.call_id, pCCMsg->msg.setup.line, - CC_CAUSE_ERROR, NULL); - } - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_get_ccb_next_available()" - " returned null.\n", fname); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; - } - /* Set this ccb to always be on the first DN. */ - sip_sm_event.ccb->dn_line = 1; - } - - sip_extract_kfactor_stats(pCCMsg, sip_sm_event.ccb); - event_handler = get_handler_index(sip_sm_event.ccb->state, sip_sm_event.type); - if (event_handler != H_INVALID_EVENT) { - - DEF_DEBUG(DEB_L_C_F_PREFIX"Processing CC event: %-6d: SM: %s <- %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, sip_sm_event.ccb->dn_line, - sip_sm_event.ccb->gsm_id, fname), - (long)buf, - sip_util_state2string(sip_sm_event.ccb->state), - sip_util_event2string(sip_sm_event.type)); - - EVENT_ACTION_SM(event_handler)(sip_sm_event.ccb, &sip_sm_event); - } else { - /* Invalid State/Event pair */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"illegal state/event pair: (%d <-- %d)\n", - fname, sip_sm_event.ccb->state, sip_sm_event.type); - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_ERROR; - } - sip_sm_event.ccb->kfactor_ptr = NULL; - cc_free_msg_data(sip_sm_event.u.cc_msg); - cpr_free(pCCMsg); - return SIP_OK; -} - -void -ccsip_handle_send_blind_notify (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "send_blind_notify"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - cc_feature_name(feature_type)); - - if (CC_FEATURE_NOTIFY == feature_type) { - if (event->u.cc_msg->msg.feature.data.notify.final == TRUE) { - ccb->flags |= FINAL_NOTIFY; - } - (void) sipSPISendNotify(ccb, event->u.cc_msg->msg.feature.data.notify.cause_code); - ccb->xfer_status = event->u.cc_msg->msg.feature.data.notify.cause_code; - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - } -} - -void -sip_sm_call_cleanup (ccsipCCB_t *ccb) -{ - const char *fname = "sip_sm_call_cleanup"; - int i = 0; - - if (ccb == NULL) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Null CCB passed into function.\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - return; - } - - /* first time the phone boots, this function gets called, but the - * CCBs haven't been initialized yet. This is the only time the - * dn_line can be zero. Otherwise, zero is invalid. On the first - * bootup, we don't need to do anything in this function. - */ - if (ccb->dn_line == 0) { - return; - } - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, "Cleaning up the call"); - - /* - * If there are any shared pointers because of duping - * make sure we have taken care of those - */ - if (ccb->dup_flags & DUP_CCB) { - free_duped(ccb); - } - - /* Cancel any outstanding timers */ - (void) sip_platform_localexpires_timer_stop(ccb->index); - - /* - * ccb->index is an unsigned type and TEL_CCB_START is zero, - * so just check the end condition - */ - if ((int) (ccb->index) <= TEL_CCB_END) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - submanager_update_ccb_addr(ccb); - } - - /* Unbind UDP ICMP Unreachable handler just incase */ - UNBIND_UDP_ICMP_HANDLER(ccb->udpId); - - /* Free DNS Srv handle if present */ - if (ccb->SRVhandle != NULL) { - dnsFreeSrvHandle(ccb->SRVhandle); - ccb->SRVhandle = NULL; - } - - /* Free Ooutbound proxy DNS Srv handle if present */ - if (ccb->ObpSRVhandle != NULL) { - dnsFreeSrvHandle(ccb->ObpSRVhandle); - ccb->ObpSRVhandle = NULL; - } - - /* - * Store call history info - */ - if ((int) (ccb->index) <= TEL_CCB_END) { - (void) sip_platform_expires_timer_stop(ccb->index); - (void) sip_platform_register_expires_timer_stop(ccb->index); - // bugid: CSCsz34666 - memcpy(gCallHistory[ccb->index].last_call_id, ccb->sipCallID, - MAX_SIP_CALL_ID); - } - - /* Free message bodies were saved during the cause of the call */ - cc_free_msg_body_parts(&ccb->local_msg_body); - - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - - /* Free last recorded request */ - if (ccb->last_request) { - free_sip_message(ccb->last_request); - ccb->last_request = NULL; - } - - /* Free CC-Diversion headers */ - for (i = 0; i < MAX_DIVERSION_HEADERS; i++) { - if (ccb->diversion[i]) { - cpr_free(ccb->diversion[i]); - ccb->diversion[i] = NULL; - } - } - - sippmh_free_diversion_info(ccb->div_info); - ccb->div_info = NULL; - ccb->call_type = CC_CALL_NONE; - - /* Free Redirection structure */ - if (ccb->redirect_info) { - sippmh_free_contact(ccb->redirect_info->sipContact); - cpr_free(ccb->redirect_info); - ccb->redirect_info = NULL; - } - - ccb->best_rpid = NULL; - sippmh_free_remote_party_id_info(ccb->rpid_info); - ccb->rpid_info = NULL; - -// ccb->authen.retries_401_407 = 0; - ccb->authen.cnonce[0] = '\0'; - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - if (ccb->refer_proxy_auth != NULL) { - cpr_free(ccb->refer_proxy_auth); - ccb->refer_proxy_auth = NULL; - } -#ifdef SIP_ACC_CONT - if (ccb->refer_acc_cont != NULL) { - cpr_free(ccb->refer_acc_cont); - ccb->refer_acc_cont = NULL; - } -#endif - - if (ccb->authen.sip_authen != NULL) { - sippmh_free_authen(ccb->authen.sip_authen); - ccb->authen.sip_authen = NULL; - } - - ccb->hold_initiated = FALSE; - ccb->wastransferred = FALSE; - ccb->blindtransferred = FALSE; - ccb->gsm_id = CC_NO_CALL_ID; - ccb->con_call_id = CC_NO_CALL_ID; - ccb->blind_xfer_call_id = CC_NO_CALL_ID; - ccb->xfer_status = 0; - - if (ccb->old_session_id != NULL) { - cpr_free(ccb->old_session_id); - } - if (ccb->old_version_id != NULL) { - cpr_free(ccb->old_version_id); - } - ccb->old_session_id = NULL; - ccb->old_version_id = NULL; - - ccb->displayCalledNumber = TRUE; - ccb->displayCallingNumber = TRUE; - - /*free all the dynamically allocated strings */ - - strlib_free(ccb->calledDisplayedName); - strlib_free(ccb->callingNumber); - strlib_free(ccb->altCallingNumber); - strlib_free(ccb->callingDisplayName); - strlib_free(ccb->calledNumber); - strlib_free(ccb->ReqURIOriginal); - strlib_free(ccb->sip_from); - strlib_free(ccb->sip_to); - strlib_free(ccb->sip_to_tag); - strlib_free(ccb->sip_from_tag); - strlib_free(ccb->sip_contact); - strlib_free(ccb->sip_reqby); - strlib_free(ccb->sip_require); - strlib_free(ccb->sip_unsupported); - strlib_free(ccb->referto); - strlib_free(ccb->sip_referTo); - strlib_free(ccb->sip_referredBy); - strlib_free(ccb->sipxfercallid); - strlib_free(ccb->sip_remote_party_id); - - if (ccb->in_call_info) { - ccsip_free_call_info_header(ccb->in_call_info); - ccb->in_call_info = NULL; - } - if (ccb->out_call_info) { - ccsip_free_call_info_header(ccb->out_call_info); - ccb->out_call_info = NULL; - } - if (ccb->join_info) { - sippmh_free_join_info(ccb->join_info); - ccb->join_info = NULL; - } - if (ccb->feature_data) { - cpr_free(ccb->feature_data); - ccb->feature_data = NULL; - } - - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - ccb->sent_request[i].cseq_number = CCSIP_START_CSEQ; - ccb->sent_request[i].cseq_method = sipMethodInvalid; - strlib_free(ccb->sent_request[i].u.sip_via_branch); - strlib_free(ccb->sent_request[i].sip_via_sentby); - ccb->recv_request[i].cseq_number = CCSIP_START_CSEQ; - ccb->recv_request[i].cseq_method = sipMethodInvalid; - strlib_free(ccb->recv_request[i].u.sip_via_header); - strlib_free(ccb->recv_request[i].sip_via_sentby); - } - - if (ccb->index >= REG_CCB_START) { - /* - * Necessary to cast the SIP_REG_STATE_IDLE to properly initialize - * registration CCBs which use the same ccb->state field. - */ - (void) sip_sm_ccb_init(ccb, ccb->index, ccb->dn_line, - SIP_REG_STATE_IDLE); - return; - } - - if (sip_platform_msg_timer_outstanding_get(ccb->index)) { - sip_sm_change_state(ccb, SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING); - (void) sip_sm_ccb_init(ccb, ccb->index, ccb->dn_line, - SIP_REG_STATE_IDLE /*_MSG_TIMER_OUTSTANDING */); - } else { - sip_sm_change_state(ccb, SIP_STATE_IDLE); - (void) sip_sm_ccb_init(ccb, ccb->index, 1, SIP_REG_STATE_IDLE); - } - -} - - -int -sip_sm_ccb_init (ccsipCCB_t *ccb, line_t ccb_index, int DN, - sipRegSMStateType_t initial_state) -{ - int nat_enable = 0; - uint8_t i; - - /* - * TEL_CCB_START equates to zero and line_t is an unsigned type, - * so just check the end condition - */ - if ((int) ccb_index <= TEL_CCB_END) { - memset(ccb, 0, sizeof(ccsipCCB_t)); - } - - ccb->dup_flags = DUP_NO_FLAGS; - ccb->mother_ccb = NULL; - sip_reg_sm_change_state(ccb, initial_state); /* print the debug msg also */ - ccb->index = ccb_index; - ccb->hold_initiated = FALSE; - ccb->wastransferred = FALSE; - ccb->blindtransferred = FALSE; - ccb->callingNumber = strlib_empty(); - ccb->calledNumberFirstDigitDialed = FALSE; - ccb->calledNumber = strlib_empty(); - ccb->altCallingNumber = strlib_empty(); - ccb->calledDisplayedName = strlib_empty(); - ccb->callingDisplayName = strlib_empty(); - ccb->displayCalledNumber = TRUE; - ccb->displayCallingNumber = TRUE; - ccb->calledNumberLen = 0; - ccb->ReqURIOriginal = strlib_empty(); - ccb->sip_to_tag = strlib_empty(); - ccb->sip_from_tag = strlib_empty(); - ccb->sip_contact = strlib_empty(); - ccb->sip_reqby = strlib_empty(); - ccb->sip_require = strlib_empty(); - ccb->sip_unsupported = strlib_empty(); - ccb->sip_remote_party_id = strlib_empty(); - ccb->flags = 0; - ccb->avt.payload_type = RTP_NONE; - ccb->alert_info = ALERTING_NONE; - ccb->alerting_ring = VCM_INSIDE_RING; - ccb->wait_for_ack = FALSE; - ccb->send_delayed_bye = FALSE; - ccb->retx_flag = FALSE; - ccb->early_transfer = FALSE; - ccb->redirect_info = NULL; - ccb->proxySelection = SIP_PROXY_DEFAULT; - ccb->outBoundProxyAddr = ip_addr_invalid; - ccb->outBoundProxyPort = 0; - ccb->oa_state = OA_IDLE; - ccb->call_type = CC_CALL_NONE; - ccb->cc_cfg_table_entry = NULL; - ccb->first_pass_3xx = TRUE; - - /* Sip msg destination is set to proxy by default */ - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&(ccb->src_addr)); - } else { - sip_config_get_nat_ipaddr(&(ccb->src_addr)); - } - - config_get_value(CFGID_VOIP_CONTROL_PORT, &ccb->local_port, - sizeof(ccb->local_port)); - - if ((int) ccb_index <= TEL_CCB_END) { - ccb->type = SIP_CALL_CCB; - ccb->dn_line = (line_t) DN; - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr), ccb->dn_line); - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - ccb->sipCallID[0] = '\0'; - } else if ((ccb_index >= REG_CCB_START) && (ccb_index <= REG_CCB_END)) { - ccb->type = SIP_REG_CCB; - ccb->dn_line = ccb_index - MAX_TEL_LINES + 1; - sip_regmgr_set_cc_info(ccb_index, ccb->dn_line, &ccb->cc_type, - (void *)&ccb->cc_cfg_table_entry); - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - If type of call control is ccm set the - * address here as well. - */ - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr), ccb->dn_line); - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } else { - /* - * regmgr - Assume it is CSPS for now. - */ - ccb->dest_sip_addr = ip_addr_invalid; - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - } else if (ccb_index == REG_BACKUP_CCB) { - ccb->type = SIP_REG_CCB; - ccb->dn_line = REG_BACKUP_DN; - sip_regmgr_set_cc_info(ccb_index, ccb->dn_line, &ccb->cc_type, - &ccb->cc_cfg_table_entry); - if (ccb->cc_type != CC_CCM) { - /* - * regmgr - Assume it is CSPS for now. - */ - sipTransportGetBkupServerAddress(&ccb->dest_sip_addr, ccb->dn_line, ccb->reg.proxy); - ccb->dest_sip_port = sipTransportGetBkupServerPort(ccb->dn_line); - } - } else if ((ccb_index >= REG_FALLBACK_CCB_START) && - (ccb_index <= REG_FALLBACK_CCB_END)) { - /* - * regmgr - There can be upto 3 fallback ccb's that get created - * dynamically. If the ccb index indicates that then set the - * type to be SIP_REG_CCB so that the register state - * machine gets the event. - */ - ccb->type = SIP_REG_CCB; - ccb->dn_line = REG_BACKUP_DN; - } - /* - * Get the listen port that is configured from the - * Transport Interface instead of the direct config - * read from config. - */ - ccb->local_port = sipTransportGetListenPort(ccb->dn_line, ccb); - /* Init SDP info */ - memset(&ccb->local_msg_body, 0, sizeof(cc_msgbody_info_t)); - //ccb->dest_port = 0; - //ccb->dest_addr = 0; - ccb->old_session_id = NULL; - ccb->old_version_id = NULL; - - /* Into To:, From:, and Request-URI: fields */ - ccb->ReqURI[0] = '\0'; - ccb->sip_from = strlib_empty(); /* There is no pre-set From: field */ - ccb->sip_to = strlib_empty(); /* There is no pre-set To: field */ - - // The following is the refer stuff - - ccb->sip_referTo = strlib_empty(); - ccb->sip_referredBy = strlib_empty(); - ccb->referto = strlib_empty(); - ccb->sipxfercallid = strlib_empty(); - ccb->featuretype = CC_FEATURE_NONE; - ccb->join_info = NULL; - ccb->feature_data = NULL; - - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - ccb->sent_request[i].cseq_number = CCSIP_START_CSEQ; - ccb->sent_request[i].cseq_method = sipMethodInvalid; - ccb->sent_request[i].u.sip_via_branch = strlib_empty(); - ccb->sent_request[i].sip_via_sentby = strlib_empty(); - ccb->recv_request[i].cseq_number = CCSIP_START_CSEQ; - ccb->recv_request[i].cseq_method = sipMethodInvalid; - ccb->recv_request[i].u.sip_via_header = strlib_empty(); - ccb->recv_request[i].sip_via_sentby = strlib_empty(); - } - - ccb->last_recv_request_cseq = 0; - ccb->last_recv_request_cseq_method = sipMethodInvalid; - - if (ccb_index < REG_CCB_START) { - // If this is a tel CCB, restart the counter - ccb->last_used_cseq = CCSIP_START_CSEQ; - } else { - // If this is a reg CCB, continue from where we left off, - // and only initialize it the first time - if (ccb->last_used_cseq == 0) { - ccb->last_used_cseq = CCSIP_START_CSEQ; - } - } - - ccb->last_request = NULL; - - ccb->xfr_inprogress = SIP_SM_NO_XFR; - - - ccb->gsm_id = CC_NO_CALL_ID; - ccb->con_call_id = CC_NO_CALL_ID; - ccb->blind_xfer_call_id = CC_NO_CALL_ID; - ccb->xfer_status = 0; - - /* AVT info */ - config_get_value(CFGID_DTMF_AVT_PAYLOAD, &ccb->avt.payload_type, - sizeof(ccb->avt.payload_type)); - - /* SIP REGISTER info */ - ccb->reg.registered = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - ccb->reg.rereg_pending = 0; - - /* SIP authentication info */ - ccb->authen.retries_401_407 = 0; - ccb->authen.cred_type = 0; - ccb->authen.authorization = NULL; - ccb->authen.status_code = 0; - ccb->authen.nc_count = 0; - ccb->authen.new_flag = FALSE; - ccb->in_call_info = NULL; - ccb->out_call_info = NULL; - ccb->udpId = NULL; - ccb->callref = 0; - - return (0); -} - - - -const char * -sip_util_state2string (sipSMStateType_t state) -{ - switch (state) { - case SIP_STATE_NONE: - return ("SIP_STATE_NONE"); - - case SIP_STATE_IDLE: - return ("SIP_STATE_IDLE"); - - case SIP_STATE_SENT_INVITE: - return ("SIP_STATE_SENT_INVITE"); - - case SIP_STATE_SENT_INVITE_CONNECTED: - return ("SIP_STATE_SENT_INVITE_CONNECTED"); - - case SIP_STATE_RECV_INVITE: - return ("SIP_STATE_RECV_INVITE"); - - case SIP_STATE_RECV_INVITE_PROCEEDING: - return ("SIP_STATE_RECV_INVITE_PROCEEDING"); - - case SIP_STATE_RECV_INVITE_ALERTING: - return ("SIP_STATE_RECV_INVITE_ALERTING"); - - case SIP_STATE_RECV_INVITE_CONNECTED: - return ("SIP_STATE_RECV_INVITE_CONNECTED"); - - case SIP_STATE_ACTIVE: - return ("SIP_STATE_ACTIVE"); - - case SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING: - return ("SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING"); - - case SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING: - return ("SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING"); - - case SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING: - return ("SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING"); - - case SIP_STATE_RELEASE: - return ("SIP_STATE_RELEASE"); - - case SIP_STATE_BLIND_XFER_PENDING: - return ("SIP_STATE_BLIND_XFER_PENDING"); - - case SIP_STATE_SENT_OOD_REFER: - return ("SIP_STATE_SENT_OOD_REFER"); - - case SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING: - return ("SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING"); - - case SIP_STATE_SENT_MIDCALL_INVITE: - return ("SIP_STATE_SENT_MIDCALL_INVITE"); - - default: - return ("UNKNOWN STATE"); - } -} - - -const char * -sip_util_event2string (sipSMEventType_t event) -{ - switch (event) { - case E_SIP_INVITE: - return ("E_SIP_INVITE"); - case E_SIP_ACK: - return ("E_SIP_ACK"); - case E_SIP_BYE: - return ("E_SIP_BYE"); - case E_SIP_CANCEL: - return ("E_SIP_CANCEL"); - case E_SIP_1xx: - return ("E_SIP_1xx"); - case E_SIP_2xx: - return ("E_SIP_2xx"); - case E_SIP_3xx: - return ("E_SIP_3xx"); - case E_SIP_FAILURE_RESPONSE: - return ("E_SIP_FAILURE_RESPONSE"); - case E_SIP_REFER: - return ("E_SIP_REFER"); - case E_CC_SETUP: - return ("E_CC_SETUP"); - case E_CC_SETUP_ACK: - return ("E_CC_SETUP_ACK"); - case E_CC_PROCEEDING: - return ("E_CC_PROCEEDING"); - case E_CC_ALERTING: - return ("E_CC_ALERTING"); - case E_CC_CONNECTED: - return ("E_CC_CONNECTED"); - case E_CC_CONNECTED_ACK: - return ("E_CC_CONNECTED_ACK"); - case E_CC_RELEASE: - return ("E_CC_RELEASE"); - case E_CC_RELEASE_COMPLETE: - return ("E_CC_RELEASE_COMPLETE"); - case E_CC_FEATURE: - return ("E_CC_FEATURE"); - case E_CC_FEATURE_ACK: - return ("E_CC_FEATURE_ACK"); - case E_CC_CAPABILITIES: - return ("E_CC_CAPABILITIES"); - case E_CC_CAPABILITIES_ACK: - return ("E_CC_CAPABILITIES_ACK"); - case E_CC_SUBSCRIBE: - return ("E_CC_SUBSCRIBE"); - case E_CC_INFO: - return ("E_CC_INFO"); - case E_SIP_INV_EXPIRES_TIMER: - return ("E_SIP_INV_EXPIRES_TIMER"); - case E_SIP_INV_LOCALEXPIRES_TIMER: - return ("E_SIP_INV_LOCALEXPIRES_TIMER"); - case E_SIP_SUPERVISION_DISCONNECT_TIMER: - return ("E_SIP_SUPERVISION_DISCONNECT_TIMER"); - case E_SIP_TIMER: - return ("E_SIP_TIMER"); - case E_SIP_OPTIONS: - return ("E_SIP_OPTIONS"); - case E_SIP_UPDATE: - return ("E_SIP_UPDATE"); - case E_SIP_UPDATE_RESPONSE: - return ("E_SIP_UPDATE_RESPONSE"); - case E_SIP_GLARE_AVOIDANCE_TIMER: - return ("E_SIP_GLARE_AVOIDANCE_TIMER"); - case E_SIP_ICMP_UNREACHABLE: - return "E_SIP_ICMP_UNREACHABLE"; - default: - return ("UNKNOWN EVENT"); - } -} - - -sipSMEventType_t -sip_util_ccevent2sipccevent (cc_msgs_t cc_msg_id) -{ - switch (cc_msg_id) { - case CC_MSG_SETUP: - return (E_CC_SETUP); - case CC_MSG_SETUP_ACK: - return (E_CC_SETUP_ACK); - case CC_MSG_PROCEEDING: - return (E_CC_PROCEEDING); - case CC_MSG_ALERTING: - return (E_CC_ALERTING); - case CC_MSG_CONNECTED: - return (E_CC_CONNECTED); - case CC_MSG_CONNECTED_ACK: - return (E_CC_CONNECTED_ACK); - case CC_MSG_RELEASE: - return (E_CC_RELEASE); - case CC_MSG_RELEASE_COMPLETE: - return (E_CC_RELEASE_COMPLETE); - case CC_MSG_FEATURE: - return (E_CC_FEATURE); - case CC_MSG_FEATURE_ACK: - return (E_CC_FEATURE_ACK); - case CC_MSG_INFO: - return (E_CC_INFO); - default: - return ((sipSMEventType_t) (-1)); - } -} - - -void -sip_create_new_sip_call_id (char *sipCallID, uint8_t *mac_address, char *pSrcAddrStr) -{ - static uint16_t count = 1; - - count++; - - if (sipCallID == NULL) { - return; - } - snprintf(sipCallID, MAX_SIP_CALL_ID, "%.4x%.4x-%.4x%.4x-%.8x-%.8x@%s", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - count, (unsigned int)cpr_rand(), (unsigned int)cpr_rand(), pSrcAddrStr); -} - -void -sip_util_get_new_call_id (ccsipCCB_t *ccb) -{ - const char *fname = "sip_util_get_new_call_id"; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char pSrcAddrStr[MAX_IPADDR_STR_LEN]; - char *temp_call_id; - - memset(pSrcAddrStr, 0, MAX_IPADDR_STR_LEN); - - /* Args Check */ - if (!ccb) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args Check: ccb is null\n", fname); - return; - } - - /* use same call id for registration */ - if ((ccb->type == SIP_REG_CCB) && (ccb->sipCallID[0] != 0)) { - return; - } - - /* - * use pre allocated sip call id, if available. - */ - if (ccb->type != SIP_REG_CCB) { - temp_call_id = ccsip_find_preallocated_sip_call_id(ccb->dn_line); - if (temp_call_id != NULL) { - sstrncpy(ccb->sipCallID, temp_call_id, MAX_SIP_CALL_ID); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"using pre allocated call ID\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - ccsip_free_preallocated_sip_call_id(ccb->dn_line); - return; - } - } - ipaddr2dotted(pSrcAddrStr, &ccb->src_addr); - - platform_get_wired_mac_address(mac_address); - - sip_create_new_sip_call_id(ccb->sipCallID, mac_address, pSrcAddrStr); -} - - -void -sip_util_make_tag (char *pTagBuf) -{ - const char *fname = "sip_util_make_tag"; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - static uint16_t count = 1; - - if (!pTagBuf) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args Check: pTagBuf is null\n", fname); - return; - } - - platform_get_wired_mac_address(mac_address); - count++; - - snprintf(pTagBuf, MAX_SIP_URL_LENGTH, "%.4x%.4x%.4x%.4x%.8x-%.8x", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - count, (unsigned int)cpr_rand(), (unsigned int)cpr_rand()); -} - -int -sip_sm_init (void) -{ - line_t i; - const char *fname = "sip_sm_init"; - int sdpmode = 0; - - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - if (!sdpmode) { - - if (ccsip_register_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"registration initialization failed\n", fname); - return SIP_ERROR; - } - - if (ccsip_info_package_handler_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"info package initialization failed\n", fname); - return SIP_ERROR; - } - - /* - * Allocate timers for CCBs - */ - if (sip_platform_timers_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"timer initialization failed\n", fname); - return SIP_ERROR; - } - - if (sipTransportInit() != SIP_OK) { - return SIP_ERROR; - } - - DEF_DEBUG(DEB_F_PREFIX"Disabling mass reg state", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - for (i = 0; i < MAX_CCBS; i++) { - if (i == 0 || i == (MAX_CCBS-1)) { - g_disable_mass_reg_debug_print = FALSE; - } else { - g_disable_mass_reg_debug_print = TRUE; - } - sip_sm_call_cleanup(&(gGlobInfo.ccbs[i])); - if (sip_sm_ccb_init(&(gGlobInfo.ccbs[i]), i, 1, SIP_REG_STATE_IDLE) < 0) { - return SIP_ERROR; - } - } - g_disable_mass_reg_debug_print = FALSE; - - /* Initialize all timers */ - sip_platform_msg_timers_init(); - - /* Initialize Subscription Manager */ - if (sip_subsManager_init() != SIP_OK) { - return SIP_ERROR; - } - - } - - /* Initialize SDP Parser */ - if (!sip_sdp_init()) { - /* Error initialize the SDP error */ - return (SIP_ERROR); - } - - return SIP_OK; -} - -void -ccsip_handle_sip_shutdown () -{ - const char *fname = "handle_sip_shutdown"; - ccsipCCB_t *ccb = NULL; - line_t i; - - for (i = TEL_CCB_START; i <= TEL_CCB_END; i++) { - ccb = sip_sm_get_ccb_by_index(i); - if (ccb) { - switch (ccb->state) { - case SIP_STATE_RECV_INVITE: - case SIP_STATE_RECV_INVITE_PROCEEDING: - case SIP_STATE_RECV_INVITE_ALERTING: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Received invite: %d: STATE: %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, 0, NULL, - FALSE /* no SDP */ , FALSE /* reTx */); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, - CC_CAUSE_FACILITY_REJECTED); - ccb->wait_for_ack = FALSE; - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_RECV_INVITE_CONNECTED: - case SIP_STATE_ACTIVE: - default: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Clearing %d STATE: %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - sipSPISendBye(ccb, NULL, NULL); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - // send this to make sure GSM goes IDLE if it's currently in CONNECTED - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_SENT_INVITE: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Sent invite: Clearing %d STATE: %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - sipSPISendCancel(ccb); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, - CC_CAUSE_FACILITY_REJECTED); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_SENT_INVITE_CONNECTED: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Sent invite connected: Clearing %d STATE: %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - if (sipSPISendAck(ccb, NULL) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - sipSPISendBye(ccb, NULL, NULL); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - // send this to make sure GSM goes IDLE if it's currently in CONNECTED - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_RELEASE: - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Release: Clearing %d STATE: %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, - CC_CAUSE_FACILITY_REJECTED); - sip_sm_call_cleanup(ccb); - break; - - case SIP_STATE_IDLE: - break; - } - - } - } -} - -void -sip_shutdown (void) -{ - - DEF_DEBUG(DEB_F_PREFIX"SIP Shutting down...\n", DEB_F_PREFIX_ARGS(SIP_TASK, "sip_shutdown")); - - // The SIP SM is already shut down - if (sip.taskInited == FALSE) { - return; - } - - sip.taskInited = FALSE; - DEF_DEBUG(DEB_F_PREFIX" sip.taskInited is set to false\n", DEB_F_PREFIX_ARGS(SIP_TASK, "sip_shutdown")); - -//CPR TODO: need reference for - if ((PHNGetState() == STATE_CONNECTED) || - (PHNGetState() == STATE_DONE_LOADING) || - (PHNGetState() == STATE_CFG_UPDATE)) { - - // Disconnect calls and clean CCB - ccsip_handle_sip_shutdown(); - - // Unregister from all servers and deallocate reg ack timer - sip_regmgr_shutdown(); - - // Stop and deallocate timers - sip_platform_timers_shutdown(); - - // Shutdown Subscription Manager - (void) sip_subsManager_shut(); - //reset publish handler - publish_reset(); - - // Close all sockets - sipTransportShutdown(); - ccsip_remove_wlan_classifiers(); - } - - ccsip_info_package_handler_shutdown(); -} - -/****** -void sip_restart_phase2 (void *data) -{ - sip.taskInited = TRUE; // Forcing sip_shutdown() to execute - sip_shutdown(); - if (sip_sm_init() < 0) { - CCSIP_DEBUG_ERROR(" Error: sip_sm_init failed\n"); - return; - } - sip_platform_init(); - sip.taskInited = TRUE; - sip_mode_quiet = FALSE; - sip_reg_all_failed = FALSE; -} - -void sip_restart_phase1 (void) -{ - if (sip_reg_all_failed) { - // NO CCM available; need not wait for unreg timer - sip_restart_phase2(NULL); - } else { - // Unregister all lines - ccsip_register_cancel(TRUE, TRUE); - // Start timer with a 2sec expiration - sip_platform_unregistration_timer_start(2000); - - // Stop the periodic timer - (void) sip_platform_subnot_periodic_timer_stop(); - } -} -*******/ -void -sip_restart (void) -{ - const char *fname = "sip_restart"; - - DEF_DEBUG(DEB_F_PREFIX"In sip_restart\n", DEB_F_PREFIX_ARGS(SIP_CTRL, fname)); - if (sip_sm_init() < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_init failed\n", fname); - return; - } - sip_platform_init(); - sip.taskInited = TRUE; - DEF_DEBUG(DEB_F_PREFIX"sip.taskInited is set to true \n", DEB_F_PREFIX_ARGS(SIP_CTRL, fname)); - sip_mode_quiet = FALSE; - sip_reg_all_failed = FALSE; - ccsip_remove_wlan_classifiers(); - - // Initialize all GSM modules - cc_fail_fallback_gsm(CC_SRC_SIP, CC_RSP_COMPLETE, CC_REG_FAILOVER_RSP); -} - -void -sip_shutdown_phase2 (int action) -{ - DEF_DEBUG(DEB_F_PREFIX"(%d)\n", - DEB_F_PREFIX_ARGS(SIP_CTRL, "sip_shutdown_phase2"), action); - sip.taskInited = TRUE; // Forcing sip_shutdown() to execute - DEF_DEBUG(DEB_F_PREFIX"sip.taskInited is set to true\n", DEB_F_PREFIX_ARGS(SIP_CTRL, "sip_shutdown_phase2")); - sip_shutdown(); - if (action == SIP_EXTERNAL || action == SIP_STOP) { - shutdownCCAck(action); - } else if (action == SIP_INTERNAL) { - // Continue on to reinit - sip_restart(); - } -} - -void -sip_shutdown_phase1 (int action, int reason) -{ - DEF_DEBUG(DEB_F_PREFIX"In sip_shutdown_phase1 (%d)\n", - DEB_F_PREFIX_ARGS(SIP_CTRL, "sip_shutdown_phase1"), action); - if (sip_reg_all_failed) { - // NO CCM available; need not wait for unreg timer - sip_shutdown_phase2(action); - } else { - // Unregister all lines - ccsip_register_cancel(TRUE, TRUE); - // Start timer with a 2sec expiration - (void) sip_platform_unregistration_timer_start(2000, (boolean) action); - } -} - -ccsipCCB_t * -sip_sm_get_ccb_by_ccm_id_and_index (int ccmid, line_t idx) -{ - static const char fname[] = "sip_sm_get_ccb_by_ccm_id_and_index"; - fallback_ccb_t *fallback_ccb; - ccsipCCB_t * ccb = NULL; - CCM_ID ccm_id = ccmid; - - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"invalid ccm_id=%d " - "ccb_index=%d\n",DEB_F_PREFIX_ARGS(SIP_BRANCH, fname), - ccm_id , idx); - return ccb; - } - - if ((int) idx < MAX_CCBS) { - ccb = &(gGlobInfo.ccbs[idx]); - } - /* - * regmgr - Could be Fallback ccb's - */ - if (ccb == NULL) { - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(idx); - if (fallback_ccb != NULL) { - ccb = fallback_ccb->ccb; - } - } - if (ccb != NULL) { - if ((ccb->cc_cfg_table_entry == NULL) || - (((ti_config_table_t *)(ccb->cc_cfg_table_entry))->ti_specific.ti_ccm.ccm_id != ccm_id)) { - /* - * the standby cucm must have moved to active position, but we did not - * yet have processed the failover response where ccb are updated to - * point to new active. That is why we are getting into this situation. - * Currently, we are throwing away the message, which is mainly the msg - * that standby cucm has sent. Should not do much harm. - */ - DEF_DEBUG(DEB_F_PREFIX"ccb index has moved or cfg_table not initialized for the cucm=%s. " - "index=%d ccb=%d. Throwing away the msg.\n",DEB_F_PREFIX_ARGS(SIP_BRANCH, fname), - CCM_ID_PRINT(ccm_id), idx, ccb); - ccb = NULL; - } - } - if (ccb == NULL) { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Could not find ccb ccb_index=%d", - DEB_F_PREFIX_ARGS(SIP_BRANCH, fname), idx); - } - return ccb; -} - -ccsipCCB_t * -sip_sm_get_ccb_by_index (line_t idx) -{ - fallback_ccb_t *fallback_ccb; - - if ((int) idx < MAX_CCBS) { - return &(gGlobInfo.ccbs[idx]); - } - /* - * regmgr - Could be Fallback ccb's - */ - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(idx); - if (fallback_ccb != NULL) { - return (fallback_ccb->ccb); - } - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), "sip_sm_get_ccb_by_index", - idx); - return NULL; -} - - -ccsipCCB_t * -sip_sm_get_ccb_by_callid (const char *callid) -{ - line_t i; - - if (callid[0] == '\0') { - /* Requesting call ID is NULL string, not allow */ - return (NULL); - } - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - return &(gGlobInfo.ccbs[i]); - } - } - - return NULL; -} - -callid_t -sip_sm_get_blind_xfereror_ccb_by_gsm_id (callid_t gsm_id) -{ - uint16_t i; - - for (i = 0; i < MAX_CCBS; i++) { - if (gsm_id == gGlobInfo.ccbs[i].blind_xfer_call_id) { - return gGlobInfo.ccbs[i].gsm_id; - } - } - - return CC_NO_CALL_ID; -} - - -ccsipCCB_t * -sip_sm_get_ccb_by_target_call_id (callid_t con_id) -{ - uint16_t i; - - for (i = 0; i < MAX_CCBS; i++) { - if (con_id == gGlobInfo.ccbs[i].gsm_id) { - return &(gGlobInfo.ccbs[i]); - } - } - - return NULL; -} - -ccsipCCB_t * -sip_sm_get_target_call_by_gsm_id (callid_t gsm_id) -{ - uint16_t i; - - for (i = 0; i < MAX_CCBS; i++) { - if (gsm_id == gGlobInfo.ccbs[i].con_call_id) { - return &(gGlobInfo.ccbs[i]); - } - } - - return NULL; -} - -ccsipCCB_t * -sip_sm_get_target_call_by_con_call_id (callid_t con_call_id) -{ - uint16_t i; - - for (i = 0; i < MAX_CCBS; i++) { - if (con_call_id == gGlobInfo.ccbs[i].gsm_id) { - return &(gGlobInfo.ccbs[i]); - } - } - - return NULL; -} - -ccsipCCB_t * -sip_sm_get_ccb_next_available (line_t *line_number) -{ - line_t i; - - for (i = TEL_CCB_START; i <= TEL_CCB_END; i++) { - if (gGlobInfo.ccbs[i].state == SIP_STATE_IDLE) { - *line_number = i; - break; - } - } - - if (i > TEL_CCB_END) { - return NULL; - } - return &(gGlobInfo.ccbs[i]); -} - -/** - * sip_sm_get_ccb_by_gsm_id - * - * This fucntion tries to match the ccbs given the gsm id - * The algorithm tries to match the non duplicate CCB first - * If the only match is a DUP_CCB it shall be returned as a match - * @param[in] gsm_id GSM ID in the CCB - * - * @return ccsipCCB_t * or NULL - * - */ -ccsipCCB_t * -sip_sm_get_ccb_by_gsm_id (callid_t gsm_id) -{ - line_t i; - ccsipCCB_t *dupCCB = NULL; - - if ( gsm_id == CC_NO_CALL_ID ) - return NULL; - - for (i = 0; i < MAX_CCBS; i++) { - if (gGlobInfo.ccbs[i].gsm_id == gsm_id) { - if ( gGlobInfo.ccbs[i].dup_flags & DUP_CCB ) { - dupCCB = &(gGlobInfo.ccbs[i]); - } else { - return &(gGlobInfo.ccbs[i]); - } - } - } - - return dupCCB; -} - -/** - * sip_sm_ccb_match_branch_cseq - * - * This fucntion tries to match the Branch and Cseq ID for a - * given CCB to see if the values match in the response with the - * values sent in the request. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] sipCseq Pointer to sipCseq_t structure. - * @param[in] via_this Pointer to sipVia_t structure. - * - * @pre (ccb not_eq NULL) - * @pre (sipCseq not_eq NULL) - * @pre (via_this not_eq NULL) - * - * @return TRUE/FALSE - * - */ -static boolean -sip_sm_ccb_match_branch_cseq (ccsipCCB_t *ccb, - sipCseq_t *sipCseq, - sipVia_t *via_this) -{ - const char *fname = "sip_sm_ccb_match_branch_cseq"; - int16_t trx_index = -1; - sipTransaction_t *trx = NULL; - - trx_index = get_method_request_trx_index(ccb, sipCseq->method, - TRUE); - if (trx_index != -1) { - // match cseq and viabranchid - trx = &(ccb->sent_request[trx_index]); - if ((trx->cseq_number == sipCseq->number) && - (trx->u.sip_via_branch[0] != '\0') && - (via_this->branch_param != NULL) && - (strncmp(trx->u.sip_via_branch, via_this->branch_param, - VIA_BRANCH_LENGTH) == 0)) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched branch_id & CSeq\n", DEB_F_PREFIX_ARGS(SIP_BRANCH, fname)); - return (TRUE); - } else { - CCSIP_DEBUG_ERROR(SIP_L_C_F_PREFIX"Mismatched CSeq or" - " Via's branch parameter in response:" - "ccb=0x%x,%d, cseq(trx,msg)=(%d,%d)," - "branch(trx,msg)=(%s,%s)\n", - ccb->dn_line, ccb->gsm_id, fname, ccb, - ccb->index, trx->cseq_number, sipCseq->number, - trx->u.sip_via_branch, - via_this->branch_param); - return (FALSE); - } - } - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Method index not found\n", fname); - return (FALSE); -} - -// The function below attempts to determine more intelligently if there -// is an existing dialog to which an incoming message should be directed. -// In addition to call-id, it also considers the Req-URI, CSeq, etc. -uint16_t -sip_sm_determine_ccb (const char *callid, - sipCseq_t * sipCseq, - sipMessage_t *pSipMessage, - boolean is_request, - ccsipCCB_t **ccb_ret) -{ - - const char *fname = "sip_sm_determine_ccb"; - const char *to = NULL; - sipLocation_t *to_loc = NULL; - line_t i; - ccsipCCB_t *ccb = NULL; - sipReqLine_t *requestURI = NULL; - genUrl_t *genUrl = NULL; - sipUrl_t *sipUriUrl = NULL; - char *pUser = NULL; - char reqURI[MAX_SIP_URL_LENGTH]; - int16_t trx_index = -1; - sipTransaction_t *trx = NULL; - sipVia_t *via_this = NULL; - sipVia_t *via_last = NULL; - const char *pViaHeaderStr = NULL; - boolean match = FALSE; - - *ccb_ret = NULL; - - // Dialog matching algorithm is as follows: - // First, obtain the CCB by matching call-id and to-tag, if present - to = sippmh_get_cached_header_val(pSipMessage, TO); - if (to) { - to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (to_loc) { - if (to_loc->tag) { - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - ccb = &(gGlobInfo.ccbs[i]); - if (ccb->sip_to_tag[0] != '\0') { - if (strcmp(to_loc->tag, ccb->sip_to_tag) == 0) { - *ccb_ret = ccb; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched to_tag\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - break; - } else if (strcmp(to_loc->tag, ccb->sip_from_tag) == 0) { - *ccb_ret = ccb; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched from_tag\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - break; - } - } - } - } - } - sippmh_free_location(to_loc); - } - } - - // Get the VIA parameters so proper matching can be done - pViaHeaderStr = sippmh_get_cached_header_val(pSipMessage, VIA); - if (pViaHeaderStr) { - via_this = sippmh_parse_via(pViaHeaderStr); - } - if (!pViaHeaderStr || !via_this) { - return (SIP_CLI_ERR_BAD_REQ); - } - - // If not found, and this is a request, obtain by matching call-id, - // and user part of the ReqURI - if ((*ccb_ret == NULL) && is_request) { - reqURI[0] = '\0'; - requestURI = sippmh_get_request_line(pSipMessage); - if (requestURI) { - if (requestURI->url) { - genUrl = sippmh_parse_url(requestURI->url, TRUE); - if (genUrl) { - if (genUrl->schema == URL_TYPE_SIP) { - sipUriUrl = genUrl->u.sipUrl; - if (sipUriUrl) { - pUser = sippmh_parse_user(sipUriUrl->user); - if (pUser) { - sstrncpy(reqURI, pUser, sizeof(reqURI)); - cpr_free(pUser); - } else { - sstrncpy(reqURI, sipUriUrl->user, sizeof(reqURI)); - } - } - } - sippmh_genurl_free(genUrl); - } - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - ccb = &(gGlobInfo.ccbs[i]); - if (ccb->ReqURI[0] != '\0') { - if (strcmp(ccb->ReqURI, reqURI) == 0) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched reqURI\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - *ccb_ret = ccb; - break; - } - } - } - } - if (*ccb_ret == NULL) { - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - ccb = &(gGlobInfo.ccbs[i]); - if ((sipCseq->method == sipMethodInvite) && - (ccb->state < SIP_STATE_ACTIVE)) { - // Return this CCB if we match call-id but have - // not connected yet - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched Call-id - not active.\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - *ccb_ret = ccb; - break; - } - if (((sipCseq->method == sipMethodCancel) && - (ccb->state < SIP_STATE_ACTIVE)) || - ((sipCseq->method == sipMethodAck) && - (ccb->state == SIP_STATE_RELEASE))) { - // For CANCEL, try and match the via branch-id with the - // corresponding via branch-id of the INVITE received earlier. - // Normally the R-URI of the CANCEL should match the stored - // ReqURI but it is possible that the stored value was overwritten. - // via_last is the via header from the previous INVITE - // For ACK, we might be receiving this if there we responded with - // an error to the initial INVITE - trx_index = get_method_request_trx_index(ccb, - sipMethodInvite, - FALSE); - - if (trx_index != -1) { - const char *toString; - const char *fromString; - - toString = sippmh_get_cached_header_val(pSipMessage, TO); - fromString = sippmh_get_cached_header_val(pSipMessage, FROM); - - trx = &(ccb->recv_request[trx_index]); - - if (trx->u.sip_via_header[0] != '\0') { - pViaHeaderStr = (char *) (trx->u.sip_via_header); - via_last = sippmh_parse_via(pViaHeaderStr); - } - - if (fromString && toString) { - if ((strcmp(ccb->sip_from, fromString) == 0) && - (strncmp(ccb->sip_to, toString, strlen(toString)) == 0) && - (trx->cseq_number == sipCseq->number) && - (via_last && (via_last->branch_param != NULL)) && - (via_this->branch_param != NULL) && - (strcmp(via_last->branch_param, via_this->branch_param) == 0)) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Matched branch_id & CSeq for CANCEL/ACK\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - *ccb_ret = ccb; - sippmh_free_via(via_last); - via_last = NULL; - break; - } - } - if (via_last) { - sippmh_free_via(via_last); - via_last = NULL; - } - } - } - } - } - } - } - - // If found, and this is a request, check for any existing trx in - // progress by matching with recd trx's cseq method and number. If - // these are the same and the branch-id is different, this is a merged - // request. Here via_last is the via header from the last receipt of the same request - if ((*ccb_ret != NULL) && is_request) { - ccb = *ccb_ret; - trx_index = get_method_request_trx_index(ccb, sipCseq->method, FALSE); - if (trx_index != -1) { - if (ccb->recv_request[trx_index].u.sip_via_header[0] != '\0') { - pViaHeaderStr = (char *) (ccb->recv_request[trx_index].u.sip_via_header); - via_last = sippmh_parse_via(pViaHeaderStr); - } - if (via_last) { - if (sipCseq->number == ccb->recv_request[trx_index].cseq_number) { - if (via_this->branch_param && via_last->branch_param) { - if (strcmp(via_this->branch_param, - via_last->branch_param)) { - // merged request - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Found Merged Request\n", fname); - sippmh_free_via(via_this); - sippmh_free_via(via_last); - return (SIP_CLI_ERR_LOOP_DETECT); - } - } - } - sippmh_free_via(via_last); - } - } - - } - // If this is a response, match it with a sent transaction in CCB - // by obtaining the CCB by call-id and then going through the - // transactions within it and matching branch-id and CSeq - if ((*ccb_ret == NULL) && !is_request) { - - for (i = 0; i < MAX_CCBS; i++) { - if (strcmp(callid, gGlobInfo.ccbs[i].sipCallID) == 0) { - ccb = &(gGlobInfo.ccbs[i]); - match = sip_sm_ccb_match_branch_cseq(ccb, sipCseq, - via_this); - sippmh_free_via(via_this); - if (match) { - *ccb_ret = ccb; - return (0); - } else { - return (SIP_CLI_ERR_NOT_ACCEPT); - } - } - } - /* - * If ret_ccb is NULL after all this and the message is a - * response, check the fallback ccb list if any of those match - * the message call id. - */ - sip_regmgr_find_fallback_ccb_by_callid(callid, ccb_ret); - } - - /* - * If the CCB is not NULL and this is a response, then check - * if the branch and Cseq match. - */ - if ((*ccb_ret != NULL) && !is_request) { - match = sip_sm_ccb_match_branch_cseq(*ccb_ret, sipCseq, - via_this); - sippmh_free_via(via_this); - if (match) { - return (0); - } else { - return (SIP_CLI_ERR_NOT_ACCEPT); - } - } - - sippmh_free_via(via_this); - return (0); -} - -void -ccsip_handle_default (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_default"; - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d No action -> %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); -} - - -void -ccsip_handle_default_sip_message (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "default_sip_message"; - sipMessage_t *msg = NULL; - int16_t trx_index = -1; - - msg = event->u.pSipMessage; - - if (event->type == E_SIP_ACK) { - // If this is an ACK, make sure and clean out the corresponding INVITE - // transaction - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - } else if (event->type == E_SIP_INVITE) { - // If this is an INVITE and we are already processing an earlier - // INVITE return a 500 response - trx_index = get_method_request_trx_index(ccb, sipMethodInvite, FALSE); - if (trx_index != -1) { - (void) sipSPISendErrorResponse(msg, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - "Earlier INVITE being processed", - NULL); - } - } else if (event->type == E_SIP_UPDATE) { - // If this is an UPDATE and we are already processing an earlier - // UPDATE return a 500 response - trx_index = get_method_request_trx_index(ccb, sipMethodUpdate, FALSE); - if (trx_index != -1) { - (void) sipSPISendErrorResponse(msg, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - "Earlier UPDATE being processed", - NULL); - } - - } else if (event->type == E_SIP_CANCEL) { - (void) sipSPISendErrorResponse(msg, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, 0, NULL, ccb); - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Sent 481 (CANCEL) %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); - } - - /* Deallocate the incoming SIP message */ - if (msg) { - free_sip_message(msg); - } - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: No action -> %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, sip_util_state2string(ccb->state)); -} - -/** - * ccsip_handle_default_ev_cc_feature - * - * The function is a default function for handling CC_FEATURE in the - * state that does not expect CC_FEATURE. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return N/A - * - */ -void -ccsip_handle_default_ev_cc_feature (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_default_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - /* - * The feature event is not supported by the current state or - * it is inappropriate event in the current state. Send feature ack - * with error code. - */ - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); -} - -/** - * ccsip_handle_default_recvreq_ack_pending_ev_cc_feature - * - * The function is a default handler for CC_FEATURE while in the - * received INVITE, UPDATE and the state machine is waiting for - * feature ack from GSM or SIP ack pending. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return N/A - */ -void -ccsip_handle_default_recvreq_ack_pending_ev_cc_feature (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = - "ccsip_handle_default_recvreq_ack_pending_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - - switch (feature_type) { - case CC_FEATURE_RESUME: - case CC_FEATURE_HOLD: - case CC_FEATURE_MEDIA: - /* - * Received resume/hold/media request while waiting for feauture ack or - * SIP ack for hold that was received. Indicate that the request - * can not proceed now and it should be retried later. - */ - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, - NULL, CC_CAUSE_REQUEST_PENDING); - break; - - case CC_FEATURE_SELECT: - case CC_FEATURE_CANCEL: - break; - default: - /* Other feature request is not supported or allowed now */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, - NULL, CC_CAUSE_ERROR); - break; - } -} - -/* - * Function: sip_is_releasing() - * - * Parameters: ccb - The current call control block - * - * Description: This routine supports determining whether the - * the call is in releasing state or not. - * - * Returns: - * TRUE - call is being released. - * FALSE - call is not being released. - */ -boolean -sip_is_releasing (ccsipCCB_t *ccb) -{ - if (ccb != NULL) { - /* Call exists */ - if (ccb->state == SIP_STATE_RELEASE) { - return (TRUE); - } - } - return (FALSE); -} - -void -ccsip_handle_default_sip_response (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "default_sip_response"; - sipMessage_t *response; - int response_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - - /* Get the response code */ - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - - /* Check if this is an INVITE response */ - if ((!sip_sm_is_invite_response(response)) || (response_code < 200)) { - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - - if (sipSPISendAck(ccb, response) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - /* Deallocate the memory for the response */ - free_sip_message(response); -} - -/* - * ccsip_restart_reTx_timer - * - * This function is called when resending a message - * due to a timeout or ICMP unreachable. It just - * restarts the re-transmit timer. - */ -void -ccsip_restart_reTx_timer (ccsipCCB_t *ccb, sipMethod_t messageType) -{ - const char *fname = "ccsip_restart_reTx_timer"; - uint32_t time_t1 = 0; - uint32_t time_t2 = 0; - uint32_t timeout = 0; - - /* Restart the reTx timer */ - config_get_value(CFGID_TIMER_T1, &time_t1, sizeof(time_t1)); - timeout = time_t1 * (1 << ccb->retx_counter); - // Adjust the max timer - but only for non INVITE transactions - if (messageType != sipMethodInvite) { - config_get_value(CFGID_TIMER_T2, &time_t2, sizeof(time_t2)); - if (timeout > time_t2) { - timeout = time_t2; - } - } - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Restarting timer (%d msec)" - " (msg is %s)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, timeout, sipGetMethodString(messageType)); - - ccb->retx_flag = TRUE; - if (sip_platform_msg_timer_start(timeout, (void *)((long)ccb->index), ccb->index, - sipPlatformUISMTimers[ccb->index].message_buffer, - sipPlatformUISMTimers[ccb->index].message_buffer_len, - sipPlatformUISMTimers[ccb->index].message_type, - &(sipPlatformUISMTimers[ccb->index].ipaddr), - sipPlatformUISMTimers[ccb->index].port, - FALSE) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "sip_platform_msg_timer_start()"); - ccb->retx_flag = FALSE; - return; - } -} - -/* - * ccsip_handle_obp_error() - * - * This function is called when a sip re-try timer - * pops or an ICMP unreachable is received after a - * msg is sent and the cause is the msg bounced or - * timed out trying to reach the outbound proxy. - * - * Data is the IP address that bounced or -1 if it was - * a timeout. - * - */ -void -ccsip_handle_obp_error (ccsipCCB_t *ccb, sipMethod_t messageType, cpr_ip_addr_t *data) -{ - const char *fname = "ccsip_handle_obp_error"; - boolean resend = FALSE; - uint32_t max_retx = 0; - - char obp_address[MAX_IPADDR_STR_LEN]; - - config_get_string(CFGID_OUTBOUND_PROXY, obp_address, sizeof(obp_address)); - /* Did the msg bounce? */ - if (util_compare_ip(data, &ccb->outBoundProxyAddr)) { - /* Try next proxy if one exists */ - ccb->outBoundProxyPort = 0; - ccb->retx_counter = 0; - if (str2ip(obp_address, &ccb->outBoundProxyAddr) != 0) { - resend = TRUE; - } - - /* Msg timed out */ - } else { - if (messageType == sipMethodInvite) { - config_get_value(CFGID_SIP_INVITE_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_INVITE_RETRY_ATTEMPTS; - } - } else { - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - } - - /* Retries exhausted, get next proxy if one exists */ - if (ccb->retx_counter >= max_retx) { - ccb->outBoundProxyPort = 0; - ccb->retx_counter = 0; - if (str2ip(obp_address, &ccb->outBoundProxyAddr) != 0) { - /* if the obp is just an ip addr, there is nothing else to try */ - resend = TRUE; - } - - /* Retries not exhausted */ - } else { - resend = TRUE; - } - } - - if (resend) { - if (sipSPISendLastMessage(ccb) == TRUE) { - ccb->retx_counter++; - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Resent message: #%d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_MSG_SEND, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->retx_counter); - ccsip_restart_reTx_timer(ccb, messageType); - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - } - } else { - sip_platform_msg_timer_outstanding_set(ccb->index, FALSE); - if ((ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) || - (ccb->state == SIP_STATE_RELEASE)) { - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - } else { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - } - } else { - sip_platform_msg_timer_outstanding_set(ccb->index, FALSE); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } -} - -int -ccsip_pick_a_proxy (ccsipCCB_t *ccb) -{ - uint32_t max_retx = 0; - sipMethod_t retxMessageType = sipPlatformUISMTimers[ccb->index].message_type; - char addr[MAX_IPADDR_STR_LEN]; - const char *fname = "ccsip_pick_a_proxy"; - - memset(addr, 0, sizeof(addr)); - - /* Get the type of the retransmitted message. - * If it INVITE, then we need to use a different timer count - */ - if (retxMessageType == sipMethodInvite) { - config_get_value(CFGID_SIP_INVITE_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_INVITE_RETRY_ATTEMPTS; - } - if (gGlobInfo.backup_active) { - if (ccb->proxySelection != SIP_PROXY_BACKUP) { - /* - * If we have previously failed to contract the normal/regular - * proxy then use a reduce re-try count for subsequent attempts - * i.e failover to the backup proxy faster - */ - if (ccb->retx_counter >= 3) { - ccb->retx_counter = max_retx; - } - } - } - /* - * Check if we have maxed out the re-transmits on invite - * and not yet tried the backup proxy. - */ - if ((ccb->retx_counter >= max_retx) && - (ccb->proxySelection != SIP_PROXY_BACKUP) && - (ccb->proxySelection != SIP_PROXY_DO_NOT_CHANGE_MIDCALL)) { - dns_error_code = DNS_ERR_HOST_UNAVAIL; - /* Try and fetch a proxy using DNS SRV records */ - sipTransportGetPrimServerAddress(ccb->dn_line, addr); - if (str2ip(addr, &ccb->dest_sip_addr) != 0) { - dns_error_code = sip_dns_gethostbysrv(addr, &ccb->dest_sip_addr, - (uint16_t *)&ccb->dest_sip_port, - &ccb->SRVhandle, TRUE); - if (dns_error_code == DNS_OK) { - util_ntohl(&(ccb->dest_sip_addr), &(ccb->dest_sip_addr)); - /* - * Modify destination fields in call back timer struct - */ - (void) sip_platform_msg_timer_update_destination(ccb->index, - &(ccb->dest_sip_addr), - (uint16_t) ccb->dest_sip_port); - /* - * Reset re-transmit counter so we try again - */ - ccb->retx_counter = 0; - - } - } - /* - * Either we are using DNS SRV records and we exhausted the list - * Or we are not using DNS SRV and we need to try the backup - */ - if (dns_error_code != DNS_OK) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Unable to reach proxy, attempting backup.\n", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - if (ccsip_attempt_backup_proxy(ccb)) { - - ccb->first_backup = TRUE; - /* - * Get rid of transaction block for the ccb, we may have - * tried primary proxy etc - */ - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - - /* - * If contact info is supplied, as in the case of a 3xx - * redirect and perhaps other cases TBD. And since calls - * to the backup are essentially a "NEW" call so to speak, - * nuke it and run. - */ - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - /* Ditto for record route */ - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - - /* - * Recreate the SIP message, because the IP address has - * changed. Ie. the reqURI has the old proxy IP address, - * but now it should have the new backup proxy address - * so we are setting boolean initInvite to TRUE. initInvite - * will be used in sipSPIGenRequestURI to make reqURI with - * new backup proxy address - */ - if ((sipSPISendInvite(ccb, - ccb->wastransferred ? SIP_INVITE_TYPE_TRANSFER : - SIP_INVITE_TYPE_NORMAL, TRUE) != TRUE)) { - sip_sm_call_cleanup(ccb); - return FALSE; - } - - /* - * Reset counters so we try again using the backup proxy - */ - ccb->retx_counter = 0; - - /* Backup proxy failed as well. Broadcast once */ - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Attempt to reach backup proxy" - " failed. Message will be broadcast.\n", - DEB_F_PREFIX_ARGS(SIP_PROXY, fname)); - return 1; - } - } - } - } else { - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - } - return max_retx; -} - -/* - * Function: ccsip_handle_icmp_unreachable: - * Description: This function handles ICMP events. For failed attempts - * for requests (that get back an ICMP) this function checks - * to see if we are in a dialog. If so, there is place holder - * to follow through with DNS SRV (future work) and if all - * DNS SRV calls have failed then it tears down the call. - * - * If request was an out-of-dialog request, the code sets - * the the ccb->retx_count to exceed max retries so it will - * be treated as a failure to send the server (so retries to - * the same server will not be attempted). - */ -void -ccsip_handle_icmp_unreachable (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_icmp_unreachable"; - - /* - * 1. Check to see if we are in a dialog - * 1.1. If we are in a dialog and the fqdn was resolved by SRV, - * then we must iterate to the next SRV result - * 1.2. if we have no more servers from the SRV lookup, - * we have to call it quits. - * 2. if we are not in a dialog, then map the icmp event to a timer event - * but set the retry count to appropriate value so the timer handler can - * pick up the next server rather than retry the same one. - */ - - if (ccb->sip_to_tag[0] != '\0') { - //we are in a dialog - // NOT USED: sipMessage_t *response; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"ICMP received within a dialog.\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - /* - * At this point we should be checking to see if we picked up an - * fqdn that picked up from the route set was a SRV RR. If so, - * we must iterate to the next result returned. - * - * But we cannot do that now. Our SRV mechanism is incorrect. - * Firstly we must store SRV associations (handle to srv returns) - * in the sipTransaction_t object. - * - * This is future work. - * - * So for now we clobber the call. - */ - - ccb->wait_for_ack = FALSE; - sip_cc_release_complete(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL); - sip_sm_call_cleanup(ccb); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"ICMP received outside of a dialog.\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - //ccb->retx_counter = 100; //to cause failover to next proxy if one is available - ccsip_handle_default_sip_timer(ccb, event); - } -} - -/* - * ccsip_handle_default_sip_timer() - * - * This function is called when a sip re-try timer - * pops or an ICMP unreachable is received after a - * msg is sent. The ICMP unreachable code sets - * retx_counter to MAX to force the code to try the - * next proxy in the list. Event.u.usrInfo is set to - * the IP address that bounced or -1 if it is a timeout. - * - * Note: Registration bounces and timeouts are handled - * by the function ccsip_handle_ev_tmr_retry. - */ -void -ccsip_handle_default_sip_timer (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_default_sip_timer"; - uint32_t max_retx = 0; - sipMethod_t retxMessageType = sipPlatformUISMTimers[ccb->index].message_type; - char addr[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t out_ip; - - CPR_IP_ADDR_INIT(out_ip); - - /* Timing issue on re-transmission and receiving an Ack. - * The timer could pop and we re-transmit and the Ack - * already be in the queue. When this happens, we process - * the Ack and go into the Active/Hold state. In the Active/Hold - * state, we don't expect an ack, so nothing happens and - * thus the new timer will eventually pop and start the - * whole process over. If we are in the Active/Hold state, we - * did receive the Ack. On the next time-out, just ignore it - * and don't re-start or re-transmit. The phone could be in - * the ACTIVE or HOLD states if a REFER has been sent with - * no response. Therefore ensure messagetype is not REFER - * before kicking out. - */ - if ((retxMessageType != sipMethodRefer) && - ((ccb->state == SIP_STATE_ACTIVE))) { - return; - } - - /* OK, we got a timer pop, but the re-transmit flag - * isn't set. This means someone got a response that - * told them they could stop re-transmitting. Simply - * exit this function and do not re-start timer or - * re-transmit the message. - */ - if (ccb->retx_flag == FALSE) { - if (ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) { - sip_platform_msg_timer_outstanding_set(ccb->index, FALSE); - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - } - return; - } - - /* Determine if msg to outbound proxy bounced or timed out */ - util_ntohl(&out_ip, &event->u.UsrInfo); - if ((util_compare_ip(&out_ip, &(ccb->outBoundProxyAddr))) || - ((event->u.UsrInfo.type == CPR_IP_ADDR_INVALID) && - util_check_if_ip_valid(&(ccb->outBoundProxyAddr)))) { - ccsip_handle_obp_error(ccb, retxMessageType, &(event->u.UsrInfo)); - return; - } - - /* Determine if there is a proxy to send to */ - max_retx = ccsip_pick_a_proxy(ccb); - - /* Increment counter */ - ccb->retx_counter++; - - /* - * Our work is done if the backup proxy has just been activated. - * We know that is has just been activated if the first_backup flag is TRUE. - */ - if ((ccb->proxySelection == SIP_PROXY_BACKUP) && (ccb->first_backup)) { - ccb->first_backup = FALSE; - return; - } - - /* Resend */ - if (ccb->retx_counter <= max_retx) { - if (sipSPISendLastMessage(ccb) == TRUE) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d:Resent message: #%d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_MSG_SEND, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->retx_counter); - } - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - } - ccsip_restart_reTx_timer(ccb, retxMessageType); - - /* All retransmit attempts have been exhausted */ - } else { - ccb->retx_counter = 0; - sip_platform_msg_timer_outstanding_set(ccb->index, FALSE); - - /* Check for redirection */ - if (ccb->state == SIP_STATE_SENT_INVITE) { - if (ccb->redirect_info != NULL) { - sip_redirect(ccb, NULL, SIP_CLI_ERR_REQ_TIMEOUT); - return; - } - } - /* - * Resend msg to next proxy in the list if one exists - * Try and fetch another proxy using DNS SRV or A records - */ - sipTransportGetPrimServerAddress(ccb->dn_line, addr); - if (str2ip(addr, &ccb->dest_sip_addr) != 0) { - dns_error_code = sipTransportGetServerAddrPort(addr, - &ccb->dest_sip_addr, - (uint16_t *)&ccb->dest_sip_port, - &ccb->SRVhandle, - TRUE); - } else { - /* This ip addr has already been tried */ - dns_error_code = DNS_ERR_HOST_UNAVAIL; - } - if (dns_error_code == 0) { - util_ntohl(&(ccb->dest_sip_addr), &(ccb->dest_sip_addr)); - /* Modify destination fields in call back timer */ - (void) sip_platform_msg_timer_update_destination(ccb->index, - &(ccb->dest_sip_addr), - (uint16_t)ccb->dest_sip_port); - if (sipSPISendLastMessage(ccb) == TRUE) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Resent message: #%d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_MSG_SEND, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->retx_counter); - } - ccsip_restart_reTx_timer(ccb, retxMessageType); - if (ccb->state == SIP_STATE_RELEASE) { - (void) sip_platform_supervision_disconnect_timer_stop(ccb->index); - } - } else { - if ((ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) || - (ccb->state == SIP_STATE_RELEASE)) { - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - return; - } else if (retxMessageType == sipMethodRefer && - (ccb->featuretype == CC_FEATURE_B2BCONF || - ccb->featuretype == CC_FEATURE_SELECT || - ccb->featuretype == CC_FEATURE_B2B_JOIN || - ccb->featuretype == CC_FEATURE_CANCEL)) { - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, - NULL, CC_CAUSE_ERROR); - return; - } else { - handle_error_for_state(ccb, SIP_CLI_ERR_REQ_TIMEOUT); - return; - } - } - } - - /* Restart re-transmit timer */ - ccsip_restart_reTx_timer(ccb, retxMessageType); -} - - -void -sip_decrement_backup_active_count (ccsipCCB_t *ccb) -{ - /* - * OK If we successfully received a response we need to back off from using the backup - * proxy if that was the case. Note if this is a response from the backup chuck it - */ - if ((gGlobInfo.backup_active) && (ccb->proxySelection != SIP_PROXY_BACKUP)) - gGlobInfo.backup_active -= 1; -} - -boolean -sip_sm_is_previous_call_id (const char *pCallID, line_t *pPreviousCallIndex) -{ - line_t i; - - for (i = TEL_CCB_START; i <= TEL_CCB_END; i++) { - if (strcmp(gCallHistory[i].last_call_id, pCallID) == 0) { - *pPreviousCallIndex = i; - return TRUE; - } - } - - return FALSE; -} - -void -sip_sm_200and300_update (ccsipCCB_t *ccb, sipMessage_t *response, int response_code) -{ - const char *fname = "sip_sm_200and300_update"; - const char *to; - const char *from; - const char *contact; - const char *record_route = NULL; - sipLocation_t *to_loc = NULL; - - to = sippmh_get_cached_header_val(response, TO); - from = sippmh_get_cached_header_val(response, FROM); - contact = sippmh_get_cached_header_val(response, CONTACT); - - if (ccb->state < SIP_STATE_ACTIVE) { - // We are not allowed to update the route once a call is established - record_route = sippmh_get_cached_header_val(response, RECORD_ROUTE); - } - /* - * Record the "tag=" parameter - only if the call is not active yet - */ - if (ccb->state < SIP_STATE_ACTIVE) { - if (to) { - to_loc = sippmh_parse_from_or_to((char *) to, TRUE); - if (to_loc) { - if (to_loc->tag) { - ccb->sip_to_tag = strlib_update(ccb->sip_to_tag, - sip_sm_purify_tag(to_loc->tag)); - if ( ccb->callref == 0 ) { - ccb->callref = get_callref(ccb->sip_to_tag); - } - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "TO header:missing \"tag=\" param"); - } - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Recorded to_tag=<%s>\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->sip_to_tag); - sippmh_free_location(to_loc); - } - } - } - - /* - * Update To/From (to capture tag). Also Contact, and Record-Route - */ - if (response_code == SIP_STATUS_SUCCESS) { - if (ccb->flags & INCOMING) { - ccb->sip_to = strlib_update(ccb->sip_to, from); - if (to) { - ccb->sip_from = strlib_update(ccb->sip_from, to); - } - } else { - if (to) { - ccb->sip_to = strlib_update(ccb->sip_to, to); - } - ccb->sip_from = strlib_update(ccb->sip_from, from); - } - } - - if (response_code == SIP_STATUS_SUCCESS) { - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - } - if (record_route) { - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - } - ccb->record_route_info = sippmh_parse_record_route(record_route); - } -} - - -char * -sip_sm_purify_tag (char *tag) -{ - char *p; - - p = tag; - while (((*p == ';') || (*p == ' ') || (*p == '\t')) && (*p != '\0')) { - p++; - } - - return p; -} - - -boolean -sip_sm_is_invite_response (sipMessage_t *response) -{ - const char *cseq; - sipCseq_t *sipCseq; - - if (response == NULL) { - return FALSE; - } - - cseq = sippmh_get_cached_header_val(response, CSEQ); - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - return FALSE; - } - - if (sipCseq->method == sipMethodInvite) { - cpr_free(sipCseq); - return TRUE; - } - cpr_free(sipCseq); - return FALSE; -} - -boolean -sip_sm_is_bye_or_cancel_response (sipMessage_t *response) -{ - const char *cseq; - sipCseq_t *sipCseq; - - if (response == NULL) { - return FALSE; - } - - cseq = sippmh_get_cached_header_val(response, CSEQ); - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - return FALSE; - } - - if ((sipCseq->method == sipMethodBye) || - (sipCseq->method == sipMethodCancel)) { - cpr_free(sipCseq); - return TRUE; - } - cpr_free(sipCseq); - return FALSE; -} - - - -void -sip_sm_dequote_string (char *str, int max_size) -{ - char *p; - - /* Get rid of leading white space and double quote */ - p = str; - while (((*p == '\"') || (*p == ' ') || (*p == '\t')) && (*p != '\0')) { - p++; - } - - // The following use of sstrncpy is using over-lapping memory regions - sstrncpy(str, p, max_size); - - /* Get rid of trailing double quote and white space */ - // should be... - // end the string at the trailing double quote, if it exists - p = str; - while ((*p != '\"') && (*p != '\0')) { - p++; - } - *p = '\0'; -} - - -void -sip_sm_check_retx_timers (ccsipCCB_t *ccb, sipMessage_t *canceller_message) -{ - const char *fname = "sip_sm_check_retx_timers"; - uint32_t canceller_cseq; - sipMethod_t canceller_cseq_method; - const char *canceller_callid; - - sipMessage_t *retx_message = NULL; - uint32_t retx_message_buf_length = 0; - uint32_t retx_cseq = 0; - sipMethod_t retx_cseq_method = sipMethodInvalid; - const char *retx_callid = NULL; - - const char *cseq; - sipCseq_t *sipCseq; - int response_code = -1; - const char *conn_type = NULL; - - if (!ccb) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "CCB is NULL"); - return; - } - - if (ccb->index >= MAX_CCBS) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, ccb->index); - return; - } - - /* In the case of TCP/TLS, no messages are retransmitted unless there was a - * socket open (CPR_ENOTCONN) error. Hence there are no retx timers started - * in this case. If any retx timers were started, then, in the - * sip_platform_msg_timer_start procedure, the message_buffer_len would be - * set to a valid non-zero value. - */ - conn_type = sipTransportGetTransportType(1, TRUE, ccb); - if ((!cpr_strcasecmp(conn_type, "TCP") || !cpr_strcasecmp(conn_type, "TLS")) && - 0 == sipPlatformUISMTimers[ccb->index].message_buffer_len) { - /* This is not an error in case of TCP/TLS. - */ - return; - } - - - /* - * Get canceller_message callid, cseq number, cseq method - */ - cseq = sippmh_get_cached_header_val(canceller_message, CSEQ); - sipCseq = sippmh_parse_cseq(cseq); - if (sipCseq) { - canceller_cseq = sipCseq->number; - canceller_cseq_method = sipCseq->method; - cpr_free(sipCseq); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_cseq()"); - return; - } - - canceller_callid = sippmh_get_cached_header_val(canceller_message, CALLID); - - /* - * Get canceller_message response code if it is a response - */ - if (!sippmh_is_request(canceller_message)) { - if (sipGetResponseCode(canceller_message, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "sipGetResponseCode()"); - return; - } - } - - /* - * Get retx_message callid, cseq number, cseq method - */ - retx_message = sippmh_message_create(); - if (!retx_message) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "sippmh_message_create()"); - return; - } - retx_message_buf_length = sipPlatformUISMTimers[ccb->index].message_buffer_len; - if (sippmh_process_network_message(retx_message, - sipPlatformUISMTimers[ccb->index].message_buffer, - &retx_message_buf_length) == STATUS_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "sippmh_process_network_message()"); - free_sip_message(retx_message); - return; - } - if (!sippmh_is_message_complete(retx_message)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, "sippmh_is_message_complete()"); - free_sip_message(retx_message); - return; - } - cseq = sippmh_get_cached_header_val(retx_message, CSEQ); - sipCseq = sippmh_parse_cseq(cseq); - if (sipCseq) { - retx_cseq = sipCseq->number; - retx_cseq_method = sipCseq->method; - cpr_free(sipCseq); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_cseq()"); - free_sip_message(retx_message); - return; - } - - retx_callid = sippmh_get_cached_header_val(retx_message, CALLID); - - /* - * Check whether callid, cseq number, cseq method match. If match, - * stop the reTx timer. - */ - if ((canceller_cseq == retx_cseq) && - ((canceller_cseq_method == retx_cseq_method) || - ((canceller_cseq_method == sipMethodAck) && - (retx_cseq_method == sipMethodInvite))) && - (strcmp(canceller_callid, retx_callid) == 0)) { - sip_platform_msg_timer_stop(ccb->index); - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Stopping reTx timer.\n" - "(callid=%s, cseq=%u, cseq_method=%s)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, retx_callid, retx_cseq, - sipGetMethodString(retx_cseq_method)); - - UNBIND_UDP_ICMP_HANDLER(ccb->udpId); - - if (ccb->state == SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) { - if ((response_code == 401) || (response_code == 407) || - ((response_code < 200) && - (!sippmh_is_request(canceller_message)))) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), ccb->index, - ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - } else { - sip_sm_change_state(ccb, SIP_STATE_IDLE); - sip_sm_call_cleanup(ccb); - } - } - } else { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d:CSeq mismatch:\n(Rx: callid=%s," - " cseq=%u, cseq_method=%s),\n(reTx: callid=%s," - " cseq=%u, cseq_method=%s)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, - canceller_callid, canceller_cseq, - sipGetMethodString(canceller_cseq_method), - retx_callid, retx_cseq, - sipGetMethodString(retx_cseq_method)); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Not stopping retx timer"); - } - - free_sip_message(retx_message); -} - - -static int -sip_sm_request_check_and_store (ccsipCCB_t *ccb, sipMessage_t *request, - sipMethod_t request_method, boolean midcall, - uint16_t *request_check_reason_code, - char *request_check_reason_phrase, - boolean store_invite) -{ - const char *fname = "sip_sm_request_check_and_store"; - const char *request_cseq = NULL; - sipCseq_t *request_cseq_structure = NULL; - uint32_t request_cseq_number = 0; - sipMethod_t request_cseq_method = sipMethodInvalid; - const char *callID = NULL; - int content_length = 0; - boolean request_uri_error = FALSE; - sipReqLine_t *requestURI = NULL; - sipLocation_t *uri_loc = NULL; - const char *sip_from = NULL; - const char *sip_to = NULL; - sipLocation_t *to_loc = NULL; - sipLocation_t *from_loc = NULL; - const char *pViaHeaderStr = NULL; - int16_t trx_index = -1; - sipVia_t *via = NULL; - - - /* test incoming parameter for NULL */ - if (!request_check_reason_phrase) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Input parameter request_check_reason_phrase is NULL\n", - fname); - return (-1); - } - - /* - * Parse Call-Id - */ - callID = sippmh_get_cached_header_val(request, CALLID); - if (!callID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain request's " - "Call-ID header.\n", fname); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CALLID_ABSENT, - SIP_WARNING_LENGTH); - return (-1); - } - - /* - * Parse CSeq - */ - request_cseq = sippmh_get_cached_header_val(request, CSEQ); - if (!request_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain request's CSeq " - "header.\n", fname); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - SIP_WARNING_LENGTH); - return (-1); - } - request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to parse request's CSeq " - "header.\n", fname); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - SIP_WARNING_LENGTH); - return (-1); - } - request_cseq_number = request_cseq_structure->number; - request_cseq_method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - - /* - * Parsing Request-Uri - */ - requestURI = sippmh_get_request_line(request); - if (requestURI) { - if (requestURI->url) { - uri_loc = sippmh_parse_from_or_to(requestURI->url, TRUE); - if (uri_loc) { - if (uri_loc->genUrl->schema != URL_TYPE_SIP) { - request_uri_error = TRUE; - } - sippmh_free_location(uri_loc); - } else { - request_uri_error = TRUE; - } - } else { - request_uri_error = TRUE; - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } else { - request_uri_error = TRUE; - } - if (request_uri_error) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid Request URI" - "failed.\n", fname); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_REQLINE_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - - /* - * Parse From - */ - sip_from = sippmh_get_cached_header_val(request, FROM); - from_loc = sippmh_parse_from_or_to((char *)sip_from, TRUE); - if (!from_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - sippmh_free_location(from_loc); - - /* - * Parse To - */ - sip_to = sippmh_get_cached_header_val(request, TO); - to_loc = sippmh_parse_from_or_to((char *)sip_to, TRUE); - if (!to_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - sippmh_free_location(to_loc); - - /* - * Parse Via - */ - pViaHeaderStr = sippmh_get_cached_header_val(request, VIA); - if (pViaHeaderStr) { - via = sippmh_parse_via(pViaHeaderStr); - } - if (!pViaHeaderStr || !via) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), NULL, - NULL, fname, "sippmh_parse_via"); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - SIP_WARNING_LENGTH); - return (-1); - - } - sippmh_free_via(via); - - /* - * Check - */ - switch (request_method) { - /* INVITE */ - case sipMethodInvite: - - content_length = sippmh_get_content_length(request); - - if (request->raw_body) { - - if ((size_t) content_length != strlen(request->raw_body)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"\n Mismatched Content length and " - "Actual message body length:content length=%d\n" - "and message as %s\n and strlen of messagebody = %d\n", - fname, content_length, request->raw_body, - strlen(request->raw_body)); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - } else { - if ((size_t) content_length != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"\n Mismatched Content length and " - "Actual message body length:content length=%d\n" - "and message is empty and strlen of messagebody = 0\n", - fname, content_length); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR, - SIP_WARNING_LENGTH); - return (-1); - } - } - if (midcall && - ((ccb->last_recv_request_cseq_method == sipMethodInvite) || - (ccb->last_recv_request_cseq_method == sipMethodAck))) { - if (request_cseq_number <= ccb->last_recv_invite_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error: CSeq (%d) is not greater " - "than previous INVITE (%d).\n", fname, - request_cseq_number, - ccb->last_recv_invite_cseq); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - SIP_WARNING_LENGTH); - return (-1); - } - } - ccb->last_recv_invite_cseq = request_cseq_number; - break; - - /* BYE */ - case sipMethodBye: - if (ccb->flags & INCOMING) { - if (request_cseq_number <= ccb->last_recv_invite_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error: CSeq (%d) is not greater " - "than original INVITE (%d).\n", fname, - request_cseq_number, - ccb->last_recv_invite_cseq); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - SIP_WARNING_LENGTH); - return (-1); - } - } - break; - - /* ACK and CANCEL */ - case sipMethodCancel: - case sipMethodAck: - if (request_cseq_number != ccb->last_recv_invite_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"CSeq (%d) is not the same as " - "original INVITE (%d).\n", fname, - request_cseq_number, ccb->last_recv_request_cseq); - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - SIP_WARNING_LENGTH); - return (-1); - } - break; - - default: - break; - } - - // Allocate a tx block and store the various params there - trx_index = get_next_request_trx_index(ccb, FALSE); - if (trx_index < 0) { - // Internal server error - *request_check_reason_code = SIP_WARN_MISC; - sstrncpy(request_check_reason_phrase, - "Too many Transactions", - SIP_WARNING_LENGTH); - return (-2); - } - /* - * Don't free it since this request will be again required - * for sending 487 response. This is a temporary solution - * and should be removed in Moonpie - */ - if (!store_invite) { - if (ccb->last_request) { - free_sip_message(ccb->last_request); - ccb->last_request = NULL; - } - } - /* Store request.Done after alloc of trx, to handle allocation failure. */ - ccb->last_request = request; - - ccb->last_recv_request_cseq = request_cseq_number; - ccb->last_recv_request_cseq_method = request_cseq_method; - ccb->recv_request[trx_index].cseq_number = request_cseq_number; - ccb->recv_request[trx_index].cseq_method = request_cseq_method; - pViaHeaderStr = sippmh_get_cached_header_val(request, VIA); - if (pViaHeaderStr) { - ccb->recv_request[trx_index].u.sip_via_header = - strlib_update(ccb->recv_request[trx_index].u.sip_via_header, - pViaHeaderStr); - } - - return (0); -} - - -/* - * Function: sip_sm_update_to_from_on_callsetup_finalresponse - * - * Parameters: ccb, response - * - * Description: Updates to and from from response - * - * Returns:Void - * - */ -void -sip_sm_update_to_from_on_callsetup_finalresponse (ccsipCCB_t *ccb, - sipMessage_t *response) -{ - const char *fname = "sip_sm_update_to_from_on_callsetup_finalresponse"; - const char *to; - const char *from; - sipLocation_t *to_loc = NULL; - - to = sippmh_get_cached_header_val(response, TO); - from = sippmh_get_cached_header_val(response, FROM); - - /* - * Record the "tag=" parameter - */ - if (to) { - to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (to_loc) { - if (to_loc->tag) { - ccb->sip_to_tag = strlib_update(ccb->sip_to_tag, sip_sm_purify_tag(to_loc->tag)); - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "TO header missing \"tag=\" param"); - /* ccb->sip_to_tag[0] = '\0'; */ - } - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d: Recorded to_tag=<%s>\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index, ccb->sip_to_tag); - sippmh_free_location(to_loc); - } - } - - /* - * Update To/From (to capture tag). Also Contact, and Record-Route - */ - if (to) { - ccb->sip_to = strlib_update(ccb->sip_to, to); - } - ccb->sip_from = strlib_update(ccb->sip_from, from); -} - - -/* - * Function: sip_sm_update_contact_recordroute - * - * Parameters:ccb, response , response_code, midcall boolean - * - * Description: Puts contact info and record_route info into ccb - * - * Returns:void - * - */ -void -sip_sm_update_contact_recordroute (ccsipCCB_t *ccb, sipMessage_t *response, - int response_code, boolean midcall) -{ - const char *contact; - const char *record_route; - - contact = sippmh_get_cached_header_val(response, CONTACT); - record_route = sippmh_get_cached_header_val(response, RECORD_ROUTE); - - if (response_code == SIP_STATUS_SUCCESS) { - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - } - if (record_route && (!midcall)) { - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - } - ccb->record_route_info = sippmh_parse_record_route(record_route); - } -} - - -/* - * SIP_STATE_ACTIVE - */ -void -ccsip_handle_active_ev_cc_feature (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "active_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - cc_feature_name(feature_type)); - - switch (feature_type) { - case CC_FEATURE_HOLD: - ccb->hold_initiated = TRUE; - ccb->featuretype = CC_FEATURE_HOLD; - ccsip_handle_active_ev_cc_feature_hold(ccb, event); - break; - case CC_FEATURE_MEDIA: - ccb->featuretype = CC_FEATURE_MEDIA; - ccsip_handle_active_ev_cc_feature_resume_or_media(ccb, event); - break; - case CC_FEATURE_RESUME: - ccb->featuretype = CC_FEATURE_RESUME; - ccsip_handle_active_ev_cc_feature_resume_or_media(ccb, event); - break; - case CC_FEATURE_BLIND_XFER: - case CC_FEATURE_XFER: - ccsip_handle_active_ev_cc_feature_xfer(ccb, event); - break; - case CC_FEATURE_NOTIFY: - if (event->u.cc_msg->msg.feature.data.notify.final == TRUE) { - ccb->flags |= FINAL_NOTIFY; - } - if (CC_CAUSE_OK != event->u.cc_msg->msg.feature.data.notify.cause) { - // Get the data from msg.get data for error code but currently we do not have any. - (void) sipSPISendNotify(ccb, event->u.cc_msg->msg.feature.data.notify.cause_code); - ccb->xfer_status = event->u.cc_msg->msg.feature.data.notify.cause_code; - } else { - (void) sipSPISendNotify(ccb, SIP_SUCCESS_SETUP); // Get the data from msg. - ccb->xfer_status = SIP_SUCCESS_SETUP; - } - break; - case CC_FEATURE_B2BCONF: - case CC_FEATURE_SELECT: - case CC_FEATURE_B2B_JOIN: - case CC_FEATURE_CANCEL: - break; - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - break; - } -} - - -/** - * This fucntion handles CC_FEATURE_HOLD in active state. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return None. - * - */ -void -ccsip_handle_active_ev_cc_feature_hold (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - cc_msgbody_info_t *msg_body; - - /* Copy the call-info into the CCB */ - ccsip_store_call_info(&event->u.cc_msg->msg.feature.data.hold.call_info, ccb); - if (event->u.cc_msg->msg.feature.data_valid) { - /* Replace the local copy of the msg. body */ - msg_body = &event->u.cc_msg->msg.feature.data.hold.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - sip_sm_change_state(ccb, SIP_STATE_SENT_MIDCALL_INVITE); - if (send_resume_or_hold_request(ccb, TRUE) == FALSE) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } -} - - -/** - * This fucntion handles CC_FEATURE_RESUME or CC_FEATURE_MEDIA in - * active state. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return None. - * - */ -void -ccsip_handle_active_ev_cc_feature_resume_or_media (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - cc_msgbody_info_t *msg_body; - - if (event->u.cc_msg->msg.feature.data_valid) { - /* Replace the local copy of the msg. body */ - msg_body = &event->u.cc_msg->msg.feature.data.resume.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - /* Copy the call-info into the CCB */ - ccsip_store_call_info(&event->u.cc_msg->msg.feature.data.resume.call_info, ccb); - sip_sm_change_state(ccb, SIP_STATE_SENT_MIDCALL_INVITE); - if (send_resume_or_hold_request(ccb, FALSE) == FALSE) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } -} - -void -ccsip_handle_active_ev_cc_feature_xfer (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "active_ev_cc_feature_xfer"; - char referto[MAX_SIP_URL_LENGTH]; - char *domainloc = NULL; - char *pTransferNumberString; - cc_feature_data_t data; - cc_xfer_methods_t method; - char addr[MAX_IPADDR_STR_LEN]; - ccsipCCB_t *xfer_ccb = NULL; - int n = 0; - static char dialtranslate[MAX_SIP_URL_LENGTH]; - char *pReferToStr = referto; - sipRefEnum_e refto_type = SIP_REF_XFER; - - memset(addr, 0, MAX_IPADDR_STR_LEN); - method = event->u.cc_msg->msg.feature.data.xfer.method; - - if (CC_FEATURE_BLIND_XFER == event->u.cc_msg->msg.feature.feature_id) { - ccb->featuretype = CC_FEATURE_BLIND_XFER; - ccb->con_call_id = CC_NO_CALL_ID; - } else if (CC_FEATURE_XFER == event->u.cc_msg->msg.feature.feature_id) { - ccb->featuretype = CC_FEATURE_XFER; - ccb->con_call_id = event->u.cc_msg->msg.feature.data.xfer.target_call_id; - xfer_ccb = sip_sm_get_ccb_by_target_call_id(ccb->con_call_id); - } - - - pTransferNumberString = event->u.cc_msg->msg.feature.data.xfer.dialstring; - (void) MatchDialTemplate(pTransferNumberString, ccb->dn_line, CAST_N &n, - dialtranslate, sizeof(dialtranslate), - (RouteMode *) &(ccb->routeMode), NULL); - /* Escape the characters in userinfo */ - domainloc = strchr(dialtranslate, '@'); - if (domainloc == NULL) { - (void) sippmh_convertURLCharToEscChar(dialtranslate, - strlen(dialtranslate), - pReferToStr, MAX_SIP_URL_LENGTH, TRUE); - } else { - (void) sippmh_convertURLCharToEscChar(dialtranslate, - domainloc - dialtranslate, - pReferToStr, MAX_SIP_URL_LENGTH, TRUE); - /* Append the host Part including @ */ - sstrncat(pReferToStr, domainloc, MAX_SIP_URL_LENGTH - strlen(pReferToStr)); - } - /* Re-write the escaped URL to dial translate */ - sstrncpy(dialtranslate, referto, MAX_SIP_URL_LENGTH); - pTransferNumberString = dialtranslate; - - - ccb->authen.cred_type = 0; - //add refer as SIP mURI - - // If there is no hostname, add proxy address as hostname - domainloc = strchr(referto, '@'); - if (domainloc == NULL) { - char *semi = NULL; - size_t len; - - /* see if we have ;user= */ - semi = strchr(pTransferNumberString, ';'); - - if (semi) { - sstrncpy(referto, "con_call_id); - if ((xfer_ccb != NULL) && - util_check_if_ip_valid(&(xfer_ccb->dest_sip_addr)) && - (ccb->featuretype == CC_FEATURE_XFER)) { - /* - * Populate addr with proxy through which transferor and - * target are talking - */ - if ((xfer_ccb->routeMode == RouteEmergency) || - (xfer_ccb->proxySelection == SIP_PROXY_BACKUP)) { - ipaddr2dotted(addr, &xfer_ccb->dest_sip_addr); - } else { - sipTransportGetPrimServerAddress(xfer_ccb->dn_line, addr); - } - } else { - /* - * In case of blind transfer xfer_ccb->dest_sip_addr will - * always show primary proxy. Since we don't know whether - * target of transfer is reachable by primary proxy or not, - * We are going to use proxy through which transferor is - * talking to transferee, assuming that transferee and target - * should be able to talk through the same proxy - */ - if ((ccb->routeMode == RouteEmergency) || - (ccb->proxySelection == SIP_PROXY_BACKUP)) { - ipaddr2dotted(addr, &ccb->dest_sip_addr); - } else { - sipTransportGetPrimServerAddress(ccb->dn_line, addr); - } - } - - sstrncpy(domainloc, addr, - MAX_SIP_URL_LENGTH - (domainloc - referto - 1)); - } - - /* if we have a ;user=, then add it to the end of the string if we can */ - if (semi) { - domainloc = referto + strlen(referto); - sstrncpy(domainloc, semi, - MAX_SIP_URL_LENGTH - (domainloc - referto - 1)); - } - - if (semi) { - sstrncat(domainloc, ">", MAX_SIP_URL_LENGTH - strlen(referto)); - } - } - /* If the method is direct trasnfer then - * add more information to referto header - */ - if (method == CC_XFER_METHOD_DIRXFR) { - refto_type = SIP_REF_DIR_XFER; - } - - if (CC_XFER_METHOD_REFER == method || - method == CC_XFER_METHOD_DIRXFR) { - // Add refer as SIP Refer - ccsipCCB_t *xfer_refer_ccb; - - ccb->sip_referTo = strlib_update(ccb->sip_referTo, referto); - xfer_refer_ccb = sip_sm_get_target_call_by_con_call_id(ccb->con_call_id); - - if ((xfer_refer_ccb != NULL) && (xfer_ccb != NULL) && (xfer_ccb->sip_referTo[0] != '\0')) { - ccb->sip_referTo = strlib_update(ccb->sip_referTo, - xfer_refer_ccb->sip_referTo); - } - - if (ccb->sip_referTo) { - if (sipSPISendRefer(ccb, (char *)ccb->sip_referTo, refto_type) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPISendRefer Failed"); - return; - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "ccb->sipreferTo is NULL"); - return; - } - - } else if (CC_XFER_METHOD_BYE == method) { - cc_features_t feature; - - ccb->referto = strlib_update(ccb->referto, referto); - data.xfer.cause = CC_CAUSE_XFER_LOCAL; - feature = fsmxfr_type_to_feature(fsmxfr_get_xfr_type(ccb->gsm_id)); - data.xfer.method = CC_XFER_METHOD_BYE; // Temp Fix Need to remove - data.xfer.dialstring[0] = '\0'; - data.xfer.target_call_id = CC_NO_CALL_ID; - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature, &data, - CC_CAUSE_NORMAL); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "Unspecified Method of Transfer"); - - } - - /* Pre-fill the ARP table */ - ADD_TO_ARP_CACHE(ccb->dest_sip_addr); -} - -void -ccsip_handle_active_ev_cc_feature_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_active_ev_cc_feature_ack"; - ccsipCCB_t *other_ccb = NULL; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - switch (feature_type) { - case CC_FEATURE_XFER: - case CC_FEATURE_BLIND_XFER: - if (CC_XFER_METHOD_REFER == event->u.cc_msg->msg.feature.data.xfer.method) { - if (CC_CAUSE_ERROR == event->u.cc_msg->msg.feature.data.xfer.cause) { - (void) sipSPISendErrorResponse(ccb->last_request, - SIP_SERV_ERR_UNAVAIL, - SIP_SERV_ERR_UNAVAIL_PHRASE, - 0, NULL, ccb); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Got CC_CAUSE_ERROR" - "from GSM \n", fname); - return; - } - if (CC_NO_CALL_ID != event->u.cc_msg->msg.feature.data.xfer.target_call_id) { - ccb->con_call_id = event->u.cc_msg->msg.feature.data.xfer.target_call_id; - if (feature_type == CC_FEATURE_BLIND_XFER) { - ccb->blind_xfer_call_id = event->u.cc_msg->msg.feature.data.xfer.target_call_id; - } - if (!sipSPISendReferResponse202(ccb)) { - (void) sipSPISendErrorResponse(ccb->last_request, - SIP_SERV_ERR_UNAVAIL, - SIP_SERV_ERR_UNAVAIL_PHRASE, - 0, NULL, ccb); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPISendReferResponse202" - " failed, sending 503\n", fname); - return; - } else { - /* Send NOTIFY 100 Trying */ - if (!sipSPISendNotify(ccb, SIP_1XX_TRYING)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPISendNotify" - " failed, sending 100\n", fname); - } - ccb->xfer_status = 100; - - if (feature_type == CC_FEATURE_BLIND_XFER) { - /* - * Release this call and tell GSM to start - * the Blind Transfer - */ - sip_cc_release(ccb->gsm_id, ccb->dn_line, - CC_CAUSE_NORMAL, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - } - } - } else if (CC_XFER_METHOD_BYE == event->u.cc_msg->msg.feature.data.xfer.method) { - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_NORMAL, NULL); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - } - break; - case CC_FEATURE_NOTIFY: - /* check for special case early attended transfer */ - other_ccb = sip_sm_get_target_call_by_con_call_id(ccb->con_call_id); - if ((other_ccb != NULL) && (other_ccb->early_transfer)) { - other_ccb->early_transfer = FALSE; - sipSPISendCancel(other_ccb); - sip_cc_release_complete(other_ccb->gsm_id, other_ccb->dn_line, - CC_CAUSE_NORMAL); - sip_sm_change_state(other_ccb, SIP_STATE_RELEASE); - } else { - // This might be a simple acknowledgement for a NOTIFY - // received from the network. Reply to the remote side - // including the cause-code received from GSM - (void) sipSPISendNotifyResponse(ccb, - event->u.cc_msg->msg.feature_ack.cause); - } - break; - - default: - break; - } -} - -void -ccsip_handle_active_ev_sip_invite (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "active_ev_sip_invite"; - sipMessage_t *request; - - // currently not used: const char *require = NULL; - const char *contact = NULL; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - cc_feature_data_t data; - sipsdp_status_t sdp_status; - boolean apply_ringout = FALSE; - - /* Unpack the event */ - request = event->u.pSipMessage; - - // Check for glare conditions - // If we have an outstanding INVITE that we sent then we have glare - if (get_method_request_trx_index(ccb, sipMethodInvite, TRUE) > -1) { - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"%d Glare condition detected \n", - DEB_L_C_F_PREFIX_ARGS(SIP_CALL_STATUS, ccb->dn_line, ccb->gsm_id, fname), - ccb->index); - // return 491 - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_REQ_PENDING, - SIP_CLI_ERR_REQ_PENDING_PHRASE, - 0, NULL, NULL); - free_sip_message(request); - return; - } - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodInvite, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - - /* update the contact information if needed */ - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - - /* - * Process SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SESSION_AUDIT: - ccb->oa_state = OA_OFFER_RECEIVED; - if (((ccb->state == SIP_STATE_SENT_MIDCALL_INVITE) && - (ccb->hold_initiated)) || (ccb->state == SIP_STATE_ACTIVE)) { - /* - * Respond to the BroadSoft Session Audit Message. - * Do same for Refresh case / ReInvite with the same SDP - * First request for the current sdp from gsm. - * - * Need to check for Call-Info ringout state and pass along so that session audit - * does not disable CCM spoofed ringout. - */ - if (ccb->in_call_info && - ccb->in_call_info->data.call_info_feat_data.feature_flag & CC_UI_STATE) { - apply_ringout = - (ccb->in_call_info->data.call_info_feat_data.ui_state == - CC_UI_STATE_RINGOUT ? TRUE : FALSE); - } - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - sip_cc_audit(ccb->gsm_id, ccb->dn_line, apply_ringout); - return; - } - /*FALLTHROUGH*/ - - case SIP_SDP_SUCCESS: - /* - * Check to see if received SDP indicates hold. If it is not - * a hold SDP, then we received a new media invite. - * Send FEATURE CC event to GSM. - */ - ccb->oa_state = OA_OFFER_RECEIVED; - /* - * Update connected party info from RPID and Call-Info header. - * Media will effect media, delay call information update. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, TRUE); - /* Move the message body from the SIP msg. into CCAPI msg */ - sip_cc_mv_msg_body_to_cc_msg(&data.resume.msg_body, request); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_MEDIA, &data); - sip_sm_change_state(ccb, - SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING); - break; - - case SIP_SDP_ERROR: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, "Invalid SDP", ccb); - return; - - case SIP_SDP_DNS_FAIL: - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", - FALSE, FALSE); - return; - - case SIP_SDP_NO_MEDIA: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "No acceptable media line in SDP", ccb); - return; - - case SIP_SDP_NOT_PRESENT: - /*FALLTHROUGH*/ - - default: - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Waiting for SDP in ACK\n", - DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - /* - * Update connected party info from RPID and Call-Info header. - * Resuming the media,update call info now. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_MEDIA, NULL); - sip_sm_change_state(ccb, - SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING); - break; - } - - sipSPISendInviteResponse100(ccb, FALSE); -} - - -void -ccsip_handle_active_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "Active_2xx"; - sipMessage_t *response; - int response_code = 0; - - /* Unpack the event */ - response = event->u.pSipMessage; - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - if (response_code == SIP_ACCEPTED) { - ccsip_handle_accept_2xx(ccb, event); - return; - } - - if (sipSPISendAck(ccb, response) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - free_sip_message(response); -} - - -/* - * SIP_STATE_SENT_MIDCALL_INVITE - */ - -/** - * ccsip_handle_sentinvite_midcall_ev_cc_feature - * - * The function handles for CC_FEATURE during mid call invite. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return N/A - */ -void ccsip_handle_sentinvite_midcall_ev_cc_feature (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sentinvite_midcall_ev_cc_feature"; - cc_features_t feature_type; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - - switch (feature_type) { - case CC_FEATURE_RESUME: - case CC_FEATURE_HOLD: - case CC_FEATURE_MEDIA: - /* - * Send resume/hold/media request and waiting for the response. - * Indicate that the request can not proceed now and it should be - * retried later. GSM should not attempt this. - */ - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, - NULL, CC_CAUSE_REQUEST_PENDING); - break; - - default: - /* Other feature request is not supported or allowed now */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, - NULL, CC_CAUSE_ERROR); - break; - } -} - -/** - * ccsip_handle_sentinvite_midcall_ev_sip_2xx - * - * The function handles for SIP 2xx during mid call invite. - * - * @param[in] ccb Pointer to ccsipCCB_t structure. - * @param[in] event Pointer to sipSMEvent_t structure. - * - * @pre (ccb not_eq NULL) - * - * @return N/A - */ -void ccsip_handle_sentinvite_midcall_ev_sip_2xx (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sentinvite_midcall_ev_sip_2xx"; - sipMessage_t *response; - cc_feature_data_t data; - sipsdp_status_t sdp_status; - - response = event->u.pSipMessage; - if (!sip_sm_is_invite_response(response)) { - free_sip_message(response); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - return; - } - - /* Stop the expires timer started to await this response */ - (void) sip_platform_expires_timer_stop(ccb->index); - - sip_sm_200and300_update(ccb, response, SIP_STATUS_SUCCESS); - - /* Reset credentials flag since Hold was successfully processed */ - ccb->authen.cred_type = 0; - - /* - * Send ACK back soon to minimize delayed cutting through at the - * remote end. - */ - if (sipSPISendAck(ccb, response) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - } - - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - /* Extract destination SDP and related fields */ - sdp_status = sip_util_extract_sdp(ccb, response); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - case SIP_SDP_NOT_PRESENT: - ccb->oa_state = OA_IDLE; - /* Move the messag bodies from SIP msg. to CCAPI msg. */ - switch (ccb->featuretype) { - case CC_FEATURE_HOLD: - sip_cc_mv_msg_body_to_cc_msg(&data.hold.msg_body, response); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, - &data, CC_CAUSE_NORMAL); - break; - case CC_FEATURE_RESUME: - case CC_FEATURE_MEDIA: - sip_cc_mv_msg_body_to_cc_msg(&data.resume.msg_body, response); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, - &data, CC_CAUSE_NORMAL); - break; - default: - /* - * Other features are not expected. - */ - CCSIP_DEBUG_ERROR(DEB_L_C_F_PREFIX"%d: unexpected feature %d\n", - ccb->dn_line, ccb->gsm_id, fname, - ccb->index, ccb->featuretype); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, - NULL, CC_CAUSE_ERROR); - break; - } - break; - - case SIP_SDP_DNS_FAIL: - case SIP_SDP_NO_MEDIA: - case SIP_SDP_ERROR: - default: - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, ccb->featuretype, NULL, - CC_CAUSE_ERROR); - break; - } - - free_sip_message(response); - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); -} - -void -ccsip_handle_accept_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - cc_feature_data_t data; - cc_features_t feature; - sipMessage_t *response; - int response_code = 0; - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - char *fname = "ccsip_handle_accept_2xx"; - sipMethod_t response_method; - - response = event->u.pSipMessage; - if (sipGetResponseCode(response, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(response); - return; - } - - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, response, TRUE, FALSE, FALSE); - - /* don't ack a 200 on a Notify message */ - // if ((response_code == SIP_SUCCESS_SETUP) && - // (ccb->last_sent_request_cseq_method == sipMethodNotify)) { - // free_sip_message(response); - // return; - // } - // Instead of checking the last request, check the CSeq method of - // the response and then determine which request it is responding to - // Then clear that request from the cseq array - cseq = sippmh_get_cached_header_val(response, CSEQ); - if (!cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CSEQ)"); - free_sip_message(response); - return; - } - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - free_sip_message(response); - return; - } - response_method = sipCseq->method; - cpr_free(sipCseq); - - if ((response_code == SIP_SUCCESS_SETUP) && - (response_method == sipMethodNotify)) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - free_sip_message(response); - return; - } - - if (response_code != SIP_ACCEPTED) { - if (sipSPISendAck(ccb, response) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPISendAck"); - free_sip_message(response); - return; - } - } - switch (ccb->featuretype) { - case CC_FEATURE_B2BCONF: - case CC_FEATURE_SELECT: - case CC_FEATURE_B2B_JOIN: - case CC_FEATURE_CANCEL: - ccb->authen.cred_type = 0; - feature = ccb->featuretype; - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature, NULL, - CC_CAUSE_OK); - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - free_sip_message(response); - return; - default: - break; - } - - data.xfer.cause = CC_CAUSE_XFER_LOCAL; - data.xfer.method = CC_XFER_METHOD_REFER; - data.xfer.dialstring[0] = '\0'; - data.xfer.target_call_id = ccb->gsm_id; - feature = fsmxfr_type_to_feature(fsmxfr_get_xfr_type(ccb->gsm_id)); - - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature, &data, CC_CAUSE_OK); - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - free_sip_message(response); -} - -/* - * SIP_STATE_RECV_MIDCALLINVITE_CCFEATUREACK_PENDING - */ -void -ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack ( - ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - cc_features_t feature_type; - cc_msgbody_info_t *msg_body; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - - switch (feature_type) { - case CC_FEATURE_HOLD: - if (event->u.cc_msg->msg.feature_ack.data_valid) { - /* Save the msg. body */ - msg_body = &event->u.cc_msg->msg.feature_ack.data.hold.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - sipSPISendInviteResponse200(ccb); /* HOLD */ - sip_sm_change_state(ccb, - SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING); - break; - - case CC_FEATURE_RESUME: - /* fall through to send the response */ - case CC_FEATURE_MEDIA: - /* new media acks put the sdp in the resume area as well */ - if (event->u.cc_msg->msg.feature_ack.data_valid) { - msg_body = &event->u.cc_msg->msg.feature_ack.data.resume.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - if (event->u.cc_msg->msg.feature_ack.cause == CC_CAUSE_PAYLOAD_MISMATCH || - event->u.cc_msg->msg.feature_ack.cause == CC_CAUSE_NO_MEDIA || - event->u.cc_msg->msg.feature_ack.cause == CC_CAUSE_ERROR) { - /* - * Rejecting the new sdp - * The above errors are the ones currently thrown by gsm sdp processing. - * If any new errors are added the above check must be updated. - */ - ccb->oa_state = OA_IDLE; - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_NOT_ACCEPT_HERE, - SIP_CLI_ERR_NOT_ACCEPT_HERE_PHRASE, - SIP_WARN_MISC, - "SDP Not Acceptable", - FALSE, /* no SDP */ TRUE /* reTx */); - } else { - sipSPISendInviteResponse200(ccb); - } - sip_sm_change_state(ccb, SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING); - break; - - default: - break; - } -} - - -/* - * SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING - */ -void -ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - const char *fname = - "ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack"; - sipMessage_t *request; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - cc_feature_data_t data; - sipsdp_status_t sdp_status; - - /* Unpack the event */ - request = event->u.pSipMessage; - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodAck, FALSE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - free_sip_message(request); - return; - } - - /* - * Process SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SUCCESS: - case SIP_SDP_SESSION_AUDIT: - if (ccb->oa_state != OA_OFFER_SENT) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Unexpected SDP in ACK, releasing call"); - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } - - /* - * Check to see if received SDP indicates hold. If it is not - * a hold SDP, then we received a new media invite. - * Send FEATURE CC event to GSM. - */ - ccb->oa_state = OA_IDLE; - - /* - * Update connected party info from RPID and Call-Info header. - * MEDIA request, delay UI update. - */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, TRUE); - - /* Move the msg. body from the SIP msg. to CCAPI msg. */ - sip_cc_mv_msg_body_to_cc_msg(&data.resume.msg_body, request); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_MEDIA, &data); - break; - - case SIP_SDP_ERROR: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, "Invalid SDP", ccb); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - return; - - case SIP_SDP_DNS_FAIL: - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", - FALSE, FALSE); - break; - - case SIP_SDP_NO_MEDIA: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "No acceptable media line in SDP", ccb); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - return; - - case SIP_SDP_NOT_PRESENT: - if (ccb->oa_state == OA_OFFER_SENT) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "No answer SDP in ACK, releasing call"); - sipSPISendBye(ccb, NULL, NULL); - sip_cc_release(ccb->gsm_id, ccb->dn_line, CC_CAUSE_ERROR, NULL); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); - sip_sm_change_state(ccb, SIP_STATE_RELEASE); - return; - } else { - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - } - break; - - default: - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - break; - - } - - /* - * Update state - */ - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - clean_method_request_trx(ccb, sipMethodAck, FALSE); - clean_method_request_trx(ccb, sipMethodInvite, FALSE); -} - - -void -ccsip_handle_transienthold_ev_cc_feature (ccsipCCB_t *ccb, int feature_type, - sipSMStateType_t final_resume_state, - sipSMEvent_t *event) -{ - const char *fname = "transienthold_ev_cc_feature"; - cc_msgbody_info_t *msg_body; - - switch (feature_type) { - case CC_FEATURE_RESUME: - if (event->u.cc_msg->msg.feature.data_valid) { - msg_body = &event->u.cc_msg->msg.feature.data.resume.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - ccb->hold_initiated = FALSE; - ccb->featuretype = CC_FEATURE_RESUME; - sip_sm_change_state(ccb, final_resume_state); - break; - - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - break; - } -} - - -int -strcasecmp_ignorewhitespace (const char *cs, const char *ct) -{ - const char *p; - const char *q; - - if (cpr_strcasecmp(cs, ct) == 0) { - return (0); - } - - p = cs; - q = ct; - - /* Ignore leading white space */ - while (((*p == ' ') || (*p == '\t')) && (*p != '\0')) { - p++; - } - while (((*q == ' ') || (*q == '\t')) && (*q != '\0')) { - q++; - } - - /* Compare until hit end or whitespace */ - while ((*p != ' ') && (*p != '\t') && (*p != '\0') && - (*q != ' ') && (*q != '\t') && (*q != '\0')) { - if (toupper(*p) != toupper(*q)) { - return (-1); - } - p++; - q++; - } - - /* Make sure that what's left (if any) is whitespace */ - while (*p != '\0') { - if ((*p != ' ') && (*p != '\t')) { - return (-1); - } - p++; - } - while (*q != '\0') { - if ((*q != ' ') && (*q != '\t')) { - return (-1); - } - q++; - } - - return (0); -} - - -void -sip_sm_util_normalize_name (ccsipCCB_t *ccb, char *dialString) -{ - char *outputString; - uint32_t usernameLength = 0; - const char *hostnameString = NULL; - uint32_t hostnameLength = 0; - char proxy_ipaddr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t proxy_ipaddr; - char *extraString = NULL; - char *parse_token; - uint32_t extraLength = 0; - uint32_t n = 0; - static char dialtranslate[MAX_SIP_URL_LENGTH]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char addr[MAX_IPADDR_STR_LEN]; - int port; - int dialStringLength; - - CPR_IP_ADDR_INIT(proxy_ipaddr); - /* - * Save away what they sent us so that we can display it to them later - */ - dialStringLength = strlen(dialString); - memcpy((void *)ccb->calledDisplayedName, dialString, dialStringLength); - /* - * See if the string needs to be rewritten by applying the dial template - */ - ccb->routeMode = RouteDefault; - (void) MatchDialTemplate(ccb->calledDisplayedName, ccb->dn_line, CAST_N &n, dialtranslate, - sizeof(dialtranslate), - (RouteMode *) &(ccb->routeMode), NULL); - dialString = dialtranslate; - dialStringLength = strlen(dialString); - /* - * Throw away any part of 0) && (dialString[0] == '<')) { - dialString++; - dialStringLength--; - } - /* - * For the SIP: part, we have to have 4 characters - */ - if ((dialStringLength > 4) && - (tolower(dialString[0]) == 's') && - (tolower(dialString[1]) == 'i') && - (tolower(dialString[2]) == 'p') && - (tolower(dialString[3]) == ':')) { - dialStringLength -= 4; - dialString += 4; - } - - /* - * Parse the remainder of the string looking for the host name - */ - parse_token = strpbrk(dialString, "@;>"); /* Skip the user name first */ - if (parse_token == NULL) { /* Only user name exists and no host, extra and ;> */ - usernameLength = dialStringLength; - } else { - usernameLength = parse_token - dialString; /* save username length */ - if (parse_token[0] == '@') { /* host name exists in addition */ - extraString = strpbrk(parse_token, ";>"); /* Skip the host name */ - if (extraString != NULL) { /* extra params exist */ - extraLength = dialStringLength - (extraString - dialString); - } - /* - * Save the host name and host length if proxy selection is - * not backup. In case of proxy selection being backup, - * ignore the hostname & rebuild using dotted IP of backup proxy later - */ - if (ccb->proxySelection != SIP_PROXY_BACKUP) { - hostnameString = parse_token + 1; - /* In case of host name, the length must exclude @ and hence -1 */ - hostnameLength = dialStringLength - usernameLength - extraLength - 1; - } - } else { /* No host, but extra param exist */ - extraLength = dialStringLength - usernameLength; - extraString = parse_token; - } - } - - /* - * At this point we have - * usernameLength - Number of characters in the user name - * starting from dialString[0] - * hostnameString - NULL if no @ was encountered, otherwise it - * points to the start of the host name string - * hostnameLength - 0 if no host name characters were encountered - * extraString - Points to any extra parameters - * extraLength - number of extra parameter characters - */ - if (hostnameLength == 0) { - /* - * At this junctor in the quantum, - * - */ - switch (ccb->routeMode) { - case RouteEmergency: - /* - * If we have failed over to the backup we need - * to not reselect the emergency proxy - */ - if (ccb->proxySelection != SIP_PROXY_BACKUP) { - // Get the Emergency Proxy - sipTransportGetEmerServerAddress(ccb->dn_line, proxy_ipaddr_str); - hostnameString = &proxy_ipaddr_str[0]; - hostnameLength = strlen(hostnameString); - if (hostnameLength) { - if (!str2ip((const char *) proxy_ipaddr_str, &proxy_ipaddr)) { - /* Fill in address and port in CCB */ - util_ntohl(&(ccb->dest_sip_addr), &(proxy_ipaddr)); - - /* - * If the Proxy Emergency Port isn't contained in the - * config table, use the PROXYN port instead. - */ - port = sipTransportGetEmerServerPort(ccb->dn_line); - if (port) { - ccb->dest_sip_port = port; - } else { - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - break; - } - } - } - // Otherwise Emergency proxy is not in configuration follow thru - /*FALLTHROUGH*/ - default: - /* - * set the proxy address differently if the backup proxy - * has been activated. The address has already been placed into - * ccb->dest_sip_addr and ccb->dest_sip_port so just use - * those values - */ - if (ccb->proxySelection == SIP_PROXY_BACKUP) { - ipaddr2dotted(dest_sip_addr_str, &ccb->dest_sip_addr); - hostnameString = dest_sip_addr_str; - hostnameLength = strlen(hostnameString); - } else { - sipTransportGetPrimServerAddress(ccb->dn_line, addr); - hostnameString = addr; - hostnameLength = strlen(hostnameString); - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr), ccb->dn_line); - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - } - } - - /* - * Construct the actual dial out string - */ - outputString = (char *) ccb->calledNumber; - sstrncpy(outputString, " - */ - outputString[extraLength] = 0; - /* - * If there was no > in what they gave us, put one in for them - */ - if (strchr(outputString, '>') == NULL) { - outputString[extraLength++] = '>'; - } - outputString += extraLength; - } else { - *outputString++ = '>'; - } - /* - * Null terminate the string for good measure and note how long it is - */ - *outputString = 0; - ccb->calledNumberLen = (uint16_t) (outputString - ccb->calledNumber); -} - - -void -get_sip_error_string (char *errortext, int response) -{ - - if (NULL == errortext) - return; - switch (response) { - case SIP_SUCCESS_SETUP: - sstrncpy(errortext, SIP_SUCCESS_SETUP_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_ACCEPTED: - sstrncpy(errortext, SIP_ACCEPTED_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_1XX_TRYING: - sstrncpy(errortext, SIP_1XX_TRYING_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_MULT_CHOICES: - sstrncpy(errortext, SIP_RED_MULT_CHOICES_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_MOVED_PERM: - sstrncpy(errortext, SIP_RED_MOVED_PERM_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_MOVED_TEMP: - sstrncpy(errortext, SIP_RED_MOVED_TEMP_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_SEE_OTHER: - sstrncpy(errortext, SIP_RED_SEE_OTHER_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_USE_PROXY: - sstrncpy(errortext, SIP_RED_USE_PROXY_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_RED_ALT_SERVICE: - sstrncpy(errortext, SIP_RED_ALT_SERVICE_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_BAD_REQ: /* 400 Bad Request */ - sstrncpy(errortext, SIP_CLI_ERR_BAD_REQ_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_UNAUTH: /* 401 Unauthorized */ - sstrncpy(errortext, SIP_CLI_ERR_UNAUTH_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_PAY_REQD: /* 402 Payment Required */ - sstrncpy(errortext, SIP_CLI_ERR_PAY_REQD_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_FORBIDDEN: /* 403 Forbidden */ - sstrncpy(errortext, SIP_CLI_ERR_FORBIDDEN_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_NOT_FOUND: /* 404 Not Found */ - sstrncpy(errortext, SIP_CLI_ERR_NOT_FOUND_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_NOT_ALLOWED: /* 405 Method Not Allowed */ - sstrncpy(errortext, SIP_CLI_ERR_NOT_ALLOWED_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_NOT_ACCEPT: /* 406 Not Acceptable */ - sstrncpy(errortext, SIP_CLI_ERR_NOT_ACCEPT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_PROXY_REQD: /* 407 Proxy Authentication Required */ - sstrncpy(errortext, SIP_CLI_ERR_PROXY_REQD_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_REQ_TIMEOUT: /* 408 Request Timeout */ - sstrncpy(errortext, SIP_CLI_ERR_REQ_TIMEOUT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_CONFLICT: /* 409 Conflict */ - sstrncpy(errortext, SIP_CLI_ERR_CONFLICT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_GONE: /* 410 Gone */ - sstrncpy(errortext, SIP_CLI_ERR_GONE_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_LEN_REQD: /* 411 Length Required */ - sstrncpy(errortext, SIP_CLI_ERR_LEN_REQD_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_LARGE_MSG: /* 413 Request Message Body Too Large */ - sstrncpy(errortext, SIP_CLI_ERR_LARGE_MSG_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_LARGE_URI: /* 414 Request-URI Too Large */ - sstrncpy(errortext, SIP_CLI_ERR_LARGE_URI_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_MEDIA: /* 415 Unsupported Media Type */ - sstrncpy(errortext, SIP_CLI_ERR_MEDIA_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_EXTENSION: /* 420 Bad Extension */ - sstrncpy(errortext, SIP_CLI_ERR_EXTENSION_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED: /* 433 Anonymity Disallowed */ - sstrncpy(errortext, SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_NOT_AVAIL: /* 480 Temporarily Not Available */ - sstrncpy(errortext, SIP_CLI_ERR_NOT_AVAIL_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_CALLEG: /* 481 Call Leg/Transaction Does Not Exist */ - sstrncpy(errortext, SIP_CLI_ERR_CALLEG_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_LOOP_DETECT: /* 482 Loop Detected */ - sstrncpy(errortext, SIP_CLI_ERR_LOOP_DETECT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_MANY_HOPS: /* 483 Too Many Hops */ - sstrncpy(errortext, SIP_CLI_ERR_MANY_HOPS_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_ADDRESS: /* 484 Address Incomplete */ - sstrncpy(errortext, SIP_CLI_ERR_ADDRESS_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_AMBIGUOUS: /* 485 Ambiguous */ - sstrncpy(errortext, SIP_CLI_ERR_AMBIGUOUS_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_BUSY_HERE: /* 486 Busy here */ - sstrncpy(errortext, SIP_CLI_ERR_BUSY_HERE_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_REQ_CANCEL: /* 487 Request Cancelled */ - sstrncpy(errortext, SIP_CLI_ERR_REQ_CANCEL_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_CLI_ERR_BAD_EVENT: /* 489 Bad Event */ - sstrncpy(errortext, SIP_CLI_ERR_BAD_EVENT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_INTERNAL: /*500 Internal Server Error */ - sstrncpy(errortext, SIP_SERV_ERR_INTERNAL_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_NOT_IMPLEM: /* 501 Not Implemented */ - sstrncpy(errortext, SIP_SERV_ERR_NOT_IMPLEM_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_BAD_GW: /*502 Bad Gateway */ - sstrncpy(errortext, SIP_SERV_ERR_BAD_GW_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_UNAVAIL: /* 503 Service Unavailable */ - sstrncpy(errortext, SIP_SERV_ERR_UNAVAIL_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_GW_TIMEOUT: /*504 Gateway Timeout */ - sstrncpy(errortext, SIP_SERV_ERR_GW_TIMEOUT_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_SIP_VER: /*505 SIP Version not supported */ - sstrncpy(errortext, SIP_SERV_ERR_SIP_VER_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_SERV_ERR_PRECOND_FAILED: /*580 Precondition Failed */ - sstrncpy(errortext, SIP_SERV_ERR_PRECOND_FAILED_PHRASE, - MAX_SIP_URL_LENGTH); - break; - case SIP_FAIL_BUSY: /*600 BUSY */ - sstrncpy(errortext, SIP_FAIL_BUSY_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_FAIL_DECLINE: /*603 Decline */ - sstrncpy(errortext, SIP_FAIL_DECLINE_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_FAIL_NOT_EXIST: /*604 Does not exist anywhere */ - sstrncpy(errortext, SIP_FAIL_NOT_EXIST_PHRASE, MAX_SIP_URL_LENGTH); - break; - case SIP_FAIL_NOT_ACCEPT: /*606 Not Acceptable */ - sstrncpy(errortext, SIP_FAIL_NOT_ACCEPT_PHRASE, MAX_SIP_URL_LENGTH); - break; - default: - sstrncpy(errortext, SIP_STATUS_PHRASE_NONE, MAX_SIP_URL_LENGTH); - break; - } -} - -/*********************************************************************** - * Function: ccsip_handle_early_ev_sip_update - * Description: This function handles an incoming UPDATE message, parses - * and sends it up to GSM as cc_feature call - *************************************** ********************************/ -void -ccsip_handle_early_ev_sip_update (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "early_ev_sip_update"; - sipMessage_t *request = NULL; - unsigned short request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - sipMethod_t method = sipMethodInvalid; - sipsdp_status_t sdp_status; - boolean display_valid = TRUE; - - - /* Unpack the event */ - request = event->u.pSipMessage; - - sipGetRequestMethod(request, &method); - - // Check if we are already processing a previously received UPDATE - if (get_method_request_trx_index(ccb, method, FALSE) > -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received UPDATE while processing an old one!\n", - fname); - (void) sipSPISendErrorResponse(request, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - NULL, NULL); - free_sip_message(request); - return; - } - - // Check if we have an UPDATE outstanding - if so we have a glare condition - if (get_method_request_trx_index(ccb, method, TRUE) > -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received UPDATE while old one outstanding!\n", - fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_REQ_PENDING, - SIP_CLI_ERR_REQ_PENDING_PHRASE, 0, NULL, NULL); - free_sip_message(request); - return; - } - - memset(request_check_reason_phrase, 0, SIP_WARNING_LENGTH); - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, method, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - /* - * Check if display options are acceptable. - */ - display_valid = ccsip_check_display_validity(ccb, request); - if (!display_valid) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Rejecting UPDATE with callerid blocked.Anonymous Callback configured!\n", - fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED, - SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - NULL, NULL); - return; - } - - // Check for anything in the REQUIRE header - // Update the contact information, if any - - // Since this is still an early dialog and we have not updated our from/to headers - // Copy the To header so that a response can be generated correctly - if (!(ccb->flags & INCOMING)) { - const char *from; - - from = sippmh_get_cached_header_val(request, FROM); - ccb->sip_to = strlib_update(ccb->sip_to, from); - } - - // If there is SDP in this message, extract it and send it up to GSM - sdp_status = sip_util_extract_sdp(ccb, request); - switch (sdp_status) { - case SIP_SDP_SUCCESS: - /* - * Since we do not support PRACK, UPDATE received for an early - * dialog can not contain SDP. RFC3311 section 5.2 describes - * the behavior to follow when receiving UPDATE. - * - * If UAS receives UPDATE before UAS has generated answer to - * previous offer, UAS must respond with 500 which includes a - * Retry-after header field with a random value between 0 and - * 10 seconds. - * - * If UAS receives UPDATE before receiving an answer to an offer - * made by the UAS, the UAS must respond with 491. - */ - if (ccb->oa_state == OA_OFFER_SENT) { - (void) sipSPISendUpdateResponse(ccb, FALSE, CC_CAUSE_REQUEST_PENDING, FALSE); - } else { - /* - * Must be case that ccb->oa_stat == OA_OFFER_RECEIVED, since we - * are an early dialog. In either case, we send 500 response. - */ - (void) sipSPISendUpdateResponse(ccb, FALSE, CC_CAUSE_NO_RESOURCE, FALSE); - } - return; - - case SIP_SDP_ERROR: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, "Invalid SDP", ccb); - return; - - case SIP_SDP_DNS_FAIL: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", ccb); - return; - - case SIP_SDP_NO_MEDIA: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "No acceptable media line in SDP", ccb); - return; - - case SIP_SDP_NOT_PRESENT: - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX":Update received without SDP\n", fname); - break; - } - - /* Update connected party info from RPID and Call-Info header */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - - /* - * Since we do not support PRACK, media can not be changed with UPDATE - * during early dialog. We alread sent the call info changes to GSM above - * so there is nothing else to inform GSM about. Go ahead and send the - * response to the far end. - * NOTE: When PRACK is supported, we will need to update this function - * to send media to GSM. - */ - (void) sipSPISendUpdateResponse(ccb, FALSE, CC_CAUSE_OK, FALSE); -} - -/*********************************************************************** - * Function: ccsip_handle_early_ev_sip_update_response - * Description: This function handles an incoming response to a previously - * send UPDATE message, and sends it up to GSM via cc_feature_ack - ***********************************************************************/ -void -ccsip_handle_early_ev_sip_update_response (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ -} - -/*********************************************************************** - * Function: ccsip_handle_early_ev_cc_feature - * Description: This function handles GSM's request to invoke a feature - * before the dialog is fully established. - ***********************************************************************/ -void -ccsip_handle_early_ev_cc_feature (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - - const char *fname = "early_ev_cc_feature"; - cc_features_t feature_type; - cc_msgbody_info_t *msg_body; - - feature_type = event->u.cc_msg->msg.feature.feature_id; - if (feature_type == CC_FEATURE_UPDATE) { - if (event->u.cc_msg->msg.feature.data_valid) { - msg_body = &event->u.cc_msg->msg.feature.data.update.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - (void) sipSPISendUpdate(ccb); - } else if (feature_type == CC_FEATURE_SELECT) { - } else { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - sip_cc_feature_ack(ccb->gsm_id, ccb->dn_line, feature_type, NULL, - CC_CAUSE_ERROR); - } -} - -/*********************************************************************** - * Function: ccsip_handle_early_ev_cc_feature_ack - * Description: This function handles GSM's acknowledgment to an early - * feature invocation. At this time only responses to the - * UPDATE message is supported - ***********************************************************************/ -void -ccsip_handle_early_ev_cc_feature_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "early_ev_cc_feature_ack"; - cc_features_t feature_type; - cc_msgbody_info_t *msg_body; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - - switch (feature_type) { - case CC_FEATURE_UPDATE: - if (event->u.cc_msg->msg.feature.data_valid) { - msg_body = &event->u.cc_msg->msg.feature.data.update.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - (void) sipSPISendUpdateResponse(ccb, event->u.cc_msg->msg.feature.data_valid, - event->u.cc_msg->msg.feature_ack.cause, - FALSE); - break; - - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FEATURE_UNSUPPORTED), - ccb->index, ccb->dn_line, fname); - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_STATE_UNCHANGED), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state)); - break; - } -} - -/*********************************************************************** - * Function: ccsip_handle_active_ev_sip_update - * - * Description: This function handles receipt of a SIP UPDATE message - * when the call is in the confirmed state. Based on the SDP contained, - * this may be put the call on hold or to propose new media. In either - * case, the new SDP is sent upto the GSM using cc_feature_update. - * - * In addition or instead of a media change, the UPDATE may also send - * updated values of the call-info header and RPID so these need to parsed - * and sent to GSM as well - * - * This function is analogous to the one the processes reINVITEs - ***********************************************************************/ -void -ccsip_handle_active_ev_sip_update (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "active_ev_sip_update"; - sipMessage_t *request; - const char *require = NULL; - const char *contact = NULL; - uint16_t request_check_reason_code = 0; - char request_check_reason_phrase[SIP_WARNING_LENGTH]; - cc_feature_data_t data; - sipsdp_status_t sdp_status; - boolean display_valid = TRUE; - - /* Unpack the event */ - request = event->u.pSipMessage; - - // Check if we are already processing a previously received UPDATE - if (get_method_request_trx_index(ccb, sipMethodUpdate, FALSE) > -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received UPDATE while processing an old one!\n", - fname); - (void) sipSPISendErrorResponse(request, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - NULL, NULL); - free_sip_message(request); - return; - } - - /* Request check and store */ - if (sip_sm_request_check_and_store(ccb, request, sipMethodUpdate, TRUE, - &request_check_reason_code, - request_check_reason_phrase, FALSE) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIP_SM_REQUEST_CHECK_AND_STORE)); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - request_check_reason_code, - request_check_reason_phrase, NULL); - free_sip_message(request); - return; - } - - /* - * Check if display options are acceptable. - */ - display_valid = ccsip_check_display_validity(ccb, request); - if (!display_valid) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Rejecting UPDATE with callerid blocked.Anonymous Callback configured!\n", - fname); - (void) sipSPISendErrorResponse(request, SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED, - SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE, - SIP_WARN_PROCESSING_PREVIOUS_REQUEST, - NULL, NULL); - return; - } - - /* Require: header */ - require = sippmh_get_cached_header_val(request, REQUIRE); - if (require) { - ccb->sip_require = strlib_update(ccb->sip_require, require); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Unsupported Require Header in UPDATE\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - sipSPISendInviteResponse(ccb, SIP_CLI_ERR_EXTENSION, - SIP_CLI_ERR_EXTENSION_PHRASE, - 0, NULL, FALSE, /*no SDP */ TRUE /*reTx */); - return; - } - - /* update the contact information if needed */ - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - - - - /* - * Process SDP - */ - sdp_status = sip_util_extract_sdp(ccb, request); - - switch (sdp_status) { - case SIP_SDP_SESSION_AUDIT: - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Received Session Audit SDP in UPDATE\n", - DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - /*FALLTHROUGH*/ - - case SIP_SDP_SUCCESS: - /* - * If UAS receives UPDATE before UAS has generated answer to - * previous offer, UAS must respond with 500 which includes a - * Retry-after header field with a random value between 0 and - * 10 seconds. - * - * If UAS receives UPDATE before receiving an answer to an offer - * made by the UAS, the UAS must respond with 491. - */ - if (ccb->oa_state != OA_IDLE) { - cc_causes_t cause; - - cause = (ccb->oa_state == OA_OFFER_SENT ? - CC_CAUSE_REQUEST_PENDING : CC_CAUSE_NO_RESOURCE); - (void) sipSPISendUpdateResponse(ccb, FALSE, cause, FALSE); - return; - } - /* - * Process Call-info header, if any - */ - if (sdp_status == SIP_SDP_SESSION_AUDIT) { - /* Update call info to UI can be not delayed */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - } else { - /* Update call info to UI can be delayed */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, TRUE); - } - - /* - * Check to see if received SDP indicates hold. If it is not - * a hold SDP, then we received a new media invite. - * Send FEATURE CC event to GSM. - */ - ccb->oa_state = OA_OFFER_RECEIVED; - /* Move the message body from the SIP msg. into CCAPI msg */ - sip_cc_mv_msg_body_to_cc_msg(&data.resume.msg_body, request); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_MEDIA, &data); - sip_sm_change_state(ccb, - SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING); - break; - - case SIP_SDP_ERROR: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, "Invalid SDP", ccb); - return; - - case SIP_SDP_DNS_FAIL: - sipSPISendInviteResponse(ccb, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - "DNS lookup failed for media destination", - FALSE, FALSE); - return; - - case SIP_SDP_NO_MEDIA: - (void) sipSPISendErrorResponse(ccb->last_request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "No acceptable media line in SDP", ccb); - return; - - case SIP_SDP_NOT_PRESENT: - default: - /* Update call info to UI can be not delayed */ - ccsip_update_callinfo(ccb, request, TRUE, TRUE, FALSE); - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_UPDATE, NULL); - (void) sipSPISendUpdateResponse(ccb, FALSE, CC_CAUSE_OK, FALSE); - break; - } - -} - -/*********************************************************************** - * Function: ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack - * - * Description: This function handles a CC_FEATURE_ACK from GSM that the - * GSM sends in response to an new media SDP or hold received in an UPDATE - * message and sent to it. - ***********************************************************************/ -void -ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack ( - ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - cc_features_t feature_type; - cc_causes_t cause; - cc_msgbody_info_t *msg_body; - - feature_type = event->u.cc_msg->msg.feature_ack.feature_id; - cause = event->u.cc_msg->msg.feature_ack.cause; - - switch (feature_type) { - case CC_FEATURE_HOLD: - if (cause == CC_CAUSE_NORMAL) { - cause = CC_CAUSE_OK; - } - if (event->u.cc_msg->msg.feature_ack.data_valid) { - msg_body = &event->u.cc_msg->msg.feature_ack.data.hold.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - (void) sipSPISendUpdateResponse(ccb, - event->u.cc_msg->msg.feature.data_valid, - cause, FALSE); - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - break; - - case CC_FEATURE_RESUME: - case CC_FEATURE_MEDIA: - if (cause == CC_CAUSE_NORMAL || cause == CC_CAUSE_NO_RESUME) { - cause = CC_CAUSE_OK; - } - - /* new media acks put the sdp in the resume area as well */ - if (event->u.cc_msg->msg.feature_ack.data_valid) { - msg_body = &event->u.cc_msg->msg.feature_ack.data.resume.msg_body; - ccsip_save_local_msg_body(ccb, msg_body); - } - - (void) sipSPISendUpdateResponse(ccb, - event->u.cc_msg->msg.feature.data_valid, - cause, FALSE); - sip_sm_change_state(ccb, SIP_STATE_ACTIVE); - break; - - default: - break; - } -} - -/*********************************************************************** - * Function: ccsip_handle_timer_glare_avoidance - * - * Description: This function handles the glare condition previously - * detected - ***********************************************************************/ -void -ccsip_handle_timer_glare_avoidance (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "timer_glare_avoidance"; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), ccb->index, - ccb->dn_line, fname, "Resending message"); - - // Check if this message still needs to be sent. - if (ccb->state == SIP_STATE_IDLE || - ccb->state == SIP_STATE_RELEASE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"LINE %d CCB no longer used - message not sent!\n", - fname, ccb->index); - return; - } - - // Note that the assumption here is that the glare condition can only happen - // on an INVITE. Perhaps some more checks could be made here to make sure - // this was the case - (void) sipSPISendInviteMidCall(ccb, FALSE); -} - -/*********************************************************************** - * - * SIPTaskProcessSIPNotifyServiceControl - * - * Handles an incoming unsolicited NOTIFY service control message - * - * Parameters: Incoming pSipMessage - * - * Return Value: scb if message is validated - * NULL if validation fails - * - ***********************************************************************/ -sipServiceControl_t * -ccsip_get_notify_service_control (sipMessage_t *pSipMessage) -{ - const char *fname = "ccsip_get_notify_service_control"; - sipServiceControl_t *scp; - line_t i; - ccsipCCB_t *ccb = NULL; - boolean param_match = FALSE; - - // Check the body - if (pSipMessage->mesg_body[0].msgBody == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY with no body\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_NO_BODY, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return NULL; - } - if (pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY with unknown body type\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_BAD_BODY_ENCODING, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return NULL; - } - // Parse the body - scp = sippmh_parse_service_control_body(pSipMessage->mesg_body[0].msgBody, - pSipMessage->mesg_body[0].msgLength); - - if (scp == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY but couldn't parse body\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_BAD_BODY_ENCODING, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return NULL; - } - // Verify common mandatory parms - if (scp->registerCallID == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY but no mandatory params\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - - - if (scp->action == SERVICE_CONTROL_ACTION_CHECK_VERSION) { - // make sure they gave us all the version stamps - boolean all_provided; - - all_provided = ((scp->configVersionStamp != NULL) && - (scp->dialplanVersionStamp != NULL) && - (scp->softkeyVersionStamp != NULL)) ? TRUE : FALSE; - if (!all_provided) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY but no mandatory params\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - } - - if (scp->action == SERVICE_CONTROL_ACTION_APPLY_CONFIG) { - // make sure they gave us all the mandatory parameters - boolean all_provided; - - /* - * following condition checks that all mandatory filed are present. - * firmwareInactiveLoadId is not mandatory field because of backward - * compatibility purposes. So, it is not included in the following - * check. - */ - all_provided = ((scp->configVersionStamp != NULL) && - (scp->dialplanVersionStamp != NULL) && - (scp->softkeyVersionStamp != NULL) && - (scp->cucm_result != NULL) && - (scp->firmwareLoadId != NULL) && - (scp->loadServer != NULL) && - (scp->logServer != NULL)) ? TRUE : FALSE; - if (!all_provided) - { - CCSIP_DEBUG_TASK(SIP_F_PREFIX "Incorrect message format or missing " - "param value for [configVer/cucmResult] in" - " apply-config NOTIFY\n\n" - "configVersionStamp=%s \ndialplanVersionStamp=%s" - "\nsoftkeyVersionStamp=%s \ncucmResult=%s " - "\nloadId=%s \ninactiveLoadId=%s \nloadServer=%s \nlogServer=%s " - "\nppid=%s\n\n", fname, - (scp->configVersionStamp != NULL) ? scp->configVersionStamp - : "", - (scp->dialplanVersionStamp != NULL) ? - scp->dialplanVersionStamp:"", - (scp->softkeyVersionStamp != NULL) ? - scp->softkeyVersionStamp : "", - scp->cucm_result != NULL ? scp->cucm_result : "", - (scp->firmwareLoadId != NULL) ? scp->firmwareLoadId : "", - (scp->firmwareInactiveLoadId != NULL) ? scp->firmwareInactiveLoadId : "", - (scp->loadServer != NULL) ? scp->loadServer : "", - (scp->logServer != NULL) ? scp->logServer : "", - scp->ppid == TRUE? "True": "False"); - - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - /* - * Now if firmwareInactiveLoadId is null, then allocate empty string to - * it so that an empty string can be passed on to java side. - */ - if (scp->firmwareInactiveLoadId == NULL) { - scp->firmwareInactiveLoadId = cpr_calloc(1, 2); - } - } - - - // Take action - // Compare the reg call id received with call-id that we sent out - for (i = REG_CCB_START; i <= TEL_CCB_END + 1; i++) { - ccb = sip_sm_get_ccb_by_index(i); - if (ccb) { - if (strcmp(scp->registerCallID, ccb->sipCallID) == 0) { - param_match = TRUE; - break; - } - } - } - - // Call Platform API for actually performing the called for action - if (param_match && ccb != NULL) { - if (sip_regmgr_get_cc_mode(ccb->dn_line) != REG_MODE_CCM) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY in non CCM mode\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY, callid doesn't match\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_service_control_info(scp); - return NULL; - } - - /* NOTIFY message validated and scp allocated */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received NOTIFY, callid matches\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - return scp; -} - -void -ccsip_handle_unsolicited_notify (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_unsolicited_notify"; - sipMessage_t *request; - sipServiceControl_t *scp; - - /* Unpack the event */ - request = event->u.pSipMessage; - - scp = ccsip_get_notify_service_control(request); - if (scp != NULL) { - if (scp->action == SERVICE_CONTROL_ACTION_CALL_PRESERVATION) { - if (ccb->state == SIP_STATE_ACTIVE) { - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_CALL_PRESERVATION, NULL); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP state %s ignoring call preservation request\n", - fname, sip_util_state2string(ccb->state)); - } - if (sipSPISendErrorResponse(request, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP); - - - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Unsupported unsolicited notify event\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (sipSPISendErrorResponse(request, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - } - sippmh_free_service_control_info(scp); - } -} - - - -/** - * This function frees a duped CCB. - * - * @param dup_ccb The duplicate CCB to free - */ -void free_duped (ccsipCCB_t *dup_ccb) -{ - -} - -/** - * This function dups the origCCB and returns a new ccb. It applies - * to only TEL CCBs. The contents of the new CCB is determined by dupCCBFlags. - * - * dupCCBFlag values are: - * DUPED_CCB 0x01 - * DUP_CCB_NEW_CALLID 0x02 - * DUP_CCB_INIT_STATE 0x04 - * DUP_CCB_REINIT_DNS 0x08 - * DUP_CCB_STOLEN_FEAT_DATA 0x10 - * if this flag is set and ccb->feature_data is NULL, then - * feature data was stolen from this ccb. - * - * if this flag is set and ccb->feature_data is non-NULL, then - * this ccb stole the feature_data pointer from the mother_ccb. - * - * The concept of duping is to maximize sharing of - * data structures by pointer sharing where it makes sense. - * The companion function of freeDupedCCB() is aware that - * of the duping. ccb->dup_flags will remember the duping - * attributes (flags shown above) and will free members - * appropriately. - * - * @param origCCB - * @param dup_flags - * - * @return duplicated CCB or NULL - */ -ccsipCCB_t * -create_dupCCB (ccsipCCB_t *origCCB, int dup_flags) -{ - ccsipCCB_t *dupCCB; - line_t child_line; - const char *fname = "dupCCB()"; - const char *outOfDialogPrefix = "OutOfDialog--"; - - dupCCB = sip_sm_get_ccb_next_available(&child_line); //need to check for failure - - if (dupCCB == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_get_ccb_next_available()" - " returned null.\n", fname); - return NULL; - } - - dupCCB->dup_flags = dup_flags|DUP_CCB; - dupCCB->mother_ccb = (void *)origCCB; - - dupCCB->flags = origCCB->flags; - sstrncpy(dupCCB->sipCallID, origCCB->sipCallID, MAX_SIP_CALL_ID); - dupCCB->gsm_id = origCCB->gsm_id; - dupCCB->con_call_id = origCCB->con_call_id; - dupCCB->blind_xfer_call_id = origCCB->blind_xfer_call_id; - - dupCCB->state = origCCB->state; - dupCCB->index = origCCB->index; - dupCCB->dn_line = origCCB->dn_line; - dupCCB->retx_counter = 0; - dupCCB->type = origCCB->type; - - dupCCB->proxySelection = origCCB->proxySelection; - dupCCB->outBoundProxyAddr = origCCB->outBoundProxyAddr; - dupCCB->outBoundProxyPort = origCCB->outBoundProxyPort; - - if (!(dup_flags & DUP_CCB_REINIT_DNS)) { - dupCCB->SRVhandle = NULL; - dupCCB->ObpSRVhandle = NULL; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Reiniting DNS fields in duped ccb\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } else { - //TBD - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Not reiniting DNS fields in duped ccb\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } - - dupCCB->routeMode = origCCB->routeMode; - dupCCB->udpId = origCCB->udpId; - - dupCCB->contact_info = NULL; - - if (dup_flags & DUP_CCB_NEW_CALLID) { - dupCCB->record_route_info = NULL; - dupCCB->sipCallID[0] = '\0'; - sip_util_get_new_call_id(dupCCB); - sstrncpy(dupCCB->sipCallID, outOfDialogPrefix, - sizeof(dupCCB->sipCallID)); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Using new Call-ID for OutofDialog ccb\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } else { - dupCCB->record_route_info = - sippmh_copy_record_route(origCCB->record_route_info); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Copied mother CCB's route set.\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } - - dupCCB->calledDisplayedName = strlib_update(dupCCB->calledDisplayedName, - origCCB->calledDisplayedName); - dupCCB->callingNumber = strlib_update(dupCCB->callingNumber, - origCCB->callingNumber); - dupCCB->callingDisplayName = strlib_update(dupCCB->callingDisplayName, - origCCB->callingDisplayName); - dupCCB->calledNumber = strlib_update(dupCCB->calledNumber, - origCCB->calledNumber); - dupCCB->calledNumberLen = origCCB->calledNumberLen; - dupCCB->calledNumberFirstDigitDialed = origCCB->calledNumberFirstDigitDialed; - - dupCCB->src_addr = origCCB->src_addr; - dupCCB->dest_sip_addr = origCCB->dest_sip_addr; - dupCCB->local_port = origCCB->local_port; - dupCCB->dest_sip_port = origCCB->dest_sip_port; - //int16_t sip_socket_handle; NOT USED ANYWHERE! - - - /* - * Headers - */ - sstrncpy(dupCCB->ReqURI, origCCB->ReqURI, sizeof(dupCCB->ReqURI)); - dupCCB->ReqURIOriginal = strlib_update(dupCCB->ReqURIOriginal, - origCCB->ReqURIOriginal); - - dupCCB->sip_to = strlib_update(dupCCB->sip_to, origCCB->sip_to); - if (dup_flags & DUP_CCB_NEW_CALLID) { - char *str, *str2; - str = strlib_open(dupCCB->sip_to, 0); - - if (str == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"strlib_open returned NULL while trying" - " to process To.", fname); - return NULL; - } - - str2 = strstr(str,";tag"); - if (str2 != NULL) { - *str2 = '\0'; - } - dupCCB->sip_to = strlib_close(str); - } - - dupCCB->sip_from = strlib_update(dupCCB->sip_from, origCCB->sip_from); - if (dup_flags & DUP_CCB_NEW_CALLID) { - char *str, *str2; - str = strlib_open(dupCCB->sip_from, 0); - - if (str == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"strlib_open returned NULL while trying" - " to process From.", fname); - return NULL; - } - - str2 = strstr(str,";tag"); - if (str2 != NULL) { - *str2 = '\0'; - } - dupCCB->sip_from = strlib_close(str); - } - - { - char tag[MAX_SIP_URL_LENGTH]; - sip_util_make_tag(tag); - - if (dupCCB->flags & INCOMING) { - dupCCB->sip_to = strlib_append(dupCCB->sip_to, ";tag="); - dupCCB->sip_to = strlib_append(dupCCB->sip_to, tag); - dupCCB->sip_to_tag = strlib_update(dupCCB->sip_to_tag, tag); - } else { - dupCCB->sip_from = strlib_append(dupCCB->sip_from, ";tag="); - dupCCB->sip_from = strlib_append(dupCCB->sip_from, tag); - dupCCB->sip_from_tag = strlib_update(dupCCB->sip_from_tag, tag); - } - } - - dupCCB->sip_contact = strlib_update(dupCCB->sip_contact, - origCCB->sip_contact); - - dupCCB->featuretype = origCCB->featuretype; - - if (dup_flags & DUP_CCB_STOLEN_FEAT_DATA) { - dupCCB->feature_data = origCCB->feature_data; - dupCCB->dup_flags |= DUP_CCB_STOLEN_FEAT_DATA; - origCCB->feature_data = NULL; - origCCB->dup_flags |= DUP_CCB_STOLEN_FEAT_DATA; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Stealing feature_data pointer from mother ccb\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } - - return dupCCB; -} - -void -ccsip_handle_sent_ood_refer_ev_sip_1xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sent_ood_refer_ev_sip_1xx"; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - sip_util_event2string(event->type)); - - ccsip_handle_sentinvite_ev_sip_1xx(ccb, event); -} - -void -ccsip_handle_sent_ood_refer_ev_sip_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sent_ood_refer_ev_sip_2xx"; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - sip_util_event2string(event->type)); - - ccsip_handle_accept_2xx(ccb, event); - sip_sm_call_cleanup(ccb); -} - -void -ccsip_handle_sent_ood_refer_ev_sip_fxx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "ccsip_handle_sent_ood_refer_ev_sip_fxx"; - sipMessage_t *response; - sipRespLine_t *respLine = NULL; - uint16_t status_code = 0; - sipMethod_t method = sipMethodInvalid; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY), - ccb->index, ccb->dn_line, fname, - sip_util_state2string(ccb->state), - sip_util_event2string(event->type)); - - response = event->u.pSipMessage; - - if (sipGetResponseMethod(response, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(response); - return; - } - - /* Get the status code */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - //status_code = 408; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - ccsip_handle_sentinvite_ev_sip_fxx(ccb, event); - - if ((status_code != SIP_CLI_ERR_UNAUTH) && - (status_code != SIP_CLI_ERR_PROXY_REQD)) { - sip_sm_call_cleanup(ccb); - } -} - -void -ccsip_handle_ev_cc_info (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - sipSPISendInfo(ccb, - (const char *)event->u.cc_msg->msg.info.info_package, - (const char *)event->u.cc_msg->msg.info.content_type, - (const char *)event->u.cc_msg->msg.info.message_body); -} - -/* - * Function: ccsip_set_replace_info - * - * Parameters: - * ccb - pointer to ccsipCCB_t. - * setup - pointer to the cc_setup_t for the cc setup msg. that - * contains "replace" flag. - * - * Description: - * The ccsip_set_replace_info populates the information in the CCB - * for replace information of the INVITE to send out. The function - * may derives certain information from the remote dialog, etc. - * - * Returns: - * TRUE - when successfully set replace information. - * FALSE - when fail to set replace information. - */ -static boolean -ccsip_set_replace_info (ccsipCCB_t *ccb, cc_setup_t * setup) -{ - cc_call_info_t *call_info = &setup->call_info; - - if (call_info->type != CC_FEAT_REPLACE) { - /* The call info does not contain the replace information */ - return (FALSE); - } - - if (call_info->data.replace.remote_call_id != CC_NO_CALL_ID) { - /* This is a replacement of the remote dialog */ - strlib_free(ccb->sipxfercallid); - ccb->sipxfercallid = strlib_empty(); - } - return (FALSE); -} - -/* - * Function: ccsip_handle_cc_select_event - * - * Parameters: - * sip_sm_event - Pointer to sipSMEvent_t - * - * Description: - * The ccsip_handle_cc_select_event checks for CC_FEATURE_SELECT and - * handled the request. - * - * Returns: - * TRUE - CC_FEATURE select has been handled. - * FALSE - CC_FEATURE select has not been handled. - */ -static boolean -ccsip_handle_cc_select_event (sipSMEvent_t *sip_sm_event) -{ - cc_feature_t *msg; - - // currently not used: line_t line_number = 0; - - msg = &(sip_sm_event->u.cc_msg->msg.feature); - if (!((msg->msg_id == CC_MSG_FEATURE) && - (msg->feature_id == CC_FEATURE_SELECT))) { - /* Some other feature or msg. */ - return (FALSE); - } - - return FALSE; -} - -/* - * Function: ccsip_handle_cc_b2bjoin_event - * - * Parameters: - * sip_sm_event - Pointer to sipSMEvent_t - * - * Description: - * The ccsip_handle_cc_b2bjoin_event checks for CC_FEATURE_B2BJOIN and - * handled the request. - * - * Returns: - * TRUE - CC_FEATURE select has been handled. - * FALSE - CC_FEATURE select has not been handled. - */ -static boolean -ccsip_handle_cc_b2bjoin_event (sipSMEvent_t *sip_sm_event) -{ - cc_feature_t *msg; - - // currently not used: line_t line_number = 0; - - msg = &(sip_sm_event->u.cc_msg->msg.feature); - if (!((msg->msg_id == CC_MSG_FEATURE) && - (msg->feature_id == CC_FEATURE_B2B_JOIN))) { - /* Some other feature or msg. */ - return (FALSE); - } - - return FALSE; -} - -/* - * Function: ccsip_set_join_info - * - * Parameters: - * ccb - pointer to ccsipCCB_t. - * setup - pointer to the cc_setup_t for the cc setup msg. - * - * Description: - * The ccsip_set_join_info populates the information in the CCB - * for join header to be sent out in the INVITE. The function - * may derives certain information from the remote dialog, etc. - * - * Returns: - * None. - */ -static void -ccsip_set_join_info (ccsipCCB_t *ccb, cc_setup_t * setup) -{ - const char *fname = "ccsip_set_join_info"; - cc_call_info_t *call_info = &setup->call_info; - - if (((call_info->type != CC_FEAT_BARGE) && - (call_info->type != CC_FEAT_CBARGE)) || - (call_info->data.join.join_call_id == CC_NO_CALL_ID)) { - /* The call info does not contain any barge information */ - return; - } - - ccb->join_info = (sipJoinInfo_t *) cpr_calloc(1, sizeof(sipJoinInfo_t)); - - if (!ccb->join_info) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, "malloc(join_info)"); - return; - } -} - -/* - * Function: ccsip_get_join_info - * - * Parameters: - * ccb - pointer to ccsipCCB_t. - * request - pointer to the sipMessage_t for the sip msg. - * - * Description: - * The ccsip_get_join_info parses the join header, finds the - * the call specified by the call id, matches the from/to tag and - * makes sure that this call is in active state. Then, it finds the - * gsm of the join target call id and populates the call info with that - * - * Returns: - * TRUE - join hdr is good. - * FALSE - join hdr is not good. - */ -static boolean -ccsip_get_join_info (ccsipCCB_t *ccb, sipMessage_t *request) -{ - const char *fname = "ccsip_get_join_info"; - const char *joinhdr = NULL; - - /* Parse Join header */ - joinhdr = sippmh_get_header_val(request, SIP_HEADER_JOIN, NULL); - if (joinhdr) { - - ccsipCCB_t *join_ccb = NULL; - - // From-tag and To-tag check to match an active call - int ff_check = 0; - int ft_check = 0; - int tf_check = 0; - int tt_check = 0; - - // currently not used: boolean joinhdr_not_valid = FALSE; - - if (ccb->join_info) { - sippmh_free_join_info(ccb->join_info); - } - ccb->join_info = sippmh_parse_join_header(joinhdr); - - if (ccb->join_info) { - join_ccb = sip_sm_get_ccb_by_callid(ccb->join_info->call_id); - } - if (join_ccb == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, - "Attempted Join call does not exist"); - return (FALSE); - } - - if (!ccb->in_call_info) { - ccb->in_call_info = (cc_call_info_t *) - cpr_calloc(1, sizeof(cc_call_info_t)); - } - if (!ccb->in_call_info) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "malloc(call_info)"); - return (FALSE); - } - - ccb->in_call_info->type = CC_FEAT_MONITOR; - - if (join_ccb->state != SIP_STATE_ACTIVE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - join_ccb->index, - join_ccb->dn_line, fname, - "Attempted Join call is not active or held, but OK to continue."); - /* return (FALSE); CSCtd11077 */ - /* OK to continue to send CC_MSG_SETUP because DCSM will hold CC_FEATURE_JOIN until */ - /* DEF is in the CONNECTED state to process the JOIN msg. */ - } - - ff_check = cpr_strcasecmp(join_ccb->sip_from_tag, ccb->join_info->from_tag); - ft_check = cpr_strcasecmp(join_ccb->sip_from_tag, ccb->join_info->to_tag); - tt_check = cpr_strcasecmp(join_ccb->sip_to_tag, ccb->join_info->to_tag); - tf_check = cpr_strcasecmp(join_ccb->sip_to_tag, ccb->join_info->from_tag); - - // In this issue, the correct match is to match F/F and T/T, or to match F/T and T/F. - // All other cases are error. - // So, (ff_check==0 && tt_check==0) || (ft_check==0 && tf_check==0) is the correct match - // thus, !( (ff_check==0 && tt_check==0) || (ft_check==0 && tf_check==0) ) represents all other cases. - if ( !( (ff_check==0 && tt_check==0) || (ft_check==0 && tf_check==0) ) ) { - CCSIP_DEBUG_ERROR( - get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - join_ccb->index, - join_ccb->dn_line, fname, - "Join Header's From/To tag does not match any ccb's From/To tag"); - return (FALSE); - } - ccb->in_call_info->data.join.join_call_id = join_ccb->gsm_id; - } - return (TRUE); -} - -/** - * - * Returns SIP call ID that is pre-allocated during off hook. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return pointer to character string of the SIP call ID. - * - * @pre none - */ -char * -getPreallocatedSipCallID (line_t dn_line) -{ - static const char *fname = "getPreallocatedSipCallID"; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char pSrcAddrStr[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t src_addr; - int nat_enable = 0; - - CPR_IP_ADDR_INIT(src_addr); - - if ((dn_line > MAX_REG_LINES) && (dn_line < 1)){ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d is greater than %d or less than 1", - fname, dn_line, MAX_REG_LINES); - return NULL; - } - /* - * if one is already created, use it. - */ - if (preAllocatedSipCallID[dn_line - 1] != NULL) { - return (preAllocatedSipCallID[dn_line - 1]); - } - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&src_addr); - } else { - sip_config_get_nat_ipaddr(&src_addr); - } - - platform_get_wired_mac_address(mac_address); - ipaddr2dotted(pSrcAddrStr, &src_addr); - - preAllocatedSipCallID[dn_line - 1] = (char *) cpr_malloc(MAX_SIP_CALL_ID); - - if (preAllocatedSipCallID[dn_line - 1] != NULL) { - sip_create_new_sip_call_id(preAllocatedSipCallID[dn_line - 1], - mac_address, pSrcAddrStr); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed", fname); - } - - return (preAllocatedSipCallID[dn_line - 1]); -} - -/** - * - * Returns preallocate local SIP tag. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return pointer to character string of the tag. - * - * @pre none - */ -char * -getPreallocatedSipLocalTag (line_t dn_line) -{ - static const char *fname = "getPreallocatedSipLocalTag"; - - if ((dn_line > MAX_REG_LINES) || (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d. The valid range is 1 to %d\n", - fname, dn_line, MAX_REG_LINES); - return NULL; - } - if (preAllocatedTag[dn_line - 1] == NULL) { - preAllocatedTag[dn_line - 1] = (char *) cpr_malloc(MAX_SIP_TAG_LENGTH); - if (preAllocatedTag[dn_line - 1] == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed\n", fname); - } else { - sip_util_make_tag(preAllocatedTag[dn_line - 1]); - } - } - - return (preAllocatedTag[dn_line - 1]); -} - -/** - * - * Returns the pre-allocated local TAG based on a given dn line number. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return pointer to character string of the tag. - * - * @pre none - */ -char * -ccsip_find_preallocated_sip_local_tag (line_t dn_line) -{ - static const char *fname = "ccsip_find_preallocated_sip_local_tag"; - - if ((dn_line > MAX_REG_LINES) || (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d. The valid range is 1 to %d\n", - fname, dn_line, MAX_REG_LINES); - return NULL; - } - - return (preAllocatedTag[dn_line - 1]); -} - -/** - * - * Frees pre-allocated local tag that. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return none - * - * @pre none - */ -void -ccsip_free_preallocated_sip_local_tag (line_t dn_line) -{ - static const char *fname = "ccsip_free_preallocated_sip_local_tag"; - - if ((dn_line > MAX_REG_LINES) || (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d. The valid range is 1 to %d\n", - fname, dn_line, MAX_REG_LINES); - return; - } - - cpr_free(preAllocatedTag[dn_line - 1]); - preAllocatedTag[dn_line - 1] = NULL; -} - -/** - * - * Returns the SIP Call ID based on the dn line number given. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return pointer to character string of the tag. - * - * @pre none - */ -static char * -ccsip_find_preallocated_sip_call_id (line_t dn_line) -{ - static const char *fname = "ccsip_find_preallocated_sip_call_id"; - - if ((dn_line > MAX_REG_LINES) && (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d is greater than %d or less than 1\n", - fname, dn_line, MAX_REG_LINES); - return NULL; - } - return (preAllocatedSipCallID[dn_line - 1]); -} - -/** - * - * Frees the SIP Call ID based on the dn line number given. - * - * @param dn_line - line_t of the line that is goes off hook. - * - * @return none - * - * @pre none - */ -static void -ccsip_free_preallocated_sip_call_id (line_t dn_line) -{ - static const char *fname = "ccsip_free_preallocated_sip_call_id"; - - if ((dn_line > MAX_REG_LINES) && (dn_line < 1)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"dn_line=%d is greater than %d or less than 1\n", - fname, dn_line, MAX_REG_LINES); - return; - } - cpr_free(preAllocatedSipCallID[dn_line - 1]); - preAllocatedSipCallID[dn_line - 1] = NULL; -} - -/* - * Function: ccsip_handle_cc_hook_event - * - * Parameters: - * sip_sm_event - Pointer to sipSMEvent_t - * - * Description: - * The ccsip_handle_cc_hook_event checks for - * CC_MSG_OFFHOOK/CC_MSG_ONHOOK and handles the request. - * - * Returns: - * TRUE - if it is hook event. - * FALSE - if it is not hook event. - */ -static boolean -ccsip_handle_cc_hook_event (sipSMEvent_t *sip_sm_event) -{ - static const char *fname = "ccsip_handle_cc_hook_event"; - line_t line_number = 0; - char *sip_call_id = NULL; - char *sip_local_tag; - cc_msg_t *pCCMsg; - ccsipCCB_t *ccb; - cc_msgs_t event; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Entering with event %d", DEB_F_PREFIX_ARGS(SIP_EVT, fname), - sip_sm_event->u.cc_msg->msg.setup.msg_id); - - pCCMsg = sip_sm_event->u.cc_msg; - event = pCCMsg->msg.setup.msg_id; - - if ((event != CC_MSG_OFFHOOK) && (event != CC_MSG_ONHOOK)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Exiting because event is not hook state\n", - DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - return FALSE; - } - - if (event == CC_MSG_OFFHOOK) { - line_number = pCCMsg->msg.offhook.line; - } else { - line_number = pCCMsg->msg.onhook.line; - } - if (sip_regmgr_get_cc_mode(line_number) != REG_MODE_CCM) { - /* this is not CCM environment */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Exiting Not CCM mode\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - return TRUE; - } - - /* - * Allocate SIP Call-ID and local tag, if they are not already allocated. - */ - if (event == CC_MSG_OFFHOOK) { - ccb = sip_sm_get_ccb_by_gsm_id(pCCMsg->msg.offhook.call_id); - line_number = pCCMsg->msg.offhook.line; - } else { - ccb = sip_sm_get_ccb_by_gsm_id(pCCMsg->msg.onhook.call_id); - line_number = pCCMsg->msg.onhook.line; - } - if (ccb == NULL) { - /* - * No CCB. So user must be just trying to make a call. - * We will pre allocate SIP Call-ID and local tag for the potential - * dialog initiated by INVITE. These values are needed for sending - * hook event notification. - */ - sip_call_id = getPreallocatedSipCallID(line_number); - sip_local_tag = getPreallocatedSipLocalTag(line_number); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"preallocated callid: %s & local-tag: %s\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname), sip_call_id, sip_local_tag); - } else { - sip_call_id = ccb->sipCallID; - sip_local_tag = (char *) (ccb->sip_from_tag); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"callid: %s & local-tag: %s\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname), sip_call_id, sip_local_tag); - } - - /* - * if CCB is NULL and we are sending ONKOOK notification, - * free up the preallocated call-id and local-tag. - */ - if ((ccb == NULL) && (event == CC_MSG_ONHOOK)) { - ccsip_free_preallocated_sip_call_id(line_number); - ccsip_free_preallocated_sip_local_tag(line_number); - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Exiting after sending hook state " - "notification\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - return TRUE; -} diff --git a/libs/sipcc/core/sipstack/ccsip_debug.c b/libs/sipcc/core/sipstack/ccsip_debug.c deleted file mode 100644 index b7d571e4f7..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_debug.c +++ /dev/null @@ -1,392 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "debug.h" -#include "phone_debug.h" -#include "ccsip_publish.h" -#include "util_string.h" -#include "sip_interface_regmgr.h" - -extern boolean dump_reg_msg; - -/* SIP flags */ -cc_int32_t SipDebugMessage = 1; /* SIP messaging output */ -cc_int32_t SipDebugState = 0; /* SIP State Machine output */ -cc_int32_t SipDebugTask = 1; /* SIP Task output */ -cc_int32_t SipDebugRegState = 0; /* SIP Registration State Mach. output */ - -/** - * SipRelDevEnabled flag is not a debug print flag. It actually turns - * on and off reliable delivery module in sip layer. We will keep - * this on as retransmissions are enabled on CUCM by default even for TCP transport - */ -int32_t SipRelDevEnabled = 1; /* Is reliable delivery on? */ - -int32_t SipDebugGenContactHeader = 0; /* Generate Contact header */ -cc_int32_t SipDebugTrx = 0; /* SIP Transaction Layer output */ - -cc_int32_t GSMDebug = 0; -cc_int32_t FIMDebug = 0; -cc_int32_t LSMDebug = 0; -cc_int32_t FSMDebugSM = 0; -int32_t CSMDebugSM = 0; -cc_int32_t CCDebug = 0; -cc_int32_t CCDebugMsg = 0; -cc_int32_t AuthDebug = 0; -cc_int32_t g_DEFDebug = 1; -cc_int32_t TNPDebug = 1; -cc_int32_t VCMDebug = 0; -cc_int32_t CCEVENTDebug = 0; -cc_int32_t PLATDebug = 0; -cc_int32_t TMRDebug = 0; -cc_int32_t g_dcsmDebug = 0; - -/** - * - * Dump sip messages - * - * @param msg - message buffer - * pSIPMessage - parsed message structure - * cc_remote_ipaddr - remote ip address - * cc_remote_port - remote port number - * - * @return none - * - * @pre (valid pSIPMessage AND - * valid cc_remote_ipaddr) - */ - -void ccsip_dump_send_msg_info (char *msg, sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port) -{ - char *disp_buf; - const char *req_uri; - const char *cseq; - const char *callid; - char ipaddr_str[MAX_IPADDR_STR_LEN]; - static const char fname[] = "ccsip_dump_send_msg_info"; - - ipaddr2dotted(ipaddr_str, cc_remote_ipaddr); - - req_uri = sippmh_get_header_val(pSIPMessage, SIP_HEADER_TO, NULL); - if (req_uri == NULL) { - /* No REQ URI, fill with blank */ - req_uri = ""; - } - cseq = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CSEQ, NULL); - if (cseq == NULL) { - /* No REQ CSEQ, fill with blank */ - cseq = ""; - } - callid = sippmh_get_header_val(pSIPMessage, SIP_HEADER_CALLID, NULL); - if (callid == NULL) { - /* No REQ CSEQ, fill with blank */ - callid = ""; - } - - /* For messages starting with SIP add 8 byte. default - * debugs do not show all the SIP message information - * rather show initial msg. - */ - if (msg != NULL) { - if (msg[0] == 'S' && - msg[1] == 'I' && - msg[2] == 'P') { - disp_buf = &msg[8]; - } else { - disp_buf = msg; - } - if ((strncmp(disp_buf, SIP_METHOD_REGISTER, sizeof(SIP_METHOD_REGISTER)-1) == 0) && - (!dump_reg_msg)) { - return; - } - } else { - /* No msg. buffer */ - disp_buf = NULL; - } - - - if (disp_buf != NULL) { - DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>:%c%c%c%c%c%c%c: %-10s :%-6s::%s\n", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), - ipaddr_str, cc_remote_port, - disp_buf[0], - disp_buf[1], - disp_buf[2], - disp_buf[3], - disp_buf[4], - disp_buf[5], - disp_buf[6], - req_uri, - cseq, callid); - } else { - /* No msg to send */ - DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message\n", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), - ipaddr_str, cc_remote_port); - } -} - -/** - * - * Dump sip messages - * - * @param msg - message buffer - * pSIPMessage - parsed message structure - * cc_remote_ipaddr - remote ip address - * cc_remote_port - remote port number - * - * @return none - * - * @pre (valid pSIPMessage AND - * valid cc_remote_ipaddr) - */ - -void ccsip_dump_recv_msg_info (sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port) -{ - char *disp_buf; - const char *req_uri; - const char *cseq; - const char *callid; - char ipaddr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t cc_ipaddr; - static const char fname[] = "ccsip_dump_recv_msg_info"; - - util_ntohl(&cc_ipaddr, cc_remote_ipaddr); - ipaddr2dotted(ipaddr_str, &cc_ipaddr); - - req_uri = sippmh_get_cached_header_val(pSIPMessage, FROM); - if (req_uri == NULL) { - /* No REQ URI, fill with blank */ - req_uri = ""; - } - cseq = sippmh_get_cached_header_val(pSIPMessage, CSEQ); - if (cseq == NULL) { - /* No REQ CSEQ, fill with blank */ - cseq = ""; - } - callid = sippmh_get_cached_header_val(pSIPMessage, CALLID); - if (callid == NULL) { - /* No REQ CSEQ, fill with blank */ - callid = ""; - } - - if (!dump_reg_msg) { - if (strstr(cseq, SIP_METHOD_REGISTER) != NULL) { - return; - } - } - - /* For messages starting with SIP add 8 byte. default - * debugs do not show all the SIP message information - * rather show initial msg. - */ - if (pSIPMessage->mesg_line != NULL) { - if (pSIPMessage->mesg_line[0] == 'S' && - pSIPMessage->mesg_line[1] == 'I' && - pSIPMessage->mesg_line[2] == 'P') { - disp_buf = &(pSIPMessage->mesg_line[8]); - } else { - disp_buf = pSIPMessage->mesg_line; - } - } else { - /* - * It is possible that this function is called with - * invalid message or partially received. - */ - disp_buf = NULL; - } - - if (disp_buf != NULL) { - DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>:%c%c%c%c%c%c%c: %-10s :%-6s::%s\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), - ipaddr_str, cc_remote_port, - disp_buf[0], - disp_buf[1], - disp_buf[2], - disp_buf[3], - disp_buf[4], - disp_buf[5], - disp_buf[6], - req_uri, - cseq, callid); - } else { - /* No line received */ - DEF_DEBUG(DEB_F_PREFIX"<%s:%-4d>: empty message\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), - ipaddr_str, cc_remote_port); - } -} - -/** - * - * platform_print_sip_msg - * - * The function perform printing SIP msg. - * - * Parameters: msg - pointer to character strings of the SIP messages. - * - * Return Value: None - * - */ -void -platform_print_sip_msg (const char *msg) -{ - char *buf; - int msg_to_crypto_line_len, msg_to_digits_tag_len, buf_len; - const char *c_line_begin, *c_line_end; - static const char crypto_line_tag[] = "a=crypto:"; - static const char crypto_mask[] = "..."; - static const char digits_tag[] = "digits="; - - if (msg == NULL) { - return; - } - - buginf_msg("\n"); - /* replace digits for security reasons */ - if (strstr(msg, "kpml-response")) { - /* This is kpml response. so supress printing digits. */ - c_line_begin = strstr(msg, digits_tag); - if (c_line_begin == NULL) { - /* No digits, print everything */ - buginf_msg(msg); - return; - } - /* - * Calculate the length of the msg. to print from - * from the beginning to the end of the "digits=" i.e. - */ - msg_to_digits_tag_len = c_line_begin - msg + sizeof(digits_tag); - buf_len = msg_to_digits_tag_len + sizeof(crypto_mask); - buf = (char *) cpr_malloc(buf_len); - if (buf == NULL) { - /* No memory */ - return; - } - - /* Copy the message upto "digits=" */ - memcpy(buf, msg, msg_to_digits_tag_len); - - /* Copy mask and the end NULL terminating char to the buffer */ - memcpy(&buf[msg_to_digits_tag_len], crypto_mask, sizeof(crypto_mask)); - /* Print it out now */ - buginf_msg(buf); - cpr_free(buf); - - c_line_end = c_line_begin + sizeof(digits_tag) + 3; /* 3 beacuse " + digit + " */ - msg = c_line_end; - buginf_msg(msg); - } else if (sip_regmgr_get_sec_level(1) == ENCRYPTED) { - /* The 1st. line is using encrypted signaling */ - while (TRUE) { - c_line_begin = strstr(msg, crypto_line_tag); - if (c_line_begin == NULL) { - /* No more crypto line, print whatever left and done */ - buginf_msg(msg); - return; - } else { - /* - * Found a crypto line: - * - * Allocate buffer to print the msg. including this - * instance of crypto line but no crypto parameter. - * For example: - * - * v=0 - * o=Cisco-SIPUA 3052 7 IN IP4 10.80.35.217 - * s=SIP Call - * t=0 0 - * m=audio 28926 RTP/SAVP 0 8 18 101 - * c=IN IP4 10.80.35.217 - * a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:GqT... - * a=rtpmap:0 PCMU/8000 - * - * - * The output of printing will be - * - * v=0 - * o=Cisco-SIPUA 3052 7 IN IP4 10.80.35.217 - * s=SIP Call - * t=0 0 - * m=audio 28926 RTP/SAVP 0 8 18 101 - * c=IN IP4 10.80.35.217 - * a=crypto:1... - * a=rtpmap:0 PCMU/8000 - * - */ - - /* - * Calculate the length of the msg. to print from - * current position to the end of the "a=crypto:n" i.e. - * from the current of msg passes the ":" by one character - * after of the "a=crypto:". This allows the first character - * of the crypto tag field character to be included in the - * output. Note that there is no explicit adding this - * extra character in the code below because of the - * sizeof(crypto_line_tag) includes extra 1 byte of string - * termination character already. It will be the extra - * character to print after the ":". - */ - msg_to_crypto_line_len = c_line_begin - msg + - sizeof(crypto_line_tag); - /* - * The buffer allocated to print includes the length from - * current msg pointer to this instance of crypto line + - * the mask length plus 1 byte for NULL terminating character. - * The NULL terminating character is included in the - * sizeof(crypto_mask) below. - */ - buf_len = msg_to_crypto_line_len + sizeof(crypto_mask); - buf = (char *) cpr_malloc(buf_len); - if (buf == NULL) { - /* No memory */ - return; - } - - /* Copy the message including this instance of crypto line */ - memcpy(buf, msg, msg_to_crypto_line_len); - - /* Copy mask and the end NULL terminating char to the buffer */ - memcpy(&buf[msg_to_crypto_line_len], crypto_mask, - sizeof(crypto_mask)); - /* Print it out now */ - buginf_msg(buf); - cpr_free(buf); - - /* Find the end of the crypto line */ - c_line_end = strpbrk(c_line_begin, "\n"); - if (c_line_end != NULL) { - /* Skip pass the "\n" character of the crypto line */ - msg = c_line_end + 1; - } else { - /* Some thing is wrong, no end line character in SDP */ - return; - } - } - } - } else { - /* print full content */ - buginf_msg(msg); - } -} - -/* - * Function: ccsip_debug_init() - * - * Parameters: None - * - * Description: Initialize the Debug keywords used by the SIP protocol stack. - * - * Returns: None - * - */ -void -ccsip_debug_init (void) -{ - /* Placeholder for doing any initialization related tasks */ -} diff --git a/libs/sipcc/core/sipstack/ccsip_info.c b/libs/sipcc/core/sipstack/ccsip_info.c deleted file mode 100644 index d58b022785..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_info.c +++ /dev/null @@ -1,898 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" - -#include "ccsip_core.h" -#include "ccsip_callinfo.h" -#include "ccsip_messaging.h" -#include "uiapi.h" -#include "lsm.h" -#include "fsm.h" -#include "vcm.h" -#include "phone_debug.h" -#include "singly_link_list.h" -#include "ccapi.h" - -extern int httpish_strncasecmp(const char *s1, const char *s2, size_t len); - -typedef unsigned int info_index_t; -typedef unsigned int type_index_t; - -typedef struct { - info_package_handler_t handler; - info_index_t info_index; // the index of the info_package in g_registered_info array - // i.e., the value returned by find_info_index() - type_index_t type_index; // the index of the content_type in g_registered_type array - // i.e., the value returned by find_type_index() -} handler_record_t; - -/* Info Package handler registry */ -static sll_handle_t s_handler_registry = NULL; - -#define INDEX_NOT_FOUND ((unsigned int)-1) - -/* - * g_registered_info[] contains the Info Package strings (such as - * "conference") for the registered handlers. - */ -char *g_registered_info[MAX_INFO_HANDLER]; - -static char *s_registered_type[MAX_INFO_HANDLER]; - -static sll_match_e is_matching_type(void *find_by_p, void *data_p); -static info_index_t find_info_index(const char *info_package); -static info_index_t find_next_available_info_index(void); -static type_index_t find_type_index(const char *type_package); -static type_index_t find_next_available_type_index(void); -static handler_record_t *find_handler_record(info_index_t info_index, - type_index_t type_index); -static boolean is_info_package_registered(info_index_t info_index); -static boolean is_content_type_registered(type_index_t type_index); -static void update_recv_info_list(const char *header_field_value, - string_t *info_packages); -static void media_control_info_package_handler(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body); -#ifdef _CONF_ROSTER_ -static void conf_info_package_handler(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body); -#endif - - - -/* - * Function: find_info_index - * - * Parameters: - * info_package - the Info Package to find - * - * Description: - * Finds the Info Package in g_registered_info array. - * - * Return: - * info_index_t - the index of the Info Package in the array - * INDEX_NOT_FOUND - the Info Package was not found in the array - */ -static info_index_t -find_info_index(const char *info_package) -{ - info_index_t info_index; - - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - if (g_registered_info[info_index] && - httpish_strncasecmp(info_package, - g_registered_info[info_index], - strlen(g_registered_info[info_index])) == 0) { - return info_index; - } - } - - return INDEX_NOT_FOUND; -} - -/* - * Function: find_next_available_info_index - * - * Parameters: - * None - * - * Description: - * Finds an empty slot in g_registered_info array. - * - * Return: - * info_index_t - the index of the empty slot in the array - * INDEX_NOT_FOUND - the array is full - */ -static info_index_t -find_next_available_info_index(void) -{ - info_index_t info_index; - - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - if (g_registered_info[info_index] == NULL) { - return info_index; - } - } - - return INDEX_NOT_FOUND; -} - -/* - * Function: find_type_index - * - * Parameters: - * content_type - the Content Type to find - * - * Description: - * Finds the Content Type in s_registered_type array. - * - * Return: - * type_index_t - the index of the Content Type in the array - * INDEX_NOT_FOUND - the Content Type was not found in the array - */ -static type_index_t -find_type_index(const char *content_type) -{ - type_index_t type_index; - - for (type_index = 0; type_index < MAX_INFO_HANDLER; type_index++) { - if (s_registered_type[type_index] && - httpish_strncasecmp(content_type, - s_registered_type[type_index], - strlen(s_registered_type[type_index])) == 0) { - return type_index; - } - } - - return INDEX_NOT_FOUND; -} - -/* - * Function: find_next_available_type_index - * - * Parameters: - * None - * - * Description: - * Finds an empty slot in s_registered_type array. - * - * Return: - * type_index_t - the index of the empty slot in the array - * INDEX_NOT_FOUND - the array is full - */ -static type_index_t -find_next_available_type_index(void) -{ - type_index_t type_index; - - for (type_index = 0; type_index < MAX_INFO_HANDLER; type_index++) { - if (s_registered_type[type_index] == NULL) { - return type_index; - } - } - - return INDEX_NOT_FOUND; -} - -/* - * Function: is_matching_type - * - * Parameters: - * find_by_p - searching criteria - * data_p - a node - * - * Description: - * Checks to see if the node matches the searching criteria. - * - * Return: - * SLL_MATCH_FOUND - the node is a match - * SLL_MATCH_NOT_FOUND - the node is not a match - */ -static sll_match_e -is_matching_type(void *find_by_p, void *data_p) -{ - handler_record_t *tuple = (handler_record_t *)find_by_p; - handler_record_t *node = (handler_record_t *)data_p; - - if ((node->info_index == tuple->info_index) && - (node->type_index == tuple->type_index)) { - return SLL_MATCH_FOUND; - } - return SLL_MATCH_NOT_FOUND; -} - -/* - * Function: find_handler_record - * - * Parameters: - * info_index - the index of the Info Package in g_registered_info array - * type_index - the index of the Content Type in s_registered_type array - * - * Description: - * Finds the Info Package handler registered for the Info Package/Content - * Type pair. - * - * Return: - * handler_record_t * - the registered handler record - * NULL - otherwise - */ -static handler_record_t * -find_handler_record(info_index_t info_index, type_index_t type_index) -{ - handler_record_t tuple; - - tuple.info_index = info_index; - tuple.type_index = type_index; - - return (handler_record_t *)sll_find(s_handler_registry, &tuple); -} - -/* - * Function: is_info_package_registered - * - * Parameters: - * info_index - the index of the Info Package in g_registered_info array - * - * Description: - * Checks to see if a handler was registered for the Info Package. - * - * Return: - * TRUE - a handler was registered for the Info Package - * FALSE - otherwise - */ -static boolean -is_info_package_registered(info_index_t info_index) -{ - handler_record_t *record; - - for (record = (handler_record_t *)sll_next(s_handler_registry, NULL); - record != NULL; - record = (handler_record_t *)sll_next(s_handler_registry, record)) { - if (record->info_index == info_index) { - return TRUE; - } - } - - return FALSE; -} - -/* - * Function: is_content_type_registered - * - * Parameters: - * type_index - the index of the Content Type in s_registered_type array - * - * Description: - * Checks to see if a handler was registered for the Content Type. - * - * Return: - * TRUE - a handler was registered for the Content Type - * FALSE - otherwise - */ -static boolean -is_content_type_registered(type_index_t type_index) -{ - handler_record_t *record; - - for (record = (handler_record_t *)sll_next(s_handler_registry, NULL); - record != NULL; - record = (handler_record_t *)sll_next(s_handler_registry, record)) { - if (record->type_index == type_index) { - return TRUE; - } - } - - return FALSE; -} - -/* - * Function: ccsip_register_info_package_handler - * - * Parameters: - * info_package - the Info Package for the handler - * content_type - the Content Type for the handler - * handler - the handler - * - * Description: - * Registers the handler for the Info Package/Content Type pair. - * - * Return: - * SIP_OK - the handler was registered successfully - * SIP_ERROR - otherwise - */ -int -ccsip_register_info_package_handler(const char *info_package, - const char *content_type, - info_package_handler_t handler) -{ - static const char *fname = "ccsip_register_info_package_handler"; - info_index_t info_index; - type_index_t type_index; - char *tmp_info = NULL; - char *tmp_type = NULL; - handler_record_t *record; - - if (s_handler_registry == NULL) { - CCSIP_DEBUG_TASK("%s: Info Package handler was not initialized\n", fname); - return SIP_ERROR; - } - - if ((info_package == NULL) || (content_type == NULL) || (handler == NULL)) { - CCSIP_DEBUG_ERROR("%s: invalid parameter\n", fname); - return SIP_ERROR; - } - - /* Find the info_index for the info_package */ - info_index = find_info_index(info_package); - - if (info_index == INDEX_NOT_FOUND) { - /* Find the first available slot */ - info_index = find_next_available_info_index(); - - if (info_index == INDEX_NOT_FOUND) { - CCSIP_DEBUG_ERROR("%s: maximum reached\n", fname); - return SIP_ERROR; - } - - tmp_info = cpr_strdup(info_package); - if (tmp_info == NULL) { - CCSIP_DEBUG_ERROR("%s: failed to duplicate info_package string\n", fname); - return SIP_ERROR; - } - } - - /* Find the type_index for the content_type */ - type_index = find_type_index(content_type); - - if (type_index == INDEX_NOT_FOUND) { - /* Find the first available slot */ - type_index = find_next_available_type_index(); - - if (type_index == INDEX_NOT_FOUND) { - CCSIP_DEBUG_ERROR("%s: maximum reached\n", fname); - if (tmp_info != NULL) { - cpr_free(tmp_info); - } - return SIP_ERROR; - } - - tmp_type = cpr_strdup(content_type); - if (tmp_type == NULL) { - CCSIP_DEBUG_ERROR("%s: failed to duplicate info_package string\n", fname); - if (tmp_info != NULL) { - cpr_free(tmp_info); - } - return SIP_ERROR; - } - } - - /* Check to see if the info/type tuple has been registered before */ - if (find_handler_record(info_index, type_index) != NULL) { - CCSIP_DEBUG_ERROR("%s: Info Package handler already registered\n", fname); - return SIP_ERROR; - } - - /* - * At this point, info_index points to the slot in g_registered_info where - * either: - * - * 1) the info_package is residing, or - * 2) the info_package (a copy of which is pointed to by *tmp_info) will be - * copied to before the function returns - * - * type_index is similar. - */ - - record = (handler_record_t *)cpr_malloc(sizeof(handler_record_t)); - if (record == NULL) { - if (tmp_type != NULL) { - cpr_free(tmp_type); - } - if (tmp_info != NULL) { - cpr_free(tmp_info); - } - CCSIP_DEBUG_ERROR("%s: failed to allocate info handler record\n", fname); - return SIP_ERROR; - } - - record->handler = handler; - record->info_index = info_index; - record->type_index = type_index; - - if (sll_append(s_handler_registry, record) != SLL_RET_SUCCESS) { - cpr_free(record); - if (tmp_type != NULL) { - cpr_free(tmp_type); - } - if (tmp_info != NULL) { - cpr_free(tmp_info); - } - CCSIP_DEBUG_ERROR("%s: failed to insert to the registry\n", fname); - return SIP_ERROR; - } - - if (tmp_info != NULL) { - g_registered_info[info_index] = tmp_info; - } - if (tmp_type != NULL) { - s_registered_type[type_index] = tmp_type; - } - - return SIP_OK; -} - -/* - * Function: ccsip_deregister_info_package_handler - * - * Parameters: - * info_package - the Info Package for the handler - * content_type - the Content Type for the handler - * handler - the handler - * - * Description: - * Deregisters the handler for the Info Package/Content Type pair. - * - * Return: - * SIP_OK - the handler was registered successfully - * SIP_ERROR - otherwise - */ -int -ccsip_deregister_info_package_handler(const char *info_package, - const char *content_type, - info_package_handler_t handler) -{ - static const char *fname = "ccsip_deregister_info_package_handler"; - info_index_t info_index; - type_index_t type_index; - handler_record_t *record; - - if (s_handler_registry == NULL) { - CCSIP_DEBUG_TASK("%s: Info Package handler was not initialized\n", fname); - return SIP_ERROR; - } - - /* Find the info_index for the info_package */ - info_index = find_info_index(info_package); - if (info_index == INDEX_NOT_FOUND) { - CCSIP_DEBUG_ERROR("%s: handler was not registered (%s)\n", - fname, info_package); - return SIP_ERROR; - } - - /* Find the type_index for the content_type */ - type_index = find_type_index(content_type); - if (type_index == INDEX_NOT_FOUND) { - CCSIP_DEBUG_ERROR("%s: handler was not registered (%s)\n", - fname, content_type); - return SIP_ERROR; - } - - /* Find the handler record */ - record = find_handler_record(info_index, type_index); - if ((record == NULL) || (record->handler != handler)) { - CCSIP_DEBUG_ERROR("%s: handler was not registered (%p)\n", - fname, handler); - return SIP_ERROR; - } - - (void)sll_remove(s_handler_registry, record); - - cpr_free(record); - - if (!is_info_package_registered(info_index)) { - /* The info_package was not found in the registry, meaning we're - * the last one who registered for this particular info_package */ - cpr_free(g_registered_info[info_index]); - g_registered_info[info_index] = NULL; - } - - if (!is_content_type_registered(type_index)) { - /* The content_type was not found in the registry, meaning we're - * the last one who registered for this particular content_type */ - cpr_free(s_registered_type[type_index]); - s_registered_type[type_index] = NULL; - } - - return SIP_OK; -} - -/* - * Function: update_recv_info_list - * - * Parameters: - * header_field_value - the header field value to match (e.g., - * "conference") - * info_packages - the Info Packages string to append the header - * field value to - * - * Description: - * Checks to see if a handler is registered for the header field value - * (e.g., "conference"), if so, append the header field value to - * the end of info_packages. - * - * Returns: - * None - */ -static void -update_recv_info_list(const char *header_field_value, string_t *info_packages) -{ - static const char *fname = "update_recv_info_list"; - info_index_t info_index; - - if ((header_field_value == NULL) || (info_packages == NULL) || - (*info_packages == NULL)) { - CCSIP_DEBUG_ERROR("%s: invalid parameter\n", fname); - return; - } - - info_index = find_info_index(header_field_value); - if (info_index != INDEX_NOT_FOUND) { - /* Info-Package is supported */ - if (**info_packages == '\0') { - *info_packages = strlib_update(*info_packages, - g_registered_info[info_index]); - } else { - *info_packages = strlib_append(*info_packages, ", "); - *info_packages = strlib_append(*info_packages, - g_registered_info[info_index]); - } - } -} - -/* - * Function: ccsip_parse_send_info_header - * - * Parameters: - * ccb - the SIP CCB - * pSipMessage - the SIP message - * - * Description: - * Checks the Send-Info header (if exists) to see if a handler was - * registered for the Info Package. If so, append the Info Package - * to the end of recv_info_list. - * - * Returns: - * None - */ -void -ccsip_parse_send_info_header(sipMessage_t *pSipMessage, string_t *recv_info_list) -{ - char *send_info[MAX_INFO_HANDLER]; - int count; - int i; - char *header_field_values; - char *header_field_value; - char *separator; - - // leading white spaces are trimmed, but not trailing ones - count = sippmh_get_num_particular_headers(pSipMessage, - SIP_HEADER_SEND_INFO, - NULL, - send_info, - MAX_INFO_HANDLER); - - if (count == 0) { - return; - } - - for (i = 0; (i < count) && (i < MAX_INFO_HANDLER); i++) { - header_field_values = cpr_strdup(send_info[i]); - if (header_field_values == NULL) { - return; - } - header_field_value = header_field_values; - - while ((separator = strchr(header_field_value, COMMA)) != NULL) { - *separator++ = '\0'; - update_recv_info_list(header_field_value, recv_info_list); - header_field_value = separator; - SKIP_WHITE_SPACE(header_field_value); - } - update_recv_info_list(header_field_value, recv_info_list); - - cpr_free(header_field_values); - } -} - -/* - * Function: ccsip_handle_info_package - * - * Parameters: - * ccb - the SIP CCB - * pSipMessage - the SIP message - * - * Description: - * Handles an incoming unsolicited Info Package message. - * XXX Currently this function only handles the first part in a - * multi-part Info Package message. - * - * Return: - * SIP_OK - if request processed. - * SIP_ERROR - if there is error - */ -int -ccsip_handle_info_package(ccsipCCB_t *ccb, sipMessage_t *pSipMessage) -{ - static const char *fname = "ccsip_handle_info_package"; - const char *info_package; - const char *content_type; - info_index_t info_index; - type_index_t type_index; - handler_record_t *record; - uint16_t status_code; - const char *reason_phrase; - int return_code = SIP_ERROR; - - /* FIXME Media Control currently does not follow the IETF draft - draft-ietf-sip-info-events-01, so short-circuit here and - bypass all the Info Package related stuff below. */ - // leading white spaces are trimmed, but not trailing ones - content_type = sippmh_get_cached_header_val(pSipMessage, - CONTENT_TYPE); - if (content_type && - httpish_strncasecmp(content_type, - SIP_CONTENT_TYPE_MEDIA_CONTROL, - strlen(SIP_CONTENT_TYPE_MEDIA_CONTROL)) == 0) { - - media_control_info_package_handler(ccb->dn_line, ccb->gsm_id, - "", // legacy mode, no Info Package - SIP_CONTENT_TYPE_MEDIA_CONTROL, - pSipMessage->mesg_body[0].msgBody); - - if (sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP_PHRASE); - return SIP_ERROR; - } - - return SIP_OK; - } - - /* - * Parse the Info-Package header - */ - // leading white spaces are trimmed, but not trailing ones - info_package = sippmh_get_header_val(pSipMessage, - SIP_HEADER_INFO_PACKAGE, - NULL); - - if (info_package == NULL) { - /* No Info-Package header */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Missing Info-Package header\n", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - - if (pSipMessage->num_body_parts == 0) { - /* No Info-Package header, and no body poarts */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Missing message body\n", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - /* Send 200 OK for legacy UA support */ - status_code = 200; - reason_phrase = SIP_SUCCESS_SETUP_PHRASE; - return_code = SIP_OK; - } else { - /* No Info-Package header, but with body part(s) */ - if (pSipMessage->num_body_parts > 1) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Multipart Info Package" - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - } - - type_index = find_type_index(pSipMessage->mesg_body[0].msgContentType); - if (type_index == INDEX_NOT_FOUND) { - /* No Info-Package header, and Content-Type is not supported */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unsupported Content Type\n", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - /* Send 415 Unsupported Media Type */ - status_code = SIP_CLI_ERR_MEDIA; - reason_phrase = SIP_CLI_ERR_MEDIA_PHRASE; - } else { - /* No Info-Package header, but Conent-Type is supported */ - /* Send 200 OK for legacy UA support */ - status_code = 200; - reason_phrase = SIP_SUCCESS_SETUP_PHRASE; - return_code = SIP_OK; - } - } - } else { - /* With Info-Package header */ - if (pSipMessage->num_body_parts == 0) { - /* With Info-Package header, but no body parts */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Missing message body\n", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - - /* ? */ - /* Send 489 Bad Event */ - status_code = SIP_CLI_ERR_BAD_EVENT; - reason_phrase = SIP_CLI_ERR_BAD_EVENT_PHRASE; - - } else { - /* With Info-Package header and body part(s) */ - if (pSipMessage->num_body_parts > 1) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Multipart Info Package " - "(only the first part is processed)\n", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - } - - info_index = find_info_index(info_package); - if (info_index == INDEX_NOT_FOUND) { - /* Info-Package is not supported */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unsupported Info Package\n", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - - /* Send 489 Bad Event */ - status_code = SIP_CLI_ERR_BAD_EVENT; - reason_phrase = SIP_CLI_ERR_BAD_EVENT_PHRASE; - - } else { - /* Info-Package is supported */ - type_index = find_type_index(pSipMessage->mesg_body[0].msgContentType); - record = find_handler_record(info_index, type_index); - if (record == NULL) { - /* Info-Package header is supported, but Content-Type is not */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unsupported Content Type\n", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname)); - /* Send 415 Unsupported Media Type */ - status_code = SIP_CLI_ERR_MEDIA; - reason_phrase = SIP_CLI_ERR_MEDIA_PHRASE; - } else { - /* a handler is registered */ - (*record->handler)(ccb->dn_line, ccb->gsm_id, - g_registered_info[record->info_index], - s_registered_type[record->type_index], - pSipMessage->mesg_body[0].msgBody); - /* Send 200 OK */ - status_code = 200; - reason_phrase = SIP_SUCCESS_SETUP_PHRASE; - return_code = SIP_OK; - } - } - } - } - - if (sipSPISendErrorResponse(pSipMessage, status_code, reason_phrase, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, reason_phrase); - return SIP_ERROR; - } - - return return_code; -} - -static void -media_control_info_package_handler(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body) -{ -} - -#ifdef _CONF_ROSTER_ -static void -conf_info_package_handler(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body) -{ - static const char *fname = "conf_info_package_handler"; - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"info_package: %s content_type: %s\n", - DEB_F_PREFIX_ARGS(SIP_INFO_PACKAGE, fname), - info_package, content_type); - - ui_info_received(line, lsm_get_ui_id(call_id), info_package, content_type, - message_body); -} -#endif - -/* - * Function: ccsip_info_package_handler_init - * - * Parameters: - * None - * - * Description: - * Initializes the Info Package handler framework. - * - * Return: - * SIP_OK - Info Package handler framework initialized successfully - * SIP_ERROR - otherwise - */ -int -ccsip_info_package_handler_init(void) -{ - static const char *fname = "ccsip_info_package_handler_init"; - info_index_t info_index; - type_index_t type_index; - - if (s_handler_registry != NULL) { - // Is this considered an error? - CCSIP_DEBUG_TASK("%s: Info Package handler already initialized\n", fname); - return SIP_OK; - } - - /* Create the SLL */ - s_handler_registry = sll_create(is_matching_type); - if (s_handler_registry == NULL) { - CCSIP_DEBUG_ERROR("%s: failed to create the registry\n", fname); - return SIP_ERROR; - } - - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - g_registered_info[info_index] = NULL; - } - - for (type_index = 0; type_index < MAX_INFO_HANDLER; type_index++) { - s_registered_type[type_index] = NULL; - } - - // XXX Where is the best place to register the application-specific handler? -#ifdef _CONF_ROSTER_ - /* Register the handler for conference & x-cisco-conference Info Packages */ - ccsip_register_info_package_handler(INFO_PACKAGE_CONFERENCE, - CONTENT_TYPE_CONFERENCE_INFO, - conf_info_package_handler); - ccsip_register_info_package_handler(INFO_PACKAGE_CISCO_CONFERENCE, - CONTENT_TYPE_CONFERENCE_INFO, - conf_info_package_handler); -#endif - return SIP_OK; -} - -/* - * Function: ccsip_info_package_handler_shutdown - * - * Parameters: - * None - * - * Description: - * Shuts down the Info Package handler framework. - * - * Return: - * None - */ -void -ccsip_info_package_handler_shutdown(void) -{ - static const char *fname = "ccsip_info_package_handler_shutdown"; - info_index_t info_index; - type_index_t type_index; - handler_record_t *record; - - if (s_handler_registry == NULL) { - // Is this considered an error? - CCSIP_DEBUG_TASK("%s: Info Package handler was not initialized\n", fname); - return; - } - - for (type_index = 0; type_index < MAX_INFO_HANDLER; type_index++) { - if (s_registered_type[type_index] != NULL) { - cpr_free(s_registered_type[type_index]); - s_registered_type[type_index] = NULL; - } - } - - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - if (g_registered_info[info_index] != NULL) { - cpr_free(g_registered_info[info_index]); - g_registered_info[info_index] = NULL; - } - } - - /* Deregister each Info Package handler */ - for (record = (handler_record_t *)sll_next(s_handler_registry, NULL); - record != NULL; - record = (handler_record_t *)sll_next(s_handler_registry, record)) { - cpr_free(record); - } - - /* Destroy the SLL */ - sll_destroy(s_handler_registry); - s_handler_registry = NULL; -} diff --git a/libs/sipcc/core/sipstack/ccsip_messaging.c b/libs/sipcc/core/sipstack/ccsip_messaging.c deleted file mode 100644 index d9a79651e9..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_messaging.c +++ /dev/null @@ -1,7639 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include "cpr_types.h" -#include "cpr_time.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_in.h" -#include "cpr_rand.h" -#include "phntask.h" -#include "text_strings.h" -#include "util_string.h" -#include "ccsip_core.h" -#include "ccsip_macros.h" -#include "ccsip_messaging.h" -#include "ccsip_platform.h" -#include "ccsip_task.h" -#include "prot_configmgr.h" -#include "phone_debug.h" -#include "ccsip_reldev.h" -#include "digcalc.h" -#include "ccsip_register.h" -#include "ccsip_credentials.h" -#include "dns_utils.h" -#include "config.h" -#include "string_lib.h" -#include "dialplan.h" -#include "rtp_defs.h" -#include "ccapi.h" -#include "ccsip_platform_udp.h" -#include "ccsip_task.h" -#include "sdp.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "uiapi.h" -#include "ccsip_callinfo.h" -#include "sip_interface_regmgr.h" -#include "ccsip_spi_utils.h" -#include "ccsip_subsmanager.h" -#include "subapi.h" -#include "platform_api.h" - -#define SIPS_URL_LEN 8 -#define NONCE_LEN 9 -#define SUBS_STATE_HDR_LEN 80 -#define MAX_EXPIRES_LEN 12 -#define MAX_ESCAPED_USER_LEN 94 // Worst case all 31 chars require escaping (3 chars) + a NULL -#define MAX_PHONE_NAME_LEN 20 -#define MAX_UNREG_REASON_STR_LEN 256 - -#define MAX_ESCAPED_USER_LEN 94 // Worst case all 31 chars require escaping (3 chars) + a NULL -#define INITIAL_BUFFER_SIZE 2048 - - -/* External declarations */ -extern int dns_error_code; // DNS error code global -extern sipPlatformUITimer_t sipPlatformUISMTimers[]; -extern sipCallHistory_t gCallHistory[]; -extern ccsipGlobInfo_t gGlobInfo; -extern int16_t clockIsSetup; -extern struct tm *gmtime_r(const time_t *, struct tm *); -extern char *Basic_is_phone_forwarded(line_t line); -extern uint16_t server_caps; -extern char sipPhoneModelNumber[]; -extern char phone_load_name[]; -extern sipGlobal_t sip; -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; - -/* Forward declarations */ -boolean sipSPIAddRequestRecordRoute(sipMessage_t *, sipMessage_t *); -static boolean sendResponse(ccsipCCB_t *ccb, sipMessage_t *response, - sipMessage_t *refrequest, boolean retx, - sipMethod_t method); -static sipRet_t CopyLocalSDPintoResponse(sipMessage_t *request, - cc_msgbody_info_t *local_msg_body); - -#if defined SIP_OS_WINDOWS -#define debugif_printf printf -#endif -/* - * Functions to manipulate transaction blocks - */ - -/* - * This function gets the index of the last request sent or received - * It determines this by choosing the last one that has a - * non CCSIP_START_CSEQ cseq value - */ -int16_t -get_last_request_trx_index (ccsipCCB_t *ccb, boolean sent) -{ - const char *fname = "get_last_request_trx_index"; - int16_t i; - - if (ccb == NULL) { - return -1; - } - - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Getting last TRX index, sent = %d\n", DEB_F_PREFIX_ARGS(SIP_TRX, fname), sent); - - if (sent) { - for (i = MAX_REQ_OUTSTANDING - 1; i >= 0; i--) { - if (ccb->sent_request[i].cseq_number != CCSIP_START_CSEQ) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for sent req\n", DEB_F_PREFIX_ARGS(SIP_TRX, fname), i); - return i; - } - } - } else { - for (i = MAX_REQ_OUTSTANDING - 1; i >= 0; i--) { - if (ccb->recv_request[i].cseq_number != CCSIP_START_CSEQ) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for recv req\n", DEB_F_PREFIX_ARGS(SIP_TRX, fname), i); - return i; - } - } - } - return -1; -} - -/* - * This function gets the next cseq index that can be used to send - * a request. It determines this by choosing the next available - * cseq index - */ -int16_t -get_next_request_trx_index (ccsipCCB_t *ccb, boolean sent) -{ - const char *fname = "get_next_request_trx_index"; - int16_t i; - - if (ccb == NULL) { - return -1; - } - - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Getting next TRX index, sent = %d\n", DEB_F_PREFIX_ARGS(SIP_TRX, fname), sent); - if (sent) { - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - if (ccb->sent_request[i].cseq_number == CCSIP_START_CSEQ) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for sent req\n", DEB_F_PREFIX_ARGS(SIP_TRX, fname), i); - return i; - } - } - } else { - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - if (ccb->recv_request[i].cseq_number == CCSIP_START_CSEQ) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for recv req\n", DEB_F_PREFIX_ARGS(SIP_TRX, fname), i); - return i; - } - } - } - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Unable to get any open TRX!!\n", DEB_F_PREFIX_ARGS(SIP_TRX, fname)); - return -1; -} - -/* - * This function gets the index corresponding to a specific method - */ -int16_t -get_method_request_trx_index (ccsipCCB_t *ccb, sipMethod_t method, boolean sent) -{ - const char *fname = "get_method_request_trx_index"; - int16_t i; - - if (ccb == NULL) { - return -1; - } - - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Getting TRX for method(%s), sent = %d\n", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), sipGetMethodString(method), sent); - - if (sent) { - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - if (ccb->sent_request[i].cseq_method == method) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for sent method(%s)\n", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), i, sipGetMethodString(method)); - return i; - } - } - } else { - for (i = 0; i < MAX_REQ_OUTSTANDING; i++) { - if (ccb->recv_request[i].cseq_method == method) { - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Got TRX(%d) for recv method(%s)\n", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), i, sipGetMethodString(method)); - return i; - } - } - } - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Unable to find any TRX for method!!\n", DEB_F_PREFIX_ARGS(SIP_TRX, fname)); - return -1; -} - -/* - * This function cleans the CSeq array and removes the entry - * corresponding to the method and compacts the array - */ -void -clean_method_request_trx (ccsipCCB_t *ccb, sipMethod_t method, boolean sent) -{ - const char *fname = "clean_method_request_trx"; - uint8_t i, j, k; - boolean found = FALSE; - sipTransaction_t *transactionp = NULL; - - if (ccb == NULL) { - return; - } - - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Removing TRX for method(%s), sent = %d\n", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), sipGetMethodString(method), sent); - - if (sent) { - transactionp = &(ccb->sent_request[0]); - } else { - transactionp = &(ccb->recv_request[0]); - } - - for (i = 0; i < MAX_REQ_OUTSTANDING && !found; i++) { - if (transactionp[i].cseq_method == method) { - transactionp[i].cseq_method = sipMethodInvalid; - transactionp[i].cseq_number = CCSIP_START_CSEQ; - strlib_free(transactionp[i].u.sip_via_header); - strlib_free(transactionp[i].sip_via_sentby); - CCSIP_DEBUG_TRX(DEB_F_PREFIX"Removed TRX(%d) for method(%s)\n", - DEB_F_PREFIX_ARGS(SIP_TRX, fname), i, sipGetMethodString(method)); - found = TRUE; - } - if (found) { - k = i; - for (j = k + 1; j < MAX_REQ_OUTSTANDING; j++, k++) { - memcpy(&(transactionp[k]), &(transactionp[j]), - sizeof(sipTransaction_t)); - } - // re-init the last transaction - transactionp[MAX_REQ_OUTSTANDING - 1].cseq_method = - sipMethodInvalid; - transactionp[MAX_REQ_OUTSTANDING - 1].cseq_number = - CCSIP_START_CSEQ; - transactionp[MAX_REQ_OUTSTANDING - 1].u.sip_via_header = - strlib_empty(); - transactionp[MAX_REQ_OUTSTANDING - 1].sip_via_sentby = - strlib_empty(); - } - } -} - -line_t -get_dn_line_from_dn (const char *watcher) -{ - line_t dn_line; - char line_name[CC_MAX_DIALSTRING_LEN]; - - for (dn_line = 1; dn_line <= MAX_REG_LINES; dn_line++) { - config_get_line_string(CFGID_LINE_NAME, line_name, (int) dn_line, - sizeof(line_name)); - if (!cpr_strcasecmp(watcher, line_name)) { - break; - } - } - return dn_line; -} - -boolean -validateHostName (char *str, char *dn) -{ - line_t dn_line = (line_t) -1; - char buffer[MAX_SIP_URL_LENGTH]; - char ccm1_addr[MAX_SIP_URL_LENGTH]; - char ccm2_addr[MAX_SIP_URL_LENGTH]; - char ccm3_addr[MAX_SIP_URL_LENGTH]; - - dn_line = get_dn_line_from_dn(dn); - if (dn_line >= 1 && dn_line <= MAX_REG_LINES) { - if (sip_regmgr_get_cc_mode(dn_line) == REG_MODE_NON_CCM) { - config_get_line_string(CFGID_PROXY_ADDRESS, buffer, dn_line, - MAX_SIP_URL_LENGTH); - if (!strncmp(buffer, str, MAX_SIP_URL_LENGTH)) { - return (TRUE); - } else { - return (FALSE); - } - } else { - config_get_string(CFGID_CCM1_ADDRESS, ccm1_addr, - MAX_SIP_URL_LENGTH); - config_get_string(CFGID_CCM2_ADDRESS, ccm2_addr, - MAX_SIP_URL_LENGTH); - config_get_string(CFGID_CCM3_ADDRESS, ccm3_addr, - MAX_SIP_URL_LENGTH); - - if (!strncmp(ccm1_addr, str, MAX_SIP_URL_LENGTH) || - !strncmp(ccm2_addr, str, MAX_SIP_URL_LENGTH) || - !strncmp(ccm3_addr, str, MAX_SIP_URL_LENGTH)) { - return (TRUE); - } else { - return (FALSE); - } - } - } - - return (FALSE); -} - -/************************************************************* - * Function: sipGetSupportedOptionList - * This function returns the list of the supported option tags. - * The function may returns NULL pointer for the case that - * there is no tag to add. - **************************************************************/ -static const char * -sipGetSupportedOptionList (ccsipCCB_t *ccb, sipMethod_t sipmethod) -{ - return (SIP_CISCO_SUPPORTED_REG_TAGS); -} - -/* - * Send REGISTER - * - * Send a SIP REGISTER request. - * Assumes that - * - connection has been setup beforehand. - */ -boolean -sipSPISendRegister (ccsipCCB_t *ccb, - boolean no_dns_lookup, - const char *user, - int expires_int) -{ - const char fname[] = "SIPSPISendRegister"; - sipMessage_t *request = NULL; - char obp_address[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t ipaddr; - boolean obp_present = FALSE; - boolean send_result = FALSE; - - CPR_IP_ADDR_INIT(ipaddr); - - if (!(request = sipSPIBuildRegisterHeaders(ccb, user, expires_int))) { - CCSIP_DEBUG_ERROR("%s: Error: Building Register Headers.\n", - fname); - return (send_result); - } - - /* - * If we are being called as a result of a 4xx message we need to - * respond to the same proxy which sent us the 4xx message so use - * the previous ccb->reg.addr to send to. - */ - config_get_string(CFGID_OUTBOUND_PROXY, obp_address, sizeof(obp_address)); - if ((cpr_strcasecmp(obp_address, UNPROVISIONED) != 0) && - (obp_address[0] != 0) && - (obp_address[0] != '0')) { - obp_present = TRUE; - } - if ((!no_dns_lookup) && - ((obp_present == FALSE) || ((ccb->index == REG_BACKUP_CCB)))) { - /* See if DNS SRV record is available */ - dns_error_code = sipTransportGetServerAddrPort(ccb->reg.proxy, &ipaddr, - (uint16_t *)&ccb->reg.port, - &ccb->SRVhandle, FALSE); - if (dns_error_code == 0) { - /* - * Found an SRV record. Use that address. If there is more - * than one record in SRV response, setup to try all the - * servers in the list - */ - util_ntohl(&(ccb->reg.addr), &ipaddr); - } else { - /* Do a DNS A record lookup on the proxy */ - dns_error_code = dnsGetHostByName(ccb->reg.proxy, &ipaddr, 100, 1); - if (dns_error_code == 0) { - util_ntohl(&ipaddr, &ipaddr); - ccb->reg.addr = ipaddr; - } else { - ccb->reg.addr = ip_addr_invalid; - } - - } - } - - /* If we failed to get a valid IP address for the proxy - * do not broadcast the REGISTER message, but bail instead. - */ - if ((util_check_if_ip_valid(&(ccb->reg.addr))) || obp_present) { - send_result = SendRequest(ccb, request, sipMethodRegister, - FALSE, TRUE, FALSE); - } else { - err_msg("%s: Unable to retrieve address of proxy.\n", fname); - free_sip_message(request); - } - - if (!send_result) { - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - } - return (send_result); -} - -char * -cc2siptype (cc_content_type_t type) -{ - switch (type) { - default: - case cc_content_type_unknown: - return SIP_CONTENT_TYPE_UNKNOWN; - case cc_content_type_SDP: - return SIP_CONTENT_TYPE_SDP; - case cc_content_type_CMXML: - return SIP_CONTENT_TYPE_CMXML; - case cc_content_type_sipfrag: - return SIP_CONTENT_TYPE_SIPFRAG; - } -} - -cc_content_type_t -sip2cctype (uint8_t type) -{ - switch (type) { - default: - case SIP_CONTENT_TYPE_UNKNOWN_VALUE: - return cc_content_type_unknown; - case SIP_CONTENT_TYPE_SDP_VALUE: - return cc_content_type_SDP; - case SIP_CONTENT_TYPE_CMXML_VALUE: - return cc_content_type_CMXML; - case SIP_CONTENT_TYPE_SIPFRAG_VALUE: - return cc_content_type_sipfrag; - } -} - -uint8_t -cc2sipdisp (cc_disposition_type_t type) -{ - switch (type) { - default: - case cc_disposition_unknown: - return SIP_CONTENT_DISPOSITION_UNKNOWN_VALUE; - case cc_disposition_render: - return SIP_CONTENT_DISPOSITION_RENDER_VALUE; - case cc_disposition_session: - return SIP_CONTENT_DISPOSITION_SESSION_VALUE; - case cc_dispostion_icon: - return SIP_CONTENT_DISPOSITION_ICON_VALUE; - case cc_disposition_alert: - return SIP_CONTENT_DISPOSITION_ALERT_VALUE; - case cc_disposition_precondition: - return SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE; - } -} - -cc_disposition_type_t -sip2ccdisp (uint8_t type) -{ - switch (type) { - default: - case SIP_CONTENT_DISPOSITION_UNKNOWN_VALUE: - return cc_disposition_unknown; - case SIP_CONTENT_DISPOSITION_RENDER_VALUE: - return cc_disposition_render; - case SIP_CONTENT_DISPOSITION_SESSION_VALUE: - return cc_disposition_session; - case SIP_CONTENT_DISPOSITION_ICON_VALUE: - return cc_dispostion_icon; - case SIP_CONTENT_DISPOSITION_ALERT_VALUE: - return cc_disposition_alert; - case SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE: - return cc_disposition_precondition; - } -} - - -static boolean -sipSPIIsPrivate (ccsipCCB_t *ccb) -{ - int blocking; - boolean private_flag = FALSE; - - /* - * If Caller ID Blocking is OFF or emergency route is ON, - * display the actual name. Otherwise, display "Anonymous". - */ - config_get_value(CFGID_CALLERID_BLOCKING, &blocking, sizeof(blocking)); - if ((blocking & 1) && (ccb->routeMode != RouteEmergency)) { - private_flag = TRUE; - } - return private_flag; -} - -/* - * sipSPISetRPID - * - * Set the RPID header string sent in either a request or response. - */ - -static int -sipSPISetRPID (ccsipCCB_t *ccb, boolean request) -{ - const char *fname = "sipSPISetRPID"; - int rpid_flag = RPID_DISABLED; - boolean private_flag; - size_t escaped_url_len; - char remote_party_id_buf[MAX_SIP_URL_LENGTH]; - char line_name[MAX_LINE_NAME_SIZE]; - char display_name[MAX_LINE_NAME_SIZE]; - char src_addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_type ip_type; - - src_addr_str[0] = '\0'; - config_get_value(CFGID_REMOTE_PARTY_ID, &rpid_flag, sizeof(rpid_flag)); - - if (rpid_flag != RPID_ENABLED) { - return RPID_DISABLED; - } - - if (!ccb) { - CCSIP_DEBUG_ERROR("%s: Error: NULL ccb.\n", fname); - return rpid_flag; - } - - /* If RPID string is already set, just return */ - if (ccb->sip_remote_party_id[0]) { - return RPID_ENABLED; - } - - private_flag = sipSPIIsPrivate(ccb); - - config_get_string((CFGID_LINE_NAME + ccb->dn_line - 1), line_name, - sizeof(line_name)); - sip_config_get_display_name(ccb->dn_line, display_name, - sizeof(display_name)); - - ip_type = sipTransportGetPrimServerAddress(ccb->dn_line, src_addr_str); - - sstrncpy(remote_party_id_buf, "\"", MAX_SIP_URL_LENGTH); - escaped_url_len = 1; - escaped_url_len += - sippmh_converQuotedStrToEscStr(display_name, strlen(display_name), - remote_party_id_buf + escaped_url_len, - MAX_SIP_URL_LENGTH - escaped_url_len, - TRUE) - 1; - sstrncat(remote_party_id_buf,"\" ;party=%s;id-type=subscriber;privacy=%s;screen=yes", - src_addr_str, (request ? "calling" : "called"), - (private_flag ? "full" : "off")); - } else { - snprintf(remote_party_id_buf + escaped_url_len, - MAX_SIP_URL_LENGTH - escaped_url_len, - "@%s>;party=%s;id-type=subscriber;privacy=%s;screen=yes", - src_addr_str, (request ? "calling" : "called"), - (private_flag ? "full" : "off")); - } - - ccb->sip_remote_party_id = strlib_update(ccb->sip_remote_party_id, - remote_party_id_buf); - - return RPID_ENABLED; -} - -static void -sipSPISetFrom (ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISetFrom"; - boolean private_flag; - size_t escaped_url_len; - char *sip_from_tag; - char *temp_from_tag; - char *sip_from_temp; - char line_name[MAX_LINE_NAME_SIZE]; - char display_name[MAX_LINE_NAME_SIZE]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char *addr_str = 0; - char addr[MAX_IPADDR_STR_LEN]; - cpr_ip_type ip_type = CPR_IP_ADDR_INVALID; - - if (!ccb) { - CCSIP_DEBUG_ERROR("%s: Error: NULL ccb.\n", fname); - return; - } - - ipaddr2dotted(dest_sip_addr_str, &ccb->dest_sip_addr); - - if ((ccb->routeMode == RouteEmergency) || - (ccb->proxySelection == SIP_PROXY_BACKUP)) { - addr_str = dest_sip_addr_str; - } else { - ip_type = sipTransportGetPrimServerAddress(ccb->dn_line, addr); - addr_str = addr; - } - - sip_from_temp = strlib_open(ccb->sip_from, MAX_SIP_URL_LENGTH); - - if (sip_from_temp == NULL) { - CCSIP_DEBUG_ERROR("%s: Error: sip_from_temp is NULL.\n", fname); - return; - } - - private_flag = sipSPIIsPrivate(ccb); - - if (private_flag == TRUE) { - if (ip_type == CPR_IP_ADDR_IPV6) { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "\"%s\" ", - SIP_HEADER_ANONYMOUS_STR, SIP_HEADER_ANONYMOUS_STR, - addr_str); - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "\"%s\" ", - SIP_HEADER_ANONYMOUS_STR, SIP_HEADER_ANONYMOUS_STR, - addr_str); - } - } else { - /* From header needs to have global address in it */ - config_get_string((CFGID_LINE_NAME + ccb->dn_line - 1), line_name, - sizeof(line_name)); - sip_config_get_display_name(ccb->dn_line, display_name, - sizeof(display_name)); - sstrncpy(sip_from_temp, "\"", MAX_SIP_URL_LENGTH); - escaped_url_len = 1; - escaped_url_len += - sippmh_converQuotedStrToEscStr(display_name, strlen(display_name), - sip_from_temp + escaped_url_len, - MAX_SIP_URL_LENGTH - escaped_url_len, - TRUE) - 1; - sstrncat(sip_from_temp,"\" ", - addr_str); - } else { - snprintf(sip_from_temp + escaped_url_len, - MAX_SIP_URL_LENGTH - escaped_url_len, "@%s>", - addr_str); - } - } - - /* Now add tag to the From header */ - sstrncat(sip_from_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - temp_from_tag = ccsip_find_preallocated_sip_local_tag(ccb->dn_line); - sip_from_tag = strlib_open(ccb->sip_from_tag, MAX_SIP_URL_LENGTH); - if (temp_from_tag == NULL) { - if (sip_from_tag) { - sip_util_make_tag(sip_from_tag); - sstrncat(sip_from_temp, sip_from_tag, - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - } - } else { - if (sip_from_tag) { - sstrncpy(sip_from_tag, temp_from_tag, MAX_SIP_URL_LENGTH); - sstrncat(sip_from_temp, temp_from_tag, - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - } - ccsip_free_preallocated_sip_local_tag(ccb->dn_line); - } - ccb->sip_from_tag = strlib_close(sip_from_tag); - ccb->sip_from = strlib_close(sip_from_temp); -} - -/* - * Send INVITE - * - * As the name suggests, called to send a SIP INVITE request. - * Assumes that - * - connection has been setup beforehand. - * - SDP description has been setup. - * Does not affect call state. - */ -boolean -sipSPISendInvite (ccsipCCB_t *ccb, sipInviteType_t inviteType, - boolean initInvite) -{ - const char *fname = "SIPSPISendInvite"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - char called_number[MAX_SIP_URL_LENGTH]; - ccsipCCB_t *referccb = NULL; - boolean inviterefer = FALSE; - sipMessageFlag_t messageflag; - int i; - int rpid_flag; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "INVITE"); - - if (ccb->wastransferred) { - inviterefer = TRUE; - } - // This routine can be called in three different contexts. These are the - // important differences between them: - // CONTEXT inviteType referccb - // ----------------------------------------------------------- - // Normal SIP_INVITE_TYPE_NORMAL NULL - // Blind Xfer SIP_INVITE_TYPE_NORMAL valid - // Att Xfer SIP_INVITE_TYPE_TRANSFER valid - - referccb = sip_sm_get_target_call_by_gsm_id(ccb->gsm_id); - - // If there is a referccb, try to get authentication stuff from it - if (referccb != NULL) { - if (referccb->refer_proxy_auth != NULL) { - ccb->refer_proxy_auth = cpr_strdup(referccb->refer_proxy_auth); - } - } - - if (inviteType == SIP_INVITE_TYPE_TRANSFER) { - // For attended transfers we need to make a local copy of the - // referccb if it exists - if (NULL != referccb) { - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, - referccb->sip_referredBy); - if (referccb->featuretype == CC_FEATURE_XFER) { - ccb->sipxfercallid = strlib_update(ccb->sipxfercallid, - referccb->sipxfercallid); - if (ccb->sipxfercallid) { - if (ccb->sipxfercallid[0] != '\0') { - ccb->wastransferred = TRUE; - inviterefer = TRUE; - } - } - } - } - - if (inviterefer == FALSE) { - //Not enough information for starting attended transfer - CCSIP_DEBUG_ERROR("%s: Error:Replaces INVITE build unsuccessful.\n", - fname); - return (FALSE); - } - } - - if (inviteType != SIP_INVITE_TYPE_REDIRECTED) { - ccb->sip_to = strlib_update(ccb->sip_to, ccb->calledNumber); - } - - - /* - * Set from header - */ - sipSPISetFrom(ccb); - - /* - * Set RPID header. - */ - rpid_flag = sipSPISetRPID(ccb, TRUE); - - /* - * The calledNumber needs to be rewritten with the backup proxy - * ip address if the backup proxy is active - */ - if (ccb->proxySelection == SIP_PROXY_BACKUP) { - sstrncpy(called_number, ccb->calledDisplayedName, MAX_SIP_URL_LENGTH); - - /* - * NOTE: Need to replace with new routine ??? - */ - if (called_number[0] != '\0') { - sip_sm_util_normalize_name(ccb, called_number); - } - } - - // Add Create Request Here - messageflag.flags = 0; - messageflag.flags |= SIP_HEADER_ACCEPT_BIT | - SIP_HEADER_EXPIRES_BIT | - SIP_HEADER_CONTACT_BIT | - SIP_HEADER_DIVERSION_BIT | - SIP_HEADER_SUPPORTED_BIT | - SIP_HEADER_ALLOW_EVENTS_BIT | - SIP_HEADER_ALLOW_BIT | - SIP_HEADER_RECV_INFO_BIT | - SIP_HEADER_REQUIRE_BIT; - - if (ccb->authen.authorization != NULL) { - messageflag.flags |= SIP_HEADER_AUTHENTICATION_BIT; - } - if (ccb->refer_proxy_auth != NULL) { - messageflag.flags |= SIP_HEADER_PROXY_AUTH_BIT; - } - if (ccb->sip_referredBy[0] != '\0') { - messageflag.flags |= SIP_HEADER_REFERRED_BY_BIT; - } - if (((TRUE == inviterefer) || (ccb->flags & SENT_INVITE_REPLACE)) && - ('\0' != ccb->sipxfercallid[0])) { - messageflag.flags |= SIP_HEADER_REPLACES_BIT; - } - if (ccb->sip_reqby[0]) { - messageflag.flags |= SIP_HEADER_REQUESTED_BY_BIT; - } - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - if (ccb->out_call_info != NULL) { - messageflag.flags |= SIP_HEADER_CALL_INFO_BIT; - } - if (ccb->join_info != NULL) { - messageflag.flags |= SIP_HEADER_JOIN_INFO_BIT; - } - - /* Write SDP */ - messageflag.flags |= SIP_HEADER_CONTENT_TYPE_BIT; - request = GET_SIP_MESSAGE(); - if (request == NULL) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to allocate INVITE request\n", - fname); - return (FALSE); - } - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodInvite, request, - initInvite, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - UPDATE_FLAGS(flag, tflag); - - ccb->ReqURIOriginal = strlib_update(ccb->ReqURIOriginal, ccb->ReqURI); - - /* - * If overloaded headers are present from the 302, add them to the - * Invite message - */ - if ((ccb->redirect_info) && - (ccb->redirect_info->sipContact->locations[0]->genUrl) && - (ccb->redirect_info->sipContact->locations[0]->genUrl->u.sipUrl) && - (ccb->redirect_info->sipContact->locations[0]->genUrl->u.sipUrl->headerp) && - (inviteType == SIP_INVITE_TYPE_REDIRECTED)) { - for (i = 0; - i < ccb->redirect_info->sipContact->locations[0]->genUrl->u.sipUrl->num_headers; - i++) { - tflag = sippmh_add_text_header(request, - ccb->redirect_info->sipContact->locations[0]->genUrl->u. - sipUrl->headerp[i].attr, - ccb->redirect_info->sipContact->locations[0]->genUrl->u. - sipUrl->headerp[i].value); - UPDATE_FLAGS(flag, tflag); - } - } - - if (flag != STATUS_SUCCESS) { - free_sip_message(request); - CCSIP_DEBUG_ERROR("%s: Error: INVITE message build unsuccessful.\n", - fname); - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } - - ccb->retx_counter = 0; - - if (SendRequest(ccb, request, sipMethodInvite, FALSE, TRUE, TRUE) - == FALSE) { - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - -sipRet_t -sipSPIAddCallStats (ccsipCCB_t *ccb, sipMessage_t *msg) -{ - int call_stats_flag; - sipRet_t tflag = STATUS_SUCCESS; - - config_get_value(CFGID_CALL_STATS, &call_stats_flag, sizeof(call_stats_flag)); - if ((call_stats_flag) && (ccb->kfactor_ptr)) { - if (ccb->kfactor_ptr->rxstats[0] != NUL) { - tflag = sippmh_add_text_header(msg, SIP_RX_CALL_STATS, ccb->kfactor_ptr->rxstats); - } - if (ccb->kfactor_ptr->txstats[0] != NUL) { - tflag = sippmh_add_text_header(msg, SIP_TX_CALL_STATS, ccb->kfactor_ptr->txstats); - } - } - return tflag; -} - -boolean -sipSPISendInviteMidCall (ccsipCCB_t *ccb, boolean expires) -{ - const char *fname = "sipSPISendInviteMidCall"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - int rpid_flag; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "INVITE"); - - /* - * Build the request Here - */ - messageflag.flags = 0; - messageflag.flags |= SIP_HEADER_CONTACT_BIT | - SIP_HEADER_ROUTE_BIT | - SIP_HEADER_CONTENT_TYPE_BIT | - SIP_HEADER_ACCEPT_BIT | - SIP_HEADER_SUPPORTED_BIT | - SIP_HEADER_ALLOW_EVENTS_BIT | - SIP_HEADER_ALLOW_BIT | - SIP_HEADER_RECV_INFO_BIT | - SIP_HEADER_REQUIRE_BIT; - - if ((ccb->authen.authorization != NULL) && - ((ccb->state == SIP_STATE_SENT_INVITE) || - (ccb->state == SIP_STATE_SENT_MIDCALL_INVITE))) { - messageflag.flags |= SIP_HEADER_AUTHENTICATION_BIT; - } - - if ((ccb->authen.authorization != NULL) && - (ccb->state == SIP_STATE_SENT_INVITE)) { - if (ccb->join_info != NULL) { - messageflag.flags |= SIP_HEADER_JOIN_INFO_BIT; - } - } - - if ('\0' != ccb->sipxfercallid[0]) { - messageflag.flags |= SIP_HEADER_REPLACES_BIT; - } - - if (expires > 0) { - messageflag.flags |= SIP_HEADER_EXPIRES_BIT; - } - - if (ccb->sip_referredBy[0]) { - messageflag.flags |= SIP_HEADER_REFERRED_BY_BIT; - } - - /* - * Set RPID header. - */ - rpid_flag = sipSPISetRPID(ccb, TRUE); - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - - if (ccb->out_call_info) { - messageflag.flags |= SIP_HEADER_CALL_INFO_BIT; - } - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodInvite, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - - tflag = sipSPIAddCallStats(ccb, request); - UPDATE_FLAGS(flag, tflag); - - /* Recalc and add Authorization header if needed */ - if ((ccb->state != SIP_STATE_SENT_INVITE) && - (ccb->state != SIP_STATE_SENT_MIDCALL_INVITE)) { - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, - SIP_METHOD_INVITE); - } - - /* Write SDP */ - if (flag != STATUS_SUCCESS) { - free_sip_message(request); - CCSIP_DEBUG_ERROR("%s: Error: INVITE message build unsuccessful.\n", - fname); - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } - /* - * Currently the following field is being set to zero when the - * midcall invite is not being done as a response to an authorization - * challenge. So utilize this fact to prevent proxy backup selection - * on a mid-call invite. The end result is to stick with the same - * proxy as the original invite. - */ - if (ccb->authen.cred_type == 0) { - ccb->proxySelection = SIP_PROXY_DO_NOT_CHANGE_MIDCALL; - } - - /* Successfully constructed msg with new URI for this INVITE to send out. - * Update URIOriginal before sending out. - */ - ccb->ReqURIOriginal = strlib_update(ccb->ReqURIOriginal, ccb->ReqURI); - - /* Enable reTx and send */ - ccb->retx_counter = 0; - if (SendRequest(ccb, request, sipMethodInvite, TRUE, TRUE, TRUE) == FALSE) { - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - - -/* - * Sends the ACK request. - * Assumes that - * - the connection is setup. - * Appends session description if sd = TRUE. (This would - * be the case, if we want to change the codec that - * was sent on the INVITE. - * Does not affect call state. - */ -boolean -sipSPISendAck (ccsipCCB_t *ccb, sipMessage_t *response) -{ - const char *fname = "sipSPISendAck"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - uint32_t response_cseq_number = 0; - sipCseq_t *response_cseq_structure; - const char *response_cseq; - int16_t trx_index = -1; - boolean retval; - int rpid_flag; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "ACK"); - - /* - * Build the request - */ - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_ROUTE_BIT | - SIP_HEADER_RECV_INFO_BIT; - - /* - * Cseq number in the response could be different from that in ccb. - * If there was no response as in - * ccsip_handle_sentinviteconnected_ev_cc_connected_ack - * then use ccb for getting Cseq number - */ - if (response) { - response_cseq = sippmh_get_cached_header_val(response, CSEQ); - if (!response_cseq) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to obtain response CSeq " - "header.\n", fname); - return (FALSE); - } - response_cseq_structure = sippmh_parse_cseq(response_cseq); - if (!response_cseq_structure) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to parse response CSeq " - "header.\n", fname); - return (FALSE); - } - response_cseq_number = response_cseq_structure->number; - cpr_free(response_cseq_structure); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Cseq from response = %d \n", - DEB_F_PREFIX_ARGS(SIP_ACK, "sipSPISendAck"), response_cseq_number); - } else { - trx_index = get_method_request_trx_index(ccb, sipMethodInvite, TRUE); - if (trx_index < 0) { - return (FALSE); - } - response_cseq_number = ccb->sent_request[trx_index].cseq_number; - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Cseq from ccb = %d \n", - DEB_F_PREFIX_ARGS(SIP_ACK, "sipSPISendAck"), response_cseq_number); - } - - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - if (ccb->authen.authorization != NULL) { - messageflag.flags |= SIP_HEADER_AUTHENTICATION_BIT; - } - - /* - * Set RPID header. - */ - rpid_flag = sipSPISetRPID(ccb, TRUE); - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodAck, request, FALSE, - response_cseq_number)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (FALSE); - } - - /* Send message */ - retval = SendRequest(ccb, request, sipMethodAck, FALSE, FALSE, FALSE); - - // We are done with this INVITE request so lets clear and reorder our - // cseq list of outstanding requests. Assumes that ACK will only be - // sent for INVITE. Also note that no trx block is allocated for Ack - // and so there is no need to free it. - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - return (retval); -} - - -/* - * Sends the BYE request for the call. - * Assumes that - * - the connection is setup. - * Does not change the state, but changes the disconnection flags. - */ -void -sipSPISendBye (ccsipCCB_t *ccb, char *alsoString, sipMessage_t *pForked200) -{ - const char *fname = "sipSPISendBye"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipContact_t *stored_contact_info = NULL; - sipRecordRoute_t *stored_record_route_info = NULL; - static char stored_sip_to[MAX_SIP_URL_LENGTH]; - static char stored_sip_from[MAX_SIP_URL_LENGTH]; - static char last_route[MAX_SIP_URL_LENGTH]; - const char *forked200_contact = NULL; - const char *forked200_record_route = NULL; - const char *forked200_to = NULL; - const char *forked200_from = NULL; - sipMessageFlag_t messageflag; - - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "BYE"); - - /* - * If this BYE is in response to the secondary forked 200 OK message - * (from the callee being rejected), then we need to use the - * Contact and Record-Route of this 200 OK message, rather than the - * stored ccb->contact_info and ccb->record_route_info. - * So, if pForked200 exists, then we will: - * - save existing ccb->contact_info and ccb->record_route_info fields - * - parse Contact and Record-Route of the forked 200 - * - use these values to form this BYE's Req-URI - * - restore the original ccb->contact_info and ccb->record_route_info - */ - if (pForked200) { - stored_contact_info = ccb->contact_info; - stored_record_route_info = ccb->record_route_info; - sstrncpy(stored_sip_to, ccb->sip_to, MAX_SIP_URL_LENGTH); - sstrncpy(stored_sip_from, ccb->sip_from, MAX_SIP_URL_LENGTH); - - forked200_contact = sippmh_get_cached_header_val(pForked200, CONTACT); - forked200_record_route = - sippmh_get_cached_header_val(pForked200, RECORD_ROUTE); - forked200_to = sippmh_get_cached_header_val(pForked200, TO); - forked200_from = sippmh_get_cached_header_val(pForked200, FROM); - - if (forked200_contact) { - ccb->contact_info = sippmh_parse_contact(forked200_contact); - } - if (forked200_record_route) { - ccb->record_route_info = - sippmh_parse_record_route(forked200_record_route); - } - ccb->sip_to = strlib_update(ccb->sip_to, forked200_to); - ccb->sip_from = strlib_update(ccb->sip_from, forked200_from); - } - - /* - * Build the request - */ - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTENT_LENGTH_BIT; - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodBye, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - - /* add in call stats header if needed */ - tflag = sipSPIAddCallStats(ccb, request); - UPDATE_FLAGS(flag, tflag); - - if (alsoString) { - tflag = sippmh_add_text_header(request, SIP_HEADER_ALSO, alsoString); - UPDATE_FLAGS(flag, tflag); - } - - memset(last_route, 0, MAX_SIP_URL_LENGTH); - tflag = (sipSPIAddRouteHeaders(request, ccb, last_route, MAX_SIP_URL_LENGTH)) ? - STATUS_SUCCESS : STATUS_FAILURE; - UPDATE_FLAGS(flag, tflag); - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, SIP_METHOD_BYE); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - if (alsoString) - cpr_free(alsoString); - clean_method_request_trx(ccb, sipMethodBye, TRUE); - return; - } - - ccb->retx_counter = 0; - /* Send message */ - (void) SendRequest(ccb, request, sipMethodBye, FALSE, TRUE, FALSE); - - /* - * Update history - */ - /* Record Also header if any */ - if (alsoString) { - if (alsoString[0]) { - sstrncpy(gCallHistory[ccb->index].last_bye_also_string, alsoString, - MAX_SIP_URL_LENGTH); - } - cpr_free(alsoString); - } else { - memset(gCallHistory[ccb->index].last_bye_also_string, 0, - MAX_SIP_URL_LENGTH); - } - - /* Record current Route */ - if (last_route[0]) { - sstrncpy(gCallHistory[ccb->index].last_route, last_route, - MAX_SIP_URL_LENGTH); - } else { - memset(gCallHistory[ccb->index].last_route, 0, MAX_SIP_URL_LENGTH); - } - /* Record current Request-URI */ - if (ccb->ReqURI[0]) { - sstrncpy(gCallHistory[ccb->index].last_route_request_uri, ccb->ReqURI, - MAX_SIP_URL_LENGTH); - } else { - memset(gCallHistory[ccb->index].last_route_request_uri, 0, - MAX_SIP_URL_LENGTH); - } - -// bugid: CSCsz34666 -// /* -// * Store call history info -// */ -// if ((int) (ccb->index) <= TEL_CCB_END) { -// memcpy(gCallHistory[ccb->index].last_call_id, ccb->sipCallID, -// MAX_SIP_CALL_ID); -// } - - /* - * Restore the original ccb->contact and ccb->record_route fields - */ - if (pForked200) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = stored_contact_info; - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - } - ccb->record_route_info = stored_record_route_info; - - ccb->sip_to = strlib_update(ccb->sip_to, stored_sip_to); - ccb->sip_from = strlib_update(ccb->sip_from, stored_sip_from); - } - - return; -} - - - -/* - * Sends the SIP CANCEL request, to disconnect a call that - * is not in the active state. - */ -void -sipSPISendCancel (ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISendCancel"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - char *temp = NULL; - char local_cpy[MAX_SIP_URL_LENGTH]; - string_t hold_to_tag = strlib_copy(ccb->sip_to); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "CANCEL"); - - messageflag.flags = 0; - ccb->authen.cred_type = 0; - - messageflag.flags = SIP_HEADER_CONTENT_LENGTH_BIT; - - /* Remove the to_tag from the CANCEL message if present */ - sstrncpy(local_cpy, ccb->sip_to, MAX_SIP_URL_LENGTH); - temp = strstr(local_cpy, ">"); - if (temp != NULL) { - *(temp + 1) = '\0'; - } - ccb->sip_to = strlib_update(ccb->sip_to, local_cpy); - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodCancel, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - /* restore the to_tag if it was there */ - if (hold_to_tag) { - ccb->sip_to = strlib_update(ccb->sip_to, hold_to_tag); - strlib_free(hold_to_tag); - } - hold_to_tag = strlib_empty(); - - UPDATE_FLAGS(flag, tflag); - /* Recalc and add Authorization header if needed */ - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, - SIP_METHOD_CANCEL); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - clean_method_request_trx(ccb, sipMethodCancel, TRUE); - return; - } - /* Record current Request-URI */ - if (ccb->ReqURI[0]) { - sstrncpy(gCallHistory[ccb->index].last_route_request_uri, ccb->ReqURI, - MAX_SIP_URL_LENGTH); - } else { - memset(gCallHistory[ccb->index].last_route_request_uri, 0, - MAX_SIP_URL_LENGTH); - } - if (SendRequest(ccb, request, sipMethodCancel, FALSE, TRUE, FALSE) - == FALSE) { - clean_method_request_trx(ccb, sipMethodCancel, TRUE); - return; - } else { - return; - } -} - -void -sip_platform_icmp_unreachable_callback (void *ccb, uint32_t ipaddr) -{ - static const char fname[] = "sip_platform_icmp_unreachable_callback"; - uint32_t *icmp_msg; - - icmp_msg = (uint32_t *) SIPTaskGetBuffer(sizeof(uint32_t)); - if (!icmp_msg) { - CCSIP_DEBUG_ERROR("%s: Error: get buffer failed.\n", fname); - return; - } - *icmp_msg = ((ccsipCCB_t *)ccb)->index; - - if (SIPTaskSendMsg(SIP_ICMP_UNREACHABLE, (cprBuffer_t)icmp_msg, - sizeof(uint32_t), (void *)(long)ipaddr) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR("%s: Error: send msg failed.\n", fname); - cpr_free((cprBuffer_t)icmp_msg); - } - return; -} - -/* - * Sends the SIP REFER request, to Transfer the call - * - * Parameters: - * ccb - reference tio the existing call control block - * referto - Dial string to make a call (If null it will pick up from ccb) - * referto_typ to indicate if the referto is trasnfer or token refer - * - */ -boolean -sipSPISendRefer (ccsipCCB_t *ccb, char *referto, sipRefEnum_e referto_type) -{ - const char *fname = "sipSPISendRefer"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - ccsipCCB_t *xfer_ccb = NULL; - char tempreferto[MAX_SIP_URL_LENGTH + 2]; - char callid[MAX_SIP_HEADER_LENGTH + 2]; - sipMessageFlag_t messageflag; - char *semi = NULL; - char *left_bracket = NULL; - char *right_bracket = NULL; - char *msg_referto = NULL; - string_t copy_of_referto = NULL; - int rpid_flag; - char *ref_to_callid = NULL; - const char *to_tag = NULL; - const char *from_tag = NULL; - boolean dm_info = FALSE; - sipJoinInfo_t join_info; - - memset(&join_info, 0, sizeof(join_info)); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "REFER"); - /* - * Build the request - */ - - if (sipSPIGenerateReferredByHeader(ccb) == FALSE) { - tflag = HSTATUS_FAILURE; - } else { - tflag = HSTATUS_SUCCESS; - } - UPDATE_FLAGS(flag, tflag); - - messageflag.flags = 0; - /* - * Don't add the content length bit here. Content length - * needs to be the last in the header. TCP uses the content - * length to do framing. - */ - messageflag.flags = SIP_HEADER_CONTACT_BIT | SIP_HEADER_ROUTE_BIT; - - /* - * Set RPID header. - */ - rpid_flag = sipSPISetRPID(ccb, TRUE); - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - - if (referto) { - // Get a new call-id if this REFER is for fallback token registration - if (strncmp(referto, TOKEN_REFER_TO, sizeof(TOKEN_REFER_TO)) == 0) { - ccb->sipCallID[0] = '\0'; - sip_util_get_new_call_id(ccb); - } - } - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodRefer, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - /* Recalc and add Authorization header if needed */ - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, - SIP_METHOD_REFER); - - memset(tempreferto, 0, MAX_SIP_URL_LENGTH + 2); - memset(callid, 0, MAX_SIP_HEADER_LENGTH + 2); - - /* see if we have ;user= */ - if (referto) { - semi = strchr(referto, ';'); - } - - if (CC_FEATURE_XFER == ccb->featuretype) { - // The con_call_id is filled up by GSM when it opens up the line This - // is used to cross reference the call_ids - xfer_ccb = sip_sm_get_ccb_by_target_call_id(ccb->con_call_id); - - if (xfer_ccb != NULL) { - ref_to_callid = xfer_ccb->sipCallID; - to_tag = xfer_ccb->sip_to_tag; - from_tag = xfer_ccb->sip_from_tag; - } - - if (xfer_ccb != NULL || dm_info == TRUE) { - int i = 0; - - // Create Refer_to header with replace id (call_id of other call) - // and To-Tag of other call - escape the replaced callid - while (*ref_to_callid != '\0') { - if (*ref_to_callid != '@') { - callid[i++] = *ref_to_callid; - } else { - callid[i++] = '%'; - callid[i++] = '4'; - callid[i++] = '0'; - } - ref_to_callid++; - } - callid[i] = '\0'; - - /* first get rid of opening and closing braces, if there */ - copy_of_referto = strlib_copy(referto); - if (copy_of_referto) { - left_bracket = strpbrk(copy_of_referto, "<"); - } - if (left_bracket) { - left_bracket++; - right_bracket = strchr(left_bracket, '>'); - if (right_bracket) { - *right_bracket++ = 0; - } - msg_referto = left_bracket; - } else { - msg_referto = referto; - } - if (msg_referto) { - if (strncmp(msg_referto, "sip:", 4) == 0) { - snprintf(tempreferto, sizeof(tempreferto), - "<%s%c%s%c%s%%3B%s%%3D%s%%3B%s%%3D%s>", - msg_referto, QUESTION_MARK, - SIP_HEADER_REPLACES, EQUAL_SIGN, callid, - TO_TAG, to_tag, - FROM_TAG, from_tag); - } else { - snprintf(tempreferto, sizeof(tempreferto), - "", - msg_referto, QUESTION_MARK, - SIP_HEADER_REPLACES, EQUAL_SIGN, callid, - TO_TAG, to_tag, - FROM_TAG, from_tag); - } - } - strlib_free(copy_of_referto); - } - - if (dm_info) { - cpr_free(join_info.call_id); - cpr_free(join_info.to_tag); - cpr_free(join_info.from_tag); - } - - tflag = sippmh_add_text_header(request, SIP_HEADER_REFER_TO, - ((NULL != xfer_ccb)|| (dm_info == TRUE)) ? tempreferto : referto); - UPDATE_FLAGS(flag, tflag); - } else { - if (referto) { - if ((strncmp(referto, "", - referto); - } else { - snprintf(tempreferto, sizeof(tempreferto), "sip:%s", - referto); - } - } - } - tflag = sippmh_add_text_header(request, SIP_HEADER_REFER_TO, - tempreferto); - UPDATE_FLAGS(flag, tflag); - } - - ccb->sip_referTo = strlib_update(ccb->sip_referTo, referto); - tflag = sippmh_add_text_header(request, SIP_HEADER_REFERRED_BY, - ccb->sip_referredBy); - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - return (FALSE); - } -// cpr_free(referto); - - /* - * Add the content length now. - */ - tflag = sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0); - UPDATE_FLAGS(flag, tflag); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - return FALSE; - } - - ccb->retx_counter = 0; - - if (SendRequest(ccb, request, sipMethodRefer, FALSE, TRUE, FALSE) == FALSE) { - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - -/* - * Sends the Notify - * Will be sent when we get OK from target (in case of Refer) - * - * Note: Assumes that the connection is setup. - * - * Parameter: - * ccb - call control block - * response -*/ -boolean -sipSPISendNotify (ccsipCCB_t *ccb, int response) -{ - const char *fname = "sipSPISendNotify"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - char *body; - char errortext[MAX_SIP_URL_LENGTH]; - char subs_state_hdr[SUBS_STATE_HDR_LEN]; - int respClass; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "Notify"); - - /* - * Clean up any remaining transactions before sending the next request. - * Normally the transactions are cleaned after final responses (200OK) - * and if not they will be cleaned after the timeouts. Currently for - * NOTIFYs there are not timeout cleanups, so we will explicitly clean - * any outstanding transactions now before the next request. - * - * This fix works today because we don't really care about any responses - * to NOTIFY requests and do not act on them. The transaction layer should - * be enhanced to handles these cases. This should be addressed under the - * Ringpops feature. - */ - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - - /* - * Before we do the real notify work, we may need to clean up the - * refer proxy authorization stuff that may have been left laying around - * during the transfer. - * - * This is the Proxy-Authorization that came in the REFER's Refer-To - * as an escaped header and therefore should only be alive till the - * transfer is done. - * - * But we have to do this only if we are sending the last notify for - * a REFER, i.e. if we are sending the last sipfrag. For ex: - * "200 OK", or "404 Not Found". We have to check for this because - * after sending a NOTIFY("100 Trying") to the Transferor we send an - * INVITE to the target and the Proxy-Authorization is required. When - * we send a NOTIFY indicating success or failure, we can remove the - * refer_proxy_auth in both ccbs. - */ - respClass = response / 100; - if (respClass >= 2) { - if (ccb->refer_proxy_auth) { - ccsipCCB_t *other_ccb; - - cpr_free(ccb->refer_proxy_auth); - ccb->refer_proxy_auth = NULL; - // now, find the ccb of the call we transferred to.... - other_ccb = sip_sm_get_ccb_by_callid(ccb->sipxfercallid); - if (other_ccb != NULL) { - if (other_ccb->refer_proxy_auth) { - cpr_free(other_ccb->refer_proxy_auth); - other_ccb->refer_proxy_auth = NULL; - } - } - } - } - - /* - * Build the request - */ - // The addition of the CSeq method will be done when CSeq number is added - // ccb->last_sent_request_cseq_method = sipMethodNotify; - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_ROUTE_BIT | SIP_HEADER_CONTACT_BIT; - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodNotify, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - tflag = sippmh_add_text_header(request, SIP_HEADER_EVENT, SIP_EVENT_REFER); - UPDATE_FLAGS(flag, tflag); - - // Add Subscription-State header - if (ccb->flags & FINAL_NOTIFY) { - snprintf(subs_state_hdr, SUBS_STATE_HDR_LEN, - "terminated; reason=noresource"); - } else { - uint32_t expires_timeout = 0; - - config_get_value(CFGID_TIMER_INVITE_EXPIRES, &expires_timeout, - sizeof(expires_timeout)); - snprintf(subs_state_hdr, SUBS_STATE_HDR_LEN, "active; expires=%d", - expires_timeout); - } - tflag = sippmh_add_text_header(request, SIP_HEADER_SUBSCRIPTION_STATE, - subs_state_hdr); - UPDATE_FLAGS(flag, tflag); - - /* Recalc and add Authorization header if needed */ - sipSPIGenerateGenAuthorizationResponse(ccb, request, &flag, - SIP_METHOD_NOTIFY); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - return (FALSE); - } - - /* Write message */ - /* - * Currently the only notify message the phone sends is with respect - * to refer. This routine looks like a general send notify routine. - * One would assume then there needs to be some sort of if (refer) - * check to cause it to send "message/sipfrag" otherwise send - * "application/sip" - */ -// tflag = sippmh_add_text_header(request, SIP_HEADER_CONTENT_TYPE, -// SIP_CONTENT_TYPE_SIP ); - // Don't add content-type explicitly - // tflag = sippmh_add_text_header(request, SIP_HEADER_CONTENT_TYPE, - // SIP_CONTENT_TYPE_SIPFRAG ); -// UPDATE_FLAGS(flag, tflag); - - body = (char *) cpr_malloc(MAX_SIP_URL_LENGTH * sizeof(char)); - if (!body) { - if (request) { - free_sip_message(request); - } - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - return FALSE; - } - memset(errortext, 0, MAX_SIP_URL_LENGTH); - get_sip_error_string(errortext, response); - snprintf(body, MAX_SIP_URL_LENGTH, "%s %d %s\r\n", SIP_VERSION, - response, errortext); - - tflag = sippmh_add_message_body(request, body, strlen(body), - SIP_CONTENT_TYPE_SIPFRAG, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, - TRUE, NULL); - UPDATE_FLAGS(flag, tflag); - - // No need to add header length separately - // tflag = sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, - // strlen(message_body)); - // UPDATE_FLAGS(flag, tflag); - - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - return (FALSE); - } - - ccb->retx_counter = 0; - - if (SendRequest(ccb, request, sipMethodNotify, FALSE, TRUE, FALSE) == FALSE) { - clean_method_request_trx(ccb, sipMethodNotify, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - -/* - * Sends the Info - * - * Note: Assumes that the connection is setup. - * - * Parameter: - * ccb - call control block - * info_package - the Info-Package header of the Info Package - * content_type - the Content-Type header of the Info Package - * message_body - the message body of the Info Package -*/ -boolean -sipSPISendInfo (ccsipCCB_t *ccb, const char *info_package, - const char *content_type, const char *message_body) -{ - const char *fname = "sipSPISendInfo"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - char *body; - boolean retval; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "Info"); - - /* - * Build the request - */ - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_ROUTE_BIT | SIP_HEADER_CONTACT_BIT; - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodInfo, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - /* FIXME Media Control currently does not follow the offer/offer - negotiation process outlined in IETF draft - draft-ietf-sip-info-events-01, so do not add Info-Package - header field if it's Media Control Info Package. */ - if (cpr_strncasecmp(content_type, SIP_CONTENT_TYPE_MEDIA_CONTROL, - strlen(SIP_CONTENT_TYPE_MEDIA_CONTROL)) != 0) { - tflag = sippmh_add_text_header(request, SIP_HEADER_INFO_PACKAGE, info_package); - UPDATE_FLAGS(flag, tflag); - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - return FALSE; - } - - body = (char *) cpr_malloc((strlen(message_body) + 1) * sizeof(char)); - if (!body) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_MEMORY_OUT_OF_MEM), fname); - if (request) { - free_sip_message(request); - } - return FALSE; - } - memcpy(body, message_body, strlen(message_body) + 1); - - tflag = sippmh_add_message_body(request, body, strlen(body), - content_type, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, - TRUE, NULL); - flag = tflag; - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - cpr_free(body); - if (request) { - free_sip_message(request); - } - return FALSE; - } - - retval = SendRequest(ccb, request, sipMethodInfo, TRUE, FALSE, FALSE); - - // Don't keep the trx so as not to mess up the retran timer of other requests - /* - * FIXME fix it when the framework is modified to support concurrent requests - */ - clean_method_request_trx(ccb, sipMethodInfo, TRUE); - - return retval; -} - -/* - * Sends the BYE or CANCEL response for the call. - * Assumes that - * - the connection is setup. - */ -boolean -sipSPISendByeOrCancelResponse (ccsipCCB_t *ccb, sipMessage_t *request, - sipMethod_t sipMethodByeorCancel) -{ - const char *fname = "sipSPISendByeResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - boolean result; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, 200); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTENT_LENGTH_BIT; - - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, SIP_STATUS_SUCCESS, response, - SIP_SUCCESS_SETUP_PHRASE, 0, NULL, sipMethodByeorCancel)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* send call stats on BYE response */ - if ((flag == STATUS_SUCCESS) && (sipMethodByeorCancel == sipMethodBye)) { - flag = sipSPIAddCallStats(ccb, response); - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) { - free_sip_message(response); - } - clean_method_request_trx(ccb, sipMethodByeorCancel, FALSE); - return (FALSE); - } - result = sendResponse(ccb, response, request, FALSE, sipMethodByeorCancel); - clean_method_request_trx(ccb, sipMethodByeorCancel, FALSE); - return (result); -} - - - -/* - * Send 100 TRYING - */ -void -sipSPISendInviteResponse100 (ccsipCCB_t *ccb, boolean remove_to_tag) -{ - char *temp = NULL; - char local_cpy[MAX_SIP_URL_LENGTH]; - string_t hold_to_tag = NULL; - - if (remove_to_tag) { - hold_to_tag = strlib_copy(ccb->sip_to); - - /* remove the to_tag from the 100 Trying message */ - sstrncpy(local_cpy, ccb->sip_to, MAX_SIP_URL_LENGTH); - temp = strstr(local_cpy, ">"); - if (temp != NULL) { - *(temp + 1) = '\0'; - } - ccb->sip_to = strlib_update(ccb->sip_to, local_cpy); - } - - sipSPISendInviteResponse(ccb, SIP_1XX_TRYING, SIP_1XX_TRYING_PHRASE, - 0, NULL, FALSE, /* no SDP */ - FALSE /* no reTx */); - - if (hold_to_tag) { - ccb->sip_to = strlib_update(ccb->sip_to, hold_to_tag); - strlib_free(hold_to_tag); - } -} - - -/* - * Send 180 RINGING - */ -void -sipSPISendInviteResponse180 (ccsipCCB_t *ccb) -{ - sipSPISendInviteResponse(ccb, SIP_1XX_RINGING, - SIP_1XX_RINGING_PHRASE, 0, NULL, - (boolean)(ccb->flags & INBAND_ALERTING), - FALSE /* no reTx */); -} - - -/* - * Send 200 OK - */ -void -sipSPISendInviteResponse200 (ccsipCCB_t *ccb) -{ - sipSPISendInviteResponse(ccb, SIP_STATUS_SUCCESS, - SIP_SUCCESS_SETUP_PHRASE, 0, NULL, - TRUE, TRUE /* reTx */); -} - -void -sipSPISendInviteResponse302 (ccsipCCB_t *ccb) -{ - - sipSPISendInviteResponse(ccb, SIP_RED_MOVED_TEMP, - SIP_RED_MOVED_TEMP_PHRASE, - 0, NULL, FALSE, /* no SDP */ - TRUE /* reTx */); -} - -/*Send Option Response - * - connection is set up. - * Currently just gives the methods supported - * Does not affect call state. -*/ -boolean -sipSPISendOptionResponse (ccsipCCB_t *ccb, sipMessage_t *request) -{ - const char *fname = "SIPSPISendOptionResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - boolean result; - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_ALLOW_BIT | - SIP_HEADER_ACCEPT_BIT | - SIP_HEADER_ACCEPT_ENCODING_BIT | - SIP_HEADER_ACCEPT_LANGUAGE_BIT | - SIP_HEADER_SUPPORTED_BIT; - - /* Write SDP */ - messageflag.flags |= SIP_HEADER_OPTIONS_CONTENT_TYPE_BIT; - - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, SIP_STATUS_SUCCESS, response, - SIP_SUCCESS_SETUP_PHRASE, 0, NULL, sipMethodOptions)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) { - free_sip_message(response); - } - clean_method_request_trx(ccb, sipMethodOptions, FALSE); - return (FALSE); - } - result = sendResponse(ccb, response, request, FALSE, sipMethodOptions); - clean_method_request_trx(ccb, sipMethodOptions, FALSE); - return (result); -} - -/* - * The function below handles an OPTIONS message not associated with - * any ongoing dialog and serves for the phone to gather capabilities - * of its server - */ -boolean -sipSPIsendNonActiveOptionResponse (sipMessage_t *msg, - cc_msgbody_info_t *local_msg_body) -{ - const char *fname = "sipSPIsendNonActiveOptionResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - const char *sip_from = NULL; - const char *sip_to = NULL; - const char *request_callid = NULL; - const char *request_cseq = NULL; - sipCseq_t *request_cseq_structure = NULL; - char temp[MAX_SIP_HEADER_LENGTH]; - sipLocation_t *to_loc = NULL; - char sip_to_tag[MAX_SIP_TAG_LENGTH]; - char sip_to_temp[MAX_SIP_URL_LENGTH]; - sipLocation_t *from_loc = NULL; - boolean request_uri_error = FALSE; - sipReqLine_t *requestURI = NULL; - sipLocation_t *uri_loc = NULL; - const char *accept_hdr = NULL; - const char *supported = NULL; - int kpml_config; - - if (!msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "msg"); - return (FALSE); - } - - // Parse through the Accept header to get the supported capabilities - accept_hdr = sippmh_get_header_val(msg, SIP_HEADER_ACCEPT, NULL); - if (accept_hdr) { - server_caps = sippmh_parse_accept_header(accept_hdr); - } - - // Parse through the Supported header to get the supported capabilities - supported = sippmh_get_cached_header_val(msg, SUPPORTED); - if (supported) { - sippmh_parse_supported_require(supported, NULL); - } - - response = GET_SIP_MESSAGE(); - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "GET_SIP_MESSAGE()"); - return (FALSE); - } - - sip_from = sippmh_get_cached_header_val(msg, FROM); - sip_to = sippmh_get_cached_header_val(msg, TO); - sstrncpy(sip_to_temp, sip_to, MAX_SIP_URL_LENGTH); - request_callid = sippmh_get_cached_header_val(msg, CALLID); - - requestURI = sippmh_get_request_line(msg); - if (requestURI) { - if (requestURI->url) { - uri_loc = sippmh_parse_from_or_to(requestURI->url, TRUE); - if (uri_loc) { - if (uri_loc->genUrl->schema != URL_TYPE_SIP) { - request_uri_error = TRUE; - } - sippmh_free_location(uri_loc); - } else { - request_uri_error = TRUE; - } - } else { - request_uri_error = TRUE; - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } else { - request_uri_error = TRUE; - } - if (request_uri_error) { - CCSIP_DEBUG_ERROR("%s: Error: Invalid Request URI failed.\n", fname); - free_sip_message(response); - /* Send 400 error */ - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_REQLINE_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return (FALSE); - } - - - /* - * Parse From - */ - from_loc = sippmh_parse_from_or_to((char *)sip_from, TRUE); - if (!from_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - free_sip_message(response); - /* Send 400 error */ - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return (FALSE); - } - - /* - * From is parsed just to make sure we got valid From - * Header, so we free it now - */ - sippmh_free_location(from_loc); - - /* - * Parse To - */ - to_loc = sippmh_parse_from_or_to((char *)sip_to, TRUE); - if (!to_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - if (response) { - free_sip_message(response); - } - /* Send 400 error */ - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return (FALSE); - } - - /* Check/Generate tags */ - if (to_loc->tag) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), NULL, - NULL, fname, "Initial Option with to_tag"); - if (response) { - free_sip_message(response); - } - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_location(to_loc); - return (FALSE); - } else { - sip_util_make_tag(sip_to_tag); - sstrncat(sip_to_temp, ";tag=", - sizeof(sip_to_temp) - strlen(sip_to_temp)); - sstrncat(sip_to_temp, sip_to_tag, - sizeof(sip_to_temp) - strlen(sip_to_temp)); - } - sippmh_free_location(to_loc); - - tflag = sippmh_add_response_line(response, SIP_VERSION, SIP_STATUS_SUCCESS, - SIP_SUCCESS_SETUP_PHRASE); - UPDATE_FLAGS(flag, tflag); - tflag = (sipSPIAddRequestVia(NULL, response, msg, sipMethodOptions)) ? - STATUS_SUCCESS : STATUS_FAILURE; - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_FROM, sip_from); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_TO, sip_to_temp); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_CALLID, request_callid); - UPDATE_FLAGS(flag, tflag); - - // Add date header - tflag = sipAddDateHeader(response); - UPDATE_FLAGS(flag, tflag); - /* Write CSeq */ - request_cseq = sippmh_get_cached_header_val(msg, CSEQ); - if (request_cseq) { - request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - free_sip_message(response); - /* - * We should send 400 here but as we don't have Cseq this - * is not possible. - */ - return FALSE; - } - if (request_cseq_structure->method != sipMethodOptions) { - CCSIP_DEBUG_ERROR("%s: Error: Invalid method in Cseq failed.\n", - fname); - free_sip_message(response); - /* Send 400 error */ - if (sipSPISendErrorResponse(msg, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - cpr_free(request_cseq_structure); - return FALSE; - } - tflag = sippmh_add_text_header(response, SIP_HEADER_CSEQ, request_cseq); - cpr_free(request_cseq_structure); - UPDATE_FLAGS(flag, tflag); - } - - tflag = sippmh_add_text_header(response, SIP_HEADER_SERVER, - sipHeaderServer); - - UPDATE_FLAGS(flag, tflag); - - /* - * Add the local sdp we got from gsm into the response - */ - tflag = CopyLocalSDPintoResponse(response, local_msg_body); - UPDATE_FLAGS(flag, tflag); - - // Add Allow - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, SIP_METHOD_OPTIONS, - SIP_METHOD_REFER, SIP_METHOD_REGISTER, SIP_METHOD_UPDATE); - tflag = sippmh_add_text_header(response, SIP_HEADER_ALLOW, temp); - UPDATE_FLAGS(flag, tflag); - - // Add Allow-Events - config_get_value(CFGID_KPML_ENABLED, &kpml_config, sizeof(kpml_config)); - if (kpml_config) { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s", SIP_EVENT_KPML, - SIP_EVENT_DIALOG, SIP_EVENT_REFER); - } else { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s", SIP_EVENT_DIALOG, - SIP_EVENT_REFER); - } - tflag = sippmh_add_text_header(response, SIP_HEADER_ALLOW_EVENTS, temp); - UPDATE_FLAGS(flag, tflag); - - // Add Accept - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s", - SIP_CONTENT_TYPE_SDP, - SIP_CONTENT_TYPE_MULTIPART_MIXED, - SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE); - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT, temp); - UPDATE_FLAGS(flag, tflag); - - // Add Accept-Encoding - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT_ENCODING, - "identity"); - UPDATE_FLAGS(flag, tflag); - - // Add Accept-Language - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT_LANGUAGE, "en"); - UPDATE_FLAGS(flag, tflag); - - tflag = sippmh_add_text_header(response, SIP_HEADER_SUPPORTED, - SIP_RFC_SUPPORTED_TAGS); - - UPDATE_FLAGS(flag, tflag); - - /* Determine from the Via field where the message is supposed - * to be sent - */ - - if (tflag != HSTATUS_SUCCESS) { - free_sip_message(response); - return FALSE; - } - return sendResponse(NULL, response, msg, FALSE, sipMethodOptions); -} - - -/* - * Send the invite response. Adds the session description - * if send_sd is TRUE. Assumes - * - connection is set up. - * Does not affect call state. - */ -void -sipSPISendInviteResponse (ccsipCCB_t *ccb, - uint16_t statusCode, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - boolean send_sd, - boolean retx) -{ - const char *fname = "SIPSPISendInviteResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - int rpid_flag; - - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, statusCode); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_ALLOW_BIT | - SIP_HEADER_DIVERSION_BIT | - SIP_HEADER_ALLOW_EVENTS_BIT; - - /* Write Content-Type */ - /* Add SDP body if required */ - if (send_sd) { - messageflag.flags |= SIP_HEADER_CONTENT_TYPE_BIT; - } else { - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - } - if (statusCode == SIP_CLI_ERR_EXTENSION) { - messageflag.flags |= SIP_HEADER_UNSUPPORTED_BIT; - } - if ((statusCode >=SIP_1XX_TRYING) && (statusCode <= SIP_STATUS_SUCCESS)) { - messageflag.flags |= SIP_HEADER_SUPPORTED_BIT; - } - if (statusCode == SIP_SERV_ERR_INTERNAL) { - messageflag.flags |= SIP_HEADER_RETRY_AFTER_BIT; - } - if ((statusCode == SIP_1XX_TRYING) || (statusCode == SIP_STATUS_SUCCESS)) { - messageflag.flags |= SIP_HEADER_RECV_INFO_BIT; - } - - /* - * Set RPID header. - */ - if (statusCode != SIP_1XX_TRYING) { - /* - * The RPID header is not sent in the 100 Trying because the response is directly - * sent from the SIP stack.The information needed for building the RPID is updated - * by the gsm later. - */ - rpid_flag = sipSPISetRPID(ccb, FALSE); - if (rpid_flag == RPID_ENABLED) { - messageflag.flags |= SIP_HEADER_REMOTE_PARTY_ID_BIT; - } - } - - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, statusCode, response, reason_phrase, - status_code_warning, reason_phrase_warning, - sipMethodInvite)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - - UPDATE_FLAGS(flag, tflag); - - tflag = sipSPIAddCallStats(ccb, response); - - UPDATE_FLAGS(flag, tflag); - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) { - free_sip_message(response); - } - return; - } - - (void) sendResponse(ccb, response, ccb->last_request, retx, sipMethodInvite); - return; -} - - -void -sipSPIGenerateGenAuthorizationResponse (ccsipCCB_t *ccb, - sipMessage_t *request, - sipRet_t *flag, - char *method) -{ - const char *fname = "sipSPIGenerateGenAuthorizationResponse"; - sipRet_t tflag = STATUS_SUCCESS; - char *author_str = NULL; - credentials_t credentials; - - /* - * CSCds70538 - * Re-generate the Authorization header for CANCEL, BYE, mid-INVITE - * The header is cached after an INVITE is challenged. - * I know that I have been challenged preciously because sip_authen - * is not NULL - */ - if (ccb->authen.sip_authen) { - cred_get_line_credentials(ccb->dn_line, &credentials, - sizeof(credentials.id), - sizeof(credentials.pw)); - if (sipSPIGenerateAuthorizationResponse(ccb->authen.sip_authen, - ccb->ReqURI, method, credentials.id, credentials.pw, - &author_str, &(ccb->authen.nc_count), ccb)) { - - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - - /* - * Don't free the sip_authen since we were not challenged - */ - ccb->authen.authorization = (char *) - cpr_malloc(strlen(author_str) + 1); - - /* - * Cache the Authorization header so that it can be used for later - * requests - */ - if (ccb->authen.authorization != NULL) { - sstrncpy(ccb->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - } - - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR("%s: Error: Authorization header build " - "unsuccessful\n", fname); - } - } - - if (ccb->authen.authorization != NULL) { - tflag = sippmh_add_text_header(request, - AUTHOR_HDR(ccb->authen.status_code), - ccb->authen.authorization); - UPDATE_FLAGS(*flag, tflag); - } -} - - -/* - * Sends the 202 Refer Accepted . - * Assumes that - * - the connection is setup. - * Will be sent when we get Refer -*/ -boolean -sipSPISendReferResponse202 (ccsipCCB_t *ccb) -{ - const char *fname = "SIPSPISendReferResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - boolean result; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, SIP_ACCEPTED); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_CONTENT_LENGTH_BIT; - - /* Add Content Length */ - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, SIP_ACCEPTED, response, - SIP_ACCEPTED_PHRASE, 0, NULL, sipMethodRefer)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) - free_sip_message(response); - clean_method_request_trx(ccb, sipMethodRefer, FALSE); - return (FALSE); - } - - result = sendResponse(ccb, response, ccb->last_request, FALSE, - sipMethodRefer); - clean_method_request_trx(ccb, sipMethodRefer, FALSE); - return (result); -} - -/* - * General function to send an error response for a given request. - * Does not affect call state or disconnection flags. - * - * Valid values of warn_code is 3xx. Set warn_code to ZERO, when - * warn_code is absent. Use of a valid warn_code, will lead to - * generation of Warning Header in the response. - */ -boolean -sipSPISendErrorResponse (sipMessage_t *msg, - uint16_t status_code, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISendErrorResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - const char *sip_from = NULL; - const char *sip_to = NULL; - const char *request_callid = NULL; - const char *request_cseq = NULL; - sipCseq_t *request_cseq_structure = NULL; - sipMethod_t method = sipMethodInvalid; - boolean result = FALSE; - char temp[MAX_SIP_HEADER_LENGTH]; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, status_code); - - if (!msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "msg"); - return (FALSE); - } - - response = GET_SIP_MESSAGE(); - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "GET_SIP_MESSAGE()"); - return (FALSE); - } - - tflag = sippmh_add_response_line(response, SIP_VERSION, status_code, - reason_phrase) ? STATUS_FAILURE : STATUS_SUCCESS; - - UPDATE_FLAGS(flag, tflag); - - tflag = (sipSPIAddRequestVia(NULL, response, msg, sipMethodInvalid)) ? - STATUS_SUCCESS : STATUS_FAILURE; - UPDATE_FLAGS(flag, tflag); - - sip_from = sippmh_get_cached_header_val(msg, FROM); - sip_to = sippmh_get_cached_header_val(msg, TO); - request_callid = sippmh_get_cached_header_val(msg, CALLID); - tflag = sippmh_add_text_header(response, SIP_HEADER_FROM, sip_from); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_TO, sip_to); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(response, SIP_HEADER_CALLID, request_callid); - UPDATE_FLAGS(flag, tflag); - - // Add date header - tflag = sipAddDateHeader(response); - UPDATE_FLAGS(flag, tflag); - - if (reason_phrase_warning) { - char *warning = NULL; - - warning = (char *) cpr_malloc(strlen(reason_phrase_warning) + 5); - if (warning) { - snprintf(warning, strlen(reason_phrase_warning) + 5, - "%d %s", status_code_warning, reason_phrase_warning); - tflag = sippmh_add_text_header(response, SIP_HEADER_WARN, warning); - UPDATE_FLAGS(flag, tflag); - cpr_free(warning); - } - } - - // Add Retry-After, if needed - if (status_code == SIP_SERV_ERR_INTERNAL && - status_code_warning == SIP_WARN_PROCESSING_PREVIOUS_REQUEST) { - tflag = sippmh_add_int_header(response, SIP_HEADER_RETRY_AFTER, - abs((cpr_rand() % 11))); - } - - //Add Accept-Encoding, Accept and Accept-Language headers - //if outgoing response is 415-Unsupported Media Type - if (status_code == SIP_CLI_ERR_MEDIA) { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s", - SIP_CONTENT_TYPE_SDP, - SIP_CONTENT_TYPE_MULTIPART_MIXED, - SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE, - SIP_CONTENT_TYPE_SIPFRAG, - SIP_CONTENT_TYPE_MWI); - // should we add all registered Info Package Content-Type here?? - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT, temp); - UPDATE_FLAGS(flag, tflag); - - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT_ENCODING, - SIP_CONTENT_ENCODING_IDENTITY); - UPDATE_FLAGS(flag, tflag); - - tflag = sippmh_add_text_header(response, SIP_HEADER_ACCEPT_LANGUAGE, - "en"); - UPDATE_FLAGS(flag, tflag); - } - - if (status_code == SIP_CLI_ERR_NOT_ALLOWED) { - // Add Allow - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, SIP_METHOD_OPTIONS, - SIP_METHOD_REFER, SIP_METHOD_UPDATE, SIP_METHOD_SUBSCRIBE); - tflag = sippmh_add_text_header(response, SIP_HEADER_ALLOW, temp); - UPDATE_FLAGS(flag, tflag); - } - - /* Write CSeq */ - request_cseq = sippmh_get_cached_header_val(msg, CSEQ); - if (request_cseq) { - request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - free_sip_message(response); - return (FALSE); - } - tflag = sippmh_add_text_header(response, SIP_HEADER_CSEQ, request_cseq); - method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - UPDATE_FLAGS(flag, tflag); - } else { - CCSIP_DEBUG_ERROR("%s: Error: Did not find valid CSeq header. " - "Cannot send response.\n", fname); - if (response) { - free_sip_message(response); - response = NULL; - } - } - - /* Write Content-Length: 0 */ - tflag = sippmh_add_int_header(response, SIP_HEADER_CONTENT_LENGTH, 0); - UPDATE_FLAGS(flag, tflag); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) { - free_sip_message(response); - response = NULL; - } - } - - /* Determine from the Via field where the message is supposed - * to be sent - */ - if (response) { - result = sendResponse(NULL, response, msg, FALSE, method); - } - if (ccb) { - clean_method_request_trx(ccb, method, FALSE); - } - return (result); -} - -void -sipSPISendFailureResponseAck (ccsipCCB_t *ccb, sipMessage_t *response, - boolean prevcall, line_t previous_call_line) -{ - const char *fname = "sipSPISendFailureResponseAck"; - - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - - char src_addr_str[MAX_IPADDR_STR_LEN]; - static char via[SIP_MAX_VIA_LENGTH]; - char via_branch[SIP_MAX_VIA_LENGTH]; - const char *response_to = NULL; - const char *response_from = NULL; - const char *response_callid = NULL; - const char *response_cseq = NULL; - - cpr_ip_addr_t dest_ipaddr; - cpr_ip_addr_t src_ipaddr; - uint32_t dest_port = 0; - uint32_t cseq_number = 0; - sipCseq_t *response_cseq_structure; - sipMethod_t response_cseq_method = sipMethodInvalid; - sipRespLine_t *respLine = NULL; - int status_code = 0; - char local_ReqURI[MAX_SIP_URL_LENGTH]; - line_t dn_line; - const char *authenticate = NULL; - credentials_t credentials; - sip_authen_t *sip_authen = NULL; - sipAuthenticate_t authen; - char *author_str = NULL; - int nc_count = 0; - boolean bad_authentication = FALSE; - int16_t trx_index = -1; - line_t line; - int nat_enable = 0; - int reldel_stored_msg = RELDEV_NO_STORED_MSG; - - CPR_IP_ADDR_INIT(dest_ipaddr); - CPR_IP_ADDR_INIT(src_ipaddr); - - if (prevcall) { - dest_ipaddr = gCallHistory[previous_call_line].last_bye_dest_ipaddr; - dest_port = gCallHistory[previous_call_line].last_bye_dest_port; - dn_line = gCallHistory[previous_call_line].dn_line; - sstrncpy(local_ReqURI, - gCallHistory[previous_call_line].last_route_request_uri, - sizeof(local_ReqURI)); - sstrncpy(via_branch, gCallHistory[previous_call_line].via_branch, - sizeof(via_branch)); - } else { - /* - * The ACK to a 300-699 response MUST - * be sent to same address, port, and - * transport to which the original request was sent. - */ - dn_line = ccb->dn_line; - // Get the via_branch from the last request that we sent - trx_index = get_method_request_trx_index(ccb, sipMethodInvite, TRUE); - if (trx_index != -1) { - sstrncpy(via_branch, - (const char *)(ccb->sent_request[trx_index].u.sip_via_branch), - sizeof(via_branch)); - } - // via_branch = (char *) ccb->sip_via_branch; - /* - * Use outbound proxy if we used to send messages for this call, - * we are using the default proxy, we are not using the Emergency - * route, and it is not the backup proxy registration. - */ - if (util_check_if_ip_valid(&(ccb->outBoundProxyAddr)) && - (ccb->proxySelection == SIP_PROXY_DEFAULT) && - (ccb->routeMode != RouteEmergency) && - (ccb->index != REG_BACKUP_CCB)) { - dest_ipaddr = ccb->outBoundProxyAddr; - if (ccb->outBoundProxyPort != 0) { - dest_port = ccb->outBoundProxyPort; - } else { - config_get_value(CFGID_OUTBOUND_PROXY_PORT, &dest_port, - sizeof(dest_port)); - } - } else { - dest_ipaddr = ccb->dest_sip_addr; - dest_port = ccb->dest_sip_port; - } - } - - response_cseq = sippmh_get_cached_header_val(response, CSEQ); - if (!response_cseq) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to obtain request's CSeq " - "header.\n", fname); - return; - } - response_cseq_structure = sippmh_parse_cseq(response_cseq); - if (!response_cseq_structure) { - CCSIP_DEBUG_ERROR("%s: Error: Unable to parse request's CSeq " - "header.\n", fname); - return; - } - cseq_number = response_cseq_structure->number; - response_cseq_method = response_cseq_structure->method; - cpr_free(response_cseq_structure); - - // Process the Failure response - response_to = sippmh_get_cached_header_val(response, TO); - response_from = sippmh_get_cached_header_val(response, FROM); - response_callid = sippmh_get_cached_header_val(response, CALLID); - - request = GET_SIP_MESSAGE(); - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "GET_SIP_MESSAGE()"); - return; - } - - /* - * Determine the Request-URI - */ - respLine = sippmh_get_response_line(response); - if (respLine) { - status_code = respLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(respLine); - } - - if (prevcall == FALSE) { - char tmp_ReqURI[MAX_SIP_URL_LENGTH]; - - // Save original ReqURI - sstrncpy(tmp_ReqURI, ccb->ReqURI, MAX_SIP_URL_LENGTH); - // Update ReqURI using RR, etc - (void) sipSPIGenRequestURI(ccb, sipMethodAck, FALSE); - // Use the ReqURI - sstrncpy(local_ReqURI, ccb->ReqURI, MAX_SIP_URL_LENGTH); - // Restore original ReqURI - sstrncpy(ccb->ReqURI, tmp_ReqURI, MAX_SIP_URL_LENGTH); - - // Clean up the INVITE transaction block as we no longer need it - clean_method_request_trx(ccb, sipMethodInvite, TRUE); - } - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&src_ipaddr); - ipaddr2dotted(src_addr_str, &src_ipaddr); - } else { - sip_config_get_nat_ipaddr(&src_ipaddr); - ipaddr2dotted(src_addr_str, &src_ipaddr); - } - - /* - * Build the request - */ - tflag = sippmh_add_request_line(request, SIP_METHOD_ACK, local_ReqURI, - SIP_VERSION); - UPDATE_FLAGS(flag, tflag); - - /* Write Via */ - if (prevcall) { - /* - * Use line 1 as default to get the transport type. - * Transport type is going to be device specific with - * the first release of skittles. Will need to change - * for mixed cc mode support. - */ - line = 1; - } else { - line = ccb->dn_line; - } - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s", - sipTransportGetTransportType(line, TRUE, ccb), - src_addr_str, sipTransportGetListenPort(line, ccb), - VIA_BRANCH, via_branch); - tflag = sippmh_add_text_header(request, SIP_HEADER_VIA, via); - UPDATE_FLAGS(flag, tflag); - - /* Write To, From, and Call-ID standard headers */ - tflag = sippmh_add_text_header(request, SIP_HEADER_FROM, response_from); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(request, SIP_HEADER_TO, response_to); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(request, SIP_HEADER_CALLID, response_callid); - UPDATE_FLAGS(flag, tflag); - - switch (status_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - if (response_cseq_method == sipMethodAck) { - authen.authorization = NULL; - cred_get_line_credentials(dn_line, &credentials, - sizeof(credentials.id), - sizeof(credentials.pw)); - authenticate = sippmh_get_header_val(response, - AUTH_HDR(status_code), NULL); - if (authenticate != NULL) { - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen) { - if (sipSPIGenerateAuthorizationResponse(sip_authen, - local_ReqURI, - SIP_METHOD_ACK, - credentials.id, - credentials.pw, - &author_str, - &nc_count, NULL)) { - authen.authorization = (char *) - cpr_malloc(strlen(author_str) * sizeof(char) + 1); - if (authen.authorization != NULL) { - sstrncpy(authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - authen.status_code = status_code; - } else { - CCSIP_DEBUG_ERROR("%s: Error: malloc() failed " - "for authen.authorization\n", - fname); - bad_authentication = TRUE; - } - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR("%s: Error: " - "sipSPIGenerateAuthorizationResponse()" - " returned null.\n", fname); - bad_authentication = TRUE; - } - sippmh_free_authen(sip_authen); - } else { - CCSIP_DEBUG_ERROR("%s: Error: sippmh_parse_authenticate() " - "returned null.\n", fname); - bad_authentication = TRUE; - } - } else { - CCSIP_DEBUG_ERROR("%s: Error: sippmh_get_header_val(AUTH_HDR) " - "returned null.\n", fname); - bad_authentication = TRUE; - } - - if (!bad_authentication) { - tflag = sippmh_add_text_header(request, - AUTHOR_HDR(status_code), - authen.authorization); - cpr_free(authen.authorization); - UPDATE_FLAGS(flag, tflag); - } else { - CCSIP_DEBUG_ERROR("%s: Error: Bad authentication header.\n", - fname); - if (request) { - free_sip_message(request); - } - if (authen.authorization) { - cpr_free(authen.authorization); - } - return; - } - - } - break; - - default: - break; - } - - /* Write Date header */ - tflag = sipAddDateHeader(request); - UPDATE_FLAGS(flag, tflag); - - /* Write CSeq */ - tflag = sippmh_add_cseq(request, SIP_METHOD_ACK, cseq_number); - UPDATE_FLAGS(flag, tflag); - - /* Add Route Header */ - tflag = (sipSPIAddRouteHeaders(request, ccb, NULL, 0)) ? - STATUS_SUCCESS : STATUS_FAILURE; - - /* Write Content-Length */ - tflag = sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0); - UPDATE_FLAGS(flag, tflag); - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) { - free_sip_message(request); - } - return; - } - /* Store the ACK so that it can be retransmitted in response - * to any duplicate 200 OK or error responses - */ - if ((previous_call_line == 0xFF) && (prevcall == FALSE)) { - CCSIP_DEBUG_ERROR("%s: INFO: Skipping store for this Ack\n", fname); - } else { - reldel_stored_msg = sipRelDevCoupledMessageStore(request, - response_callid, - cseq_number, - response_cseq_method, - TRUE, - status_code, - &dest_ipaddr, - (int16_t)dest_port, - FALSE /*Do check tag*/); - } - /* Send message */ - if (sipTransportChannelCreateSend(NULL, request, sipMethodAck, - &dest_ipaddr, (int16_t)dest_port, 0, - reldel_stored_msg) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportChannelCreateSend()"); - if (request) - free_sip_message(request); - return; - } - - return; -} - - -/* - * Resend the last message sent - */ -boolean -sipSPISendLastMessage (ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISendLastMessage"; - - /* Args Check */ - if (!ccb) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "ccb"); - return (FALSE); - } - - - /* Send message */ - if (ccb->index == 0) { - if (sipTransportSendMessage(ccb, - sipPlatformUISMTimers[ccb->index].message_buffer, - sipPlatformUISMTimers[ccb->index].message_buffer_len, - sipPlatformUISMTimers[ccb->index].message_type, - &(sipPlatformUISMTimers[ccb->index].ipaddr), - sipPlatformUISMTimers[ccb->index].port, - TRUE, TRUE, 0, NULL) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportSendMessage()"); - return (FALSE); - } - } else { - if (sipTransportChannelSend(ccb, - sipPlatformUISMTimers[ccb->index].message_buffer, - sipPlatformUISMTimers[ccb->index].message_buffer_len, - sipPlatformUISMTimers[ccb->index].message_type, - &(sipPlatformUISMTimers[ccb->index].ipaddr), - sipPlatformUISMTimers[ccb->index].port, 0) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportChannelSend()"); - return (FALSE); - } - } - return (TRUE); -} - -void -sipGetRequestMethod (sipMessage_t *pRequest, sipMethod_t *pMethod) -{ - const char *fname = "SIPGetRequestMethod"; - sipReqLine_t *pReqLine = NULL; - - *pMethod = sipMethodInvalid; - pReqLine = sippmh_get_request_line(pRequest); - - if (!pReqLine) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_request_line()"); - return; - } - - if (pReqLine->method) { - *pMethod = sippmh_get_method_code(pReqLine->method); - } else { - CCSIP_DEBUG_ERROR("%s: Error: No recognizable method in Req-URI!\n", - fname); - } - - SIPPMH_FREE_REQUEST_LINE(pReqLine); - return; -} - - -int -sipGetResponseMethod (sipMessage_t *pResponse, sipMethod_t *pMethod) -{ - const char *fname = "SIPGetResponseMethod"; - sipRespLine_t *pRespLine = NULL; - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - - pRespLine = sippmh_get_response_line(pResponse); - if (pRespLine) { - cseq = sippmh_get_cached_header_val(pResponse, CSEQ); - if (!cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CSEQ)"); - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - return (-1); - } - /* Extract method code */ - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - return (-1); - } - *pMethod = sipCseq->method; - cpr_free(sipCseq); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_response_line()"); - return (-1); - } - - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - return (0); -} - - -int -sipGetResponseCode (sipMessage_t *pResponse, int *pResponseCode) -{ - const char *fname = "SIPGetResponseCode"; - sipRespLine_t *pRespLine = NULL; - - pRespLine = sippmh_get_response_line(pResponse); - if (pRespLine) { - *pResponseCode = pRespLine->status_code; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_response_line()"); - return (-1); - } - - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - return (0); -} - - -/* - * Util workhorse to add the standard headers to all SIP messages. - * Does not affect call state. - */ -boolean -sipSPIAddStdHeaders (sipMessage_t *msg, ccsipCCB_t *ccb, boolean isResponse) -{ - boolean retval = FALSE; - boolean flip = TRUE; - int max_fwd = 0; - - if (!(ccb && msg)) { - return (retval); - } - - if (isResponse) { - if (ccb->flags & INCOMING) { - flip = FALSE; - } else { - flip = TRUE; - } - } else { - if (ccb->flags & INCOMING) { - flip = TRUE; - } else { - flip = FALSE; - } - } - - if (!flip) { - retval = (boolean) - ((STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_FROM, - ccb->sip_from)) && - (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_TO, - ccb->sip_to)) && - (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_CALLID, - ccb->sipCallID))); - } else { - retval = (boolean) - ((STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_FROM, - ccb->sip_to)) && - (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_TO, - ccb->sip_from)) && - (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_CALLID, - ccb->sipCallID))); - } - - // Add max-forwards header if this is a request - if (isResponse == FALSE && retval == TRUE) { - config_get_value(CFGID_SIP_MAX_FORWARDS, &max_fwd, sizeof(max_fwd)); - if (max_fwd == 0) { - max_fwd = SIP_MAX_FORWARDS_DEFAULT_VALUE; - } - if (sippmh_add_int_header(msg, SIP_HEADER_MAX_FORWARDS, max_fwd) - != STATUS_SUCCESS) { - retval = FALSE; - } - } - return (retval); -} - - -/* - * Add a SIP Via header to the sipMessage_t. - * Should return (TRUE) if the right members are - * present in the CCB struct. - * Does not affect call state. - */ -boolean -sipSPIAddLocalVia (sipMessage_t *msg, ccsipCCB_t *ccb, sipMethod_t method) -{ - const char *fname = "sipSPIAddLocalVia"; - - if (msg && ccb) { - if (util_check_if_ip_valid(&(ccb->src_addr))) { - static char via[SIP_MAX_VIA_LENGTH]; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char *sip_via_branch; - int16_t trx_index = -1; - - /* - * We don't allocate a block for ACK(200 OK) although - * it is technically another transaction. Instead we - * locate the INVITE transaction in ccb. - */ - if (method == sipMethodAck) { - trx_index = get_method_request_trx_index(ccb, sipMethodInvite, - TRUE); - } else { - trx_index = get_last_request_trx_index(ccb, TRUE); - } - - if (trx_index < 0) { - return FALSE; - } - ipaddr2dotted(src_addr_str, &ccb->src_addr); - if (method == sipMethodCancel) { - // Get the via header from last sent request transaction - if (trx_index < 1) { - return FALSE; - } - sip_via_branch = strlib_open(ccb->sent_request[trx_index].u.sip_via_branch, - VIA_BRANCH_LENGTH); - sstrncpy(sip_via_branch, (char *)(ccb->sent_request[trx_index - 1].u.sip_via_branch), VIA_BRANCH_LENGTH); - ccb->sent_request[trx_index].u.sip_via_branch = strlib_close(sip_via_branch); - - snprintf(via, sizeof(via), - "SIP/2.0/%s %s:%d;%s=%s", - sipTransportGetTransportType(ccb->dn_line, TRUE, ccb), - src_addr_str, ccb->local_port, VIA_BRANCH, - (char *)(ccb->sent_request[trx_index].u.sip_via_branch)); - - } else { - snprintf(via, sizeof(via), - "SIP/2.0/%s %s:%d;%s=", - sipTransportGetTransportType(ccb->dn_line, TRUE, ccb), - src_addr_str, ccb->local_port, VIA_BRANCH); - - sip_via_branch = strlib_open(ccb->sent_request[trx_index].u.sip_via_branch, - VIA_BRANCH_LENGTH); - if (sip_via_branch) { - snprintf(sip_via_branch, VIA_BRANCH_LENGTH, - "%s%.8x", VIA_BRANCH_START, - (unsigned int)cpr_rand()); - } - ccb->sent_request[trx_index].u.sip_via_branch = - strlib_close(sip_via_branch); - - if (sip_via_branch) { - sstrncat(via, sip_via_branch, - SIP_MAX_VIA_LENGTH - strlen(via)); - } - } - if (sippmh_add_text_header(msg, SIP_HEADER_VIA, via) - != STATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_add_text_header(VIA)"); - return (FALSE); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "ccb->src_addr"); - return (FALSE); - } - } - - return (TRUE); -} - - -/* - * For a response, add the Via headers that came in with the - * request to the response. - */ -boolean -sipSPIAddRequestVia (ccsipCCB_t *ccb, sipMessage_t *response, - sipMessage_t *request, sipMethod_t method) -{ - const char *fname = "sipSPIAddRequestVia"; - int16_t trx_index = -1; - - /* Check args */ - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "response"); - return (FALSE); - } - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "request"); - return (FALSE); - } - - // Get the stored via from the transaction that we are responding to - if (ccb) { - trx_index = get_method_request_trx_index(ccb, method, FALSE); - if (trx_index >= 0) { - (void) sippmh_add_text_header(response, SIP_HEADER_VIA, - (char *)(ccb->recv_request[trx_index].u.sip_via_header)); - return (TRUE); - } - } - - // If no transaction, get the via directly from the request - (void) sippmh_add_text_header(response, SIP_HEADER_VIA, - sippmh_get_cached_header_val(request, VIA)); - - return (TRUE); -} - - -/* - * Procedure to add a Route/Record-Route header in SIP responses - */ -boolean -sipSPIAddRouteHeaders (sipMessage_t *msg, ccsipCCB_t *ccb, - char *result_route, int result_route_length) -{ - const char *fname = "SIPSPIAddRouteHeaders"; - /* NOTE: route will be limited to 4 hops */ - static char route[MAX_SIP_HEADER_LENGTH * NUM_INITIAL_RECORD_ROUTE_BUFS]; - static char Contact[MAX_SIP_HEADER_LENGTH]; - boolean lr = FALSE; - - /* Check args */ - if (!msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "msg"); - return (FALSE); - } - if (!ccb) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "ccb"); - return (FALSE); - } - - if (!ccb->record_route_info) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Route info not available; will not" - " add Route header.\n", DEB_F_PREFIX_ARGS(SIP_ROUTE, fname)); - return (TRUE); - } - - memset(route, 0, MAX_SIP_HEADER_LENGTH * NUM_INITIAL_RECORD_ROUTE_BUFS); - memset(Contact, 0, MAX_SIP_HEADER_LENGTH); - - if (ccb->flags & INCOMING) { - /* - * For Incoming call (UAS), Copy the RR headers as it is - * If Contact is present, append it at the end - */ - if (sipSPIGenerateRouteHeaderUAS(ccb->record_route_info, route, - sizeof(route), &lr) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateRouteHeaderUAS()"); - return (FALSE); - } - } else { - /* - * For Outgoing call (UAC), Copy the RR headers in the reverse - * order. If Contact is present, append it at the end - */ - if (sipSPIGenerateRouteHeaderUAC(ccb->record_route_info, route, - sizeof(route), &lr) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateRouteHeaderUAC()"); - return (FALSE); - } - } - /* - * If loose_routing is TRUE, then the contact header is NOT appended - * to the Routeset but is instead used in the Req-URI - */ - if (!lr) { - Contact[0] = '\0'; - if (sipSPIGenerateContactHeader(ccb->contact_info, Contact, - sizeof(Contact)) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateContactHeader()"); - return (FALSE); - } - - /* Append Contact to the Route Header, if Contact is available */ - if (Contact[0] != '\0') { - if (route[0] != '\0') { - sstrncat(route, ", ", sizeof(route) - strlen(route)); - } - sstrncat(route, Contact, sizeof(route) - strlen(route)); - } - } - - if (route[0] != '\0') { - if (sippmh_add_text_header(msg, SIP_HEADER_ROUTE, route) - == STATUS_SUCCESS) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Adding route = %s\n", - DEB_F_PREFIX_ARGS(SIP_ROUTE, fname), route); - if (result_route) { - sstrncpy(result_route, route, result_route_length); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_add_text_header(ROUTE)"); - return (FALSE); - } - } else { - /* Having nothing in Route header is a legal case. - * This would happen when the Record-Route header has - * a single entry and Contact was NULL - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Not adding route \n", DEB_F_PREFIX_ARGS(SIP_ROUTE, fname)); - } - - return (TRUE); -} - - -boolean -sipSPIAddRequestRecordRoute (sipMessage_t *response, sipMessage_t *request) -{ - const char *fname = "SIPSPIAddRequestRecordRoute"; - - /* Check args */ - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "response"); - return (FALSE); - } - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "request"); - return (FALSE); - } - - (void) sippmh_add_text_header(response, SIP_HEADER_RECORD_ROUTE, - sippmh_get_cached_header_val(request, RECORD_ROUTE)); - - return (TRUE); -} - - -/* - * Procedure to add a proprietary SIP header to carry GUID in the SIP messsage - */ -boolean -sipSPIAddCiscoGuid (sipMessage_t *msg, ccsipCCB_t *ccb) -{ - boolean retval = STATUS_FAILURE; -/* - const char *fname = "sipSPIAddCiscoGuid"; - uint32_t guid[4]; - char guid_char[4*CC_GUID_SIZE]; - - if (ccb && msg) { - - memcpy(&guid[0], ccb->guid, sizeof(guid[0])); - memcpy(&guid[1], &ccb->guid[sizeof(guid[0])], sizeof(guid[0])); - memcpy(&guid[2], &ccb->guid[2*sizeof(guid[0])], sizeof(guid[0])); - memcpy(&guid[3], &ccb->guid[3*sizeof(guid[0])], sizeof(guid[0])); - - sprintf(guid_char, "%u-%u-%u-%u", guid[0], guid[1], guid[2], guid[3]); - - retval = (STATUS_SUCCESS == sippmh_add_text_header(msg, - SIP_HEADER_CISCO_GUID, - guid_char)); - } else { - CCSIP_DEBUG_ERROR("%s: Error: Fatal error in parsing ccb.\n", - fname); - } -*/ - return (retval); -} - -int -sipSPICheckContentHeaders (sipMessage_t *msg) -{ - uint8_t i; - const char *accept_hdr = NULL; - const char *content_enc = NULL; - const char *content_disp_str = NULL; - const char *accepted_enc_str = NULL; - cc_content_disposition_t *content_disp = NULL; - const char *fname = "sipSPICheckContentHeaders"; - sipMethod_t method = sipMethodInvalid; - char *lasts = NULL; - - if (!msg) { - return (SIP_MESSAGING_ERROR); - } - - if (sippmh_msg_header_present(msg, SIP_HEADER_ACCEPT)) { - accept_hdr = sippmh_get_header_val(msg, SIP_HEADER_ACCEPT, NULL); - if (!accept_hdr) { - if (sippmh_is_request(msg)) { - sipGetRequestMethod(msg, &method); - if (method == sipMethodInvite) { - /* - * Currently we are rejecting empty Accept headers for - * INVITE only. This check is done here instead of - * previously because Accept is Content related header - * and also in the future if we want to extend this - * check to other requests and responses this would be - * a good place - */ - return (SIP_MESSAGING_NOT_ACCEPTABLE); - } - } - } - } - content_enc = sippmh_get_header_val(msg, SIP_HEADER_CONTENT_ENCODING, - SIP_C_HEADER_CONTENT_ENCODING); - content_disp_str = sippmh_get_header_val(msg, SIP_HEADER_CONTENT_DISP, - SIP_HEADER_CONTENT_DISP); - accepted_enc_str = sippmh_get_header_val(msg, SIP_HEADER_ACCEPT_ENCODING, - SIP_HEADER_ACCEPT_ENCODING); - if (content_disp_str) { - content_disp = sippmh_parse_content_disposition(content_disp_str); - } - - // Check Content-Encoding - // Only identity encoding is supported at this time - if (content_enc) { - if (cpr_strcasecmp(content_enc, SIP_CONTENT_ENCODING_IDENTITY)) { - // If Content-Encoding is not understood, check to see if - // the Content-Disposition is required. If so, flag an error - if (content_disp) { - if (content_disp->required_handling) { - cpr_free(content_disp); - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } else { - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } - } - - // Check Content-Disposition - // Only disposition of "session", if not reject if handling it - // content is required - if (content_disp) { - if (content_disp->disposition != cc_disposition_session) { - if (content_disp->required_handling) { - cpr_free(content_disp); - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } - } - if (content_disp) { - cpr_free(content_disp); - } - - if (accepted_enc_str) { - //parse the accepted_enc_str - //check to see if it contains "identity" - //if it does not contain "identity" return error - - boolean found = FALSE; - char *ptr = NULL; - char *accepted_enc_str_dup; - - accepted_enc_str_dup = cpr_strdup(accepted_enc_str); - if (accepted_enc_str_dup == NULL) { - CCSIP_DEBUG_ERROR("%s: Error: cpr_strdup() failed " - "for accepted_enc_str_dup\n", fname); - return (SIP_SERV_ERR_INTERNAL); - } - - ptr = PL_strtok_r(accepted_enc_str_dup, ", ", &lasts); - - while (ptr) { - if (strcmp(ptr, SIP_CONTENT_ENCODING_IDENTITY) == 0) { - found = TRUE; - break; - } - ptr = PL_strtok_r(NULL, ", ", &lasts); - } - - cpr_free(accepted_enc_str_dup); - - if (found == FALSE) { - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } - - - // Check all the body parts - for (i = 0; i < HTTPISH_MAX_BODY_PARTS; i++) { - if (msg->mesg_body[i].msgBody) { - if (msg->mesg_body[i].msgContentTypeValue - == SIP_CONTENT_TYPE_UNKNOWN_VALUE) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Pass-through \"%s\"\n", - DEB_F_PREFIX_ARGS(SIP_CONTENT_TYPE, fname), - msg->mesg_body[i].msgContentType); - // return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - if ((msg->mesg_body[i].msgContentEnc - != SIP_CONTENT_ENCODING_IDENTITY_VALUE) && - (msg->mesg_body[i].msgRequiredHandling == TRUE)) { - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - if ((msg->mesg_body[i].msgContentDisp - != SIP_CONTENT_DISPOSITION_SESSION_VALUE) && - (msg->mesg_body[i].msgRequiredHandling == TRUE)) { - return (SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA); - } - } - } - - return (SIP_MESSAGING_OK); -} - -// This function returns TRUE if the header length is acceptable -boolean -is_good_header_length (const char *header, uint8_t header_type) -{ - - if (!header) { - return FALSE; - } - switch (header_type) { - case FROM: - case TO: - if ((strlen(header) >= MAX_SIP_URL_LENGTH) || (strlen(header) == 0)) { - return FALSE; - } - break; - case CALLID: - if ((strlen(header) >= MAX_SIP_CALL_ID) || (strlen(header) == 0)) { - return FALSE; - } - break; - default: - break; - } - return TRUE; -} - -/* - * sipCheckRequestURI - * - * Check the validity of mandatory fields in Req URI - * - * Adding restrictive checks to the following will break - * ccm features: "user=phone" - * - */ -int -sipCheckRequestURI (ccsipCCB_t *ccb, sipMessage_t *request) -{ - sipReqLine_t *requestURI = NULL; - genUrl_t *genUrl = NULL; - sipUrl_t *sipUriUrl = NULL; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char *pUser = NULL; - cpr_ip_addr_t src_addr; - int nat_enable = 0; - boolean request_uri_error = FALSE; - int errorCode = SIP_MESSAGING_ERROR; - cpr_ip_addr_t ipaddr; - - CPR_IP_ADDR_INIT(src_addr); - CPR_IP_ADDR_INIT(ipaddr); - - requestURI = sippmh_get_request_line(request); - if (requestURI) { - if (requestURI->url) { - genUrl = sippmh_parse_url(requestURI->url, TRUE); - if (genUrl) { - if (genUrl->schema == URL_TYPE_SIP) { - sipUriUrl = genUrl->u.sipUrl; - } - if (sipUriUrl) { - pUser = sippmh_parse_user(sipUriUrl->user); - if (pUser) { - if (sipUriUrl->host) { - if (!str2ip(sipUriUrl->host, &ipaddr)) { - config_get_value(CFGID_NAT_ENABLE, &nat_enable, - sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&src_addr); - } else { - sip_config_get_nat_ipaddr(&src_addr); - } - ipaddr2dotted(src_addr_str, &src_addr); - if (strcmp(sipUriUrl->host, src_addr_str)) { - if (!validateHostName(sipUriUrl->host, pUser)) { - CCSIP_DEBUG_ERROR("Unknown address in Request URI\n"); - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } - } - } else { - if (!validateHostName(sipUriUrl->host, pUser)) { - CCSIP_DEBUG_ERROR("Unknown address in Request URI\n"); - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } - } - if (sipUriUrl->port_present) { - if (ccb && - cpr_strcasecmp(sipTransportGetTransportType(ccb->dn_line, FALSE, ccb), "udp") == 0) { - if (sipUriUrl->port != ccb->local_port) { - CCSIP_DEBUG_ERROR("Port Mismatch(UDP), URL Port: %d, Port Used: %d\n", - sipUriUrl->port, ccb->local_port); - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } - } - } - } - if (pUser[0] == '\0') { - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } else { - if (ccb && !request_uri_error) { - sstrncpy(ccb->ReqURI, pUser, - sizeof(ccb->ReqURI)); - } - } - cpr_free(pUser); - } - } - sippmh_genurl_free(genUrl); - } else { - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ENDPOINT_NOT_FOUND; - } - } else { - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ERROR; - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } else { - request_uri_error = TRUE; - errorCode = SIP_MESSAGING_ERROR; - } - - if (request_uri_error) { - return errorCode; - } else { - return (SIP_MESSAGING_OK); - } -} - -/* - * This is called for every request received. - * It checks the basic fields(url, From, To). - * Does not affect call state. - * It sends error responses for generic error types. - */ -int -sipSPICheckRequest (ccsipCCB_t *ccb, sipMessage_t *request) -{ - const char *fname = "sipSPICheckRequest"; - const char *callID = NULL; - const char *via = NULL; - const char *from = NULL; - const char *to = NULL; - const char *contact = NULL; - int retval = SIP_MESSAGING_OK; - char *replaceshdr = NULL; - - const char *request_cseq = NULL; - sipCseq_t *request_cseq_structure = NULL; - uint32_t request_cseq_number = 0; - sipMethod_t request_cseq_method = sipMethodInvalid; - sipReqLine_t *requestURI; - - /* - * Check args - CCB may be NULL - */ - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "request"); - return (SIP_MESSAGING_ERROR); - } - - /* - * Check for the incomplete message body - */ - if (!sippmh_is_message_complete(request)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_is_message_complete()"); - return (SIP_MESSAGING_ERROR); - } - - - if ((retval = sipCheckRequestURI(ccb, request)) != SIP_MESSAGING_OK) { - CCSIP_DEBUG_ERROR("%s: Request URI Not Found\n", fname); - return (retval); - } - - - /* - * Check whether all mandatory SIP request headers are there. - * Also check if their lengths are within an acceptable range. - */ - from = sippmh_get_cached_header_val(request, FROM); - if (!from || (!is_good_header_length(from, FROM))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(FROM)"); - return (SIP_MESSAGING_ERROR); - } - - to = sippmh_get_cached_header_val(request, TO); - if (!to || (!is_good_header_length(to, TO))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(TO)"); - return (SIP_MESSAGING_ERROR); - } - - via = sippmh_get_cached_header_val(request, VIA); - if (!via) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(VIA)"); - return (SIP_MESSAGING_ERROR); - } - - callID = sippmh_get_cached_header_val(request, CALLID); - if (!callID || (!is_good_header_length(callID, CALLID))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CALLID)"); - return (SIP_MESSAGING_ERROR); - } - - contact = sippmh_get_cached_header_val(request, CONTACT); - if (contact) { - int contact_check_result = 0; - - contact_check_result = sipSPICheckContact(contact); - if (contact_check_result < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPICheckContact()"); - return contact_check_result; - } - } - - if ((retval = sipSPICheckContentHeaders(request)) != SIP_MESSAGING_OK) { - CCSIP_DEBUG_ERROR("%s: Content header value not supported\n", fname); - return (retval); - } - - /* - * Check whether the current call id and this request's CallId match - */ - if (ccb && ccb->sipCallID[0]) { - if (strcmp(ccb->sipCallID, callID) != 0) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Call ID match: new call id.\n", DEB_F_PREFIX_ARGS(SIP_CALL_ID, fname)); - retval = SIP_MESSAGING_NEW_CALLID; - } else { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Call ID match: same call id.\n", DEB_F_PREFIX_ARGS(SIP_CALL_ID, fname)); - } - } - - /* - * Parse CSeq - */ - request_cseq = sippmh_get_cached_header_val(request, CSEQ); - if (!request_cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CSEQ)"); - return (SIP_MESSAGING_ERROR); - } - - request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - return (SIP_MESSAGING_ERROR); - } - request_cseq_number = request_cseq_structure->number; - request_cseq_method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - - // Check continuity of this request wrt CSeq number and method - if (request_cseq_method != sipMethodAck && - request_cseq_method != sipMethodCancel) { - // If ccb is present, check if the CSeq number is acceptable - if (ccb) { - if (request_cseq_number < ccb->last_recv_request_cseq) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Inconsistent CSEQ number. " - "current= %d, last= %d.\n", - DEB_F_PREFIX_ARGS(SIP_CSEQ, fname), request_cseq_number, - ccb->last_recv_request_cseq); - - return (SIP_CLI_ERR_BAD_REQ); - } - if (request_cseq_number == ccb->last_recv_request_cseq) { - if (request_cseq_method != ccb->last_recv_request_cseq_method) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Inconsistent CSEQ method. " - "current= %s, last= %s\n.", - DEB_F_PREFIX_ARGS(SIP_CSEQ, fname), - sipGetMethodString(request_cseq_method), - sipGetMethodString(ccb->last_recv_request_cseq_method)); - - return (SIP_CLI_ERR_BAD_REQ); - } - } - } - } - - if (request->mesg_line) { - if (strlen(request->mesg_line) >= MAX_SIP_URL_LENGTH) { - CCSIP_DEBUG_ERROR("%s: Request URI length exceeds acceptable value\n", - fname); - return (SIP_MESSAGING_ERROR); - } - } - - requestURI = sippmh_get_request_line(request); - if (requestURI) { - if (sippmh_get_method_code(requestURI->method) != request_cseq_method) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "Method in RURI != method in CSeq"); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return (SIP_MESSAGING_ERROR); - } - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - - if (request_cseq_method != sipMethodInvite) { - if (sippmh_msg_header_present(request, SIP_HEADER_REPLACES)) { - CCSIP_DEBUG_ERROR("%s: Error: Replace header is not valid for " - "this request\n", fname); - return SIP_MESSAGING_ERROR; - } - } else { - if (sippmh_get_num_particular_headers(request, SIP_HEADER_REPLACES, - NULL, &replaceshdr, MAX_REPLACES_HEADERS + 1) - > MAX_REPLACES_HEADERS) { - CCSIP_DEBUG_ERROR("%s: Error: More than one replaces header " - "in this request\n", fname); - return SIP_MESSAGING_ERROR; - } - } - - /* - * Reliable Delivery - */ - if (SipRelDevEnabled) { - /* - * responseRecord is a static because the structure it is made out of is - * so large. - */ - static sipRelDevMessageRecord_t requestRecord; - int handle = -1; - const char *reldev_to = NULL; - sipLocation_t *reldev_to_loc = NULL; - char reldev_to_tag[MAX_SIP_TAG_LENGTH]; - const char *reldev_from = NULL; - sipLocation_t *reldev_from_loc = NULL; - char reldev_from_tag[MAX_SIP_TAG_LENGTH]; - - memset(&requestRecord, 0, sizeof(requestRecord)); - memset(reldev_to_tag, 0, MAX_SIP_TAG_LENGTH); - memset(reldev_from_tag, 0, MAX_SIP_TAG_LENGTH); - - /* Get to_tag */ - reldev_to = sippmh_get_cached_header_val(request, TO); - - if (reldev_to) { - reldev_to_loc = sippmh_parse_from_or_to((char *)reldev_to, TRUE); - if (reldev_to_loc) { - if (reldev_to_loc->genUrl->schema != URL_TYPE_SIP) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), - fname); - sippmh_free_location(reldev_to_loc); - return (SIP_CLI_ERR_FORBIDDEN); - } - - if (reldev_to_loc->tag) { - sstrncpy(reldev_to_tag, - sip_sm_purify_tag(reldev_to_loc->tag), - MAX_SIP_TAG_LENGTH); - } - sstrncpy(requestRecord.to_user, - reldev_to_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sippmh_free_location(reldev_to_loc); - - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - return (SIP_MESSAGING_ERROR); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(TO)"); - return (SIP_MESSAGING_ERROR); - } - - /* Store from_user and from_host */ - reldev_from = sippmh_get_cached_header_val(request, FROM); - if (reldev_from) { - reldev_from_loc = sippmh_parse_from_or_to((char *)reldev_from, TRUE); - if (reldev_from_loc) { - sstrncpy(requestRecord.from_user, - reldev_from_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sstrncpy(requestRecord.from_host, - reldev_from_loc->genUrl->u.sipUrl->host, - RELDEV_MAX_HOST_NAME_LEN); - if (reldev_from_loc->tag) { - sstrncpy(reldev_from_tag, - sip_sm_purify_tag(reldev_from_loc->tag), - MAX_SIP_TAG_LENGTH); - } - sippmh_free_location(reldev_from_loc); - } - } - - /* Check whether the tag matches the stored tag */ - if (ccb) { - if ((request_cseq_method == sipMethodInvite) || - (request_cseq_method == sipMethodAck) || - (request_cseq_method == sipMethodBye)) { - - boolean to_tag_match = TRUE; - boolean from_tag_match = TRUE; - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"in_to_tag:<%s>, in_from_tag:<%s>, " - "stored to tag=<%s>, stored from tag=<%s>\n", - DEB_F_PREFIX_ARGS(SIP_TAG, fname), reldev_to_tag, reldev_from_tag, - ccb->sip_to_tag, ccb->sip_from_tag); - - /* Check to_tag first */ - if (ccb->sip_to_tag[0]) { - if ((request_cseq_method == sipMethodBye) && - (reldev_to_tag[0] == '\0') && - (SIP_SM_CALL_SETUP_NOT_COMPLETED(ccb))) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Allow early call termination " - "BYE.\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } else if ((request_cseq_method == sipMethodInvite) && - (reldev_to_tag[0] == '\0') && - (SIP_SM_CALL_SETUP_NOT_COMPLETED(ccb))) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Allow crossed " - "response and INVITE.\n", DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname)); - } else { - if (ccb->flags & INCOMING) { - // Incoming request for an incoming call - // Match the stored to-tag with the to-tag in request - if (strcasecmp_ignorewhitespace(reldev_to_tag, - ccb->sip_to_tag) != 0) { - to_tag_match = FALSE; - } - } else { - // We made the call, so match the stored to-tag - // with the from-tag in the incoming request - if (strcasecmp_ignorewhitespace(reldev_from_tag, - ccb->sip_to_tag) != 0) { - to_tag_match = FALSE; - } - } - } - } - if (!to_tag_match) { - CCSIP_DEBUG_ERROR("%s: To-Tag mismatch detected!\n", fname); - return (SIP_CLI_ERR_CALLEG); - } - // Now check from-tag - if (ccb->sip_from_tag[0]) { - if (ccb->flags & INCOMING) { - // Incoming request for an incoming call - // Match the stored from-tag with the from-tag in request - if (strcasecmp_ignorewhitespace(reldev_from_tag, - ccb->sip_from_tag) != 0) { - from_tag_match = FALSE; - } - } else { - // We made the call, so match the stored from-tag - // with the to-tag in the incoming request - if (strcasecmp_ignorewhitespace(reldev_to_tag, - ccb->sip_from_tag) != 0) { - from_tag_match = FALSE; - } - } - if (!from_tag_match) { - CCSIP_DEBUG_ERROR("%s: From-Tag mismatch detected!\n", - fname); - return (SIP_CLI_ERR_CALLEG); - } - } - } - } - - requestRecord.is_request = TRUE; - sstrncpy(requestRecord.call_id, (callID) ? callID : "", - MAX_SIP_CALL_ID); - requestRecord.cseq_number = request_cseq_number; - requestRecord.cseq_method = request_cseq_method; - sstrncpy(requestRecord.tag, reldev_to_tag, MAX_SIP_TAG_LENGTH); - if (ccb) { - //requestRecord.line = ccb->index; - } else { - //requestRecord.line = 1; - } - if (ccb && (requestRecord.cseq_method == sipMethodInvite) && - (ccb->state == SIP_STATE_IDLE)) { - sipRelDevMessagesClear(requestRecord.call_id, - requestRecord.from_user, - requestRecord.from_host, - requestRecord.to_user); - } - /* Check if duplicate */ - if (sipRelDevMessageIsDuplicate(&requestRecord, &handle)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Duplicate request detected...\n", DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - // If the request is an ACK we do not have any thing to send - // This was retransmitted ACK so drop it. - if (requestRecord.cseq_method != sipMethodAck) { - if (sipRelDevCoupledMessageSend(handle) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipRelDevCoupledMessageSend()"); - } - } - return (SIP_MESSAGING_DUPLICATE); - } - - /* Record the request in Recent Requests List */ - sipRelDevMessageStore(&requestRecord); - } - return (retval); -} - - -/* - * This is called for every response received. - * It checks the basic fields(response line, From, To). - * If a session description is present, it reads and parses it. - * (and overwrites an old one if present in the CCB.) - * Does not affect call state. - * Returns TRUE if the request is valid. - * Usually, but not necessarily an action function will drop - * an invalid response. Exceptions are usually disconnection states, - * where a bad response may still be accepted. - * - * NOTE: - * It is assumed that this routine would never be called recursively or - * reentered via a separate task because responseRecord is declared as a - * large static variable - */ -int -sipSPICheckResponse (ccsipCCB_t *ccb, sipMessage_t *response) -{ - const char *fname = "sipSPICheckResponse"; - const char *from = NULL; - const char *to = NULL; - const char *callID = NULL; - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - sipRespLine_t *pRespLine = NULL; - uint32_t response_cseq_number = 0; - sipMethod_t response_method = sipMethodInvalid; - uint16_t response_code = 0; - sipStatusCodeClass_t code_class = codeClassInvalid; - int16_t trx_index = -1; - const char *via = NULL; - - /* - * Check for the incomplete message body - */ - if (!sippmh_is_message_complete(response)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_is_message_complete()"); - return (SIP_MESSAGING_ERROR); - } - - /* - * Check whether all mandatory SIP request headers are there. - */ - from = sippmh_get_cached_header_val(response, FROM); - if (!from || (!is_good_header_length(from, FROM))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(FROM)"); - return (SIP_MESSAGING_ERROR); - } - to = sippmh_get_cached_header_val(response, TO); - if (!to || (!is_good_header_length(to, TO))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(TO)"); - return (SIP_MESSAGING_ERROR); - } - callID = sippmh_get_cached_header_val(response, CALLID); - if (!callID || (!is_good_header_length(callID, CALLID))) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CALLID)"); - return (SIP_MESSAGING_ERROR); - } - cseq = sippmh_get_cached_header_val(response, CSEQ); - if (!cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_cached_header_val(CSEQ)"); - return (SIP_MESSAGING_ERROR); - } - via = sippmh_get_cached_header_val(response, VIA); - if (via) { - if (strchr(via, COMMA)) { - CCSIP_DEBUG_ERROR("%s: Multiple Via headers found in response\n", - fname); - return (SIP_MESSAGING_ERROR); - } - } - - if (sipSPICheckContentHeaders(response) != SIP_MESSAGING_OK) { - CCSIP_DEBUG_ERROR("%s: Content header value not supported\n", fname); - return (SIP_MESSAGING_ERROR); - } - - /* - * Get SIP response code - */ - pRespLine = sippmh_get_response_line(response); - if (!pRespLine) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_get_response_line()"); - return (SIP_MESSAGING_ERROR); - } - response_code = pRespLine->status_code; - SIPPMH_FREE_RESPONSE_LINE(pRespLine); - code_class = sippmh_get_code_class(response_code); - - /* - * Extract response method and Cseq number from CSeq - */ - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_cseq()"); - return (SIP_MESSAGING_ERROR); - } - response_method = sipCseq->method; - response_cseq_number = sipCseq->number; - cpr_free(sipCseq); - - /* - * If its a authentication response should not do any response - * mismatch checking since some ACK's are not stored and so this - * check will could return response mismatch. - */ - switch (response_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - if (response_method == sipMethodAck) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Authentication Request for ACK: callid=%s," - "cseq=%u, cseq_method=%s\n", - DEB_F_PREFIX_ARGS(SIP_ACK, fname), callID, response_cseq_number, - sipGetMethodString(response_method)); - return (SIP_MESSAGING_OK); - } - break; - - default: - break; - } - - if (sippmh_msg_header_present(response, SIP_HEADER_REPLACES)) { - CCSIP_DEBUG_ERROR("%s: Error: Replace header is not valid " - "in a response\n", fname); - return SIP_MESSAGING_ERROR; - } - - /* - * Reliable Delivery - */ - if (SipRelDevEnabled) { - /* - * responseRecord is a static because the structure it is - * made out of is so large. - */ - static sipRelDevMessageRecord_t responseRecord; - int handle = -1; - sipLocation_t *reldev_to_loc = NULL; - char reldev_to_tag[MAX_SIP_TAG_LENGTH]; - sipLocation_t *reldev_from_loc = NULL; - - memset(&responseRecord, 0, sizeof(responseRecord)); - memset(reldev_to_tag, 0, MAX_SIP_TAG_LENGTH); - - /* Get to_tag */ - reldev_to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (reldev_to_loc) { - if (reldev_to_loc->tag) { - sstrncpy(reldev_to_tag, - sip_sm_purify_tag(reldev_to_loc->tag), - MAX_SIP_TAG_LENGTH); - } else { - reldev_to_tag[0] = '\0'; - } - sstrncpy(responseRecord.to_user, - reldev_to_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sippmh_free_location(reldev_to_loc); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - return (SIP_MESSAGING_ERROR); - } - - reldev_from_loc = sippmh_parse_from_or_to((char *)from, TRUE); - if (reldev_from_loc) { - sstrncpy(responseRecord.from_user, - reldev_from_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sstrncpy(responseRecord.from_host, - reldev_from_loc->genUrl->u.sipUrl->host, - RELDEV_MAX_HOST_NAME_LEN); - - /* Check from-tag */ - if (reldev_from_loc->tag) { - if (!(ccb->flags & INCOMING)) { - if (strcmp(reldev_from_loc->tag, ccb->sip_from_tag) != 0) { - sippmh_free_location(reldev_from_loc); - CCSIP_DEBUG_ERROR("%s: Outgoing: From tag in response " - "does not match stored value\n", - fname); - return (SIP_MESSAGING_ERROR); - } - } else { - if (strcmp(reldev_from_loc->tag, ccb->sip_to_tag) != 0) { - sippmh_free_location(reldev_from_loc); - CCSIP_DEBUG_ERROR("%s: Incoming: From tag in response " - "does not match stored value\n", - fname); - return (SIP_MESSAGING_ERROR); - } - } - } - - sippmh_free_location(reldev_from_loc); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - return (SIP_MESSAGING_ERROR); - } - - responseRecord.is_request = FALSE; - sstrncpy(responseRecord.call_id, (callID) ? callID : "", - MAX_SIP_CALL_ID); - responseRecord.cseq_method = response_method; - responseRecord.cseq_number = response_cseq_number; - responseRecord.response_code = response_code; - sstrncpy(responseRecord.tag, reldev_to_tag, MAX_SIP_TAG_LENGTH); - //responseRecord.line = ccb->index; - - /* Check if duplicate */ - if (sipRelDevMessageIsDuplicate(&responseRecord, &handle)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Duplicate response detected...\n", DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - if (sipRelDevCoupledMessageSend(handle) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipRelDevCoupledMessageSend()"); - } - if ((response_method == sipMethodInvite) && - (code_class == codeClass1xx)) { - /* Allow multiple provisional responses */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Allowed duplicate provisional response\n", - DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - } else { - return (SIP_MESSAGING_DUPLICATE); - } - } - /* Record the response in Recent Requests List */ - sipRelDevMessageStore(&responseRecord); - } - - /* - * Check whether the outstanding request's and this response's - * call id, cseq, and cseq method match - */ - trx_index = get_method_request_trx_index(ccb, response_method, TRUE); - if (trx_index < 0) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"No Matching Request Found!:\n" - "(Response: cseq=%u, trx_method=%s)\n", - DEB_F_PREFIX_ARGS(SIP_CALL_STATUS, fname), response_cseq_number, - sipGetMethodString(response_method)); - return (SIP_MESSAGING_ERROR_NO_TRX); - } - if ((ccb->sent_request[trx_index].cseq_number != response_cseq_number) || - (ccb->sent_request[trx_index].cseq_method != response_method) || - (strcmp(ccb->sipCallID, callID) != 0)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Response mismatch:\n(Response:" - "callid=%s, cseq=%u, cseq_method=%s),\n" - "(Request: callid=%s, cseq=%u, " - "cseq_method=%s)\n", - DEB_F_PREFIX_ARGS(SIP_RESP, fname), callID, response_cseq_number, - sipGetMethodString(response_method), - ccb->sipCallID, - ccb->sent_request[trx_index].cseq_number, - sipGetMethodString(ccb->sent_request[trx_index].cseq_method)); - /* - * What happened here is that a timing - * issue occured between the proxy and phone where we - * timed out at almost the same time and we have already - * sent another request(probably a cancel) when the proxy - * sends this response back to us. So that we just Ack this - * response, we play games with previous call fields. We don't - * want to store the information because this response is basically - * stale at this point. We set the prevcall boolean to FALSE - * but we set the previous_line to 0xFF. This will indicate to - * the send routine to skip the storing of this Ack for retransmission. - */ - if (response_method == sipMethodInvite) { - const char *resp_via = NULL; - sipVia_t *resp_via_parm = NULL; - int16_t trx_index_temp = -1; - const char *sip_via_branch = NULL; - - switch (code_class) { - case codeClass2xx: - /* - * If we get 200 response to a cancelled invite, send bye - * to clear up the call. - */ - trx_index_temp = get_method_request_trx_index(ccb, - sipMethodCancel, - TRUE); - // if there is a CANCEL request outstanding - - // if (ccb->last_sent_request_cseq_method == sipMethodCancel) { - if (trx_index_temp > 0) { - const char *contact = NULL; - - /* - * We need to update the contact and to, from tags recvd. - * in ccb because the CANCEL effectively becomes a nop due - * to the race condition where the UAS sent 200 OK to - * INVITE at the same instance we sent CANCEL. Hence we - * need to ACK the 200 OK for INVITE with route header and - * then send a BYE with to tag sent in order to clean up - * the call at the called party - */ - ccb->sip_to = strlib_update(ccb->sip_to, to); - ccb->sip_from = strlib_update(ccb->sip_from, from); - contact = sippmh_get_cached_header_val(response, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - sipSPISendFailureResponseAck(ccb, response, FALSE, 0xFF); - sipSPISendBye(ccb, NULL, NULL); - } else { - /* - * No CANCEL was sent, so this is a plain mismatch - * of the CSeq # - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Ignoring response message\n", - DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - return (SIP_MESSAGING_ERROR); - } - break; - case codeClass4xx: - case codeClass5xx: - case codeClass6xx: - /* - * Locate the branch Parameter. If the branch parameter is - * the same, we are dealing with an outstanding transaction, - * but the response was out of sync with expected. If branch - * parameter is different, the transaction is gone. Ignore - * stray responses - */ - resp_via = sippmh_get_cached_header_val(response, VIA); - if (resp_via) { - resp_via_parm = sippmh_parse_via(resp_via); - if (resp_via_parm) { - /* check for branch param match for transaction */ - if ((resp_via_parm->branch_param) && - (strncmp(resp_via_parm->branch_param, - VIA_BRANCH_START, 7) == 0)) { - trx_index_temp = get_last_request_trx_index(ccb, - TRUE); - if (trx_index_temp != -1) { - sip_via_branch = (char *) - ccb->sent_request[trx_index_temp].u.sip_via_branch; - if (strncmp(resp_via_parm->branch_param, - // (char *) ccb->sip_via_branch, - sip_via_branch, VIA_BRANCH_LENGTH) != 0) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Stray Response: " - "Response branch: %s Request " - "branch: %s\n", DEB_F_PREFIX_ARGS(SIP_RESP, fname), - resp_via_parm->branch_param, - // (char *) ccb->sip_via_branch); - sip_via_branch); - sippmh_free_via(resp_via_parm); - return (SIP_MESSAGING_ERROR_STALE_RESP); - } - } - } - sippmh_free_via(resp_via_parm); - } - } - sipSPISendFailureResponseAck(ccb, response, FALSE, 0xFF); - break; - default: - sipSPISendFailureResponseAck(ccb, response, FALSE, 0xFF); - } - } - return (SIP_MESSAGING_ERROR_STALE_RESP); - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Response match: callid=%s, cseq=%u, " - "cseq_method=%s\n", DEB_F_PREFIX_ARGS(SIP_RESP, fname), - callID, response_cseq_number, sipGetMethodString(response_method)); - - - return (SIP_MESSAGING_OK); -} - -/* - * Generate Authorization response - * Concats all the right strings and MD5s the result - */ -boolean -sipSPIGenerateAuthorizationResponse (sip_authen_t *sip_authen, - const char *uri, - const char *method, - const char *user_name, - const char *user_password, - char **author_str, - int *nc_count, - ccsipCCB_t *ccb) -{ - static const char fname[] = "sipSPIGenerateAuthorizationResponse"; - sip_author_t sip_author; - HASHHEX HA1; - HASHHEX HA2 = ""; - char cnonce_str[NONCE_LEN]; - char nc_count_str[NONCE_LEN]; - boolean md5_sess_used; - uint32_t i; - - md5_sess_used = (cpr_strcasecmp(sip_authen->algorithm, "md5-sess") == 0) ? - TRUE : FALSE; - - if ((sip_authen->scheme != SIP_DIGEST) || - (!md5_sess_used && - (cpr_strcasecmp(sip_authen->algorithm, "md5") != 0))) { - CCSIP_DEBUG_ERROR("%s: Error: invalid XXX-Authenticate.\n", fname); - CCSIP_DEBUG_ERROR(" scheme: %d, algorithm: %s.\n", sip_authen->scheme, - sip_authen->algorithm); - return (FALSE); - } - - sip_author.response = (char *) cpr_malloc(33 * sizeof(char)); - - /* sip_author has pointers that point to the same data that sip_authen - * points to. Ensure that sip_authen is not freed before sip_author - * is finished. - */ - - sip_author.str_start = NULL; - sip_author.user_pass = (char *) user_password; - sip_author.d_username = (char *) user_name; - sip_author.unparsed_uri = (char *) uri; - sip_author.scheme = sip_authen->scheme; - sip_author.realm = sip_authen->realm; - sip_author.nonce = sip_authen->nonce; - sip_author.algorithm = sip_authen->algorithm; - - sip_author.opaque = sip_authen->opaque; - sip_author.qop = sip_authen->qop; - - /* - * Setup the cnonce and nc_count if qop options are used or if - * md5-sess is the algorithm requested. - */ - if (!md5_sess_used && (sip_authen->qop == NULL)) { - sip_author.cnonce = NULL; - sip_author.nc_count = NULL; - } else { - if (md5_sess_used && (ccb != NULL)) { - if (ccb->authen.cnonce[0] == '\0') { - snprintf(ccb->authen.cnonce, NONCE_LEN, "%8.8x", - (unsigned int)cpr_rand()); - } - sip_author.cnonce = ccb->authen.cnonce; - } else { - snprintf(cnonce_str, NONCE_LEN, "%8.8x", - (unsigned int)cpr_rand()); - sip_author.cnonce = cnonce_str; - } - snprintf(nc_count_str, NONCE_LEN, "%08x", ++(*nc_count)); - sip_author.nc_count = nc_count_str; - } - sip_author.auth_param = NULL; - - DigestCalcHA1(sip_author.algorithm, sip_author.d_username, - sip_author.realm, (char *) user_password, sip_author.nonce, - sip_author.cnonce, HA1); - - /* - * Need to calculate HEntity. - * HEntity is basically just the hash of the SDP. Only the INVITE has SDP - * so we hash the SDP for the INVITE and for other methods we just - * hash the "". - */ - if ((strcmp(method, SIP_METHOD_INVITE) == 0) && (ccb != NULL)) { - /* Use the content from the body saved */ - for (i = 0; i < ccb->local_msg_body.num_parts; i++) { - if (ccb->local_msg_body.parts[i].body != NULL) { - DigestString(ccb->local_msg_body.parts[i].body, HA2); - AUTH_DEBUG(DEB_F_PREFIX"entity body= \n", DEB_F_PREFIX_ARGS(SIP_MSG, fname)); - } - } - } else { - DigestString("", HA2); - } - - DigestCalcResponse(HA1, sip_author.nonce, sip_author.nc_count, - sip_author.cnonce, sip_author.qop, - (char *)method, //SIP_METHOD_REGISTER, - sip_author.unparsed_uri, HA2, sip_author.response); - - *author_str = sippmh_generate_authorization(&sip_author); - - cpr_free(sip_author.response); - - return (TRUE); -} - - -/* - * Generates Route Headers for UAC - * Pops the first RR entry and puts in Req Line - * Copies the rest of RR entries in reverse order into Route Header - * Appends Contact Header at the end of Route - * header - * If the first route entry has loose routing,"lr", set. does not add the - * Contact Header to the end of Route, and does not pop the first entry. - * In this case, indicates loose - * routing to caller so that they may add the Contact to the Req-URI - * instead - */ -boolean -sipSPIGenerateRouteHeaderUAC (sipRecordRoute_t *rr_info, - char *route, - int route_str_len, - boolean *loose_routing) -{ - boolean retval = FALSE; - int i, j, start, limit; - static char temp_route[MAX_SIP_HEADER_LENGTH]; - sipUrl_t *url_info = NULL; - genUrl_t *gen; - boolean lr = FALSE; - char url[SIPS_URL_LEN]; - - if (route == NULL) { - return retval; - } - - start = rr_info->num_locations - 1; - limit = 0; - route[0] = '\0'; - - for (i = start; i >= limit; i--) { - url_info = rr_info->locations[i]->genUrl->u.sipUrl; - if (i == start) { - if (url_info->lr_flag == FALSE) { - // Skip the first entry if lr flag is not set - continue; - } else { - lr = TRUE; - } - } - if (rr_info->locations[i]->genUrl->sips) { - snprintf(url, sizeof(url), "sips"); - } else { - snprintf(url, sizeof(url), "sip"); - } - temp_route[0] = '\0'; - if (url_info->user == NULL) { - snprintf(temp_route, sizeof(temp_route), - "<%s:%s:%d", url, url_info->host, url_info->port); - } else { - if (url_info->password) { - snprintf(temp_route, sizeof(temp_route), "<%s:%s:%s@%s:%d", - url, url_info->user, url_info->password, - url_info->host, url_info->port); - } else { - snprintf(temp_route, sizeof(temp_route), "<%s:%s@%s:%d", - url, url_info->user, url_info->host, url_info->port); - } - } - if (url_info->maddr) { - /*static */ char maddr[MAX_SIP_HEADER_LENGTH]; - - snprintf(maddr, sizeof(maddr), ";maddr=%s", url_info->maddr); - sstrncat(temp_route, maddr, - sizeof(temp_route) - strlen(temp_route)); - } - - if (url_info->ttl_val) { - /*static */ char ttl[MAX_SIP_HEADER_LENGTH]; - - snprintf(ttl, sizeof(ttl), ";ttl=%d", url_info->ttl_val); - sstrncat(temp_route, ttl, - sizeof(temp_route) - strlen(temp_route)); - } - - switch (url_info->transport) { - case TRANSPORT_UDP: - sstrncat(temp_route, ";transport=udp", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_TCP: - sstrncat(temp_route, ";transport=tcp", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_TLS: - sstrncat(temp_route, ";transport=tls", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_SCTP: - sstrncat(temp_route, ";transport=sctp", - sizeof(temp_route) - strlen(temp_route)); - break; - } - - if (url_info->is_phone) { - sstrncat(temp_route, ";user=phone", - sizeof(temp_route) - strlen(temp_route)); - } - - if (url_info->lr_flag) { - sstrncat(temp_route, ";lr", - sizeof(temp_route) - strlen(temp_route)); - } - - j = 0; - gen = rr_info->locations[i]->genUrl; - - while (j < SIP_MAX_LOCATIONS) { - if (gen->other_params[j] != NULL) { - sstrncat(temp_route, ";", - sizeof(temp_route) - strlen(temp_route)); - sstrncat(temp_route, gen->other_params[j], - sizeof(temp_route) - strlen(temp_route)); - break; - } - j++; - } - - if (i > limit) { - sstrncat(temp_route, ">,", - sizeof(temp_route) - strlen(temp_route)); - } else { - sstrncat(temp_route, ">", - sizeof(temp_route) - strlen(temp_route)); - } - - sstrncat(route, temp_route, route_str_len - strlen(route)); - - } - - *loose_routing = lr; - retval = TRUE; - return retval; -} - -/* - * Generates Route Headers for UAS - * Pops the first RR entry and puts in Req Line - * Copies the rest of RR entries into Route Header - * Appends Contact Header at the end of Route - * header - */ -boolean -sipSPIGenerateRouteHeaderUAS (sipRecordRoute_t *rr_info, - char *route, - int route_str_len, - boolean *loose_routing) -{ - const char *fname = "sipSPIGenerateRouteHeaderUAS"; - boolean retval = FALSE; - int i, j, start, limit; - static char temp_route[MAX_SIP_HEADER_LENGTH]; - sipUrl_t *url_info; - genUrl_t *gen; - boolean lr = FALSE; - char url[SIPS_URL_LEN]; - - if (route == NULL) { - return (retval); - } - - start = 0; - limit = rr_info->num_locations - 1; - route[0] = '\0'; - - for (i = start; i <= limit; i++) { - if (rr_info->locations[i]->genUrl->schema == URL_TYPE_SIP) { - url_info = rr_info->locations[i]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - return (FALSE); - } - if (i == start) { - if (url_info->lr_flag == FALSE) { - // don't add the first route, if the lr flag is not set - continue; - } else { - lr = TRUE; - } - } - if (rr_info->locations[i]->genUrl->sips) { - snprintf(url, sizeof(url), "sips"); - } else { - snprintf(url, sizeof(url), "sip"); - } - temp_route[0] = '\0'; - if (url_info->user == NULL) { - snprintf(temp_route, sizeof(temp_route), - "<%s:%s:%d", url, url_info->host, url_info->port); - } else { - if (url_info->password) { - snprintf(temp_route, sizeof(temp_route), "<%s:%s:%s@%s:%d", - url, url_info->user, - url_info->password, url_info->host, url_info->port); - } else { - snprintf(temp_route, sizeof(temp_route), "<%s:%s@%s:%d", - url, url_info->user, url_info->host, url_info->port); - } - } - - if (url_info->maddr) { - /*static */ char maddr[MAX_SIP_HEADER_LENGTH]; - - snprintf(maddr, sizeof(maddr), ";maddr=%s", url_info->maddr); - sstrncat(temp_route, maddr, - sizeof(temp_route) - strlen(temp_route)); - } - - if (url_info->ttl_val) { - /*static */ char ttl[MAX_SIP_HEADER_LENGTH]; - - snprintf(ttl, sizeof(ttl), ";ttl=%d", url_info->ttl_val); - sstrncat(temp_route, ttl, - sizeof(temp_route) - strlen(temp_route)); - } - - switch (url_info->transport) { - case TRANSPORT_UDP: - sstrncat(temp_route, ";transport=udp", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_TCP: - sstrncat(temp_route, ";transport=tcp", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_TLS: - sstrncat(temp_route, ";transport=tls", - sizeof(temp_route) - strlen(temp_route)); - break; - case TRANSPORT_SCTP: - sstrncat(temp_route, ";transport=sctp", - sizeof(temp_route) - strlen(temp_route)); - break; - } - - if (url_info->is_phone) { - sstrncat(temp_route, ";user=phone", - sizeof(temp_route) - strlen(temp_route)); - } - - if (url_info->lr_flag) { - sstrncat(temp_route, ";lr", - sizeof(temp_route) - strlen(temp_route)); - } - - j = 0; - gen = rr_info->locations[i]->genUrl; - - while (j < SIP_MAX_LOCATIONS) { - if (gen->other_params[j] != NULL) { - sstrncat(temp_route, ";", - sizeof(temp_route) - strlen(temp_route)); - sstrncat(temp_route, gen->other_params[j], - sizeof(temp_route) - strlen(temp_route)); - break; - } - j++; - } - - if (i < limit) { - sstrncat(temp_route, ">,", - sizeof(temp_route) - strlen(temp_route)); - } else { - sstrncat(temp_route, ">", - sizeof(temp_route) - strlen(temp_route)); - } - sstrncat(route, temp_route, route_str_len - strlen(route)); - } - - *loose_routing = lr; - retval = TRUE; - return (retval); -} - -/* - * This function regenerates the Contact Header - * from the parsed information stored in CCB - */ -boolean -sipSPIGenerateContactHeader (sipContact_t *contact_info, - char *contact, - int len) -{ - const char *fname = "sipSPIGenerateContactHeader"; - boolean retval = FALSE; - sipUrl_t *sipUrl; - - if (contact == NULL) { - return (retval); - } - - if (contact_info == NULL) { - contact[0] = '\0'; - retval = TRUE; - return (retval); - } - - if (contact_info->locations[0]->genUrl->schema == URL_TYPE_SIP) { - sipUrl = contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - return (FALSE); - } - - if (sipUrl->user == NULL) { - snprintf(contact, len, "host, sipUrl->port); - } else { - if ((sipUrl->password) && (*(sipUrl->password))) { - snprintf(contact, len, "user, - sipUrl->password, sipUrl->host, sipUrl->port); - } else { - snprintf(contact, len, "user, - sipUrl->host, sipUrl->port); - } - } - - /* Assume contact length is the same for all clients */ - - if (sipUrl->maddr) { - /*static */ char maddr[MAX_SIP_HEADER_LENGTH]; - - snprintf(maddr, sizeof(maddr), ";maddr=%s", sipUrl->maddr); - sstrncat(contact, maddr, len - strlen(contact)); - } - - if (sipUrl->ttl_val) { - /*static */ char ttl[MAX_SIP_HEADER_LENGTH]; - - snprintf(ttl, sizeof(ttl), ";ttl=%d", sipUrl->ttl_val); - sstrncat(contact, ttl, len - strlen(contact)); - } - - switch (sipUrl->transport) { - case TRANSPORT_UDP: - sstrncat(contact, ";transport=udp", len - strlen(contact)); - break; - case TRANSPORT_TCP: - sstrncat(contact, ";transport=tcp", len - strlen(contact)); - break; - case TRANSPORT_TLS: - sstrncat(contact, ";transport=tls", len - strlen(contact)); - break; - case TRANSPORT_SCTP: - sstrncat(contact, ";transport=sctp", len - strlen(contact)); - break; - } - - if (sipUrl->is_phone) { - sstrncat(contact, ";user=phone", len - strlen(contact)); - } - - sstrncat(contact, ">", len - strlen(contact)); - retval = TRUE; - return (retval); -} - - -char * -sipSPIUrlDestination (sipUrl_t *sipUrl) -{ - return ((sipUrl->maddr) ? sipUrl->maddr : sipUrl->host); -} - - -int -sipSPICheckContact (const char *contact) -{ - const char *fname = "sipSPICheckContact"; - sipContact_t *contact_info = NULL; - int result = 0; - - contact_info = sippmh_parse_contact(contact); - if (contact_info) { - if (contact_info->locations[0]->genUrl->schema != URL_TYPE_SIP) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - sippmh_free_contact(contact_info); - return (-1); - } - - sippmh_free_contact(contact_info); - } - - return (result); -} - - -sipRet_t -sipAddDateHeader (sipMessage_t *sip_message) -{ - char sip_date[MAX_SIP_DATE_LENGTH]; - cpr_time_t timestamp; - struct tm ts; - - (void) time((time_t *)×tamp); - - (void) gmtime_r((time_t *)×tamp, &ts); - - if (strftime(sip_date, MAX_SIP_DATE_LENGTH, "%a, %d %b %Y %H:%M:%S GMT", &ts) - == 0) { - /* If defined, allow for a failure if unable to create date header */ - return STATUS_FAILURE; - } - - return sippmh_add_text_header(sip_message, SIP_HEADER_DATE, sip_date); -} - -int -sipGetMessageCSeq (sipMessage_t *pMessage, - uint32_t *pResultCSeqNumber, - sipMethod_t *pResultCSeqMethod) -{ - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - - cseq = sippmh_get_cached_header_val(pMessage, CSEQ); - if (!cseq) { - return (-1); - } - - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - return (-1); - } - - *pResultCSeqNumber = sipCseq->number; - *pResultCSeqMethod = sipCseq->method; - - cpr_free(sipCseq); - return (0); -} - - -void -sipGetMessageToTag (sipMessage_t *pMessage, char *to_tag, - int to_tag_max_length) -{ - const char *to = NULL; - sipLocation_t *to_loc = NULL; - - memset(to_tag, 0, to_tag_max_length); - //For self generated methods (i.e. outgoing), the TO HEADER - //may not be in the cached area of the message structue. - to = sippmh_get_cached_header_val(pMessage, TO); - if (!to) { - to = sippmh_get_header_val(pMessage, SIP_HEADER_TO, SIP_C_HEADER_TO); - } - - if (to) { - to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (to_loc) { - if (to_loc->tag) { - sstrncpy(to_tag, sip_sm_purify_tag(to_loc->tag), - to_tag_max_length); - } - sippmh_free_location(to_loc); - } - } - - return; -} - - -boolean -sipSPISendByeAuth (sipMessage_t *pResponse, - sipAuthenticate_t authen, - cpr_ip_addr_t *dest_ipaddr, - uint16_t dest_port, - uint32_t cseq_number, - char *alsoString, - char *last_call_route, - char *last_call_route_request_uri, - line_t previous_call_line) -{ - const char *fname = "sipSPISendByeAuth"; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - const char *response_contact = NULL; - const char *response_record_route = NULL; - const char *response_to = NULL; - const char *response_from = NULL; - const char *response_callid = NULL; - sipContact_t *response_contact_info = NULL; - sipRecordRoute_t *response_record_route_info = NULL; - - cpr_ip_addr_t request_uri_addr; - uint16_t request_uri_port = 0; - cpr_ip_addr_t src_ipaddr; - char src_addr_str[MAX_IPADDR_STR_LEN]; - static char ReqURI[MAX_SIP_URL_LENGTH]; - static char via[SIP_MAX_VIA_LENGTH]; - ccsipCCB_t *ccb = NULL; - int timeout = 0; - sipLocation_t *request_uri_loc = NULL; - sipUrl_t *request_uri_url = NULL; - sipUrl_t *sipUrl = NULL; - int i = 0; - int nat_enable = 0; - - CPR_IP_ADDR_INIT(request_uri_addr); - CPR_IP_ADDR_INIT(src_ipaddr); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "BYE(Auth)"); - - request = GET_SIP_MESSAGE(); - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "GET_SIP_MESSAGE()"); - return (FALSE); - } - - /* Init temp ccb to ccbs[previous_call_line] */ - ccb = &gGlobInfo.ccbs[previous_call_line]; - if (ccb->state != SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING) { - CCSIP_DEBUG_ERROR("%s: Error: ccb %d is not in " - "SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING state.\n", - fname, previous_call_line); - free_sip_message(request); - return (FALSE); - } - ccb->contact_info = NULL; - ccb->record_route_info = NULL; - ccb->flags = 0; - - response_contact = sippmh_get_cached_header_val(pResponse, CONTACT); - response_record_route = - sippmh_get_cached_header_val(pResponse, RECORD_ROUTE); - response_to = sippmh_get_cached_header_val(pResponse, TO); - response_from = sippmh_get_cached_header_val(pResponse, FROM); - response_callid = sippmh_get_cached_header_val(pResponse, CALLID); - - if (response_contact) { - response_contact_info = sippmh_parse_contact(response_contact); - ccb->contact_info = response_contact_info; - } - if (response_record_route) { - response_record_route_info = - sippmh_parse_record_route(response_record_route); - ccb->record_route_info = response_record_route_info; - } - - /* - * Determine the Request-URI - */ - memset(ReqURI, 0, sizeof(ReqURI)); - if (response_record_route_info) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI: using 401/407's Record-Route\n", - DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - i = response_record_route_info->num_locations - 1; - if (response_record_route_info->locations[i]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = response_record_route_info->locations[i]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - free_sip_message(request); - return (FALSE); - } - - request_uri_port = sipUrl->port; - if (!sipUrl->port_present) { - dns_error_code = - sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &request_uri_addr, - &request_uri_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(sipSPIUrlDestination(sipUrl), - &request_uri_addr, 100, 1); - } - if (dns_error_code == 0) { - util_ntohl(&request_uri_addr, &request_uri_addr); - - } else { - request_uri_addr = ip_addr_invalid; - } - - if (sipUrl->user != NULL) { - if (sipUrl->password) { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s@%s:%d;user=phone" : - "sip:%s@%s:%d", sipUrl->user, sipUrl->host, - sipUrl->port); - } - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s:%d;user=phone" : "sip:%s:%d", - sipUrl->host, sipUrl->port); - } - } else if (last_call_route[0] && last_call_route_request_uri[0]) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI: using current Route " - "information.\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - sstrncpy(ReqURI, last_call_route_request_uri, sizeof(ReqURI)); - request_uri_addr = *dest_ipaddr; - request_uri_port = dest_port; - } else if (response_contact_info) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI: using Contact\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - if (response_contact_info->locations[0]->genUrl->schema == URL_TYPE_SIP) { - sipUrl = response_contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - free_sip_message(request); - return (FALSE); - } - - request_uri_port = sipUrl->port; - if (!sipUrl->port_present) { - dns_error_code = - sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &request_uri_addr, - &request_uri_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(sipSPIUrlDestination(sipUrl), - &request_uri_addr, 100, 1); - } - if (dns_error_code == 0) { - - util_ntohl(&request_uri_addr, &request_uri_addr); - } else { - request_uri_addr = ip_addr_invalid; - } - - if (sipUrl->user != NULL) { - if (sipUrl->password) { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s@%s:%d;user=phone" : - "sip:%s@%s:%d", sipUrl->user, - sipUrl->host, sipUrl->port); - } - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? "sip:%s:%d;user=phone" : "sip:%s:%d", - sipUrl->host, sipUrl->port); - } - } else { - request_uri_addr = *dest_ipaddr; - request_uri_port = dest_port; - request_uri_loc = sippmh_parse_from_or_to((char *)response_to, TRUE); - if (!request_uri_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - free_sip_message(request); - return (FALSE); - } - - if (!sippmh_valid_url(request_uri_loc->genUrl)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_valid_url()"); - sippmh_free_location(request_uri_loc); - free_sip_message(request); - return (FALSE); - } - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI (Caller): using original " - "Req-URI\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - if (request_uri_loc->name) { - if (request_uri_loc->name[0]) { - sstrncat(ReqURI, "\"", sizeof(ReqURI) - strlen(ReqURI)); - sstrncat(ReqURI, request_uri_loc->name, - sizeof(ReqURI) - strlen(ReqURI)); - sstrncat(ReqURI, "\" ", sizeof(ReqURI) - strlen(ReqURI)); - } - } - sstrncat(ReqURI, "sip:", sizeof(ReqURI) - strlen(ReqURI)); - if (request_uri_loc->genUrl->schema == URL_TYPE_SIP) { - request_uri_url = request_uri_loc->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - sippmh_free_location(request_uri_loc); - free_sip_message(request); - return (FALSE); - } - - if (request_uri_url->user) { - sstrncat(ReqURI, request_uri_url->user, - sizeof(ReqURI) - strlen(ReqURI)); - sstrncat(ReqURI, "@", sizeof(ReqURI) - strlen(ReqURI)); - } - if (request_uri_url->is_phone) { - sstrncat(ReqURI, ";user=phone", - sizeof(ReqURI) - strlen(ReqURI)); - } - sstrncat(ReqURI, request_uri_url->host, - sizeof(ReqURI) - strlen(ReqURI)); - sippmh_free_location(request_uri_loc); - } - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&src_ipaddr); - ipaddr2dotted(src_addr_str, &src_ipaddr); - } else { - sip_config_get_nat_ipaddr(&src_ipaddr); - ipaddr2dotted(src_addr_str, &src_ipaddr); - } - - /* - * Build the request - */ - - /* Write Req-URI */ - tflag = sippmh_add_request_line(request, SIP_METHOD_BYE, ReqURI, - SIP_VERSION); - UPDATE_FLAGS(flag, tflag); - - /* Write Via */ - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s%.8x", - sipTransportGetTransportType(ccb->dn_line, TRUE, ccb), - src_addr_str, - ccb->local_port, - VIA_BRANCH, VIA_BRANCH_START, - (unsigned int)cpr_rand()); - tflag = sippmh_add_text_header(request, SIP_HEADER_VIA, via); - UPDATE_FLAGS(flag, tflag); - - /* Write To, From, and Call-ID standard headers */ - tflag = sippmh_add_text_header(request, SIP_HEADER_FROM, response_from); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(request, SIP_HEADER_TO, response_to); - UPDATE_FLAGS(flag, tflag); - tflag = sippmh_add_text_header(request, SIP_HEADER_CALLID, response_callid); - UPDATE_FLAGS(flag, tflag); - - /* Write Date header */ - tflag = sipAddDateHeader(request); - UPDATE_FLAGS(flag, tflag); - - /* Write User Agent header */ - tflag = sippmh_add_text_header(request, SIP_HEADER_USER_AGENT, - sipHeaderUserAgent); - UPDATE_FLAGS(flag, tflag); - - /* add in call stats header if needed */ - tflag = sipSPIAddCallStats(ccb, request); - UPDATE_FLAGS(flag, tflag); - - /* Write Route */ - if (response_record_route_info) { - tflag = (sipSPIAddRouteHeaders(request, ccb, NULL, 0)) ? - STATUS_SUCCESS : STATUS_FAILURE; - } else if (last_call_route[0]) { - tflag = sippmh_add_text_header(request, SIP_HEADER_ROUTE, - last_call_route); - } - UPDATE_FLAGS(flag, tflag); - - /* Free contact and record-route */ - if (response_contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - } - if (response_record_route) { - if (ccb->record_route_info) { - sippmh_free_record_route(ccb->record_route_info); - ccb->record_route_info = NULL; - } - } - - /* Write CSeq */ - tflag = sippmh_add_cseq(request, SIP_METHOD_BYE, cseq_number); - UPDATE_FLAGS(flag, tflag); - - if (alsoString) { - if (alsoString[0]) { - tflag = sippmh_add_text_header(request, SIP_HEADER_ALSO, - alsoString); - UPDATE_FLAGS(flag, tflag); - } - } - - if (authen.authorization != NULL) { - tflag = sippmh_add_text_header(request, AUTHOR_HDR(authen.status_code), - authen.authorization); - UPDATE_FLAGS(flag, tflag); - cpr_free(authen.authorization); - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (request) - free_sip_message(request); - return (FALSE); - } - - /* Send message */ - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - ccb->retx_counter = 0; - if (sipTransportChannelCreateSend(ccb, request, sipMethodBye, - &request_uri_addr, - request_uri_port, timeout, - RELDEV_NO_STORED_MSG) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportChannelCreateSend()"); - if (request) - free_sip_message(request); - - return (FALSE); - } - return (TRUE); -} - -void -free_sip_message (sipMessage_t *message) -{ - if (message) { - sippmh_message_free(message); - } -} - -/* - * Generate the full URL (currently limited to the sipUrl only) - */ -void -sipSPIGenerateTargetUrl (genUrl_t *genUrl, char *sipurlstr) -{ - uint8_t i; - char temp[MAX_SIP_HEADER_LENGTH]; - size_t url_length = 0; - char *right_bracket = NULL; - boolean right_bracket_removed = FALSE; - - if (genUrl->schema == URL_TYPE_SIP) { - sipSPIGenerateSipUrl(genUrl->u.sipUrl, sipurlstr); - } else { - return; - } - - url_length = strlen(sipurlstr); - if (url_length == 0) { - return; - } - - for (i = 0; i < SIP_MAX_LOCATIONS; i++) { - if (genUrl->other_params[i] != NULL) { - if (i == 0) { - // Remove the ">" from the end of sipurlstr - right_bracket = strchr(sipurlstr, '>'); - if (right_bracket) { - *right_bracket = '\0'; - right_bracket_removed = TRUE; - } - } - snprintf(temp, sizeof(temp), ";%s", genUrl->other_params[i]); - sstrncat(sipurlstr, temp, MAX_SIP_URL_LENGTH - url_length ); - url_length = strlen(sipurlstr); - } - } - - if (right_bracket_removed) { - sstrncat(sipurlstr, ">", MAX_SIP_URL_LENGTH - url_length); - } -} - -/* - * Generates a plain string from sipUrl structure - * -*/ -void -sipSPIGenerateSipUrl (sipUrl_t *sipUrl, char *sipurlstr) -{ - char temp[MAX_SIP_HEADER_LENGTH]; - - if (sipUrl->user == NULL) { - snprintf(sipurlstr, MAX_SIP_HEADER_LENGTH, "host, sipUrl->port); - } else { - snprintf(sipurlstr, MAX_SIP_HEADER_LENGTH, "user, sipUrl->host, sipUrl->port); - } - - /* Assume sipurlstr _length is the same for all clients */ - - if (sipUrl->maddr) { - snprintf(temp, sizeof(temp), ";maddr=%s", sipUrl->maddr); - sstrncat(sipurlstr, temp, MAX_SIP_HEADER_LENGTH ); - } - - if (sipUrl->ttl_val) { - snprintf(temp, sizeof(temp), ";ttl=%d", sipUrl->ttl_val); - sstrncat(sipurlstr, temp, MAX_SIP_HEADER_LENGTH); - } - - switch (sipUrl->transport) { - case TRANSPORT_UDP: - sstrncat(sipurlstr, ";transport=udp", MAX_SIP_HEADER_LENGTH); - break; - case TRANSPORT_TCP: - sstrncat(sipurlstr, ";transport=tcp", MAX_SIP_HEADER_LENGTH); - break; - case TRANSPORT_TLS: - sstrncat(sipurlstr, ";transport=tls", MAX_SIP_HEADER_LENGTH); - break; - case TRANSPORT_SCTP: - sstrncat(sipurlstr, ";transport=sctp", MAX_SIP_HEADER_LENGTH); - break; - } - - if (sipUrl->is_phone) { - sstrncat(sipurlstr, ";user=phone", MAX_SIP_HEADER_LENGTH); - } - - sstrncat(sipurlstr, ">", MAX_SIP_HEADER_LENGTH); - -} - -#define MAX_SIP_METHOD_STRINGS 17 -#define MAX_SIP_METHOD_STRING_LEN 16 -const char * -sipGetMethodString (sipMethod_t methodname /*, char *methodstring */) -{ - int ino = (int) methodname; //Register is defined as 100 in pmh.h file - //Please make sure the following array is consistent with the enum - int idx = 0; - static const char methods[MAX_SIP_METHOD_STRINGS][MAX_SIP_METHOD_STRING_LEN] = - { "REGISTER", "OPTIONS", "INVITE", "BYE", - "CANCEL", "PRACK", "COMET", "NOTIFY", - "REFER", "ACK", "MESSAGE", "SUBSCRIBE", - "PUBLISH", "UPDATE", "RESPONSE", "INFO", "UNKNOWN" - }; - - - idx = ino - (int) sipMethodRegister; - if (idx >= 0 && idx <= (int) (sizeof(methods) / sizeof(methods[0]) - 1)) { - return methods[idx]; // Its OK to send this as it is a static array - } else { - return NULL; - } -} - -sipRet_t -sipSPIAddRequestLine (ccsipCCB_t *ccb, sipMessage_t *request, - sipMethod_t methodname, boolean initInvite) -{ - sipRet_t tflag = STATUS_FAILURE; - - if (TRUE == sipSPIGenRequestURI(ccb, methodname, initInvite)) { - tflag = sippmh_add_request_line(request, - sipGetMethodString(methodname), - ccb->ReqURI, - SIP_VERSION); - } else { - tflag = STATUS_FAILURE; - } - return tflag; -} - -boolean -getCSeqInfo (sipMessage_t *request, sipCseq_t ** request_cseq_structure) -{ - const char *request_cseq = NULL; - - request_cseq = sippmh_get_cached_header_val(request, CSEQ); - if (!request_cseq) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "AddCSeq in Factory", - "sippmh_get_cached_header_val()"); - return (FALSE); - } - *request_cseq_structure = sippmh_parse_cseq(request_cseq); - if (!*request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "AddCSeq in Factory", - "sippmh_parse_cseq()"); - return (FALSE); - } - return TRUE; -} - -// Allocate an outgoing transaction and fill in the cseq number and method -boolean -allocateTrx (ccsipCCB_t *ccb, sipMethod_t method) -{ - uint32_t trx_cseq_number = 0; - int16_t new_trx_index = -1, last_trx_index = -1; - - if (method == sipMethodCancel) { - // For CANCEL, the cseq is the same as the cseq - // of the earlier sent request that it cancels - last_trx_index = get_last_request_trx_index(ccb, TRUE); - if (last_trx_index < 0) { - return FALSE; - } - trx_cseq_number = ccb->sent_request[last_trx_index].cseq_number; - // Now allocate a new CSeq for the CANCEL request itself - new_trx_index = get_next_request_trx_index(ccb, TRUE); - if (new_trx_index < 0) { - return FALSE; - } - ccb->sent_request[new_trx_index].cseq_number = trx_cseq_number; - ccb->sent_request[new_trx_index].cseq_method = sipMethodCancel; - - } else if (method != sipMethodAck) { - // No new transaction is needed for Ack - new_trx_index = get_next_request_trx_index(ccb, TRUE); - if (new_trx_index < 0) { - return FALSE; - } - ccb->sent_request[new_trx_index].cseq_number = ++(ccb->last_used_cseq); - ccb->sent_request[new_trx_index].cseq_method = method; - } - return TRUE; -} - -boolean -AddCSeq (ccsipCCB_t *ccb, - sipMessage_t *request, - boolean isResponse, - sipMethod_t method, - uint32_t response_cseq_number) -{ - uint32_t request_cseq_number = 0; - sipRet_t tflag = STATUS_FAILURE; - int16_t trx_index = -1; - - if (TRUE == isResponse) { - if (response_cseq_number == 0) { - trx_index = get_method_request_trx_index(ccb, method, FALSE); - if (trx_index != -1) { - request_cseq_number = ccb->recv_request[trx_index].cseq_number; - } else { - return FALSE; - } - } else { - request_cseq_number = response_cseq_number; - } - } else { - // For Request - if (method == sipMethodAck) { - request_cseq_number = response_cseq_number; - } else { - // Pull up the previously allocated transaction - trx_index = get_last_request_trx_index(ccb, TRUE); - if (trx_index < 0) { - return FALSE; - } - request_cseq_number = ccb->sent_request[trx_index].cseq_number; - } - } - tflag = sippmh_add_cseq(request, sipGetMethodString(method), - request_cseq_number); - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - return TRUE; -} - -/* - * This will generate the most common headers for every message - */ - -sipRet_t -sipSPIAddCommonHeaders (ccsipCCB_t *ccb, - sipMessage_t *request, - boolean isResponse, - sipMethod_t method, - uint32_t response_cseq_number) -{ - sipRet_t tflag = STATUS_FAILURE; - - tflag = (sipSPIAddStdHeaders(request, ccb, isResponse)) ? - STATUS_SUCCESS : STATUS_FAILURE; - if (tflag != HSTATUS_SUCCESS) { - return tflag; - } - - // Add date header - tflag = sipAddDateHeader(request); - if (tflag != HSTATUS_SUCCESS) { - return tflag; - } - - // Add CSEQ - if (AddCSeq(ccb, request, isResponse, method, response_cseq_number) - == FALSE) { - return STATUS_FAILURE; - } - - return HSTATUS_SUCCESS; -} - -boolean -is_extended_feature (ccsipCCB_t *ccb) -{ - if (ccb) { - switch (ccb->featuretype) { - case CC_FEATURE_B2BCONF: - case CC_FEATURE_CANCEL: - return TRUE; - default: - return FALSE; - } - } - return FALSE; -} - -boolean -sipSPIGenRequestURI (ccsipCCB_t *ccb, sipMethod_t sipmethod, boolean initInvite) -{ - sipUrl_t *sipUrl = NULL; - int i = 0; - const char *fname = "sipSPIGenRequestURI"; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char *domainloc; - genUrl_t *gen; - int j = 0; - boolean lr = FALSE, uriAdded = FALSE; - char hdr_str[MAX_SIP_URL_LENGTH]; - - /* - * Construct the request URI - */ - // Special case for Initial Invite and Cancel messgae for creating - // the Request URI - if ((sipMethodInvite == sipmethod) && (initInvite == TRUE)) { - // This is the first Invite initiated so Request URI is - // built differently. - if (ccb->calledNumber[0] == '<') { - // Remove leading '<' - sstrncpy(ccb->ReqURI, ccb->calledNumber + 1, MAX_SIP_URL_LENGTH); - } - // If there is no hostname, add proxy address as hostname - domainloc = strchr(ccb->ReqURI, '@'); - if (domainloc == NULL) { - domainloc = ccb->ReqURI + strlen(ccb->ReqURI); - if ((domainloc - ccb->ReqURI) < (MAX_SIP_URL_LENGTH - 1)) { - /* - * We need to check and see if we are already truncating a - * string string that goes into ReqURI. If we are, then we - * CANNOT add any more characters without overwriting memory - */ - *domainloc++ = '@'; - sstrncpy(dest_sip_addr_str, ccb->reg.proxy, - MAX_IPADDR_STR_LEN); - - if (ccb->reg.addr.type == CPR_IP_ADDR_IPV6) { - *domainloc++ = '['; - } - - sstrncpy(domainloc, dest_sip_addr_str, - MAX_SIP_URL_LENGTH - (domainloc - ccb->ReqURI)); - - if (ccb->reg.addr.type == CPR_IP_ADDR_IPV6) { - *domainloc++ = ']'; - } - } - } - // Remove trailing '>' - domainloc = strchr(ccb->ReqURI, '>'); - if (domainloc) { - *domainloc = '\0'; - } - return TRUE; - } else if ((sipMethodCancel == sipmethod) || - ((sipMethodAck == sipmethod) && - (gCallHistory[ccb->index].last_rspcode_rcvd > codeClass2xx))) { - /* Use the same REQ URI that was created on the INVITE - * Replace the ReqURI with the contents of ReqURIOriginal - */ - if (ccb->ReqURIOriginal[0] != '\0') { - sstrncpy(ccb->ReqURI, ccb->ReqURIOriginal, MAX_SIP_URL_LENGTH); - } - return TRUE; - } - - if (sipMethodRegister == sipmethod || - ((sipMethodRefer == sipmethod) && - (ccb->type == SIP_REG_CCB || is_extended_feature(ccb)))) { - // If it is REGISTER or a token-registration REFER, the URI is formed - // simply by the destination IP address. This is also the case when - // sending a REFER for one of the softkey functions for TNP - if (ccb->reg.proxy[0] == '\0') { - ipaddr2dotted(dest_sip_addr_str, &ccb->dest_sip_addr); - } else { - sstrncpy(dest_sip_addr_str, ccb->reg.proxy, MAX_IPADDR_STR_LEN); - } - if (ccb->dest_sip_addr.type == CPR_IP_ADDR_IPV6) { - - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, "sip:[%s]", - dest_sip_addr_str); /* proxy */ - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, "sip:%s", - dest_sip_addr_str); /* proxy */ - } - - return TRUE; - } else { - if (ccb->record_route_info) { - /* - * If loose-routing is being used, use the remote contact in - * REQ-URI - */ - if (ccb->flags & INCOMING) { - i = 0; - } else { - i = ccb->record_route_info->num_locations - 1; - } - - if (ccb->record_route_info->locations[i]->genUrl->schema - == URL_TYPE_SIP) { - if (ccb->record_route_info->locations[i]->genUrl->u.sipUrl->lr_flag) { - lr = TRUE; - } - } - if (!lr) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Strict Routing: Forming Req-URI using " - "Record Route\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - if (ccb->record_route_info->locations[i]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = ccb->record_route_info->locations[i]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), - fname); - return (FALSE); - } - - if (sipUrl->user != NULL) { - if (sipUrl->password) { - if (sipUrl->port_present) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%s@%s;user=phone" : - "sip:%s:%s@%s", - sipUrl->user, sipUrl->password, - sipUrl->host); - } - } else { - if (sipUrl->port_present) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s@%s:%d;user=phone" : "sip:%s@%s:%d", - sipUrl->user, sipUrl->host, sipUrl->port); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s@%s;user=phone" : "sip:%s@%s", - sipUrl->user, sipUrl->host); - } - } - } else { - if (sipUrl->port_present) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%d;user=phone" : "sip:%s:%d", - sipUrl->host, sipUrl->port); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s;user=phone" : "sip:%s", - sipUrl->host); - } - } - uriAdded = TRUE; - } - } - - if (!uriAdded) { - if ((ccb->contact_info) && - (lr || (ccb->state >= SIP_STATE_SENT_INVITE_CONNECTED))) { - // Use Contact info ONLY if loose routing or - // if we're fully connected - otherwise use proxy - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI: using Contact\n", - DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - - if ((sipMethodInvite == sipmethod) && - (ccb->redirect_info) && - (ccb->state == SIP_STATE_SENT_INVITE)) { - sipUrl = ccb->redirect_info->sipContact->locations - [ccb->redirect_info->next_choice - 1]->genUrl->u.sipUrl; - } else if (ccb->contact_info->locations[0]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = ccb->contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), - fname); - return (FALSE); - } - if (sipUrl->user != NULL) { - if (sipUrl->password) { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s@%s:%d;user=phone" : - "sip:%s@%s:%d", - sipUrl->user, sipUrl->host, sipUrl->port); - } - } else { - snprintf(ccb->ReqURI, MAX_SIP_URL_LENGTH, - sipUrl->is_phone ? - "sip:%s:%d;user=phone" : - "sip:%s:%d", - sipUrl->host, sipUrl->port); - } - } else { - if (ccb->flags & INCOMING) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI (Callee): using " - "From\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - if (ccb->sip_from) { - sstrncpy(hdr_str, ccb->sip_from, MAX_SIP_URL_LENGTH); - sstrncpy(ccb->ReqURI, sippmh_get_url_from_hdr(hdr_str), MAX_SIP_URL_LENGTH); - } - } else { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI (Caller): using " - "original Req-URI\n", DEB_F_PREFIX_ARGS(SIP_REQ_URI, fname)); - sstrncpy(ccb->ReqURI, ccb->ReqURIOriginal, - MAX_SIP_URL_LENGTH); - } - } - } - - // Check to see the transport parameter specified in sipUrl. - // If this is different than UDP, add it to the URI - if (sipUrl) { - switch (sipUrl->transport) { - case TRANSPORT_UDP: - sstrncat(ccb->ReqURI, ";transport=udp", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - case TRANSPORT_TCP: - sstrncat(ccb->ReqURI, ";transport=tcp", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - case TRANSPORT_TLS: - sstrncat(ccb->ReqURI, ";transport=tls", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - case TRANSPORT_SCTP: - sstrncat(ccb->ReqURI, ";transport=sctp", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - default: - break; - } - } - if (ccb->record_route_info) { - /* - * Look for any unknown params that might have been - * glued onto the URL - */ - gen = ccb->record_route_info->locations[i]->genUrl; - while (j < SIP_MAX_LOCATIONS) { - if (gen->other_params[j] != NULL) { - sstrncat(ccb->ReqURI, ";", - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - sstrncat(ccb->ReqURI, gen->other_params[j], - sizeof(ccb->ReqURI) - strlen(ccb->ReqURI)); - break; - } - j++; - } - } - } - return TRUE; -} - -sipRet_t -sipSPIAddContactHeader (ccsipCCB_t *ccb, sipMessage_t *request) -{ - char pContactStr[MAX_SIP_URL_LENGTH]; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char line_name[MAX_LINE_NAME_SIZE]; - char reg_user_info[MAX_REG_USER_INFO_LEN]; - int rpid_flag = RPID_DISABLED; - int blocking; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char device_instance[MAX_SIP_TAG_LENGTH]; - char contact[MAX_LINE_CONTACT_SIZE]; - size_t escaped_char_str_len; - const char *transport_type_str; - int size; - char sipDeviceName[MAX_REG_USER_INFO_LEN]; - - config_get_value(CFGID_REMOTE_PARTY_ID, &rpid_flag, sizeof(rpid_flag)); - - config_get_value(CFGID_DEVICE_NAME, sipDeviceName, sizeof(sipDeviceName)); - - /* get reg_user_info and pk-id */ - contact[0] = '\0'; - config_get_string(CFGID_REG_USER_INFO, reg_user_info, - sizeof(reg_user_info)); - config_get_line_string(CFGID_LINE_CONTACT, contact, ccb->dn_line, - sizeof(contact)); - - - ipaddr2dotted(src_addr_str, &ccb->src_addr); - - config_get_value(CFGID_CALLERID_BLOCKING, &blocking, sizeof(blocking)); - - transport_type_str = sipTransportGetTransportType(ccb->dn_line, FALSE, ccb); - - /* - * If caller id blocking is enabled and phone - * is configured to use RPID then userinfo should - * be random identifier same as that used in from - * header - */ - if ((blocking & 1) && (rpid_flag == RPID_ENABLED) && - (ccb->type != SIP_REG_CCB)) { - sstrncpy(line_name, SIP_HEADER_ANONYMOUS_STR, MAX_LINE_NAME_SIZE); - } else { - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, - sizeof(line_name)); - } - - if (ccb->type == SIP_REG_CCB) { - snprintf(pContactStr, 6, "", src_addr_str, - ccb->local_port, transport_type_str); - } else { - snprintf(pContactStr + 5 + escaped_char_str_len, - sizeof(pContactStr) - 5 - escaped_char_str_len, - "@%s:%d;user=%s;transport=%s>", - src_addr_str, ccb->local_port, reg_user_info, - transport_type_str); - } - - // Add the instance ID for unique device identification - // The format is as follows: - // Contact: - // ;+sip.instance="" - // ;+u.sip!model.ccm.cisco.com="336" - // where the 000A95A0E128 is the MAC address of the phone and - // the 336 is the model number of the phone - // All the 000's are supposed to encode callee capabilities (RFC 3840) - // but we are leaving them 000 for now as no-one reads them - platform_get_active_mac_address(mac_address); - memset(device_instance, '\0', sizeof(device_instance)); - snprintf(device_instance, MAX_SIP_TAG_LENGTH, - ";+sip.instance=\"\"", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5]); - size = MAX_SIP_URL_LENGTH - strlen(pContactStr); - if (size > (int)strlen(device_instance)) { - sstrncat(pContactStr, device_instance, size); - } - // Add the instance ID for unique device identification - // The format is as follows: - // Contact: ;+sip.instance=""; - //+u.sip!devicename.ccm.cisco.com="SEP0019E89A7F3D"; - //++u.sip!model.ccm.cisco.com="30006" - // where the 000A95A0E128 is the MAC address of the phone and - // the 336 is the model number of the phone - // All the 000's are supposed to encode callee capabilities (RFC 3840) - // but we are leaving them 000 for now as no-one reads them - platform_get_wired_mac_address(mac_address); - memset(device_instance, '\0', sizeof(device_instance)); - snprintf(device_instance, MAX_SIP_TAG_LENGTH, - ";+sip.instance=\"\"" - ";+u.sip!devicename.ccm.cisco.com=\"%s\"" - ";+u.sip!model.ccm.cisco.com=\"%s\"", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - sipDeviceName, - sipPhoneModelNumber); - size = MAX_SIP_URL_LENGTH - strlen(pContactStr); - if (size > (int)strlen(device_instance)) { - sstrncat(pContactStr, device_instance, size); - } - // add tag cisco-keep-alive for keep alive messages in ccm mode - if ((ccb->cc_type == CC_CCM) && (ccb->index >= REG_BACKUP_CCB)) { - sipMethod_t method = sipMethodInvalid; - - sipGetRequestMethod(request, &method); - if (method == sipMethodRegister) { - sstrncat(pContactStr, ";expires=0;cisco-keep-alive", - sizeof(pContactStr) - strlen(pContactStr)); - } - } - } else { - char *forward_url = NULL; - - forward_url = Basic_is_phone_forwarded(ccb->dn_line); - /* only use the forward URL if we are sending a 302 */ - if ((forward_url) && - (strstr(request->mesg_line, SIP_RED_MOVED_TEMP_PHRASE))) { - char *user_info = strchr(forward_url, '@'); - - /* - * forward_url will always have domain/host address preceded - * by @ following the user, returned by - * Basic_is_phone_forwarded. so no need to check for - * user_info == NULL - */ - snprintf(pContactStr, 6, "", - user_info); - } else { - /* - * Use the contact value supplied to us, if available. - * If not, use name - */ - snprintf(pContactStr, 6, "", src_addr_str, - ccb->local_port, transport_type_str); - } else { - snprintf(pContactStr + 5 + escaped_char_str_len, - sizeof(pContactStr) - 5 - escaped_char_str_len, - "@%s:%d;user=%s;transport=%s>", - src_addr_str, ccb->local_port, - reg_user_info, transport_type_str); - } - } - } - return (sippmh_add_text_header(request, SIP_HEADER_CONTACT, pContactStr)); -} - -/** - * Convert phone name to upper case - * - * @param phone_name - phone name - * - * @return status none - * - * @pre none - */ -void convert_phone_name_to_upper_case(char *phone_name) -{ - while (phone_name && (*phone_name) != '\0') { - *phone_name = (char)toupper(*phone_name); - phone_name++; - } -} -/** - * Add reason header to SIP message - * - * eg: Reason: SIP;cause=200;text="cisco:22 Name=SEP000000000000 - * Load=SIP70.8-2-25 Last=reset-reset - * - * @param ccb call control block - * @param request sip message - * - * @return status - * success: STATUS_SUCCESS - * failure: STATUS_FAILURE - * - * @pre (ccb not_eq NULL) - * @pre (request not_eq NULL) - * - */ -sipRet_t -sipSPIAddReasonHeader (ccsipCCB_t *ccb, sipMessage_t *request) -{ - const char *fname = "sipSPIAddReasonHeader"; - char pReasonStr[MAX_SIP_HEADER_LENGTH]; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char phone_name[MAX_PHONE_NAME_LEN]; - char image_a[MAX_LOAD_ID_STRING]; - char image_b[MAX_LOAD_ID_STRING]; - int active_partition; - int unreg_reason_code = 0; - char unreg_reason_str[MAX_UNREG_REASON_STR_LEN]; - - if (ccb->send_reason_header) { - // should only be set when the phone is registering after a restart/reset - platform_get_wired_mac_address(mac_address); - - snprintf(phone_name, MAX_PHONE_NAME_LEN, "SEP%04x%04x%04x", mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5]); - - convert_phone_name_to_upper_case(phone_name); - - - unreg_reason_code = platGetUnregReason(); - - unreg_reason_str[0] = '\0'; - get_reason_string(unreg_reason_code, unreg_reason_str, MAX_UNREG_REASON_STR_LEN); - active_partition = platGetActiveInactivePhoneLoadName(image_a, image_b, MAX_LOAD_ID_STRING); - snprintf(pReasonStr, MAX_SIP_HEADER_LENGTH, - "SIP;cause=200;text=\"cisco-alarm:%d Name=%s ActiveLoad=%s InactiveLoad=%s Last=%s", - unreg_reason_code, phone_name, (active_partition == 1) ? image_a:image_b, - (active_partition == 1) ? image_b:image_a, unreg_reason_str); - sstrncat(pReasonStr, "\"", - MAX_SIP_HEADER_LENGTH - strlen(pReasonStr) - 1); - return (sippmh_add_text_header(request, SIP_HEADER_REASON, pReasonStr)); - } else { - CCSIP_DEBUG_ERROR("%s called with send_reason_header set to false\n", fname); - return (STATUS_SUCCESS); - } -} - -/** - * Return the reason string that is to be returned - * corresponding to the unreg reason that is to be sent - * in the register message. - * - * @param unreg_reason - unreg reason code - * @param char * - reason string corresponding to the code - * @return none - * - */ -void -get_reason_string (int unreg_reason, char *unreg_reason_str, int len) -{ - - switch(unreg_reason) { - case UNREG_REASON_RESET_RESTART: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "reset-restart"); - break; - case UNREG_REASON_RESET_RESET: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "reset-reset"); - break; - case UNREG_REASON_PHONE_INITIALIZED: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "initialized"); - break; - case UNREG_REASON_REG_TIMEOUT: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "reg-timeout"); - break; - case UNREG_REASON_PHONE_KEYPAD: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "phone-keypad"); - break; - case UNREG_REASON_PHONE_REG_REJ: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "phone-reg-rej"); - break; - case UNREG_REASON_FALLBACK: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "fallback"); - break; - case UNREG_REASON_VERSION_STAMP_MISMATCH: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "version-stamp-mismatch(%s)", sipUnregisterReason); - break; - case UNREG_REASON_VERSION_STAMP_MISMATCH_CONFIG: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "version-stamp-mismatch-config"); - break; - case UNREG_REASON_VERSION_STAMP_MISMATCH_SOFTKEY: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "version-stamp-mismatch-softkey"); - break; - case UNREG_REASON_VERSION_STAMP_MISMATCH_DIALPLAN: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "version-stamp-mismatch-dialplan"); - break; - case UNREG_REASON_CONFIG_RETRY_RESTART: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "config-retry-restart"); - break; - case UNREG_REASON_TLS_ERROR: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "tls-error"); - break; - case UNREG_REASON_TCP_TIMEOUT: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "tcp_timeout"); - break; - case UNREG_REASON_CM_CLOSED_TCP: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "cm-closed-tcp"); - break; - case UNREG_REASON_CM_RESET_TCP: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "cm-reset-tcp"); - break; - case UNREG_REASON_CM_ABORTED_TCP: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "cm-aborted-tcp"); - break; - case UNREG_REASON_APPLY_CONFIG_RESTART: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "apply_config"); - break; - case UNREG_REASON_VOICE_VLAN_CHANGED: - snprintf(unreg_reason_str, MAX_UNREG_REASON_STR_LEN, "VLAN-Changed"); - break; - default: - unreg_reason_str[0] = '\0'; - CCSIP_DEBUG_ERROR("Unkown unreg reason code passed\n"); - break; - } -} -boolean -CreateRequest (ccsipCCB_t *ccb, sipMessageFlag_t messageflag, - sipMethod_t sipmethod, sipMessage_t *request, - boolean initInvite, uint32_t response_cseq_number) -{ - sipRet_t tflag = STATUS_FAILURE; - - if (!request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "CreateRequest", "GET_SIP_MESSAGE()"); - return FALSE; - } - - - if (sipMethodResponse != sipmethod) { - if (sipSPIAddRequestLine(ccb, request, sipmethod, initInvite) - == STATUS_FAILURE) { - return FALSE; - } - } - - ccb->outBoundProxyPort = 0; - ccb->outBoundProxyAddr = ip_addr_invalid; - if (ccb->ObpSRVhandle != NULL) { - dnsFreeSrvHandle(ccb->ObpSRVhandle); - ccb->ObpSRVhandle = NULL; - } - - tflag = (allocateTrx(ccb, sipmethod)) ? STATUS_SUCCESS : STATUS_FAILURE; - - if (tflag == STATUS_SUCCESS) { - tflag = (sipSPIAddLocalVia(request, ccb, sipmethod)) ? - STATUS_SUCCESS : STATUS_FAILURE; - /* Don't stop adding headers to a Register just because - * the VIA line wasn't added. A Register doesn't really - * need the VIA line anyways. - */ - if ((HSTATUS_SUCCESS != tflag) && (ccb->type != SIP_REG_CCB)) { - return FALSE; - } - } - - if (tflag == STATUS_SUCCESS) { - tflag = sipSPIAddCommonHeaders(ccb, request, FALSE, sipmethod, - response_cseq_number); - } - - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - - tflag = sippmh_add_text_header(request, SIP_HEADER_USER_AGENT, - sipHeaderUserAgent); - - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - return AddGeneralHeaders(ccb, messageflag, request, sipmethod); -} - -boolean -CreateResponse (ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - uint16_t status_code, - sipMessage_t *response, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - sipMethod_t method) -{ - sipRet_t tflag = HSTATUS_SUCCESS; - char *warning = NULL; - uint32_t response_cseq_number = 0; - - if (!ccb) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - "CreateResponse", "ccb"); - return FALSE; - } - if (!ccb->last_request) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - "Create Response", "ccb->last_request"); - return FALSE; - } - if (!response) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "CreateResponse", "GET_SIP_MESSAGE()"); - return FALSE; - } - - tflag = sippmh_add_response_line(response, SIP_VERSION, status_code, - reason_phrase); - - if (tflag != HSTATUS_SUCCESS) - return FALSE; - - tflag = (sipSPIAddRequestVia(ccb, response, ccb->last_request, method)) ? - STATUS_SUCCESS : STATUS_FAILURE; - - if (tflag != HSTATUS_SUCCESS) - return FALSE; - - response_cseq_number = 0; - - tflag = sipSPIAddCommonHeaders(ccb, response, TRUE, method, - response_cseq_number); - if (tflag != HSTATUS_SUCCESS) - return FALSE; - - if (reason_phrase_warning) { - warning = (char *) cpr_malloc(strlen(reason_phrase_warning) + 5); - if (warning) { - snprintf(warning, strlen(reason_phrase_warning) + 5, - "%d %s", status_code_warning, reason_phrase_warning); - tflag = sippmh_add_text_header(response, SIP_HEADER_WARN, warning); - cpr_free(warning); - if (tflag != HSTATUS_SUCCESS) - return FALSE; - } - } - - tflag = sippmh_add_text_header(response, SIP_HEADER_SERVER, - sipHeaderServer); - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - - return AddGeneralHeaders(ccb, messageflag, response, method); -} - -/************************************************************* - * Function: SendRequest - * this function sends out a request pointed to by the request parameter - * in ccb's context. - * - * 'request' will be freed. The caller does not have the responsibility - * to free it. - **************************************************************/ -boolean -SendRequest (ccsipCCB_t *ccb, sipMessage_t *request, sipMethod_t method, - boolean midcall, boolean reTx, boolean retranTimer) -{ - const char *fname = "SendRequest"; - cpr_ip_addr_t cc_remote_ipaddr; - uint16_t cc_remote_port = 0; - int timeout = 0; - int expires_timeout; - sipUrl_t *sipUrl = NULL; - boolean isRegister = FALSE; - int16_t trx_index; - int reldev_stored_msg = RELDEV_NO_STORED_MSG; - - CPR_IP_ADDR_INIT(cc_remote_ipaddr); - - if (sipMethodRegister == method) { - if (ccb->reg.proxy[0] == '\0') { - cc_remote_ipaddr = ccb->dest_sip_addr; - cc_remote_port = (uint16_t) ccb->dest_sip_port; - } else { - cc_remote_ipaddr = ccb->reg.addr; - cc_remote_port = ccb->reg.port; - } - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - isRegister = TRUE; - - } else if ((sipMethodInvite == method) && (midcall == FALSE)) { - char *host; - - if (!ccb->ReqURI) { - free_sip_message(request); - return FALSE; - } - host = strchr(ccb->ReqURI, '@'); - if (!host) { - free_sip_message(request); - return FALSE; - } - - /* Enable reTx and send */ - if (TRUE == reTx) { - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - } - cc_remote_ipaddr = ccb->dest_sip_addr; - cc_remote_port = (uint16_t) ccb->dest_sip_port; - } else { - if ((ccb->record_route_info) && (sipMethodCancel != method)) { - int16_t i; - - if (ccb->flags & INCOMING) { - i = 0; - } else { - i = ccb->record_route_info->num_locations - 1; - } - - if (ccb->record_route_info->locations[i]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = ccb->record_route_info->locations[i]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - free_sip_message(request); - return (FALSE); - } - - cc_remote_port = sipUrl->port; - - if (!sipUrl->port_present) { - dns_error_code = - sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(sipSPIUrlDestination(sipUrl), - &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code == 0) { - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } else { - cc_remote_ipaddr = ip_addr_invalid; - } - - } else if ((ccb->contact_info) && - (ccb->state >= SIP_STATE_SENT_INVITE_CONNECTED)) { - /* - * If the call has been set up, we are free to use the - * contact header. If the call has NOT been set up, - * drop through and use the proxy. - */ - if (ccb->contact_info->locations[0]->genUrl->schema - == URL_TYPE_SIP) { - sipUrl = ccb->contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_URL_ERROR), fname); - free_sip_message(request); - return (FALSE); - } - - cc_remote_port = sipUrl->port; - - if (!sipUrl->port_present) { - dns_error_code = - sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(sipSPIUrlDestination(sipUrl), - &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code == 0) { - - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } else { - cc_remote_ipaddr = ip_addr_invalid; - } - - } else { - cc_remote_ipaddr = ccb->dest_sip_addr; - cc_remote_port = (uint16_t) ccb->dest_sip_port; - } - if (TRUE == reTx) - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - } - - if (util_check_if_ip_valid(&cc_remote_ipaddr) == FALSE) { - free_sip_message(request); - return (FALSE); - } - - // Update default destination address and port - ccb->dest_sip_addr = cc_remote_ipaddr; - ccb->dest_sip_port = cc_remote_port; - - /* - * Store the ACK so that it can be retransmitted in response - * to any duplicate 200 OK or error responses - */ - trx_index = get_last_request_trx_index(ccb, TRUE); - if (trx_index < 0) { - CCSIP_DEBUG_ERROR("%s: No Valid Trx found!\n", "SendRequest"); - return (FALSE); - } - if (sipMethodAck == method) { - reldev_stored_msg = - sipRelDevCoupledMessageStore(request, ccb->sipCallID, - ccb->sent_request[trx_index].cseq_number, - ccb->sent_request[trx_index].cseq_method, - TRUE, ccb->last_recvd_response_code, - &cc_remote_ipaddr, cc_remote_port, - FALSE /* Do check tag */); - } - if (sipTransportCreateSendMessage(ccb, request, method, - &cc_remote_ipaddr, cc_remote_port, - isRegister, reTx, timeout, NULL, - reldev_stored_msg) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "SendRequest", "sipTransportCreateSendMessage()"); - //dont need message free here..sipTransportCreateSendMessage() will free it - return (FALSE); - } - - /* Start INVITE expires timer */ - if (retranTimer) { - config_get_value(CFGID_TIMER_INVITE_EXPIRES, &expires_timeout, - sizeof(expires_timeout)); - if (expires_timeout > 0) { - if (sip_platform_expires_timer_start(expires_timeout * 1000, - ccb->index, - &cc_remote_ipaddr, //ccb->dest_sip_addr, - cc_remote_port) //ccb->dest_sip_port, - != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "SendRequest", - "sip_platform_expires_timer_start()"); - return (FALSE); - } - } - } - // Save Call History - if (sipMethodCancel == method || sipMethodBye == method) { - gCallHistory[ccb->index].last_bye_cseq_number = - ccb->sent_request[trx_index].cseq_number; - gCallHistory[ccb->index].proxy_dest_ipaddr = ccb->dest_sip_addr; - gCallHistory[ccb->index].dn_line = ccb->dn_line; - sstrncpy(gCallHistory[ccb->index].via_branch, - ccb->sent_request[trx_index].u.sip_via_branch, - VIA_BRANCH_LENGTH); - } - return (TRUE); -} - -boolean -sendResponse (ccsipCCB_t *ccb, - sipMessage_t *response, - sipMessage_t *refrequest, - boolean retx, - sipMethod_t method) -{ - sipVia_t *via = NULL; - const char *request_callid = NULL; - sipCseq_t *request_cseq_structure; - cpr_ip_addr_t cc_remote_ipaddr; - uint16_t cc_remote_port = 0; - int timeout = 0; - const char *pViaHeaderStr = NULL; - char *dest_ip_addr_str = 0; - int16_t trx_index = -1; - boolean port_present = FALSE; - int reldev_stored_msg; - int status_code = 0; - - CPR_IP_ADDR_INIT(cc_remote_ipaddr); - - if (ccb) { - request_callid = ccb->sipCallID; - trx_index = get_method_request_trx_index(ccb, method, FALSE); - if (trx_index >= 0) { - pViaHeaderStr = (const char *) - (ccb->recv_request[trx_index].u.sip_via_header); - request_cseq_structure = (sipCseq_t *) - cpr_malloc(sizeof(sipCseq_t)); - if (!request_cseq_structure) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", "malloc failed"); - free_sip_message(response); - return (FALSE); - } - request_cseq_structure->method = - ccb->recv_request[trx_index].cseq_method; - request_cseq_structure->number = - ccb->recv_request[trx_index].cseq_number; - } else { - pViaHeaderStr = - sippmh_get_cached_header_val(ccb->last_request, VIA); - if (getCSeqInfo(ccb->last_request, &request_cseq_structure) - == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", "getCSeqInfo returned false"); - free_sip_message(response); - return (FALSE); - } - } - } else { - pViaHeaderStr = sippmh_get_cached_header_val(refrequest, VIA); - request_callid = sippmh_get_cached_header_val(refrequest, CALLID); - if (FALSE == getCSeqInfo(refrequest, &request_cseq_structure)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", "getCSeqInfo returned false"); - free_sip_message(response); - return (FALSE); - } - } - - via = sippmh_parse_via(pViaHeaderStr); - if (!via) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", "Bad Via Header in Message!"); - cpr_free(request_cseq_structure); - free_sip_message(response); - return (FALSE); - } - - if (via->remote_port) { - cc_remote_port = via->remote_port; - port_present = TRUE; - } else { - /* Use default 5060 if via does not have port */ - cc_remote_port = SIP_WELL_KNOWN_PORT; - } - - /* - * if maddr is present use it - */ - if (via->maddr) { - if (!port_present) { - dns_error_code = sipTransportGetServerAddrPort(via->maddr, - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(via->maddr, - &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", - "sipTransportGetServerAddrPort or dnsGetHostByName"); - } else { - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } - } - - /* - * if maddr isn't present, or the DNS lookup failed, send the - * response to the IP address we received the message from. - */ - if (util_check_if_ip_valid(&cc_remote_ipaddr) == FALSE) { - if (via->recd_host) { - dest_ip_addr_str = via->recd_host; - } else { - dest_ip_addr_str = via->host; - } - - if (!port_present) { - dns_error_code = sipTransportGetServerAddrPort(dest_ip_addr_str, - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(dest_ip_addr_str, - &cc_remote_ipaddr, 100, 1); - } - if (dns_error_code != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "Sendresponse", - "sipTransportGetServerAddrPort or dnsGetHostByName"); - cpr_free(request_cseq_structure); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } else { - util_ntohl(&cc_remote_ipaddr , &cc_remote_ipaddr); - } - } - - sippmh_free_via(via); - - reldev_stored_msg = - sipRelDevCoupledMessageStore(response, request_callid, - request_cseq_structure->number, - request_cseq_structure->method, - FALSE, status_code, - &cc_remote_ipaddr, cc_remote_port, - /* If responding to call setup don't check tag */ - (boolean)(ccb != NULL ? - SIP_SM_CALL_SETUP_RESPONDING(ccb) : - FALSE)); - cpr_free(request_cseq_structure); - /* Enable reTx and send */ - if (retx) { - config_get_value(CFGID_TIMER_T1, &timeout, sizeof(timeout)); - if (ccb) { - ccb->retx_counter = 0; - } - } else { - timeout = 0; /* No reTx timer */ - } - - if (sipTransportChannelCreateSend(ccb, response, sipMethodResponse, - &cc_remote_ipaddr, cc_remote_port, - timeout, reldev_stored_msg) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "SendResponse", "sipTransportChannelCreateSend()"); - return FALSE; - } - return TRUE; -} - -static sipRet_t -CopyLocalSDPintoResponse (sipMessage_t *request, - cc_msgbody_info_t *local_msg_body) -{ - sipRet_t tflag = HSTATUS_SUCCESS; - uint32_t body_index; - cc_msgbody_info_t tmp_body, *tmp_body_p; - cc_msgbody_t *part; - - if (local_msg_body->num_parts == 0) { - /* content type specified but no msg. body to add */ - return HSTATUS_FAILURE; - } - - /* - * Duplicate a msg. body to send out which will be freed - * after the full message is created during the send of the - * msg. - */ - tmp_body.num_parts = 0; /*initialize to no parts */ - tmp_body_p = &tmp_body; - if (cc_cp_msg_body_parts(tmp_body_p, local_msg_body) != CC_RC_SUCCESS) { - /* Unable to duplicate the msg. body */ - return HSTATUS_FAILURE; - } - part = &tmp_body_p->parts[0]; - for (body_index = 0; body_index < tmp_body_p->num_parts; body_index++) { - if ((part->body != NULL) && (part->body_length)) { - tflag = sippmh_add_message_body(request, part->body, - part->body_length, - cc2siptype(part->content_type), - cc2sipdisp(part->content_disposition.disposition), - part->content_disposition.required_handling, - part->content_id); - } else { - /* Invalid entry */ - tflag = HSTATUS_FAILURE; - break; - } - } - return tflag; -} - -boolean -AddGeneralHeaders (ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - sipMessage_t *request, - sipMethod_t sipmethod) -{ - const char *fname = "AddGeneralHeaders"; - sipRet_t tflag = HSTATUS_SUCCESS; - unsigned int isOver = messageflag.flags; - unsigned int whichflag = 0x0001; - unsigned int bit_to_reset = 0; // Test and then reset - int16_t i; - int time_exp; - unsigned int info_index; - cpr_ip_mode_e ip_mode; - - while (0 != isOver) { - bit_to_reset = (whichflag & messageflag.flags); - switch (bit_to_reset) { - case SIP_HEADER_CONTACT_BIT: - tflag = sipSPIAddContactHeader(ccb, request); - break; - - case SIP_HEADER_RECORD_ROUTE_BIT: - if (ccb->record_route_info) { - tflag = (sipSPIAddRequestRecordRoute(request, ccb->last_request)) ? - STATUS_SUCCESS : STATUS_FAILURE; - } - break; - - case SIP_HEADER_ROUTE_BIT: - tflag = (sipSPIAddRouteHeaders(request, ccb, NULL, 0)) ? - STATUS_SUCCESS : STATUS_FAILURE; - break; - - case SIP_HEADER_UNSUPPORTED_BIT: - if (ccb->sip_unsupported[0] != '\0') { - tflag = sippmh_add_text_header(request, - SIP_HEADER_UNSUPPORTED, - &ccb->sip_unsupported[0]); - } - break; - - case SIP_HEADER_REQUESTED_BY_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_REQUESTED_BY, - ccb->sip_reqby); - break; - - case SIP_HEADER_REMOTE_PARTY_ID_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_REMOTE_PARTY_ID, - ccb->sip_remote_party_id); - break; - - case SIP_HEADER_DIVERSION_BIT: - for (i = 0; i < MAX_DIVERSION_HEADERS; i++) { - if (ccb->diversion[i]) { - tflag = sippmh_add_text_header(request, - SIP_HEADER_DIVERSION, - ccb->diversion[i]); - if (tflag != HSTATUS_SUCCESS) - break; - } - } - break; - - case SIP_HEADER_AUTHENTICATION_BIT: - tflag = sippmh_add_text_header(request, - AUTHOR_HDR(ccb->authen.status_code), - ccb->authen.authorization); - break; - - case SIP_HEADER_PROXY_AUTH_BIT: - // This happens when we get a refer with a proxy-auth. We just - // parrot whatever the proxy told us to do in this invite. - tflag = sippmh_add_text_header(request, - SIP_HEADER_PROXY_AUTHORIZATION, - ccb->refer_proxy_auth); - break; - - case SIP_HEADER_REFER_TO_BIT: - break; - - case SIP_HEADER_REFERRED_BY_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_REFERRED_BY, - ccb->sip_referredBy); - break; - - case SIP_HEADER_REPLACES_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_REPLACES, - ccb->sipxfercallid); - break; - - case SIP_HEADER_EVENT_BIT: - break; - - case SIP_HEADER_EXPIRES_BIT: - config_get_value(CFGID_TIMER_INVITE_EXPIRES, &time_exp, - sizeof(time_exp)); - tflag = sippmh_add_int_header(request, SIP_HEADER_EXPIRES, - time_exp); - break; - - case SIP_HEADER_REASON_BIT: - tflag = sipSPIAddReasonHeader(ccb, request); - break; - - case SIP_HEADER_CONTENT_LENGTH_BIT: - if ((messageflag.flags & SIP_HEADER_CONTENT_TYPE_BIT) || - (messageflag.flags & SIP_HEADER_OPTIONS_CONTENT_TYPE_BIT)) { - /* - * Header content length will be set when SDP body is added - * so we do not set it here. - */ - break; - } - tflag = sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0); - break; - - case SIP_HEADER_CONTENT_TYPE_BIT: - tflag = CopyLocalSDPintoResponse(request, &ccb->local_msg_body); - if (tflag != HSTATUS_SUCCESS) { - /* there is some thing wrong with message body */ - CCSIP_DEBUG_ERROR("%s: Error adding message body.\n", fname); - break; - } - - /* - * SDP successfully added to message. Update offer/answer state. - */ - if (ccb->oa_state == OA_OFFER_RECEIVED) { - ccb->oa_state = OA_IDLE; - } else { - ccb->oa_state = OA_OFFER_SENT; - } - break; - - case SIP_HEADER_OPTIONS_CONTENT_TYPE_BIT: - tflag = CopyLocalSDPintoResponse(request, &ccb->local_msg_body); - if (tflag != HSTATUS_SUCCESS) { - /* there is some thing wrong with message body */ - CCSIP_DEBUG_ERROR("%s: Error adding options message body.\n", - fname); - } - - /* - * SDP successfully added to message. OPTIONS response does - * not alter offer/answer state as the - * SIP_HEADER_CONTENT_TYPE_BIT does. - */ - break; - - case SIP_HEADER_ALLOW_BIT: - { - char temp[MAX_SIP_HEADER_LENGTH]; - - snprintf(temp, MAX_SIP_HEADER_LENGTH, - "%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, - SIP_METHOD_OPTIONS, SIP_METHOD_REFER, - SIP_METHOD_REGISTER, SIP_METHOD_UPDATE); - sstrncat(temp, ",", sizeof(temp) - strlen(temp)); - sstrncat(temp, SIP_METHOD_SUBSCRIBE, sizeof(temp) - strlen(temp)); - sstrncat(temp, ",", sizeof(temp) - strlen(temp)); - sstrncat(temp, SIP_METHOD_INFO, sizeof(temp) - strlen(temp)); - tflag = sippmh_add_text_header(request, SIP_HEADER_ALLOW, temp); - } - break; - - case SIP_HEADER_ACCEPT_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - "application/sdp"); - break; - - case SIP_HEADER_ACCEPT_ENCODING_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT_ENCODING, - "identity"); - break; - - case SIP_HEADER_ACCEPT_LANGUAGE_BIT: - tflag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT_LANGUAGE, - "en"); - break; - - case SIP_HEADER_CISCO_GUID_BIT: - tflag = (sipSPIAddCiscoGuid(request, ccb)) ? - STATUS_SUCCESS : STATUS_FAILURE; - break; - - case SIP_HEADER_CALL_INFO_BIT: - /* - * Include call info header if in CCM mode or - * other end indicates that it can support it. - */ - if ((sip_regmgr_get_cc_mode(ccb->dn_line) == REG_MODE_CCM) || - (ccb->supported_tags & cisco_callinfo_tag)) { - tflag = (sipRet_t) sippmh_add_call_info(request, - ccb->out_call_info); - } - break; - - case SIP_HEADER_JOIN_INFO_BIT: - tflag = (sipRet_t) sippmh_add_join_header(request, ccb->join_info); - break; - - case SIP_HEADER_ALLOW_EVENTS_BIT: - { - char temp[MAX_SIP_HEADER_LENGTH]; - int kpml_config; - - // Get kpml configuration - config_get_value(CFGID_KPML_ENABLED, &kpml_config, - sizeof(kpml_config)); - if (kpml_config) { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s,%s", - SIP_EVENT_KPML, SIP_EVENT_DIALOG); - } else { - snprintf(temp, MAX_SIP_HEADER_LENGTH, "%s", - SIP_EVENT_DIALOG); - } - tflag = sippmh_add_text_header(request, SIP_HEADER_ALLOW_EVENTS, - temp); - } - break; - - case SIP_HEADER_SUPPORTED_BIT: - { - const char *opt_tags; - - opt_tags = sipGetSupportedOptionList(ccb, sipmethod); - - tflag = sippmh_add_text_header(request, - SIP_HEADER_SUPPORTED, - opt_tags); - } - break; - - case SIP_HEADER_REQUIRE_BIT: - ip_mode = platform_get_ip_address_mode(); - if (ip_mode == CPR_IP_MODE_DUAL) { - tflag = sippmh_add_text_header(request, SIP_HEADER_REQUIRE, "sdp-anat"); - } - break; - - case SIP_HEADER_RETRY_AFTER_BIT: - tflag = sippmh_add_int_header(request, - SIP_HEADER_RETRY_AFTER, - abs((cpr_rand() % 11))); - break; - - case SIP_HEADER_RECV_INFO_BIT: - for (info_index = 0; info_index < MAX_INFO_HANDLER; info_index++) { - if (g_registered_info[info_index] != NULL) { - tflag = sippmh_add_text_header(request, SIP_HEADER_RECV_INFO, - g_registered_info[info_index]); - if (tflag != HSTATUS_SUCCESS) { - break; - } - } - } - break; - - default: - //tflag = HSTATUS_FAILURE; - break; - } - - if (tflag != HSTATUS_SUCCESS) { - return FALSE; - } - whichflag = whichflag << 1; - /* - * Reset this bit so if nothing else is there we do not need to test - */ - isOver &= ~bit_to_reset; - } - return TRUE; -} - - -/************************************************************* - * Function: sipSPISendUpdate - * This function creates, formats, and sends an UPDATE message - * on an existing (early) dialog - **************************************************************/ -boolean -sipSPISendUpdate (ccsipCCB_t *ccb) -{ - const char *fname = "sipSPISendUpdate"; - sipMessageFlag_t messageflag; - sipMessage_t *request = NULL; - sipRet_t flag = STATUS_SUCCESS; - - - // UPDATE requests mandates the use of the following headers: - // Allow, Call-ID, Contact, CSeq, From, Max-Forwards, To, and Via - - messageflag.flags = 0; - messageflag.flags |= SIP_HEADER_ALLOW_BIT | - SIP_HEADER_CONTACT_BIT | - SIP_HEADER_ROUTE_BIT; - - if (ccb->local_msg_body.num_parts) { - messageflag.flags |= SIP_HEADER_CONTENT_TYPE_BIT; - } else { - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - } - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - // CreateRequest adds the request line, Via, Date, CSeq, User-Agent - // and all the headers in the messageflags above. It will also write - // the new SDP which it picks from the ccb (ccb->sip_sdp) - if (CreateRequest(ccb, messageflag, sipMethodUpdate, request, FALSE, 0)) { - flag = STATUS_SUCCESS; - } else { - flag = STATUS_FAILURE; - } - - if (flag != STATUS_SUCCESS) { - free_sip_message(request); - CCSIP_DEBUG_ERROR("%s: Error: UPDATE message build unsuccessful.\n", - fname); - clean_method_request_trx(ccb, sipMethodUpdate, TRUE); - return (FALSE); - } - // Send the request - ccb->retx_counter = 0; - if (SendRequest(ccb, request, sipMethodUpdate, TRUE, TRUE, FALSE) == FALSE) { - clean_method_request_trx(ccb, sipMethodUpdate, TRUE); - return (FALSE); - } else { - return (TRUE); - } -} - -/************************************************************* - * Function: sipSPISendUpdateResponse - * This function creates, formats, and sends a response to an - * UPDATE message received on an early dialog - **************************************************************/ -boolean -sipSPISendUpdateResponse (ccsipCCB_t *ccb, - boolean send_sdp, - cc_causes_t cause, - boolean retx) -{ - const char *fname = "SIPSPISendUpdateResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - int statusCode; - char *reason_phrase; - boolean result; - - // Determine the statusCode and reason_phrase from the cause value - statusCode = ccsip_cc_to_sip_cause(cause, &reason_phrase); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, statusCode); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_ALLOW_BIT; - - if (send_sdp) { - messageflag.flags |= SIP_HEADER_CONTENT_TYPE_BIT; - } else { - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - } - - if (statusCode == SIP_CLI_ERR_EXTENSION) { - messageflag.flags |= SIP_HEADER_UNSUPPORTED_BIT; - } - if (statusCode == SIP_SERV_ERR_INTERNAL) { - messageflag.flags |= SIP_HEADER_RETRY_AFTER_BIT; - } - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, (uint16_t)statusCode, - response, reason_phrase, 0, NULL, sipMethodUpdate)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) - free_sip_message(response); - clean_method_request_trx(ccb, sipMethodUpdate, FALSE); - return (FALSE); - } - - result = sendResponse(ccb, response, ccb->last_request, retx, - sipMethodUpdate); - clean_method_request_trx(ccb, sipMethodUpdate, FALSE); - return result; -} - -boolean -sipSPISendNotifyResponse (ccsipCCB_t *ccb, cc_causes_t cause) -{ - const char *fname = "SIPSPISendNotifyResponse"; - sipMessage_t *response = NULL; - sipRet_t flag = STATUS_SUCCESS; - sipMessageFlag_t messageflag; - int sip_response_code; - char *sip_response_phrase; - boolean result; - - sip_response_code = ccsip_cc_to_sip_cause(cause, &sip_response_phrase); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), - fname, sip_response_code); - - messageflag.flags = 0; - messageflag.flags = SIP_HEADER_CONTACT_BIT | - SIP_HEADER_RECORD_ROUTE_BIT | - SIP_HEADER_CONTENT_LENGTH_BIT; - - /* Add Content Length */ - - response = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateResponse(ccb, messageflag, (unsigned short)sip_response_code, - response, sip_response_phrase, 0, NULL, sipMethodNotify)) { - flag = HSTATUS_SUCCESS; - } else { - flag = HSTATUS_FAILURE; - } - - /* If build error detected, cleanup and do not send message */ - if (flag != STATUS_SUCCESS) { - /* !!! Clean up */ - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_BUILDFLAG_ERROR), fname); - if (response) - free_sip_message(response); - clean_method_request_trx(ccb, sipMethodNotify, FALSE); - return (FALSE); - } - - result = sendResponse(ccb, response, ccb->last_request, FALSE, - sipMethodNotify); - clean_method_request_trx(ccb, sipMethodNotify, FALSE); - return result; -} - -/* - * sipSPIGenerateReferredByHeader - * - * This function is called to generate SIP Referred-By Header - * when SIP REFER request is sent, to Transfer the call - * - * @param[in,out] ccb CCB call info structure - * - * @return TRUE if the header is successfully - * created; FALSE otherwise. - * - * @pre (ccb not_eqs NULL) - * - */ -boolean -sipSPIGenerateReferredByHeader (ccsipCCB_t *ccb) -{ - char line_name[MAX_LINE_NAME_SIZE]; - char escaped_line_name[MAX_ESCAPED_USER_LEN]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char pReferByStr[MAX_SIP_URL_LENGTH]; - boolean retval = FALSE; - cpr_ip_type ip_type; - - /* Initialize */ - line_name[0] = '\0'; - escaped_line_name[0] = '\0'; - dest_sip_addr_str[0] = '\0'; - pReferByStr[0] = '\0'; - - /* - * get Server Ip Addr, line_name and form AOR to populate referredBy - */ - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, - sizeof(line_name)); - - if (line_name[0] != '\0') { - (void) sippmh_convertURLCharToEscChar(line_name, strlen(line_name), - escaped_line_name, - sizeof(escaped_line_name), - TRUE); - } - - ip_type = sipTransportGetPrimServerAddress(ccb->dn_line, dest_sip_addr_str); - - if (escaped_line_name[0] != '\0') { - if (ip_type == CPR_IP_ADDR_IPV6) { - snprintf(pReferByStr, MAX_SIP_URL_LENGTH, "", - escaped_line_name, dest_sip_addr_str); - } else { - snprintf(pReferByStr, MAX_SIP_URL_LENGTH, "", - escaped_line_name, dest_sip_addr_str); - } - } - - if (pReferByStr[0] != '\0') { - ccb->sip_referredBy = strlib_update(ccb->sip_referredBy, pReferByStr); - retval = TRUE; - } - - return (retval); -} - -/* - * Function: sipSPIBuildRegisterHeaders - * - * Parameters: - * ccsipCCB_t * - pointer to the ccb used for registration - * const char * user - used to build the headers - * int expires_int - registration expiry time - * - * Description: The function builds the register message - * - * Returns: - * sipMessage_t * - pointer to the sip request - * - */ -sipMessage_t * -sipSPIBuildRegisterHeaders(ccsipCCB_t *ccb, - const char *user, - int expires_int) -{ - const char fname[] = "sipSPIBuildRegisterHeaders"; - char *sip_from_temp; - char *sip_to_temp; - sipRet_t flag = STATUS_SUCCESS; - sipRet_t tflag = STATUS_SUCCESS; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char expires[MAX_EXPIRES_LEN]; - sipMessageFlag_t messageflag; - char reg_user_info[MAX_REG_USER_INFO_LEN]; - char escaped_user[MAX_ESCAPED_USER_LEN]; - char *sip_from_tag; - sipMessage_t *request = NULL; - - (void) sippmh_convertURLCharToEscChar(user, strlen(user), - escaped_user, sizeof(escaped_user), - TRUE); - /* get reg_user_info */ - config_get_string(CFGID_REG_USER_INFO, reg_user_info, - sizeof(reg_user_info)); - ipaddr2dotted(src_addr_str, &ccb->src_addr); - - sstrncpy(dest_sip_addr_str, ccb->reg.proxy, MAX_IPADDR_STR_LEN); - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), - fname, "REGISTER"); - - // Create a new From header only if the previous one in the CCB is blank. - // It will not be blank if we received a 401/407 response to a prior - // REGISTER request where we reuse the CCB that we first used without - // cleaning it. - - if (ccb->sip_from[0] == '\0') { - sip_from_temp = strlib_open(ccb->sip_from, MAX_SIP_URL_LENGTH); - if (sip_from_temp) { - if (ccb->reg.addr.type == CPR_IP_ADDR_IPV6) { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "", - escaped_user, dest_sip_addr_str); /* proxy */ - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "", - escaped_user, dest_sip_addr_str); /* proxy */ - } - /* Now add tag to the From header */ - sip_from_tag = strlib_open(ccb->sip_from_tag, MAX_SIP_URL_LENGTH); - if (sip_from_tag) { - sip_util_make_tag(sip_from_tag); - sstrncat(sip_from_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - sstrncat(sip_from_temp, sip_from_tag, - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - } - ccb->sip_from_tag = strlib_close(sip_from_tag); - } - ccb->sip_from = strlib_close(sip_from_temp); - } - sip_to_temp = strlib_open(ccb->sip_to, MAX_SIP_URL_LENGTH); - if (ccb->reg.addr.type == CPR_IP_ADDR_IPV6) { - snprintf(sip_to_temp, MAX_SIP_URL_LENGTH, "", - escaped_user, dest_sip_addr_str); /* proxy */ - } else { - snprintf(sip_to_temp, MAX_SIP_URL_LENGTH, "", - escaped_user, dest_sip_addr_str); /* proxy */ - } - ccb->sip_to = strlib_close(sip_to_temp); - /* - * Build A request from Message Factory using following Flags... - * You do not need to specify common headers they will automatically - * get added - */ - - messageflag.flags = 0; - - messageflag.flags |= SIP_HEADER_CONTACT_BIT | - SIP_HEADER_SUPPORTED_BIT | - SIP_HEADER_CISCO_GUID_BIT; - - messageflag.flags |= SIP_HEADER_CONTENT_LENGTH_BIT; - - - if (ccb->authen.authorization != NULL) { - messageflag.flags |= SIP_HEADER_AUTHENTICATION_BIT; - } - - if (ccb->send_reason_header) { - messageflag.flags |= SIP_HEADER_REASON_BIT; - } - - - request = GET_SIP_MESSAGE(); - messageflag.extflags = 0; - if (CreateRequest(ccb, messageflag, sipMethodRegister, request, FALSE, 0)) { - tflag = HSTATUS_SUCCESS; - } else { - tflag = HSTATUS_FAILURE; - } - UPDATE_FLAGS(flag, tflag); - - snprintf(expires, sizeof(expires), "%d", expires_int); - tflag = sippmh_add_text_header(request, SIP_HEADER_EXPIRES, expires); - - UPDATE_FLAGS(flag, tflag); - - if (flag != STATUS_SUCCESS) { - free_sip_message(request); - CCSIP_DEBUG_ERROR("%s: Error: REGISTER message build unsuccessful.\n", - fname); - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - return (NULL); - } - - return (request); -} - diff --git a/libs/sipcc/core/sipstack/ccsip_platform.c b/libs/sipcc/core/sipstack/ccsip_platform.c deleted file mode 100644 index de752158a2..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_platform.c +++ /dev/null @@ -1,122 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "phone.h" -#include "phone_debug.h" -#include "ccsip_register.h" -#include "ccsip_task.h" -#include "ccsip_pmh.h" -#include "config.h" -#include "sip_common_transport.h" -#include "sip_csps_transport.h" -#include "uiapi.h" -#include "sip_interface_regmgr.h" - -#include "platform_api.h" - -extern void platform_sync_cfg_vers(char *cfg_ver, char *dp_ver, char *softkey_ver); -extern void platform_reg_failover_ind(void *data); -extern void platform_reg_fallback_ind(void *data); -extern int platGetUnregReason(); -extern void ccsip_add_wlan_classifiers(); -void ccsip_remove_wlan_classifiers(); - -/* - * Function: sip_platform_init() - * - * Parameters: None - * - * Description: Performs platform initialization stuff. Should probably be - * renamed or moved to make it more "generic". - * - * Returns: None - * - */ -void -sip_platform_init (void) -{ - - // Since we have all our configuration information now - // we want to do a final check to see if our network media - // type has changed - - /* Unregister the phone */ - ccsip_register_cancel(FALSE, TRUE); - ccsip_register_reset_proxy(); - - /* - * Make sure that the IP stack is up before trying to connect - */ - if (PHNGetState() > STATE_IP_CFG) { - - ccsip_add_wlan_classifiers(); - /* - * regmgr - The SIPTaskDisconnectFromSipProxies and - * SIPTaskConnectToSipProxies calls will be called - * as part of the transport interface init and regmgr - * inits. - */ - - ccsip_register_all_lines(); - ui_sip_config_done(); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "IP Stack Not Initialized.\n", "sip_platform_init"); - } -} - - -/* - * Send StationReset message - * Parameters supplied by application: - * none - * Parameters supplied in the message - * - reset type (RESTART) - */ -int -sip_platform_ui_restart (void) -{ - phone_reset(DEVICE_RESTART); - return TRUE; -} - - -void -sip_platform_handle_service_control_notify (sipServiceControl_t *scp) -{ - switch (scp->action) { - - case SERVICE_CONTROL_ACTION_RESET: - platform_reset_req(DEVICE_RESET); - break; - - case SERVICE_CONTROL_ACTION_RESTART: - platform_reset_req(DEVICE_RESTART); - break; - - case SERVICE_CONTROL_ACTION_CHECK_VERSION: - platform_sync_cfg_vers(scp->configVersionStamp, - scp->dialplanVersionStamp, - scp->softkeyVersionStamp); - break; - - case SERVICE_CONTROL_ACTION_APPLY_CONFIG: - // call the function to process apply config NOTIFY message. - platform_apply_config(scp->configVersionStamp, - scp->dialplanVersionStamp, - scp->fcpVersionStamp, - scp->cucm_result, - scp->firmwareLoadId, - scp->firmwareInactiveLoadId, - scp->loadServer, - scp->logServer, - scp->ppid); - break; - default: - break; - - } -} diff --git a/libs/sipcc/core/sipstack/ccsip_platform_tcp.c b/libs/sipcc/core/sipstack/ccsip_platform_tcp.c deleted file mode 100644 index bbc09c3206..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_platform_tcp.c +++ /dev/null @@ -1,1220 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "sip_platform_task.h" -#include "ccsip_platform_udp.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "phone_debug.h" -#include "util_string.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_platform_timers.h" -#include "text_strings.h" -#include "ccsip_register.h" -#include "phntask.h" -#include "plat_api.h" -#include "sip_socket_api.h" - - -/* - * Externs - */ -extern cc_config_table_t CC_Config_Table[]; -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; -extern cpr_sockaddr_t *sip_set_sockaddr(cpr_sockaddr_storage *psock_storage, uint16_t family, - cpr_ip_addr_t ip_addr, uint16_t port, uint16_t *addr_len); -extern void ccsip_dump_recv_msg_info(sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port); - -#define MAX_CHUNKS 12 -#define MAX_PAYLOAD_SIZE (MAX_CHUNKS*CPR_MAX_MSG_SIZE) -/* - * Globals - */ -static uint32_t sip_tcp_incomplete_msg = 0; -static uint32_t sip_tcp_fail_network_msg = 0; -int max_tcp_send_msg_q_size = 0; -int max_tcp_send_msg_q_connid = 0; -cpr_ip_addr_t max_tcp_send_msg_q_ipaddr = {0,{0}}; -ushort max_tcp_send_msg_q_port = 0; - -/* - * The following routine that set the socket option has been - * ported over from IOS. So not renaming. - */ -static ccsipRet_e -ccsipSocketSetNonblock (cpr_socket_t fd, int optval) -{ - const char *fname = "ccsipSocketSetNonblock"; - - if (cprSetSockNonBlock(fd)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set non-blocking socket mode %d\n", - fname, cpr_errno); - return SIP_INTERNAL_ERR; - } - return SIP_SUCCESS; -} - -/* - * The following routine that set the socket option has been - * ported over from IOS. So not renaming. - */ -static ccsipRet_e -ccsipSocketSetKeepAlive (cpr_socket_t fd, int optval) -{ - const char *fname = "ccsipSocketSetKeepAlive"; - - if (cprSetSockOpt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, - sizeof(optval))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set KEEP ALIVE on a socket %d\n", - fname, cpr_errno); - return SIP_INTERNAL_ERR; - } - - return SIP_SUCCESS; -} - -/* - * The following routine that set the socket option has been - * ported over from IOS. So not renaming. - */ -#ifdef NOT_AVAILABLE_WIN32 -static ccsipRet_e -ccsipSocketSetTCPtos (cpr_socket_t fd, uint8_t optval) -{ - const char *fname = "ccsipSocketSetTCPtos"; - - if (cprSetSockOpt(fd, SOL_TCP, TCP_TOS, (void *)&optval, - sizeof(optval))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set TCP TOS on a socket %d\n", - fname, cpr_errno); - return SIP_INTERNAL_ERR; - } - - return SIP_SUCCESS; -} - -/* - * The following routine that set the socket option has been - * ported over from IOS. So not renaming. - */ -static ccsipRet_e -ccsipSocketSetPushBit (cpr_socket_t fd, int optval) -{ - const char *fname = "ccsipSocketSetPushBit"; - - if (cprSetSockOpt(fd, SOL_TCP, TCP_ALWAYSPUSH, (void *)&optval, - sizeof(optval))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set PUSH BIT on a socket %d\n", - fname, cpr_errno); - return SIP_INTERNAL_ERR; - } - - return SIP_SUCCESS; -} -#endif /* NOT_AVAILABLE_WIN32 */ - -static boolean ccsipIsSecureType(sipSPIConnId_t connid) -{ - if (sip_tcp_conn_tab[connid].soc_type == SIP_SOC_TLS) { - return TRUE; - } - return FALSE; -} -/** - * - * sip_tcp_attach_socket - * - * Attach the socket to the select call - * - * Parameters: s - the socket - * - * Return Value: SIP_OK or SIP_ERROR - * - * Remarks: No check is made to see if socket is already attached - * - */ -int -sip_tcp_attach_socket (cpr_socket_t s) -{ - int i; - - /* - * Attach socket to select call - */ - for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - if (sip_conn.read[i] == INVALID_SOCKET) { - sip_conn.read[i] = s; - FD_SET(s, &read_fds); - nfds = MAX(nfds, (uint32_t)s); - sip_conn.write[i] = s; - FD_SET(s, &write_fds); - break; - } - } - - /* - * Are there already too many connections? - */ - if (i == MAX_SIP_CONNECTIONS) { - return SIP_ERROR; - } - return SIP_OK; -} - -/** - * - * sip_tcp_detach_socket - * - * Attach the socket to the select call - * - * Parameters: s - the socket - * - * Return Value: SIP_OK or SIP_ERROR - * - * Remarks: No check is made to see if socket is already attached - * - */ -static int -sip_tcp_detach_socket (cpr_socket_t s) -{ - int i; - const char *fname = "sip_tcp_detach_socket"; - - if (s == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid socket\n", fname); - return SIP_ERROR; - } - /* - * Attach socket to select call - */ - for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - if (sip_conn.read[i] == s) { - sip_conn.read[i] = INVALID_SOCKET; - FD_CLR(s, &read_fds); - nfds = MAX(nfds, (uint32_t)s); - sip_conn.write[i] = INVALID_SOCKET; - FD_CLR(s, &write_fds); - break; - } - } - - /* - * Are there already too many connections? - */ - if (i == MAX_SIP_CONNECTIONS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Max TCP connections reached.\n", fname); - return SIP_ERROR; - } - return SIP_OK; -} - -/** - * - * sip_tcp_set_sock_options - * - * Attach the socket to the select call - * - * Parameters: fd - the file descriptor - * - * Return Value: SIP_OK or SIP_ERROR - * - * Remarks: No check is made to see if socket is already attached - * - */ -boolean -sip_tcp_set_sock_options (int fd) -{ - int optval; - ccsipRet_e status = SIP_SUCCESS; - - optval = 1; - - /* Set non-blocking mode */ - status = ccsipSocketSetNonblock(fd, optval); - if (status != SIP_SUCCESS) { - return FALSE; - } - - /* Set the keepalive option */ - status = ccsipSocketSetKeepAlive(fd, optval); - if (status != SIP_SUCCESS) { - return FALSE; - } - - return TRUE; -} - -/** - * - * sip_tcp_fd_to_connid - * - * returns the tcp conn table index for a particular socket - * - * Parameters: fd - the file descriptor - * - * Return Value: sip_tcp_conn_tab index - * - */ -int -sip_tcp_fd_to_connid (cpr_socket_t fd) -{ - int i; - - for (i = 0; i < MAX_CONNECTIONS; ++i) { - if (sip_tcp_conn_tab[i].fd == fd) { - return i; - } - } - return -1; -} - -/* - * sip_tcp_get_free_conn_entry () - * - * Description : This procedure returns the first free entry from the TCP - * conn table. - * - * Input Params : None. - * - * Returns : Index to the Connection table (if SUCCESSFUL) - * -1 in case of failure. - */ -int -sip_tcp_get_free_conn_entry (void) -{ - int i; - const char *fname = "sip_tcp_get_free_conn_entry"; - - for (i = 0; i < MAX_CONNECTIONS; ++i) { - if (sip_tcp_conn_tab[i].fd == -1) { - /* Zero the connection table entry */ - memset((sip_tcp_conn_tab + i), 0, sizeof(sip_tcp_conn_t)); - sip_tcp_conn_tab[i].state = SOCK_IDLE; - sip_tcp_conn_tab[i].dirtyFlag = FALSE; - sip_tcp_conn_tab[i].error_cause = SOCKET_NO_ERROR; - return i; - } - } - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"TCP Connection table full\n", fname); - - return -1; -} - -/* - * sip_tcp_init_conn_table() - * Description : Cleans up the entry associated with the connid - * from the sip_tcp_conn_tab - * - * Input : void - * - * Output : void - * - */ -void -sip_tcp_init_conn_table (void) -{ - static boolean initial_call = TRUE; - int idx; - - if (initial_call) { - /* - * Initialize the tcp conn table - */ - for (idx = 0; idx < MAX_CONNECTIONS; ++idx) { - sip_tcp_conn_tab[idx].fd = -1; - } - initial_call = FALSE; - } -} - -/* - * sip_tcp_purge_entry() - * Description : Cleans up the entry associated with the connid - * from the sip_tcp_conn_tab - * - * Input : connid - * - * Output : None - * - */ -void -sip_tcp_purge_entry (sipSPIConnId_t connid) -{ - sip_tcp_conn_t *entry = sip_tcp_conn_tab + connid; - const char *fname= "sip_tcp_purge_entry"; - boolean secure; - - if (!VALID_CONNID(connid)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid TCP connection Id=%ld.\n", - fname, connid); - return; - } - secure = ccsipIsSecureType(connid); - - (void) sip_tcp_detach_socket(entry->fd); - (void) sipSocketClose(entry->fd, secure); - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Socket fd: %d closed for connid %ld with " - "address: %i, remote port: %u\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), entry->fd, connid, entry->ipaddr, entry->port); - - entry->fd = -1; /* Free the connection table entry in the BEGINNING ! */ - sipTcpFlushRetrySendQueue(entry); - entry->ipaddr = ip_addr_invalid; - entry->port = 0; - entry->context = NULL; - entry->dirtyFlag = FALSE; - if (entry->prev_bytes) { - cpr_free(entry->prev_msg); - } - return; -} - - -/* - * sip_tcp_create_connection() - * Description : This routine is called is response to a create connection - * request from SIP_SPI to SIP_TCP. - * - * Input : spi_msg - Pointer to sipSPIMessage_t containing the create conn - * parameters. - * - * Output : Nothing - */ -cpr_socket_t -sip_tcp_create_connection (sipSPIMessage_t *spi_msg) -{ - const char* fname = "sip_tcp_create_connection"; - int idx; - cpr_socket_t new_fd; - cpr_sockaddr_storage *local_addr_ptr; - sipSPICreateConnection_t *create_msg; - cpr_sockaddr_t local_addr; - cpr_socklen_t local_addr_len = sizeof(cpr_sockaddr_t); - int tos_dscp_val = 0; // set to default if there is no config. for dscp -#ifdef IPV6_STACK_ENABLED - - int ip_mode = CPR_IP_MODE_IPV4; -#endif - uint16_t af_listen = AF_INET6; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len; - cpr_sockaddr_storage local_sock_addr; - cpr_ip_addr_t local_ipaddr; - - sip_tcp_init_conn_table(); - create_msg = &(spi_msg->createConnMsg); - CPR_IP_ADDR_INIT(local_ipaddr); - -#ifdef IPV6_STACK_ENABLED - - config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); - - /* - * Create a socket - */ - if (ip_mode == CPR_IP_MODE_IPV6 || - ip_mode == CPR_IP_MODE_DUAL) { - af_listen = AF_INET6; - } else { -#endif - af_listen = AF_INET; -#ifdef IPV6_STACK_ENABLED - } -#endif - - /* Create New connection to the (addr,port) pair */ - new_fd = cprSocket(af_listen, SOCK_STREAM, 0 /* IPPROTO_TCP */); - if (new_fd < 0) { - /* Send create connection failed message to SIP_SPI */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Socket creation failed %d.\n", - fname, cpr_errno); - return INVALID_SOCKET; - } - idx = sip_tcp_get_free_conn_entry(); - if (idx == -1) { - /* Send create connection failed message to SIP_SPI */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No Free connection entry.\n", - fname); - (void) sipSocketClose(new_fd, FALSE); - return INVALID_SOCKET; - } - - if (sip_tcp_set_sock_options(new_fd) != TRUE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Socket set option failed.\n", - fname); - } - - sip_config_get_net_device_ipaddr(&local_ipaddr); - - memset(&local_sock_addr, 0, sizeof(local_sock_addr)); - - (void) sip_set_sockaddr(&local_sock_addr, af_listen, local_ipaddr, 0, &addr_len); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"local_ipaddr.u.ip4=%x\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), local_ipaddr.u.ip4); - - if (cprBind(new_fd, (cpr_sockaddr_t *)&local_sock_addr, addr_len)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"TCP bind failed with error %d\n", fname, - cpr_errno); - (void) sipSocketClose(new_fd, FALSE); - sip_tcp_conn_tab[idx].fd = INVALID_SOCKET; - return INVALID_SOCKET; - } - - memset(&sock_addr, 0, sizeof(sock_addr)); - - (void) sip_set_sockaddr(&sock_addr, af_listen, create_msg->addr, - (uint16_t)(create_msg->port), &addr_len); - - sip_tcp_conn_tab[idx].fd = new_fd; - sip_tcp_conn_tab[idx].ipaddr = create_msg->addr; - sip_tcp_conn_tab[idx].port = create_msg->port; - sip_tcp_conn_tab[idx].context = spi_msg->context; - sip_tcp_conn_tab[idx].dirtyFlag = FALSE; - sip_tcp_conn_tab[idx].addr = sock_addr; - - if (cprConnect(new_fd, (cpr_sockaddr_t *)&sock_addr, addr_len) - == CPR_FAILURE) { - if (errno == EWOULDBLOCK || errno == EINPROGRESS) { - char ipaddr_str[MAX_IPADDR_STR_LEN]; - - ipaddr2dotted(ipaddr_str, &create_msg->addr); - - /* connect in progress. Include this socket in select */ - sip_tcp_conn_tab[idx].state = SOCK_CONNECT_PENDING; - - CCSIP_DEBUG_MESSAGE(SIP_F_PREFIX"socket connection in progress errno:%d" - "ipaddr: %s, port: %d\n", - fname, errno, ipaddr_str, create_msg->port); - } else { - char ipaddr_str[MAX_IPADDR_STR_LEN]; - - ipaddr2dotted(ipaddr_str, &create_msg->addr); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket connect failed errno: %d " - "ipaddr: %s, port: %d\n", - fname, errno, ipaddr_str, create_msg->port); - sip_tcp_purge_entry(idx); - return INVALID_SOCKET; - } - } else { - /* Even for this non-blocking socket, the connection was - * completed immediately. Is that a possibility ?? - * I am not sure. Just send a connectioncreated msg to SIP_SPI - */ - sip_tcp_conn_tab[idx].state = SOCK_CONNECTED; - } - - if (cprGetSockName(new_fd, &local_addr, &local_addr_len) != CPR_FAILURE) { - local_addr_ptr = (cpr_sockaddr_storage *)&local_addr; - - if (local_addr_ptr->ss_family == AF_INET6) { - - create_msg->local_listener_port = ntohs(((cpr_sockaddr_in6_t *)local_addr_ptr)->sin6_port); - - } else { - - create_msg->local_listener_port = ntohs(((cpr_sockaddr_in_t *)local_addr_ptr)->sin_port); - } - - (void) sip_tcp_attach_socket(new_fd); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error getting local port info.\n", - fname); - sip_tcp_purge_entry(idx); - return INVALID_SOCKET; - } - - // set IP tos/dscp value for SIP messaging - config_get_value(CFGID_DSCP_FOR_CALL_CONTROL, (int *)&tos_dscp_val, - sizeof(tos_dscp_val)); - if (cprSetSockOpt(new_fd, SOL_IP, IP_TOS, (void *)&tos_dscp_val, - sizeof(tos_dscp_val)) == CPR_FAILURE) { - // do NOT take hard action; just log the error and move on - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set IP TOS %d on TCP socket. cpr_errno = %d", - fname, tos_dscp_val, cpr_errno); - } - - return (new_fd); -} - -/* - * sip_tcp_newmsg_to_spi() - * Description : This routine is called to parse a tcp packet - * and send it to the spi for further processing. - * - * Input : buf: pointer to the message - * nbytes: length of the message - * connID: connid over which the message was received - * - * Output : success / failure in processing - */ -static int -sip_tcp_newmsg_to_spi (char *buf, unsigned long nbytes, int connID) -{ - static const char *fname = "sip_tcp_newmsg_to_spi"; - sipMessage_t *sip_msg; - ccsipRet_e val; - cpr_sockaddr_storage from; - char *disply_msg_buff = NULL; - char **display_msg_buff_p; - boolean error; - cpr_ip_addr_t ip_addr; - - CPR_IP_ADDR_INIT(ip_addr); - - /* Set up display msg. if debug msg. is enabled */ - if (SipDebugMessage) { - display_msg_buff_p = &disply_msg_buff; - } else { - /* No display msg. is needed */ - display_msg_buff_p = NULL; - } - - do { - disply_msg_buff = NULL; - error = FALSE; - val = ccsip_process_network_message(&sip_msg, &buf, &nbytes, - display_msg_buff_p); - - switch (val) { - case SIP_SUCCESS: - /* - * Print the received TCP packet info - */ - if (disply_msg_buff != NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"RCV: TCP message=\n", fname); - platform_print_sip_msg(disply_msg_buff); - } - from = sip_tcp_conn_tab[connID].addr; - - util_extract_ip(&ip_addr, &from); - ccsip_dump_recv_msg_info(sip_msg, &ip_addr, 0); - /* Process SIP message */ - SIPTaskProcessTCPMessage(sip_msg, from); - break; - - case SIP_MSG_INCOMPLETE_ERR: - - sip_tcp_conn_tab[connID].prev_msg = cpr_strdup(buf); - if (sip_tcp_conn_tab[connID].prev_msg) { - sip_tcp_conn_tab[connID].prev_bytes = nbytes; - } - sip_tcp_incomplete_msg++; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP Incomplete message.%d\n",fname, - sip_tcp_incomplete_msg); - error = TRUE; - break; - - case SIP_MSG_PARSE_ERR: - /* - * Print the received TCP packet info - */ - if (disply_msg_buff != NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"RCV: TCP message=\n", fname); - platform_print_sip_msg(disply_msg_buff); - } - sip_tcp_fail_network_msg++; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP Message Parse error %d.\n", fname, - sip_tcp_fail_network_msg); - error = TRUE; - break; - - case SIP_MSG_CREATE_ERR: - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP Message create error.\n", fname); - error = TRUE; - break; - } - - /* Free display msg. buffer if it is allocated */ - if (disply_msg_buff != NULL) { - cpr_free(disply_msg_buff); - disply_msg_buff = NULL; - } - - if (error) { - /* There was an error encountered, exit */ - return -1; - } - } while (nbytes > 0); - return 0; -} - -void -sip_tcp_createconnfailed_to_spi (cpr_ip_addr_t *ipaddr, - uint16_t port, - void *context, - ccsipSockErrCodes_e errcode, - int connid) -{ - static const char *fname = "sip_tcp_createconnfailed_to_spi"; - ccsipCCB_t *ccb = NULL; - ti_config_table_t *ccm_active_table_entry = NULL, - *ccm_standby_table_entry = NULL, - *ccm_table_entry = NULL; - ti_common_t *active_ti_common = NULL; - ti_common_t *standby_ti_common = NULL; - uint32_t retx_value; - char ip_addr_str[MAX_IPADDR_STR_LEN]; - - - /* - * Use LINE1 for now as there is only one type of cc - * supported, no mixed mode. Will have to change when - * we add mixed mode cc support on the phone. - */ - if (CC_Config_Table[LINE1].cc_type == CC_CCM) { - - /* - * Check and see which tcp link went down, active / - * standby and get the appropriate reg ccb. - * Using ipaddr:port combination to find if the active - * or the standby went down. To use fd we will have to - * write a routine to return connid of the tcp conn table - * for an ipaddr:port combination. - */ - ccm_active_table_entry = CCM_Active_Standby_Table.active_ccm_entry; - ccm_standby_table_entry = CCM_Active_Standby_Table.standby_ccm_entry; - if (ccm_active_table_entry) { - active_ti_common = &ccm_active_table_entry->ti_common; - } - if (ccm_standby_table_entry) { - standby_ti_common = &ccm_standby_table_entry->ti_common; - } - - ipaddr2dotted(ip_addr_str, ipaddr); - if (active_ti_common && util_compare_ip(&(active_ti_common->addr), ipaddr) && - active_ti_common->port == port) { - /* - * Active link has gone down - */ - int last_cpr_err = cpr_errno; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Active server going down due to " - "%s. ip_addr:%s\n", DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), - last_cpr_err == CPR_ETIMEDOUT ? "ETIMEDOUT": - last_cpr_err == CPR_ECONNABORTED ? "ECONNABORTED": - last_cpr_err == CPR_ECONNRESET ? "CM_RESET_TCP": "CM_CLOSED_TCP", - ip_addr_str); - - ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - ccm_table_entry = ccm_active_table_entry; - - } else if (standby_ti_common && - util_compare_ip(&(standby_ti_common->addr), ipaddr) && - standby_ti_common->port == port) { - /* - * Standby link has gone down - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Standby server going down " - "ip_addr=%s\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), - ip_addr_str); - - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - ccm_table_entry = ccm_standby_table_entry; - } else { - /* - * Neither of the links, just return. - * This could happen with fall back ccm - */ - ccsipCCB_t *ccb_of_fallback = NULL; - - // Find fallback ccb and set the socket handle INVALID - if (sip_regmgr_find_fallback_ccb_by_addr_port(ipaddr, port, - &ccb_of_fallback)) { - if (ccb_of_fallback && (ccb_of_fallback->cc_cfg_table_entry)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Fallback server going " - " down ip_addr=%s\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), - ip_addr_str); - sip_tcp_purge_entry(connid); - sipTransportSetServerHandleAndPort(INVALID_SOCKET, 0, - (ti_config_table_t *)ccb_of_fallback->cc_cfg_table_entry); - } - } else { - sipTransportClearServerHandle(ipaddr, port, connid); - } - return; - } - /* - * In this case we need to make sure any pending - * calls are cleared as well... Need to make sure - * we clear that, because we are setting the local port - * to zero. So any one-time udp message that needs to get - * sent will have the port as 0 in the contact header. - */ - if (ccm_table_entry) { - sip_tcp_purge_entry(connid); - sipTransportSetServerHandleAndPort(INVALID_SOCKET, 0, - (ti_config_table_t *) (ccm_table_entry)); - } else { - sipTransportClearServerHandle(ipaddr, port, connid); - } - /* - * Set the retx_counter to the configured retx_value - * so no more retries happen - */ - if (ccb != NULL) { - config_get_value(CFGID_SIP_RETX, &retx_value, sizeof(retx_value)); - ccb->retx_counter = retx_value + 1; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"send a SIP_TMR_REG_RETRY" - "message so this cucm ip:%s can be put in fallback list \n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), ip_addr_str); - if (ccsip_register_send_msg(SIP_TMR_REG_RETRY, ccb->index) - != SIP_REG_OK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"REG send message failed.\n", fname); - ccsip_register_cleanup(ccb, TRUE); - } - - } - } -} - -/* - * sip_tcp_read_socket() - * Description : After we come out of select call, for every valid socket in - * the connection table it - * 1. Checks it for readability - * 2. If it is readable, either accept the incoming connect (for master - * port) or receive data from network - * 3. Processes the data received from the network. - * - * Input : Value of read mask after call to socket_select() - * - * Output : Nothing - */ -void -sip_tcp_read_socket (cpr_socket_t this_fd) -{ - int nbytes; - char *sip_tcp_buf; - char temp; - int connid; - const char *fname="sip_tcp_read_socket"; - boolean secure; - - connid = sip_tcp_fd_to_connid(this_fd); - if (connid == -1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Read failed for unknown socket %d.\n", - fname, this_fd); - return; - } - secure = ccsipIsSecureType(connid); - - if (sip_tcp_conn_tab[connid].state == SOCK_CONNECT_PENDING) { - int bytes_read = 0; - - /* This socket is now readable, connection complete. - * Inform SIP SPI - * Do a dummy read, if it is successful, change state - */ - bytes_read = sipSocketRecv(this_fd, &temp, 0, 0, secure); - if ((bytes_read != -1) || (errno == EWOULDBLOCK)) { - sip_tcp_conn_tab[connid].state = SOCK_CONNECTED; - } else if (errno == ENOTCONN) { - sip_tcp_conn_tab[connid].dirtyFlag = TRUE; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=\n", fname, errno); - sip_tcp_createconnfailed_to_spi(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - return; - } - } else { - unsigned long offset = sip_tcp_conn_tab[connid].prev_bytes; - - if (offset) { - sip_tcp_buf = (char *) cpr_realloc(sip_tcp_conn_tab[connid].prev_msg, - (offset + CPR_MAX_MSG_SIZE + 1)); - sip_tcp_conn_tab[connid].prev_bytes = 0; - - if (sip_tcp_buf == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to realloc tcp_msg buffer memory.\n", - fname); - cpr_free(sip_tcp_conn_tab[connid].prev_msg); - sip_tcp_conn_tab[connid].prev_msg = NULL; - return; - } - - nbytes = sipSocketRecv(this_fd, &sip_tcp_buf[offset], - CPR_MAX_MSG_SIZE, 0, secure); - - /* Ensure that we dont have too much buffered which may - * be due to some error conditions. - */ - if ((nbytes + offset) > (MAX_PAYLOAD_SIZE + 1)) { - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Total SIP message size of %d " - "bytes exceeds maximum of %d bytes", - fname, (nbytes + offset), - (MAX_PAYLOAD_SIZE + 1)); - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Dropping SIP message %s", - fname, sip_tcp_buf); - cpr_free(sip_tcp_buf); - return; - } - } else { - sip_tcp_buf = (char *) cpr_malloc(CPR_MAX_MSG_SIZE + 1); - if (sip_tcp_buf == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to malloc tcp_msg buffer memory.\n", - fname); - return; - } - nbytes = sipSocketRecv(this_fd, sip_tcp_buf, CPR_MAX_MSG_SIZE, 0, secure); - } - - if (nbytes > 0) { - nbytes += offset; - sip_tcp_buf[nbytes] = 0; - (void) sip_tcp_newmsg_to_spi(sip_tcp_buf, nbytes, connid); - } else if ((nbytes == 0) || - ((nbytes == -1) && (errno != EWOULDBLOCK))) { - /* - * Remote connection closure or broken pipe - post a message - * to sip transport and wait for connection close command. - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"CUCM closed TCP connection.\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname)); - sip_tcp_conn_tab[connid].error_cause = SOCKET_REMOTE_CLOSURE; - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=\n", fname, errno); - - sip_tcp_createconnfailed_to_spi(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - // Clear proxy handle - if (CC_Config_Table[LINE1].cc_type != CC_CCM) { - sipTransportCSPSClearProxyHandle(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - this_fd); - sip_tcp_purge_entry(connid); - } - } - cpr_free(sip_tcp_buf); - } -} - -/* - ** sip_tcp_find_msg - * - * FILENAME: ip_phone\sip\ccsip_platform_tcp.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -sll_match_e -sip_tcp_find_msg (void *find_by_p, void *data_p) -{ - return (SLL_MATCH_FOUND); -} - -/* Socket is not writable. Queue the data to be sent. - * - * Inputs: - * total_len - total length of message - * connid - connection id - * buf - buffer of data to be written (this is the entire - * contents not just the remaining data. We do this - * so we can display the entire message when the last - * chunk is written. - * send_msg_display - boolean indicating whether the sent message - * is to be displayed for debugging etc. - */ -static void -sipTcpQueueSendData (int total_len, int connid, - char *buf, void *context, boolean send_msg_display, - uint8_t ip_sig_tos) -{ - static const char *fname = "sipTcpQueueSendData"; - ccsipTCPSendData_t *sendData; - sip_tcp_conn_t *entry; - int send_msg_q_size = 0; - - entry = sip_tcp_conn_tab + connid; - if (entry->sendQueue == NULL) { - entry->sendQueue = sll_create(sip_tcp_find_msg); - if (entry->sendQueue == NULL) { - CCSIP_DEBUG_ERROR("%s Failed to create sendQueue to buffer data!\n", fname); - return; - } - } - - sendData = (ccsipTCPSendData_t *) cpr_malloc(sizeof(ccsipTCPSendData_t)); - if (sendData == NULL) { - CCSIP_DEBUG_ERROR("%s Failed to allocate memory for sendData!\n", fname); - return; - } - memset(sendData, 0, sizeof(ccsipTCPSendData_t)); - - sendData->data = (char *) cpr_malloc(total_len + 1); - - if (sendData->data) { - sstrncpy(sendData->data, buf, total_len); - } else { - CCSIP_DEBUG_ERROR("%s Failed to allocate memory for sendData->data!\n", fname); - cpr_free(sendData); - return; - } - - sendData->bytesSent = 0; - sendData->bytesLeft = (uint16_t) total_len; - sendData->context = context; - sendData->msg_display = send_msg_display; - sendData->ip_sig_tos = ip_sig_tos; - (void) sll_append(entry->sendQueue, sendData); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Data queued length %d\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), total_len); - - if (send_msg_q_size > max_tcp_send_msg_q_size) { - max_tcp_send_msg_q_size = send_msg_q_size; - max_tcp_send_msg_q_connid = connid; - max_tcp_send_msg_q_ipaddr = entry->ipaddr; - max_tcp_send_msg_q_port = entry->port; - } -} - -/* - * Free memory for any queued write data. - */ -void -sipTcpFlushRetrySendQueue (sip_tcp_conn_t *entry) -{ - ccsipTCPSendData_t *sendData = NULL; - - if (entry->sendQueue) { - sendData = (ccsipTCPSendData_t *) sll_next(entry->sendQueue, sendData); - while (sendData) { - cpr_free(sendData->data); - (void) sll_remove(entry->sendQueue, sendData); - cpr_free(sendData); - sendData = (ccsipTCPSendData_t *) sll_next(entry->sendQueue, NULL); - } - (void) sll_destroy(entry->sendQueue); - entry->sendQueue = NULL; - } -} - -void -sip_tcp_resend (int connid) -{ - static const char *fname = "sip_tcp_resend"; - ccsipTCPSendData_t *qElem = NULL; - sip_tcp_conn_t *entry; - int bytes_sent; - boolean secure; - - if (!VALID_CONNID(connid)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Resend failed for unknown socket %d.\n", - fname, connid); - return; - } - - secure = ccsipIsSecureType(connid); - - entry = sip_tcp_conn_tab + connid; - if (entry->sendQueue) { - qElem = (ccsipTCPSendData_t *) sll_next(entry->sendQueue, NULL); -// ccsipSocketSetIPtos(entry->fd, qElem->ip_sig_tos); - while (qElem) { - while (qElem->bytesLeft) { - bytes_sent = sipSocketSend(entry->fd, &qElem->data[qElem->bytesSent], - qElem->bytesLeft, 0, secure); - if (bytes_sent > 0) { - qElem->bytesSent += bytes_sent; - qElem->bytesLeft -= bytes_sent; - } else { - if (errno == EWOULDBLOCK) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Socket blocked requeue data\n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname)); - } else { - entry->error_cause = SOCKET_SEND_ERROR; - sipTcpFlushRetrySendQueue(entry); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=\n", fname, errno); - sip_tcp_createconnfailed_to_spi( - &(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - CCSIP_DEBUG_ERROR("%s: Socket send error." - "Purge queued entry data.\n", fname); - } - return; - } - } /* while (qElem->bytesLeft) */ - - cpr_free(qElem->data); - (void) sll_remove(entry->sendQueue, qElem); - cpr_free(qElem); - CCSIP_DEBUG_REG_STATE("%s: sent out successfully, dequeue an entry.\n", fname); - - qElem = (ccsipTCPSendData_t *) sll_next(entry->sendQueue, NULL); - } /* while qElem */ - } -} - - -/* - * sip_tcp_channel_send() - * Description : This routine is called to send out a tcp message - * - * - * Input : s: socket to send the message over - * buf: message to send - * len: length of the message - * - * Output : success / failure in processing - */ -int -sip_tcp_channel_send (cpr_socket_t s, char *buf, uint32_t len) -{ - static const char *fname = "sip_tcp_channel_send"; - int bytesSent = 0, totalBytesSent = 0; - int connid = 0; - sip_tcp_conn_t *entry; - boolean secure; - - /* convert socket to connid */ - connid = sip_tcp_fd_to_connid(s); - if (!VALID_CONNID(connid)) { - CCSIP_DEBUG_ERROR("%s: Couldn't map socket to a valid connid!\n", fname); - return SIP_TCP_SEND_ERROR; - } - /* use connid we can get this socket's entry in sip_tcp_conn_tab[] */ - entry = sip_tcp_conn_tab + connid; - - /* secd requires that the socket should be in connected state - * to send message. Return if the status is pending. - * Currently this gets control in fallback state. The retry timer - * event in fallback state will resend the message. - */ - if ((sip_tcp_conn_tab[connid].soc_type == SIP_SOC_TLS) && - (sip_tcp_conn_tab[connid].state == SOCK_CONNECT_PENDING)) { - plat_soc_connect_status_e conn_status; - conn_status = platSecSockIsConnected(s); - if (conn_status == PLAT_SOCK_CONN_OK) { - sip_tcp_conn_tab[connid].state = SOCK_CONNECTED; - - } else if (conn_status == PLAT_SOCK_CONN_WAITING) { - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"tls socket waiting %d\n", DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), s); - return SIP_TCP_SEND_OK; - - } else if (conn_status == PLAT_SOCK_CONN_FAILED) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=\n", fname, errno); - sip_tcp_createconnfailed_to_spi(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"TLS socket connect failed %d\n", - fname, s); - return SIP_TCP_SEND_ERROR; - } - } - - /* - * Check not exceeding max allowed payload size - */ - if (len >= MAX_PAYLOAD_SIZE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_TCP_PAYLOAD_TOO_LARGE), - fname, len, CPR_MAX_MSG_SIZE); - return SIP_TCP_SIZE_ERROR; - } - - /* - * Check to see if the send q is empty. If it is not, then - * queue the current message in the sendqueue so that it - * gets sent in order when the socket is ready. - */ - if (entry->sendQueue && sll_count(entry->sendQueue)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"%d Socket waiting on EWOULDBLOCK, " - " queueing data\n", DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), connid); - sipTcpQueueSendData(len, connid, buf, NULL, TRUE, 0x0); - return SIP_TCP_SEND_OK; - } - - secure = ccsipIsSecureType(connid); - - while (len > 0) { - bytesSent = sipSocketSend(s, (void *)buf, (size_t) len, 0, secure); - if (bytesSent == SOCKET_ERROR) { - if (cpr_errno == CPR_EWOULDBLOCK) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"%d Socket EWOULDBLOCK while " - "sending, queueing data\n", DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), - connid); - sipTcpQueueSendData(len, connid, buf, NULL, - TRUE, 0x0); - break; - } - if (cpr_errno != CPR_ENOTCONN) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socket error=%d=\n", fname, errno); - sip_tcp_createconnfailed_to_spi(&(sip_tcp_conn_tab[connid].ipaddr), - sip_tcp_conn_tab[connid].port, - sip_tcp_conn_tab[connid].context, - SOCKET_CONNECT_ERROR, connid); - } - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "sipSocketSend", cpr_errno); - return (cpr_errno== CPR_ENOTCONN? cpr_errno: SIP_TCP_SEND_ERROR); - } - len -= bytesSent; - totalBytesSent += bytesSent; - buf += bytesSent; - } - return SIP_TCP_SEND_OK; -} - -/* - * Free memory for any queued write data. - */ -void -sipTcpFreeSendQueue (int connid) -{ - static const char *fname = "sipTcpFreeSendQueue"; - sip_tcp_conn_t *entry; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Free TCP send queue for connid %d \n", - DEB_F_PREFIX_ARGS(SIP_TCP_MSG, fname), connid); - if (!VALID_CONNID(connid)) { - return; - } - entry = sip_tcp_conn_tab + connid; - sipTcpFlushRetrySendQueue(entry); -} - -/* - * sip_tcp_create_conn_using_blocking_socket() - * Description : This routine is called to create blocking socket - * request from SIP_SPI to SIP_TCP. - * - * Input : spi_msg - Pointer to sipSPIMessage_t containing the create conn - * parameters. - * - * Output : socket fd - */ -cpr_socket_t -sip_tcp_create_conn_using_blocking_socket (sipSPIMessage_t *spi_msg) { - - cpr_socket_t server_conn_handle = INVALID_SOCKET; - - server_conn_handle = sip_tcp_create_connection(spi_msg); - - return server_conn_handle; -} diff --git a/libs/sipcc/core/sipstack/ccsip_platform_timers.c b/libs/sipcc/core/sipstack/ccsip_platform_timers.c deleted file mode 100644 index 7de215d448..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_platform_timers.c +++ /dev/null @@ -1,989 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "phntask.h" -#include "text_strings.h" -#include "ccsip_platform.h" -#include "phone_debug.h" -#include "ccsip_task.h" -#include "ccsip_pmh.h" -#include "ccsip_register.h" -#include "ccsip_core.h" -#include "ccsip_subsmanager.h" - -/* - * Constants - */ - -/* - * Globals TODO: hang off of a single SIP global - */ -sipPlatformUITimer_t sipPlatformUISMTimers[MAX_CCBS]; -sipPlatformUIExpiresTimer_t sipPlatformUISMExpiresTimers[MAX_CCBS]; -sipPlatformUIExpiresTimer_t sipPlatformUISMRegExpiresTimers[MAX_CCBS]; -sipPlatformUIExpiresTimer_t sipPlatformUISMLocalExpiresTimers[MAX_CCBS]; -// This timer will kick in after 1xx in releasing state so if 2xx gets lost -// we will be able to kill the ccb -sipPlatformSupervisionTimer_t sipPlatformSupervisionTimers[MAX_TEL_LINES]; - -sipPlatformUITimer_t sipPlatformUISMSubNotTimers[MAX_SCBS]; -sipPlatformSupervisionTimer_t sipPlatformSubNotPeriodicTimer; -static cprTimer_t sipPlatformRegAllFailedTimer; -static cprTimer_t sipPlatformNotifyTimer; -static cprTimer_t sipPlatformStandbyKeepaliveTimer; -static cprTimer_t sipPlatformUnRegistrationTimer; -static cprTimer_t sipPassThroughTimer; -int -sip_platform_timers_init (void) -{ - static const char fname[] = "sip_platform_timers_init"; - static const char sipMsgTimerName[] = "sipMsg"; - static const char sipExpireTimerName[] = "sipExp"; - static const char sipRegTimeOutTimerName[] = "sipRegTimeout"; - static const char sipRegExpireTimerName[] = "sipRegExp"; - static const char sipLocalExpireTimerName[] = "sipLocalExp"; - static const char sipSupervisionTimerName[] = "sipSupervision"; - static const char sipSubNotTimerName[] = "sipSubNot"; - static const char sipSubNotPeriodicTimerName[] = "sipSubNotPeriodic"; - static const char sipRegAllFailedTimerName[] = "sipRegAllFailed"; - static const char sipNotifyTimerName[] = "sipNotify"; - static const char sipStandbyKeepaliveTimerName[] = "sipStandbyKeepalive"; - static const char sipUnregistrationTimerName[] = "sipUnregistration"; - static const char sipPassThroughTimerName[] = "sipPassThrough"; - - int i; - - for (i = 0; i < MAX_CCBS; i++) { - sipPlatformUISMTimers[i].timer = - cprCreateTimer(sipMsgTimerName, - SIP_MSG_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - sipPlatformUISMTimers[i].reg_timer = - cprCreateTimer(sipRegTimeOutTimerName, - SIP_REG_TIMEOUT_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - sipPlatformUISMExpiresTimers[i].timer = - cprCreateTimer(sipExpireTimerName, - SIP_EXPIRES_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - sipPlatformUISMRegExpiresTimers[i].timer = - cprCreateTimer(sipRegExpireTimerName, - SIP_REG_EXPIRES_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - sipPlatformUISMLocalExpiresTimers[i].timer = - cprCreateTimer(sipLocalExpireTimerName, - SIP_LOCAL_EXPIRES_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - if (!sipPlatformUISMTimers[i].timer || - !sipPlatformUISMTimers[i].reg_timer || - !sipPlatformUISMExpiresTimers[i].timer || - !sipPlatformUISMRegExpiresTimers[i].timer || - !sipPlatformUISMLocalExpiresTimers[i].timer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create one or more" - " UISM timers: %d\n", fname, i); - return SIP_ERROR; - } - } - for (i = 0; i < MAX_TEL_LINES; i++) { - sipPlatformSupervisionTimers[i].timer = - cprCreateTimer(sipSupervisionTimerName, - SIP_SUPERVISION_TIMER, - TIMER_EXPIRATION, - sip_msgq); - } - for (i = 0; i < MAX_SCBS; i++) { - sipPlatformUISMSubNotTimers[i].timer = - cprCreateTimer(sipSubNotTimerName, - SIP_SUBNOT_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - if (!sipPlatformUISMSubNotTimers[i].timer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create Sub/Not" - " UISM timers: %d\n", fname, i); - return SIP_ERROR; - } - } - sipPlatformSubNotPeriodicTimer.timer = - cprCreateTimer(sipSubNotPeriodicTimerName, - SIP_SUBNOT_PERIODIC_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - if (!sipPlatformSubNotPeriodicTimer.timer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create supervision timer: %d\n", - fname, i); - return SIP_ERROR; - } - - sipPlatformRegAllFailedTimer = - cprCreateTimer(sipRegAllFailedTimerName, - SIP_REGALLFAIL_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (!sipPlatformRegAllFailedTimer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create RegAllFailed timer\n", fname); - return SIP_ERROR; - } - /* - * Create the standby cc keepalive timer used by the - * registration Manager. - */ - sipPlatformStandbyKeepaliveTimer = - cprCreateTimer(sipStandbyKeepaliveTimerName, - SIP_KEEPALIVE_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - if (!sipPlatformStandbyKeepaliveTimer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create Standby" - " keepalive timer\n", fname); - return SIP_ERROR; - } - sipPlatformUnRegistrationTimer = - cprCreateTimer(sipUnregistrationTimerName, - SIP_UNREGISTRATION_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (!sipPlatformUnRegistrationTimer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create Stanby keepalive timer\n", - fname); - return SIP_ERROR; - } - sipPlatformNotifyTimer = - cprCreateTimer(sipNotifyTimerName, - SIP_NOTIFY_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (!sipPlatformNotifyTimer) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Failed to create Notify timer\n", fname); - return SIP_ERROR; - } - - sipPassThroughTimer = - cprCreateTimer(sipPassThroughTimerName, - SIP_PASSTHROUGH_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (!sipPassThroughTimer) { - CCSIP_DEBUG_ERROR("%s: failed to create sip PassThrough timer\n", fname); - return SIP_ERROR; - } - - return SIP_OK; -} - -void -sip_platform_timers_shutdown (void) -{ - int i; - - for (i = 0; i < MAX_CCBS; i++) { - sip_platform_msg_timer_stop(i); - (void) cprDestroyTimer(sipPlatformUISMTimers[i].timer); - sipPlatformUISMTimers[i].timer = NULL; - (void) cprDestroyTimer(sipPlatformUISMTimers[i].reg_timer); - sipPlatformUISMTimers[i].reg_timer = NULL; - - (void) sip_platform_expires_timer_stop(i); - (void) cprDestroyTimer(sipPlatformUISMExpiresTimers[i].timer); - sipPlatformUISMExpiresTimers[i].timer = NULL; - - (void) sip_platform_register_expires_timer_stop(i); - (void) cprDestroyTimer(sipPlatformUISMRegExpiresTimers[i].timer); - sipPlatformUISMRegExpiresTimers[i].timer = NULL; - - (void) sip_platform_localexpires_timer_stop(i); - (void) cprDestroyTimer(sipPlatformUISMLocalExpiresTimers[i].timer); - sipPlatformUISMLocalExpiresTimers[i].timer = NULL; - } - - for (i = 0; i < MAX_TEL_LINES; i++) { - (void) sip_platform_supervision_disconnect_timer_stop(i); - (void) cprDestroyTimer(sipPlatformSupervisionTimers[i].timer); - sipPlatformSupervisionTimers[i].timer = NULL; - } - - for (i = 0; i < MAX_SCBS; i++) { - sip_platform_msg_timer_subnot_stop(&sipPlatformUISMSubNotTimers[i]); - (void) cprDestroyTimer(sipPlatformUISMSubNotTimers[i].timer); - sipPlatformUISMSubNotTimers[i].timer = NULL; - } - (void) sip_platform_subnot_periodic_timer_stop(); - (void) cprDestroyTimer(sipPlatformSubNotPeriodicTimer.timer); - sipPlatformSubNotPeriodicTimer.timer = NULL; - (void) sip_platform_reg_all_fail_timer_stop(); - (void) cprDestroyTimer(sipPlatformRegAllFailedTimer); - sipPlatformRegAllFailedTimer = NULL; - (void) sip_platform_standby_keepalive_timer_stop(); - (void) cprDestroyTimer(sipPlatformStandbyKeepaliveTimer); - sipPlatformStandbyKeepaliveTimer = NULL; - (void) sip_platform_unregistration_timer_stop(); - (void) cprDestroyTimer(sipPlatformUnRegistrationTimer); - sipPlatformUnRegistrationTimer = NULL; - (void) sip_platform_notify_timer_stop(); - (void) cprDestroyTimer(sipPlatformNotifyTimer); - sipPlatformNotifyTimer = NULL; - (void) sip_platform_pass_through_timer_stop(); - (void) cprDestroyTimer(sipPassThroughTimer); - sipPassThroughTimer = NULL; -} - -/******************************************************** - * - * Message timer support functions for SIP SM - * - ********************************************************/ -void -sip_platform_msg_timers_init (void) -{ - static const char fname[] = "sip_platform_msg_timers_init"; - static long timer_init_complete = 0; - int i; - cprTimer_t timer, reg_timer; - - for (i = 0; i < MAX_CCBS; i++) { - if (timer_init_complete) { - if ((cprCancelTimer(sipPlatformUISMTimers[i].timer) - == CPR_FAILURE) || - (cprCancelTimer(sipPlatformUISMTimers[i].reg_timer) - == CPR_FAILURE)) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "cprCancelTimer"); - } - } - timer = sipPlatformUISMTimers[i].timer; - reg_timer = sipPlatformUISMTimers[i].reg_timer; - - if (sipPlatformUISMTimers[i].message_buffer != NULL) { - cpr_free(sipPlatformUISMTimers[i].message_buffer); - sipPlatformUISMTimers[i].message_buffer = NULL; - sipPlatformUISMTimers[i].message_buffer_len = 0; - } - - memset(&sipPlatformUISMTimers[i], 0, sizeof(sipPlatformUITimer_t)); - sipPlatformUISMTimers[i].timer = timer; - sipPlatformUISMTimers[i].reg_timer = reg_timer; - } - timer_init_complete = 1; - return; -} - - -int -sip_platform_msg_timer_start (uint32_t msec, - void *data, - int idx, - char *message_buffer, - int message_buffer_len, - int message_type, - cpr_ip_addr_t *ipaddr, - uint16_t port, - boolean isRegister) -{ - static const char fname[] = "sip_platform_msg_timer_start"; - cprTimer_t timer; - - /* validate index */ - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - /* validate length */ - if (message_buffer_len >= SIP_UDP_MESSAGE_SIZE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_MSG_BUFFER_TOO_BIG), - fname, message_buffer_len); - return SIP_ERROR; - } - - /* stop the timer if it is running */ - if (cprCancelTimer(sipPlatformUISMTimers[idx].timer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - if (cprCancelTimer(sipPlatformUISMTimers[idx].reg_timer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - if (sipPlatformUISMTimers[idx].message_buffer == NULL) { - sipPlatformUISMTimers[idx].message_buffer = (char *)cpr_malloc(message_buffer_len+1); - if (sipPlatformUISMTimers[idx].message_buffer == NULL) return SIP_ERROR; - } - else if (message_buffer != sipPlatformUISMTimers[idx].message_buffer) { - cpr_free(sipPlatformUISMTimers[idx].message_buffer); - sipPlatformUISMTimers[idx].message_buffer = (char *)cpr_malloc(message_buffer_len+1); - if (sipPlatformUISMTimers[idx].message_buffer == NULL) return SIP_ERROR; - } - - sipPlatformUISMTimers[idx].message_buffer_len = message_buffer_len; - sipPlatformUISMTimers[idx].message_buffer[message_buffer_len] = '\0'; - memcpy(sipPlatformUISMTimers[idx].message_buffer, message_buffer, - message_buffer_len); - sipPlatformUISMTimers[idx].message_type = (sipMethod_t) message_type; - sipPlatformUISMTimers[idx].ipaddr = *ipaddr; - sipPlatformUISMTimers[idx].port = port; - - /* start the timer */ - if (isRegister) { - timer = sipPlatformUISMTimers[idx].reg_timer; - } else { - timer = sipPlatformUISMTimers[idx].timer; - } - - if (cprStartTimer(timer, msec, data) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - cpr_free(sipPlatformUISMTimers[idx].message_buffer); - sipPlatformUISMTimers[idx].message_buffer = NULL; - sipPlatformUISMTimers[idx].message_buffer_len = 0; - return SIP_ERROR; - } - sipPlatformUISMTimers[idx].outstanding = TRUE; - return SIP_OK; -} - - -void -sip_platform_msg_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_msg_timer_stop"; - - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return; - } - - if ((cprCancelTimer(sipPlatformUISMTimers[idx].timer) == CPR_FAILURE) || - (cprCancelTimer(sipPlatformUISMTimers[idx].reg_timer) == CPR_FAILURE)) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return; - } - sipPlatformUISMTimers[idx].outstanding = FALSE; -} - - -boolean -sip_platform_msg_timer_outstanding_get (int idx) -{ - return sipPlatformUISMTimers[idx].outstanding; -} - - -void -sip_platform_msg_timer_outstanding_set (int idx, boolean value) -{ - sipPlatformUISMTimers[idx].outstanding = value; -} - - -int -sip_platform_msg_timer_update_destination (int idx, - cpr_ip_addr_t *ipaddr, - uint16_t port) -{ - static const char fname[] = "sip_platform_msg_timer_update_destination"; - - if ((idx < TEL_CCB_START) || (idx > REG_BACKUP_CCB)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - if (ipaddr == NULL) { - sipPlatformUISMExpiresTimers[idx].ipaddr = ip_addr_invalid; - } else { - sipPlatformUISMTimers[idx].ipaddr = *ipaddr; - } - - sipPlatformUISMTimers[idx].port = port; - - return SIP_OK; -} - -/******************************************************** - * - * Expires timer support functions for SIP SM - * - ********************************************************/ -int -sip_platform_expires_timer_start (uint32_t msec, - int idx, - cpr_ip_addr_t *ipaddr, - uint16_t port) -{ - static const char fname[] = "sip_platform_expires_timer_start"; - - if (sip_platform_expires_timer_stop(idx) == SIP_ERROR) { - return SIP_ERROR; - } - - if (ipaddr == NULL) { - sipPlatformUISMExpiresTimers[idx].ipaddr = ip_addr_invalid; - } else { - sipPlatformUISMExpiresTimers[idx].ipaddr = *ipaddr; - } - - sipPlatformUISMExpiresTimers[idx].port = port; - - //sip_platform_expires_timer_callback - if (cprStartTimer(sipPlatformUISMExpiresTimers[idx].timer, msec, - (void *) (long)idx) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_expires_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_expires_timer_stop"; - - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - if (cprCancelTimer(sipPlatformUISMExpiresTimers[idx].timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_register_expires_timer_start (uint32_t msec, int idx) -{ - static const char fname[] = "sip_platform_register_expires_timer_start"; - - if (sip_platform_register_expires_timer_stop(idx) == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformUISMRegExpiresTimers[idx].timer, msec, - (void *)(long) idx) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_register_expires_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_register_expires_timer_stop"; - - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - if (cprCancelTimer(sipPlatformUISMRegExpiresTimers[idx].timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - -/******************************************************** - * - * Local Expires timer support functions for SIP SM - * - ********************************************************/ -int -sip_platform_localexpires_timer_start (uint32_t msec, - int idx, - cpr_ip_addr_t *ipaddr, - uint16_t port) -{ - static const char fname[] = "sip_platform_localexpires_timer_start"; - - if (sip_platform_localexpires_timer_stop(idx) == SIP_ERROR) { - return SIP_ERROR; - } - - sipPlatformUISMLocalExpiresTimers[idx].ipaddr = *ipaddr; - sipPlatformUISMLocalExpiresTimers[idx].port = port; - - //sip_platform_localexpires_timer_callback - if (cprStartTimer(sipPlatformUISMLocalExpiresTimers[idx].timer, msec, - (void *)(long) idx) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_localexpires_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_localexpires_timer_stop"; - - if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID), - fname, idx); - return SIP_ERROR; - } - - if (cprCancelTimer(sipPlatformUISMLocalExpiresTimers[idx].timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -sipMethod_t -sip_platform_msg_timer_messageType_get (int idx) -{ - if ((idx >= TEL_CCB_START) && (idx <= REG_BACKUP_CCB)) { - if (sipPlatformUISMTimers[idx].outstanding) { - return sipPlatformUISMTimers[idx].message_type; - } - } - return sipMethodUnknown; -} - -/* - * Call disconnect timer - */ -int -sip_platform_supervision_disconnect_timer_start (uint32_t msec, int idx) -{ - static const char fname[] = "sip_platform_supervision_disconnect_timer_start"; - - if (sip_platform_supervision_disconnect_timer_stop(idx) == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformSupervisionTimers[idx].timer, msec, - (void *)(long) idx) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - - -int -sip_platform_supervision_disconnect_timer_stop (int idx) -{ - static const char fname[] = "sip_platform_supervision_disconnect_timer_stop"; - - if ((idx < TEL_CCB_START) || (idx > TEL_CCB_END)) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_LINE_NUMBER_INVALID), fname, idx); - return SIP_ERROR; - } - - if (cprCancelTimer(sipPlatformSupervisionTimers[idx].timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - idx, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - - return SIP_OK; -} - -void -sip_platform_post_timer (uint32_t cmd, void *data) -{ - static const char fname[] = "sip_platform_post_timer"; - uint32_t *timer_msg = NULL; - - /* grab msg buffer */ - timer_msg = (uint32_t *) SIPTaskGetBuffer(sizeof(uint32_t)); - if (!timer_msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SYSBUF_UNAVAILABLE), fname); - return; - } - *timer_msg = (long) data; - - /* Put it on the SIP message queue */ - if (SIPTaskSendMsg(cmd, (cprBuffer_t) timer_msg, sizeof(uint32_t), NULL) - == CPR_FAILURE) { - cpr_free(timer_msg); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Send msg failed.\n", fname); - } - return; -} - - -/**************************************************** - * Timer functions for Subscribe / Notify operations - ****************************************************/ - -int -sip_platform_msg_timer_subnot_start (uint32_t msec, - sipPlatformUITimer_t *timer_p, - uint32_t id, - char *message_buffer, - int message_buffer_len, - int message_type, - cpr_ip_addr_t *ipaddr, - uint16_t port) -{ - static const char fname[] = "sip_platform_msg_timer_start_subnot"; - - sip_platform_msg_timer_subnot_stop(timer_p); - - if (message_buffer_len > SIP_UDP_MESSAGE_SIZE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_MSG_BUFFER_TOO_BIG), - fname, message_buffer_len); - return SIP_ERROR; - } - - if (timer_p->message_buffer == NULL) { - timer_p->message_buffer = (char *)cpr_malloc(message_buffer_len+1); - if (timer_p->message_buffer == NULL) return SIP_ERROR; - } - else if (timer_p->message_buffer != message_buffer) { - cpr_free(timer_p->message_buffer); - timer_p->message_buffer = (char *)cpr_malloc(message_buffer_len+1); - if (timer_p->message_buffer == NULL) return SIP_ERROR; - } - - timer_p->message_buffer_len = message_buffer_len; - timer_p->message_buffer[message_buffer_len] = '\0'; - memcpy(timer_p->message_buffer, message_buffer, - message_buffer_len); - timer_p->message_type = - (sipMethod_t) message_type; - timer_p->ipaddr = *ipaddr; - timer_p->port = port; - - if (cprStartTimer(timer_p->timer, msec, (void *)(long)id) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "%s failed\n", - fname, "cprStartTimer"); - cpr_free(timer_p->message_buffer); - timer_p->message_buffer = NULL; - timer_p->message_buffer_len = 0; - return SIP_ERROR; - } - - return SIP_OK; - -} - -void -sip_platform_msg_timer_subnot_stop (sipPlatformUITimer_t *timer_p) -{ - static const char fname[] = "sip_platform_msg_timer_stop_subnot"; - - if (timer_p->message_buffer != NULL) { - cpr_free(timer_p->message_buffer); - timer_p->message_buffer = NULL; - } - if (cprCancelTimer(timer_p->timer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX "%s failed\n", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), "cprCancelTimer"); - return; - } -} - -void -sip_platform_subnot_msg_timer_callback (void *data) -{ - sip_platform_post_timer(SIP_TMR_MSG_RETRY_SUBNOT, data); -} - -int -sip_platform_subnot_periodic_timer_start (uint32_t msec) -{ - static const char fname[] = "sip_platform_subnot_periodic_timer_start"; - - if (sip_platform_subnot_periodic_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformSubNotPeriodicTimer.timer, msec, (void *) 0) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - -1, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - sipPlatformSubNotPeriodicTimer.started = TRUE; - return SIP_OK; -} - -int -sip_platform_subnot_periodic_timer_stop (void) -{ - static const char fname[] = "sip_platform_subnot_periodic_timer_stop"; - - if (sipPlatformSubNotPeriodicTimer.started == TRUE) { - if (cprCancelTimer(sipPlatformSubNotPeriodicTimer.timer) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - -1, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - } - sipPlatformSubNotPeriodicTimer.started = FALSE; - return SIP_OK; -} - -void -sip_platform_subnot_periodic_timer_callback (void *data) -{ - sip_platform_post_timer(SIP_TMR_PERIODIC_SUBNOT, data); -} - -/** - ** sip_platform_reg_all_fail_timer_start - * Starts a timer when all registrations fail. - * - * @param msec Value of the timer to be started - * - * @return SIP_OK if timer could be started; else SIP_ERROR - * - */ -int -sip_platform_reg_all_fail_timer_start (uint32_t msec) -{ - - static const char fname[] = "sip_platform_reg_all_fail_timer_start"; - if (sip_platform_reg_all_fail_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformRegAllFailedTimer, msec, NULL) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX - "Timer started for %lu msecs\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), msec); - return SIP_OK; -} - -/** - ** sip_platform_reg_all_fail_timer_stop - * Stops the Reg-All Fail timer - * - * @param none - * - * @return SIP_OK if timer could be stopped; else SIP_ERROR - * - */ -int -sip_platform_reg_all_fail_timer_stop (void) -{ - static const char fname[] = "sip_platform_reg_all_fail_timer_stop"; - - if (cprCancelTimer(sipPlatformRegAllFailedTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} - -/**************************************************** - * Timer functions for standby cc keepalive operations - ****************************************************/ -int -sip_platform_standby_keepalive_timer_start (uint32_t msec) -{ - static const char fname[] = "sip_platform_standby_keepalive_timer_start"; - - if (sip_platform_standby_keepalive_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformStandbyKeepaliveTimer, msec, NULL) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - CCSIP_DEBUG_STATE(DEB_F_PREFIX - "Timer started for %lu msecs\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), msec); - return SIP_OK; -} - -int -sip_platform_standby_keepalive_timer_stop () -{ - static const char fname[] = "sip_platform_standby_keepalive_timer_stop"; - - if (cprCancelTimer(sipPlatformStandbyKeepaliveTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} - -int -sip_platform_unregistration_timer_start (uint32_t msec, boolean external) -{ - static const char fname[] = "sip_platform_unregistration_timer_start"; - - if (sip_platform_unregistration_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformUnRegistrationTimer, msec, (void *)(long)external) - == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - CCSIP_DEBUG_STATE(DEB_F_PREFIX - "Timer started for %lu msecs\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), msec); - return SIP_OK; -} - -int -sip_platform_unregistration_timer_stop () -{ - static const char fname[] = "sip_platform_unregistration_timer_stop"; - - if (cprCancelTimer(sipPlatformUnRegistrationTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} - -void -sip_platform_unregistration_callback (void *data) -{ - sip_platform_post_timer(SIP_TMR_SHUTDOWN_PHASE2, data); -} - -int -sip_platform_notify_timer_start (uint32_t msec) -{ - static const char fname[] = "sip_platform_notify_timer_start"; - - if (sip_platform_notify_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - - if (cprStartTimer(sipPlatformNotifyTimer, msec, NULL) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - CCSIP_DEBUG_STATE(DEB_F_PREFIX - "Timer started for %lu msecs\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), msec); - return SIP_OK; -} - -int -sip_platform_notify_timer_stop () -{ - static const char fname[] = "sip_platform_notify_timer_stop"; - - if (cprCancelTimer(sipPlatformNotifyTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} - -/*********************************************** - * PassThrough Timer - *********************************************** - ** sip_platform_pass_through_timer_start - * Starts a timer when all registrations fail. - * - * @param sec Value of the timer to be started - * - * @return SIP_OK if timer could be started; else SIP_ERROR - * - */ -int -sip_platform_pass_through_timer_start (uint32_t sec) -{ - static const char fname[] = "sip_platform_pass_through_timer_start"; - - if (sip_platform_pass_through_timer_stop() == SIP_ERROR) { - return SIP_ERROR; - } - if (cprStartTimer(sipPassThroughTimer, sec*1000, NULL) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprStartTimer"); - return SIP_ERROR; - } - - CCSIP_DEBUG_REG_STATE("%s: Regmgr Pass Through Timer started for %lu secs\n", fname, sec); - return SIP_OK; -} - - /** - ** sip_platform_pass_through_timer_stop - * Stops the Pass Through timer - * - * @param none - * - * @return SIP_OK if timer could be stopped; else SIP_ERROR - * - */ -int -sip_platform_pass_through_timer_stop (void) -{ - static const char fname[] = "sip_platform_pass_through_timer_stop"; - - if (cprCancelTimer(sipPassThroughTimer) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - 0, 0, fname, "cprCancelTimer"); - return SIP_ERROR; - } - return SIP_OK; -} diff --git a/libs/sipcc/core/sipstack/ccsip_platform_tls.c b/libs/sipcc/core/sipstack/ccsip_platform_tls.c deleted file mode 100644 index 7183841780..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_platform_tls.c +++ /dev/null @@ -1,176 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "sip_platform_task.h" -#include "ccsip_platform_udp.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "phone_debug.h" -#include "util_string.h" -#include "ccsip_platform_tcp.h" -#include "text_strings.h" -#include "ccsip_register.h" -#include "phntask.h" -#include "plat_api.h" -#include "sip_socket_api.h" - -#define HOST_SIZE 64 - - -cpr_socket_t sip_tls_create_connection(sipSPIMessage_t *spi_msg, - boolean blocking, - sec_level_t sec); -extern cpr_sockaddr_t *sip_set_sockaddr(cpr_sockaddr_storage *psock_storage, uint16_t family, - cpr_ip_addr_t ip_addr, uint16_t port, uint16_t *addr_len); - -/* - * sip_tls_create_connection() - * Description : This routine is called is response to a create connection - * request from SIP_SPI to SIP_TLS. - * - * Input : spi_msg - Pointer to sipSPIMessage_t containing the create conn - * parameters. - * blocking - connection mode; FALSE - nonblock; TRUE - block - * - * Output : Nothing - */ -cpr_socket_t -sip_tls_create_connection (sipSPIMessage_t *spi_msg, boolean blocking, - sec_level_t sec) -{ - const char fname[] = "sip_tls_create_connection"; - int idx; - sipSPICreateConnection_t *create_msg; - char ipaddr_str[MAX_IPADDR_STR_LEN]; - plat_soc_status_e ret; - cpr_socket_t sock = INVALID_SOCKET; - uint16_t sec_port = 0; - plat_soc_connect_status_e conn_status; - int tos_dscp_val = 0; // set to default if there is no config. for dscp -#ifdef IPV6_STACK_ENABLED - int ip_mode = CPR_IP_MODE_IPV4; -#endif - uint16_t af_listen = AF_INET6; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len; - int ip_mode = 0; // currently hardcoded to ipv4 - plat_soc_connect_mode_e conn_mode; - -#ifdef IPV6_STACK_ENABLED - - config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); - - /* - * Create a socket - */ - if (ip_mode == CPR_IP_MODE_IPV6 || - ip_mode == CPR_IP_MODE_DUAL) { - af_listen = AF_INET6; - } else { -#endif - af_listen = AF_INET; -#ifdef IPV6_STACK_ENABLED - } -#endif - - sip_tcp_init_conn_table(); - create_msg = &(spi_msg->createConnMsg); - ipaddr2dotted(ipaddr_str, &create_msg->addr); - ret = platSecIsServerSecure(); - if (ret != PLAT_SOCK_SECURE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Secure connection is not created because" - " there is no secure servers\n", fname); - return INVALID_SOCKET; - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX - "Creating secure connection\n", DEB_F_PREFIX_ARGS(SIP_TLS, fname)); - /* connect securely via TLS */ - config_get_value(CFGID_DSCP_FOR_CALL_CONTROL, (int *)&tos_dscp_val, - sizeof(tos_dscp_val)); - - if (sec == AUTHENTICATED) { - conn_mode = PLAT_SOCK_AUTHENTICATED; - } else if (sec == ENCRYPTED) { - conn_mode = PLAT_SOCK_ENCRYPTED; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Secure connection is not created. Security mode was" - " not encrypyted or authenticated.\n", fname); - conn_mode = PLAT_SOCK_NON_SECURE; - } - sock = platSecSocConnect(ipaddr_str, /* host */ - create_msg->port, /* port */ - ip_mode, /* ip mode, ipv4 = 0, ipv6 = 1, dual = 2 */ - blocking, /* 1 - block */ - tos_dscp_val, /* TOS value */ - conn_mode, /* The mode (Auth/Encry/None) */ - &sec_port); /* local port */ - - if (sock < 0) { - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Secure connect failed!!\n",fname); - return INVALID_SOCKET; - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX "Secure connect ok\n", DEB_F_PREFIX_ARGS(SIP_TLS, fname)); - if (!blocking) { - /* should not call this api in blocking mode */ - conn_status = platSecSockIsConnected(sock); - if (conn_status == PLAT_SOCK_CONN_FAILED) { - (void)sipSocketClose(sock, TRUE); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Establish non-blocking mode secure" - " connection failed!!\n", fname); - return INVALID_SOCKET; - } - } else { - conn_status = PLAT_SOCK_CONN_OK; - } - if (sip_tcp_set_sock_options(sock) != TRUE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Socket set option failure\n", - fname); - } - - idx = sip_tcp_get_free_conn_entry(); - if (idx == -1) { - /* Send create connection failed message to SIP_SPI */ - (void)sipSocketClose(sock, TRUE); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Get free TCP connection entry failed\n", - fname); - return INVALID_SOCKET; - } - - memset(&sock_addr, 0, sizeof(sock_addr)); - (void) sip_set_sockaddr(&sock_addr, af_listen, create_msg->addr, - (uint16_t)(create_msg->port), &addr_len); - - sip_tcp_conn_tab[idx].fd = sock; - sip_tcp_conn_tab[idx].ipaddr = create_msg->addr; - sip_tcp_conn_tab[idx].port = create_msg->port; - sip_tcp_conn_tab[idx].context = spi_msg->context; - sip_tcp_conn_tab[idx].dirtyFlag = FALSE; - sip_tcp_conn_tab[idx].addr = sock_addr; - sip_tcp_conn_tab[idx].soc_type = SIP_SOC_TLS; - - if (conn_status == PLAT_SOCK_CONN_OK) { - sip_tcp_conn_tab[idx].state = SOCK_CONNECTED; - } else { - sip_tcp_conn_tab[idx].state = SOCK_CONNECT_PENDING; - } - create_msg->local_listener_port = (uint16) sec_port; - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX - "Local listening port=%d\n", DEB_F_PREFIX_ARGS(SIP_TLS, fname), - create_msg->local_listener_port); - (void)sip_tcp_attach_socket(sock); - return (sock); -} diff --git a/libs/sipcc/core/sipstack/ccsip_platform_udp.c b/libs/sipcc/core/sipstack/ccsip_platform_udp.c deleted file mode 100644 index 0b09bbc792..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_platform_udp.c +++ /dev/null @@ -1,455 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_socket.h" -#include "cpr_memory.h" -#include "cpr_ipc.h" -#include "cpr_in.h" -#include "cpr_errno.h" -#include "cpr_string.h" -#include "util_string.h" -#include "text_strings.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "ccsip_platform_udp.h" -#include "phone.h" -#include "phone_debug.h" -#include "sip_common_transport.h" -#include "sip_platform_task.h" -#include "sip_socket_api.h" - -// FIXME include does not exist on windows -//#include - -static uint16_t af_family_listen = AF_INET6; -static uint16_t af_family_connect = AF_INET6; - -/* - * To set the appropriate socket strcutre based on the family. The called - * of the function is responsible for allocating the memory. - * - * @param psock_storage pointer to cpar_sockaddr_storage - * family network family AF_INET or AF_INET6 - * ip_addr ip address - * port - * addr_len legth returned based on family - * - * - * @return pointer to cpr_sockaddr, which is also psock_storage - * - * @pre none - * - */ - -cpr_sockaddr_t *sip_set_sockaddr (cpr_sockaddr_storage *psock_storage, uint16_t family, - cpr_ip_addr_t ip_addr, uint16_t port, uint16_t *addr_len) -{ - static const char fname[] = "sip_set_sockaddr"; - - cpr_sockaddr_in6_t *pin6_addr; - cpr_sockaddr_in_t *pin_addr; - cpr_sockaddr_t *psock_addr; - uint32_t tmp_ip; - int i,j; - unsigned char tmp; - - switch (family) { - case AF_INET6: - - pin6_addr = (cpr_sockaddr_in6_t *)psock_storage; - memset(pin6_addr, 0, sizeof(cpr_sockaddr_in6_t)); - pin6_addr->sin6_family = family; - pin6_addr->sin6_port = htons(port); - - if (ip_addr.type == CPR_IP_ADDR_IPV4) { - - if (ip_addr.u.ip4 != INADDR_ANY) { - pin6_addr->sin6_addr.addr.base16[5] = 0xffff; - } - tmp_ip = ntohl(ip_addr.u.ip4); - memcpy((void *)&(pin6_addr->sin6_addr.addr.base16[6]), (void *)&tmp_ip, 4); - - } else { - - for (i=0, j=15; i<16; i++, j--) { - tmp = pin6_addr->sin6_addr.addr.base8[j]; - pin6_addr->sin6_addr.addr.base8[j] = ip_addr.u.ip6.addr.base8[i]; - ip_addr.u.ip6.addr.base8[i] = tmp; - } - - } - - *addr_len = sizeof(cpr_sockaddr_in6_t); - return(psock_addr=(cpr_sockaddr_t *)pin6_addr); - - case AF_INET: - if (ip_addr.type == CPR_IP_ADDR_IPV6) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Setting ipv6 address in AF_INET\n",fname); - break; - } - pin_addr = (cpr_sockaddr_in_t *)psock_storage; - memset(pin_addr, 0, sizeof(cpr_sockaddr_in_t)); - pin_addr->sin_family = family; - pin_addr->sin_addr.s_addr = htonl(ip_addr.u.ip4); - pin_addr->sin_port = htons(port); - - *addr_len = sizeof(cpr_sockaddr_in_t); - return(psock_addr=(cpr_sockaddr_t *)pin_addr); - - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set sockaddr.\n",fname); - break; - } - - return(NULL); -} - -int -sip_platform_udp_channel_listen (cpr_ip_mode_e ip_mode, cpr_socket_t *s, - cpr_ip_addr_t *local_ipaddr, - uint16_t local_port) -{ - static const char fname[] = "sip_platform_udp_channel_listen"; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len; - - /* - * If socket passed is is not INVALID_SOCKET close it first - */ - - if (*s != INVALID_SOCKET) { - if (sipSocketClose(*s, FALSE) != CPR_SUCCESS) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "sipSocketClose", cpr_errno); - } - sip_platform_task_reset_listen_socket(*s); - } - - /* - * Create a socket - */ - if (ip_mode == CPR_IP_MODE_IPV6 || - ip_mode == CPR_IP_MODE_DUAL) { - af_family_listen = AF_INET6; - } else { - af_family_listen = AF_INET; - } - - *s = cprSocket(af_family_listen, SOCK_DGRAM, 0); - if (*s == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSocket unable to open socket", cpr_errno); - if (ip_mode == CPR_IP_MODE_DUAL) { - - af_family_listen = AF_INET; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Socket open failed for IPv6 using IPv4 address.", - DEB_F_PREFIX_ARGS(SIP_SDP, fname)); - - *s = cprSocket(af_family_listen, SOCK_DGRAM, 0); - if (*s == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSocket unable to open socket for IPv4", - cpr_errno); - return SIP_ERROR; - } - } - } - - (void) sip_set_sockaddr(&sock_addr, af_family_listen, *local_ipaddr, - local_port, &addr_len); - - if (cprBind(*s, (cpr_sockaddr_t *)&sock_addr, addr_len) == CPR_FAILURE) { - (void) sipSocketClose(*s, FALSE); - *s = INVALID_SOCKET; - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprBind", cpr_errno); - return SIP_ERROR; - } - sip_platform_task_set_listen_socket(*s); - - return SIP_OK; -} - -int -sip_platform_udp_channel_create (cpr_ip_mode_e ip_mode, cpr_socket_t *s, - cpr_ip_addr_t *remote_ipaddr, - uint16_t remote_port, - uint32_t local_udp_port) -{ - static const char *fname = "sip_platform_udp_channel_create"; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len; - cpr_sockaddr_storage local_sock_addr; - cpr_ip_addr_t local_signaladdr; - - int tos_dscp_val = 0; // set to default if there is no config. for dscp - - CPR_IP_ADDR_INIT(local_signaladdr); - - if (*s != INVALID_SOCKET) { - (void) sipSocketClose(*s, FALSE); - } - - if (ip_mode == CPR_IP_MODE_IPV6 || - ip_mode == CPR_IP_MODE_DUAL) { - af_family_connect = AF_INET6; - } else { - af_family_connect = AF_INET; - } - /* - * Create socket - */ - *s = cprSocket(af_family_connect, SOCK_DGRAM, 0); - if (*s == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSocket unable to open socket", - cpr_errno); - /* Try opening ipv4 socket */ - if (ip_mode == CPR_IP_MODE_DUAL) { - - CCSIP_DEBUG_TASK("%s: cprSocket Open failed for IPv6 trying IPv4", - fname); - af_family_connect = AF_INET; - *s = cprSocket(af_family_connect, SOCK_DGRAM, 0); - if (*s == INVALID_SOCKET) { - - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSocket unable to open AF_INET socket", - cpr_errno); - return SIP_ERROR; - } - } - } - - sip_config_get_net_device_ipaddr(&local_signaladdr); - memset(&local_sock_addr, 0, sizeof(local_sock_addr)); - - (void) sip_set_sockaddr(&local_sock_addr, af_family_connect, local_signaladdr, 0, &addr_len); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"local_signaladdr.u.ip4=%x\n", - DEB_F_PREFIX_ARGS(SIP_SDP, fname), local_signaladdr.u.ip4); - - if(cprBind(*s, (cpr_sockaddr_t *)&local_sock_addr, addr_len)){ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"UDP bind failed with errno %d\n", fname, cpr_errno); - (void) sipSocketClose(*s, FALSE); - *s = INVALID_SOCKET; - return SIP_ERROR; - } - - /* - * Connect to remote address - */ - (void) sip_set_sockaddr(&sock_addr, af_family_connect, *remote_ipaddr, - remote_port, &addr_len); - - /* if (cprConnect(*s, (cpr_sockaddr_t *)&sock_addr, addr_len) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprConnect", cpr_errno); - (void) sipSocketClose(*s, FALSE); - *s = INVALID_SOCKET; - return SIP_ERROR; - } -*/ - // set IP tos/dscp value for SIP messaging - config_get_value(CFGID_DSCP_FOR_CALL_CONTROL, (int *)&tos_dscp_val, - sizeof(tos_dscp_val)); - - if (cprSetSockOpt(*s, SOL_IP, IP_TOS, (void *)&tos_dscp_val, - sizeof(tos_dscp_val)) == CPR_FAILURE) { - // do NOT take hard action; just log the error and move on - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set IP TOS %d on UDP socket. " - "cpr_errno = %d\n", fname, tos_dscp_val, cpr_errno); - } - return SIP_OK; -} - - -int -sip_platform_udp_channel_destroy (cpr_socket_t s) -{ - static const char fname[] = "sip_platform_udp_channel_destroy"; - - if (s != INVALID_SOCKET) { - if (sipSocketClose(s, FALSE) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "sipSocketClose", cpr_errno); - return SIP_ERROR; - } - } - return SIP_OK; -} - -int -sip_platform_udp_channel_read (cpr_socket_t s, - cprBuffer_t buf, - uint16_t *len, - cpr_sockaddr_t *soc_addr, - cpr_socklen_t *soc_addr_len) -{ - static const char *fname = "sip_platform_udp_channel_read"; - int bytes_read; - // NOT USED: cpr_sockaddr_in_t *addr = (cpr_sockaddr_in_t *)soc_addr; - - bytes_read = cprRecvFrom(s, buf, CPR_MAX_MSG_SIZE, 0, soc_addr, - soc_addr_len); - - switch (bytes_read) { - case SOCKET_ERROR: - /* - * If no data is available to read (CPR_EWOULDBLOCK), - * for non-blocking socket, it is not an error. - */ - cpr_free(buf); - *len = 0; - if (cpr_errno != CPR_EWOULDBLOCK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"fd[%d]\n", fname, s); - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprRecvFrom", cpr_errno); - return SIP_ERROR; - } - /* - * Will continue reading when data arrives at socket - */ - break; - case 0: - /* - * Return value 0 is OK. This does NOT mean the connection - * has closed by the peer, as with TCP sockets. With UDP - * sockets, there is no such thing as closing a connection. - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"No data on fd %d\n", DEB_F_PREFIX_ARGS(SIP_SDP, fname), s); - cpr_free(buf); - *len = 0; - break; - default: - /* PKT has been read */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Recvd on fd %d\n", DEB_F_PREFIX_ARGS(SIP_SDP, fname), s); - *len = (uint16_t) bytes_read; - break; - } - - return SIP_OK; -} - -int -sip_platform_udp_channel_send (cpr_socket_t s, char *buf, uint16_t len) -{ - static const char *fname = "sip_platform_udp_channel_send"; - ssize_t bytesSent; - - /* - * Check not exceeding max allowed payload size - */ - if (len >= PKTBUF_SIZ) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_UDP_PAYLOAD_TOO_LARGE), - fname, len, PKTBUF_SIZ); - return SIP_ERROR; - } - - while (len > 0) { - bytesSent = sipSocketSend(s, (void *)buf, (size_t)len, 0, FALSE); - if (bytesSent == SOCKET_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSend", cpr_errno); - return SIP_ERROR; - } - - len -= bytesSent; - buf += bytesSent; - } - - return SIP_OK; -} - -/** - * - * sip_platform_udp_read_socket - * - * Read from the socket to extract received message - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_udp_read_socket (cpr_socket_t s) -{ - cprBuffer_t buf; - uint16_t len = 0; - cpr_sockaddr_storage from; - cpr_socklen_t from_len; - const char *fname = "sip_platform_udp_read_socket"; - - if (af_family_listen == AF_INET6) { - from_len = sizeof(cpr_sockaddr_in6_t); - } else { - from_len = sizeof(cpr_sockaddr_in_t); - } - - buf = SIPTaskGetBuffer(CPR_MAX_MSG_SIZE); - if (buf) { - if ((sip_platform_udp_channel_read(s, buf, &len, - (cpr_sockaddr_t *)&from, &from_len) == SIP_OK) && - (len != 0)) { - (void) SIPTaskProcessUDPMessage(buf, len, from); - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No buffers available to read UDP socket.\n", - fname); - } -} - -int -sip_platform_udp_channel_sendto (cpr_socket_t s, char *buf, uint32_t len, - cpr_ip_addr_t *dst_ipaddr, uint16_t dst_port) -{ - static const char *fname = "sip_platform_udp_channel_sendto"; - ssize_t bytesSent; - cpr_sockaddr_storage sock_addr; - uint16_t addr_len; - cpr_ip_addr_t dest_ip_addr; - - /* - * Connect to remote address - */ - dest_ip_addr = *dst_ipaddr; - (void) sip_set_sockaddr(&sock_addr, af_family_connect, dest_ip_addr, - dst_port, &addr_len); - - - /* - * Check not exceeding max allowed payload size - */ - if (len >= PKTBUF_SIZ) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_UDP_PAYLOAD_TOO_LARGE), - fname, len, PKTBUF_SIZ); - return SIP_ERROR; - } - - while (len > 0) { - bytesSent = cprSendTo(s, (void *)buf, (size_t)len, 0, - (cpr_sockaddr_t *)&sock_addr, addr_len); - - if ((bytesSent == SOCKET_ERROR) && (cpr_errno == CPR_ECONNREFUSED)) { - /* - * Will get socket error ECONNREFUSED after an ICMP message - * resend the message - */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"UDP send to error %d\n", DEB_F_PREFIX_ARGS(SIP_SOCK, fname), cpr_errno); - bytesSent = cprSendTo(s, (void *)buf, (size_t)len, 0, - (cpr_sockaddr_t *)&sock_addr, addr_len); - } - if (bytesSent == SOCKET_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "cprSendTo", cpr_errno); - return SIP_ERROR; - } - - len -= bytesSent; - buf += bytesSent; - } - - return SIP_OK; -} diff --git a/libs/sipcc/core/sipstack/ccsip_pmh.c b/libs/sipcc/core/sipstack/ccsip_pmh.c deleted file mode 100644 index 399de6a993..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_pmh.c +++ /dev/null @@ -1,5751 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Routines that parse SIP messages into individual components - * defined in ccsip_pmh.h. Used by the code that receives the - * messages to decipher them and then effect callstate as - * appropriate. - * Some SIP messages are exactly the same as HTTP/1.1 messages, - * and these are parsed using wrapper functions to those in - * httpish.c - */ - -#include -#include - -#include "plstr.h" -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_in.h" -#include "cpr_memory.h" -#include "ccsip_pmh.h" -#include "phone_debug.h" -#include "ccapi.h" -#include "text_strings.h" -#include "util_string.h" -#include "ccsip_spi_utils.h" -#include "ccsip_callinfo.h" -#include "ccsip_core.h" - -/* Skip linear whitespace */ -#define SKIP_LWS(p) while (*p == SPACE || *p == TAB) { \ - p++; \ - } - -#define SKIP_WHITE_SPACE(p) while (*p == SPACE || *p == TAB || \ - *p == '\n') { \ - p++; \ - } - -#define AUTHENTICATION_BASIC "Basic" -#define AUTHENTICATION_DIGEST "Digest" -#define AUTHENTICATION_REALM "realm" -#define AUTHENTICATION_NONCE "nonce" -#define AUTHENTICATION_URI "uri" -#define AUTHENTICATION_DOMAIN "domain" -#define AUTHENTICATION_ALGORITHM "algorithm" -#define AUTHENTICATION_OPAQUE "opaque" -#define AUTHENTICATION_USERNAME "username" -#define AUTHENTICATION_RESPONSE "response" - - -/* Trim trailing space from end of string */ -static void -trim_right (char *pstr) -{ - char *pend; - - if (!pstr) { - return; - } - - pend = (pstr + (strlen(pstr) - 1)); - while (pend > pstr) { - if (!isspace((int) *pend)) { - break; - } - *pend = '\0'; - pend--; - } -} - -/* - * Remove square brackets from IPv6 address - * - * @param pstr address string - * - * @return none - * - * @pre none - * - */ - -static void trim_ipv6_host(char *pstr) -{ - if (!pstr) { - return; - } - - if (*pstr == '[') { - pstr++; - } - - if (*(pstr + strlen(pstr)-1) == ']') { - *(pstr + strlen(pstr)-1) = '\0'; - } -} - -int parse_errno = 0; - -/* The order of these error messages corresponds to parse error codes - * defined in ccsip_pmh.h - */ -static char *parse_errors[] = { "", - ERROR_1, - ERROR_2, - ERROR_3, - ERROR_4, - ERROR_5, - ERROR_6, - ERROR_7, - ERROR_8 -}; - -/* - * These headers are defined as per the values of Header indexes ( in - * ccsip_protocol.h. To include a header in the cached list, increase - * the HEADER_CACHE_SIZE in httpish.h and add its entry here. Its index - * should be consistent with the index value in ccsip_protocol.h. - * For example, #define VIA 2, implies sip_cached_headers[2] has Via header - * related stuff. - */ -sip_header_t sip_cached_headers[] = { -/* 0 */ {"From", "f"}, -/* 1 */ {"To", "t"}, -/* 2 */ {HTTPISH_HEADER_VIA, "v"}, -/* 3 */ {"Call-ID", "i"}, -/* 4 */ {"CSeq", NULL}, -/* 5 */ {"Contact", "m"}, -/* 6 */ {HTTPISH_HEADER_CONTENT_LENGTH, HTTPISH_C_HEADER_CONTENT_LENGTH}, -/* 7 */ {HTTPISH_HEADER_CONTENT_TYPE, "c"}, -/* 8 */ {"Record-Route", NULL}, -/* 9 */ {"Require", NULL}, -/* 10 */ {"Route", NULL}, -/* 11 */ {"Supported", "k"} -}; - -static boolean -is_dtmf_or_pause (char *digit) -{ - if (!(*digit)) { - return FALSE; - } - switch (*digit) { - case 'A': - case 'B': - case 'C': - case 'D': - case '*': - case '#': - case 'p': - case 'w': - return TRUE; - default: - return FALSE; - } -} - -/* Inefficient ? Somewhat... */ -sipMethod_t -sippmh_get_method_code (const char *method) -{ - sipMethod_t ret = sipMethodInvalid; - - if (method) { - - ret = sipMethodUnknown; - - if (strcmp(method, SIP_METHOD_INVITE) == 0) - ret = sipMethodInvite; - else if (strcmp(method, SIP_METHOD_BYE) == 0) - ret = sipMethodBye; - else if (strcmp(method, SIP_METHOD_ACK) == 0) - ret = sipMethodAck; - else if (strcmp(method, SIP_METHOD_PRACK) == 0) - ret = sipMethodPrack; - else if (strcmp(method, SIP_METHOD_COMET) == 0) - ret = sipMethodComet; - else if (strcmp(method, SIP_METHOD_OPTIONS) == 0) - ret = sipMethodOptions; - else if (strcmp(method, SIP_METHOD_CANCEL) == 0) - ret = sipMethodCancel; - else if (strcmp(method, SIP_METHOD_NOTIFY) == 0) - ret = sipMethodNotify; - else if (strcmp(method, SIP_METHOD_REFER) == 0) - ret = sipMethodRefer; - else if (strcmp(method, SIP_METHOD_SUBSCRIBE) == 0) - ret = sipMethodSubscribe; - else if (strcmp(method, SIP_METHOD_REGISTER) == 0) - ret = sipMethodRegister; - else if (strcmp(method, SIP_METHOD_UPDATE) == 0) - ret = sipMethodUpdate; - else if (strcmp(method, SIP_METHOD_INFO) == 0) - ret = sipMethodInfo; - else if (strcmp(method, SIP_METHOD_PUBLISH) == 0) - ret = sipMethodPublish; - else if (strcmp(method, SIP_METHOD_MESSAGE) == 0) - ret = sipMethodMessage; - else if (strcmp(method, SIP_METHOD_INFO) == 0) - ret = sipMethodInfo; - } - - return ret; -} - -#define SKIP_SIP_TOKEN(inp_str) \ - while (isalnum((int)*inp_str) || *inp_str == DASH || \ - *inp_str == DOT || *inp_str == EXCLAMATION || \ - *inp_str == PERCENT || *inp_str == STAR || \ - *inp_str == UNDERSCORE || *inp_str == PLUS || \ - *inp_str == '`' || *inp_str == SINGLE_QUOTE || \ - *inp_str == COLON || *inp_str == TILDA || \ - *inp_str == AT_SIGN) { \ - inp_str++; \ - } - -static char * -parse_generic_param (char *param, char **param_val) -{ - boolean match_found; - char *tok_start; - - /* - * param is pointing to the first character after the name of the - * parameter. It could be - * white space or - * equal sign or - * semi-colon or - * comma or - * end of string - */ - if (*param == SPACE || *param == TAB) { - *param++ = 0; - SKIP_LWS(param); - } - - if (*param != EQUAL_SIGN) { - /* - * Parameter exists but its value is empty - */ - *param_val = ""; - return param; - } - - *param++ = 0; - SKIP_LWS(param); - *param_val = param; - if (*param == DOUBLE_QUOTE) { - param++; - match_found = FALSE; - while (*param) { - if (*param == DOUBLE_QUOTE && *(param - 1) != ESCAPE_CHAR) { - param++; - match_found = TRUE; - break; - } - param++; - } - if (match_found == FALSE) { - return NULL; - } - } else { - tok_start = param; - SKIP_SIP_TOKEN(param); - if (param == tok_start) { - return NULL; - } - } - return param; -} - -/* - * The syntax of other-param in SIP URL is same as extension-attribute in - * Contact header. A pointer to the start of the token=value or - * token="value" string is returned in other_param_value. This allows - * the calling code to store this value if needed such as in the - * case of supporting contact-extensions. The function returns - * a pointer to the next character to be parsed. - */ -static char * -parse_other_param (char *inp_str, char **other_param_value) -{ - char temp; - char *token_string; - - - SKIP_LWS(inp_str); - token_string = inp_str; - SKIP_SIP_TOKEN(inp_str); - switch (*inp_str) { - case COMMA: - case '\0': - case SEMI_COLON: - /* - * Either we have encountered end of string or another - * parameter follows this other-param. In either case we - * are done with parsing other-param. Since this is - * not in the form of token=value or token="value" discard - * it. - */ - *other_param_value = NULL; - - /* check for loose routing specifier */ - temp = *inp_str; - *inp_str = 0; - if (!cpr_strcasecmp(token_string, "lr")) { - *other_param_value = (char *) cpr_malloc(4); - if (*other_param_value != NULL) { - sstrncpy(*other_param_value, token_string, 4); - } - } - *inp_str = temp; - break; - - case EQUAL_SIGN: - /* It is either token=token form or token=quoted-string form */ - inp_str++; - if (*inp_str == DOUBLE_QUOTE) { - /* quoted-string follows */ - inp_str++; /* skip the " char */ - while (*inp_str) { - if (*inp_str == DOUBLE_QUOTE && *(inp_str - 1) != ESCAPE_CHAR) { - inp_str++; - break; - } - inp_str++; - } - } else { - /* token follows */ - // SKIP_SIP_TOKEN(inp_str); - // Continue until another semicolon is found or end of string is - // reached - while (*inp_str != '\0' && *inp_str != SEMI_COLON) { - inp_str++; - } - } - - /* - * Terminate the string that token_string is pointing - * to while keeping the value of *inp_str unchanged. - * Then assign the null terminated string to other_param_value - */ - *other_param_value = (char *) cpr_malloc(SIP_MAX_OTHER_PARAM_LENGTH + 1 * sizeof(char)); - if (*other_param_value != NULL) { - temp = *inp_str; - *inp_str = 0; - sstrncpy(*other_param_value, token_string, SIP_MAX_OTHER_PARAM_LENGTH); - *inp_str = temp; - } - break; - - default: - CCSIP_DEBUG_ERROR(ERROR_3, "parse_other_param", inp_str); - *other_param_value = NULL; - return NULL; - } - return inp_str; -} - -/* - * This function creates an array of url headers. Each - * element of the array has two member pointers: - * char pointer to header name, - * char pointer to header value - */ -static int -url_add_headers_to_list (char *url_strp, sipUrl_t *sip_url) -{ - char *tmp_ptr = NULL; - char num_head = 1; - char *lasts = NULL; - - if (!url_strp) { - return (PARSE_ERR_NULL_PTR); - } - - tmp_ptr = strchr(url_strp, AMPERSAND); - while (tmp_ptr != NULL) { - num_head++; - tmp_ptr++; - tmp_ptr = strchr(tmp_ptr, AMPERSAND); - } - - sip_url->headerp = (attr_value_pair_t *) - cpr_malloc(sizeof(attr_value_pair_t) * num_head); - if (!sip_url->headerp) { - return (PARSE_ERR_NO_MEMORY); - } - - sip_url->num_headers = num_head; - num_head = 0; - url_strp = PL_strtok_r(url_strp, "&?", &lasts); - while ((url_strp != NULL) && (num_head < sip_url->num_headers)) { - - tmp_ptr = strchr(url_strp, EQUAL_SIGN); - if (!tmp_ptr) { - return (PARSE_ERR_SYNTAX); - } - *tmp_ptr++ = 0; - - sip_url->headerp[(uint16_t)num_head].attr = url_strp; - sip_url->headerp[(uint16_t)num_head].value = tmp_ptr; - - num_head++; - url_strp = PL_strtok_r(NULL, "&", &lasts); - } - - return 0; -} - -static int -parseUrlParams (char *url_param, sipUrl_t *sipUrl, genUrl_t *genUrl) -{ - static const char fname[] = "parseUrlParams"; - char *param_val; - char *url_other_param = NULL; - uint16_t i; - // uint32_t ttl_val; - unsigned long strtoul_result; - char *strtoul_end; - - - /* - * url-parameters = *( ";" url-parameter ) - * url-parameter = transport-param | user-param | method-param - * | ttl-param | maddr-param | other-param - * transport-param = "transport=" ( "udp" | "tcp" | "sctp" | "tls" - * | other-transport ) - * ttl-param = "ttl=" ttl - * ttl = 1*3DIGIT ; 0 to 255 - * maddr-param = "maddr=" host - * user-param = "user=" ( "phone" | "ip" ) - * method-param = "method=" Method - * tag-param = "tag=" UUID - * lr-param = "lr" - * UUID = 1*( hex | "-" ) - * other-param = ( token | ( token "=" ( token | quoted-string ))) - * other-transport = token - */ - - /* - * url_param is pointing to the first character after the ';' - * This routine only prints error message for SYNTAX error, since we - * want to pinpoint the error location. For other errors it simply - * returns the error code. - */ - SKIP_LWS(url_param); - if (*url_param == 0) { - return PARSE_ERR_UNEXPECTED_EOS; - } - while (1) { - if (cpr_strncasecmp(url_param, "transport=", 10) == 0) { - url_param += 10; - SKIP_LWS(url_param); - if (cpr_strncasecmp(url_param, "tcp", 3) == 0) { - sipUrl->transport = TRANSPORT_TCP; - url_param += 3; - } else if (cpr_strncasecmp(url_param, "tls", 3) == 0) { - sipUrl->transport = TRANSPORT_TLS; - url_param += 3; - } else if (cpr_strncasecmp(url_param, "sctp", 4) == 0) { - sipUrl->transport = TRANSPORT_SCTP; - url_param += 4; - } else if (cpr_strncasecmp(url_param, "udp", 3) == 0) { - sipUrl->transport = TRANSPORT_UDP; - url_param += 3; - } else { - SKIP_SIP_TOKEN(url_param); - SKIP_LWS(url_param); - if (*url_param != SEMI_COLON && *url_param != 0) { - CCSIP_DEBUG_ERROR(ERROR_3, fname, url_param); - return PARSE_ERR_SYNTAX; - } - } - } else if (cpr_strncasecmp(url_param, "user=", 5) == 0) { - url_param += 5; - SKIP_LWS(url_param); - if (cpr_strncasecmp(url_param, "phone", 5) == 0) { - sipUrl->is_phone = 1; - url_param += 5; - } else if (cpr_strncasecmp(url_param, "ip", 2) == 0) { - url_param += 2; - } else { - CCSIP_DEBUG_ERROR(ERROR_3, fname, url_param); - return PARSE_ERR_SYNTAX; - } - } else if (cpr_strncasecmp(url_param, "method=", 7) == 0) { - url_param += 7; - SKIP_LWS(url_param); - param_val = url_param; - while (isalpha((int) *url_param)) { - url_param++; - } - if (param_val == url_param) { - return PARSE_ERR_UNEXPECTED_EOS; - } - sipUrl->method = param_val; - /* Note that we have not terminated the method str yet */ - } else if (cpr_strncasecmp(url_param, "ttl=", 4) == 0) { - char save_ch; - - url_param += 4; - SKIP_LWS(url_param); - param_val = url_param; - while (isdigit((int) *url_param)) { - url_param++; - /* Atmost 3 digits allowed in ttl value */ - if ((url_param - param_val) > 3) { - CCSIP_DEBUG_ERROR(ERROR_3, fname, url_param); - return PARSE_ERR_SYNTAX; - } - } - if (url_param == param_val) { - /* Did not find any digit after "ttl=" */ - return PARSE_ERR_UNEXPECTED_EOS; - } - save_ch = *url_param; - *url_param = 0; /* Terminate the string for strtoul */ - - errno = 0; - strtoul_result = strtoul(param_val, &strtoul_end, 10); - - if (errno || param_val == strtoul_end || strtoul_result > MAX_TTL_VAL) { - CCSIP_DEBUG_ERROR(ERROR_7, fname, sipUrl->ttl_val); - return PARSE_ERR_INVALID_TTL_VAL; - } - sipUrl->ttl_val = (unsigned char) strtoul_result; - *url_param = save_ch; /* Restore string state */ - } else if (cpr_strncasecmp(url_param, "maddr=", 6) == 0) { - url_param += 6; - SKIP_LWS(url_param); - param_val = url_param; /* maddr now points to a host */ - while (isalnum((int) *url_param) || *url_param == DOT || - *url_param == DASH) { - url_param++; - } - if (url_param == param_val) { - /* Empty value of maddr */ - return PARSE_ERR_UNEXPECTED_EOS; - } - sipUrl->maddr = param_val; - } else if (cpr_strncasecmp(url_param, "phone-context=", 14) == 0) { - url_param += 14; - SKIP_LWS(url_param); - param_val = url_param; - - while (isalpha((int) *url_param)) { - url_param++; - } - if (param_val == url_param) { - return PARSE_ERR_SYNTAX; - } - - /* If the next character is a space, we want to zero the - * string, otherwise the next character is EOF or ; in - * which case the code below will handle these cases. - */ - if (isspace((int) *url_param)) { - *url_param++ = 0; - } - genUrl->phone_context = param_val; - } else if (cpr_strncasecmp(url_param, "lr", 2) == 0) { - // skip to the following SEMI_COLON or end - while (*url_param && *url_param != SEMI_COLON) { - url_param++; - } - sipUrl->lr_flag = TRUE; - } else { - /* other-param */ - url_param = parse_other_param(url_param, &url_other_param); - - if (url_param == NULL) { - return PARSE_ERR_SYNTAX; - } - - if (url_other_param != NULL) { - /* Store it in first free slot */ - i = 0; - while (i < SIP_MAX_LOCATIONS) { - if (genUrl->other_params[i] == NULL) { - break; - } - i++; - } - - if (i == SIP_MAX_LOCATIONS) { - cpr_free(url_other_param); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"parseUrlParams: Too many unknown parameters" - " in URL of Contact header", fname); - } else { - genUrl->other_params[i] = url_other_param; - url_other_param = NULL; - } - } - } - - SKIP_LWS(url_param); - /* We either expect - end of string or ';' */ - if (*url_param == 0) { - return 0; - } - if (*url_param != SEMI_COLON) { - CCSIP_DEBUG_ERROR(ERROR_3, fname, url_param); - return PARSE_ERR_SYNTAX; - } - *url_param++ = 0; /* Zero the ';' and advance pointer */ - SKIP_LWS(url_param); - if (*url_param == 0) { - return PARSE_ERR_UNEXPECTED_EOS; - } - } -} - - - - -/* - * This routine is based on a very simple and valid assumption. SIP URL can be - * of the following forms (before the parameters, which start with ';') - * My understanding is that it is NOT a context-free grammar - * sip:host - * sip:host:port - * sip:user@host - * sip:user@host:port - * sip:user:password@host - * sip:user:password@host:port - * sip:user:password@[ipv6host]:port - * - * e.g. "1218@[2001:db8:c18:1:211:11ff:feb1:fb65]" - * - * Parse the SIP URL and zero the separators ( @ : ; etc) - * Point fields of sipUrl to appropriate places in the duplicated string - * This saves multiple mallocs for different fields of the sipUrl - * For a SIP URL of the form sip:user:password@host:port;params... - * loc_ptr[0] = Beginning of user part - * loc_ptr[1] = Beginning of password - * loc_ptr[2] = Beginning of host - * loc_ptr[3] = Beginning of port - * loc_ptr[4] = Beginning of parameters - */ -static int -parseSipUrl (char *url_start, genUrl_t *genUrl) -{ - static const char fname[] = "parseSipUrl"; - sipUrl_t *sipUrl = genUrl->u.sipUrl; - char ch = 0; - int token_cnt, separator_cnt; - char *url_main; - char *tokens[4]; - char separator[4]; - char *endptr; - uint16_t port; - boolean parsing_user_part; - char *temp_url; - boolean ipv6_addr = FALSE; - - /* initializing separator */ - separator[0] = '\0'; - - /* - * SIP-URL = "sip:" [ userinfo "@" ] hostport - * url-parameters [ headers ] - * userinfo = user [ ":" password ] - * user = *( unreserved | escaped - * | "&" | "=" | "+" | "$" | "," ) - * password = *( unreserved | escaped - * | "&" | "=" | "+" | "$" | "," ) - * hostport = host [ ":" port ] - * host = hostname | IPv4address | IPv6reference - * IPv6reference = "[" IPv6address "]" - * IPv6address = hexpart [ ":" IPv4address ] - * hexpart = hexseq / hexseq "::" [ hexseq ] / "::" [ hexseq ] - * hexseq = hex4 *( ":" hex4) - * hex4 = 1*4HEXDIG - * port = 1*DIGIT - * hostname = *( domainlabel "." ) toplabel [ "." ] - * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum - * toplabel = alpha | alpha *( alphanum | "-" ) alphanum - * IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit - * port = *digit - */ - - /* Ignore any leading white spaces too, */ - SKIP_LWS(url_start); - - /* we are pointing at whatever is after "sip:" */ - url_main = url_start; - - tokens[0] = url_main; - token_cnt = 0; - separator_cnt = 0; - - /* Scan the string for : and @ and store their pointers. Terminate - * the search when you reach end of string or beginning of parameters - * indicated by ;. However the bis02 version of the spec allows ; in - * the user part of the URL. Thus the code must differentiate between - * a ; in the user part and a ; indicating the start of URL params. - */ - while (1) { - if (*url_main == 0 || *url_main == SEMI_COLON || - *url_main == QUESTION_MARK) { - /* Either end of string or beginning of SIP URL parameters - * or a ; encountered in the user part - */ - parsing_user_part = FALSE; - temp_url = url_main; - while (*temp_url != 0) { - if (*temp_url == AT_SIGN) { - parsing_user_part = TRUE; - break; - } else if (*temp_url == QUESTION_MARK) { - /* overloaded headers in url */ - break; - } - temp_url++; - } - temp_url = NULL; - - if (!parsing_user_part) { - ch = *url_main; - *url_main++ = 0; /* Terminate the current token */ - token_cnt++; - break; - } - } - - /* For IPv6 address colon present so skip that */ - if ((*url_main == COLON && ipv6_addr == FALSE)|| *url_main == AT_SIGN || *url_main == SPACE || - *url_main == TAB) { - - if (*url_main == SPACE || *url_main == TAB) { - *url_main++ = 0; /* Terminate current token */ - SKIP_LWS(url_main); - } - /* - * Now we should be pointing to end of string or a separator - * (even ';' - beginning of parameters - */ - if (*url_main == COLON || *url_main == AT_SIGN) { - if (separator_cnt == 3) { - /* Too many separators */ - CCSIP_DEBUG_ERROR(ERROR_3_1, fname, *url_main); - return PARSE_ERR_SYNTAX; - } - separator[separator_cnt++] = *url_main; - *url_main++ = 0; /* Zero the separator */ - SKIP_LWS(url_main); - - if (*url_main == LEFT_SQUARE_BRACKET) { - *url_main++ = 0; /* Must be IPv6 address */ - ipv6_addr = TRUE; - } - tokens[++token_cnt] = url_main; - if (*url_main == 0) { - break; - } - } - - } else if (*url_main == RIGHT_SQUARE_BRACKET && ipv6_addr == TRUE) { - - *url_main++ = 0; /* Found complete IPv6 address*/ - } else { - url_main++; - } - } - - sipUrl->port = SIP_WELL_KNOWN_PORT; - sipUrl->port_present = FALSE; - - /* token_cnt contains the number of entries in the tokens array */ - switch (token_cnt) { - - case 1: - /* sip:host */ - sipUrl->host = tokens[0]; - break; - - case 2: - if (separator[0] == AT_SIGN) { - /* sip:user@host */ - sipUrl->user = tokens[0]; - sipUrl->host = tokens[1]; - sipUrl->is_ipv6 = ipv6_addr; - } else { - /* sip:host:port */ - sipUrl->host = tokens[0]; - port = (uint16_t) strtol(tokens[1], &endptr, 10); - if (*endptr == 0) { - sipUrl->port = port; - sipUrl->port_present = TRUE; - } else { - sipUrl->port = 0; - } - } - break; - - case 3: - if (separator[0] == separator[1]) { - /* Cannot have 2 successive entries of : or @ */ - CCSIP_DEBUG_ERROR(ERROR_3_1, fname, separator[1]); - return PARSE_ERR_SYNTAX; - } - if (separator[0] == AT_SIGN) { - /* sip:user@host:port */ - sipUrl->user = tokens[0]; - sipUrl->host = tokens[1]; - port = (uint16_t) strtol(tokens[2], &endptr, 10); - if (*endptr == 0) { - sipUrl->port = port; - sipUrl->port_present = TRUE; - } else { - sipUrl->port = 0; - } - } else { - /* sip:user:password@host */ - sipUrl->user = tokens[0]; - sipUrl->password = tokens[1]; - sipUrl->host = tokens[2]; - } - break; - - case 4: - /* sip:user:password@host:port */ - - if (separator[0] == COLON && separator[1] == AT_SIGN && - separator[2] == COLON) { - sipUrl->user = tokens[0]; - sipUrl->password = tokens[1]; - sipUrl->host = tokens[2]; - port = (uint16_t) strtol(tokens[3], &endptr, 10); - if (*endptr == 0) { - sipUrl->port = port; - sipUrl->port_present = TRUE; - } else { - sipUrl->port = 0; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad separator sequence", fname); - return PARSE_ERR_SYNTAX; - } - break; - - } - - /* Remove [ and ] from IPv6 address*/ - trim_ipv6_host(sipUrl->host); - - /* Verify the Port */ - if (sipUrl->port == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received Bad Port", fname); - return PARSE_ERR_SYNTAX; - } - - /* Verify the host portion */ - if (sipSPI_validate_ip_addr_name(sipUrl->host) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received Bad Host", fname); - return PARSE_ERR_SYNTAX; - } - - /* Set default transport to UNSPECIFIED */ - sipUrl->transport = TRANSPORT_UNSPECIFIED; - if (ch == SEMI_COLON) { /* Process URL parameters */ - return parseUrlParams(url_main, sipUrl, genUrl); - } else if (ch == QUESTION_MARK) { /* Process URL headers */ - return url_add_headers_to_list(url_main, sipUrl); - } - return 0; /* SUCCESS */ -} - -/* - * This routine is based on a very simple and valid assumption. TEL URL can be - * of the following forms (before the parameters, which start with ';') - * tel:user - * - * Parse the TEL URL and zero the separators (;) - * Point fields of sipUrl to appropriate places in the duplicated string - * This saves multiple mallocs for different fields of the telUrl - * For a TEL URL of the form tel:user;params... - */ -static int -parseTelUrl (char *url_start, genUrl_t *genUrl) -{ - static const char fname[] = "parseTelUrl"; - char *url_main; - telUrl_t *telUrl = genUrl->u.telUrl; - boolean is_local_subscriber = FALSE; - - /* - * TEL-URL = telephone-scheme ":" telephone-subscriber - * telephone-scheme = "tel" - * telephone-subscriber = global-phone-number/local-phone-number - * global-phone-number = "+" base-phone-number [isdn-subaddress] - * [post-dial] *(area-specifier/service-provider/ - * future-extension) - * base-phone-number = 1*phonedigit - * local-phone-number = 1*(phonedigit / dtmf-digit /pause-character) - * [isdn-subaddress] [post-dial] area-specifier - * *(are-specifier/service-provider/ - * future-extension) - * isdn-subaddress = ";isub=" 1*phonedigit - * post-dial = ";postd=" 1*(phonedigit / dtmf-digit / - * pause-character) - * area-specifier = ";" phone-context-tag "=" phone-context-ident - * phone-context-tag = "phone-context" - * phone-context-ident = network-prefix / private-prefix - * network-prefix = global-network-prefix / local-network-prefix - * global-network-prefix = "+" 1*phonedigit - * local-network-prefix = 1*(phonedigit / dtmf-digit / pause-character) - * private-prefix = (%x21-22 / %x24-27 / %x2C / %x2F / %x3A / - * %x3C-40 /%x45-4F / %x51-56 / %x58-60 / - * %x65-6F / %x71-76 / %x78-7E /) *(%x21-3A / - * %x3C-7E) - * service-provider = ";" provider-tag "=" provider-hostname - * provider-tag = "tsp" - * provider-hostname = domain ; is defined in [RFC1035] - * future-extension = ";" token ["=" token] - * phonedigit = DIGIT / visual-separator - * visual-separator = "-" / "." / "(" / ")" - * pause-character = "p" / "w" - * dtmf-digit = "*" / "#" / "A" / "B" / "C" / "D" - */ - - if (!url_start) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Missing user field", fname); - return PARSE_ERR_SYNTAX; - } - - url_main = url_start; - SKIP_LWS(url_main); - /* - * User field is the only mandatory field. The rest are optional - */ - - if (*url_main == PLUS) { - /* global-phone number */ - url_main++; - telUrl->user = url_main; - - while ((url_main) && ((*url_main == DASH) || - (isdigit((int)*url_main)) || (*url_main == DOT))) { - url_main++; - } - } else { - /* local-phone-number */ - telUrl->user = url_main; - is_local_subscriber = TRUE; - - while ((url_main) && ((is_dtmf_or_pause(url_main)) || - (*url_main == DASH) || (isdigit((int)*url_main)) || - (*url_main == DOT))) { - url_main++; - } - } - if (url_main) { - SKIP_LWS(url_main); - } - if ((url_main) && (!(*url_main))) { - if (!is_local_subscriber) { - return 0; /* no fields to parse */ - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"local-phone-number must have area-specifier", - fname); - return PARSE_ERR_SYNTAX; - } - } - if (url_main) { - if ((*url_main) && (*url_main == SEMI_COLON)) { - *url_main++ = 0; /* skip separator */ - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Need ';' before parameters", fname); - return PARSE_ERR_SYNTAX; - } - } - - while (url_main) { - SKIP_LWS(url_main); - if (cpr_strncasecmp(url_main, "isub=", 5) == 0) { - url_main += 5; - SKIP_LWS(url_main); - telUrl->isdn_subaddr = url_main; - } else if (cpr_strncasecmp(url_main, "postd=", 6) == 0) { - url_main += 6; - SKIP_LWS(url_main); - telUrl->post_dial = url_main; - } else if (cpr_strncasecmp(url_main, "phone-context", 13) == 0) { - url_main += 13; - SKIP_LWS(url_main); - if (*url_main != EQUAL_SIGN) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad syntax in phone_context field", fname); - return PARSE_ERR_SYNTAX; - } - *url_main++ = 0; /* skip "=" */ - SKIP_LWS(url_main); - genUrl->phone_context = url_main; - } else if (cpr_strncasecmp(url_main, "tsp", 3) == 0) { - url_main += 3; - SKIP_LWS(url_main); - if (*url_main != EQUAL_SIGN) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad syntax in service-provider field", fname); - return PARSE_ERR_SYNTAX; - } - *url_main++ = 0; /* skip "=" */ - SKIP_LWS(url_main); - telUrl->unparsed_tsp = url_main; - } else { - /* future extension */ - if (telUrl->future_ext) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Only one future extension allowed", fname); - return PARSE_ERR_SYNTAX; - } - SKIP_LWS(url_main); - url_main = strchr(url_main, EQUAL_SIGN); - if (!url_main) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad field value", fname); - return PARSE_ERR_SYNTAX; - } else { - *url_main++ = 0; - SKIP_LWS(url_main); - telUrl->future_ext = url_main; - } - } - url_main = strchr(url_main, SEMI_COLON); - if (url_main) { - *url_main++ = 0; /* skip and zero separator */ - } - } - if ((is_local_subscriber) && (!genUrl->phone_context)) { - /* local-phone-number must have area-specifier */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"local-phone-number requires area-specifier", fname); - return PARSE_ERR_SYNTAX; - } - return 0; /* Success */ -} - -/* - * Parses a URL - * (eg. "sip:14085266593@sip.cisco.com;transport=UDP;user=phone") - * (eg. "tel:+1-555-555-5555") - * into a usable genUrl_t struct. Memory is created by this function. - * To free first free internal members(sippmh_genurl_free(genUrl)). - * Returns NULL if there is a parse error or malloc fails. Components/tokens - * not found in the URL are set to NULL, unless they have a default value - * defined by the protocol ( for example port 5060 is default) - * Parse error will set parse_errno variable to indicate the error. - * Expects a NULL terminated string in url. - * See comment block before parseSipUrl() and parseTelUrl() - * for some other details. - * - * url - Pointer to URL to be parsed - * dup_flag - Should this URL be duplicated and modified ?? - */ -genUrl_t * -sippmh_parse_url (char *url, boolean dup_flag) -{ - genUrl_t *genUrl; - char *url_main; - uint16_t i; - uint16_t skipValue; - - if (url == NULL) { - return NULL; - } - - genUrl = (genUrl_t *) cpr_calloc(1, sizeof(genUrl_t)); - if (genUrl == NULL) { - return NULL; - } - - /* - * Ensure clean other params pointers - */ - i = 0; - while (i < SIP_MAX_LOCATIONS) { - genUrl->other_params[i] = NULL; - i++; - } - - if (dup_flag) { - url_main = cpr_strdup(url); - if (!url_main) { - cpr_free(genUrl); - return NULL; - } - genUrl->str_start = url_main; - } else { - url_main = url; - } - - SKIP_LWS(url_main); - if (!cpr_strncasecmp(url_main, "sips", 4)) { - genUrl->schema = URL_TYPE_SIP; - genUrl->sips = TRUE; - skipValue = 4; - } else if (!cpr_strncasecmp(url_main, "sip", 3)) { - genUrl->schema = URL_TYPE_SIP; - skipValue = 3; - } else if (!cpr_strncasecmp(url_main, "tel", 3)) { - genUrl->schema = URL_TYPE_TEL; - skipValue = 3; - } else if (!cpr_strncasecmp(url_main, "cid", 3)) { - genUrl->schema = URL_TYPE_CID; - skipValue = 3; - } else { - genUrl->schema = URL_TYPE_UNKNOWN; - skipValue = 0; - } - url_main += skipValue; /* skip "sip", "sips", cid, or "tel" */ - if (*url_main != COLON) { - if (dup_flag) { - cpr_free(genUrl->str_start); - } - cpr_free(genUrl); - return NULL; - } - *url_main++ = 0; /* terminate ":" for schema */ - switch (genUrl->schema) { - case URL_TYPE_CID: - case URL_TYPE_SIP: - genUrl->u.sipUrl = (sipUrl_t *) cpr_calloc(1, sizeof(sipUrl_t)); - if (!genUrl->u.sipUrl) { - if (dup_flag) { - cpr_free(genUrl->str_start); - } - cpr_free(genUrl); - return NULL; - } - parse_errno = parseSipUrl(url_main, genUrl); - if (parse_errno == 0) { - //remove_visual_separators(genUrl); - if (genUrl->u.sipUrl->port == 0) { - /* If no port specified in SIP-URL, then use 5060 */ - genUrl->u.sipUrl->port = SIP_WELL_KNOWN_PORT; - genUrl->u.sipUrl->port_present = FALSE; - } - return genUrl; - } - /* For syntax error, we would already have printed the error msg */ - if (parse_errno != PARSE_ERR_SYNTAX) { - if (parse_errno == PARSE_ERR_NO_MEMORY) { - parse_errno = 0; /* Not really a parse error (out of mem) */ - } else { - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], "sippmh_parse_url"); - } - } - sippmh_genurl_free(genUrl); - return NULL; - case URL_TYPE_TEL: - genUrl->u.telUrl = (telUrl_t *) cpr_calloc(1, sizeof(telUrl_t)); - if (!genUrl->u.telUrl) { - if (dup_flag) { - cpr_free(genUrl->str_start); - } - cpr_free(genUrl); - return NULL; - } - parse_errno = parseTelUrl(url_main, genUrl); - if (parse_errno == 0) { - //remove_visual_separators(genUrl); - return genUrl; - } - /* For syntax error, we would already have printed the error msg */ - if (parse_errno != PARSE_ERR_SYNTAX) { - if (parse_errno == PARSE_ERR_NO_MEMORY) { - parse_errno = 0; /* Not really a parse error (out of mem) */ - } else { - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], "sippmh_parse_url"); - } - } - sippmh_genurl_free(genUrl); - return NULL; - default: - sippmh_genurl_free(genUrl); - return NULL; - } -} - -/* If this is a SIP URL, free the sipUrl_t. If this is - * a telUrl_t free the telUrl_t. Also, free memory allocated by creation - * of the genUrl_t then free the genUrl_t. - */ -void -sippmh_genurl_free (genUrl_t *genUrl) -{ - uint16_t i; - - if (!genUrl) { - return; - } - if (genUrl->str_start) { - cpr_free(genUrl->str_start); - } - if ((genUrl->schema == URL_TYPE_SIP) || - (genUrl->schema == URL_TYPE_CID)) { - if (genUrl->u.sipUrl->headerp) { - cpr_free(genUrl->u.sipUrl->headerp); - } - cpr_free(genUrl->u.sipUrl); - } else if (genUrl->schema == URL_TYPE_TEL) { - cpr_free(genUrl->u.telUrl); - } - - /* Free any "other" parameters that were saved */ - i = 0; - while (i < SIP_MAX_LOCATIONS) { - if (genUrl->other_params[i] != NULL) { - cpr_free(genUrl->other_params[i]); - } - i++; - } - - cpr_free(genUrl); -} - -/* Parse display name: - * "Mr. Watson" - * "Mr. Watson" is the display-name - * Return pointer to the '<' - */ - -static char * -parse_display_name (char *ptr) -{ - static const char fname[] = "parse_display_name"; - - while (*ptr) { - if (*ptr == DOUBLE_QUOTE && *(ptr - 1) != ESCAPE_CHAR) { - /* We reached end of quoted-string, mark end of display name */ - *ptr++ = 0; - SKIP_LWS(ptr); /* Skip spaces till '<' */ - /* ptr should now be pointing to '<' */ - if (*ptr != LEFT_ANGULAR_BRACKET) { - parse_errno = PARSE_ERR_UNMATCHED_BRACKET; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname); - - return NULL; - } - return ptr; - } - ptr++; - } - - parse_errno = PARSE_ERR_UNTERMINATED_STRING; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname); - - return NULL; /* Unmatched " */ -} - - -/* - * Parse the name-addr form or the addr-spec form. These parse entities can - * be present in the From, To and Contact headers. So it is called either - * by sippmh_parse_contact() or sippmh_parse_from_or_to(). - * - * input_loc_ptr - Pointer to the string to be parsed - * dup_flag - Should the input string be duplicated before parsing - * more_ptr - Return pointer to the next - * Tokens are extracted in place, i.e. we do not do a strdup for every token. - * We have on string and the output struct has pointers pointing to various - * tokens in the string. - * Note that this routine relies on the caller setting parse_errno to 0 - * before calling. - * - * input_loc_ptr - Pointer to input string to be parsed - * start_ptr - Pointer to beginning of the string, which will be used for - * cleanup. - * dup_flag - Should the input string be duplicated before parsing - * name_addr_only_flag - If TRUE, means only name-addr form is allowed - * more_ptr - Return pointer to start of remaining string ( string that - * remains after parsing name-addr or addr-spec - * - * Output: A pointer to a valid SIP location OR - * NULL (in case of error) - * - */ -sipLocation_t * -sippmh_parse_nameaddr_or_addrspec (char *input_loc_ptr, - char *start_ptr, - boolean dup_flag, - boolean name_addr_only_flag, - char **more_ptr) -{ - const char *fname = "sippmh_parse_nameaddr_or_addrspec"; - char *addr_param; - char *loc_ptr, *addr_spec, *left_bracket; - sipLocation_t *sipLoc = NULL; - char *right_bracket = NULL; - char save_ch = 0; - char *displayNameStart; - - *more_ptr = NULL; - - /* - * name-addr = [ display-name ] "<" addr-spec ">" - * addr-spec = SIP-URL | URI - * display-name = *token | quoted-string - */ - if (dup_flag) { - /* Duplicate the string and work with it */ - start_ptr = loc_ptr = cpr_strdup(input_loc_ptr); - if (loc_ptr == NULL) { - return NULL; - } - } else { - loc_ptr = input_loc_ptr; - } - - if (*loc_ptr == DOUBLE_QUOTE) { - displayNameStart = loc_ptr + 1; - left_bracket = parse_display_name(loc_ptr + 1); - if (left_bracket == NULL) { - /* Could not find matching " or reached end of string or could not - * find < - */ - if (dup_flag) { - cpr_free(loc_ptr); - } - /* parse_display_name has already set the parse_errno */ - - return NULL; - } - } else { - - displayNameStart = loc_ptr; - /* Either we have token(s) preceding '<' or start of addr-spec */ - left_bracket = strpbrk(loc_ptr, ",<"); - if (left_bracket) { - if (*left_bracket == COMMA) { - *left_bracket = 0; - *more_ptr = left_bracket; - left_bracket = NULL; - save_ch = COMMA; - } - } else { - *more_ptr = NULL; - } - } - - sipLoc = (sipLocation_t *) cpr_calloc(1, sizeof(sipLocation_t)); - if (sipLoc == NULL) { - if (dup_flag) { - cpr_free(loc_ptr); - } - return NULL; - } - sipLoc->loc_start = start_ptr; /* Save pointer to start of allocated mem */ - - if (left_bracket) { - /* This is a name-addr form */ - - *left_bracket = 0; /* Terminate the display-name portion */ - sipLoc->name = displayNameStart; - addr_spec = left_bracket + 1; - right_bracket = strchr(addr_spec, RIGHT_ANGULAR_BRACKET); - if (right_bracket == NULL) { - if (dup_flag) { - cpr_free(loc_ptr); - } - cpr_free(sipLoc); - parse_errno = PARSE_ERR_UNMATCHED_BRACKET; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], - "sippmh_parse_nameaddr_or_addrspec"); - return NULL; - } - - /* Terminate the addr_spec at the > */ - *right_bracket++ = 0; - - /* Look for the next non-whitespace character */ - SKIP_LWS(right_bracket); - *more_ptr = right_bracket; - } else { - - /* This is addr-spec format */ - - if (name_addr_only_flag) { - if (dup_flag) { - cpr_free(loc_ptr); - } - cpr_free(sipLoc); - CCSIP_ERR_DEBUG { - buginf("\n%s: Bad name-addr format", fname); - } - return NULL; - } - - addr_spec = loc_ptr; - /* In addr-spec form, it is illegal to have URL special - * chars such as SEMI_COLON, QUESTION MARK - */ - addr_param = addr_spec; - while (*addr_param) { - if (*addr_param == QUESTION_MARK || *addr_param == SEMI_COLON) { - - if ((save_ch != 0) && *more_ptr) { - /* restore the saved char mostly COMMA */ - **more_ptr = save_ch; - } - - save_ch = *addr_param; - *more_ptr = addr_param; - - /* Terminate the addr-spec form at Special char */ - *addr_param = 0; - break; - } - addr_param++; - } - } - - sipLoc->genUrl = sippmh_parse_url(addr_spec, FALSE); - if (sipLoc->genUrl == NULL) { - if (dup_flag) { - cpr_free(loc_ptr); - } - cpr_free(sipLoc); - /* sippmh_parse_url would have set the parse_errno */ - return NULL; - } - - /* - * There is more stuff to follow since *more_ptr is not NULL - * replace the special chars (such as ? or ;) in original string - */ - if ((save_ch != 0) && (*more_ptr != NULL)) { - **more_ptr = save_ch; - } - return sipLoc; -} - - -/* - * Validate the tag. The tag is composed of tokens. The tag_ptr - * points to the start of the tag and a list of semicolon - * separated addr-extensions or just the tag itself. - * - * Returns 0 (no error) if the tag is valid, else - * returns PARSE_ERR_SYNTAX. - * - */ -static int -validate_tag (sipLocation_t *sipLoc, char *tag_ptr) -{ - static const char fname[] = "validate_tag"; - int ret_val = 0; - char *term_ptr; - - /* Skip "tag=", points to value */ - tag_ptr += 4; - SKIP_LWS(tag_ptr); - if (*tag_ptr == 0) { - ret_val = PARSE_ERR_UNEXPECTED_EOS; - CCSIP_ERR_DEBUG { - buginf(parse_errors[ret_val], fname); - } - - return ret_val; - } - - sipLoc->tag = tag_ptr; - - /* Walk the string until we encounter a non-token - * character. The only valid character at the end of - * string is either semicolon or end-of-line. - */ - - SKIP_SIP_TOKEN(tag_ptr); - term_ptr = tag_ptr; - /* skip trailing spaces */ - SKIP_LWS(tag_ptr); - if ((*tag_ptr != SEMI_COLON) && (*tag_ptr != 0)) { - ret_val = PARSE_ERR_SYNTAX; - CCSIP_ERR_DEBUG { - buginf(parse_errors[ret_val], fname, tag_ptr); - } - } else { - /* terminate the tag */ - *term_ptr = 0; - } - - return ret_val; -} - - -sipLocation_t * -sippmh_parse_from_or_to (char *input_loc_ptr, boolean dup_flag) -{ - static const char fname[] = "sippmh_parse_from_or_to"; - char *more_ptr; - sipLocation_t *sipLoc; - boolean tag_found = FALSE; - char *lasts = NULL; - - /* - * From = ( "From" | "f" ) ":" ( name-addr | addr-spec ) - * *( ";" addr-params ) - * addr-params = tag-param | addr-extension - * tag-param = "tag=" token - * addr-exten = token = ["=" (token | quoted-string)] - * - * NOTE: Only the tag parameter in the addr-params is relevant to - * SIP so we skip all addr-extensions when parsing addr-params. - */ - - parse_errno = 0; - more_ptr = NULL; - sipLoc = sippmh_parse_nameaddr_or_addrspec(input_loc_ptr, input_loc_ptr, - dup_flag, FALSE, &more_ptr); - - if (sipLoc) { /* valid sipLocation */ - - if (more_ptr == NULL) { - return sipLoc; - } - - /* initialize the tag */ - sipLoc->tag = NULL; - if (*more_ptr == SEMI_COLON) { - *more_ptr++ = 0; - more_ptr = PL_strtok_r(more_ptr, ";", &lasts); - /* if we had a ; without any addr-params */ - if (more_ptr == NULL) { - parse_errno = PARSE_ERR_UNEXPECTED_EOS; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname); - } else { - /* parse the tag but skip any addr-extensions */ - while (more_ptr && tag_found == FALSE) { - SKIP_LWS(more_ptr); - if (strncmp(more_ptr, "tag=", 4) == 0) { - tag_found = TRUE; - parse_errno = validate_tag(sipLoc, more_ptr); - } else { - more_ptr = PL_strtok_r(NULL, ";", &lasts); - } - } - } - - } else if (*more_ptr) { - parse_errno = PARSE_ERR_SYNTAX; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname, more_ptr); - } - } - - if (parse_errno) { - sippmh_free_location(sipLoc); - sipLoc = NULL; - } - - return sipLoc; -} - -void -sippmh_free_location (sipLocation_t * sipLoc) -{ - if (sipLoc) { - cpr_free(sipLoc->loc_start); - /* make sure to free contents in genUrl_t. */ - sippmh_genurl_free(sipLoc->genUrl); - cpr_free(sipLoc); - } -} - -static char * -sippmh_parse_contact_params (char *params, sipContactParams_t *contact_params) -{ - char *param_value; - char *contact_other_param = NULL; - boolean good_params; - boolean good_qval; - char tmp_char; - - - /* - * contact-params = "q" "=" qvalue - * | "action" "=" "proxy" | "redirect" - * | "expires" "=" delta-seconds | <"> SIP-date <"> - * | extension-attribute - * - * params is pointing to first character after ';' - */ - SKIP_LWS(params); - if (*params == 0) { - return params; - } - while (1) { - good_params = FALSE; - - /* Parse qval parameter */ - if (*params == 'q' || *params == 'Q') { - params++; - SKIP_LWS(params); - if (*params == EQUAL_SIGN) { - params++; - SKIP_LWS(params); - if (*params) { - param_value = params; - good_qval = TRUE; - tmp_char = *params; - /* the qval must be in one of these forms */ - if ((!strncmp(params, "0", 1)) || - (!strncmp(params, "1", 1))) { - params++; /* move up to "." if present */ - if (*params == DOT) { - params++; - if (isdigit((int) *params)) { - while (isdigit((int) *params)) { - if ((tmp_char == '1') && - (*params != '0')) { - good_qval = FALSE; - break; - } - params++; - } - } else { - good_qval = FALSE; - } - } else if (((*params)) && ((*params != SPACE) && - (*params != SEMI_COLON) && - (*params != TAB))) { - good_qval = FALSE; - } - } else { - good_qval = FALSE; - } - if (good_qval) { - good_params = TRUE; - contact_params->qval = param_value; - if (*params == SPACE || *params == TAB) { - *params++ = 0; /* Terminate the qval */ - } - } - } - } - - /* Parse action paramater */ - } else if (cpr_strncasecmp(params, "action", 6) == 0) { - params += 6; - SKIP_LWS(params); - if (*params == EQUAL_SIGN) { - params++; - SKIP_LWS(params); - if (cpr_strncasecmp(params, "proxy", 5) == 0) { - contact_params->action = PROXY; - params += 5; - good_params = TRUE; - } else if (cpr_strncasecmp(params, "redirect", 8) == 0) { - contact_params->action = REDIRECT; - params += 8; - good_params = TRUE; - } - } - - /* Parse expires paramater */ - } else if (cpr_strncasecmp(params, "expires", 7) == 0) { - params += 7; - SKIP_LWS(params); - if (*params == EQUAL_SIGN) { - params++; - SKIP_LWS(params); - if (*params) { - char save_ch; - boolean is_int = FALSE; - - /* Expires can be given in delta seconds or date format. - * If date is used, the date must be enclosed in quotes. - * IOS does not use this parameter, but the SIP phones - * do. - */ - contact_params->expires_gmt = '\0'; - good_params = TRUE; - param_value = params; - while (isdigit((int) *params)) { - params++; - is_int = TRUE; - } - if (is_int == TRUE) { - save_ch = *params; - *params = 0; /* terminate the string for strtoul */ - contact_params->expires = strtoul(param_value, NULL, 10); - *params = save_ch; - } else { - /* expires may be in SIP-date format */ - char *gmt_str; - - if (*params == DOUBLE_QUOTE) { /* skip the quote */ - params++; - } - if ((gmt_str = strstr(params, "GMT")) != NULL) { - contact_params->expires_gmt = params; - params = gmt_str + 3; - contact_params->expires = 0; - - if (*params == SPACE || *params == TAB || *params == DOUBLE_QUOTE) { - *params++ = '\0'; - } - } - } - } - } - /* Parse x-cisco-newreg */ - } else if (cpr_strncasecmp(params, REQ_CONT_PARAM_CISCO_NEWREG, - sizeof(REQ_CONT_PARAM_CISCO_NEWREG) - 1) == 0) { - /* - * x-cisco-newreg in the contact is set by CCM in the 200 OK - * response to the 1st. line registration message as information - * only to the endpoint that its registration is a new - * registration to the CCM. - */ - - /* - * Move parameter pointer pass this parm (-1 is to exclude - * null terminating character of the parameter name). - */ - params += sizeof(REQ_CONT_PARAM_CISCO_NEWREG) - 1; - good_params = TRUE; - contact_params->flags |= SIP_CONTACT_PARM_X_CISCO_NEWREG; - - /* Parse contact-extension paramater */ - } else { - if (params) { - params = parse_other_param(params, &contact_other_param); - if (params) { - good_params = TRUE; - /* - * Contact extensions are not supported. Throw away - * any that were just parsed. - */ - if (contact_other_param != NULL) { - cpr_free(contact_other_param); - } - } - } - } - if (good_params == FALSE) { - parse_errno = PARSE_ERR_SYNTAX; - return params; - } - SKIP_LWS(params); - if (*params == SEMI_COLON) { - /* More parameters follow */ - *params++ = 0; - SKIP_LWS(params); - } else { - /* Either we have encountered end of string or start of next - * location in this contact header. - */ - return params; - } - } -} - -/* Parses limit parameter for CC-Diversion or CC-Redirect - * header. The parsed value is in sipDiversion_t structure. - * Returns pointer to remaining characters in the buffer, if fails NULL - */ -static char * -sippmh_parse_limit_params (char *limit_t, sipDiversion_t *sipdiversion) -{ - boolean params_good = FALSE; - char save_ch; - char *param_value = NULL; - int digit_count = 0; - - if ((limit_t == NULL) || (sipdiversion == NULL)) { - return NULL; - } - - SKIP_LWS(limit_t); - if (*limit_t == EQUAL_SIGN) { - limit_t++; - SKIP_LWS(limit_t); - if (*limit_t) { - params_good = TRUE; - param_value = limit_t; - while (isdigit((int) *limit_t)) { - digit_count++; - limit_t++; - } - if (digit_count > 2) { - /* More than two digits */ - params_good = FALSE; - return NULL; - } - digit_count = 0; - save_ch = *limit_t; - *limit_t = 0; - sipdiversion->limit = strtoul(param_value, NULL, 10); - *limit_t = save_ch; - } - } else { - /* Equal to sign missing */ - params_good = FALSE; - } - - if (params_good) { - return limit_t; - } else { - return NULL; - } -} - - -/* Parses counter parameter for CC-Diversion or CC-Redirect - * header. The parsed value is in sipDiversion_t structure. - * Returns pointer to remaining characters in the buffer, if fails NULL - */ -static char * -sippmh_parse_counter_params (char *counter_t, sipDiversion_t *sipdiversion) -{ - boolean params_good = FALSE; - char save_ch; - char *param_value = NULL; - int digit_count = 0; - - if ((counter_t == NULL) || (sipdiversion == NULL)) { - return NULL; - } - - SKIP_LWS(counter_t); - if (*counter_t == EQUAL_SIGN) { - counter_t++; - SKIP_LWS(counter_t); - if (*counter_t) { - params_good = TRUE; - param_value = counter_t; - while (isdigit((int) *counter_t)) { - digit_count++; - counter_t++; - } - if (digit_count > 2) { - /* More than two digits */ - params_good = FALSE; - return NULL; - } - digit_count = 0; - save_ch = *counter_t; - *counter_t = 0; - sipdiversion->counter = strtoul(param_value, NULL, 10); - *counter_t = save_ch; - - } - } else { - /* Equal to sign missing */ - params_good = FALSE; - } - - if (params_good) { - return counter_t; - } else { - return NULL; - } -} - - -static boolean -sippmh_parse_diversion_params (char *diversion_t, sipDiversion_t *sipdiversion) -{ - - while (1) { - /* Parsing diversion-reason parameter */ - if (strncasecmp(diversion_t, DIVERSION_REASON, 6) == 0) { -// We don't use reason parameter, so comment out at this time. -// diversion_t += 6; -// if ((diversion_t = sippmh_parse_reason_params(diversion_t, sipdiversion)) == NULL) -// return FALSE; - /* - * Since we do not use reason parameter, search for semi-colan to mark - * start of next parameter. If no semi-colon, then we are done. - */ - diversion_t = strchr(diversion_t, SEMI_COLON); - if (diversion_t == NULL) { - // End of parameter list - return TRUE; - } - /* Parse diversion-limit parameter */ - } else if (strncasecmp(diversion_t, DIVERSION_LIMIT, 5) == 0) { - diversion_t += 5; - if ((diversion_t = sippmh_parse_limit_params(diversion_t, sipdiversion)) == FALSE) - return FALSE; - - /* Parse diversion-counter parameter */ - } else if (strncasecmp(diversion_t, DIVERSION_COUNTER, 7) == 0) { - diversion_t += 7; - if ((diversion_t = sippmh_parse_counter_params(diversion_t, sipdiversion)) == FALSE) - return FALSE; - - /* Parse diversion-privacy parameter */ - } else if (strncasecmp(diversion_t, DIVERSION_PRIVACY, 7) == 0) { - diversion_t += 7; - if ((diversion_t = parse_generic_param(diversion_t, &(sipdiversion->privacy))) == NULL) - return FALSE; - - /* Parse diversion-screen parameter */ - } else if (strncasecmp(diversion_t, DIVERSION_SCREEN, 6) == 0) { - diversion_t += 6; - if ((diversion_t = parse_generic_param(diversion_t, &(sipdiversion->screen))) == NULL) - return FALSE; - } - - SKIP_LWS(diversion_t); - if (*diversion_t == SEMI_COLON) { - /* More parameters follow */ - *diversion_t++ = 0; - SKIP_LWS(diversion_t); - } else { - break; - } - } - - return TRUE; - -} - -sipDiversion_t * -sippmh_parse_diversion (const char *diversion, char *diversionhead) -{ - char *param_ptr; - sipDiversion_t *sipdiversion; - sipLocation_t *sipLoc; - char *diversion_t, *start_ptr; - - /* CC-Diversion = "CC-Diversion" - * *(diversion-params [comment]) - * diversion-params = diversion-addr | diversion-reason | - * diversion-counter| diversion-limit - * diversion-addr = (name-addr | addr-spec)*(";"addr-params) - * diversion-reason = "reason"= "unknown" | "user-busy" | "no-answer" | - * "unconditional" | "deflection"| "follow-me" | - * "out-of-service" | " time-of-day" | "unavailable" | - * "do-not-disturb" - * diversion-counter = "counter" = 2*DIGIT - * diversion-limit = "limit" = 2*DIGIT - */ - - /* - * Diversion = "Diversion" ":" 1# (name-addr *( ";" diversion_params )) - * diversion-params = diversion-reason | diversion-counter | - * diversion-limit | diversion-privacy | - * diversion-screen | diversion-extension - * diversion-reason = "reason" "=" - * ( "unknown" | "user-busy" | "no-answer" | - * "unavailable" | "unconditional" | - * "time-of-day" | "do-not-disturb" | - * "deflection" | "follow-me" | - * "out-of-service" | "away" | - * token | quoted-string ) - * diversion-counter = "counter" "=" 1*2DIGIT - * diversion-limit = "limit" "=" 1*2DIGIT - * diversion-privacy = "privacy" "=" ( "full" | "name" | - * "uri" | "off" | token | quoted-string ) - * diversion-screen = "screen" "=" ( "yes" | "no" | token | - * quoted-string ) - * diversion-extension = token ["=" (token | quoted-string)] - */ - - sipdiversion = (sipDiversion_t *) cpr_calloc(1, sizeof(sipDiversion_t)); - if (sipdiversion == NULL) { - return NULL; - } - - diversion_t = cpr_strdup(diversion); - - if (diversion_t == NULL) { - sippmh_free_diversion(sipdiversion); - return NULL; - } - - start_ptr = diversion_t; - - do { - - param_ptr = NULL; - sipLoc = sippmh_parse_nameaddr_or_addrspec(diversion_t, start_ptr, FALSE, FALSE, - ¶m_ptr); - if (sipLoc == NULL) { - cpr_free(start_ptr); - sippmh_free_diversion(sipdiversion); - sipdiversion = NULL; - break; - } - - sipdiversion->locations = sipLoc; - - if (param_ptr == NULL || *param_ptr == 0) { - /* No params */ - break; - } - diversion_t = param_ptr; - if (*diversion_t == SEMI_COLON) { - /* Parsing Diversion Headers */ - *diversion_t++ = 0; - - if ((strncasecmp(diversionhead, SIP_HEADER_DIVERSION, - sizeof(SIP_HEADER_DIVERSION)) == 0) || - (strncasecmp(diversionhead, SIP_HEADER_CC_DIVERSION, - sizeof(SIP_HEADER_CC_DIVERSION)) == 0)) { - - if (sippmh_parse_diversion_params(diversion_t, sipdiversion) == FALSE) { - - CCSIP_ERR_DEBUG { - buginf("\nsippmh_parse_diversion: syntax error in Diversion header"); - } - parse_errno = PARSE_ERR_SYNTAX; - sippmh_free_diversion(sipdiversion); - sipdiversion = NULL; - break; - } - } - /* Must reach here after parsing all parameters */ - break; /* break out of original do loop */ - } else { - CCSIP_ERR_DEBUG { - buginf("\nsippmh_parse_diversion: syntax error missing " - "semicolon in Diversion header"); - } - parse_errno = PARSE_ERR_SYNTAX; - sippmh_free_diversion(sipdiversion); - sipdiversion = NULL; - break; - } - - } while (1); - return sipdiversion; -} - -void -sippmh_free_diversion (sipDiversion_t * ccr) -{ - if (ccr) { - if (ccr->locations) { - sippmh_free_location(ccr->locations); - } - cpr_free(ccr); - } -} - - -sipContact_t * -sippmh_parse_contact (const char *input_contact) -{ - int j, k; - char *contact = NULL, *start_ptr = NULL; - char *more_ptr; - sipContact_t *sipContact; - sipContactParams_t params; - - /* - * Contact = ( "Contact" | "m" ) ":" - * ("*" | (1# (( name-addr | addr-spec ) - * [ *( ";" contact-params ) ] [ comment ] ))) - * name-addr = [ display-name ] "<" addr-spec ">" - * addr-spec = SIP-URL | URI - * display-name = *token | quoted-string - * - * contact-params = "q" "=" qvalue - * | "action" "=" "proxy" | "redirect" - * | "expires" "=" delta-seconds | <"> SIP-date <"> - * | extension-attribute - * - */ - parse_errno = 0; - contact = cpr_strdup(input_contact); - if (contact == NULL) { - return NULL; - } - - sipContact = (sipContact_t *) cpr_calloc(1, sizeof(sipContact_t)); - if (sipContact == NULL) { - cpr_free(contact); - return NULL; - } - - memset(¶ms, 0, sizeof(sipContactParams_t)); - - start_ptr = contact; - - do { - sipLocation_t *sipLoc; - - more_ptr = NULL; - sipLoc = sippmh_parse_nameaddr_or_addrspec(contact, start_ptr, FALSE, - FALSE, &more_ptr); - if (sipLoc == NULL) { - if ((more_ptr != NULL) && (*more_ptr == COMMA)) { - /* Another location follows */ - contact = more_ptr; - *contact++ = 0; - SKIP_LWS(contact); - if (sipContact->num_locations == SIP_MAX_LOCATIONS) { - CCSIP_ERR_DEBUG { - buginf("\nsippmh_parse_contact: Too many location headers" - " in Contact header"); - } - /* go with what we have */ - break; - } - continue; - } else { - if (sipContact->num_locations == 0) { - // Free start_ptr only if we fail the first location - // For the others, it will be freed when sipContact is - // freed - cpr_free(start_ptr); - } - sippmh_free_contact(sipContact); - sipContact = NULL; - break; - } - } - if (sipContact->num_locations) { - sipLoc->loc_start = NULL; - } - if (more_ptr == NULL || *more_ptr == 0) { - /* No params, means no qval and assume lowest priority */ - sipContact->locations[sipContact->num_locations++] = sipLoc; - break; - } - contact = more_ptr; - /* - * At this point, either contact is pointing to - * 1) ';' - Contact params - * 2) ',' - Beginning of next location - * 3) End of string - * 4) Any other character is syntax error - */ - - j = sipContact->num_locations; /* By default insert at the end */ - params.qval = ""; - - if (*contact == SEMI_COLON) { - /* Now parse the Contact params */ - *contact++ = 0; - params.flags = 0; - contact = sippmh_parse_contact_params(contact, ¶ms); - /* - * Now, do an insertion sort on this list (qval is the key). - * Higher values of q come first. - */ - for (j = 0; j < sipContact->num_locations; ++j) { - if (strcmp(params.qval, sipContact->params[j].qval) > 0) { - for (k = sipContact->num_locations; k > j; --k) { - sipContact->locations[k] = sipContact->locations[k - 1]; - sipContact->params[k] = sipContact->params[k - 1]; - } - break; - } - } - /* At this point j points to the entry to use */ - } - - sipContact->params[j] = params; - sipContact->locations[j] = sipLoc; - sipContact->num_locations++; - - if (contact && *contact == COMMA) { - /* Another location follows */ - *contact++ = 0; - SKIP_LWS(contact); - if (sipContact->num_locations == SIP_MAX_LOCATIONS) { - CCSIP_ERR_DEBUG { - buginf("\nsippmh_parse_contact: Too many location headers" - " in Contact header"); - } - /* go with what we have */ - break; - } - } else { - if (contact && *contact) { - parse_errno = PARSE_ERR_SYNTAX; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], "sippmh_parse_contact", - contact); - sippmh_free_contact(sipContact); - sipContact = NULL; - } - break; - } - } while (1); - - if (sipContact) { - sipContact->new_flag = TRUE; - } - return sipContact; -} - - -void -sippmh_free_contact (sipContact_t *sc) -{ - int i; - - if (sc) { - for (i = 0; i < sc->num_locations; ++i) { - if (sc->locations[i]->loc_start) { - /* Free the entire header value that we duplicated */ - cpr_free(sc->locations[i]->loc_start); - } - /* Free the genUrl_t struct in the sipLocation_t */ - sippmh_genurl_free(sc->locations[i]->genUrl); - /* Free the sipLocation_t struct */ - cpr_free(sc->locations[i]); - } - - /* Free the sipContact_t struct */ - cpr_free(sc); - } -} - -static boolean -parse_via_params (char *str, sipVia_t *sipVia) -{ - char **ptr; - - /* str is currently pointing to beginning of parameters */ - - while (1) { - /* To be friendly, skip leading spaces */ - SKIP_LWS(str); - if (strncasecmp(str, VIA_HIDDEN, 6) == 0) { - str += 6; - sipVia->flags |= VIA_IS_HIDDEN; - ptr = NULL; - } else if (strncasecmp(str, VIA_TTL, 3) == 0) { - str += 3; - ptr = &(sipVia->ttl); - } else if (strncasecmp(str, VIA_MADDR, 5) == 0) { - str += 5; - ptr = &(sipVia->maddr); - } else if (strncasecmp(str, VIA_RECEIVED, 8) == 0) { - str += 8; - ptr = &(sipVia->recd_host); - } else if (strncasecmp(str, VIA_BRANCH, 6) == 0) { - str += 6; - ptr = &(sipVia->branch_param); - } else { - ptr = NULL; - } - if (ptr) { - if (*ptr) { - /* ptr already points to something - * -- duplicate param found */ - return FALSE; - } - SKIP_LWS(str); /* Skip spaces till equal sign */ - if (*str == EQUAL_SIGN) { - str++; - SKIP_LWS(str); - *ptr = str; - } - } - str = strpbrk(str, ";,"); - if (str == NULL) { - if (ptr && *ptr) { - trim_right(*ptr); - } - return TRUE; - } - if (*str == COMMA) { - *str++ = 0; - SKIP_LWS(str); - sipVia->more_via = str; - if (ptr && *ptr) { - trim_right(*ptr); - } - return TRUE; - } - *str++ = 0; /* Zero ';' and advance pointer */ - if (ptr && *ptr) { - trim_right(*ptr); - } - } -} - -sipVia_t * -sippmh_parse_via (const char *input_via) -{ - static const char fname[] = "sippmh_parse_via"; - char *via; - char *separator; - sipVia_t *sipVia; - char *endptr; - char *port_num_str; - uint16_t port_num; - - /* - * Via = ( "Via" | "v") ":" 1#( sent-protocol sent-by - * *( ";" via-params ) [ comment ] ) - * via-params = via-hidden | via-ttl | via-maddr - * | via-received | via-branch - * via-hidden = "hidden" - * via-ttl = "ttl" "=" ttl - * via-maddr = "maddr" "=" maddr - * via-received = "received" "=" host - * via-branch = "branch" "=" token - * sent-protocol = protocol-name "/" protocol-version "/" transport - * protocol-name = "SIP" | token - * protocol-version = token - * transport = "UDP" | "TCP" | "TLS" | token - * sent-by = ( host [ ":" port ] ) | ( concealed-host ) - * concealed-host = token - * ttl = 1*3DIGIT ; 0 to 255 - */ - - parse_errno = PARSE_ERR_SYNTAX; - if (input_via == NULL) { - return NULL; - } - sipVia = NULL; - via = NULL; - SKIP_LWS(input_via); - do { - if (strncasecmp(input_via, "SIP", 3)) { - /* Unknown protocol-name */ - break; - } - input_via += 3; - - SKIP_LWS(input_via); - if (*input_via != '/') { - break; - } - input_via++; /* Skip '/' */ - - SKIP_LWS(input_via); - /* input_via should now be pointing to version */ - - /* Duplicate the string and work with it */ - via = cpr_strdup(input_via); - if (via == NULL) { - parse_errno = 0; - return NULL; - } - /* Allocate sipVia_t struct */ - sipVia = (sipVia_t *) cpr_calloc(1, sizeof(sipVia_t)); - if (sipVia == NULL) { - parse_errno = 0; - cpr_free(via); - return NULL; - } - - /* version also points to the start of memory allocated */ - sipVia->version = via; - if (strncmp(via, "2.0", 3)) { - break; - } - via += 3; /* Go past version */ - - SKIP_LWS(via); - if (*via != '/') { - break; - } - *via++ = 0; /* Terminate version string and go past '/' */ - - SKIP_LWS(via); /* Point to transport */ - sipVia->transport = via; - if (strncasecmp(via, "UDP", 3) && strncasecmp(via, "TCP", 3) && - strncasecmp(via, "TLS", 3)) { - /* Invalid transport */ - break; - } - via += 3; /* Go past the transport string */ - *via++ = 0; /* Terminate transport string and advance pointer */ - - - /* Skip blanks */ - SKIP_LWS(via); - if (*via == 0) { - parse_errno = PARSE_ERR_UNEXPECTED_EOS; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname); - break; - } - - parse_errno = 0; - - } while (0); - - if (parse_errno) { - if (parse_errno == PARSE_ERR_SYNTAX) { - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], fname, via ? via : input_via); - } - sippmh_free_via(sipVia); - return NULL; - } - - port_num_str = SIP_WELL_KNOWN_PORT_STR; - sipVia->host = via; - /* - * Either we can have a ':' followed by port - * or start of parameters signalled by ';' - * or end of this Via indicated by ',' - */ - if (*via == '[') { - /* IPv6 address */ - sipVia->host = via; - sipVia->is_ipv6 = TRUE; - separator = strpbrk(via, "]"); - - if (separator && *separator == ']') { - separator++; - } - } else { - - separator = via; - } - - if (separator) { - separator = strpbrk(separator, ":;,"); - } - if (separator) { - if (*separator == COLON) { - /* Port number follows */ - *separator++ = 0; - port_num_str = separator; - separator = strpbrk(separator, ";,"); - } - if (separator) { - if (*separator == SEMI_COLON) { - *separator++ = 0; - /* Parameters follow */ - if (parse_via_params(separator, sipVia) == FALSE) { - CCSIP_ERR_DEBUG - buginf("%s: Duplicate params in Via\n", fname); - sippmh_free_via(sipVia); - return NULL; - } - } else { - *separator++ = 0; - SKIP_LWS(separator); - sipVia->more_via = separator; - } - } - } - - /* Validate the host portion */ - if ((sipSPI_validate_ip_addr_name(sipVia->host) == FALSE)) { - CCSIP_ERR_DEBUG buginf("\n%s: Invalid host in Via", fname); - sippmh_free_via(sipVia); - return NULL; - } - - /* Fix host portion */ - trim_right(sipVia->host); - /* Fix IPv6 host */ - trim_ipv6_host(sipVia->host); - - /* validate port portion */ - port_num = (uint16_t) strtol(port_num_str, &endptr, 10); - - /* - * There may be trailing white space in the port portion. So, ignore them. - */ - SKIP_LWS(endptr); - if (*endptr || port_num == 0) { - sippmh_free_via(sipVia); - CCSIP_ERR_DEBUG buginf("\n%s: Invalid port number in Via", fname); - return NULL; - } - sipVia->remote_port = port_num; - sipVia->recd_host = sipVia->host; - return sipVia; -} - -void -sippmh_free_via (sipVia_t * sipVia) -{ - if (sipVia) { - cpr_free(sipVia->version); - cpr_free(sipVia); - } -} - - -sipCseq_t * -sippmh_parse_cseq (const char *cseq) -{ - char *lasts = NULL; - /* - * CSeq = "CSeq" ":" 1*DIGIT Method - */ - sipCseq_t *sipCseq = (sipCseq_t *) cpr_calloc(1, sizeof(sipCseq_t)); - - if (!sipCseq) { - return (NULL); - } - -/* if ',' is present then more than 1 cseq are present */ - if (strchr(cseq, ',')) { - cpr_free(sipCseq); - return (NULL); - } - - if (cseq) { - char *mycseq = cpr_strdup(cseq); - - sipCseq->method = sipMethodInvalid; - - if (mycseq) { - char *this_token = PL_strtok_r(mycseq, " ", &lasts); - - if (this_token) { - sipCseq->number = strtoul(this_token, NULL, 10); - - /* make sure the CSeq value is not > 2^^31 */ - if (sipCseq->number >= TWO_POWER_31) { - cpr_free(sipCseq); - cpr_free(mycseq); - return (NULL); - } - - this_token = PL_strtok_r(NULL, " ", &lasts); - if (this_token) { - sipCseq->method = sippmh_get_method_code(this_token); - } - - } - if (!this_token) { - cpr_free(sipCseq); - cpr_free(mycseq); - return (NULL); - } - cpr_free(mycseq); - } else { - cpr_free(sipCseq); - return NULL; - } - } - - return (sipCseq); -} - -sipRet_t -sippmh_add_cseq (sipMessage_t *msg, const char *method, uint32_t seq_no) -{ - sipRet_t retval = STATUS_FAILURE; - - if (msg && method) { - char cseq[32]; - - sprintf(&cseq[0], "%lu %s", (unsigned long) seq_no, method); - retval = sippmh_add_text_header(msg, SIP_HEADER_CSEQ, - (const char *)&cseq[0]); - } - - return (retval); -} - -/* - * The Valid SIP URL MUST contain host field. - * This is not true for TEL URLs. Only user is mandatory. - * This check is sufficient for "From" & "To" headers - * from a GW standpoint. The ReqLine MUST have a "user" - * in the URL as the GW supports multiple users. - */ -boolean -sippmh_valid_url (genUrl_t *genUrl) -{ - boolean retval = FALSE; - - if (!genUrl) { - return retval; - } - if (genUrl->schema == URL_TYPE_SIP) { - if (genUrl->u.sipUrl->host && genUrl->u.sipUrl->host[0]) - retval = TRUE; - } else if (genUrl->schema == URL_TYPE_TEL) { - if (genUrl->u.telUrl->user) - retval = TRUE; - } - - return (retval); -} - -/* - * The Input string is the comma separated cached Record-Route - * header string. This function duplicates the input string - * and generates a set of pointers which are pointing to a - * name-addr format string. These pointers are pointing within - * the duplicated cached header string. - * - * Loc 0 Loc 1 Loc 2 - * Loc_start -> name-addr1, name-addr2, name-addr3 - * - * Loc_start points to the duplicated input string and needs - * to be freed. - * Loc_start is preserved so that the string - * can be freed, when required. Thus this pointer needs to be - * stored only once. - */ -sipRecordRoute_t * -sippmh_parse_record_route (const char *input_record_route) -{ - char *record_route = NULL, *start_ptr = NULL; - char *more_ptr; - sipRecordRoute_t *sipRecordRoute; - char *rr_other_param = NULL; - - /* - * Record-Route = "Record-Route" ":" (name-addr *(";" rr-param)) - * name-addr = [ display-name ] "<" addr-spec ">" - * addr-spec = SIP-URL | URI - * display-name = *token | quoted-string - * rr-param = generic-param - * generic-param = token [ = ( token | host | quoted-string ) ] - */ - - record_route = cpr_strdup(input_record_route); - if (record_route == NULL) { - return NULL; - } - - sipRecordRoute = (sipRecordRoute_t *) - cpr_calloc(1, sizeof(sipRecordRoute_t)); - - if (sipRecordRoute == NULL) { - cpr_free(record_route); - return NULL; - } - - start_ptr = record_route; - - do { - sipLocation_t *sipLoc; - - more_ptr = NULL; - parse_errno = 0; - sipLoc = sippmh_parse_nameaddr_or_addrspec(record_route, start_ptr, - FALSE, TRUE, &more_ptr); - if (sipLoc == NULL) { - if (sipRecordRoute->locations == 0) { - // Free record_route only if we fail the first location - // For the others, it will be freed when sipRecordRoute is - // freed - cpr_free(record_route); - } - sippmh_free_record_route(sipRecordRoute); - sipRecordRoute = NULL; - break; - } - - /* Loc_start points to the duplicated input string & - * is stored in the zeroth location of location[]. - * This value needs to be freed only once - */ - if (sipRecordRoute->num_locations) { - sipLoc->loc_start = NULL; - } - - sipRecordRoute->locations[sipRecordRoute->num_locations++] = sipLoc; - - if (more_ptr == NULL || *more_ptr == 0) { - /* No params, means no qval and assume lowest priority */ - break; - } - - record_route = more_ptr; - - /* - * At this point, either record_route is pointing to - * 1) ',' - Beginning of next location - * 3) End of string - * 4) Any other character is syntax error - */ - - /* - * This following while loop eats up all the rr_params. - * Note that these 'other_params' are not the same as the ones handled - * by parseURLParams. That routines parses other params INSIDE the < > brackets. - * The following code would handle unknown params outside the brackets. - */ - while (record_route && *record_route == SEMI_COLON) { - record_route++; - record_route = parse_other_param(record_route, &rr_other_param); - /* - * Record route extensions are not supported. Throw away - * any that were just parsed. - */ - if (rr_other_param != NULL) { - cpr_free(rr_other_param); - } - } - - - if (record_route && *record_route == COMMA) { - /* Another location follows */ - *record_route++ = 0; - SKIP_LWS(record_route); - if (sipRecordRoute->num_locations == SIP_MAX_LOCATIONS) { - sippmh_free_record_route(sipRecordRoute); - sipRecordRoute = NULL; - CCSIP_ERR_DEBUG { - buginf("\nsippmh_parse_record_route: Too many location " - "headers in Record-Route header"); - } - break; - } - } else { - /* Flag error if not "end of header" & - * any other character other than COMMA - */ - if (record_route && *record_route) { - parse_errno = PARSE_ERR_SYNTAX; - CCSIP_DEBUG_ERROR(parse_errors[parse_errno], - "sippmh_parse_record_route", record_route); - sippmh_free_record_route(sipRecordRoute); - sipRecordRoute = NULL; - } - break; - } - } while (1); - - if (sipRecordRoute) { - sipRecordRoute->new_flag = TRUE; - } - return sipRecordRoute; -} - -/* - * This function is a placeholder for future expansion. - * If deep copy of the record route is needed from one ccb to another - * this function can be used. - */ -sipRecordRoute_t * -sippmh_copy_record_route (sipRecordRoute_t *rr) -{ - //TBD - return NULL; -} - -void -sippmh_free_record_route (sipRecordRoute_t *rr) -{ - int i; - - if (rr) { - for (i = 0; i < rr->num_locations; ++i) { - if (rr->locations[i]->loc_start) { - /* Free the entire header value that we duplicated */ - cpr_free(rr->locations[i]->loc_start); - } - /* Free the genUrl_t struct in the sipLocation_t */ - sippmh_genurl_free(rr->locations[i]->genUrl); - /* Free the sipLocation_t in Record-Route struct */ - cpr_free(rr->locations[i]); - } - /* Free the sipContact_t struct */ - cpr_free(rr); - } -} - -cc_content_disposition_t * -sippmh_parse_content_disposition (const char *input_content_disp) -{ - char *content_disp = NULL; - char *content_disp_start = NULL; - cc_content_disposition_t *sipContentDisp = NULL; - char *separator = NULL; - char *more_ptr = NULL; - - if (input_content_disp == NULL) { - return NULL; - } - - content_disp_start = content_disp = cpr_strdup(input_content_disp); - if (content_disp == NULL) { - return NULL; - } - - /* - * Content-Disposition = "Content-Disposition" ":" - * disposition-type*(";" disposition-param) - * disposition-type = "render" "session" "Icon" "alert" "precondition" - * disp-extension-token - * disposition-param = "handling" "=" - * ("optional"|"required" other-handling) - * generic-param - * other-handling = token - * disp-extension-token = token - */ - - sipContentDisp = (cc_content_disposition_t *) - cpr_calloc(1, sizeof(cc_content_disposition_t)); - if (sipContentDisp == NULL) { - cpr_free(content_disp); - return sipContentDisp; - } - - /* Set the field to protocol define defaults - * - Session & required handling - */ - sipContentDisp->disposition = cc_disposition_session; - sipContentDisp->required_handling = TRUE; - - /* first token should be disposition-type - so look for - * a token delimiter either a space or semicolon - */ - SKIP_LWS(content_disp); - separator = strpbrk(content_disp, " ;"); - if (separator) { - if (*separator == ';') { - *separator = 0; - more_ptr = separator + 1; - } else { - *separator = 0; - more_ptr = NULL; - } - } else { - more_ptr = NULL; - } - - /* Parse disposition-type */ - if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_SESSION, 7) == 0) { - sipContentDisp->disposition = cc_disposition_session; - } else if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_PRECONDITION, 12) == 0) { - sipContentDisp->disposition = cc_disposition_precondition; - } else if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_ICON, 4) == 0) { - sipContentDisp->disposition = cc_dispostion_icon; - } else if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_ALERT, 5) == 0) { - sipContentDisp->disposition = cc_disposition_alert; - } else if (strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_RENDER, 6) == 0) { - sipContentDisp->disposition = cc_disposition_render; - } else { - sipContentDisp->disposition = cc_disposition_unknown; - } - - if (more_ptr) { - /* parse disposition-param */ - SKIP_LWS(more_ptr); - if (strncasecmp(more_ptr, "handling", 8) == 0) { - more_ptr += 8; - SKIP_LWS(more_ptr); - if (*more_ptr == '=') { - more_ptr++; - SKIP_LWS(more_ptr); - if (strncasecmp(more_ptr, "optional", 8) == 0) { - sipContentDisp->required_handling = FALSE; - } else if (strncasecmp(more_ptr, "required", 8) == 0) { - sipContentDisp->required_handling = TRUE; - } - } - } else { - /* Keyword "handling" is not found - * default values are already populated - */ - } - } - - cpr_free(content_disp_start); - return (sipContentDisp); -} - - -/*************************************************************** - * - * Parses headers in Refer-To body in a char array - * - **************************************************************/ -static uint16_t -sippmh_parse_referto_headers (char *refto_line, char **header_arr) -{ - uint16_t headNum = 0; - char *tmpHead = NULL; - char *lasts = NULL; - - if (refto_line == NULL) { - return 0; - } - - tmpHead = PL_strtok_r(refto_line, "?&", &lasts); - while (tmpHead != NULL) { - header_arr[headNum++] = tmpHead; - tmpHead = PL_strtok_r(NULL, "?&", &lasts); - } - return headNum; -} - - -/******************************************************************* - * - * Parser routine for headers other than sip url. Parses Replaces - * header, copies Accept-Contact and Proxy-Authorization headers - * and skips other headers. - * - * Input parameters : Array containing headers in Refer-To body, - * count of number of headers in Refer-To body - * & pointer to Refer-To structure for parsed - * values to be returned to calling function - * - * Returns : Zero if success, non-zero otherwise - * - *******************************************************************/ -static int -sippmh_parse_other_headers (char **headerArr, uint16_t tokCount, - sipReferTo_t *refer_to) -{ - uint16_t count = 0; - char *dup_header, *mhead; - - dup_header = mhead = NULL; - - for (count = 1; count < tokCount; count++) { - dup_header = cpr_strdup(headerArr[count]); - if (dup_header == NULL) { - return (PARSE_ERR_NO_MEMORY); - } - mhead = strchr(dup_header, '='); - if (mhead == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } else { - *mhead = '\0'; - } - if (cpr_strcasecmp(dup_header, SIP_HEADER_REPLACES) == 0) { - - char *unescRepl_str = NULL; - - /* - * copy the Replaces header so that it can be - * echoed back in the triggered INVITE. Also - * unescape any escpaed characters. - */ - headerArr[count] = strstr(headerArr[count], "="); - if (headerArr[count] == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - *(headerArr[count])++ = 0; - SKIP_LWS(headerArr[count]); - - /* if header body is NULL, return syntax error */ - if (*headerArr[count] == '\0') { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - - unescRepl_str = (char *) cpr_malloc(strlen(headerArr[count]) + 1); - if (unescRepl_str == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_NO_MEMORY); - } - - sippmh_convertEscCharToChar((const char *) headerArr[count], - (uint8_t) strlen(headerArr[count]), unescRepl_str); - - refer_to->sip_replaces_hdr = unescRepl_str; - - } else if (cpr_strcasecmp(dup_header, SIP_HEADER_ACCEPT_CONTACT) == 0 || - cpr_strcasecmp(dup_header, SIP_C_HEADER_ACCEPT_CONTACT) == 0) { - char *unescAccCont = NULL; - - /* - * copy unescaped version of this header so - * that it can be echoed back in triggered INVITE - */ - headerArr[count] = strstr(headerArr[count], "="); - if (headerArr[count] == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - *(headerArr[count])++ = 0; - SKIP_LWS(headerArr[count]); - - /* if header body is NULL, return syntax error */ - if (*headerArr[count] == '\0') { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - - unescAccCont = (char *) cpr_malloc(strlen(headerArr[count]) + 1); - - if (unescAccCont == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_NO_MEMORY); - } - - sippmh_convertEscCharToChar((const char *) headerArr[count], - (uint8_t) strlen(headerArr[count]), - unescAccCont); - - refer_to->sip_acc_cont = unescAccCont; - - } else if (cpr_strcasecmp(dup_header, SIP_HEADER_PROXY_AUTH) == 0) { - - char *unescPrAuth = NULL; - - /* - * copy this header to be echoed back in triggered INVITE - * unescape any escaped chars before storing - */ - - headerArr[count] = strstr(headerArr[count], "="); - if (headerArr[count] == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - *(headerArr[count])++ = 0; - SKIP_LWS(headerArr[count]); - - /* if header body is NULL, return syntax error */ - if (*headerArr[count] == '\0') { - cpr_free(dup_header); - return (PARSE_ERR_SYNTAX); - } - - unescPrAuth = (char *) cpr_malloc(strlen(headerArr[count]) + 1); - if (unescPrAuth == NULL) { - cpr_free(dup_header); - return (PARSE_ERR_NO_MEMORY); - } - - sippmh_convertEscCharToChar((const char *) headerArr[count], - (uint8_t) strlen(headerArr[count]), - unescPrAuth); - - refer_to->sip_proxy_auth = unescPrAuth; - } - cpr_free(dup_header); - } - - return 0; /* SUCCESS */ -} - -/************************************************************** - * Parser routine for Refer-To header. Refer-To may contain - * other headers like: - * a) Replaces - * b) Accept-Contact - * c) Proxy-Authorization - * will skip headers, we do not understand; parse Replaces; - * and copy Accept-Contact and Proxy-Authorization headers - * to be echoed back in the triggered INVITE. - * - * Input parameters : Refer-To string to be parsed. - * Returns : Pointer to Refer-To structure with parsed values - * if successful, NULL otherwise. - * - **************************************************************/ -sipReferTo_t * -sippmh_parse_refer_to (char *input_refer_to) -{ - char *refer_to_headers[MAX_REFER_TO_HEADER_CONTENTS]; - char *left_bracket, *right_bracket, *msg_body, *refer_to_val; - sipReferTo_t *sipReferTo = NULL; - genUrl_t *refUrl = NULL; - uint16_t tokens = 0; - int ref_header_count = 0; - - left_bracket = right_bracket = msg_body = refer_to_val = NULL; - - if (input_refer_to == NULL) { - return NULL; - } - - /* - * Refer-To = ("Refer-To" | "r") ":" URL - */ - - /* make a copy of refer-to to work with */ - refer_to_val = cpr_strdup(input_refer_to); - if (refer_to_val == NULL) { - return NULL; - } - - sipReferTo = (sipReferTo_t *) cpr_calloc(1, sizeof(sipReferTo_t)); - if (sipReferTo == NULL) { - cpr_free(refer_to_val); - return NULL; - } - sipReferTo->ref_to_start = refer_to_val; - - /* Initialize */ - for (ref_header_count = 0; - ref_header_count < MAX_REFER_TO_HEADER_CONTENTS; - ref_header_count++) { - refer_to_headers[ref_header_count] = NULL; - } - - /* first get rid of opening and closing braces, if there */ - left_bracket = strpbrk(refer_to_val, ",<"); - if (left_bracket) { - - /* This is a name-addr form */ - left_bracket++; - right_bracket = strchr(left_bracket, '>'); - if (right_bracket) { - *right_bracket++ = 0; - } - msg_body = left_bracket; - } else { - - /* This is addr-spec format */ - msg_body = refer_to_val; - SKIP_LWS(msg_body); - } - - /* parse headers separated by ? or & in an array of char pointers */ - tokens = sippmh_parse_referto_headers(msg_body, refer_to_headers); - - if (tokens == 0) { - CCSIP_ERR_DEBUG { - buginf("\nEmpty Refer-To header\n"); - } - sippmh_free_refer_to(sipReferTo); - return NULL; - } - - /* First parse url portion, this should be the first element - * of the headers array - */ - refUrl = sippmh_parse_url(refer_to_headers[0], FALSE); - if (refUrl == NULL) { - sippmh_free_refer_to(sipReferTo); - return NULL; - } - sipReferTo->targetUrl = refUrl; - - /* next parse rest of the headers, skip ones we don't understand */ - parse_errno = sippmh_parse_other_headers(refer_to_headers, tokens, - sipReferTo); - - if (parse_errno != 0) { - CCSIP_ERR_DEBUG { - buginf("\nError while parsing other Refer-To header\n"); - } - sippmh_free_refer_to(sipReferTo); - return NULL; - } - - return (sipReferTo); -} - - - - - -/***************************************************************** - * - * Parser routine for Replaces header. Replaces header has - * call-id, to and from tags and signature scheme as parameters. - * The parser parses and stores call-id and tags in the Replaces - * structure and copies the signature scheme to be echoed back - * in the triggered INVITE for attended transfer. - * - * Input parameters : Replaces string to be parsed, - * boolean flag indicating whether the input - * string shall be duplicated or not. - * - * Returns : pointer to Replaces structure with parsed values - * if successful, NULL otherwise. - * - *****************************************************************/ -sipReplaces_t * -sippmh_parse_replaces (char *input_repl, boolean dup_flag) -{ - - char *repl_str, *this_tok, *tagVal, *sign, *callid; - sipReplaces_t *repcs = NULL; - char *lasts = NULL; - - repl_str = this_tok = tagVal = sign = NULL; - - if (input_repl == NULL) { - return NULL; - } - - - /* - * Replaces = "Replaces" ":" 1#replaces-values - * replaces-values = callid *( ";" replaces-param ) - * callid = token [ "@" token ] - * replaces-param = to-tag | from-tag | rep-signature - * | extension-param - * to-tag = "to-tag=" UUID - * from-tag = "from-tag=" UUID - * rep-signature = signature-scheme *( ";" sig-scheme-params) - * signature-scheme = "scheme" "=" token - * sig-scheme-params = token "=" ( token | quoted string ) - */ - - repcs = (sipReplaces_t *) cpr_calloc(1, sizeof(sipReplaces_t)); - if (repcs == NULL) { - return NULL; - } - - if (dup_flag) { - repl_str = cpr_strdup(input_repl); - if (!repl_str) { - cpr_free(repcs); - return NULL; - } - repcs->str_start = repl_str; - } else { - repl_str = input_repl; - } - - - /* if Replaces string has signature scheme parameter, - * make a copy of the input string for parsing entire signature - * parameter - */ - - if ((sign = strstr(repl_str, SIGNATURE_SCHEME)) != NULL) { - - /* - * if to or from tag follows signature params, remove - * them from this string - */ - char *sign_str, *tag_str; - - sign_str = tag_str = NULL; - - sign_str = cpr_strdup(sign); - if (sign_str == NULL) { - sippmh_free_replaces(repcs); - return NULL; - } - if ((tag_str = strstr(sign_str, ";to-tag")) || - (tag_str = strstr(sign_str, ";from-tag"))) { - *tag_str = '\0'; - } else { - /* terminate input string at signature param */ - *sign = '\0'; - } - (repcs->signature_scheme) = sign_str; - } - - - this_tok = PL_strtok_r(input_repl, ";", &lasts); - while (this_tok != NULL) { - if (strncasecmp(this_tok, TO_TAG, 6) == 0) { - if (repcs->toTag != NULL) { - sippmh_free_replaces(repcs); - return NULL; /* ERROR - more than 1 TO tag */ - } else { - tagVal = strchr(this_tok, '='); - if (tagVal) { - tagVal++; - SKIP_LWS(tagVal); - repcs->toTag = tagVal; - } else { - sippmh_free_replaces(repcs); - return NULL; /* ERROR */ - } - } - } else if (strncasecmp(this_tok, FROM_TAG, 8) == 0) { - if (repcs->fromTag != NULL) { - sippmh_free_replaces(repcs); - return NULL; /* ERROR - more than 1 FROM tag */ - } else { - tagVal = strchr(this_tok, '='); - if (tagVal) { - tagVal++; - SKIP_LWS(tagVal); - repcs->fromTag = tagVal; - } else { - sippmh_free_replaces(repcs); - return NULL; /* ERROR */ - } - } - } else if (strncasecmp(this_tok, SIP_HEADER_REPLACES, - sizeof(SIP_HEADER_REPLACES) - 1) == 0) { - /* only other allowable field should be callid */ - callid = strchr(this_tok, '='); - if (callid) { - char *sp_token; - - callid++; - SKIP_LWS(callid); - repcs->callid = callid; - /* remove trailing spaces */ - sp_token = strchr(repcs->callid, ' '); - if (sp_token == NULL) { - sp_token = strchr(repcs->callid, '\t'); - } - if (sp_token) { - *sp_token = 0; - } - } else { - sippmh_free_replaces(repcs); - return NULL; /* ERROR */ - } - } else { - sippmh_free_replaces(repcs); - return NULL; - } - this_tok = PL_strtok_r(NULL, ";", &lasts); - } - /* check for errors */ - if ((repcs->callid == NULL) || - (repcs->toTag == NULL) || - (repcs->fromTag == NULL)) { - sippmh_free_replaces(repcs); - return NULL; - } - - return repcs; /* SUCCESS */ -} - - -/* - * Converts a hex character (0-9, a-f, or A-F) into its integer - * equivalent value. - * ex.) '9' --> 9 - * 'a' --> 10 - * 'F' --> 15 - */ -static int -sippmh_htoi (const char inputChar) -{ - char inputValue[2]; - long strtol_result; - char *strtol_end; - - inputValue[0] = inputChar; - inputValue[1] = '\0'; - - errno = 0; - strtol_result = strtol(inputValue, &strtol_end, 16); - - if (errno || inputValue == strtol_end) { - return 0; - } else { - return (int) strtol_result; - } -} - -/* - * This function(similar to memchr()) works with both strings and array of characters. - * Returns the pointer to the matched character, if any; NULL otherwise. To include memchr.c - * in the phone library takes 1K of extra size and hence wrote this. - */ -static void * -char_lookup (const void *src, unsigned char c, int n) -{ - const unsigned char *mem = (unsigned char *) src; - - while (n--) { - if (*mem == c) { - return ((void *) mem); - } - mem++; - } - - return NULL; -} - - -/* List of characters that can exist in user part of URL/URI without escaping */ -#define userUnResCharListSize 17 -static char userUnResCharList[userUnResCharListSize] = -{ - SEMI_COLON, EQUAL_SIGN, TILDA, STAR, UNDERSCORE, PLUS, - SINGLE_QUOTE, LEFT_PARENTHESIS, RIGHT_PARENTHESIS, DOLLAR_SIGN, - FORWARD_SLASH, DOT, DASH, EXCLAMATION, AMPERSAND, COMMA, QUESTION_MARK -}; - - -/* - * This utility function converts selected characters in a string to escaped characters, - * per RFC2396. Escape format = %hexhex (hexhex - hex value of ASCII character) - * ex. 'abc@123' gets converted to "abc%40123" if '@' exists in escapable character list - * - * inptStr = ptr to string of chars - * inputStrLen = num of characters that you want to convert - * excludeCharTbl = lookup table/string of characters that need not be escaped - * excludeCharTblSize = number of characters in the table/string that need not be escaped - * null_terminate = TRUE if '\0' is required to be added at end - * FALSE if not required. - * outputStr = ptr to pre-allocated memory for storing the - * converted string - * outputStrSize = the size limit of the outputStr buffer - * - * returns the new size of the output string - * Converted string is stored in outputStr - * (contents = converted str) - */ -static size_t -sippmh_escapeChars_util (const char *inputStr, size_t inputStrLen, - char *excludeCharTbl, size_t excludeCharTblSize, - char *outputStr, size_t outputStrSize, - boolean null_terminate) -{ - size_t char_cnt = 0; - char *nextOutputChar; - int additional_byte = null_terminate ? 1 : 0; - size_t copy_count = 0; - - nextOutputChar = outputStr; - - while (char_cnt++ < inputStrLen) { - /* Check for characters that doesn't need to be escaped */ - if (((*inputStr) >= 'A' && (*inputStr) <= 'Z') || - ((*inputStr) >= 'a' && (*inputStr) <= 'z') || - ((*inputStr) >= '0' && (*inputStr) <= '9') || - (char_lookup(excludeCharTbl, (unsigned char) *inputStr, - excludeCharTblSize) != NULL)) { - if (outputStrSize < (copy_count + 1 + additional_byte)) { - break; - } - *nextOutputChar++ = *inputStr++; - copy_count++; - } else { // Characters that need escaping - if (outputStrSize < (copy_count + 3 + additional_byte)) { - break; - } - /* Copy %hh to output string */ - sprintf(nextOutputChar, "%c%x", '%', *inputStr++); - nextOutputChar = nextOutputChar + 3; - copy_count += 3; - } - - } - - if (null_terminate) { - copy_count++; - *nextOutputChar = '\0'; - } - return (copy_count); -} - -/* - * This function converts selected characters in a string to escaped characters, - * per RFC2396. Escape format = %hexhex (hexhex - hex value of ASCII character) - * ex. 'abc@123' gets converted to "abc%40123" if '@' exists in escapable character list - * - * inptStr = ptr to string of chars - * inputStrLen = num of characters that you want to convert - * outputStr = ptr to pre-allocated memory for storing the - * converted string - * outputStrSize = the size limit of the outputStr buffer - * null_terminate = TRUE if '\0' is required to be added at end - * FALSE if not required. - * returns the new size of the output string - * - * Converted string is stored in outputStr - * (contents = converted str) - */ -size_t -sippmh_convertURLCharToEscChar (const char *inputStr, size_t inputStrLen, - char *outputStr, size_t outputStrSize, - boolean null_terminate) -{ - return (sippmh_escapeChars_util(inputStr, inputStrLen, - userUnResCharList, userUnResCharListSize, - outputStr, outputStrSize, null_terminate)); -} -/* - * This function converts any '\' or '"' character in a quoted string to escaped characters, - * per RFC3261. Escape format = %hexhex (hexhex - hex value of ASCII character) - * ex. 'abc\\' gets converted to "abc%5c%5c" if '\' exists in escapable character list - * - * inptStr = ptr to string of chars - * inputStrLen = num of characters that you want to convert - * outputStr = ptr to pre-allocated memory for storing the - * converted string - * outputStrSize = the size limit of the outputStr buffer - * null_terminate = TRUE if '\0' is required to be added at end - * FALSE if not required. - * returns the new size of the output string - * - * Converted string is stored in outputStr - * (contents = converted str) - */ -size_t -sippmh_converQuotedStrToEscStr(const char *inputStr, size_t inputStrLen, - char *outputStr, size_t outputStrSize, - boolean null_terminate) -{ - size_t char_cnt = 0; - char *nextOutputChar; - int additional_byte = null_terminate ? 1 : 0; - size_t copy_count = 0; - - nextOutputChar = outputStr; - - while (char_cnt++ < inputStrLen) { - /* Check for characters that need to be escaped */ - if( ((*inputStr) == ESCAPE_CHAR) || ((*inputStr) == DOUBLE_QUOTE)) - { - // Characters that need escaping - if (outputStrSize < (copy_count + 3 + additional_byte)) { - break; - } - /* Copy %hh to output string */ - sprintf(nextOutputChar, "%c%02x", '%', *inputStr++); - nextOutputChar = nextOutputChar + 3; - copy_count += 3; - } - else { - if (outputStrSize < (copy_count + 1 + additional_byte)) { - break; - } - *nextOutputChar++ = *inputStr++; - copy_count++; - } - - } - - if (null_terminate) { - copy_count++; - *nextOutputChar = '\0'; - } - - return (copy_count); -} - -/* - * This function converts all Escaped characters in a string - * to their non-escaped format according to RFC2396. - * Escape format = %hh (%) - * ex. 'abc%40123' gets converted to "abc@123" - * - * inptStr = ptr to string of chars - * inputStrLen = num of characters that you want to convert - * outputStr = ptr to pre-allocated memory for storing the - * converted string - * - * Converted string is stored in outputStr - * (contents = converted str) - * (contents = '\0' if no input string) - */ -void -sippmh_convertEscCharToChar (const char *inputStr, size_t inputStrLen, - char *outputStr) -{ - size_t char_cnt = 0; - char *nextOutputChar; - int value; - boolean esc_char_found = FALSE; - - *outputStr = '\0'; - nextOutputChar = outputStr; - - while (char_cnt < inputStrLen) { - if (*inputStr == PERCENT) { - /* Skip ESC syntax */ - inputStr++; - char_cnt++; - esc_char_found = TRUE; - } - - /* Copy character to output str */ - if (esc_char_found) { - - /* Convert 1st and 2nd hex chars to int */ - value = sippmh_htoi(*inputStr) * 16; - inputStr++; - char_cnt++; - value += sippmh_htoi(*inputStr); - sprintf(nextOutputChar, "%c", toascii(value)); - - inputStr++; - char_cnt++; - esc_char_found = FALSE; - - } else { - *nextOutputChar = *inputStr; - inputStr++; - char_cnt++; - } - - nextOutputChar++; - } - - *nextOutputChar = '\0'; -} - - -void -sippmh_free_replaces (sipReplaces_t *repl) -{ - - if (repl == NULL) { - return; - } - if (repl->str_start) { - cpr_free(repl->str_start); - } - if (repl->signature_scheme) { - cpr_free(repl->signature_scheme); - } - cpr_free(repl); -} - - -void -sippmh_free_refer_to (sipReferTo_t *ref_to) -{ - - if (ref_to == NULL) { - return; - } - if (ref_to->ref_to_start) { - cpr_free(ref_to->ref_to_start); - } - if (ref_to->sip_replaces_hdr) { - cpr_free(ref_to->sip_replaces_hdr); - } - if (ref_to->sip_acc_cont) { - cpr_free(ref_to->sip_acc_cont); - } - if (ref_to->sip_proxy_auth) { - cpr_free(ref_to->sip_proxy_auth); - } - if (ref_to->targetUrl) { - sippmh_genurl_free(ref_to->targetUrl); - } - cpr_free(ref_to); - -} - - -static void -sippmh_free_remote_party_id (sipRemotePartyId_t *remote_party_id) -{ - if (remote_party_id) { - if (remote_party_id->loc) { - sippmh_free_location(remote_party_id->loc); - } - cpr_free(remote_party_id); - } -} - - -void -sippmh_free_remote_party_id_info (sipRemotePartyIdInfo_t *rpid_info) -{ - uint32_t i; - - if (rpid_info) { - if (rpid_info->num_rpid > 0) { - for (i = 0; i < rpid_info->num_rpid; i++) { - sippmh_free_remote_party_id(rpid_info->rpid[i]); - rpid_info->rpid[i] = NULL; - } - } - cpr_free(rpid_info); - } -} - -void -sippmh_free_diversion_info (sipDiversionInfo_t *div_info) -{ - if (div_info) { - if (div_info->orig_called_name) { - strlib_free(div_info->orig_called_name); - } - if (div_info->orig_called_number) { - strlib_free(div_info->orig_called_number); - } - if (div_info->last_redirect_name) { - strlib_free(div_info->last_redirect_name); - } - if (div_info->last_redirect_number) { - strlib_free(div_info->last_redirect_number); - } - cpr_free(div_info); - } - -} - -static boolean -sippmh_parse_remote_party_id_params (char *params, - sipRemotePartyId_t *remote_party_id) -{ - boolean params_good; - int param_len; - char *param_name; - - if ((params == NULL) || (remote_party_id == NULL)) { - return FALSE; - } - - while (1) { - params_good = FALSE; - - while (*params == ';') { - params++; - } - - param_name = params; - SKIP_SIP_TOKEN(params); - param_len = params - param_name; - if (param_len == 0) { - return FALSE; - } - - /* Parse screen parameter */ - /* If there are multiple screen parameters, "no" takes precedence */ - if ((param_len == RPID_SCREEN_LEN) && - (strncasecmp(param_name, RPID_SCREEN, RPID_SCREEN_LEN) == 0) && - (!remote_party_id->screen || - cpr_strcasecmp(remote_party_id->screen, "no"))) { - params = parse_generic_param(params, &remote_party_id->screen); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse party-type parameter */ - } else if ((param_len == RPID_PARTY_TYPE_LEN) && - (strncasecmp(param_name, RPID_PARTY_TYPE, - RPID_PARTY_TYPE_LEN) == 0)) { - params = parse_generic_param(params, &remote_party_id->party_type); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse id-type parameter */ - } else if ((param_len == RPID_ID_TYPE_LEN) && - (strncasecmp(param_name, RPID_ID_TYPE, - RPID_ID_TYPE_LEN) == 0)) { - params = parse_generic_param(params, &remote_party_id->id_type); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse privacy parameter */ - } else if ((param_len == RPID_PRIVACY_LEN) && - (strncasecmp(param_name, RPID_PRIVACY, - RPID_PRIVACY_LEN) == 0)) { - params = parse_generic_param(params, &remote_party_id->privacy); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse np parameter */ - } else if ((param_len == RPID_NP_LEN) && - (strncasecmp(param_name, RPID_NP, RPID_NP_LEN) == 0)) { - params = parse_generic_param(params, &remote_party_id->np); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - } - - SKIP_LWS(params); - if (*params == SEMI_COLON) { - /* More parameters follow */ - *params++ = '\0'; - SKIP_LWS(params); - } else { - break; - } - } - - return params_good; -} - -sipRemotePartyId_t * -sippmh_parse_remote_party_id (const char *input_remote_party_id) -{ - /* static const char fname[] = "sippmh_parse_remote_party_id"; */ - char *more_ptr; - sipRemotePartyId_t *remote_party_id; - char *remote_party_id_str; - - /* - * Remote-Party-ID = "Remote-Party-ID" ":" [display-name] - * "<" addr-spec ">" *(";" rpi-token) - * rpi-token = rpi-screen | rpi-pty-type | - * rpi-id-type | rpi-privacy | rpi-np | - * other-rpi-token - * rpi-screen = "screen" "=" ("no" | "yes") - * rpi-pty-type = "party" "=" ("calling" | "called" | token) - * rpi-id-type = "id-type" "=" ("subscriber" | "user" | "alias" | - * "return" | "term" | token) - * rpi-privacy = "privacy" = 1#( - * ("full" | "name" | "uri" | "off" | token) - * ["-" ("network" | token) ] ) - * rpi-np = "np" "=" ("ordinary" | "residential" | "business" | - * "priority" | "hotel" | "failure" | "hospital" | - * "prison" | "police" | "test" | "payphone" | - * "coin" | "payphone-public" | "payphone-private" | - * "coinless" | "restrict" | "coin-restrict" | - * "coinless-restrict" | "reserved" | "operator" | - * "trans-freephone" | "isdn-res" | "isdn-bus" | - * "unknown" | "emergency" | token ) - * other-rpi-token = ["-"] token ["=" (token | quoted-string)] - */ - - remote_party_id = (sipRemotePartyId_t *) - cpr_calloc(1, sizeof(sipRemotePartyId_t)); - if (remote_party_id == NULL) { - return NULL; - } - - /* Duplicate the string and work with it - - * This duplicate string is stored in the location structure - * pointed to by remote_party_id->loc and freed when the that - * structure is freed. Note that this pointer is *not* dup'ed - * in the parse_nameaddr_or_addrspec structure - */ - remote_party_id_str = cpr_strdup(input_remote_party_id); - - if (remote_party_id_str == NULL) { - sippmh_free_remote_party_id(remote_party_id); - remote_party_id = NULL; - more_ptr = NULL; - } else { - remote_party_id->loc = - sippmh_parse_nameaddr_or_addrspec(remote_party_id_str, - remote_party_id_str, FALSE, - FALSE, &more_ptr); - - if (remote_party_id->loc == NULL) { - cpr_free(remote_party_id_str); - sippmh_free_remote_party_id(remote_party_id); - remote_party_id = NULL; - more_ptr = NULL; - } - } - - if (more_ptr == NULL || *more_ptr == 0) { - /* No params. Use defaults of: - * party=calling, screen=no, id-type=subscriber, - * privacy=off, np=0 (ordinary) - */ - } else { - (void) sippmh_parse_remote_party_id_params(more_ptr, remote_party_id); - } - - return remote_party_id; -} - - -char * -sippmh_generate_authorization (sip_author_t *sip_author) -{ - char *buffer; - - /* - * This routine takes a sip_author_t struct and generates an Authorization - * header or a Proxy-Authorization header. Since this routine generates - * a header for Authorization or Proxy-Authorization, the header will - * start with "Digest" or "Basic". The user should use sstrncat to - * add "Proxy Authorization: " or "Authorization: " depending which is - * needed. - */ - if (!sip_author) { - return NULL; - } - buffer = (char *) cpr_malloc(MAX_SIP_HEADER_LENGTH); - if (!buffer) { - return NULL; - } - - if (sip_author->scheme == SIP_DIGEST) { - snprintf(buffer, MAX_SIP_HEADER_LENGTH, - "%s %s=\"%s\",%s=\"%s\",%s=\"%s\",%s=\"%s\",%s=\"%s\"", - AUTHENTICATION_DIGEST, - AUTHENTICATION_USERNAME, sip_author->d_username, - AUTHENTICATION_REALM, sip_author->realm, - AUTHENTICATION_URI, sip_author->unparsed_uri, - AUTHENTICATION_RESPONSE, sip_author->response, - AUTHENTICATION_NONCE, sip_author->nonce); - - /* - * The header must have username, realm, uri, response, and nonce. - * All other parameters are optional, so check if they exist and - * add them on to the buffer if they do. - */ - - if (sip_author->opaque) { - char *buffer2; - - buffer2 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer2) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer2, MAX_URI_LENGTH, ",%s=\"%s\"", - AUTHENTICATION_OPAQUE, sip_author->opaque); - sstrncat(buffer, buffer2, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer2); - } - if (sip_author->cnonce) { - char *buffer3; - - buffer3 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer3) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer3, MAX_URI_LENGTH, - ",cnonce=\"%s\"", sip_author->cnonce); - sstrncat(buffer, buffer3, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer3); - } - if (sip_author->qop) { - char *buffer4; - - buffer4 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer4) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer4, MAX_URI_LENGTH, ",qop=%s", sip_author->qop); - sstrncat(buffer, buffer4, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer4); - } - if (sip_author->nc_count) { - char *buffer5; - - buffer5 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer5) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer5, MAX_URI_LENGTH, ",nc=%s", sip_author->nc_count); - sstrncat(buffer, buffer5, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer5); - } - if (sip_author->algorithm) { - char *buffer6; - - buffer6 = (char *) cpr_malloc(MAX_URI_LENGTH); - if (!buffer6) { - cpr_free(buffer); - return NULL; - } - snprintf(buffer6, MAX_URI_LENGTH, - ",%s=%s", AUTHENTICATION_ALGORITHM, sip_author->algorithm); - sstrncat(buffer, buffer6, MAX_SIP_HEADER_LENGTH - strlen(buffer)); - cpr_free(buffer6); - } - } else { - sprintf(buffer, "%s %s", AUTHENTICATION_BASIC, sip_author->user_pass); - } - return buffer; -} - -void -sippmh_free_authen (sip_authen_t *sip_authen) -{ - if (sip_authen) { - cpr_free(sip_authen->str_start); - cpr_free(sip_authen); - } -} - -static boolean -sippmh_validate_authenticate (sip_authen_t *sip_authen) -{ - if (sip_authen) { - if ((sip_authen->realm != NULL) && (sip_authen->nonce != NULL)) { - return TRUE; - } else { - return FALSE; - } - } - return FALSE; -} - -/* routine used to parse WWW-Authenticate and Proxy-Authenticate headers */ - -sip_authen_t * -sippmh_parse_authenticate (const char *input_char) -{ - sip_authen_t *sip_authen; - char *input; - boolean good_params; - boolean qop_found = FALSE; - char *trash; - -/* - * Basic: - * "WWW-Authenticate" ":" 1#challenge - * challenge = "Basic" realm - ******************************************************* - * Digest: - * "Digest" digest-challenge - * digest-challenge = 1#( realm | [ domain ] | nonce | - * [ opaque ] |[ stale ] | [ algorithm ] | - * [ qop-options ] | [auth-param] ) - * - * domain = "domain" "=" <"> URI ( 1*SP URI ) <"> - * URI = absoluteURI | abs_path - * opaque = "opaque" "=" quoted-string - * stale = "stale" "=" ( "true" | "false" ) - * algorithm = "algorithm" "=" ( "MD5" | "MD5-sess" | - * token ) - * qop-options = "qop" "=" <"> 1#qop-value <"> - * qop-value = "auth" | "auth-int" | token - */ - - if (!input_char) { - return NULL; - } - - input = cpr_strdup(input_char); - if (!input) { - return NULL; - } - - sip_authen = (sip_authen_t *) cpr_calloc(1, sizeof(sip_authen_t)); - if (!sip_authen) { - cpr_free(input); - return NULL; - } - - sip_authen->str_start = input; - SKIP_WHITE_SPACE(input); - - /* now pointing at Basic, pgp or Digest */ - - if (strncasecmp(input, AUTHENTICATION_BASIC, 5) == 0) { - sip_authen->scheme = SIP_BASIC; - input += 5; - *input = 0; - input++; - SKIP_WHITE_SPACE(input); - if (strncasecmp(input, AUTHENTICATION_REALM, 5) == 0) { - input += 5; - SKIP_WHITE_SPACE(input); - if (*input == '=') { - input++; - } else { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - buginf("\n%s", get_debug_string(DEBUG_PMH_INCORRECT_SYNTAX)); - } - return NULL; - } - SKIP_WHITE_SPACE(input); - sip_authen->realm = input; - return sip_authen; - } - sip_authen->user_pass = input; /* encoded base 64 */ - return sip_authen; - - } else if (strncasecmp(input, AUTHENTICATION_DIGEST, 6) == 0) { - sip_authen->scheme = SIP_DIGEST; - input += 6; - *input = 0; - input++; - SKIP_WHITE_SPACE(input); - } else { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - buginf("\n%s", get_debug_string(DEBUG_PMH_INVALID_SCHEME)); - } - return NULL; - } - - /* pointing at Digest-challenge */ - - /* if algorithm is not in string set it to md5 */ - - sip_authen->algorithm = "md5"; - - /* loop through string until all fields have been handled */ - - while (input) { - char **ptr = NULL; - - if (strncasecmp(input, AUTHENTICATION_DOMAIN, 6) == 0) { - input += 6; - ptr = &(sip_authen->unparsed_domain); - } else if (strncasecmp(input, AUTHENTICATION_ALGORITHM, 9) == 0) { - input += 9; - ptr = &(sip_authen->algorithm); - } else if (strncasecmp(input, AUTHENTICATION_OPAQUE, 6) == 0) { - input += 6; - ptr = &(sip_authen->opaque); - } else if (strncasecmp(input, "stale", 5) == 0) { - input += 5; - ptr = &(sip_authen->stale); - } else if (strncasecmp(input, AUTHENTICATION_REALM, 5) == 0) { - input += 5; - ptr = &(sip_authen->realm); - } else if (strncasecmp(input, AUTHENTICATION_NONCE, 5) == 0) { - input += 5; - ptr = &(sip_authen->nonce); - } else if (strncasecmp(input, "qop", 3) == 0) { - input += 3; - ptr = &(sip_authen->qop); - qop_found = TRUE; - } else { - /* - * Ignore unrecognized parameters. - */ - ptr = &trash; - input = strchr(input, EQUAL_SIGN); - if (input == NULL) { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - buginf("\n%s", get_debug_string(DEBUG_PMH_INVALID_FIELD_VALUE)); - } - return NULL; - } - } - SKIP_WHITE_SPACE(input); - if (*input != EQUAL_SIGN) { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - buginf("\n%s", get_debug_string(DEBUG_PMH_INCORRECT_SYNTAX)); - } - return NULL; - } - input++; /* skip the equal sign */ - SKIP_WHITE_SPACE(input); - /* input is now pointing at the value of the parameter */ - *ptr = input; - if (*input == DOUBLE_QUOTE) { - input++; - *ptr = input; /*sam do not want the quotes in the string */ - input = strchr(input, DOUBLE_QUOTE); - if (input == NULL) { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - buginf("\n%s", get_debug_string(DEBUG_PMH_INCORRECT_SYNTAX)); - } - return NULL; - } else { - *input++ = '\0'; /*sam string needs to be null terminated */ - } - /* - * Check the qop. If qop is included it has to be either - * auth, auth-int or both. If both are included then we will - * just drop the second one. - */ - if (qop_found == TRUE) { - char *qop_input = NULL; - - if (sip_authen->qop) { - qop_input = strchr(sip_authen->qop, COMMA); - } - if (qop_input != NULL) { - *qop_input = '\0'; - } - - /* - * Make sure that the qop is either auth or auth-int - */ - if ((strncasecmp(sip_authen->qop, "auth", 4) != 0) && - (strncasecmp(sip_authen->qop, "auth-int", 8) != 0)) { - sip_authen->qop = NULL; - } - } - } - - input = strchr(input, COMMA); - if (!input) { - good_params = sippmh_validate_authenticate(sip_authen); - if (good_params) { - return sip_authen; - } else { - sippmh_free_authen(sip_authen); - CCSIP_ERR_DEBUG { - buginf("\n%s", get_debug_string(DEBUG_PMH_NOT_ENOUGH_PARAMETERS)); - } - return NULL; - } - } - *input++ = 0; - SKIP_WHITE_SPACE(input); - } - - sippmh_free_authen(sip_authen); - return NULL; -} - -/* - * Function: sippmh_parse_displaystr - * - * Parameters: Display string to be parsed - * - * Description:Removes leading '); - if (temp) { - *temp = 0; - } - displaystr = strlib_update(displaystr, temp_ptr); - return (displaystr); -} - -/* - * Function: sippmh_process_via_header - * - * Parameters: Received Sip Message - * IP Address the Message was received from - * - * Description: Appends received= to the first Via - * field if the ip address we received this message - * from is not the same as the ip address in the via - * field or if it contains a domain name - * - * Returns: None - * - */ -void -sippmh_process_via_header (sipMessage_t *sip_message, - cpr_ip_addr_t *source_ip_address) -{ - char dotted_ip[MAX_IPADDR_STR_LEN]; - char *hdr_start; - char *new_buf; - int new_buf_len; - char *offset; - long old_header_offset; - sipVia_t *via; - cpr_ip_addr_t tmp_ip_addr; - - CPR_IP_ADDR_INIT(tmp_ip_addr); - - if (sip_message && sippmh_is_request(sip_message)) { - via = sippmh_parse_via(sip_message->hdr_cache[VIA].val_start); - if (via == NULL) { - /* error message already displayed in parse function */ - /* mark the message as being incomplete so a 400 will get sent */ - sip_message->is_complete = 0; - return; - } - - util_ntohl(&tmp_ip_addr, source_ip_address); - ipaddr2dotted(dotted_ip, &tmp_ip_addr); - if (strcmp(via->host, dotted_ip) && (via->recd_host == NULL)) { - hdr_start = sip_message->hdr_cache[VIA].hdr_start; - - /* - * +3 accounts for the ; and the = before and after the received - * and the terminating NULL - */ - new_buf_len = strlen(hdr_start) + sizeof(VIA_RECEIVED) + strlen(dotted_ip) + 3; - new_buf = (char *) cpr_malloc(new_buf_len); - /* - * If we cannot allocate memory, we will just leave - * the VIA alone and hope things work out for the best - */ - if (new_buf != NULL) { - offset = strchr(hdr_start, ','); - old_header_offset = sip_message->hdr_cache[VIA].val_start - - hdr_start; - sip_message->hdr_cache[VIA].hdr_start = new_buf; - sip_message->hdr_cache[VIA].val_start = new_buf + - old_header_offset; - - if (offset) { - snprintf(new_buf, new_buf_len, "%.*s;%s=%s%s", (int) (offset - hdr_start), hdr_start, VIA_RECEIVED, dotted_ip, offset); - } else { - snprintf(new_buf, new_buf_len, "%s;%s=%s", hdr_start, VIA_RECEIVED, dotted_ip); - } - - cpr_free(hdr_start); - } - } - sippmh_free_via(via); - } -} - - -/* - * Function: sippmh_parse_user - * - * Parameters: user portion of URL to parse - * - * Description: This function will remove any parameters - * which appear in the user portion of the url. - * (i.e. 15726;oct3=128@10.10.10.10 will return 15726) - * The SIP Phone does not care about the extra parameters and - * they need to be removed so that the user portion will - * match the phone provisioning and display correctly. - * - * Returns: A Copy of the input string with the parameters removed - * if things go well. NULL if we encounter an error. - */ -char * -sippmh_parse_user (char *url_main) -{ - char *user = NULL; - size_t size = 0; - char *lasts = NULL; - - if (url_main == NULL) { - return (NULL); - } - - /* - * If the first char is ';', give up. That - * breaks our assumption. - */ - if (*url_main == SEMI_COLON) { - return (NULL); - } - - /* - * Create a new string and copy the url_main - * string into it. (We can't change the original - * string because it may be needed for creating - * SIP response messages.) - */ - size = strlen(url_main) + 1; - user = (char *) cpr_malloc(size); - /* - * If the malloc fails, return the original URL. - */ - if (user == NULL) { - return (NULL); - } - - sstrncpy(user, url_main, size); - - /* - * Search for ";" and null terminate the string there. - * An assumption has been made that any parameters will come - * after the number. i.e.: "15726;param=paramval" - */ - (void) PL_strtok_r(user, ";", &lasts); - return (user); -} - -/* - * Function: sippmh_parse_message_summary - * - * Parameters: The incoming SIP message and a container to be - * filled with the parsed message body. - * - * Description: This function will parse the incoming MWI NTFY SIP message - * and fill the passed in structure with the - * contents of the parsed message.Basic Error checking is done on - * the passed in message. - * - * Returns: SIP_ERROR on error.SIP_OK otherwise. - */ -int32_t -sippmh_parse_message_summary(sipMessage_t *pSipMessage, sipMessageSummary_t *mesgSummary) -{ - int i = 0; - int j = 0; - char *p = NULL; - char *val = NULL; - char temp[MAX_SIP_URL_LENGTH]; - boolean token_found = FALSE; - boolean hp_found = FALSE; - long strtol_result; - char *strtol_end; - - p = strstr(pSipMessage->mesg_body[0].msgBody, "Messages-Waiting"); - - if (!p) { - p = strstr(pSipMessage->mesg_body[0].msgBody, "Message-Waiting"); - } - - if (p) { - memset(temp, '\0', MAX_SIP_URL_LENGTH); - - trim_right(p); - - val = strstr(p, ":"); - if (val) { - val++; - - i = j = 0; - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - while (val[j] != '\0' && val[j] != '\n' && val[j] != '\r') { - // return error if obviously wrong - if (!isalpha(val[j])) { - return SIP_ERROR; - } - temp[i] = val[j]; - j++; - if (++i >= MAX_SIP_URL_LENGTH) { - return SIP_ERROR; - } - } - temp[i] = '\0'; - } else { - return SIP_ERROR; - } - } else { - return SIP_ERROR; - } - - if (cpr_strcasecmp(temp, "no") == 0) { - mesgSummary->mesg_waiting_on = FALSE; - } else if (cpr_strcasecmp(temp, "yes") == 0) { - mesgSummary->mesg_waiting_on = TRUE; - } else { - return SIP_ERROR; - } - -/* - p = strstr(pSipMessage->mesg_body[0].msgBody, "Message-Account"); - - if (p) { - trim_right(p); - - val = strstr(p, ":"); - if (val) { - val++; - - i = j = 0; - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - - while (val[j] != '\0' && val[j] != '\n' && val[j] != '\r') { - mesgSummary->message_account[i] = val[j]; - j++; - if (++i >= MAX_SIP_URL_LENGTH) { - return SIP_ERROR; - } - } - mesgSummary->message_account[i] = '\0'; - } else { - return SIP_ERROR; - } - } -*/ - - p = strstr(pSipMessage->mesg_body[0].msgBody, "Voice-Message"); - - if (p) { - mesgSummary->type = mwiVoiceType; - memset(temp, '\0', MAX_SIP_URL_LENGTH); - trim_right(p); - i = j = 0; - val = strstr(p, ":"); - if (val) { - val++; - - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - - while (val[j] != '\0' && val[j] != '\n' && val[j] != '\r' && !isspace(val[j]) && val[j] != '(') { - if (!isdigit(val[j])) { - if (val[j] == '/') { - temp[i] = '\0'; - - errno = 0; - strtol_result = strtol(temp, &strtol_end, 10); - - if (errno || temp == strtol_end || strtol_result > INT_MAX) { - return SIP_ERROR; - } - - mesgSummary->newCount = (int) strtol_result; - token_found = TRUE; - i = 0; - } else { - return SIP_ERROR; - } - } else { - temp[i] = val[j]; - if (++i >= MAX_SIP_URL_LENGTH) { - return SIP_ERROR; - } - } - j++; - } - temp[i] = '\0'; - - if (token_found) { - errno = 0; - strtol_result = strtol(temp, &strtol_end, 10); - - if (errno || temp == strtol_end || strtol_result > INT_MAX) { - return SIP_ERROR; - } - - mesgSummary->oldCount = (int) strtol_result; - } - - temp[i = 0] = '\0'; - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - - if (val[j] == '(') { - j++; - while (val[j] != '\0' && val[j] != '\n' && isspace(val[j])) { - j++; - } - - while (val[j] != '\0' && val[j] != '\n' && val[j] != '\r' && !isspace(val[j]) && val[j] != ')') { - if (!isdigit(val[j])) { - if (val[j] == '/') { - temp[i] = '\0'; - - errno = 0; - strtol_result = strtol(temp, &strtol_end, 10); - - if (errno || temp == strtol_end || strtol_result > INT_MAX) { - return SIP_ERROR; - } - - mesgSummary->hpNewCount = (int) strtol_result; - hp_found = TRUE; - i = 0; - } else { - return SIP_ERROR; - } - } else { - temp[i] = val[j]; - if (++i >= MAX_SIP_URL_LENGTH) { - return SIP_ERROR; - } - } - j++; - } - temp[i] = '\0'; - if (hp_found) { - errno = 0; - strtol_result = strtol(temp, &strtol_end, 10); - - if (errno || temp == strtol_end || strtol_result > INT_MAX) { - return SIP_ERROR; - } - - mesgSummary->hpOldCount = (int) strtol_result; - } - } - if (!hp_found) { - mesgSummary->hpNewCount = mesgSummary->hpOldCount = -1; - } - /*make sure the urgent message counts don't exceed the total message counts*/ - if ((mesgSummary->hpNewCount > mesgSummary->newCount) || - (mesgSummary->hpOldCount > mesgSummary->oldCount)) { - return SIP_ERROR; - } - if (!token_found) { - return SIP_ERROR; - } - } else { - return SIP_ERROR; - } - } - - return SIP_OK; -} -/* - * This function compares two strings that may contain escaped characters - * in either of them and determines if they are equivalent, ignoring the - * case if ignore_case is TRUE. - * s1 = ptr to the first string of chars - * s2 = ptr to the second string of chars - * return: integer value of 0 if they are equivalent, <> 0 otherwise. - */ -int -sippmh_cmpURLStrings (const char *s1, const char *s2, boolean ignore_case) -{ - const unsigned char *us1 = (const unsigned char *) s1; - const unsigned char *us2 = (const unsigned char *) s2; - int value1, value2; - int esc_char_incr_in_s1 = 0; // # of chars to skip in s1 if the given char is escaped - int esc_char_incr_in_s2 = 0; // # of chars to skip in s2 if the given char is escaped - - if ((!s1 && s2) || (s1 && !s2)) /* no match if only one ptr is NULL */ - return (int) (s1 - s2); /* if one of these is NULL it will be the - * lesser of the two values and therefore - * we'll get the proper sign in the int */ - - if (s1 == s2) { /* match if both ptrs the same (e.g. NULL) */ - return 0; - } - - value1 = 0; - value2 = 0; - while (*us1 != '\0') { - if (*us1 == PERCENT) { - esc_char_incr_in_s1 = 2; - - /* Convert 1st and 2nd hex chars to int */ - value1 = sippmh_htoi(*(us1 + 1)) * 16; - value1 += sippmh_htoi(*(us1 + 2)); - } else { - value1 = *us1; - } - - if (*us2 == PERCENT) { - esc_char_incr_in_s2 = 2; - - /* Convert 1st and 2nd hex chars to int */ - value2 = sippmh_htoi(*(us2 + 1)) * 16; - value2 += sippmh_htoi(*(us2 + 2)); - } else { - value2 = *us2; - } - - if ((ignore_case && (toupper(value1) == toupper(value2))) || - (!ignore_case && (value1 == value2))) { - us1 += (1 + esc_char_incr_in_s1); - us2 += (1 + esc_char_incr_in_s2); - esc_char_incr_in_s1 = 0; - esc_char_incr_in_s2 = 0; - } else { - break; - } - } - - if (ignore_case) { - return (toupper(value1) - toupper(value2)); - } else { - return (value1 - value2); - } -} - -int -sippmh_add_call_info (sipMessage_t *sip_message_p, cc_call_info_t *call_info_p) -{ - if (sip_message_p && call_info_p) { - char *call_info_hdr_p = ccsip_encode_call_info_hdr(call_info_p, NULL); - - if (call_info_hdr_p != NULL) { - (void) sippmh_add_text_header(sip_message_p, SIP_HEADER_CALL_INFO, - (const char *) call_info_hdr_p); - cpr_free(call_info_hdr_p); - } - } - return (0); -} - -/* - * Function: sippmh_parse_supported_require - * - * Parameters: contents of the Supported or Require header - * - * punsupported_tokens: if the caller wants to know the - * unsupported option tokens, it will pass a non-null pointer. - * If punsupporte_tokens is NULL, then the caller does not - * want to know the unsupported options. - * - * It is caller's responsibility to free the contents of this - * pointer. - * - * Description: This function will parse for the various options tags - * in the supported and require headers - * - * Returns: A bit map containing the values in the header - * - * Format of the line is as follows: - * Supported: replaces, join, sec-agree, whatever ... - * Require: replaces, join, sec-agree, whatever ... - */ -uint32_t -sippmh_parse_supported_require (const char *header, char **punsupported_tokens) -{ - const char *fname = "sippmh_parse_supported_require"; - uint32_t tags = 0; - char *temp_header; - char *token; - const char *delim = ", \r\n\t"; - int unsupported_tokens_size = 0; - char *bad_token = NULL; - int size; - char *lasts = NULL; - - if (header == NULL) { - return (tags); - } - - if (punsupported_tokens != NULL) { - *punsupported_tokens = NULL; //assume everything will go right - } - - //need to keep own buffer since PL_strtok_r is destructive - size = strlen(header) + 1; - temp_header = (char *) cpr_malloc(size); - if (temp_header == NULL) { - CCSIP_DEBUG_ERROR("%s: malloc failed for strlen(header)=%d\n", fname, - strlen(header)); - return tags; - } - sstrncpy(temp_header, header, size); - - token = PL_strtok_r(temp_header, delim, &lasts); - while (token != NULL) { - bad_token = NULL; - - if (strcmp(token, REQ_SUPP_PARAM_REPLACES) == 0) { - tags |= replaces_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_100REL) == 0) { - tags |= rel_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_EARLY_SESSION) == 0) { - tags |= early_session_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_JOIN) == 0) { - tags |= join_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_PATH) == 0) { - tags |= path_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_PRECONDITION) == 0) { - tags |= precondition_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_PREF) == 0) { - tags |= pref_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_PRIVACY) == 0) { - tags |= privacy_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_SEC_AGREE) == 0) { - tags |= sec_agree_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_TIMER) == 0) { - tags |= timer_tag; - bad_token = token; - } else if (strcmp(token, REQ_SUPP_PARAM_NOREFERSUB) == 0) { - tags |= norefersub_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_CALLINFO) == 0) { - tags |= cisco_callinfo_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_SERVICE_CONTROL) == 0) { - tags |= cisco_service_control_tag; - - } else if (strcmp(token, REQ_SUPP_PARAM_SDP_ANAT) == 0) { - tags |= sdp_anat_tag; - } - else if (strcmp(token, REQ_SUPP_PARAM_EXTENED_REFER) == 0) { - tags |= extended_refer_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_SERVICEURI) == 0) { - tags |= cisco_serviceuri_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_ESCAPECODES) == 0) { - tags |= cisco_escapecodes_tag; - } else if (strcmp(token, REQ_SUPP_PARAM_CISCO_SRTP_FALLBACK) == 0) { - tags |= cisco_srtp_fallback_tag; - } - else { - //This is not necessarily an error. Other end may support something we - //don't. Is only an error if it shows up in Require. - tags |= (uint32_t) unrecognized_tag; - bad_token = token; - } - - if (bad_token != NULL) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Invalid tag in Require/Supported %s\n", - DEB_F_PREFIX_ARGS(SIP_TAG, fname), bad_token); - - //allocate memory for unsupported options if necessary - if (punsupported_tokens) { - if (!*punsupported_tokens) { - unsupported_tokens_size = strlen(header) + 1; - *punsupported_tokens = (char *) cpr_malloc(unsupported_tokens_size); - if (*punsupported_tokens) { - memset(*punsupported_tokens, 0, unsupported_tokens_size); - } - } - } - - //caller wants to know what came in Require and we dont support - if (punsupported_tokens && *punsupported_tokens) { - //include token into illegal_tokens - if (strlen(*punsupported_tokens) > 0) { - sstrncat(*punsupported_tokens, ",", unsupported_tokens_size - strlen(*punsupported_tokens)); //add a "," - } - sstrncat(*punsupported_tokens, bad_token, unsupported_tokens_size - strlen(*punsupported_tokens)); - } - bad_token = NULL; - } - - //get next token - token = PL_strtok_r(NULL, delim, &lasts); - } - cpr_free(temp_header); - return (tags); -} - -/* - * Function: sippmh_parse_allow_header - * - * Parameters: contents of the Allow header - * - * Description: This function will parse for the various methods - * supported in the allow header - * - * Returns: A bit map containing the values in the header - * - * Format of the line is as follows: - * Allow: ACK, BYE, CANCEL, .... - */ -uint16_t -sippmh_parse_allow_header (const char *header) -{ - uint16_t tags = 0; - - if (header == NULL) { - return (tags); - } - if (strstr(header, SIP_METHOD_ACK)) { - tags |= ALLOW_ACK; - } - if (strstr(header, SIP_METHOD_BYE)) { - tags |= ALLOW_BYE; - } - if (strstr(header, SIP_METHOD_CANCEL)) { - tags |= ALLOW_CANCEL; - } - if (strstr(header, SIP_METHOD_INFO)) { - tags |= ALLOW_INFO; - } - if (strstr(header, SIP_METHOD_INVITE)) { - tags |= ALLOW_INVITE; - } - if (strstr(header, SIP_METHOD_MESSAGE)) { - tags |= ALLOW_MESSAGE; - } - if (strstr(header, SIP_METHOD_NOTIFY)) { - tags |= ALLOW_NOTIFY; - } - if (strstr(header, SIP_METHOD_OPTIONS)) { - tags |= ALLOW_OPTIONS; - } - if (strstr(header, SIP_METHOD_PRACK)) { - tags |= ALLOW_PRACK; - } - if (strstr(header, SIP_METHOD_PUBLISH)) { - tags |= ALLOW_PUBLISH; - } - if (strstr(header, SIP_METHOD_REFER)) { - tags |= ALLOW_REFER; - } - if (strstr(header, SIP_METHOD_REGISTER)) { - tags |= ALLOW_REGISTER; - } - if (strstr(header, SIP_METHOD_SUBSCRIBE)) { - tags |= ALLOW_SUBSCRIBE; - } - if (strstr(header, SIP_METHOD_UPDATE)) { - tags |= ALLOW_UPDATE; - } - return (tags); -} - -/* - * Function: sippmh_parse_accept_header - * - * Parameters: contents of the Accept header - * - * Description: This function will parse for the various capabilities - * signalled in the Accept header - * - * Returns: A bit map containing the values in the header - * - * Format of the line is as follows: - * Accept: application/sdp, nultipart/mixed, multipart/alternative - */ -uint16_t -sippmh_parse_accept_header (const char *header) -{ - uint16_t tags = 0; - - if (header == NULL) { - return (tags); - } - if (strstr(header, SIP_CONTENT_TYPE_SDP)) { - tags |= (0x01 << SIP_CONTENT_TYPE_SDP_VALUE); - } - if (strstr(header, SIP_CONTENT_TYPE_MULTIPART_MIXED)) { - tags |= (0x01 << SIP_CONTENT_TYPE_MULTIPART_MIXED_VALUE); - } - if (strstr(header, SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE)) { - tags |= (0x01 << SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE_VALUE); - } - return tags; -} - -/* - * Function: ccsip_process_network_message - * - * Parameters: sipmsg, pointer to pointer of the buffer - * bytes used, display message. - * - * Description: Currently only used for tcp packets received to do the - * framing. Ported from Propel. - * Returns: A bit map containing the values in the header - */ -ccsipRet_e -ccsip_process_network_message (sipMessage_t **sipmsg_p, - char **buf, - unsigned long *nbytes_used, - char **display_msg) -{ - static const char fname[] = "ccsip_process_network_message"; - sipMessage_t *sip_msg = NULL; - int local_nbytes = *nbytes_used; - uint32_t bytes_used; - char *local_buf_ptr; - - sip_msg = sippmh_message_create(); - if (sip_msg == NULL) { - CCSIP_ERR_DEBUG { - buginf("%s: Error in creating SIP Msg\n", fname); - } - *sipmsg_p = NULL; - return SIP_MSG_CREATE_ERR; - } - - /* Init local variables */ - bytes_used = local_nbytes; - local_buf_ptr = *buf; - - if (sippmh_process_network_message(sip_msg, local_buf_ptr, &bytes_used) - == STATUS_FAILURE) { - CCSIP_ERR_DEBUG { - buginf("%s: process_network_message failed.\n", fname); - } - sippmh_message_free(sip_msg); - *sipmsg_p = NULL; - return SIP_MSG_PARSE_ERR; - } - - if (sippmh_is_message_complete(sip_msg)) { - if (display_msg) { - *display_msg = (char *) cpr_malloc(bytes_used + 1); - if (*display_msg == NULL) { - CCSIP_ERR_DEBUG { - buginf("%s: malloc of display msg failed.\n", fname); - } - sippmh_message_free(sip_msg); - *sipmsg_p = NULL; - return SIP_MSG_PARSE_ERR; - } - sstrncpy(*display_msg, local_buf_ptr, bytes_used + 1); - } - local_nbytes -= bytes_used; - local_buf_ptr += bytes_used; - - /* Update information */ - *sipmsg_p = sip_msg; - *nbytes_used = local_nbytes; - *buf = local_buf_ptr; - - return SIP_SUCCESS; - } else { - CCSIP_ERR_DEBUG { - buginf("%s: process_network_msg: not complete\n", fname); - } - sippmh_message_free(sip_msg); - *sipmsg_p = NULL; - - return SIP_MSG_INCOMPLETE_ERR; - } -} - -/* - * Function: sippmh_parse_service_control_body - * - * Parameters: contents of the service control notify body and its length - * - * Description: This function will parse for the reset/restart - * instructions and parameters in this body - * - * Returns: 0 if body parsed correctly - * Parsed values are added to passed structure - * - * Format of the body is as follows: - * action = [reset | restart | check-version | call-preservation | apply-config ] - * RegisterCallId= {} - * ConfigVersionStamp = {79829A69-9489-4C8E-8143-90A9C22DFAD7} - * DialplanVersionStamp = {79829A69-9489-4C8E-8143-90A9C22DFAD7} - * SoftkeyVersionStamp = {79829A69-9489-4C8E-8143-90A9C22DFAD7} - * CUCMResult=[no_change | config_applied | reregister_needed] - * FirmwareLoadId = {SIP70.8-4-0-28S} - * LoadServer={10.81.15.24} - * LogServer={ } // This is used for ppid - * UpgradeTime=[now | later] - * PPID=[enabled | disabled] - */ - -sipServiceControl_t * -sippmh_parse_service_control_body (char *msgBody, int msgLength) -{ - pmhRstream_t *rs = NULL; - char *line = NULL, *value = NULL; - boolean body_read = FALSE; - sipServiceControl_t *scp = NULL; - - if (msgLength==0) { - return (NULL); - } - - if ((rs = pmhutils_rstream_create(msgBody, msgLength)) - == NULL) { - return (NULL); - } - - scp = (sipServiceControl_t *) - cpr_calloc(1, sizeof(sipServiceControl_t)); - if (!scp) { - cpr_free(rs); - return NULL; - } - - while (!body_read) { - line = pmhutils_rstream_read_line(rs); - if (line) { - value = strchr(line, '='); - if (value) { - value++; - while (*value == ' ') { - value++; - } - } - if (strlen(line) == 0) { - - } else if (!strncasecmp(line, "action", sizeof("action") - 1)) { - if (value == NULL) { - scp->action = SERVICE_CONTROL_ACTION_INVALID; - } else if (!strncasecmp(value, "reset", sizeof("reset") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_RESET; - } else if (!strncasecmp(value, "restart", - sizeof("restart") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_RESTART; - } else if (!strncasecmp(value, "check-version", - sizeof("check-version") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_CHECK_VERSION; - } else if (!strncasecmp(value, "call-preservation", - sizeof("call-preservation") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_CALL_PRESERVATION; - } else if (!strncasecmp(value, "apply-config", - sizeof("apply-config") - 1)) { - scp->action = SERVICE_CONTROL_ACTION_APPLY_CONFIG; - - } else { - scp->action = SERVICE_CONTROL_ACTION_INVALID; - } - } else if (!strncasecmp(line, "RegisterCallId", - sizeof("RegisterCallId") - 1)) { - if (scp->registerCallID == NULL) { - if (value == NULL) { - scp->registerCallID = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->registerCallID = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->registerCallID) - memcpy(scp->registerCallID, value + 1, - (len - 2)); - } - } - } - - } else if (!strncasecmp(line, "ConfigVersionStamp", - sizeof("ConfigVersionStamp") - 1)) { - if (scp->configVersionStamp == NULL) { - if (value == NULL) { - scp->configVersionStamp = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->configVersionStamp = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->configVersionStamp) - memcpy(scp->configVersionStamp, value + 1, - (len - 2)); - } - } - } - - } else if (!strncasecmp(line, "DialplanVersionStamp", - sizeof("DialplanVersionStamp") - 1)) { - if (scp->dialplanVersionStamp == NULL) { - if (value == NULL) { - scp->dialplanVersionStamp = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->dialplanVersionStamp = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->dialplanVersionStamp) - memcpy(scp->dialplanVersionStamp, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "SoftkeyVersionStamp", - sizeof("SoftkeyVersionStamp") - 1)) { - if (scp->softkeyVersionStamp == NULL) { - if (value == NULL) { - scp->softkeyVersionStamp = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->softkeyVersionStamp = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->softkeyVersionStamp) - memcpy(scp->softkeyVersionStamp, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "FeatureControlVersionStamp", - sizeof("FeatureControlVersionStamp") - 1)) { - if (scp->fcpVersionStamp == NULL) { - if (value == NULL) { - scp->fcpVersionStamp = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->fcpVersionStamp = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->fcpVersionStamp) - memcpy(scp->fcpVersionStamp, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "CUCMResult", - sizeof("CUCMResult") - 1)) { - if (value == NULL) { - scp->cucm_result = NULL; - } else { - int len =0; - if ((strncasecmp(value, "no_change", - len = strlen("no_change")) == 0) || - (strncasecmp(value, "config_applied", - len = strlen("config_applied")) == 0) || - (strncasecmp(value, "reregister_needed", - len = strlen("reregister_needed")) == 0)) { - scp->cucm_result = (char *) cpr_calloc(1,len + 1); - if (scp->cucm_result) { - sstrncpy(scp->cucm_result, value, len); - scp->cucm_result[len] = '\0'; - } - } - } - } else if (!strncasecmp(line, "LoadId", - sizeof("LoadId") - 1)) { - if (scp->firmwareLoadId == NULL) { - if (value == NULL) { - scp->firmwareLoadId = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->firmwareLoadId = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->firmwareLoadId) - memcpy(scp->firmwareLoadId, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "InactiveLoadId", - sizeof("InactiveLoadId") - 1)) { - if (scp->firmwareInactiveLoadId == NULL) { - if (value == NULL) { - scp->firmwareInactiveLoadId = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->firmwareInactiveLoadId = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->firmwareInactiveLoadId) - memcpy(scp->firmwareInactiveLoadId, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "LoadServer", - sizeof("LoadServer") - 1)) { - if (scp->loadServer == NULL) { - if (value == NULL) { - scp->loadServer = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->loadServer = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->loadServer) - memcpy(scp->loadServer, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "LogServer", - sizeof("LogServer") - 1)) { - if (scp->logServer == NULL) { - if (value == NULL) { - scp->logServer = NULL; - } else if (value[0]) { - int len = strlen(value); - - /* make sure curly braces are present */ - if ((*value == '{') && (*(value + len - 1) == '}')) { - scp->logServer = (char *) - cpr_calloc(1, len + 1); - /* ignore the beginning and ending curly brace */ - if (scp->logServer) - memcpy(scp->logServer, value + 1, - (len - 2)); - } - } - } - } else if (!strncasecmp(line, "PPID", sizeof("PPID") - 1)) { - if (value == NULL) { - scp->ppid = FALSE; - } else if (!strncasecmp(value, "enabled", sizeof("enabled") - 1)) { - scp->ppid = TRUE; - } else if (!strncasecmp(value, "disabled", - sizeof("disabled") - 1)) { - scp->ppid = FALSE; - } else { - scp->ppid = FALSE; - } - - } - cpr_free(line); - - } else { - body_read = TRUE; - } - } - // Free the created stream structure - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return (scp); -} - -void -sippmh_free_service_control_info (sipServiceControl_t *scp) -{ - if (!scp) { - return; - } - - if (scp->configVersionStamp) - cpr_free(scp->configVersionStamp); - if (scp->dialplanVersionStamp) - cpr_free(scp->dialplanVersionStamp); - if (scp->registerCallID) - cpr_free(scp->registerCallID); - if (scp->softkeyVersionStamp) - cpr_free(scp->softkeyVersionStamp); - if (scp->fcpVersionStamp) - cpr_free(scp->fcpVersionStamp); - if (scp->cucm_result) - cpr_free(scp->cucm_result); - if (scp->loadServer) - cpr_free(scp->loadServer); - if (scp->firmwareLoadId) - cpr_free(scp->firmwareLoadId); - if (scp->logServer) - cpr_free(scp->logServer); - - cpr_free(scp); -} - -int32_t -sippmh_parse_max_forwards (const char *max_fwd_hdr) -{ - int32_t maxFwd; - - if (max_fwd_hdr) { - if (isdigit(*max_fwd_hdr)) { - maxFwd = strtol(max_fwd_hdr, NULL, 10); - if ((maxFwd >= 0) && (maxFwd <= 255)) { - return maxFwd; - } - } - } - return -1; -} - -/* - * Function: sippmh_parse_url_from_hdr - * - * Parameters: String that needs to be parsed - * - * Description: This function will strip out the tags and - * other characters in the header to retreive - * a string that could be used as the request uri. - * Note that the input string needs to be well formed. - * - * Returns: A string containing the request uri - * - */ -string_t -sippmh_get_url_from_hdr (char *input_str) -{ - char *left_bracket, *right_bracket = NULL; - - /* - This function is only intended for properly - formed headers. - */ - left_bracket = strpbrk(input_str, ",<"); - if (left_bracket) { - left_bracket++; - right_bracket = strchr(left_bracket, '>'); - if (right_bracket) { - *right_bracket = '\0'; - } - input_str = left_bracket; - } - return (string_t)input_str; -} -/* - * Function: sippmh_parse_join_header - * - * Parameters: pointer to string of the join header contents - * - * Returns: Parsed structure if parsed correctly, NULL otherwise - * - * Format of the header is as follows: - * Join: abcd;from-tag=efgh;to-tag=ijkl - */ -sipJoinInfo_t * -sippmh_parse_join_header (const char *header) -{ - sipJoinInfo_t *join = NULL; - char *semi = NULL; - unsigned int param_len; - char *params, *param_name, *param_value, *save_params; - - if (!header) { - return NULL; - } - - join = (sipJoinInfo_t *) cpr_calloc(1, sizeof(sipJoinInfo_t)); - if (!join) { - return NULL; - } - - // Read the call-id, if present - semi = strchr(header, SEMI_COLON); - if (semi) { - join->call_id = (char *) cpr_calloc(1, semi-header + 1); - if (join->call_id == NULL) { - sippmh_free_join_info(join); - return NULL; - } - sstrncpy(join->call_id, header, semi-header); - } else { - // call-id is the only parameter - join->call_id = cpr_strdup(header); - if (join->call_id == NULL) { - sippmh_free_join_info(join); - return NULL; - } - return (join); - } - - params = cpr_strdup(semi); - if (!params) { - sippmh_free_join_info(join); - return NULL; - } - save_params = params; - while (1) { - while (*params == ';') { - params++; - } - param_name = params; - SKIP_SIP_TOKEN(params); - param_len = params - param_name; - if (param_len == 0) { - sippmh_free_join_info(join); - cpr_free(save_params); - return NULL; - } - - /* Parse from-tag parameter */ - if ((param_len == sizeof(SIP_HEADER_JOIN_FROM_TAG) - 1) && - (strncasecmp(param_name, SIP_HEADER_JOIN_FROM_TAG, - sizeof(SIP_HEADER_JOIN_FROM_TAG) - 1) == 0) && - (join->from_tag == NULL)) { - params = parse_generic_param(params, ¶m_value); - if (params == NULL) { - sippmh_free_join_info(join); - cpr_free(save_params); - return NULL; - } else { - join->from_tag = (char *) cpr_calloc(1, params-param_value + 1); - if (join->from_tag) { - sstrncpy(join->from_tag, param_value, params-param_value + 1); - } - SKIP_LWS(params); - if (*params == SEMI_COLON) { - *params++ = '\0'; - } else { - break; - } - - } - - /* Parse to-tag parameter */ - } else if ((param_len == sizeof(SIP_HEADER_JOIN_TO_TAG) - 1) && - (strncasecmp(param_name, SIP_HEADER_JOIN_TO_TAG, - sizeof(SIP_HEADER_JOIN_TO_TAG) - 1) == 0) && - (join->to_tag == NULL)) { - params = parse_generic_param(params, ¶m_value); - if (params == NULL) { - sippmh_free_join_info(join); - cpr_free(save_params); - return NULL; - } else { - join->to_tag = (char *) cpr_calloc(1, params-param_value + 1); - if (join->to_tag) { - sstrncpy(join->to_tag, param_value, params-param_value + 1); - } - if (*params == SEMI_COLON) { - *params++ = '\0'; - } else { - break; - } - } - - } else { - // Skip over unexpected parameter - SKIP_SIP_TOKEN(params); - } - - SKIP_LWS(params); - } - cpr_free(save_params); - return (join); -} - -void -sippmh_free_join_info (sipJoinInfo_t *join) -{ - - if (!join) { - return; - } - if (join->call_id) - cpr_free(join->call_id); - if (join->from_tag) - cpr_free(join->from_tag); - if (join->to_tag) - cpr_free(join->to_tag); - cpr_free(join); -} - -sipRet_t -sippmh_add_join_header (sipMessage_t *message, sipJoinInfo_t *join) -{ - char joinhdr[MAX_SIP_HEADER_LENGTH+1]; - int left; - - // Write out the header in a buffer - if (!message) { - return STATUS_FAILURE; - } - - snprintf(joinhdr, MAX_SIP_HEADER_LENGTH, "%s", join->call_id); - left = (uint16_t) MAX_SIP_HEADER_LENGTH - strlen(join->call_id); - if (join->from_tag && left > 0) { - sstrncat(joinhdr, ";from-tag=", left); - left -= sizeof(";from-tag=") - 1; - sstrncat(joinhdr, join->from_tag, left); - left -= strlen(join->from_tag); - } - if (join->to_tag && left > 0) { - sstrncat(joinhdr, ";to-tag=", left); - left -= sizeof(";to-tag=") - 1; - sstrncat(joinhdr, join->to_tag, left); - } - return (sippmh_add_text_header(message, SIP_HEADER_JOIN, joinhdr)); -} - -/* - * Function: sippmh_parse_subscription_state - * - * Parameters: contents of the Subscription-State header - * - * Description: This function will parse for the state, expiry - * time, and a reason code in the header - * - * Returns: -1 if error, 0 if successfully parsed. - * - * Format of the line is as follows: - * Subscription-State: active;expires=7200;reason=whatever;retry-after=50 - */ -int -sippmh_parse_subscription_state(sipSubscriptionStateInfo_t *subsStateInfo, - const char *subs_state) -//TODO: how can subs_state be a const char [] when it can be modified below? -{ - char *ptr; - char temp[TEMP_PARSE_BUFFER_SIZE]; - uint8_t i; - - if (!subs_state) { - return (-1); - } - - if (!strncasecmp(subs_state, SIP_SUBSCRIPTION_STATE_ACTIVE, - sizeof(SIP_SUBSCRIPTION_STATE_ACTIVE) - 1)) { - subsStateInfo->state = SUBSCRIPTION_STATE_ACTIVE; - } else if (!strncasecmp(subs_state, SIP_SUBSCRIPTION_STATE_PENDING, - sizeof(SIP_SUBSCRIPTION_STATE_PENDING) - 1)) { - subsStateInfo->state = SUBSCRIPTION_STATE_PENDING; - } else if (!strncasecmp(subs_state, SIP_SUBSCRIPTION_STATE_TERMINATED, - sizeof(SIP_SUBSCRIPTION_STATE_PENDING) - 1)) { - subsStateInfo->state = SUBSCRIPTION_STATE_TERMINATED; - } - - ptr = strchr(subs_state, ';'); - if (!ptr) { - return (0); - } - SKIP_LWS(ptr); - - // Look for expires tag - ptr = strstr(subs_state, SIP_SUBSCRIPTION_STATE_EXPIRES); - if (ptr) { - ptr = ptr + sizeof(SIP_SUBSCRIPTION_STATE_EXPIRES); // Go over the '=' - SKIP_LWS(ptr); - if (*ptr) { - boolean is_int = FALSE; - - memset(temp, 0, sizeof(temp)); - i = 0; - while (isdigit(*ptr) && (i < sizeof(temp)-1)) { - temp[i++] = *ptr; - ptr++; - is_int = TRUE; - } - if (is_int == TRUE) { - subsStateInfo->expires = strtoul(temp, NULL, 10); - } - } - } - // Look for reason tag - ptr = strstr(subs_state, SIP_SUBSCRIPTION_STATE_REASON); - if (ptr) { - ptr = ptr + sizeof(SIP_SUBSCRIPTION_STATE_REASON); - SKIP_LWS(ptr); - if (*ptr) { - if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_DEACTIVATED, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_DEACTIVATED) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_DEACTIVATED; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_PROBATION, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_PROBATION) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_PROBATION; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_REJECTED, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_REJECTED) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_REJECTED; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_TIMEOUT, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_TIMEOUT) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_TIMEOUT; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_GIVEUP, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_GIVEUP) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_GIVEUP; - } else if (!strncasecmp(ptr, SIP_SUBSCRIPTION_STATE_REASON_NORESOURCE, - sizeof(SIP_SUBSCRIPTION_STATE_REASON_NORESOURCE) - 1)) { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_NORESOURCE; - } else { - subsStateInfo->reason = SUBSCRIPTION_STATE_REASON_INVALID; - } - } - } - - // Look for retry-after tag - ptr = strstr(subs_state, SIP_SUBSCRIPTION_STATE_RETRY_AFTER); - if (ptr) { - ptr = ptr + sizeof(SIP_SUBSCRIPTION_STATE_RETRY_AFTER); // Go over the '=' - SKIP_LWS(ptr); - if (*ptr) { - boolean is_int = FALSE; - - memset(temp, 0, sizeof(temp)); - i = 0; - while (isdigit(*ptr) && (i < sizeof(temp)-1)) { - temp[i++] = *ptr; - ptr++; - is_int = TRUE; - } - if (is_int == TRUE) { - *ptr = '\0'; - subsStateInfo->retry_after = strtoul(temp, NULL, 10); - } - } - } - - return (0); -} - -/* - * Function: sippmh_add_subscription_state - * - * Parameters: contents of the Subscription-State header - * - * Description: This function will add the subscription state header - * - * Returns: -1 if error, 0 if successfully added - * - * Format of the line is as follows: - * Subscription-State: active; expires=7200; reason=whatever - */ -int -sippmh_add_subscription_state(sipMessage_t *msg, - sipSubscriptionStateInfo_t *subsStateInfo) -{ - char subs_state[MAX_SUB_STATE_HEADER_SIZE]; - - if (!msg) { - return -1; - } - - if ((subsStateInfo->state == SUBSCRIPTION_STATE_ACTIVE) && (subsStateInfo->expires == 0)) { - snprintf(&subs_state[0], MAX_SUB_STATE_HEADER_SIZE, "%s", SIP_SUBSCRIPTION_STATE_ACTIVE); - } else if (subsStateInfo->state == SUBSCRIPTION_STATE_ACTIVE) { - snprintf(&subs_state[0], MAX_SUB_STATE_HEADER_SIZE, "%s; expires=%d", - SIP_SUBSCRIPTION_STATE_ACTIVE, - subsStateInfo->expires); - } else if (subsStateInfo->state == SUBSCRIPTION_STATE_PENDING) { - snprintf(&subs_state[0], MAX_SUB_STATE_HEADER_SIZE, "%s; expires=%d", - SIP_SUBSCRIPTION_STATE_PENDING, - subsStateInfo->expires); - } else if (subsStateInfo->state == SUBSCRIPTION_STATE_TERMINATED) { - snprintf(&subs_state[0], MAX_SUB_STATE_HEADER_SIZE, "%s; reason=timeout", - SIP_SUBSCRIPTION_STATE_TERMINATED); - } - - (void) sippmh_add_text_header(msg, SIP_HEADER_SUBSCRIPTION_STATE, - (const char *)&subs_state[0]); - return 0; -} - -boolean -sippmh_parse_kpml_event_id_params (char *params, char **call_id, - char **from_tag, char **to_tag) -{ - boolean params_good; - int param_len; - char *param_name; - - if (params == NULL) { - return FALSE; - } - - while (1) { - params_good = FALSE; - - while (*params == ';') { - params++; - } - - param_name = params; - SKIP_SIP_TOKEN(params); - param_len = params - param_name; - if (param_len == 0) { - return FALSE; - } - - /* Parse call-id parameter */ - if ((param_len == KPML_ID_CALLID_LEN) && - (strncasecmp(param_name, KPML_ID_CALLID, KPML_ID_CALLID_LEN) == 0)) { - params = parse_generic_param(params, call_id); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse from-tag parameter */ - } else if ((param_len == KPML_ID_FROM_TAG_LEN) && - (strncasecmp(param_name, KPML_ID_FROM_TAG, - KPML_ID_FROM_TAG_LEN) == 0)) { - params = parse_generic_param(params, from_tag); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - /* Parse to-tag parameter */ - } else if ((param_len == KPML_ID_TO_TAG_LEN) && - (strncasecmp(param_name, KPML_ID_TO_TAG, - KPML_ID_TO_TAG_LEN) == 0)) { - params = parse_generic_param(params, to_tag); - if (params == NULL) { - return FALSE; - } else { - params_good = TRUE; - } - - } - - SKIP_LWS(params); - if (*params == SEMI_COLON) { - /* More parameters follow */ - *params++ = '\0'; - SKIP_LWS(params); - } else { - break; - } - } - - return params_good; -} diff --git a/libs/sipcc/core/sipstack/ccsip_publish.c b/libs/sipcc/core/sipstack/ccsip_publish.c deleted file mode 100644 index acde663e9f..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_publish.c +++ /dev/null @@ -1,896 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ccsip_publish.h" -#include "phntask.h" -#include "sip_common_transport.h" -#include "ccsip_task.h" -#include "ccsip_callinfo.h" -#include "ccsip_macros.h" -#include "util_string.h" -#include "cpr_rand.h" -#include "platform_api.h" -#include "ccsip_register.h" -#include "ccsip_reldev.h" -#include "debug.h" - -static sll_handle_t s_PCB_list = NULL; // signly linked list handle of PCBs -static int outgoingPublishes; - -static boolean sipSPISendPublish(ccsip_publish_cb_t *pcb_p, boolean authen); -static void free_pending_reqs (sll_handle_t list); - -/** - * This function will generate a new handle and return it. - * - * @return a non-zero integer value - */ -static pub_handle_t generate_new_pub_handle (void) -{ - static pub_handle_t handle = 0; - - handle++; - if (handle == NULL_PUBLISH_HANDLE) { - handle++; - } - return handle; -} - -/** - * This function will check if it is the PCB we are looking for based on the key. - * This is only invoked by sll_find(). - * - * @param[in] key - pointer to the key. - * @param[in] data - pointer to a node data. - * - * @return SLL_MATCH_FOUND if the node matches. - * Otherwise, SLL_MATCH_NOT_FOUND is returned. - * - * @pre (key != NULL) and (data != NULL) - */ -static sll_match_e is_matching_pcb (void *key, void *data) -{ - pub_handle_t pub_handle = *((pub_handle_t *)key); - ccsip_publish_cb_t *pcb_p = (ccsip_publish_cb_t *)data; - - if (pub_handle == pcb_p->pub_handle) { - return SLL_MATCH_FOUND; - } - return SLL_MATCH_NOT_FOUND; -} - -/** - * This function will create a PCB. It will also create the PCB linked list. - * - * @return NULL if there are no resources to create a PCB. - * Otherwise, pointer to a new PCB is returned. - * - * @pre (key != NULL) and (data != NULL) - */ -static ccsip_publish_cb_t *get_new_pcb (void) -{ - ccsip_publish_cb_t *pcb_p; - - /* - * If PCB list is not created yet, create the list. - */ - if (s_PCB_list == NULL) { - s_PCB_list = sll_create(is_matching_pcb); - if (s_PCB_list == NULL) { - return NULL; - } - } - - pcb_p = (ccsip_publish_cb_t *)cpr_malloc(sizeof(ccsip_publish_cb_t)); - if (pcb_p == NULL) { - return NULL; - } - memset(pcb_p, 0, sizeof(ccsip_publish_cb_t)); - pcb_p->pub_handle = generate_new_pub_handle(); - pcb_p->hb.cb_type = PUBLISH_CB; - pcb_p->hb.dn_line = 1; // for now set it to primary line. This will change when we do line based PUBLISH. - /* - * set up dest & src ip addr and port number. - */ - ccsip_common_util_set_dest_ipaddr_port(&pcb_p->hb); - ccsip_common_util_set_src_ipaddr(&pcb_p->hb); - pcb_p->hb.local_port = sipTransportGetListenPort(pcb_p->hb.dn_line, NULL); - pcb_p->retry_timer.timer = cprCreateTimer("PUBLISH retry timer", - SIP_PUBLISH_RETRY_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (pcb_p->retry_timer.timer == NULL) { - cpr_free(pcb_p); - return NULL; - } - pcb_p->pending_reqs = sll_create(NULL); - if (pcb_p->pending_reqs == NULL) { - (void)cprDestroyTimer(pcb_p->retry_timer.timer); - cpr_free(pcb_p); - return NULL; - } - (void) sll_append(s_PCB_list, pcb_p); - - return pcb_p; -} - -/** - * This function will find matching PCB by the key in the PCB list. - * - * @param[in] pub_handle - publish handle. - * - * @return NULL if there is no matching PCB - * Otherwise, pointer to the found PCB is returned. - * - * @pre (pub_handle > 0) and (s_PCB_list != NULL) - */ -static ccsip_publish_cb_t *find_pcb (pub_handle_t pub_handle) -{ - ccsip_publish_cb_t *pcb_p; - - pcb_p = (ccsip_publish_cb_t *)sll_find(s_PCB_list, &pub_handle); - - return pcb_p; -} - -/** - * This function will find matching PCB by the SIP Call-ID in the PCB list. - * - * @param[in] callID_p - SIP Call-ID - * - * @return NULL if there is no matching PCB - * Otherwise, pointer to the found PCB is returned. - * - * @pre (callID_p != NULL) - */ -static ccsip_publish_cb_t *find_pcb_by_sip_callid (const char *callID_p) -{ - ccsip_publish_cb_t *pcb_p; - - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); - while (pcb_p != NULL) { - if (strncmp(callID_p, pcb_p->hb.sipCallID, (sizeof(pcb_p->hb.sipCallID) -1)) == 0) { - return pcb_p; - } - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, pcb_p); - } - return NULL; -} - -/** - * This function will free up the PCB resources and removes it from the PCB list. - * - * @param[in] pcb_p - pointer to a PCB. - * - * @return none - * - * @pre (pcb_p != NULL) - */ -static void free_pcb (ccsip_publish_cb_t *pcb_p) -{ - if (pcb_p->hb.authen.authorization != NULL) { - cpr_free(pcb_p->hb.authen.authorization); - } - if (pcb_p->hb.authen.sip_authen != NULL) { - sippmh_free_authen(pcb_p->hb.authen.sip_authen); - } - - cpr_free(pcb_p->entity_tag); - free_pending_reqs(pcb_p->pending_reqs); - (void)cprDestroyTimer(pcb_p->retry_timer.timer); - free_event_data(pcb_p->hb.event_data_p); - (void)sll_remove(s_PCB_list, (void *)pcb_p); - cpr_free(pcb_p); -} - -/** - * This function will append the application request in a pending list. - * - * @param[in] pcb_p - pointer to a PCB. - * @param[in] msg_p - pointer to an application request. - * - * @return TRUE if it is successful. - * Otherwise, FALSE is returned. - * - * @pre (pcb_p != NULL) and (msg_p != NULL) - * @post ((slink_list_t *)s_pres_req_list->count++) - */ -static boolean append_pending_reqs (ccsip_publish_cb_t *pcb_p, pub_req_t *msg_p) -{ - pub_req_t *temp_msg_p; - - temp_msg_p = (pub_req_t *)cpr_malloc(sizeof(pub_req_t)); - if (temp_msg_p == NULL) { - return FALSE; - } - (*temp_msg_p) = (*msg_p); - (void) sll_append(pcb_p->pending_reqs, temp_msg_p); - return TRUE; -} - -/** - * This function will free up entire list of pending requests - * - * @param[in] list - pending requests list handle - * - * @return none - * - */ -static void free_pending_reqs (sll_handle_t list) -{ - pub_req_t *msg_p; - - if (list == NULL) { - return; - } - - msg_p = (pub_req_t *)sll_next(list, NULL); - while (msg_p != NULL) { - free_event_data(msg_p->event_data_p); - (void)sll_remove(list, (void *)msg_p); - cpr_free(msg_p); - msg_p = (pub_req_t *)sll_next(list, NULL); - } - sll_destroy(list); -} - -/** - * This function will send the PUBLSIH request response to the application. - * - * @param[in] resp_code - this also includes error responses that start at 1000 - * @param[in] pub_handle - handle to a PCB - * @param[in] app_handle - application generated handle to this PUBLISH context. - * @param[in] callback_task - task in which the application resides. - * @param[in] resp_msg_id - messageID posted to the task. - * - * @return none - */ -static void send_resp_to_app (int resp_code, pub_handle_t pub_handle, pub_handle_t app_handle, - cc_srcs_t callback_task, int resp_msg_id) -{ - static const char fname[] = "send_resp_to_app"; - pub_rsp_t rsp; - - rsp.resp_code = resp_code; - rsp.pub_handle = pub_handle; - rsp.app_handle = app_handle; - if (publish_int_response(&rsp, callback_task, resp_msg_id) != CC_RC_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Failed to post PUBLISH response to the application", fname); - } -} - -/** - * This function will process SIPSPI_EV_CC_PUBLISH posted by applications. - * If there is an outstanding transaction, it will hold the request in the pending list. - * - * @param[in] buf - inter-process message buffer. - * - * @return SIP_OK if it successfully processes the request. - * SIP_ERROR if it fails to process the request. - * SIP_DEFER if it defers the processing. - * - * @note This will not free buf. - * - * @pre (buf != NULL) - */ -int publish_handle_ev_app_publish (cprBuffer_t buf) -{ - static const char fname[] = "publish_handle_ev_app_publish"; - pub_req_t *msg_p = (pub_req_t *)buf; - ccsip_publish_cb_t *pcb_p; - - - /* - * If this is initial PUBLISH, allocate a PCB. - * Otherwise, look up for PCB based on pub_handle. - */ - if (msg_p->pub_handle != NULL_PUBLISH_HANDLE) { - pcb_p = find_pcb(msg_p->pub_handle); - - if (pcb_p == NULL) { - send_resp_to_app(PUBLISH_FAILED_NOCONTEXT, msg_p->pub_handle, msg_p->app_handle, - msg_p->callback_task, msg_p->resp_msg_id); - free_event_data(msg_p->event_data_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX - "Modification PUBLISH cannot be sent as the PCB is missing\n", - fname); - return SIP_ERROR; - } - - /* - * Check if there is an outstanding transaction. - * if so, put the request in pending request queue. - */ - if (pcb_p->outstanding_trxn == TRUE) { - if (append_pending_reqs(pcb_p, msg_p) == TRUE) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"deffering as there is an outstanding transaction\n", - DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_DEFER; - } - /* free up PCB and respond with error */ - free_pcb (pcb_p); - send_resp_to_app(PUBLISH_FAILED_NORESOURCE, msg_p->pub_handle, msg_p->app_handle, - msg_p->callback_task, msg_p->resp_msg_id); - free_event_data(msg_p->event_data_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Queueing outgoing PUBLISH request failed\n", fname); - return SIP_ERROR; - } - /* - * if event_data_p is NULL, this is terminating PUBLISH. - * otherwise, it is a modifying PUBLISH. - */ - free_event_data(pcb_p->hb.event_data_p); - pcb_p->hb.event_data_p = msg_p->event_data_p; - if ((msg_p->event_data_p == NULL) && (msg_p->expires == 0)) { // removing PUBLISH - pcb_p->hb.orig_expiration = 0; - } - } else { - pcb_p = get_new_pcb(); - if (pcb_p == NULL) { - send_resp_to_app(PUBLISH_FAILED_NORESOURCE, msg_p->pub_handle, msg_p->app_handle, - msg_p->callback_task, msg_p->resp_msg_id); - free_event_data(msg_p->event_data_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"PCB allocation failed\n", fname); - return SIP_ERROR; - } - pcb_p->app_handle = msg_p->app_handle; - sstrncpy(pcb_p->ruri, msg_p->ruri, MAX_URI_LENGTH); - sstrncpy(pcb_p->esc, msg_p->esc, MAX_URI_LENGTH); - pcb_p->hb.orig_expiration = msg_p->expires; - pcb_p->hb.event_type = msg_p->event_type; - pcb_p->hb.event_data_p = msg_p->event_data_p; - pcb_p->callback_task = msg_p->callback_task; - pcb_p->resp_msg_id = msg_p->resp_msg_id; - } - - pcb_p->hb.authen.cred_type = 0; - - if (sipSPISendPublish(pcb_p, FALSE) == TRUE) { - pcb_p->outstanding_trxn = TRUE; - outgoingPublishes++; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"PUBLISH request sent successfully\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_OK; - } - - /* free up PCB and respond with error */ - free_pcb (pcb_p); - send_resp_to_app(PUBLISH_FAILED_SEND, msg_p->pub_handle, msg_p->app_handle, - msg_p->callback_task, msg_p->resp_msg_id); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Failed to send PUBLISH request\n", fname); - return SIP_ERROR; - -} - - -/** - * This function will create the PUBLISH message and send it. it also starts the retry timer. - * - * @param[in] pcb_p - pointer to PCB - * @param[in] authen - boolean that indicates whether to add authorization header. - * - * @return TRUE if it successfully sent PUBLISH - * Otherwise, FALSE is returned - * - * @pre (pcb_p != NULL) - */ -static boolean sipSPISendPublish (ccsip_publish_cb_t *pcb_p, boolean authen) -{ - static const char fname[] = "sipSPISendPublish"; - static uint32_t cseq = 0; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char *domainloc; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char sip_temp_str[MAX_SIP_URL_LENGTH]; - char sip_temp_tag[MAX_SIP_URL_LENGTH]; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char via[SIP_MAX_VIA_LENGTH]; - int max_forwards_value = 70; - static uint16_t count = 1; - sipMessage_t *request = NULL; - int timeout = 0; - - request = GET_SIP_MESSAGE(); - if (!request) { - return FALSE; - } - - /* - * Populate full RURI if it is not yet. Sometimes, applications may only provide user part. - */ - if (pcb_p->full_ruri[0] == 0) { - sstrncpy(pcb_p->full_ruri, "sip:", MAX_SIP_URL_LENGTH); - sstrncat(pcb_p->full_ruri, pcb_p->ruri, MAX_SIP_URL_LENGTH - sizeof("sip:")); - /* check if it has host part */ - domainloc = strchr(pcb_p->full_ruri, '@'); - if (domainloc == NULL) { - domainloc = pcb_p->full_ruri + strlen(pcb_p->full_ruri); - if ((domainloc - pcb_p->full_ruri) < (MAX_SIP_URL_LENGTH - 1)) { - /* Do not include @ when there is no user part */ - if (pcb_p->ruri[0] != '\0') { - *domainloc++ = '@'; - } - ipaddr2dotted(dest_sip_addr_str, &pcb_p->hb.dest_sip_addr); - sstrncpy(domainloc, dest_sip_addr_str, - MAX_SIP_URL_LENGTH - (domainloc - (pcb_p->full_ruri))); - } - } - } - - ipaddr2dotted(src_addr_str, &pcb_p->hb.src_addr); - - // Add request line - if (HSTATUS_SUCCESS != sippmh_add_request_line(request, - sipGetMethodString(sipMethodPublish), - pcb_p->full_ruri, SIP_VERSION)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Request line\n", fname); - free_sip_message(request); - return (FALSE); - } - - // Add local Via - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s%.8x", - sipTransportGetTransportType(1, TRUE, NULL), - src_addr_str, pcb_p->hb.local_port, VIA_BRANCH, - VIA_BRANCH_START, (unsigned int) cpr_rand()); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_VIA, via)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding VIA header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // Add To Header - snprintf(sip_temp_str, MAX_SIP_URL_LENGTH, "<%s>", pcb_p->full_ruri); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_TO, sip_temp_str)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding TO header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // Add From Header. - sstrncat(sip_temp_str, ";tag=", MAX_SIP_URL_LENGTH - strlen(sip_temp_str)); - sip_util_make_tag(sip_temp_tag); - sstrncat(sip_temp_str, sip_temp_tag, MAX_SIP_URL_LENGTH - strlen(sip_temp_str)); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_FROM, sip_temp_str)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding FROM header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // Add Call-ID Header. - platform_get_wired_mac_address(mac_address); - count++; - snprintf(pcb_p->hb.sipCallID, MAX_SIP_CALL_ID, "%.4x%.4x-%.4x%.4x-%.8x-%.8x@%s", // was MAX_SIP_URL_LENGTH - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], count, - (unsigned int) cpr_rand(), - (unsigned int) cpr_rand(), - src_addr_str); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CALLID, pcb_p->hb.sipCallID)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CALLID header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // Add Contact header. Contact header is not needed as per RFC. BUT CCM needs it. - snprintf(sip_temp_str, MAX_SIP_URL_LENGTH, "", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - src_addr_str, pcb_p->hb.local_port); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CONTACT, sip_temp_str)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Contact header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // Add Cseq. - cseq++; - if (cseq == 0) { - cseq = 1; - } - if (HSTATUS_SUCCESS != sippmh_add_cseq(request, sipGetMethodString(sipMethodPublish), cseq)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CSEQ header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // Add UserAgent header - (void) sippmh_add_text_header(request, SIP_HEADER_USER_AGENT, - sipHeaderUserAgent); - - - // Add SIP-If-Match header. - if (pcb_p->entity_tag != NULL) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_SIPIFMATCH, - pcb_p->entity_tag)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Event header\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - // Add Expires Header - if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_EXPIRES, - pcb_p->hb.orig_expiration)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Expires header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // Add max-forwards header - config_get_value(CFGID_SIP_MAX_FORWARDS, &max_forwards_value, - sizeof(max_forwards_value)); - if (HSTATUS_SUCCESS != - sippmh_add_int_header(request, SIP_HEADER_MAX_FORWARDS, - max_forwards_value)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Max-Forwards header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // add Authorization header - if (authen) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, AUTHOR_HDR(pcb_p->hb.authen.status_code), - pcb_p->hb.authen.authorization)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Authorization header\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - // Add content, if any - if (pcb_p->hb.event_data_p) { - if (add_content(pcb_p->hb.event_data_p, request, fname) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content\n", fname); - free_sip_message(request); - return (FALSE); - } - } else { - if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content-Len\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - ccsip_common_util_set_retry_settings(&pcb_p->hb, &timeout); - if (sipTransportCreateSendMessage(NULL, request, sipMethodPublish, - &(pcb_p->hb.dest_sip_addr), - (int16_t) pcb_p->hb.dest_sip_port, - FALSE, TRUE, timeout, pcb_p, - RELDEV_NO_STORED_MSG) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send PUBLISH message\n", fname); - return (FALSE); - } - - return (TRUE); - -} - -/** - * This function will handle retry-timer expiration - * - * @param[in] handle - handle to PCB - * - * @return 0 if it is successful in handling the timer - * Otherwise, -1 is returned - * - * @pre (handle != 0) - */ -int publish_handle_retry_timer_expire (uint32_t handle) -{ - static const char fname[] = "publish_handle_retry_timer_expire"; - pub_handle_t pub_handle = handle; - ccsip_publish_cb_t *pcb_p; - uint32_t max_retx = 0; - uint32_t time_t1 = 0; - uint32_t time_t2 = 0; - uint32_t timeout = 0; - - /* - * find the PCB - */ - pcb_p = find_pcb(pub_handle); - if (pcb_p == NULL) { - /* No PCB. So do nothing. */ - return 0; - } - if (pcb_p->hb.retx_flag == FALSE) { - /* probably we got some response. so do nothing */ - return 0; - } - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - if (pcb_p->hb.retx_counter < max_retx) { - pcb_p->hb.retx_counter++; - config_get_value(CFGID_TIMER_T1, &time_t1, sizeof(time_t1)); - timeout = time_t1 * (1 << pcb_p->hb.retx_counter); - config_get_value(CFGID_TIMER_T2, &time_t2, sizeof(time_t2)); - if (timeout > time_t2) { - timeout = time_t2; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Resending message #%d\n", - DEB_F_PREFIX_ARGS(SIP_PUB, fname), pcb_p->hb.retx_counter); - if (sipTransportSendMessage(NULL, - pcb_p->retry_timer.message_buffer, - pcb_p->retry_timer.message_buffer_len, - pcb_p->retry_timer.message_type, - &(pcb_p->retry_timer.ipaddr), - pcb_p->retry_timer.port, - FALSE, TRUE, timeout, pcb_p) < 0) { - /* free up PCB and respond with error */ - send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send message", fname); - return (-1); - } - - } else { - /* - * send timeout response and free up PCB - */ - send_resp_to_app(SIP_CLI_ERR_REQ_TIMEOUT, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"reached MAX retries", fname); - } - return 0; -} - -/** - * This function will check if wee need to send refresh PUBLISH. - * If so, it will send refresh PUBLISH - * - * @param[in] none - * - * @return none - */ -void publish_handle_periodic_timer_expire (void) -{ - static const char fname[] = "publish_handle_periodic_timer_expire"; - int delta = 0; - ccsip_publish_cb_t *pcb_p; - pub_req_t msg; - - config_get_value(CFGID_TIMER_SUBSCRIBE_DELTA, &delta, - sizeof(delta)); - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); - while (pcb_p != NULL) { - if (pcb_p->outstanding_trxn == FALSE) { - if (pcb_p->hb.expires >= TMR_PERIODIC_PUBLISH_INTERVAL) { - pcb_p->hb.expires -= TMR_PERIODIC_PUBLISH_INTERVAL; - } - if (pcb_p->hb.expires <= (delta + TMR_PERIODIC_PUBLISH_INTERVAL)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sending REFRESH PUBLISH", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - memset (&msg, 0, sizeof(msg)); - /* refresh is triggered by NULL event data and non-zero expires value */ - msg.pub_handle = pcb_p->pub_handle; - msg.expires = pcb_p->hb.orig_expiration; - (void)publish_handle_ev_app_publish(&msg); - } - } - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, pcb_p); - } -} - -/** - * This function will process the response to PUBLISH request sent by us. - * - * @param[in] pSipMessage - pointer to received SIP response msg - * - * @return SIP_OK if it successfully processes the response. - * SIP_ERROR if it fails to process the response. - * - * @pre (pSipMessage != NULL) - */ -int publish_handle_ev_sip_response (sipMessage_t *pSipMessage) -{ - static const char fname[] = "publish_handle_ev_sip_response"; - const char *callID_p = NULL; - int response_code = 0; - const char *expires = NULL; - const char *sip_etag = NULL; - long expiry_time; - pub_req_t *msg_p; - ccsip_publish_cb_t *pcb_p; - int entity_tag_size; - - callID_p = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!callID_p) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.\n", fname); - return SIP_ERROR; - } - - /* - * Find PCB by Call-ID. The Call-IDs generated by the phone ae unique. - */ - pcb_p = find_pcb_by_sip_callid(callID_p); - if (pcb_p == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No matching PCB found\n", fname); - return SIP_ERROR; - } - - /* - * Cancel the retry_timer and set the retx_flag to FALSE. - */ - sip_platform_msg_timer_subnot_stop(&(pcb_p->retry_timer)); - pcb_p->hb.retx_flag = FALSE; - - // Parse the return code - (void) sipGetResponseCode(pSipMessage, &response_code); - - if (response_code >= 200) { - pcb_p->outstanding_trxn = FALSE; - } - - - if ((response_code == SIP_CLI_ERR_UNAUTH) || - (response_code == SIP_CLI_ERR_PROXY_REQD)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authentication Required\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - if (ccsip_common_util_generate_auth(pSipMessage, &pcb_p->hb, SIP_METHOD_PUBLISH, - response_code, pcb_p->full_ruri) == TRUE) { - if (sipSPISendPublish(pcb_p, TRUE) == TRUE) { - pcb_p->outstanding_trxn = TRUE; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with Auth header\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_OK; - } - } - /* - * Since we failed to resend the PUBLISH request, free up the PCB and let the app know. - */ - send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to auth challenge\n", fname); - return SIP_ERROR; - } - - /* - * if response code is 423, grab Min-Expires and send new PUBLISH with new expires value - */ - if (response_code == SIP_CLI_ERR_INTERVAL_TOO_SMALL) { - expires = sippmh_get_header_val(pSipMessage, - (const char *)SIP_HEADER_MIN_EXPIRES, - NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - //ensure new Min-Expires is > what we set before in Expires - if ((long) expiry_time > pcb_p->hb.expires) { - pcb_p->hb.expires = expiry_time; - pcb_p->hb.orig_expiration = expiry_time; - } - if (sipSPISendPublish(pcb_p, FALSE) == TRUE) { - pcb_p->outstanding_trxn = TRUE; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with increased expires\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_OK; - } - } - /* - * Since we failed to resend the PUBLISH request, free up the PCB and let the app know. - */ - send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to 423\n", fname); - return SIP_ERROR; - } - - /* - * if the response_code is > 299, free up the PCB and let the app know. - */ - if (response_code > 299) { - send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code); - return SIP_OK; - } - - /* - * if the response is < 200, do nothing. - */ - if (response_code < 200) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code); - return SIP_OK; - } - - /* - * If it is PUBLISH remove operation, free up PCB - */ - if (pcb_p->hb.orig_expiration == 0) { - send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb (pcb_p); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"removed PCB as this was a terminating PUBLISH\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); - return SIP_OK; - } - - /* - * extract Expires and SIP-ETag headers and save them. - */ - expires = sippmh_get_header_val(pSipMessage, SIP_HEADER_EXPIRES, NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - pcb_p->hb.expires = expiry_time; - } - sip_etag = sippmh_get_header_val(pSipMessage, SIP_HEADER_SIPETAG, NULL); - if (sip_etag != NULL) { - cpr_free(pcb_p->entity_tag); - entity_tag_size = strlen(sip_etag) + 1; - pcb_p->entity_tag = cpr_malloc(entity_tag_size); - if (pcb_p->entity_tag != NULL) { - sstrncpy(pcb_p->entity_tag, sip_etag, entity_tag_size); - } else { - free_pcb (pcb_p); - send_resp_to_app(PUBLISH_FAILED_NORESOURCE, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"memory allocation failed\n", fname); - return SIP_ERROR; - - } - } - - /* - * If there are no pending requests, provide the response to the application. - */ - msg_p = (pub_req_t *)sll_next(pcb_p->pending_reqs, NULL); - if (msg_p != NULL) { - (void)sll_remove(pcb_p->pending_reqs, msg_p); - (void)publish_handle_ev_app_publish(msg_p); - cpr_free(msg_p); - return SIP_OK; - } - send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent response %d to app\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code); - return SIP_OK; -} - -/** - * This function will inform the application that phone is either - * 1. restarting or - * 2. failing over/ falling back - * - * @note detection of CCM reboot will be handled by PUBLISH ETag mechanism. - * - * @param[in] none - * - * @return none - */ -void publish_reset (void) -{ - ccsip_publish_cb_t *pcb_p; - - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); - while (pcb_p != NULL) { - send_resp_to_app(PUBLISH_FAILED_RESET, pcb_p->pub_handle, pcb_p->app_handle, - pcb_p->callback_task, pcb_p->resp_msg_id); - free_pcb(pcb_p); - pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); - } -} - -/** - * This function will print the stats (invoked by show command) - * - * @param[in] none - * - * @return 0 always - */ -cc_int32_t show_publish_stats (cc_int32_t argc, const char *argv[]) -{ - debugif_printf("------ Current PUBLISH Statistics ------\n"); - if (s_PCB_list != NULL) { - debugif_printf("Number of PCBs allocated: %d\n", sll_count(s_PCB_list)); - } else { - debugif_printf("Number of PCBs allocated: 0\n"); - } - debugif_printf("Total outgoing PUBLISH requests: %d\n", outgoingPublishes); - return 0; -} - diff --git a/libs/sipcc/core/sipstack/ccsip_register.c b/libs/sipcc/core/sipstack/ccsip_register.c deleted file mode 100644 index 8f79d62e60..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_register.c +++ /dev/null @@ -1,3079 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_timers.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "cpr_ipc.h" -#include "cpr_in.h" -#include "util_string.h" -#include "task.h" -#include "phntask.h" -#include "ccsip_core.h" -#include "ccsip_messaging.h" -#include "phone_debug.h" -#include "ccsip_platform.h" -#include "ccsip_platform_timers.h" -#include "ccsip_macros.h" -#include "ccsip_pmh.h" -#include "ccsip_register.h" -#include "ccsip_task.h" -#include "ccsip_credentials.h" -#include "debug.h" -#include "logmsg.h" -#include "ccsip_pmh.h" -#include "ccsip_credentials.h" -#include "dns_utils.h" -#include "config.h" -#include "sip_common_transport.h" -#include "uiapi.h" -#include "sip_common_regmgr.h" -#include "text_strings.h" -#include "sip_interface_regmgr.h" -#include "phone_platform_constants.h" -#include "ccsip_common_cb.h" -#include "misc_util.h" - -extern sipPlatformUITimer_t sipPlatformUISMTimers[]; -extern void *new_standby_available; -extern boolean regall_fail_attempt; -extern boolean registration_reject; - -extern void ui_set_sip_registration_state(line_t line, boolean registered); -extern void ui_update_registration_state_all_lines(boolean registered); - -boolean dump_reg_msg = TRUE; -boolean refresh_reg_msg = FALSE; - -static ccsip_register_states_t ccsip_register_state = SIP_REG_IDLE; - -/* Need an additional ack timer for the backup proxy */ -static cprTimer_t ack_tmrs[MAX_REG_LINES + 1]; -ccm_act_stdby_table_t CCM_Active_Standby_Table; -extern ccm_failover_table_t CCM_Failover_Table; -static boolean start_standby_monitor = TRUE; -extern boolean Is794x; - -static void show_register_data(void); - -#define SIP_REG_TMR_EXPIRE_TICKS 55000 /* msec; re-registration timer */ -#define REGISTER_CMD "register" -#define SIP_REG_TMR_ACK_TICKS 32000 /* msec; supervision timer equivalent to Timer F */ - -static const char *ccsip_register_state_names[] = { - "IDLE", - "REGISTERING", - "REGISTERED", - "UNREGISTERING", - "PRE_FALLBACK", - "IN_FAILOVER", - "POST_FAILOVER", - "STANDBY_FAILOVER", - "NO_CC", - "NO_STANDBY", - "NO_REGISTER" -}; - -static const char *ccsip_register_reg_state_names[] = { - "NONE", - "IDLE", - "REGISTERING", - "REGISTERED", - "UNREGISTERING", - "PRE_FALLBACK", - "IN_FAILOVER", - "POST_FAILOVER", - "STANDBY_FAILOVER", - "NO_CC", - "NO_STANDBY", - "NO_REGISTER" -}; - - -void ccsip_handle_ev_reg_req(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_reg_cancel(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_unreg_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_1xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_3xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_4xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_failure_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_tmr_expire(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_tmr_ack(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_tmr_retry(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_unreg_tmr_ack(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_standby_keepalive_tmr_expire(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_idle_tmr_expire(ccsipCCB_t *ccb, sipSMEvent_t *event); - -const char *ccsip_register_state_name(ccsip_register_states_t state); -const char *ccsip_register_reg_state_name(sipRegSMStateType_t state); -const char *sip_util_reg_event2string(sipRegSMEventType_t event); -char *sip_util_reg_state2string(sipRegSMStateType_t state); -void ccsip_register_retry_timer_start(ccsipCCB_t *ccb); -void ccsip_register_cleanup(ccsipCCB_t *ccb, boolean start); -cc_int32_t ccsip_register_cmd(cc_int32_t argc, const char *argv[]); -void ccsip_register_clear_all_logs(void); -boolean ccsip_register_all_registered(void); - -/* convert sip line to reg line */ -#define SIP_REG_LINE2REGLINE(line) ((line) - (REG_CCB_START)) - -/* convert reg line to sip line */ -#define SIP_REG_REGLINE2LINE(line) ((line) + (REG_CCB_START)) - -// Date holder -static struct { - boolean valid; - char datestring[MAX_SIP_DATE_LENGTH]; -} ccm_date; - -static const sipSMEventActionFn_t -gSIPRegSMTable[SIP_REG_STATE_END - SIP_REG_STATE_BASE + 1] - [SIPSPI_REG_EV_END - SIPSPI_REG_EV_BASE + 1] = -{ - /* SIP_REG_STATE_IDLE - */ - { - /* E_SIP_REG_REG_REQ */ ccsip_handle_ev_reg_req, - /* E_SIP_REG_CANCEL */ ccsip_handle_ev_default, - /* E_SIP_REG_1xx */ ccsip_handle_ev_default, - /* E_SIP_REG_2xx */ ccsip_handle_ev_default, - /* E_SIP_REG_3xx */ ccsip_handle_ev_default, - /* E_SIP_REG_4xx */ ccsip_handle_ev_default, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_ACK */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_EXPIRE */ ccsip_handle_ev_idle_tmr_expire, - /* E_SIP_REG_TMR_WAIT */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_RETRY */ ccsip_handle_ev_default, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - - /* SIP_REG_STATE_REGISTERING - */ - { - /* E_SIP_REG_REG_REQ */ ccsip_handle_ev_reg_req, - /* E_SIP_REG_CANCEL */ ccsip_handle_ev_reg_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ ccsip_handle_ev_2xx, - /* E_SIP_REG_3xx */ ccsip_handle_ev_3xx, - /* E_SIP_REG_4xx */ ccsip_handle_ev_4xx, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_failure_response, - /* E_SIP_REG_TMR_ACK */ ccsip_handle_ev_tmr_ack, - /* E_SIP_REG_TMR_EXPIRE */ ccsip_handle_ev_tmr_expire, - /* E_SIP_REG_TMR_WAIT */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_RETRY */ ccsip_handle_ev_tmr_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - - /* SIP_REG_STATE_REGISTERED - */ - { - /* E_SIP_REG_REG_REQ */ ccsip_handle_ev_default, - /* E_SIP_REG_CANCEL */ ccsip_handle_ev_reg_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_default, - /* E_SIP_REG_2xx */ ccsip_handle_ev_default, - /* E_SIP_REG_3xx */ ccsip_handle_ev_default, - /* E_SIP_REG_4xx */ ccsip_handle_ev_default, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_ACK */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_EXPIRE */ ccsip_handle_ev_tmr_expire, - /* E_SIP_REG_TMR_WAIT */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_RETRY */ ccsip_handle_ev_tmr_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - - /* SIP_REG_STATE_UNREGISTERING - */ - { - /* E_SIP_REG_REG_REQ */ ccsip_handle_ev_default, - /* E_SIP_REG_CANCEL */ ccsip_handle_ev_reg_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ ccsip_handle_ev_unreg_2xx, - /* E_SIP_REG_3xx */ ccsip_handle_ev_3xx, - /* E_SIP_REG_4xx */ ccsip_handle_ev_4xx, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_failure_response, - /* E_SIP_REG_TMR_ACK */ ccsip_handle_ev_unreg_tmr_ack, - /* E_SIP_REG_TMR_EXPIRE */ ccsip_handle_ev_default, - /* E_SIP_REG_TMR_WAIT */ ccsip_handle_ev_standby_keepalive_tmr_expire, - /* E_SIP_REG_TMR_RETRY */ ccsip_handle_ev_tmr_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - - /* SIP_REG_STATE_IN_FALLBACK - */ - { - /* E_SIP_REG_REG_REQ */ sip_regmgr_ev_default, - /* E_SIP_REG_CANCEL */ sip_regmgr_ev_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ sip_regmgr_ev_in_fallback_2xx, - /* E_SIP_REG_3xx */ sip_regmgr_ev_default, - /* E_SIP_REG_4xx */ sip_regmgr_ev_fallback_retry, - /* E_SIP_REG_FAILURE_RESPONSE */ sip_regmgr_ev_fallback_retry, - /* E_SIP_REG_TMR_ACK */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_TMR_EXPIRE */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_WAIT */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_RETRY */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - /* SIP_REG_STATE_STABILITY_CHECK - */ - { - /* E_SIP_REG_REG_REQ */ sip_regmgr_ev_default, - /* E_SIP_REG_CANCEL */ sip_regmgr_ev_cancel, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ sip_regmgr_ev_stability_check_2xx, - /* E_SIP_REG_3xx */ sip_regmgr_ev_default, - /* E_SIP_REG_4xx */ sip_regmgr_ev_default, - /* E_SIP_REG_FAILURE_RESPONSE */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_ACK */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_TMR_EXPIRE */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_WAIT */ sip_regmgr_ev_stability_check_tmr_wait, - /* E_SIP_REG_TMR_RETRY */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_default, - }, - /* SIP_REG_STATE_TOKEN_WAIT - */ - { - /* E_SIP_REG_REG_REQ */ sip_regmgr_ev_default, - /* E_SIP_REG_CANCEL */ sip_regmgr_ev_default, - /* E_SIP_REG_1xx */ ccsip_handle_ev_1xx, - /* E_SIP_REG_2xx */ sip_regmgr_ev_token_wait_2xx, - /* E_SIP_REG_3xx */ sip_regmgr_ev_default, - /* E_SIP_REG_4xx */ ccsip_handle_ev_4xx, - /* E_SIP_REG_FAILURE_RESPONSE */ ccsip_handle_ev_failure_response, - /* E_SIP_REG_TMR_ACK */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_TMR_EXPIRE */ sip_regmgr_ev_default, - /* E_SIP_REG_TMR_WAIT */ sip_regmgr_ev_token_wait_tmr_wait, - /* E_SIP_REG_TMR_RETRY */ sip_regmgr_ev_tmr_ack_retry, - /* E_SIP_REG_CLEANUP */ sip_regmgr_ev_cleanup, - } -}; - -/* - * This function gets the supported option tags from the 200 OK response - * to the REG message sent. - */ -void -sip_get_supported_options_2xx (ccsipCCB_t *ccb, sipMessage_t *response) -{ - const char *supported; - - ccb->supported_tags = 0; - supported = sippmh_get_cached_header_val(response, SUPPORTED); - if (supported != NULL) { - /* - * Supported header is found, find the interrested supported - * function from 2xx response from the REG msg. sent. Note that - * the sippmh_parse_supported_require() can be used but - * decided to minimize the impact on performance parsing all other - * tags that are not interested during registration times and - * vice versa making changes to sippmh_parse_supported_require() - * to parse the tags that are not interested for other messages - * also impact the processing time for other messages. - */ - if (strcasestr(supported, REQ_SUPP_PARAM_CISCO_SRTP_FALLBACK)) { - /* cisco SRTP fallback is supported by the other end */ - ccb->supported_tags |= cisco_srtp_fallback_tag; - } - } -} - -/* - * This function starts the Register message - * ack timer. If no response is received from - * the register message within four minutes, - * this timer will pop and resend the Register - * message. - */ -void -sip_start_ack_timer (ccsipCCB_t *ccb) -{ - uint16_t ack_timer_index; - - if (ccb->index == REG_BACKUP_CCB) { - ack_timer_index = MAX_REG_LINES; - } else { - ack_timer_index = ccb->dn_line - 1; - } - - CCSIP_DEBUG_REG_STATE( DEB_L_C_F_PREFIX " ccb->index=%d ack_timer_index=%d ", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, 0, "sip_start_ack_timer"), - ccb->index, ack_timer_index); - - if (cprStartTimer(ack_tmrs[ack_timer_index], SIP_REG_TMR_ACK_TICKS, - (void *)(long)ccb->index) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "sip_start_ack_timer", "cprStartTimer"); - } -} - - -/* - * This function stops the Register message - * ack timer. - */ -void -sip_stop_ack_timer (ccsipCCB_t *ccb) -{ - uint16_t ack_timer_index; - - if (ccb->index == REG_BACKUP_CCB) { - ack_timer_index = MAX_REG_LINES; - } else { - ack_timer_index = ccb->dn_line - 1; - } - - CCSIP_DEBUG_REG_STATE( DEB_L_C_F_PREFIX " ccb->index=%d ack_timer_index=%d ", - DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->dn_line, 0, "sip_stop_ack_timer"), - ccb->index, ack_timer_index); - - if (cprCancelTimer(ack_tmrs[ack_timer_index]) == CPR_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "sip_stop_ack_timer", "cprCancelTimer"); - } -} - - -void -sip_reg_sm_change_state (ccsipCCB_t *ccb, sipRegSMStateType_t new_state) -{ - if (g_disable_mass_reg_debug_print == FALSE) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Registration state change: %s ---> " - "%s\n", DEB_L_C_F_PREFIX_ARGS(SIP_STATE, ccb->index, ccb->dn_line, "sip_reg_sm_change_state"), - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - sip_util_reg_state2string(new_state)); - } - ccb->state = (sipSMStateType_t) new_state; - - if (ccb->index == REG_CCB_START) { - if ((new_state > SIP_REG_STATE_REGISTERED) || (!refresh_reg_msg)) { - dump_reg_msg = TRUE; - } else { - dump_reg_msg = FALSE; - } - } -} - - -void -ccsip_handle_ev_reg_req (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_reg_req"; - char line_name[MAX_LINE_NAME_SIZE]; - int value; - - config_get_value(CFGID_PROXY_REGISTER, &value, sizeof(value)); - if (value == 0) { - ui_set_sip_registration_state(ccb->dn_line, FALSE); - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_REG_DISABLED), - ccb->index, ccb->dn_line, fname); - - return; - } - - ccsip_register_clear_all_logs(); - - sip_stop_ack_timer(ccb); - sip_start_ack_timer(ccb); - - (void) sip_platform_register_expires_timer_stop(ccb->index); - - - sip_util_get_new_call_id(ccb); - - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, - sizeof(line_name)); - - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &ccb->reg.tmr_expire, - sizeof(ccb->reg.tmr_expire)); - ccb->reg.act_time = (int) time(NULL); - - if (sipSPISendRegister(ccb, 0, line_name, ccb->reg.tmr_expire) != TRUE) { - // set expire timer and cleanup ccb in non-ccm mode. - // do not change the expire timer value in ccm mode - if (ccb->cc_type != CC_CCM) { - ccsip_register_cleanup(ccb, TRUE); - } - log_clear(LOG_REG_MSG); - log_msg(LOG_REG_MSG); - } - - sip_reg_sm_change_state(ccb, SIP_REG_STATE_REGISTERING); -} - - - -void -ccsip_handle_ev_default (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - if ((event->type == (int) E_SIP_REG_CANCEL) && (ccb->state == (int) SIP_REG_STATE_IDLE)) { - (void) sip_platform_register_expires_timer_stop(ccb->index); - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - ccsip_register_cleanup(ccb, FALSE); - } - - /* only free SIP messages, timeouts are internal */ - if (event->type < (int) E_SIP_REG_TMR_ACK) { - free_sip_message(event->u.pSipMessage); - } -} - - -void -ccsip_handle_ev_tmr_expire (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - // Initiate registration if prime line or not in failover state - if ((!CCM_Failover_Table.failover_started) || - (ccb->index == REG_CCB_START)) { - /*If the phone is registered with CSPS, the failover_started flag - * will always be false. Therefore, this code will always be - * executed. */ - - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - - refresh_reg_msg = TRUE; - /* send a message to the SIP_REG SM to initiate registration */ - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } else { - ccsip_handle_ev_default(ccb, event); - } -} - -void -ccsip_handle_ev_idle_tmr_expire (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - - if (ccb->cc_type == CC_CCM) { - if (ccb->index == REG_BACKUP_CCB) { - ccsip_handle_ev_tmr_expire(ccb, event); - } else { - ccsip_handle_ev_default(ccb, event); - } - } else { - /* assuming CSPS */ - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - - /* send a message to the SIP_REG SM to initiate registration */ - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - - -void -ccsip_handle_ev_tmr_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - log_clear(LOG_REG_AUTH_ACK_TMR); - log_msg(LOG_REG_AUTH_ACK_TMR); - - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - Send tmr ack event to the regmgr/ - */ - sip_regmgr_ev_tmr_ack_retry(ccb, event); - } else { - /* - * regmgr - Assume it is csps - */ - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - /* send a message to the SIP_REG SM to initiate registration */ - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - - -void -ccsip_handle_ev_1xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_1xx"; - sipMessage_t *response = NULL; - int status_code = 0; - char status[LOG_MAX_LEN]; - - response = event->u.pSipMessage; - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), - ccb->index, ccb->dn_line, fname); - return; - } - - free_sip_message(response); - - switch (status_code) { - case SIP_1XX_TRYING: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), - ccb->index, ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP", status_code); - return; - - default: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), ccb->index, - ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP BAD", status_code); - - snprintf(status, sizeof(status), "in %d, information", status_code); - log_clear(LOG_REG_UNSUPPORTED); - log_msg(LOG_REG_UNSUPPORTED, status); - - ccsip_register_cleanup(ccb, TRUE); - - return; - } -} - -static boolean -ccsip_get_exp_time_2xx (ccsipCCB_t *ccb, sipContact_t *contact_info, - const char *expires, uint32_t *exp_time_ret) -{ - static const char fname[] = "ccsip_get_exp_time_2xx"; - boolean exp_found = FALSE; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char user[MAX_LINE_NAME_SIZE]; - int i; - uint32_t gmt_time; //TODO convert to time_t - //uint32_t diff_time; //TODO convert to time_t - int32_t gmt_rc; - uint32_t exp_time; - uint32_t register_delta; - - /* did the server change the expires time? */ - - /* - * Form the contact header. - * The proxy can return multiple contacts so we will need to see which one - * matches this REGISTER. - */ - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &exp_time, sizeof(uint32_t)); - if (contact_info != NULL) { - ipaddr2dotted(src_addr_str, &ccb->src_addr); - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, - sizeof(user)); - - /* is expires header for this line included in the contact? */ - for (i = 0; i < contact_info->num_locations; i++) { - if ((sippmh_cmpURLStrings(contact_info->locations[i]->genUrl->u.sipUrl->user, - user, FALSE) == 0) && - (strcmp(contact_info->locations[i]->genUrl->u.sipUrl->host, - src_addr_str) == 0)) { - if ((contact_info->params[i].expires > 0) && - (contact_info->params[i].expires < exp_time)) { - exp_time = contact_info->params[i].expires; - exp_found = TRUE; - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_REG_PROXY_EXPIRES), - ccb->index, ccb->dn_line, fname); - break; - } - } - } - } - - - if (exp_found != TRUE) { - //expires param is not found in the CONTACT header - // look for Expires header. - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &exp_time, - sizeof(exp_time)); - if (expires) { - gmt_rc = gmt_string_to_seconds((char *)expires, - (unsigned long *)&gmt_time); - if (gmt_rc != -1) { - // We only want to update the expires timeout if it is lower - // than our predefined threshold. We don't want to allow - // people to keep us hung up for infinite periods of time - if (gmt_rc == 1) { - // We got a numeric entry in the expires field - if (gmt_time < exp_time) { - exp_time = gmt_time; - exp_found = TRUE; - } - } - } - } - } - - /* - * Subtract some user defined period of time to account for network delay - * or the possibility that the registration server is down and this - * request has to be processed by a backup server after the timeout - * occurs. If the user has not defined this value in the config, it - * defaults to 5 seconds. - */ - config_get_value(CFGID_TIMER_REGISTER_DELTA, ®ister_delta, - sizeof(register_delta)); - - /* - * Sanity check the register delta value as the proxy could have returned - * a much lower registration period in its' response. The minimum - * registration expiration is 60 seconds to prevent the phone from being - * flooded with msgs. - */ - if ((exp_time - register_delta) < MIN_REGISTRATION_PERIOD) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX - "Warning - Registration period received (%d) " - "minus configured timer_register_delta (%d) is less than " - "%d seconds.\n", DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), exp_time, - register_delta, MIN_REGISTRATION_PERIOD); - exp_found = FALSE; - } else { - exp_time = exp_time - register_delta; - exp_found = TRUE; - } - *exp_time_ret = exp_time; - return (exp_found); -} - -/* - * Function: ccsip_check_ccm_restarted - * - * Parameters: - * new_reg_ccb - pointer to ccsipCCB_t of REG CCB. - * contact_info - Pointer to sipContact_t. - * - * Description: - * The function detects CCM just came up i.e. it sees the phone - * registration as a new registration. This means CCM has restarted - * between a REG refresh cycle. - * - * Note: - * CCM only sends x-cisco-newreg to the first REG that it sees - * from the phone as a new REG. If the phone has more than one lines, - * the REG of the rest of the lines will not have the x-cisco-newreg. - * - * Returns: - * TRUE - CCM restarted is detected. - * FALSE - CCM restarted is not detected. - */ -static boolean -ccsip_check_ccm_restarted (sipContact_t *contact_info) -{ - int i; - - if (contact_info == NULL) { - /* No contact info. */ - return (FALSE); - } - - for (i = 0; i < contact_info->num_locations; i++) { - if (contact_info->params[i].flags & SIP_CONTACT_PARM_X_CISCO_NEWREG) { - /* - * CCM or proxy just indicates that it sees the REG - * as a new registration to it. This means that the CCM or - * proxy has restarted. - */ - return (TRUE); - } - } - return (FALSE); -} - -/* - * Function: update_sis_protocol_version - * - * Parameters: - * response - 200 OK message pointer - * - * Description: - * The function parses theupported header in response and updates - * SIS protocol version received. If no version is received the default - * SEADRAGON version gets updated - * - * Returns: - * void - */ - -void -update_sis_protocol_version (sipMessage_t *response) -{ - const char *supported; - char * sipver; - supported = sippmh_get_cached_header_val(response, SUPPORTED); - if (supported != NULL) { - sipver = strcasestr(supported, REQ_SUPP_PARAM_CISCO_SISTAG); - if (sipver) { - cc_uint32_t major = SIS_PROTOCOL_MAJOR_VERSION_SEADRAGON, minor = 0, addtnl = 0; - if ( sscanf ( &sipver[strlen(REQ_SUPP_PARAM_CISCO_SISTAG)], "%d.%d.%d", - &major, &minor, &addtnl) == 3) { - platSetSISProtocolVer ( major, minor, addtnl,REQ_SUPP_PARAM_CISCO_SISTAG); - return; - } - } - } - /* All other cases we set the version to 1.0.0 */ - platSetSISProtocolVer ( SIS_PROTOCOL_MAJOR_VERSION_SEADRAGON, 0, 0,REQ_SUPP_PARAM_CISCO_SISTAG); -} - -void -update_cme_sis_version (sipMessage_t *response) -{ - const char *supported; - char * sipver; - - supported = sippmh_get_cached_header_val(response, SUPPORTED); - if (supported != NULL) { - sipver = strcasestr(supported, REQ_SUPP_PARAM_CISCO_CME_SISTAG); - if (sipver) { - cc_uint32_t major = 0, minor = 0, addtnl = 0; - if ( sscanf( &sipver[strlen(REQ_SUPP_PARAM_CISCO_CME_SISTAG)], "%d.%d.%d", - &major, &minor, &addtnl) ==3) { - platSetSISProtocolVer(major, minor, addtnl,REQ_SUPP_PARAM_CISCO_CME_SISTAG); - } - } - } -} - -void -ccsip_handle_ev_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_2xx"; - sipMessage_t *response = event->u.pSipMessage; - const char *pViaHeaderStr = NULL; - sipVia_t *via = NULL; - uint32_t exp_time; - //uint32_t line_feature; - int dns_err_code; - int nat_enable = 0; - int nat_rx_proc_enable = 0; - //int last_button_index =0; - const char *datehdr = NULL; - const char *contact = NULL; - const char *expires = NULL; - sipContact_t *contact_info = NULL; - //line_t line_index = 0; - //ccsipCCB_t *line_ccb = NULL; - - - // Extract Date header and store - datehdr = sippmh_get_header_val(response, SIP_HEADER_DATE, NULL); - if (datehdr) { - // Copy date header in a global variable since it would be needed - // to set system time - sstrncpy(ccm_date.datestring, datehdr, sizeof(ccm_date.datestring)); - ccm_date.valid = TRUE; - - // call ntp set time handler (TNP/cnu specific; stub for legacy) - // do not call the handler if 2xx is from StdBy CCM - // We do not need to set the time when in the browser - //if (ccb->index != REG_BACKUP_CCB) { - // SipNtpUpdateClockFromCCM(); - //} - } - - contact = sippmh_get_cached_header_val(response, CONTACT); - if (contact != NULL) { - /* There is a contact header pass it */ - contact_info = sippmh_parse_contact(contact); - } - - /* Update the sip interface protocol version */ - update_sis_protocol_version(response); - - /*update the CME for the version negotiation feature */ - update_cme_sis_version(response); - - if (ccb->dn_line == PRIMARY_LINE && ccsip_check_ccm_restarted(contact_info)) { - /* CCM has restarted detected */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Detected server has restarted via line %d\n", - DEB_F_PREFIX_ARGS(SIP_CCM_RESTART, fname), ccb->dn_line); - sip_regmgr_ccm_restarted(ccb); - } - - sip_stop_ack_timer(ccb); - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (ccb->send_reason_header) { - ccb->send_reason_header = FALSE; - sipUnregisterReason[0] = '\0'; - } - - /* - * Get expiration time. The expriation time are from contact info. or - * from the expire header. - */ - expires = sippmh_get_header_val(response, SIP_HEADER_EXPIRES, NULL); - if (ccsip_get_exp_time_2xx(ccb, contact_info, expires, &exp_time) - == FALSE) { - /* - * The expire time received in 200OK is smaller than the minimum - * allowed. The phone will be unregistered and a message will be - * displayed under the Status Messages. The phone will retry to - * register after the configured expire-timer interval. - */ - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &exp_time, - sizeof(uint32_t)); - ccb->reg.tmr_expire = exp_time; - ccb->reg.act_time = (int) time(NULL); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_UNREGISTERING); - - if (ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - (void) sip_platform_register_expires_timer_start(ccb->reg.tmr_expire * 1000, - ccb->index); - if (contact_info != NULL) { - sippmh_free_contact(contact_info); - } - free_sip_message(response); - log_clear(LOG_REG_EXPIRE); - log_msg(LOG_REG_EXPIRE); - return; - } - - - ccb->reg.registered = 1; - sip_reg_sm_change_state(ccb, SIP_REG_STATE_REGISTERED); - regall_fail_attempt = FALSE; - - if (ccb->index != REG_BACKUP_CCB) { - registration_reject = FALSE; - ui_set_sip_registration_state(ccb->dn_line, TRUE); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Setting Reg state to TRUE for line=%d\n", - DEB_F_PREFIX_ARGS(SIP_REG_STATE, fname), ccb->dn_line); - /* Get supported options from the supported header from the response */ - sip_get_supported_options_2xx(ccb, response); - } else { - log_clear(LOG_REG_BACKUP); - } - - - if (contact_info != NULL) { - sippmh_free_contact(contact_info); - } - - ccb->reg.tmr_expire = exp_time; - - ccb->reg.act_time = (int) time(NULL); - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting expires timer (%d " - "sec)\n", DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->index, ccb->dn_line, fname), - ccb->reg.tmr_expire); - (void) sip_platform_register_expires_timer_start(ccb->reg.tmr_expire * 1000, - ccb->index); - - - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - A 200 OK will reach here only if the state is - * REGISTERING, the unreg_200ok eve is handled - * separately. - */ - ti_config_table_t *ccm_table_ptr; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - - if ((ccm_table_ptr == CCM_Active_Standby_Table.active_ccm_entry) && - start_standby_monitor) { - ccsipCCB_t *standby_ccb; - - start_standby_monitor = FALSE; - sip_platform_set_ccm_status(); - - /* - * Kickoff monitoring the standby - */ - - standby_ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (CCM_Active_Standby_Table.standby_ccm_entry) { - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, - &exp_time, sizeof(uint32_t)); - standby_ccb->reg.tmr_expire = exp_time; - standby_ccb->reg.act_time = (int) time(NULL); - sip_reg_sm_change_state(standby_ccb, - SIP_REG_STATE_UNREGISTERING); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, standby_ccb->index); - (void) sip_platform_register_expires_timer_start(standby_ccb->reg.tmr_expire * 1000, - standby_ccb->index); - } - } else if (ccm_table_ptr == - CCM_Active_Standby_Table.standby_ccm_entry) { - /* - * REGMGR - Update stats Got a 200OK for a expires 0 - * Keepalive msg to standby, update stats ? - */ - } - } - - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - config_get_value(CFGID_NAT_RECEIVED_PROCESSING, &nat_rx_proc_enable, - sizeof(nat_rx_proc_enable)); - if (nat_enable == 1 && nat_rx_proc_enable == 1) { - pViaHeaderStr = sippmh_get_cached_header_val(response, VIA); - if (pViaHeaderStr != NULL) { - via = sippmh_parse_via(pViaHeaderStr); - if (via != NULL) { - if (via->recd_host != NULL) { - cpr_ip_addr_t received_ip; - - memset(&received_ip, 0, sizeof(cpr_ip_addr_t)); - dns_err_code = dnsGetHostByName(via->recd_host, - &received_ip, 100, 1); - if (dns_err_code == 0) { - util_ntohl(&received_ip, &received_ip); - } else { - sip_config_get_nat_ipaddr(&received_ip); - } - - if (util_compare_ip(&received_ip, &(ccb->src_addr)) == FALSE) { - /* - * The address the proxy/registration server received - * is not the same as the one that we think we have - * so we'll update our address and re-register with - * the proxy/registration server - */ - - ccb->reg.rereg_pending = 1; - - // Make sure our running config has the correct - // IP address that we got from the proxy server - sip_config_set_nat_ipaddr(&received_ip); - - if (ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - - // Update the tel ccb that this reg line belongs to - ccb = sip_sm_get_ccb_by_index((line_t)(ccb->index - REG_CCB_START + 1)); - if (ccb) { - ccb->src_addr = received_ip; - } - } - } - - // Cleanup memory - sippmh_free_via(via); - } - } - } - - free_sip_message(response); -} - -void -ccsip_handle_ev_3xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_3xx"; - sipMessage_t *response = NULL; - int status_code = 0; - char status[LOG_MAX_LEN]; - char user[MAX_LINE_NAME_SIZE]; - sipUrl_t *url; - const char *contact = NULL; - - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), - ccb->index, ccb->dn_line, fname); - free_sip_message(response); - return; - } - - switch (status_code) { - case SIP_RED_MULT_CHOICES /* 300 */: - case SIP_RED_MOVED_PERM /* 301 */: - case SIP_RED_MOVED_TEMP /* 302 */: - case SIP_RED_USE_PROXY /* 305 */: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), - ccb->index, ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP", status_code); - - sip_sm_200and300_update(ccb, response, status_code); - - /* - * Record the Contact header. For 3xx messages we are recording - * the Contact header here, not in the sipSPICheckResponse() header, - * so that the ACK response to 3xx is sent to the original INVITE - * destination (or to the Record-Route specified destination), rather - * than to the new 302 Contact - */ - contact = sippmh_get_cached_header_val(response, CONTACT); - if (contact) { - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - } - ccb->contact_info = sippmh_parse_contact(contact); - } - - - /* - * Check the validity of Contact header - */ - if (!ccb->contact_info) { - CCSIP_DEBUG_ERROR("%s: Error: Invalid Contact field. Aborting " - "REGISTER.\n", fname); - free_sip_message(response); - ccsip_register_cleanup(ccb, TRUE); - return; - } - - if (ccb->contact_info->locations[0]->genUrl->schema == URL_TYPE_SIP) { - url = ccb->contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR("%s: Error: URL is not Sip. Aborting " - "REGISTER.\n", fname); - free_sip_message(response); - ccsip_register_cleanup(ccb, TRUE); - return; - } - - sstrncpy(ccb->reg.proxy, url->host, MAX_IPADDR_STR_LEN); - ccb->reg.port = url->port; - - if (ccb->contact_info) { - sippmh_free_contact(ccb->contact_info); - ccb->contact_info = NULL; - } - - sip_util_get_new_call_id(ccb); - - /* - * Send out a new REGISTER - */ - ccb->authen.cred_type = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, - sizeof(user)); - - if (sipSPISendRegister(ccb, 0, user, ccb->reg.tmr_expire) != TRUE) { - ccsip_register_cleanup(ccb, TRUE); - free_sip_message(response); - - log_clear(LOG_REG_RED_MSG); - log_msg(LOG_REG_RED_MSG); - } - return; - - default: - free_sip_message(event->u.pSipMessage); - - snprintf(status, sizeof(status), "in %d, redirection", status_code); - log_clear(LOG_REG_UNSUPPORTED); - log_msg(LOG_REG_UNSUPPORTED, status); - - ccsip_register_cleanup(ccb, TRUE); - } -} - - -void -ccsip_handle_ev_4xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_4xx"; - sipMessage_t *response = NULL; - int status_code = 0; - const char *authenticate = NULL; - char user[MAX_LINE_NAME_SIZE]; - credentials_t credentials; - char status[LOG_MAX_LEN]; - sip_authen_t *sip_authen = NULL; - char *author_str = NULL; - char uri[MAX_IPADDR_STR_LEN + 10]; /* Proxy IP address string */ - char tmp_str[STATUS_LINE_MAX_LEN]; - ti_config_table_t *ccm_table_ptr = NULL; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - - - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), - ccb->index, ccb->dn_line, fname); - free_sip_message(response); - return; - } - - /* - * Set reject flag if we get 4xx from publisher cucm. - * Note: if non-prime dn is congfigured with #, such as 1234##, - * then phone will get 404 for that DN, even though the prime DN is - * registered. - */ - if (ccm_table_ptr && - ccb->index != REG_BACKUP_CCB) { - DEF_DEBUG(DEB_F_PREFIX"Receive 4xx in ccm mode. set registration_reject to TRUE.\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - registration_reject = TRUE; - } - - switch (status_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), - ccb->index, ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP", status_code); - - if (cred_get_credentials_r(ccb, &credentials) == FALSE) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"no more credentials, retry %d, %d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CRED, ccb->index, ccb->dn_line, fname), - ccb->authen.retries_401_407, - MAX_RETRIES_401); - - - if (ccb->cc_type == CC_CCM) { - sip_regmgr_ev_failure_response(ccb, event); - free_sip_message(response); - return; - } - ccsip_register_cleanup(ccb, TRUE); - free_sip_message(response); - - log_clear(LOG_REG_AUTH_NO_CRED); - log_msg(LOG_REG_AUTH_NO_CRED); - - break; - } - - authenticate = sippmh_get_header_val(response, AUTH_HDR(status_code), - NULL); - if (authenticate) { - sip_authen = sippmh_parse_authenticate(authenticate); - } - - if (sip_authen) { - if (sip_authen->scheme == SIP_DIGEST) { - if (authenticate != NULL) { - ccb->retx_counter = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, - sizeof(user)); - ccb->authen.cnonce[0] = '\0'; - snprintf(uri, sizeof(uri), "sip:%s", ccb->reg.proxy); /* proxy */ - if (sipSPIGenerateAuthorizationResponse(sip_authen, uri, - SIP_METHOD_REGISTER, - credentials.id, - credentials.pw, - &author_str, - &(ccb->authen.nc_count), - ccb)) { - - if (author_str) { - if (ccb->authen.authorization != NULL) { - cpr_free(ccb->authen.authorization); - ccb->authen.authorization = NULL; - } - - ccb->authen.authorization = - (char *) cpr_malloc(strlen(author_str) * - sizeof(char) + 1); - - if (ccb->authen.authorization != NULL) { - sstrncpy(ccb->authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - ccb->authen.status_code = status_code; - } - cpr_free(author_str); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sipSPIGenerateAuthorizationResponse"); - } - - if (!sipSPISendRegister(ccb, TRUE, user, - ccb->reg.tmr_expire)){ - ccsip_register_cleanup(ccb, TRUE); - - log_clear(LOG_REG_AUTH_MSG); - log_msg(LOG_REG_AUTH_MSG); - } - - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sippmh_parse_authenticate"); - - ccsip_register_cleanup(ccb, TRUE); - log_clear(LOG_REG_AUTH_HDR_MSG); - log_msg(LOG_REG_AUTH_HDR_MSG); - } - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"auth scheme unsupported= %d\n", - DEB_F_PREFIX_ARGS(SIP_AUTH, fname), sip_authen->scheme); - - ccsip_register_cleanup(ccb, TRUE); - log_clear(LOG_REG_AUTH_SCH_MSG); - log_msg(LOG_REG_AUTH_SCH_MSG); - } - sippmh_free_authen(sip_authen); - } - - free_sip_message(response); - return; - - case SIP_CLI_ERR_INTERVAL_TOO_SMALL: - { - int new_expires = MAX_REG_EXPIRES; - const char *msg_ptr = NULL; - char line_name[MAX_LINE_NAME_SIZE]; - - msg_ptr = sippmh_get_header_val(response, - (const char *)SIP_HEADER_MIN_EXPIRES, - NULL); - if (msg_ptr) { - new_expires = strtoul(msg_ptr, NULL, 10); - } - - //ensure new Min-Expires is > what we set before in Expires - if (new_expires > ccb->reg.tmr_expire) { - ccb->reg.tmr_expire = new_expires; - } else { - ccb->reg.tmr_expire = MAX_REG_EXPIRES; - } - - //We have to make a fresh request - sip_stop_ack_timer(ccb); - sip_start_ack_timer(ccb); - - (void) sip_platform_register_expires_timer_stop(ccb->index); - - sip_util_get_new_call_id(ccb); - - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - config_get_line_string(CFGID_LINE_NAME, line_name, ccb->dn_line, - sizeof(line_name)); - - ccb->reg.act_time = (int) time(NULL); - - if (sipSPISendRegister(ccb, 0, line_name, ccb->reg.tmr_expire) != TRUE) { - // set expire timer and cleanup ccb in non-ccm mode. - // do not change the expire timer value in ccm mode - - if (ccb->cc_type != CC_CCM) { - ccsip_register_cleanup(ccb, TRUE); - } - - log_clear(LOG_REG_MSG); - log_msg(LOG_REG_MSG); - } - - //no change in state - } - free_sip_message(response); - return; - - - /* - * 404 (Not Found) - * 413 (Request Entity Too Large) - * 480 (Temporarily Unavailable) - * 486 (Busy here) - */ - case SIP_CLI_ERR_NOT_FOUND: - case SIP_CLI_ERR_LARGE_MSG: - case SIP_CLI_ERR_NOT_AVAIL: - case SIP_CLI_ERR_BUSY_HERE: - if (ccb->cc_type == CC_CCM) { - if (ccb->state == (int) SIP_REG_STATE_TOKEN_WAIT) { - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - sip_regmgr_ev_token_wait_4xx_n_5xx(ccb, event); - } else { - /* - * Phone sends a REGISTER message with expires=0 as a - * Keepalive msg. Proxy and CCM will respond with a - * 200 OK. - */ - if (ccb->index != REG_BACKUP_CCB) { - if (ccsip_register_get_register_state() != SIP_REG_UNREGISTERING) { - if (((ti_config_table_t *)(ccb->cc_cfg_table_entry)) || - ccb->dn_line == PRIMARY_LINE) { - if (platGetPhraseText(STR_INDEX_REGISTRATION_REJECTED, - (char *)tmp_str, STATUS_LINE_MAX_LEN - 1)== CPR_SUCCESS) { - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, tmp_str, 15, FALSE, - DEF_NOTIFY_PRI); - } - } - log_clear(STR_INDEX_REGISTRATION_REJECTED); - log_msg(STR_INDEX_REGISTRATION_REJECTED); - } - } - if (process_retry_after(ccb, response) == FALSE) { - sip_regmgr_ev_failure_response(ccb, event); - } - } - } else { - if (process_retry_after(ccb, response) == FALSE) { - ccsip_register_cleanup(ccb, TRUE); - } - } - free_sip_message(response); - return; - - default: - if (ccb->cc_type == CC_CCM) { - if (ccb->state == (int) SIP_REG_STATE_TOKEN_WAIT) { - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - sip_regmgr_ev_token_wait_4xx_n_5xx(ccb, event); - } else { - sip_regmgr_ev_failure_response(ccb, event); - } - free_sip_message(response); - return; - } - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_FUNCTION_ENTRY2), - ccb->index, ccb->dn_line, fname, - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - "SIP BAD", status_code); - - snprintf(status, sizeof(status), "in %d, client error", status_code); - ccsip_register_cleanup(ccb, TRUE); - - snprintf(status, sizeof(status), "in %d, request failure", status_code); - log_clear(LOG_REG_UNSUPPORTED); - log_msg(LOG_REG_UNSUPPORTED, status); - free_sip_message(response); - break; - } - - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - - -void -ccsip_handle_ev_failure_response (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_failure_response"; - sipMessage_t *response = NULL; - int status_code = 0; - char status[LOG_MAX_LEN]; - sipStatusCodeClass_t code_class = codeClassInvalid; - ti_config_table_t *ccm_table_ptr = NULL; - - /* - * Set reject flag if we get 5xx/6xx from publisher cucm. - */ - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr && - ccb->index != REG_BACKUP_CCB) { - registration_reject = TRUE; - DEF_DEBUG(DEB_F_PREFIX"registration has been rejected. Set registration_reject to TRUE.\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), - ccb->index, ccb->dn_line, fname); - free_sip_message(response); - ccsip_register_cleanup(ccb, TRUE); - return; - } - - code_class = sippmh_get_code_class((uint16_t)status_code); - - log_clear(LOG_REG_AUTH); - - switch (code_class) { - case codeClass5xx: - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_FAILURE), - ccb->index, ccb->dn_line, fname, status_code); - - log_msg(LOG_REG_AUTH_SERVER_ERR, status_code); - - break; - - case codeClass6xx: - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_FAILURE), - ccb->index, ccb->dn_line, fname, status_code); - - log_msg(LOG_REG_AUTH_GLOBAL_ERR, status_code); - - break; - - default: - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_FAILURE), - ccb->index, ccb->dn_line, fname, status_code); - - snprintf(status, sizeof(status), "in %d, ??? error", status_code); - log_msg(LOG_REG_AUTH_UNKN_ERR, status_code); - - break; - } - - if (ccb->cc_type == CC_CCM) { - if (ccb->state == (int) SIP_REG_STATE_TOKEN_WAIT) { - - /* Handle only 503 error condition for other errors - * use default state - */ - if (status_code == SIP_SERV_ERR_UNAVAIL) { - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - sip_regmgr_ev_token_wait_4xx_n_5xx(ccb, event); - free_sip_message(response); - } else { - sip_regmgr_ev_default(ccb, event); - } - return; - } - - /* retry registration using value in the Retry-After header - * if response code is 503 with Retry-After - */ - if ((status_code == SIP_SERV_ERR_UNAVAIL) && - (process_retry_after(ccb, response) == TRUE)) { - free_sip_message(response); - return; - } - /* - * regmgr - Pass the event to the regmgr - */ - sip_regmgr_ev_failure_response(ccb, event); - free_sip_message(response); - } else { - /* - * Assume CSPS for now - */ - - switch (status_code) { - - /* - * 500 (Server Internal Error) - * 503 (Service Unavailable) - * 600 (Busy), - * 603 (Declined - */ - case SIP_SERV_ERR_INTERNAL: - case SIP_SERV_ERR_UNAVAIL: - - case SIP_FAIL_BUSY: - case SIP_FAIL_DECLINE: - if (process_retry_after(ccb, response) == FALSE) { - ccsip_register_cleanup(ccb, TRUE); - } - free_sip_message(response); - return; - - default: - break; - } - ccsip_register_cleanup(ccb, TRUE); - free_sip_message(response); - - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } - } -} - -/* - * ccsip_handle_ev_tmr_retry() - * - * This function is called when registration re-try timer - * pops or an ICMP unreachable is received after sending - * out the registration. The ICMP unreachable code sets the - * retx_counter to MAX to force the code to try the next - * proxy in the list. Event.u.usrInfo is set to the IP - * address that bounced or -1 if is a timeout. - */ -void -ccsip_handle_ev_tmr_retry (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_tmr_retry"; - boolean start_timer; - uint32_t value; - int dns_err_code = DNS_ERR_HOST_UNAVAIL; - cpr_ip_addr_t ip_addr; - - CPR_IP_ADDR_INIT(ip_addr); - - start_timer = (ccsip_register_get_register_state() == SIP_REG_UNREGISTERING) ? - (FALSE) : (TRUE); - - config_get_value(CFGID_SIP_RETX, &value, sizeof(value)); - if (value > MAX_NON_INVITE_RETRY_ATTEMPTS) { - value = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - if (ccb->retx_counter >= value) { - if (ccb->cc_type == CC_CCM /* RAMC Some other state */) { - /* - * regmgr - Send event to the regmgr - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Reached here for ccb->index=%d \n", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), ccb->index); - sip_regmgr_ev_tmr_ack_retry(ccb, event); - return; - } else { - /* - * Assume CSPS for now - */ - ccb->retx_counter = 0; - - /* - * Did the registration msg bounce trying to reach the outbound - * proxy (1st check) or did it timeout trying to reach the - * outbound proxy (2nd check)? - */ - util_ntohl(&ip_addr, &(event->u.UsrInfo)); - if (util_compare_ip(&ip_addr, &(ccb->outBoundProxyAddr)) || - ((event->u.UsrInfo.type == CPR_IP_ADDR_INVALID) && - util_check_if_ip_valid(&(ccb->outBoundProxyAddr)))) { - /* - * If there are more records, reset address to force code - * to use next entry. If not then bail. - */ - ccb->outBoundProxyPort = 0; - dns_err_code = DNS_OK; - - /* - * Trouble reaching the normal proxy. Get another proxy - * if records are available - */ - } else if (str2ip(ccb->reg.proxy, &ccb->reg.addr) != 0) { - dns_err_code = sipTransportGetServerAddrPort(ccb->reg.proxy, - &ccb->reg.addr, - (uint16_t *) &ccb->reg.port, - &ccb->SRVhandle, - TRUE); - if (dns_err_code == 0) { - util_ntohl(&(ccb->reg.addr), &(ccb->reg.addr)); - } else { - ccb->reg.addr = ip_addr_invalid; - } - - /* - * Modify destination fields in call back timer struct - */ - (void) sip_platform_msg_timer_update_destination(ccb->index, - &(ccb->reg.addr), - ccb->reg.port); - } else { - /* No other proxy to try */ - dns_err_code = DNS_ERR_HOST_UNAVAIL; - } - - /* - * Cleanup if unable to find another proxy - */ - if (dns_err_code != DNS_OK) { - /* - * All retransmit attempts have been exhausted. - * Cleanup the call and move to the IDLE state - */ - ccsip_register_cleanup(ccb, start_timer); - - log_clear(LOG_REG_RETRY); - log_msg(LOG_REG_RETRY); - if ((ccb->index == REG_BACKUP_CCB) && - (ccb->cc_type != CC_CCM)) { - log_clear(LOG_REG_BACKUP); - log_msg(LOG_REG_BACKUP); - } - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } - - return; - } - } - } - - if (ccb->state != (int) SIP_REG_STATE_REGISTERED) { - /* - * Handling Retry timer in REGISTERED state is not needed - * the event has come due to race condition - */ - ccb->retx_counter++; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Resending message: #%d\n", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), ccb->retx_counter); - - if (sipSPISendLastMessage(ccb) != TRUE) { - if (ccb->cc_type == CC_CCM) { - sip_regmgr_ev_tmr_ack_retry(ccb, event); - } else { - ccsip_register_cleanup(ccb, start_timer); - } - return; - } - - ccsip_register_retry_timer_start(ccb); - } - -} - - -void -ccsip_handle_ev_reg_cancel (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - char user[MAX_LINE_NAME_SIZE]; - int exp_time = 0; - - ccsip_register_clear_all_logs(); - - sip_stop_ack_timer(ccb); - sip_start_ack_timer(ccb); - - (void) sip_platform_register_expires_timer_stop(ccb->index); - - sip_util_get_new_call_id(ccb); - - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, sizeof(user)); - - if (sipSPISendRegister(ccb, 0, user, exp_time) != TRUE) { - log_clear(LOG_REG_CANCEL_MSG); - log_msg(LOG_REG_CANCEL_MSG); - } else if ((ccb->index == REG_BACKUP_CCB) && (ccb->cc_type != CC_CCM)) { - log_clear(LOG_REG_BACKUP); - log_msg(LOG_REG_BACKUP); - } - - sip_reg_sm_change_state(ccb, SIP_REG_STATE_UNREGISTERING); -} - - -void -ccsip_handle_ev_unreg_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "ccsip_handle_ev_unreg_2xx"; - sipMessage_t *response = event->u.pSipMessage; - int timeout; - - free_sip_message(response); - - ccb->reg.registered = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (ccb->cc_type == CC_CCM) { - if (ccb->index == REG_BACKUP_CCB) { - /* - * Stay in unregistering state and wait for the - * expires timer to pop to send the next keepalive. - */ - sip_stop_ack_timer(ccb); - if (new_standby_available) { - sip_regmgr_replace_standby(ccb); - } - - timeout = sip_config_get_keepalive_expires(); - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Keep alive timer (%d sec)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->index, ccb->dn_line, fname), timeout); - (void) sip_platform_standby_keepalive_timer_start(timeout * 1000); - } else { - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - sip_stop_ack_timer(ccb); - - if (ccsip_register_all_unregistered() == TRUE) { - ccsip_register_set_register_state(SIP_REG_IDLE); - /* - * regmgr - FALLBACK: Pick the ccb of the ccm that has - * come up (falling back) and post the fallback event, - * now that the unregistering is done. - * Will commit change after integration with ccm. - */ - } - platSetSISProtocolVer(1,0,0,NULL); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"set[1] the SIS protocol ver to 1.0.0\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - } else { - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - sip_stop_ack_timer(ccb); - - if (ccsip_register_all_unregistered() == TRUE) { - ccsip_register_set_register_state(SIP_REG_IDLE); - } - - /* - * Our unregistration from the proxy has succeeded now we - * can reregister again - */ - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } - platSetSISProtocolVer(1,0,0,NULL); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"set[2] the SIS protocol ver to 1.0.0\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } -} - - -void -ccsip_handle_ev_unreg_tmr_ack (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - log_clear(LOG_REG_AUTH_UNREG_TMR); - log_msg(LOG_REG_AUTH_UNREG_TMR); - - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - Send tmr ack event to the regmgr - */ - sip_regmgr_ev_tmr_ack_retry(ccb, event); - return; - } - ccsip_register_cleanup(ccb, FALSE); - /* - * We are unregistering ourselves from the proxy when our own registration - * timer has expired. This means that we do not need to complete our - * unregistration from the proxy since it is being done automatically. - * We can just send our new registration now - */ - if (ccb->reg.rereg_pending != 0) { - ccb->reg.rereg_pending = 0; - if (ccsip_register_send_msg(SIP_REG_REQ, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - -void -ccsip_handle_ev_standby_keepalive_tmr_expire (ccsipCCB_t *ccb, - sipSMEvent_t *event) -{ - /* - * regmgr - If there is a fallback ccb in TOKEN_WAIT - * state waiting to fallback notify it so it can - * continue with the fallback procedure. - */ - if (ccb->cc_type == CC_CCM) { - /* - * REGMGR - CHECK if this event gets called. - * Will get in here only for REG_BACKUP_CCB in - * unregistering state i.e, the standby cc which - * is periodically monitored. - */ - /* - * Stay in unregistering state and post a message - * to send another keep-alive message. - */ - (void) sip_platform_standby_keepalive_timer_stop(); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index); - } else { - ccsip_handle_ev_default(ccb, event); - } -} - -int -sip_reg_sm_process_event (sipSMEvent_t *pEvent) -{ - static const char fname[] = "sip_reg_sm_process_event"; - ccsipCCB_t *ccb = NULL; - - ccb = pEvent->ccb; - if (!ccb) { - CCSIP_DEBUG_ERROR("%s: Error: ccb is null. Unable to process event " - "<%d>\n", fname, pEvent->type); - return (-1); - } - - /* Unbind UDP ICMP response handler */ - if ((REG_CHECK_EVENT_SANITY((int) ccb->state, (int) pEvent->type)) && - (REG_EVENT_ACTION(ccb->state, (int) pEvent->type))) { - if (dump_reg_msg == TRUE) { - DEF_DEBUG(DEB_L_C_F_PREFIX"%s <- %s\n", - DEB_L_C_F_PREFIX_ARGS(SIP_REG_STATE, ccb->dn_line, ccb->index, fname), - sip_util_reg_state2string((sipRegSMStateType_t)ccb->state), - sip_util_reg_event2string((sipRegSMEventType_t)pEvent->type)); - } - REG_EVENT_ACTION(ccb->state, pEvent->type) (ccb, pEvent); - } else { - /* Invalid State/Event pair */ - CCSIP_DEBUG_ERROR("%s: Error: illegal state/event pair: (%d <-- %d)\n", - fname, ccb->state, pEvent->type); - return (-1); - } - - return (0); -} - - -const char * -sip_util_reg_event2string (sipRegSMEventType_t event) -{ - switch (event) { - case E_SIP_REG_REG_REQ: - return ("E_SIP_REG_REG_REQ"); - - case E_SIP_REG_CANCEL: - return ("E_SIP_REG_CANCEL"); - - case E_SIP_REG_1xx: - return ("E_SIP_REG_1xx"); - - case E_SIP_REG_2xx: - return ("E_SIP_REG_2xx"); - - case E_SIP_REG_3xx: - return ("E_SIP_REG_3xx"); - - case E_SIP_REG_4xx: - return ("E_SIP_REG_4xx"); - - case E_SIP_REG_FAILURE_RESPONSE: - return ("E_SIP_REG_FAILURE_RESPONSE"); - - case E_SIP_REG_TMR_EXPIRE: - return ("E_SIP_REG_TMR_EXPIRE"); - - case E_SIP_REG_TMR_ACK: - return ("E_SIP_REG_TMR_ACK"); - - case E_SIP_REG_TMR_WAIT: - return ("E_SIP_REG_TMR_WAIT"); - - case E_SIP_REG_TMR_RETRY: - return ("E_SIP_REG_TMR_RETRY"); - - case E_SIP_REG_CLEANUP: - return ("E_SIP_REG_CLEANUP"); - - default: - return ("SIP_REG_STATE_UNKNOWN"); - - } -} - - -char * -sip_util_reg_state2string (sipRegSMStateType_t state) -{ - switch (state) { - case SIP_REG_STATE_NONE: - return ("SIP_REG_STATE_NONE"); - - case SIP_REG_STATE_IDLE: - return ("SIP_REG_STATE_IDLE"); - - case SIP_REG_STATE_REGISTERING: - return ("SIP_REG_STATE_REGISTERING"); - - case SIP_REG_STATE_REGISTERED: - return ("SIP_REG_STATE_REGISTERED"); - - case SIP_REG_STATE_UNREGISTERING: - return ("SIP_REG_STATE_UNREGISTERING"); - - case SIP_REG_STATE_IN_FALLBACK: - return ("SIP_REG_STATE_IN_FALLBACK"); - - case SIP_REG_STATE_STABILITY_CHECK: - return ("SIP_REG_STATE_STABILITY_CHECK"); - - case SIP_REG_STATE_TOKEN_WAIT: - return ("SIP_REG_STATE_TOKEN_WAIT"); - - default: - return ("SIP_REG_STATE_UNKNOWN"); - - } -} - - -sipRegSMEventType_t -ccsip_register_sip2sipreg_event (int sip_event) -{ - static const char fname[] = "ccsip_register_sip2sipreg"; - sipRegSMEventType_t reg_event = E_SIP_REG_NONE; - - switch (sip_event) { - case E_SIP_1xx: - reg_event = E_SIP_REG_1xx; - break; - - case E_SIP_2xx: - reg_event = E_SIP_REG_2xx; - break; - - case E_SIP_3xx: - reg_event = E_SIP_REG_3xx; - break; - - case E_SIP_FAILURE_RESPONSE: - reg_event = E_SIP_REG_4xx; - break; - - default: - CCSIP_DEBUG_ERROR("%s: Error: Unknown event.\n", fname); - reg_event = E_SIP_REG_NONE; - break; - } - return (reg_event); -} - - -void -ccsip_register_timeout_retry (void *data) -{ - static const char fname[] = "ccsip_register_timeout_retry"; - ccsipCCB_t *ccb; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - ccb = (ccsipCCB_t *) data; - if (ccb == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "ccsip_register_timeout_retry"); - return; - } - - if (ccsip_register_send_msg(SIP_TMR_REG_RETRY, ccb->index) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } -} - - -/* - * timer callback function - * - * The function will search for the line that set the timer and then - * (1) send expire event to sm or - * (2) set another 60s timer. The setting of another timer is necessary - * because the max ticks for an OS timer is 10m. The expire timer can - * be larger. Therefore, set x 1m timers and count down. - */ -int -ccsip_register_send_msg (uint32_t cmd, line_t ndx) -{ - static const char fname[] = "ccsip_register_send_msg"; - ccsip_registration_msg_t *register_msg; - ccsipCCB_t *ccb = NULL; - CCM_ID ccm_id = UNUSED_PARAM; - ti_config_table_t * cc_cfg_table; - - /* - * Get the ccm_id type from ccb corresponding to ndx. - * Currently, only SIP_TMR_REG_RETRY msg in SIPTaskProcessListEvent is - * making use of ccm_id field. No other reg msg make use of ccm_id. Also in - * case of SIP_REG_UPDATE, ccm_id will not be determined below but remain - * initialized to UNUSED_PARAM because, in case of SIP_REG_UPDATE, ndx is - * not ccb->index but number of available lines when lkem is attached. - */ - if (cmd != SIP_REG_UPDATE) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - cc_cfg_table = (ti_config_table_t *)(ccb->cc_cfg_table_entry); - if (cc_cfg_table != NULL) { - ccm_id = cc_cfg_table->ti_specific.ti_ccm.ccm_id; - } - else { - CCSIP_DEBUG_ERROR("%s: Error: cc_cfg_table is null.\n", fname); - return SIP_ERROR; - } - } - else { - CCSIP_DEBUG_ERROR("%s: Error: ccb is null.\n", fname); - return SIP_ERROR; - } - } - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cmd=%d=%s ccb->index=%d ccm_id=%s\n", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), - cmd, REG_CMD_PRINT(cmd), ndx, CCM_ID_PRINT(ccm_id)); - - register_msg = (ccsip_registration_msg_t *) - SIPTaskGetBuffer(sizeof(ccsip_registration_msg_t)); - - if (!register_msg) { - CCSIP_DEBUG_ERROR("%s: Error: get buffer failed.\n", fname); - return SIP_ERROR; - } - register_msg->ccb_index = ndx; - register_msg->ccm_id = ccm_id; - - if (SIPTaskSendMsg(cmd, register_msg, sizeof(ccsip_registration_msg_t), NULL) - == CPR_FAILURE) { - cpr_free(register_msg); - CCSIP_DEBUG_ERROR("%s: Error: send buffer failed.\n", fname); - return SIP_ERROR; - } - - return SIP_REG_OK; -} - -void -ccsip_register_retry_timer_start (ccsipCCB_t *ccb) -{ - static const char fname[] = "ccsip_register_retry_timer_start"; - int timeout; - int time_t1; - int time_t2; - - /* Double the timeout value and do exponential time increases - * The doubling is used because the invite timeout is too short - */ - config_get_value(CFGID_TIMER_T1, &time_t1, sizeof(time_t1)); - timeout = time_t1 * (1 << ccb->retx_counter); - config_get_value(CFGID_TIMER_T2, &time_t2, sizeof(time_t2)); - if (timeout > time_t2) { - timeout = time_t2; - } - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting reTx timer (%d msec)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->index, ccb->dn_line, fname), timeout); - - ccb->retx_flag = TRUE; - if (sip_platform_msg_timer_start(timeout, (void *)ccb, ccb->index, - sipPlatformUISMTimers[ccb->index].message_buffer, - sipPlatformUISMTimers[ccb->index].message_buffer_len, - sipMethodRegister, - &(sipPlatformUISMTimers[ccb->index].ipaddr), - sipPlatformUISMTimers[ccb->index].port, - TRUE) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, ccb->dn_line, fname, - "sip_platform_msg_timer_start"); - ccb->retx_flag = FALSE; - } -} - - -void -ccsip_register_cleanup (ccsipCCB_t *ccb, boolean start) -{ - static const char fname[] = "ccsip_register_cleanup"; - int exp_time; - - config_get_value(CFGID_TIMER_REGISTER_EXPIRES, &exp_time, sizeof(exp_time)); - - ccb->reg.registered = 0; - - if (ccb->index != REG_BACKUP_CCB) { - ui_set_sip_registration_state(ccb->dn_line, FALSE); - } - - sip_stop_ack_timer(ccb); - - if ((start) && (ccb->state != (int) SIP_REG_STATE_UNREGISTERING)) { - if (ccb->index == REG_BACKUP_CCB) { - ccb->reg.tmr_expire = (exp_time > 5) ? exp_time - 5 : exp_time; - } else { - ccb->reg.tmr_expire = 60; - } - ccb->reg.act_time = (int) time(NULL); - - CCSIP_DEBUG_STATE(DEB_L_C_F_PREFIX"Starting expires timer (%d " - "sec)\n", DEB_L_C_F_PREFIX_ARGS(SIP_TIMER, ccb->index, ccb->dn_line, fname), - ccb->reg.tmr_expire); - (void) sip_platform_register_expires_timer_start(ccb->reg.tmr_expire * 1000, - ccb->index); - } - - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - if (ccsip_register_all_unregistered() == TRUE) { - ccsip_register_set_register_state(SIP_REG_IDLE); - } - - /* - * Always check how sip_sm_call_cleanup is implemented. - * The function has a tendency to change. - */ - - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); -} - - -cc_int32_t -ccsip_register_cmd (cc_int32_t argc, const char *argv[]) -{ - /* - * On 7970 phones the command is reg line [option] [line] - * On 7940/60 the command is reg [option] [line] - * Thus the location in the argument array is different - * based on the phone type. OFFSET is used to get around - * this difference while still having common code. - */ -#define OFFSET 1 - ccsipCCB_t *ccb = NULL; - line_t ndx = 0; - line_t temp_line = 0; - char str_val[MAX_LINE_NAME_SIZE]; - const char *line_string; - char *strtol_end; - - /* - * check if need help - */ - if ((argc == 2 + OFFSET) && (argv[1 + OFFSET][0] == '?')) { - debugif_printf("reg [option] [line]\n"); - debugif_printf(" options = 0: unregister\n"); - debugif_printf(" 1: register\n"); - debugif_printf(" line = 1 through 6\n"); - debugif_printf(" = backup (line 1 to backup proxy)\n"); - debugif_printf("\n"); - return (0); - }else if (cpr_strcasecmp(argv[0 + OFFSET], "line") == 0) { - - /* - make sure the user entered a complete command - */ - if (argc < 3 + OFFSET) { - debugif_printf("Incomplete command\n"); - debugif_printf("reg [option] [line]\n"); - debugif_printf(" options = 0: unregister\n"); - debugif_printf(" 1: register\n"); - debugif_printf(" line = 1 through 6\n"); - debugif_printf(" = backup (line 1 to backup proxy)\n"); - debugif_printf("\n"); - return (0); - } - - /* make sure we have at least one line configured */ - config_get_line_string(CFGID_LINE_NAME, str_val, 1, sizeof(str_val)); - if ((strcmp(str_val, UNPROVISIONED) == 0) || (str_val[0] == '\0')) { - debugif_printf("Error:No lines configured\n"); - return (0); - } - - line_string = argv[2 + OFFSET]; - if (cpr_strcasecmp(line_string, "backup") == 0) { - temp_line = REG_BACKUP_LINE; - } else { - errno = 0; - temp_line = (line_t) strtol(line_string, &strtol_end, 10); - if (errno || line_string == strtol_end || !sip_config_check_line(temp_line)) { - debugif_printf("Error:Invalid Line\n"); - return (0); - } - } - - - ndx = SIP_REG_REGLINE2LINE(temp_line - 1); - ccb = sip_sm_get_ccb_by_index(ndx); - - if (ccb == NULL) { - debugif_printf("Unable to retrieve registration information for this line.\n"); - debugif_printf("Command aborted.\n"); - return (0); - } - - if ((temp_line == REG_BACKUP_LINE) && util_check_if_ip_valid(&(ccb->dest_sip_addr)) == FALSE) { - debugif_printf("Backup Proxy is invalid or not configured.\n"); - return (0); - } - - switch (argv[1 + OFFSET][0]) { - case '0': - - if (ccb->index != REG_BACKUP_CCB) { - ui_set_sip_registration_state(ccb->dn_line, FALSE); - } - - if (temp_line != REG_BACKUP_LINE) { - debugif_printf("Unregistering line %d\n", temp_line); - } else { - debugif_printf("Unregistering line 1 to backup proxy\n"); - } - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - - if (ccsip_register_send_msg(SIP_REG_CANCEL, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - break; - - case '1': - - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - - if (temp_line != REG_BACKUP_LINE) { - debugif_printf("Registering line %d\n", temp_line); - } else { - debugif_printf("Registering line 1 to backup proxy\n"); - } - (void) ccsip_register_send_msg(SIP_REG_REQ, ndx); - break; - - default: - debugif_printf("Invalid Option Value - please choose 1 or 0\n"); - return (0); - } - } - return (0); -} - -/* - * Function: build_reg_flags - * - * Parameters: - * - * Description: builds a 3 character string representing various flags - * for use by the show_reg command - * - * Returns: none - * - */ -static void -build_reg_flags (char *buf, int buf_size, int prox_reg, ccsipCCB_t *ccb, - boolean provisioned) -{ - sstrncpy(buf, "...", buf_size); - if (!provisioned || !prox_reg) { - return; - } - - buf[1] = '1'; // Set the Provisioned bit - - if (ccb->authen.authorization != NULL) { - buf[0] = '1'; - } else { - if (ccb->authen.status_code != 0) { - buf[0] = 'x'; - } - } - if (ccb->reg.registered) { - buf[2] = '1'; - } else { - buf[2] = 'x'; - } -} - -/* - * Function: show_register_data - * - * Parameters: - * - * Description: Internal print routine for show_register_cmd. Also - * called by reg command - * - * Returns: - * - */ -#define TMP_BUF_SIZE 8 -static void -show_register_data (void) -{ - ccsipCCB_t *ccb; - char buf[TMP_BUF_SIZE]; - line_t ndx = 0; - int proxy_register = 0; - boolean valid_line = FALSE; - int timer_count_down = 0; - - config_get_value(CFGID_PROXY_REGISTER, &proxy_register, - sizeof(proxy_register)); - - debugif_printf("\nLINE REGISTRATION TABLE\nProxy Registration: "); - if (proxy_register == 1) { - debugif_printf("ENABLED"); - } else { - debugif_printf("DISABLED"); - } - debugif_printf(", state: %s\n", - ccsip_register_state_name(ccsip_register_get_register_state())); - debugif_printf("line APR state timer expires proxy:port\n"); - debugif_printf("---- --- ------------- ---------- ---------- ----------------------------\n"); - for (ndx = REG_CCB_START; ndx <= REG_BACKUP_CCB; ndx++) { - ccb = sip_sm_get_ccb_by_index(ndx); - valid_line = FALSE; - if (ndx == REG_BACKUP_CCB) { - valid_line = TRUE; - } else { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - valid_line = TRUE; - } - } - // calc the time until registration expires - if (ccb && valid_line) { - if (!proxy_register || !valid_line) { - timer_count_down = 0; - } else { - if (ccb->reg.act_time == 0) { - timer_count_down = 0; - } else if ((sipRegSMStateType_t)ccb->state == - SIP_REG_STATE_REGISTERING) { - timer_count_down = - (SIP_REG_TMR_ACK_TICKS / 1000) - - (((int) time(NULL)) - ccb->reg.act_time); - } else { - timer_count_down = ccb->reg.tmr_expire - - (((int) time(NULL)) - ccb->reg.act_time); - } - } - - /* - * Ensure that the timer_count_down value is valid. There - * are cases where the phone completes registration before an - * SNTP/NTP response is received which makes the act_time and - * time(NULL) values inconsistent. - */ - if ((timer_count_down < 0) || - (timer_count_down > ccb->reg.tmr_expire)) { - - timer_count_down = 0; - } - } - - // build the flag string - if (ccb) { - build_reg_flags((char *)&buf, TMP_BUF_SIZE, proxy_register, - ccb, valid_line); - } - - if (ndx != REG_BACKUP_CCB) { - debugif_printf("%-4d", ndx - TEL_CCB_END); - } else { - debugif_printf("1-BU"); - } - if (ccb && valid_line) { - debugif_printf(" %-3s %-13s %-10d %-10d %s:%d\n", - buf, - ccsip_register_reg_state_name((sipRegSMStateType_t)ccb->state), - ccb->reg.tmr_expire, - timer_count_down, - ((ccb->reg.proxy[0] != '\0') ? (ccb->reg.proxy) : ("undefined")), - ccb->reg.port); - } else { - debugif_printf(" %-3s %-13s %-10d %-10d %s:%d\n", - buf, "NONE", 0, 0, "undefined", 0); - } - } - debugif_printf("\nNote: APR is Authenticated, Provisioned, Registered\n"); -} - -/* - * Function: show_register_cmd - * - * Parameters: argc,argv - * - * Description: Shows the current registration table - * - * Returns: - * - */ -cc_int32_t -show_register_cmd (cc_int32_t argc, const char *argv[]) -{ - - /* - * check if need help - */ - if ((argc == 2) && (argv[1][0] == '?')) { - debugif_printf("sh reg\n"); - return (0); - } - show_register_data(); - - return (0); -} - -void -ccsip_register_clear_all_logs (void) -{ - log_clear(LOG_REG_MSG); - log_clear(LOG_REG_AUTH); - log_clear(LOG_REG_RETRY); - log_clear(LOG_REG_UNSUPPORTED); -} - - -void -ccsip_register_reset_proxy (void) -{ - ccsipCCB_t *ccb; - line_t ndx; - line_t line_end; - - /* - * If this is a restart (phone is resetting) then reset the proxy - * string for each line. The proxy string is used to determine - * what address to use when registering. The proxy remains the - * same throughout a boot cycle and on restarts there is a new - * boot cycle so the proxy address is reset. - */ - line_end = 1; - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 1 and 2 and REG CCBs are at 3 and 4. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - //ccsip_register_lines = line_end - REG_CCB_START + 1; - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb) { - ccb->reg.proxy[0] = '\0'; - } - } - } - - //reset backup proxy registration; - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (ccb) { - ccb->reg.proxy[0] = '\0'; - } -} - -int -ccsip_register_init (void) -{ - static const char fname[] = "ccsip_register_init"; - static const char sipAckTimerName[] = "sipAck"; - int i; - - ccsip_register_set_register_state(SIP_REG_IDLE); - - /* - * Create acknowledgement timers - */ - for (i = 0; i < MAX_REG_LINES + 1; i++) { - ack_tmrs[i] = cprCreateTimer(sipAckTimerName, SIP_ACK_TIMER, - TIMER_EXPIRATION, sip_msgq); - if (ack_tmrs[i] == NULL) { - CCSIP_DEBUG_ERROR("%s: timer NOT created: %d\n", - fname, i); - return SIP_ERROR; - } - } - - // Initialize date holder structure - ccm_date.valid = FALSE; - ccm_date.datestring[0] = '\0'; - start_standby_monitor = TRUE; - - return SIP_OK; -} - - -ccsip_register_states_t -ccsip_register_get_register_state (void) -{ - return (ccsip_register_state); -} - - -void -ccsip_register_set_register_state (ccsip_register_states_t state) -{ - ccsip_register_state = state; -} - -void -ccsip_register_cancel (boolean cancel_reg, boolean backup_proxy) -{ - static const char fname[] = "ccsip_register_cancel"; - ccsipCCB_t *ccb; - line_t ndx; - line_t line_end; - - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - if (ccsip_register_get_register_state() == SIP_REG_IDLE) { - return; - } - - ccsip_register_set_register_state(SIP_REG_UNREGISTERING); - - line_end = 1; - - ui_set_sip_registration_state((line_t) (line_end + 1), FALSE); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"unregistering %d lines\n", DEB_F_PREFIX_ARGS(SIP_REG, fname), line_end); - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 1 and 2 and REG CCBs are at 3 and 4. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t) (ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (!ccb) { - continue; - } - ui_set_sip_registration_state(ccb->dn_line, FALSE); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling timers, line= %d\n", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), ccb->index); - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - - if (cancel_reg) { - if (ccb->index == REG_CCB_START) { - ccb->send_reason_header = TRUE; - } - if (ccb->index == REG_CCB_START) { - ccb->send_reason_header = TRUE; - } - - if (ccsip_register_send_msg(SIP_REG_CANCEL, ndx) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - - } else { - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - if (ndx == line_end) { - ccsip_register_set_register_state(SIP_REG_IDLE); - } - } - } - } - - if (backup_proxy == FALSE) { - return; - } - - /* cancel backup registration as well */ - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling timers, line= %d\n", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), ccb->index); - - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - - if (cancel_reg) { - if (ccsip_register_send_msg(SIP_REG_CANCEL, REG_BACKUP_CCB) - != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - } else { - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - } -} - - -void -ccsip_register_all_lines (void) -{ - static const char fname[] = "ccsip_register_all_lines"; - ccsipCCB_t *ccb = 0; - line_t ndx; - line_t line; - line_t line_end = 1; - int value = 0; - char proxyaddress[MAX_IPADDR_STR_LEN]; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - /* Do not register if - * - no need to register - * - and already registered - */ - - line_end = 1; - config_get_value(CFGID_PROXY_REGISTER, &value, sizeof(value)); - if (value == 0) { - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_REG_DISABLED), NULL, - NULL, fname); - - // mark all unregistered - for (line = 1; line <= line_end; line++) { - if (sip_config_check_line(line)) { - ui_set_sip_registration_state(line, FALSE); - } - } - ccsip_register_reset_proxy(); - return; - } else if (ccsip_register_get_register_state() == SIP_REG_REGISTERED) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"lines already registered\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - return; - } - - - ccsip_register_reset_proxy(); - ccsip_register_set_register_state(SIP_REG_REGISTERING); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"registering %d line%c\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname), line_end, line_end > 1 ? 's' : ' '); - - /* register line 1 to the backup proxy. - * Start with the backup as DNS lookups hold - * the task meaning it could take a while to - * register the six regular lines. - */ - ndx = REG_BACKUP_CCB; - ccb = sip_sm_get_ccb_by_index(ndx); - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - if (ccb->cc_type == CC_CCM) { - /* - * regmgr - Set the Backup (standby ccm) info. - */ - ti_config_table_t *standby_ccm = - CCM_Active_Standby_Table.standby_ccm_entry; - - if (standby_ccm) { - ti_ccm_t *ti_ccm = &standby_ccm->ti_specific.ti_ccm; - - sip_regmgr_setup_new_standby_ccb(ti_ccm->ccm_id); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"ERROR: Standby ccm entry is NULL\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - } else { - /* - * Assume CSPS since only those two for now. - */ - if (util_check_if_ip_valid(&(ccb->dest_sip_addr))) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d, 0x%x\n", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), - ndx, ccb); - - ccb->reg.addr = ccb->dest_sip_addr; - ccb->reg.port = (uint16_t) ccb->dest_sip_port; - - if (ccb->index == REG_CCB_START) { - ccb->send_reason_header = TRUE; - } else { - ccb->send_reason_header = FALSE; - } - - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } else { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d: Backup Proxy not configured\n", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), ndx); - } - } - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 1 and 2 and REG CCBs are at 3 and 4. - * So, line_end equals the number of lines and then add the TEL_CCB_END to - * get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - DEF_DEBUG(DEB_F_PREFIX"Disabling mass reg state", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (!ccb) { - continue; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d, 0x%x\n", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), - ndx, ccb); - - - /* - * Clean up and re-initialize the proxy address. - * It is possible that the REGISTER can be redirected - * and this address needs to be reused for later register attempts. - * But, on restarts and re-enabling of registering we reset back - * to the original configured proxy - */ - if (ndx == REG_CCB_START || ndx == (line_end)) { - g_disable_mass_reg_debug_print = FALSE; - } else { - g_disable_mass_reg_debug_print = TRUE; - } - sip_sm_call_cleanup(ccb); - - /* - * Look up the name of the proxy - */ - sipTransportGetPrimServerAddress(ccb->dn_line, proxyaddress); - - sstrncpy(ccb->reg.proxy, proxyaddress, MAX_IPADDR_STR_LEN); - - ccb->reg.addr = ccb->dest_sip_addr; - ccb->reg.port = (uint16_t) ccb->dest_sip_port; - - if (ccb->index == REG_CCB_START) { - ccb->send_reason_header = TRUE; - } else { - ccb->send_reason_header = FALSE; - } - - ui_set_sip_registration_state(ccb->dn_line, FALSE); - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - - } - } - g_disable_mass_reg_debug_print = FALSE; - - sip_platform_cc_mode_notify(); -} - - -boolean -ccsip_register_all_registered (void) -{ - ccsipCCB_t *ccb; - line_t ndx; - line_t line_end; - - line_end = 1; - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 1 and 2 and REG CCBs are at 3 and 4. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - - if (ccb && (ccb->reg.registered == 0)) { - return (FALSE); - } - } - } - return (TRUE); -} - - -boolean -ccsip_register_all_unregistered (void) -{ - ccsipCCB_t *ccb; - line_t ndx; - line_t line_end; - - line_end = 1; - - /* - * REG CCBs start after the TEL CCBs. - * EG., TEL CCBs are at 0 and 1 and REG CCBs are at 6 and 7. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t)(ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - - if (ccb && (ccb->reg.registered == 1)) { - return (FALSE); - } - } - } - return (TRUE); -} - - -void -ccsip_register_commit (void) -{ - static const char fname[] = "ccsip_register_commit"; - int register_get; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - /* - * Determine if lines need to register or unregister - * - * register if - * - proxy_register was changed from 0 to 1 - * - * unregister if - * - proxy_register was changed from 1 to 0 and already registered - */ - config_get_value(CFGID_PROXY_REGISTER, ®ister_get, - sizeof(register_get)); - - switch (register_get) { - case 0: - if (ccsip_register_get_register_state() != SIP_REG_IDLE) { - ccsip_register_cancel(TRUE, TRUE); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"lines already unregistered.\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - - break; - - case 1: - if (ccsip_register_get_register_state() != SIP_REG_REGISTERED) { - ccsip_register_cancel(FALSE, TRUE); - ccsip_register_all_lines(); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"lines already registered.\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - break; - - default: - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Error: invalid register_get= %d\n", DEB_F_PREFIX_ARGS(SIP_REG, fname), - register_get); - } -} - -void -ccsip_backup_register_commit (void) -{ - static const char fname[] = "ccsip_backup_register_commit"; - line_t ndx; - ccsipCCB_t *ccb = 0; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - ndx = REG_BACKUP_CCB; - ccb = sip_sm_get_ccb_by_index(ndx); - - /* cancel an existing registration if it exists */ - if (util_check_if_ip_valid(&(ccb->reg.addr))) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling registration, line= %d\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname), ccb->index); - if (ccsip_register_send_msg(SIP_REG_CANCEL, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, FALSE); - } - } - - /* Cleanup and re-initialize CCB */ - sip_sm_call_cleanup(ccb); - - if (util_check_if_ip_valid(&(ccb->dest_sip_addr))) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d, 0x%x\n", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), - ndx, ccb); - ccb->reg.addr = ccb->dest_sip_addr; - ccb->reg.port = (uint16_t) ccb->dest_sip_port; - - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } else { - log_clear(LOG_REG_BACKUP); - } -} - - -void -cred_get_line_credentials (line_t line, credentials_t *pcredentials, - int id_len, int pw_len) -{ - config_get_line_string(CFGID_LINE_AUTHNAME, pcredentials->id, line, - id_len); - - if ((strcmp(pcredentials->id, "") == 0) || - (strcmp(pcredentials->id, UNPROVISIONED) == 0)) { - config_get_line_string((CFGID_LINE_AUTHNAME), pcredentials->id, 1, - id_len); - } - - config_get_line_string(CFGID_LINE_PASSWORD, pcredentials->pw, line, - pw_len); - if ((strcmp(pcredentials->pw, "") == 0) || - (strcmp(pcredentials->pw, UNPROVISIONED) == 0)) { - config_get_line_string(CFGID_LINE_PASSWORD, pcredentials->pw, 1, - pw_len); - } -} - - -boolean -cred_get_credentials_r (ccsipCCB_t *ccb, credentials_t *pcredentials) -{ - if (!(ccb->authen.cred_type & CRED_LINE) || - (ccb->authen.retries_401_407 < MAX_RETRIES_401)) { - ccb->authen.cred_type |= CRED_LINE; - ccb->authen.retries_401_407++; - cred_get_line_credentials(ccb->dn_line, pcredentials, - sizeof(pcredentials->id), - sizeof(pcredentials->pw)); - return (TRUE); - } - - return (FALSE); -} - - -const char * -ccsip_register_state_name (ccsip_register_states_t state) -{ - if ((state < SIP_REG_IDLE) || (state >= SIP_REG_NO_REGISTER)) { - return ("UNDEFINED"); - } - - return (ccsip_register_state_names[state]); -} - - -const char * -ccsip_register_reg_state_name (sipRegSMStateType_t state) -{ - if ((state < SIP_REG_STATE_NONE) || (state >= SIP_REG_STATE_UNREGISTERING)) { - return ("UNDEFINED"); - } - - return (ccsip_register_reg_state_names[state]); -} - -void -ccsip_register_shutdown () -{ - int i; - - for (i = 0; i < MAX_REG_LINES + 1; i++) { - (void) cprCancelTimer(ack_tmrs[i]); - (void) cprDestroyTimer(ack_tmrs[i]); - ack_tmrs[i] = NULL; - } -} - -boolean -ccsip_get_ccm_date (char *date_value) -{ - if (date_value) { - if (ccm_date.valid) { - sstrncpy(date_value, ccm_date.datestring, - sizeof(ccm_date.datestring)); - return (TRUE); - } else { - date_value[0] = '\0'; - } - } - return (FALSE); -} - -/* - * Function: ccsip_is_line_registered - * - * Parameters: - * dn_line - line number. - * - * Description: The function determines whether the current line - * is registered or not. - * - * Returns: - * TRUE if the line is registered. - * FALSE if the line is not registered or the given line is invalid. - * - */ -boolean -ccsip_is_line_registered (line_t dn_line) -{ - line_t ndx; - line_t line_end; - ccsipCCB_t *ccb; - - /* Get the number of lines configured */ - line_end = 1; - /* - * REG CCBs start after the TEL CCBs. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - ccb = sip_sm_get_ccb_by_index(ndx); - if ((ccb != NULL) && (ccb->dn_line == dn_line)) { - /* found the requested REG ccb */ - if (ccb->state == (int) SIP_REG_STATE_REGISTERED) { - return (TRUE); - } else { - /* the line is not in registered state */ - break; - } - } - } - - /* Found no matching REG ccb or the line is not in registered state */ - return (FALSE); -} - -/* - * Function: process_retry_after - * - * Parameters: - * ccsipCCB_t *ccb - The reg ccb. - * sipMessage_t *response - The received response. - * - * Description: The function processes the Retry-After header that may - * be present in the response. - * - * Returns: - * TRUE if a valid Retry-After header was present and processed correctly. - * FALSE if a valid Retry-After header was not present and therefore - * was not processed. - * - */ -boolean -process_retry_after (ccsipCCB_t *ccb, sipMessage_t *response) -{ - const char *msg_ptr = NULL; - int32_t retry_after = 0; - static const char fname[] = "process_retry_after"; - - msg_ptr = sippmh_get_header_val(response, - (const char *)SIP_HEADER_RETRY_AFTER, - NULL); - - if (msg_ptr) { - retry_after = strtoul(msg_ptr, NULL, 10); - - } else { - return (FALSE); - } - - if (retry_after > 0) { - sip_stop_ack_timer(ccb); - (void) sip_platform_register_expires_timer_start(retry_after * 1000, - ccb->index); - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Retrying after %d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), retry_after); - return (TRUE); - } else { - CCSIP_DEBUG_ERROR("REG %d/%d: %-35s: Error: invalid Retry-After " - "header in response.\n", - ccb->index, ccb->dn_line, fname); - return (FALSE); - } -} - - diff --git a/libs/sipcc/core/sipstack/ccsip_reldev.c b/libs/sipcc/core/sipstack/ccsip_reldev.c deleted file mode 100644 index 24d19abfb1..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_reldev.c +++ /dev/null @@ -1,284 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_string.h" -#include "ccsip_reldev.h" -#include "ccsip_macros.h" -#include "phone_debug.h" -#include "ccsip_pmh.h" -#include "ccsip_messaging.h" -#include "sip_common_transport.h" -#include "util_string.h" - -/* Constants */ -#define SIP_RRLIST_LENGTH (MAX_TEL_LINES) - -/* Global variables */ -sipRelDevMessageRecord_t gSIPRRList[SIP_RRLIST_LENGTH]; - - -void -sipRelDevMessageStore (sipRelDevMessageRecord_t * pMessageRecord) -{ - static int counter = 0; - - /* Loop around */ - if (counter > (SIP_RRLIST_LENGTH - 1)) { - counter = 0; - } - - gSIPRRList[counter] = *pMessageRecord; - gSIPRRList[counter].valid_coupled_message = FALSE; - counter++; -} - - -boolean -sipRelDevMessageIsDuplicate (sipRelDevMessageRecord_t *pMessageRecord, - int *idx) -{ - int i = 0; - - for (i = 0; i < SIP_RRLIST_LENGTH; i++) { - if ((strcmp(pMessageRecord->call_id, gSIPRRList[i].call_id) == 0) && - (pMessageRecord->cseq_number == gSIPRRList[i].cseq_number) && - (pMessageRecord->cseq_method == gSIPRRList[i].cseq_method) && - (strcasecmp_ignorewhitespace(pMessageRecord->tag, gSIPRRList[i].tag) == 0) && - (strcmp(pMessageRecord->from_user, gSIPRRList[i].from_user) == 0) && - (strcmp(pMessageRecord->from_host, gSIPRRList[i].from_host) == 0) && - (strcmp(pMessageRecord->to_user, gSIPRRList[i].to_user) == 0)) { - - if (pMessageRecord->is_request) { - *idx = i; - return (TRUE); - } else { - if (pMessageRecord->response_code == gSIPRRList[i].response_code) { - *idx = i; - return (TRUE); - } - } - } - } - - *idx = -1; - return (FALSE); -} - - -/* - * Function: sipRelDevCoupledMessageStore - * - * Parameters: - * pCoupledMessage - pointer to sipMessage_t for the message that - * needed reliable delivery store. - * call_id - pointer to const. char for the SIP call ID. - * cseq_number - the uint32_t for CSeq of the message. - * sipMethod_t - sipMethod_t the SIP method of the message. - * dest_ipaddr - uint32_t IP address of the destination address. - * dest_port - uint16_t destination port - * ignore_tag - boolean to ignore tag. - * - * Description: - * The function finds the corresponding entry in the gSIPRRList - * array that matches call_id, cseq number, method and possibly tag. - * If a match entry is found, the SIP message is composed and stored - * in the corresponding entry. - * - * Returns: - * idx - When the entry is found and successfully stored the - * SIP message. - * RELDEV_NO_STORED_MSG - encounter errors or no message is - * stored. - */ -int -sipRelDevCoupledMessageStore (sipMessage_t *pCoupledMessage, - const char *call_id, - uint32_t cseq_number, - sipMethod_t cseq_method, - boolean is_request, - int response_code, - cpr_ip_addr_t *dest_ipaddr, - uint16_t dest_port, - boolean ignore_tag) -{ - static const char *fname = "sipRelDevCoupledMessageStore"; - int i = 0; - char to_tag[MAX_SIP_TAG_LENGTH]; - - sipGetMessageToTag(pCoupledMessage, to_tag, MAX_SIP_TAG_LENGTH); - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Storing for reTx (cseq=%d, method=%s, " - "to_tag=<%s>)\n", DEB_F_PREFIX_ARGS(SIP_STORE, fname), cseq_number, - sipGetMethodString(cseq_method), to_tag); - - for (i = 0; i < SIP_RRLIST_LENGTH; i++) { - if ((strcmp(call_id, gSIPRRList[i].call_id) == 0) && - (cseq_number == gSIPRRList[i].cseq_number) && - (cseq_method == gSIPRRList[i].cseq_method) && - ((ignore_tag) ? TRUE : (strcasecmp_ignorewhitespace(to_tag, - gSIPRRList[i].tag) - == 0))) { - hStatus_t sippmh_write_status = STATUS_FAILURE; - uint32_t nbytes = SIP_UDP_MESSAGE_SIZE; - - /* - When storing the ACK message check that you are storing it - coupled with the correct response code and not transitional responses - */ - if (is_request == FALSE || - (is_request == TRUE && gSIPRRList[i].response_code == response_code)) { - gSIPRRList[i].coupled_message.message_buf[0] = '\0'; - sippmh_write_status = - sippmh_write(pCoupledMessage, - gSIPRRList[i].coupled_message.message_buf, - &nbytes); - if (sippmh_write_status == STATUS_FAILURE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_write() failed.\n", fname); - return (RELDEV_NO_STORED_MSG); - } - if ((gSIPRRList[i].coupled_message.message_buf[0] == '\0') || - (nbytes == 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_write() returned empty buffer string.\n", - fname); - return (RELDEV_NO_STORED_MSG); - } - gSIPRRList[i].coupled_message.message_buf_len = nbytes; - gSIPRRList[i].coupled_message.dest_ipaddr = *dest_ipaddr; - gSIPRRList[i].coupled_message.dest_port = dest_port; - gSIPRRList[i].valid_coupled_message = TRUE; - /* Return the stored idx to the caller */ - return (i); - } - } - } - return (RELDEV_NO_STORED_MSG); -} - -/* - * Function: sipRelDevGetStoredCoupledMessage - * - * Parameters: - * idx - int for the idx to retrieve stored SIP message. - * dest_buffer - pointer to char to retrieve the copy of the - * stored SIP message. - * dest_buf_size - uint32_t for the size of the dest_buffer. - * - * Description: - * The function gets the stored SIP message for the request entry. - * - * Returns: - * The function returns the number of the bytes of the SIP message - * obtained if SIP message is found otherwise it returns zero ( - * no SIP message available). - */ -uint32_t -sipRelDevGetStoredCoupledMessage (int idx, - char *dest_buffer, - uint32_t dest_buf_size) -{ - sipRelDevMessageRecord_t *record; - - if (dest_buffer == NULL) { - /* No destination buffer given, can not provide any result */ - return (0); - } - if ((idx < 0) || (idx >= SIP_RRLIST_LENGTH)) { - /* the stored message is out of range */ - return (0); - } - - record = &gSIPRRList[idx]; - - if (!record->valid_coupled_message) { - /* No message stored for the given idx */ - return (0); - } - if ((record->coupled_message.message_buf_len > dest_buf_size) || - (record->coupled_message.message_buf_len == 0)) { - /* - * The stored message size is larger than the give buffer or - * stored message length is zero? - */ - return (0); - } - /* Get the stored message to the caller */ - memcpy(dest_buffer, &record->coupled_message.message_buf[0], - record->coupled_message.message_buf_len); - return (record->coupled_message.message_buf_len); -} - -int -sipRelDevCoupledMessageSend (int idx) -{ - static const char *fname = "sipRelDevCoupledMessageSend"; - char dest_ipaddr_str[MAX_IPADDR_STR_LEN]; - - if ((idx < 0) || (idx >= SIP_RRLIST_LENGTH)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Argument Check: idx (=%d) out of bounds.\n", - fname, idx); - return SIP_ERROR; - } - - if (gSIPRRList[idx].valid_coupled_message) { - ipaddr2dotted(dest_ipaddr_str, - &gSIPRRList[idx].coupled_message.dest_ipaddr); - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Sending stored coupled message (idx=%d) to " - "<%s>:<%d>\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname), idx, dest_ipaddr_str, - gSIPRRList[idx].coupled_message.dest_port); - if (sipTransportChannelSend(NULL, - gSIPRRList[idx].coupled_message.message_buf, - gSIPRRList[idx].coupled_message.message_buf_len, - sipMethodInvalid, - &(gSIPRRList[idx].coupled_message.dest_ipaddr), - gSIPRRList[idx].coupled_message.dest_port, - 0) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipTransportChannelSend() failed." - " Stored message not sent.\n", fname); - return SIP_ERROR; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Duplicate message detected but failed to" - " find valid coupled message. Stored message not sent.\n", - fname); - return SIP_ERROR; - } - return SIP_OK; -} - - -/* - * Function for clearing all the messages belonging to the - * associated with the specified call_id, from_user, from_host, - * and to_user - */ -void -sipRelDevMessagesClear (const char *call_id, - const char *from_user, - const char *from_host, - const char *to_user) -{ - int i = 0; - - for (i = 0; i < SIP_RRLIST_LENGTH; i++) { - if ((strcmp(call_id, gSIPRRList[i].call_id) == 0) && - (strcmp(from_user, gSIPRRList[i].from_user) == 0) && - (strcmp(from_host, gSIPRRList[i].from_host) == 0) && - (strcmp(to_user, gSIPRRList[i].to_user) == 0)) { - memset(&gSIPRRList[i], 0, sizeof(sipRelDevMessageRecord_t)); - } - } - return; -} - -/* - * Function for clearing all the messages - */ -void sipRelDevAllMessagesClear(){ - int i = 0; - for (i = 0; i < SIP_RRLIST_LENGTH; i++) { - memset(&gSIPRRList[i], 0, sizeof(sipRelDevMessageRecord_t)); - } - return; -} diff --git a/libs/sipcc/core/sipstack/ccsip_sdp.c b/libs/sipcc/core/sipstack/ccsip_sdp.c deleted file mode 100644 index 763978c3e3..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_sdp.c +++ /dev/null @@ -1,354 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Implements functions to parse and create SDP(Session Description Protocol) - * (RFC 2327) messages. Coded to be sufficient for SIP only. - * Note: The SDP body fields as per the RFC are : - * Optional items are marked with a `*'. - * - * Session description - * v= (protocol version) - * o= (owner/creator and session identifier). - * s= (session name) - * i=* (session information) - * u=* (URI of description) - * e=* (email address) - * p=* (phone number) - * c=* (connection information - not required if included in all media) - * b=* (bandwidth information) - * One or more time descriptions (see below) - * z=* (time zone adjustments) - * k=* (encryption key) - * a=* (zero or more session attribute lines) - * Zero or more media descriptions (see below) - * - *Time description - * t= (time the session is active) - * r=* (zero or more repeat times) - * - *Media description - * m= (media name and transport address) - * i=* (media title) - * c=* (connection information - optional if included at session-level) - * b=* (bandwidth information) - * k=* (encryption key) - * a=* (zero or more media attribute lines) - * - * Note that the mandatory fields are : - * v= , o=, s=, t=, m= - * Email address and phone number (e=, p=) fields would very soon be useful - * to SDP in large scale SIP networks. - * - * t= 0 0 - * would indicate an unbound or a permanent session . This would be changed - * to specific (or probably user-configured values) once the time duration - * of SIP call sessions are recorded and are used for scheduling. - */ - - -#include "cpr_types.h" -#include "cpr_memory.h" -#include "sdp.h" -#include "text_strings.h" -#include "ccsip_sdp.h" -#include "ccsip_core.h" -#include "phone_debug.h" - - - -static void *ccsip_sdp_config = NULL; /* SDP parser/builder configuration */ - -/* - * sip_sdp_init - * - * This function initializes SDP parser with SIP-specific parameters. - * This includes supported media, network types, address types, - * transports and codecs. - * - * The function must be called once. - * - * Returns TRUE - successful - * FALSE - failed - */ -boolean -sip_sdp_init (void) -{ - ccsip_sdp_config = sdp_init_config(); - if (!ccsip_sdp_config) { - CCSIP_ERR_MSG("sdp_init_config() failure"); - return FALSE; - } - - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_AUDIO, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_VIDEO, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_APPLICATION, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_DATA, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_CONTROL, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_NAS_RADIUS, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_NAS_TACACS, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_NAS_DIAMETER, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_NAS_L2TP, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_NAS_LOGIN, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_NAS_NONE, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_IMAGE, TRUE); - sdp_media_supported(ccsip_sdp_config, SDP_MEDIA_TEXT, TRUE); - sdp_nettype_supported(ccsip_sdp_config, SDP_NT_INTERNET, TRUE); - sdp_addrtype_supported(ccsip_sdp_config, SDP_AT_IP4, TRUE); - sdp_addrtype_supported(ccsip_sdp_config, SDP_AT_IP6, TRUE); - sdp_transport_supported(ccsip_sdp_config, SDP_TRANSPORT_RTPAVP, TRUE); - sdp_transport_supported(ccsip_sdp_config, SDP_TRANSPORT_UDPTL, TRUE); - sdp_require_session_name(ccsip_sdp_config, FALSE); - - return (TRUE); -} - -/* - * sipsdp_create() - * - * Allocate a standard SDP with SIP config and set debug options - * based on ccsip debug settings - */ -sdp_t * -sipsdp_create (const char *peerconnection) -{ - sdp_t *sdp; - - sdp = sdp_init_description(peerconnection, ccsip_sdp_config); - if (!sdp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SDP allocation failure\n", __FUNCTION__); - return (NULL); - } - - /* - * Map "ccsip debug events (or info)" to SDP warnings - * "ccsip debug errors to SDP errors - */ - CCSIP_INFO_DEBUG { - sdp_debug(sdp, SDP_DEBUG_WARNINGS, TRUE); - } - - CCSIP_ERR_DEBUG { - sdp_debug(sdp, SDP_DEBUG_ERRORS, TRUE); - } - - -#ifdef DEBUG_SDP_LIB - /* - * Enabling this is redundant to the existing message printing - * available for the entire SIP text messages, so it is not - * enabled here. It is useful for debugging the SDP parser, - * however. - */ - CCSIP_MESSAGES_DEBUG { - sdp_debug(sdp, SDP_DEBUG_TRACE, TRUE); - } -#endif - - return (sdp); -} - -/* - * sipsdp_free() - * - * Frees the SIP SDP structure, the contained common SDP structure, - * and each stream structure in the linked stream list. - * - * sip_sdp is set to NULL after being freed. - */ -void -sipsdp_free (cc_sdp_t **sip_sdp) -{ - const char *fname = "sipsdp_free: "; - sdp_result_e sdp_ret; - - if (!*sip_sdp) { - return; - } - - if ((*sip_sdp)->src_sdp) { - sdp_ret = sdp_free_description((*sip_sdp)->src_sdp); - if (sdp_ret != SDP_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%d while freeing src_sdp\n", - fname, sdp_ret); - } - } - if ((*sip_sdp)->dest_sdp) { - sdp_ret = sdp_free_description((*sip_sdp)->dest_sdp); - if (sdp_ret != SDP_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%d while freeing dest_sdp\n", - fname, sdp_ret); - } - } - - SDP_FREE(*sip_sdp); -} - -/* - * sipsdp_info_create() - * - * Allocates and initializes a SIP SDP structure. This function does - * not create the src_sdp, dest_sdp, or streams list. - * - * Returns: pointer to SIP SDP structure - if successful - * NULL - failure to allocate storage - */ -cc_sdp_t * -sipsdp_info_create (void) -{ - cc_sdp_t *sdp_info = (cc_sdp_t *) cpr_malloc(sizeof(cc_sdp_t)); - - if (sdp_info) { - sdp_info->src_sdp = NULL; - sdp_info->dest_sdp = NULL; - } - - return (sdp_info); -} - - -/* - * sipsdp_src_dest_free() - * - * Frees the SRC and/or DEST SDP. It will also free the sdp_info - * structure if both SRC and DEST SDP are freed. - * - * Input: - * flags - bitmask indicating if src and/or dest sdp should be - * freed - * - * Returns: - * sdp_info is set to NULL if freed. - */ -void -sipsdp_src_dest_free (uint16_t flags, cc_sdp_t **sdp_info) -{ - const char *fname = "sipsdp_src_dest_free: "; - sdp_result_e sdp_ret; - - if ((sdp_info == NULL) || (*sdp_info == NULL)) { - return; - } - - /* Free the SRC and/or DEST SDP */ - if (flags & CCSIP_SRC_SDP_BIT) { - if ((*sdp_info)->src_sdp) { - sdp_ret = sdp_free_description((*sdp_info)->src_sdp); - if (sdp_ret != SDP_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%d while freeing src_sdp\n", - fname, sdp_ret); - } - (*sdp_info)->src_sdp = NULL; - } - } - - if (flags & CCSIP_DEST_SDP_BIT) { - if ((*sdp_info)->dest_sdp) { - sdp_ret = sdp_free_description((*sdp_info)->dest_sdp); - if (sdp_ret != SDP_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%d while freeing dest_sdp\n", - fname, sdp_ret); - } - (*sdp_info)->dest_sdp = NULL; - } - - } - - /* - * If both src and dest sdp are NULL, there is no need to keep the - * sdp_info structure around. Free it. - */ - if (((*sdp_info)->src_sdp == NULL) && ((*sdp_info)->dest_sdp == NULL)) { - sipsdp_free(sdp_info); - *sdp_info = NULL; - } -} - - -/* - * sipsdp_src_dest_create() - * - * Allocates and initializes a SRC and/or DEST SDP. If the sdp_info - * structure has not yet been allocated, it is allocated here. - * - * Input: - * flags - bitmask indicating if src and/or dest sdp should be - * created - * - * Returns: pointer to SIP SDP structure - if successful - * NULL - failure to allocate storage - */ -void -sipsdp_src_dest_create (const char *peerconnection, - uint16_t flags, cc_sdp_t **sdp_info) -{ - - if (!(*sdp_info)) { - *sdp_info = sipsdp_info_create(); - if (!(*sdp_info)) { - return; - } - } - - /* Create the SRC and/or DEST SDP */ - if (flags & CCSIP_SRC_SDP_BIT) { - (*sdp_info)->src_sdp = sipsdp_create(peerconnection); - if (!((*sdp_info)->src_sdp)) { - sipsdp_src_dest_free(flags, sdp_info); - return; - } - } - - if (flags & CCSIP_DEST_SDP_BIT) { - (*sdp_info)->dest_sdp = sipsdp_create(peerconnection); - if (!((*sdp_info)->dest_sdp)) { - sipsdp_src_dest_free(flags, sdp_info); - return; - } - } -} - -/* - * sipsdp_write_to_buf() - * - * This function builds the specified SDP in a text buffer and returns - * a pointer to this buffer. - * - * Returns: pointer to buffer - no errors - * NULL - errors were encountered while building - * the SDP. The details of the build failure - * can be determined by enabling SDP debugs - * and by examining SDP library error counters. - */ -char * -sipsdp_write_to_buf (cc_sdp_t *sdp_info, uint32_t *retbytes) -{ - flex_string fs; - // uint32_t sdp_len; - sdp_result_e rc; - - flex_string_init(&fs); - - if (!sdp_info || !sdp_info->src_sdp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"NULL sdp_info or src_sdp\n", __FUNCTION__); - return (NULL); - } - - if ((rc = sdp_build(sdp_info->src_sdp, &fs)) - != SDP_SUCCESS) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sdp_build rc=%s\n", DEB_F_PREFIX_ARGS(SIP_SDP, __FUNCTION__), - sdp_get_result_name(rc)); - - flex_string_free(&fs); - *retbytes = 0; - return (NULL); - } - - *retbytes = fs.string_length; - - /* We are not calling flex_string_free on this, instead returning the buffer - * caller's responsibility to free - */ - return fs.buffer; -} diff --git a/libs/sipcc/core/sipstack/ccsip_spi_utils.c b/libs/sipcc/core/sipstack/ccsip_spi_utils.c deleted file mode 100755 index 97ce502d31..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_spi_utils.c +++ /dev/null @@ -1,134 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This file implements a bunch of stuff used only by ccsip_spi.c, - * and this is done mostly to reduce the file size and some extra - * modularity. Includes things like tables/trees to hold SIP and - * CCAPI callids, conversion from CCAPI to SIP cause codes and the - * like. - */ -#include "plstr.h" -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "pmhutils.h" -#include "ccsip_spi_utils.h" -#include "util_string.h" -#include "ccsip_core.h" - -extern uint32_t IPNameCk(char *name, char *addr_error); - -/* - * Checks a token which forms a part of the - * domain-name and makes sure that it conforms - * to the grammar specified in RFC 1034 (DNS) - */ -int -sipSPICheckDomainToken (char *token) -{ - if (token == NULL) { - return FALSE; - } - - if (*token) { - if (isalnum((int)token[strlen(token) - 1]) == FALSE) { - return FALSE; - } - } - - if (isalnum((int)token[0]) == FALSE) { - return FALSE; - } - - while (*token) { - if ((isalnum((int)*token) == FALSE) && (*token != '-')) { - return FALSE; - } - token++; - } - return TRUE; -} - -/* - * Checks domain-name is valid syntax-wise - * Returns TRUE, if valid - */ -boolean -sipSPI_validate_hostname (char *str) -{ - char *tok; - char ip_addr_out[MAX_IPADDR_STR_LEN]; - char *strtok_state; - - if (str == NULL) { - return FALSE; - } - - /* Check if valid IPv6 address */ - if (cpr_inet_pton(AF_INET6, str, ip_addr_out)) { - return TRUE; - } - - if (*str) { - if (isalnum((int)str[strlen(str) - 1]) == FALSE) { - return FALSE; - } - } - - if (isalnum((int)str[0]) == FALSE) { - return FALSE; - } - - tok = PL_strtok_r(str, ".", &strtok_state); - if (tok == NULL) { - return FALSE; - } else { - if (sipSPICheckDomainToken(tok) == FALSE) { - return FALSE; - } - } - - while ((tok = PL_strtok_r(NULL, ".", &strtok_state)) != NULL) { - if (sipSPICheckDomainToken(tok) == FALSE) { - return FALSE; - } - } - - return TRUE; -} - -/* - * Determines if the IP address or domain-name is - * valid (syntax-wise only) - * Returns TRUE, if valid - */ -boolean -sipSPI_validate_ip_addr_name (char *str) -{ - uint32_t sip_address; - boolean retval = TRUE; - char *target = NULL; - char addr_error; - - if (str == NULL) { - return FALSE; - } else { - target = cpr_strdup(str); - if (!target) { - return FALSE; - } - } - sip_address = IPNameCk(target, &addr_error); - if ((!sip_address) && (addr_error)) { - cpr_free(target); - return retval; - } else { - if (sipSPI_validate_hostname(target) == FALSE) { - retval = FALSE; - } - } - cpr_free(target); - return retval; -} diff --git a/libs/sipcc/core/sipstack/ccsip_subsmanager.c b/libs/sipcc/core/sipstack/ccsip_subsmanager.c deleted file mode 100644 index 5189eb24c7..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_subsmanager.c +++ /dev/null @@ -1,5290 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_in.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_rand.h" -#include "ccsip_subsmanager.h" -#include "util_string.h" -#include "ccapi.h" -#include "phone_debug.h" -#include "ccsip_messaging.h" -#include "ccsip_platform_udp.h" -#include "ccsip_macros.h" -#include "ccsip_task.h" -#include "sip_common_transport.h" -#include "ccsip_platform_timers.h" -#include "platform_api.h" -#include "ccsip_register.h" -#include "ccsip_reldev.h" -#include "phntask.h" -#include "subapi.h" -#include "debug.h" -#include "ccsip_callinfo.h" -#include "regmgrapi.h" -#include "text_strings.h" -#include "configapp.h" -#include "kpmlmap.h" - -/* - * Global Variables - */ -sipSCB_t subsManagerSCBS[MAX_SCBS]; // Array of SCBS -sipSubsHistory_t gSubHistory[MAX_SCB_HISTORY]; -sipTimerCallbackFn_t callbackFunctionSubNot = sip_platform_subnot_msg_timer_callback; -sipTimerCallbackFn_t callbackFunctionPeriodic = sip_platform_subnot_periodic_timer_callback; -extern sipPlatformUITimer_t sipPlatformUISMSubNotTimers[]; // Array of timers -const char kpmlRequestAcceptHeader[] = SIP_CONTENT_TYPE_KPML_REQUEST; -const char kpmlResponseAcceptHeader[] = SIP_CONTENT_TYPE_KPML_RESPONSE; -const char dialogAcceptHeader[] = SIP_CONTENT_TYPE_DIALOG; -const char presenceAcceptHeader[] = "application/cpim-pidf+xml"; -const char remoteccResponseAcceptHeader[] = SIP_CONTENT_TYPE_REMOTECC_RESPONSE; -const char remoteccRequestAcceptHeader[] = SIP_CONTENT_TYPE_REMOTECC_REQUEST; - -static sll_handle_t s_TCB_list = NULL; // signly linked list handle of TCBs - -// Externs -extern int dns_error_code; // Global DNS error code - -// Status and statistics for the Subscription Manager -int subsManagerRunning = 0; -int internalRegistrations = 0; - -int incomingSubscribes = 0; -int incomingRefers = 0; -int incomingNotifies = 0; -int incomingUnsolicitedNotifies = 0; -int incomingSubscriptions = 0; - -int outgoingSubscribes = 0; -int outgoingNotifies = 0; -int outgoingUnsolicitedNotifies = 0; -int outgoingSubscriptions = 0; - -int currentScbsAllocated = 0; -int maxScbsAllocated = 0; - -#define MAX_SUB_EVENTS 5 -#define MAX_SUB_EVENT_NAME_LEN 16 -/* - * sub_id format: - * - * sub_id is a 32 bit quantity. The bit 32-16 holds a unique ID and - * the bits 15-0 holds a SCB index. The following definitions help - * support this formation. - * - * Assumption: The above format assumes that SCB index never be - * larger than 16 bit unsigned value. - */ -#define SUB_ID_UNIQUE_ID_POSITION 16 /* shift position of unique id part*/ -#define SUB_IDSCB_INDEX_MASK 0xffff /* mask for obtaining scb index */ -#define GET_SCB_INDEX_FROM_SUB_ID(sub_id) \ - (sub_id & SUB_IDSCB_INDEX_MASK) - -/* - * Event names - */ -const char eventNames[MAX_SUB_EVENTS][MAX_SUB_EVENT_NAME_LEN] = -{ - "dialog", - "sip-profile", - "kpml", - "presence", - "refer" -}; - -/* - * Forward Function Declarations - */ -boolean sipSPISendSubscribe(sipSCB_t *scbp, boolean renew, boolean authen); -boolean sipSPISendSubNotify(ccsip_common_cb_t *cbp, boolean authen); -boolean sipSPISendSubscribeNotifyResponse(sipSCB_t *scbp, - uint16_t response_code, - uint32_t cseq); -boolean sipSPISendSubNotifyResponse(sipSCB_t *scbp, int response_code); -void free_scb(int scb_index, const char *fname); - -// External Declarations -extern uint32_t IPNameCk(char *name, char *addr_error); -extern void kpml_init(void); -extern void kpml_shutdown(void); - - -extern void sip_platform_handle_service_control_notify(sipServiceControl_t * scp); -cc_int32_t show_subsmanager_stats(cc_int32_t argc, const char *argv[]); -static void show_scbs_inuse(void); -static void tcb_reset(void); - -typedef struct { - unsigned long cseq; - char *via; -} sub_not_trxn_t; - -/* - * Function: find_matching_trxn() - * - * Parameters: key - key to find the matching node. - * data - node data. - * - * Descriotion: is invoked by sll_find() to find the matching node based on the key. - * - * Returns: either SLL_MATCH_FOUND or SLL_MATCH_NOT_FOUND. - */ -static sll_match_e -find_matching_trxn (void *key, void *data) -{ - unsigned long cseq = *((unsigned long *)key); - sub_not_trxn_t *trxn_p = (sub_not_trxn_t *) data; - - if (cseq == trxn_p->cseq) { - return SLL_MATCH_FOUND; - } - - return SLL_MATCH_NOT_FOUND; -} - -/* - * Function: store_incoming_trxn() - * - * Description: stores the via header in incoming_trxns - * - * Parameters: via, cseq and scbp - * - * Returns: TRUE if the via header is successfully stored, - * FALSE otherwise. - */ -static boolean -store_incoming_trxn (const char *via, unsigned long cseq, sipSCB_t *scbp) -{ - static const char *fname = "store_incoming_trxn"; - size_t size = 0; - - sub_not_trxn_t *sub_not_trxn_p; - - if (scbp->incoming_trxns == NULL) { - scbp->incoming_trxns = sll_create(find_matching_trxn); - if (scbp->incoming_trxns == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sll_create() failed\n", fname); - return FALSE; - } - } - sub_not_trxn_p = (sub_not_trxn_t *)cpr_malloc(sizeof(sub_not_trxn_t)); - if (sub_not_trxn_p == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed\n", fname); - return FALSE; - } - sub_not_trxn_p->cseq = cseq; - size = strlen(via) + 1; - sub_not_trxn_p->via = (char *) cpr_malloc(size); - if (sub_not_trxn_p->via) { - sstrncpy(sub_not_trxn_p->via, via, size); - } - (void) sll_append(scbp->incoming_trxns, sub_not_trxn_p); - - return TRUE; -} - -void -free_event_data (ccsip_event_data_t *event_data) -{ - ccsip_event_data_t *tmp; - - if (event_data == NULL) { - return; - } - - while (event_data != NULL) { - tmp = event_data->next; - if (event_data->type == EVENT_DATA_RAW) { - if (event_data->u.raw_data.data) - cpr_free(event_data->u.raw_data.data); - } - cpr_free(event_data); - event_data = tmp; - } -} - -void -append_event_data (ccsip_event_data_t * event_data, - ccsip_event_data_t *new_data) -{ - while (event_data->next != NULL) { - event_data = event_data->next; - } - event_data->next = new_data; - new_data->next = NULL; -} - -void -free_pending_requests (sipspi_msg_list_t *pendingRequests) -{ - sipspi_msg_list_t *tmp; - - while (pendingRequests) { - switch (pendingRequests->cmd) { - case SIPSPI_EV_CC_NOTIFY: - { - sipspi_notify_t *notify = &(pendingRequests->msg->msg.notify); - - free_event_data(notify->eventData); - cpr_free(pendingRequests->msg); - } - break; - case SIPSPI_EV_CC_SUBSCRIBE_REGISTER: - cpr_free(&pendingRequests->msg->msg.subs_reg); - break; - case SIPSPI_EV_CC_SUBSCRIBE: - { - sipspi_subscribe_t *subs = &(pendingRequests->msg->msg.subscribe); - - free_event_data(subs->eventData); - cpr_free(pendingRequests->msg); - } - break; - case SIPSPI_EV_CC_SUBSCRIBE_RESPONSE: - cpr_free(pendingRequests->msg); - break; - case SIPSPI_EV_CC_NOTIFY_RESPONSE: - cpr_free(pendingRequests->msg); - break; - case SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED: - cpr_free(pendingRequests->msg); - break; - default: - break; - } - tmp = pendingRequests; - pendingRequests = pendingRequests->next; - cpr_free(tmp); - } -} - -boolean -append_pending_requests (sipSCB_t *scbp, - sipspi_msg_t *newRequest, - uint32_t cmd) -{ - static const char *fname = "append_pending_requests"; - sipspi_msg_list_t *pendingRequest = NULL; - sipspi_msg_list_t *tmp = NULL; - - if (!scbp) - return (FALSE); - - pendingRequest = (sipspi_msg_list_t *) - cpr_malloc(sizeof(sipspi_msg_list_t)); - if (!pendingRequest) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed\n", fname); - return (FALSE); - } - pendingRequest->cmd = cmd; - pendingRequest->msg = newRequest; - pendingRequest->next = NULL; - - if (scbp->pendingRequests == NULL) { - scbp->pendingRequests = pendingRequest; - return (TRUE); - } - - tmp = scbp->pendingRequests; - while (tmp->next != NULL) { - tmp = tmp->next; - } - tmp->next = pendingRequest; - return (TRUE); -} - -void -handle_pending_requests (sipSCB_t *scbp) -{ - sipspi_msg_list_t *pendingRequest = NULL; - - if (scbp->pendingRequests) { - pendingRequest = scbp->pendingRequests; - scbp->pendingRequests = pendingRequest->next; - switch (pendingRequest->cmd) { - case SIPSPI_EV_CC_NOTIFY: - { - sipspi_msg_t *notify = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_notify(notify); - cpr_free(notify); - } - break; - case SIPSPI_EV_CC_SUBSCRIBE_REGISTER: - cpr_free(pendingRequest->msg); - cpr_free(pendingRequest); - break; - case SIPSPI_EV_CC_SUBSCRIBE: - { - sipspi_msg_t *subs = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_subscribe(subs); - cpr_free(subs); - } - break; - case SIPSPI_EV_CC_SUBSCRIBE_RESPONSE: - { - sipspi_msg_t *subs_resp = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_subscribe_response(subs_resp); - cpr_free(subs_resp); - } - break; - case SIPSPI_EV_CC_NOTIFY_RESPONSE: - { - sipspi_msg_t *not_resp = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_notify_response(not_resp); - cpr_free(not_resp); - } - break; - case SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED: - { - sipspi_msg_t *term = pendingRequest->msg; - - cpr_free(pendingRequest); - (void) subsmanager_handle_ev_app_subscription_terminated(term); - cpr_free(term); - } - break; - default: - if (pendingRequest->msg) { - cpr_free(pendingRequest->msg); - } - cpr_free(pendingRequest); - break; - } - } -} - -///////////////////////////////////////////////////////////// Test Only !! - -static void -ccsip_api_subscribe_result (ccsip_sub_not_data_t * msg_data) -{ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Subscribe Response: request_id=%d, sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB_RESP, "ccsip_api_subscribe_result"), - msg_data->request_id, msg_data->sub_id); - if (msg_data->u.subs_result_data.status_code == REQUEST_TIMEOUT) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Request timed out\n", DEB_F_PREFIX_ARGS(SIP_SUB_RESP, "ccsip_api_subscribe_result")); - } -} - -static void -print_event_data (ccsip_event_data_t * eventDatap) -{ - static const char *fname = "print_event_data"; - - while (eventDatap) { - switch (eventDatap->type) { - case EVENT_DATA_INVALID: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Invalid Data Received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_KPML_REQUEST: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"KPML Request Event Data Received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_KPML_RESPONSE: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"KPML Response Event Data Received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_PRESENCE: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Presence Event Data Received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_DIALOG: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Dialog Event Data Received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - case EVENT_DATA_RAW: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Raw Event Data Received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - default: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Event Data Type Not Understood\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - eventDatap = eventDatap->next; - } -} - -static void -ccsip_api_notify_result (ccsip_sub_not_data_t *msg_data) -{ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Notify Response\n", DEB_F_PREFIX_ARGS(SIP_SUB_RESP, "ccsip_api_notify_result")); -} - -static void -ccsip_api_notify_ind (ccsip_sub_not_data_t *msg) -{ - static const char *fname = "ccsip_api_notify_ind"; - sipspi_msg_t not_resp; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Notify, request_id=%d, sub_id=%x\n",DEB_F_PREFIX_ARGS(SIP_SUB_RESP, fname), - msg->request_id, msg->sub_id); - - // Check out what's there in the notify indication - if (msg->u.notify_ind_data.eventData) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Event Data Received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - print_event_data(msg->u.notify_ind_data.eventData); - free_event_data(msg->u.notify_ind_data.eventData); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No event data received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - } - - // Respond with a 200OK - memset(¬_resp, 0, sizeof(sipspi_msg_t)); - not_resp.msg.notify_resp.sub_id = msg->sub_id; - not_resp.msg.notify_resp.response_code = SIP_SUCCESS_SETUP; - not_resp.msg.notify_resp.duration = 3600; - - (void) subsmanager_handle_ev_app_notify_response(¬_resp); -} - -static void -ccsip_api_subscribe_terminate (ccsip_sub_not_data_t *msg_data) -{ - sipspi_msg_t terminate; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Terminate notice\n", DEB_F_PREFIX_ARGS(SIP_SUB, "ccsip_api_subscribe_terminate")); - if (msg_data->u.subs_term_data.status_code == NETWORK_SUBSCRIPTION_EXPIRED) { - terminate.msg.subs_term.sub_id = msg_data->sub_id; - terminate.msg.subs_term.immediate = TRUE; - (void) subsmanager_handle_ev_app_subscription_terminated(&terminate); - } -} - -static void -ccsip_api_subscribe_ind (ccsip_sub_not_data_t *msg) -{ - static const char *fname = "ccsip_api_subscribe_ind"; - sipspi_msg_t subs_resp, notify, terminate; - ccsip_event_data_t *eventData; - char *junkdata; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received Subscription Request\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - // Check out what's there in the subs indication - if (msg->u.subs_ind_data.eventData) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Event Data Received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - print_event_data(msg->u.subs_ind_data.eventData); - free_event_data(msg->u.subs_ind_data.eventData); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No event data received\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - } - - // Accept the subscription with a 200 OK response - subs_resp.msg.subscribe_resp.duration = msg->u.subs_ind_data.expires; - subs_resp.msg.subscribe_resp.response_code = SIP_SUCCESS_SETUP; - subs_resp.msg.subscribe_resp.sub_id = msg->sub_id; - (void) subsmanager_handle_ev_app_subscribe_response(&subs_resp); - - // Now send a NOTIFY - notify.msg.notify.notifyResultCallback = ccsip_api_notify_result; - notify.msg.notify.sub_id = msg->sub_id; - notify.msg.notify.eventData = NULL; - - // Now fill in some data in the kpml structure - eventData = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (eventData == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Malloc of ccsip event data structure failed.\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - return; - } - - memset(eventData, 0, sizeof(ccsip_event_data_t)); - sstrncpy(eventData->u.kpml_request.pattern.regex.regexData, "012", 32); - sstrncpy(eventData->u.kpml_request.version, "1.0", 16); - eventData->type = EVENT_DATA_KPML_REQUEST; - notify.msg.notify.eventData = eventData; - - // Now fill in some other junk data - eventData = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (eventData == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Malloc of ccsip event structure failed.\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - cpr_free(notify.msg.notify.eventData); - return; - } - - junkdata = (char *) cpr_malloc(20); - if (junkdata == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Malloc of junk data structure failed.\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - cpr_free(eventData); - cpr_free(notify.msg.notify.eventData); - return; - } - - memset(eventData, 0, sizeof(ccsip_event_data_t)); - memset(junkdata, 0, 20); - sstrncpy(junkdata, "Hello", 20); - - eventData->u.raw_data.data = junkdata; - eventData->u.raw_data.length = strlen(junkdata); - eventData->type = EVENT_DATA_RAW; - notify.msg.notify.eventData->next = eventData; - (void) subsmanager_handle_ev_app_notify(¬ify); - - // If expires is 0, terminate the subscription - if (msg->u.subs_ind_data.expires == 0) { - terminate.msg.subs_term.sub_id = msg->sub_id; - terminate.msg.subs_term.immediate = TRUE; - (void) subsmanager_handle_ev_app_subscription_terminated(&terminate); - } -} - -static void -test_send_subscribe () -{ - sipspi_msg_t subscribe; - ccsip_event_data_t *eventData; - - memset(&subscribe.msg.subscribe, 0, sizeof(sipspi_subscribe_t)); - - subscribe.msg.subscribe.eventPackage = CC_SUBSCRIPTIONS_KPML; - subscribe.msg.subscribe.duration = 15; - sstrncpy(subscribe.msg.subscribe.subscribe_uri, "19921", CC_MAX_DIALSTRING_LEN); - sstrncpy(subscribe.msg.subscribe.subscriber_uri, "12345", CC_MAX_DIALSTRING_LEN); - subscribe.msg.subscribe.request_id = 1003; - subscribe.msg.subscribe.dn_line = 2; - subscribe.msg.subscribe.sub_id = CCSIP_SUBS_INVALID_SUB_ID; - subscribe.msg.subscribe.subsResultCallback = ccsip_api_subscribe_result; - subscribe.msg.subscribe.subsTermCallback = ccsip_api_subscribe_terminate; - subscribe.msg.subscribe.notifyIndCallback = ccsip_api_notify_ind; - subscribe.msg.subscribe.auto_resubscribe = TRUE; - - // Now fill in some data in the kpml structure - /* - * eventData = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - * if (eventData == NULL) { - * CCSIP_DEBUG_TASK("Malloc of ccsip event data failed.\n"); - * return; - * } - * - * memset(eventData, 0, sizeof(ccsip_event_data_t)); - * sstrncpy(eventData->u.kpml_request.pattern.regex.regexData, "012", sizeof(eventData->u.kpml_request.pattern.regex.regexData)); - * sstrncpy(eventData->u.kpml_request.version, "1.0", sizeof(eventData->u.kpml_request.version)); - * eventData->type = EVENT_DATA_KPML_REQUEST; - * subscribe.msg.subscribe.eventData = eventData; - */ - // Now fill in some other junk data - eventData = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (eventData == NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Malloc of ccsip event data failed.\n", DEB_F_PREFIX_ARGS(SIP_EVT, "test_send_subscribe")); - return; - } - - memset(eventData, 0, sizeof(ccsip_event_data_t)); - eventData->type = EVENT_DATA_RAW; - eventData->u.raw_data.data = (char *) cpr_malloc(150); - if (eventData->u.raw_data.data) { - eventData->u.raw_data.length = 150; - memset(eventData->u.raw_data.data, 'V', 150); - } else { - eventData->u.raw_data.length = 0; - } - eventData->next = NULL; - subscribe.msg.subscribe.eventData = eventData; - - (void) subsmanager_handle_ev_app_subscribe(&subscribe); -} - -static void -test_send_register () -{ - sipspi_msg_t register_msg; - - memset(®ister_msg, 0, sizeof(sipspi_msg_t)); - register_msg.msg.subs_reg.eventPackage = CC_SUBSCRIPTIONS_PRESENCE; - register_msg.msg.subs_reg.subsIndCallback = ccsip_api_subscribe_ind; - register_msg.msg.subs_reg.subsTermCallback = ccsip_api_subscribe_terminate; - (void) subsmanager_handle_ev_app_subscribe_register(®ister_msg); -} - -int -subsmanager_test_start_routine () -{ - static int subscribe_sent = 0; - static int register_sent = 0; - - if (subscribe_sent == 0) { - test_send_subscribe(); - subscribe_sent = 1; - } - - if (register_sent == 0) { - test_send_register(); - register_sent = 1; - } - return 0; - -} - -/************************************************************ - * Send local error to the calling application - * This function reuses the callback interface to pass the - * (bad) result of requests from the application - ************************************************************/ -void -sip_send_error_message (ccsip_sub_not_data_t *msg_data, - cc_srcs_t dest_task, - int msgid, - ccsipGenericCallbackFn_t callbackFn, - const char *fname) -{ - if (!msg_data) { - return; - } - if (callbackFn) { - (*callbackFn) (msg_data); - } else if (dest_task != CC_SRC_MIN) { - (void) sip_send_message(msg_data, dest_task, msgid); - } -} - - -/******************************************************** - * Shutdown the Subscription Manager - ********************************************************/ -int -sip_subsManager_shut () -{ - const char *fname = "sip_subsManager_shut"; - int i; - sipSCB_t *scbp = NULL; - ccsip_sub_not_data_t error_data; - - if (subsManagerRunning == 0) { - return (0); - } - error_data.reason_code = SM_REASON_CODE_SHUTDOWN; - // Send indication of subscription ended to internal apps - // then clean and free up subscriptions and SCB - for (i = 0; i < MAX_SCBS; i++) { - scbp = &(subsManagerSCBS[i]); - if (scbp->smState == SUBS_STATE_IDLE) { - continue; - } - - error_data.sub_id = scbp->sub_id; - error_data.request_id = scbp->request_id; - error_data.sub_duration = 0; - error_data.event = scbp->hb.event_type; - error_data.msg_id = scbp->subsTermCallbackMsgID; - error_data.line_id = scbp->hb.dn_line; - error_data.gsm_id = scbp->gsm_id; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Sending shutdown notification for scb=%d" - " sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), i, scbp->sub_id); - - sip_send_error_message(&error_data, scbp->subsNotCallbackTask, - scbp->subsTermCallbackMsgID, - scbp->subsTermCallback, fname); - - free_scb(i, fname); - } - - // Shut down the periodic timer - (void) sip_platform_subnot_periodic_timer_stop(); - - // Mark subsManager as stopped running - subsManagerRunning = 0; - - tcb_reset(); - - return (0); -} - -/******************************************************** - * Common code notifying application for a failover/fallback - * or CCM new registration (reset) event. Send a notification to - * applications that have an active subscription - ********************************************************/ -static int -sip_subsManager_reg_failure_common (ccsip_reason_code_e reason) -{ - const char *fname = "sip_subsManager_reg_failure_common"; - int i; - sipSCB_t *scbp = NULL; - ccsip_sub_not_data_t error_data; - - if (subsManagerRunning == 0) { - return (0); - } - error_data.reason_code = reason; - // Send indication of subscription ended to internal apps - // then clean and free up subscriptions and SCB - for (i = 0; i < MAX_SCBS; i++) { - scbp = &(subsManagerSCBS[i]); - if (scbp->smState == SUBS_STATE_IDLE || - scbp->smState == SUBS_STATE_REGISTERED) { - // Update addr and port after rollover/ccm reset - scbp->hb.local_port = sipTransportGetListenPort(1, NULL); - sipTransportGetServerIPAddr(&(scbp->hb.dest_sip_addr),1); - scbp->hb.dest_sip_port = sipTransportGetPrimServerPort(1); - continue; - } - - error_data.sub_id = scbp->sub_id; - error_data.line_id = scbp->hb.dn_line; - error_data.request_id = scbp->request_id; - error_data.sub_duration = 0; - error_data.event = scbp->hb.event_type; - error_data.msg_id = scbp->subsTermCallbackMsgID; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Sending reg failure notification for " - "scb=%d sub_id=%x reason=%d\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), i, - scbp->sub_id, reason); - - sip_send_error_message(&error_data, scbp->subsNotCallbackTask, - scbp->subsTermCallbackMsgID, - scbp->subsTermCallback, fname); - - if (scbp->internal) { - outgoingSubscriptions--; - } else { - incomingSubscriptions--; - } - free_scb(i, fname); - } - - sipRelDevAllMessagesClear(); - return (0); -} - -/******************************************************** - * Handle a failover/fallback event - * to handle this event, send a notification to all - * applications that have an active subscription - ********************************************************/ -int -sip_subsManager_rollover () -{ - tcb_reset(); - return (sip_subsManager_reg_failure_common(SM_REASON_CODE_ROLLOVER)); -} - -/******************************************************** - * Handle a (CCM or Proxy) server down and up event^M - * to handle this event, send a notification to all^M - * applications that have an active subscription^M - ********************************************************/ -int -sip_subsManager_reset_reg (void) -{ - return (sip_subsManager_reg_failure_common(SM_REASON_CODE_RESET_REG)); -} - - -/*********************************************************** - * Send a protocol error message to application. The application - * decides whether to terminate and restart the subscription - * or otherwise - ***********************************************************/ -void -sip_subsManager_send_protocol_error (sipSCB_t *scbp, int scb_index, - boolean terminate) -{ - const char *fname = "sip_subsManager_send_protocol_error"; - ccsip_sub_not_data_t error_data; - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Protocol Error for scb=%d sub_id=%x\n", fname, - scb_index, scbp->sub_id); - - error_data.reason_code = SM_REASON_CODE_ERROR; - error_data.sub_id = scbp->sub_id; - error_data.request_id = scbp->request_id; - error_data.sub_duration = 0; - error_data.event = scbp->hb.event_type; - error_data.msg_id = scbp->subsTermCallbackMsgID; - error_data.line_id = scbp->hb.dn_line; - - sip_send_error_message(&error_data, scbp->subsNotCallbackTask, - scbp->subsTermCallbackMsgID, scbp->subsTermCallback, - fname); - - if (terminate) { - free_scb(scb_index, fname); - } - -} - -/******************************************************** - * Start and initialize the Subscription Manager - ********************************************************/ -void -initialize_scb (sipSCB_t *scbp) -{ - int nat_enable = 0; - - if (!scbp) { - return; - } - memset(scbp, 0, sizeof(sipSCB_t)); - - scbp->sub_id = CCSIP_SUBS_INVALID_SUB_ID; - scbp->pendingClean = FALSE; - scbp->pendingCount = 0; - scbp->internal = FALSE; - scbp->subsIndCallback = NULL; - scbp->subsResultCallback = NULL; - scbp->notifyIndCallback = NULL; - scbp->notifyResultCallback = NULL; - scbp->subsTermCallback = NULL; - scbp->notIndCallbackMsgID = 0; - scbp->notResCallbackMsgID = 0; - scbp->subsIndCallbackMsgID = 0; - scbp->subsResCallbackMsgID = 0; - scbp->subsTermCallbackMsgID = 0; - scbp->subsIndCallbackTask = CC_SRC_MIN; - scbp->subsNotCallbackTask = CC_SRC_MIN; - - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&(scbp->hb.src_addr)); - } else { - sip_config_get_nat_ipaddr(&(scbp->hb.src_addr)); - } - scbp->hb.cb_type = SUBNOT_CB; - scbp->hb.dn_line = 1; - scbp->hb.local_port = sipTransportGetListenPort(scbp->hb.dn_line, NULL); - sipTransportGetServerIPAddr(&(scbp->hb.dest_sip_addr),1); - scbp->hb.dest_sip_port = sipTransportGetPrimServerPort(1); - - scbp->hb.sipCallID[0] = '\0'; - scbp->smState = SUBS_STATE_IDLE; - scbp->SubURI[0] = '\0'; - scbp->SubscriberURI[0] = '\0'; - scbp->sip_from = strlib_empty(); - scbp->sip_to = strlib_empty(); - scbp->sip_to_tag = strlib_empty(); - scbp->sip_from_tag = strlib_empty(); - scbp->sip_contact = strlib_empty(); - scbp->cached_record_route = strlib_empty(); - scbp->callingNumber = strlib_empty(); - scbp->subscription_state = SUBSCRIPTION_STATE_INVALID; - scbp->norefersub = FALSE; - scbp->request_id = -1; - scbp->hb.authen.cred_type = 0; - scbp->hb.authen.authorization = NULL; - scbp->hb.authen.status_code = 0; - scbp->hb.authen.nc_count = 0; - scbp->hb.authen.new_flag = FALSE; - scbp->hb.event_data_p = NULL; - scbp->pendingRequests = NULL; -} - -int -sip_subsManager_init () -{ - // Initialize SCBS array - const char *fname = "sip_subsManager_init"; - line_t i = 0; - sipSCB_t *scbp; - - if (subsManagerRunning == 1) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription Manager already running!!\n", fname); - return SIP_OK; - } - - for (i = 0; i < MAX_SCBS; i++) { - scbp = &(subsManagerSCBS[i]); - initialize_scb(scbp); - scbp->line = i; - } - - for (i = 0; i < MAX_SCB_HISTORY; i++) { - gSubHistory[i].last_call_id[0] = '\0'; - gSubHistory[i].last_from_tag[0] = '\0'; - gSubHistory[i].eventPackage = CC_SUBSCRIPTIONS_NONE; - } - - // reset status and stats - internalRegistrations = 0; - - incomingSubscribes = 0; - incomingRefers = 0; - incomingNotifies = 0; - incomingUnsolicitedNotifies = 0; - incomingSubscriptions = 0; - - outgoingSubscribes = 0; - outgoingNotifies = 0; - outgoingUnsolicitedNotifies = 0; - outgoingSubscriptions = 0; - - currentScbsAllocated = 0; - maxScbsAllocated = 0; - - // Start periodic timer - (void) sip_platform_subnot_periodic_timer_start(TMR_PERIODIC_SUBNOT_INTERVAL * 1000); - - subsManagerRunning = 1; - - // Print out the size of the SCB - // CCSIP_DEBUG_ERROR("SCB Size=%d\n", sizeof(sipSCB_t)); - // CCSIP_DEBUG_ERROR("CCB Size=%d\n", sizeof(ccsipCCB_t)); - // Kick-off the test routine - // subsmanager_test_start_routine(); - - /* Initialize modules which uses SUB/MANAGER */ - kpml_init(); - configapp_init(); - - return SIP_OK; -} - - -/******************************************************** - * Functions to allocate, locate, free, and update SCBs - ********************************************************/ - -/* - * Function: find_scb_by_callid - * - * Parameters: - * callID - pointer to const. char for the target call ID. - * scb_index - pointer to int where the SCB index of the result - * SCB to be stored. - * - * Description: - * The find_scb_by_callid function searches for an SCB that - * contains the matching callID. It is possible to have multiple - * SCB that matches the given callID. The function only returns - * the first SCB that has the matching callID. - * - * Returns: - * Pointer to SCB and its index if the SCB is found. Otherwise - * it returns NULL and the index is undefined. - */ -sipSCB_t * -find_scb_by_callid (const char *callID, int *scb_index) -{ - int i; - int num_scb = currentScbsAllocated; - sipSCB_t *scbp; - - if (num_scb == 0) { - /* No active subscription */ - return (NULL); - } - scbp = &subsManagerSCBS[0]; - for (i = 0; (i < MAX_SCBS) && num_scb; i++, scbp++) { - if (scbp->smState != SUBS_STATE_IDLE) { - if ((scbp->smState != SUBS_STATE_REGISTERED) && - (strcmp(callID, scbp->hb.sipCallID) == 0)) { - *scb_index = i; - return (scbp); - } - num_scb--; - } - } - - return (NULL); -} - -/* - * Function: find_req_scb - * - * Parameters: - * callID - pointer to const. char for the target call ID. - * method - SIP method to match. - * cseq - CSEQ value to match. - * scb_index - pointer to int where the SCB index of the result - * SCB to be stored. - * - * Description: - * The find_req_scb function searches for an SCB that contains - * the matching callID, last request method and last cseq sent. If - * the match SCB is found, the function returns the pointer to the - * sipSCB_t along with the corresponding index. - * - * Returns: - * Pointer to SCB and its index if the SCB is found. Otherwise - * returns NULL and the index will be set to MAX_SCBS. - */ -static sipSCB_t * -find_req_scb (const char *callID, sipMethod_t method, - uint32_t cseq, int *scb_index) -{ - int idx, num_scb; - sipSCB_t *scbp; - - scbp = &subsManagerSCBS[0]; - num_scb = currentScbsAllocated; - /* - * Search SCB tables for all allocated SCBs. - */ - for (idx = 0; (idx < MAX_SCBS) && num_scb; idx++, scbp++) { - if (scbp->smState != SUBS_STATE_IDLE) { - if ((scbp->smState != SUBS_STATE_REGISTERED) && - (scbp->last_sent_request_cseq_method == method) && - (scbp->last_sent_request_cseq == cseq) && - (strcmp(callID, scbp->hb.sipCallID) == 0)) { - /* Found the matching scb */ - *scb_index = idx; - return (scbp); - } - num_scb--; - } - } - *scb_index = MAX_SCBS; - return (NULL); -} - -/* - * Function: find_scb_by_sub_id - * - * Parameters: - * sub_id - the sub_id_t parameter from which scb index - * to be obtained. - * scb_index - pointer to int for index of the SCB entry to - * be returned if the pointer is provided (not - * NULL). - * - * Description: - * The function finds the SCB for the given sub_id. - * - * Returns: - * 1) pointer to sipSCB_t or NULL if finding fails. - * 2) the index into the SCB array is also returned if the - * scb_index parameter is provided. - */ -static sipSCB_t * -find_scb_by_sub_id (sub_id_t sub_id, int *scb_index) -{ - int idx, ret_idx = MAX_SCBS; - sipSCB_t *scbp = NULL; - - /* - * Use index part of the sub_id to find the SCB - */ - idx = GET_SCB_INDEX_FROM_SUB_ID(sub_id); - if (idx < MAX_SCBS) { - /* - * SCB index is within a valid range, get the SCB by index. - * Match the SCB's sub_id and the one provided. - */ - if (subsManagerSCBS[idx].sub_id == sub_id) { - /* The correct SCB is found */ - scbp = &(subsManagerSCBS[idx]); - ret_idx = idx; - } - } - - if (scb_index != NULL) { - *scb_index = ret_idx; - } - return (scbp); -} - -sipSCB_t * -find_scb_by_registration (cc_subscriptions_t event, int *scb_index) -{ - int i; - - for (i = 0; i < MAX_SCBS; i++) { - if ((subsManagerSCBS[i].hb.event_type == event) && - (subsManagerSCBS[i].smState == SUBS_STATE_REGISTERED)) { - *scb_index = i; - return &(subsManagerSCBS[i]); - } - } - - return (NULL); -} - -sipSCB_t * -find_scb_by_subscription (cc_subscriptions_t event, int *scb_index, - const char *callID) -{ - int i; - - for (i = 0; i < MAX_SCBS; i++) { - if (cpr_strcasecmp(subsManagerSCBS[i].hb.sipCallID, callID) == 0) { - *scb_index = i; - return &(subsManagerSCBS[i]); - } - } - return (NULL); -} - -/* - * Function: new_sub_id - * - * Parameters: - * scb_index - the SCB index. - * - * Description: - * The function allocates a new unique sub_id and return - * it to the caller. - * - * NOTE: the scb_index can not exceed 16 bit unsigned value. - * - * Returns: - * sub_id. - */ -static sub_id_t -new_sub_id (int scb_index) -{ - static sub_id_t unique_id = 0; - sub_id_t sub_id; - - /* - * Form the sub_id is encoded as the following: - * bit 31 - bit 16 contains unique ID - * bit 15 - bit 0 contains scb index. - */ - sub_id = (unique_id << SUB_ID_UNIQUE_ID_POSITION) | - (sub_id_t)(scb_index & SUB_IDSCB_INDEX_MASK); - unique_id++; /* next unique sub id */ - if (sub_id == CCSIP_SUBS_INVALID_SUB_ID) { - /* sub_id becomes the invalid value marker, re-calcualte new id */ - sub_id = (unique_id << SUB_ID_UNIQUE_ID_POSITION) | - (sub_id_t)(scb_index & SUB_IDSCB_INDEX_MASK); - unique_id++; - } - return (sub_id); -} - -sipSCB_t * -allocate_scb (int *scb_index) -{ - int i; - - for (i = 0; i < MAX_SCBS; i++) { - if (subsManagerSCBS[i].smState == SUBS_STATE_IDLE) { - *scb_index = i; - currentScbsAllocated++; - if (currentScbsAllocated > maxScbsAllocated) { - maxScbsAllocated = currentScbsAllocated; - } - /* - * assigned sub_id to the allocated SCB. - */ - subsManagerSCBS[i].sub_id = new_sub_id(i); - CCSIP_DEBUG_TASK("allocate_scb scb_index: %d, currentScbsAllocated: %d, " - "maxScbsAllocated: %d, sub_id: %x\n", scb_index, - currentScbsAllocated, maxScbsAllocated, subsManagerSCBS[i].sub_id); - - /* - * local port may have changed because of failover/fallback. - * So update it with current info so that the Via & Contact headers - * in SUB/NOT are generated correctly. - */ - subsManagerSCBS[i].hb.local_port = - sipTransportGetListenPort(subsManagerSCBS[i].hb.dn_line, NULL); - return &(subsManagerSCBS[i]); - } - } - return (NULL); -} - -boolean -is_previous_sub (const char *pCallID, - char *pFromTag, - cc_subscriptions_t event) -{ - int i; - - if (!pCallID || !pFromTag) { - return FALSE; - } - - for (i = 0; i < MAX_SCB_HISTORY; i++) { - if (strncmp(gSubHistory[i].last_call_id, pCallID, MAX_SIP_CALL_ID) == 0) { - if (strncmp(gSubHistory[i].last_from_tag, pFromTag, MAX_SIP_TAG_LENGTH) == 0) { - if (gSubHistory[i].eventPackage == event) { - return TRUE; - } - } - } - } - - return FALSE; -} - -void -clean_scb (sipSCB_t *scbp) -{ - sub_not_trxn_t *trxn_p; - - if (scbp) { - strlib_free(scbp->sip_from); - strlib_free(scbp->sip_to); - strlib_free(scbp->sip_to_tag); - strlib_free(scbp->sip_from_tag); - strlib_free(scbp->callingNumber); - strlib_free(scbp->sip_contact); - strlib_free(scbp->cached_record_route); - if (scbp->contact_info) - sippmh_free_contact(scbp->contact_info); - if (scbp->record_route_info) - sippmh_free_record_route(scbp->record_route_info); - if (scbp->hb.event_data_p) - free_event_data(scbp->hb.event_data_p); - if (scbp->pendingRequests) { - free_pending_requests(scbp->pendingRequests); - } - - scbp->hb.authen.cnonce[0] = '\0'; - if (scbp->hb.authen.authorization != NULL) { - cpr_free(scbp->hb.authen.authorization); - scbp->hb.authen.authorization = NULL; - } - if (scbp->hb.authen.sip_authen != NULL) { - sippmh_free_authen(scbp->hb.authen.sip_authen); - scbp->hb.authen.sip_authen = NULL; - } - - /* free all transactions */ - if (scbp->incoming_trxns) { - while ((trxn_p = (sub_not_trxn_t *) - sll_next(scbp->incoming_trxns, NULL)) != NULL) { - (void) sll_remove(scbp->incoming_trxns, (void *)trxn_p); - cpr_free(trxn_p->via); - cpr_free(trxn_p); - } - sll_destroy(scbp->incoming_trxns); - scbp->incoming_trxns = NULL; - } - - } -} -void -store_scb_history (sipSCB_t *scbp) -{ - // Copy SCB parameters in the next available history array - static int next_history = 0; - - next_history++; - if (next_history == MAX_SCB_HISTORY) { - next_history = 0; - } - sstrncpy(gSubHistory[next_history].last_call_id, scbp->hb.sipCallID, MAX_SIP_CALL_ID); - sstrncpy(gSubHistory[next_history].last_from_tag, scbp->sip_from_tag, MAX_SIP_TAG_LENGTH); - gSubHistory[next_history].eventPackage = scbp->hb.event_type; -} - -/** - * - * frees the SCB. It will cleanup the scb (ie, free the memory allocated for any sub fields). - * It will also mark the SCB as free (smState = SUBS_STATE_IDLE). - * Please note this function may be invoked can be invoked even when smState == SUBS_STATE_IDLE. - * An example case is when parse_body() fails. - * - * @param[in] scb_index - indext of the SCB into SCB array. - * @param[in] fname - name of the function calling this function. - * - * @return none - * - * @pre (scb_index >= 0) and (scb_index < MAX_SCBS) - * @post (subsManagerSCBS[scb_index].smState equals FALSE) - */ -void -free_scb (int scb_index, const char *fname) -{ - sipSCB_t *scbp = NULL; - - if (scb_index >= MAX_SCBS || scb_index < 0) { - CCSIP_DEBUG_ERROR("%s Trying to free an invalid scb_index. Return.\n", fname); - return; - } - scbp = &(subsManagerSCBS[scb_index]); - - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Freeing SCB: scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, "free_scb"), scb_index, scbp->sub_id); - - if (scbp->smState != SUBS_STATE_IDLE) { - currentScbsAllocated--; - /* - * This condition should never happen. If occurs, it is a strong indication - * something has gone wrong in our code logic and should be investigated. - */ - if (currentScbsAllocated < 0) { - CCSIP_DEBUG_ERROR("%s: Error somewhere in scb accounting which results" - "in negative currentScbsAllocated. Set it to 0.\n", fname); - currentScbsAllocated = 0; - } - } - // If this was an incoming subscription, store values in history first - if ((scbp->internal == FALSE) && (scbp->smState != SUBS_STATE_REGISTERED)) { - store_scb_history(scbp); - } - - clean_scb(scbp); - - // Stop associated message retry timer - if (sipPlatformUISMSubNotTimers[scb_index].outstanding) { - sip_platform_msg_timer_subnot_stop(&sipPlatformUISMSubNotTimers[scb_index]); - } - - // Re-initialize - initialize_scb(scbp); - scbp->line = (line_t) scb_index; -} - -/** - * This function will free up the TCB resources and removes it from the TCB list. - * - * @param[in] tcbp - pointer to a TCB. - * - * @return none - * - * @pre (tcbp != NULL) - */ -static void free_tcb (sipTCB_t *tcbp) -{ - if (tcbp->hb.authen.authorization != NULL) { - cpr_free(tcbp->hb.authen.authorization); - } - if (tcbp->hb.authen.sip_authen != NULL) { - sippmh_free_authen(tcbp->hb.authen.sip_authen); - } - - (void)cprDestroyTimer(tcbp->timer); - free_event_data(tcbp->hb.event_data_p); - (void)sll_remove(s_TCB_list, (void *)tcbp); - cpr_free(tcbp); -} - -/** - * This function will find matching TCB by the SIP Call-ID in the TCB list. - * - * @param[in] callID_p - SIP Call-ID - * - * @return NULL if there is no matching TCB - * Otherwise, pointer to the found TCB is returned. - * - * @pre (callID_p != NULL) - */ -sipTCB_t *find_tcb_by_sip_callid (const char *callID_p) -{ - sipTCB_t *tcb_p; - - tcb_p = (sipTCB_t *)sll_next(s_TCB_list, NULL); - while (tcb_p != NULL) { - if (strncmp(callID_p, tcb_p->hb.sipCallID, (sizeof(tcb_p->hb.sipCallID) -1)) == 0) { - return tcb_p; - } - tcb_p = (sipTCB_t *)sll_next(s_TCB_list, tcb_p); - } - return NULL; -} - -/** - * This function will free up TCBs when - * 1. restarting or - * 2. failing over/ falling back - * - * @param[in] none - * - * @return none - */ -static void tcb_reset (void) -{ - sipTCB_t *tcb_p; - - tcb_p = (sipTCB_t *)sll_next(s_TCB_list, NULL); - while (tcb_p != NULL) { - free_tcb(tcb_p); - tcb_p = (sipTCB_t *)sll_next(s_TCB_list, NULL); - } -} - -/* - * Function is called to remove ccb pointer from scb - * When the dialog is cleared then ccb associated with - * that dialog is cleared as well. Remove that from - * scb parameters as well - */ -void -submanager_update_ccb_addr (ccsipCCB_t *ccb) -{ - sipSCB_t *scbp = NULL; - int scb_index = 0; - int num_scb; - - if ((ccb == NULL) || (currentScbsAllocated == 0)) { - /* The CCB is NULL or no active SCBs */ - return; - } - - /* Once the dialog is cleared i.e ccb is removed, the subnot - * should continue to use from its last sequence number. So - * re-assign last sequence value to scbp. - * - * There are possibility of multiple subscriptions associate - * with a call dialog. Search all of the SCB for the given CCB. - */ - scbp = &subsManagerSCBS[0]; - num_scb = currentScbsAllocated; - for (scb_index = 0; (scb_index < MAX_SCBS) && num_scb; scb_index++, scbp++) { - if (scbp->smState != SUBS_STATE_IDLE) { - if ((scbp->smState != SUBS_STATE_REGISTERED) && - (scbp->ccbp == ccb)) { - scbp->last_sent_request_cseq = ccb->last_used_cseq; - scbp->ccbp = NULL; - } - num_scb--; - } - } - -} - - -/* - * Takes care of all the parsing requirements - */ -static int -parse_body (cc_subscriptions_t event_type, char *msgBody, int msgLength, - ccsip_event_data_t **eventDatapp, - const char *fname) -{ - const char *fname1 = "parse_body"; - ccsip_event_data_type_e type = EVENT_DATA_INVALID; - - if (!msgBody) { - return SIP_ERROR; - } - - switch (event_type) { - case CC_SUBSCRIPTIONS_KPML: - type = EVENT_DATA_KPML_REQUEST; - break; - case CC_SUBSCRIPTIONS_CONFIGAPP: - type = EVENT_DATA_CONFIGAPP_REQUEST; - break; - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%s: unknown event type %d\n", fname1, fname, type); - return SIP_ERROR; - } - - return SIP_OK; -} - -boolean -add_content (ccsip_event_data_t *eventData, sipMessage_t *request, const char *fname) -{ - return FALSE; - -/* This function requires XML handling */ -#if 0 - const char *fname1 = "add_content"; - uint32_t len; - char *eventBody = NULL; - - while (eventData) { - /* Encode eventData into eventBody here */ - len = strlen(eventBody); - - switch (eventData->type) { - case EVENT_DATA_RAW: - // Assume body is of type CMXML for now - (void) sippmh_add_message_body(request, eventBody, len, - SIP_CONTENT_TYPE_CMXML, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, TRUE, NULL); - break; - case EVENT_DATA_KPML_REQUEST: - (void) sippmh_add_message_body(request, eventBody, len, - SIP_CONTENT_TYPE_KPML_REQUEST, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, TRUE, NULL); - break; - case EVENT_DATA_KPML_RESPONSE: - (void) sippmh_add_message_body(request, eventBody, len, - SIP_CONTENT_TYPE_KPML_RESPONSE, - SIP_CONTENT_DISPOSITION_SESSION_VALUE, TRUE, NULL); - break; - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%s: Data type not supported\n", fname1, fname); - cpr_free(eventBody); - break; - } - - eventData = eventData->next; - } - return (TRUE); -#endif -} - -// Functions to handle requests from internal applications - -/************************************************************ - * Applications Register to Receive an incoming subscribe(s) - ************************************************************/ -int -subsmanager_handle_ev_app_subscribe_register (cprBuffer_t buf) -{ - const char *fname = "subsmanager_handle_ev_app_register"; - sipspi_subscribe_reg_t *reg_datap; - sipSCB_t *scbp = NULL; - int scb_index; - sipspi_msg_t *pSIPSPIMsg = NULL; - - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a new subscription registration\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - if (!subsManagerRunning) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription Manager Not Initialized!\n", fname); - return SIP_ERROR; - } - - reg_datap = &(pSIPSPIMsg->msg.subs_reg); - if (reg_datap->subsIndCallback == NULL && - reg_datap->subsIndCallbackMsgID == 0) { - return SIP_ERROR; - } - - scbp = find_scb_by_registration(reg_datap->eventPackage, &scb_index); - if (scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Duplicate registration!\n", fname); - return SIP_ERROR; - } else { - scbp = allocate_scb(&scb_index); - if (!scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription control block allocation failed\n", fname); - return SIP_ERROR; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Allocated SCB for App Registration," - " event=%d, scb=%d, sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), - reg_datap->eventPackage, - GET_SCB_INDEX_FROM_SUB_ID(scbp->sub_id), - scbp->sub_id); - } - - scbp->hb.dn_line = 1; - scbp->hb.event_type = reg_datap->eventPackage; - if (reg_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG > -1 && - reg_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG < 5) { - sstrncpy(scbp->event_name, eventNames[reg_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG], MAX_EVENT_NAME_LEN); - } - - // Get callback information (either event or function) - scbp->subsIndCallback = reg_datap->subsIndCallback; - scbp->subsIndCallbackTask = reg_datap->subsIndCallbackTask; - scbp->subsNotCallbackTask = reg_datap->subsIndCallbackTask; - scbp->subsIndCallbackMsgID = reg_datap->subsIndCallbackMsgID; - scbp->subsTermCallback = reg_datap->subsTermCallback; - scbp->subsTermCallbackMsgID = reg_datap->subsTermCallbackMsgID; - scbp->subsTermCallback = reg_datap->subsTermCallback; - scbp->subsTermCallbackMsgID = reg_datap->subsTermCallbackMsgID; - - scbp->smState = SUBS_STATE_REGISTERED; - internalRegistrations++; - return (0); -} - -/******************************************************** - * Application Generated Subscribe Request - ********************************************************/ -int -subsmanager_handle_ev_app_subscribe (cprBuffer_t buf) -{ - const char *fname = "subsmanager_handle_ev_app_subscribe"; - sipspi_subscribe_t *sub_datap; - sipSCB_t *scbp = NULL; - int scb_index; - ccsip_sub_not_data_t subs_result_data; - boolean reSubscribe = FALSE; - ccsipCCB_t *ccbp = NULL; - sipspi_msg_t *pSIPSPIMsg = NULL; - int subscription_expires; - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a new App subscription request\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - if (!subsManagerRunning) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription Manager Not Initialized!\n", fname); - return SIP_ERROR; - } - - // Get Data - sub_datap = &(pSIPSPIMsg->msg.subscribe); - - /* Steps: - * * Extract subscription details from the event information - * * Check data to ensure we support the event package asked for - * * Allocate an SCB to hold subscription details - * * Create body of the SUBSCRIBE message, if needed - * * Prep the message by adding fields to the SCB - * * Call sipSPISendSubscribe to send the message out - */ - - // Get ready for any failure - subs_result_data.u.subs_result_data.expires = 0; - subs_result_data.u.subs_result_data.status_code = SUBSCRIBE_REQUEST_FAILED; - subs_result_data.sub_id = CCSIP_SUBS_INVALID_SUB_ID; - subs_result_data.request_id = sub_datap->request_id; - subs_result_data.msg_id = sub_datap->subsResCallbackMsgID; - - /* - * Finding SCB by sub_id or request id and eventPakage if the - * sub_id is not known. - */ - if (sub_datap->sub_id == CCSIP_SUBS_INVALID_SUB_ID) { - /* - * find scb based on request_id and event package. - * This scenario is possible if application decides to terminate a - * subscription before subsmanager provides app with sub_id. - */ - for (scb_index = 0; scb_index < MAX_SCBS; scb_index++) { - if ((subsManagerSCBS[scb_index].request_id == sub_datap->request_id) && - (subsManagerSCBS[scb_index].hb.event_type == sub_datap->eventPackage) && - (!subsManagerSCBS[scb_index].pendingClean)) { - scbp = &(subsManagerSCBS[scb_index]); - break; - } - } - } else { - /* Find SCB from sub_id */ - scbp = find_scb_by_sub_id(sub_datap->sub_id, &scb_index); - } - if (scbp == NULL) { - // Process new subscription - if ((sub_datap->eventPackage != CC_SUBSCRIPTIONS_DIALOG) && - (sub_datap->eventPackage != CC_SUBSCRIPTIONS_KPML) && - (sub_datap->eventPackage != CC_SUBSCRIPTIONS_PRESENCE)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Event %d not supported!\n", - fname, sub_datap->eventPackage); - subs_result_data.u.subs_result_data.status_code = SUBSCRIBE_FAILED_BADEVENT; - sip_send_error_message(&subs_result_data, sub_datap->subsNotCallbackTask, - sub_datap->subsResCallbackMsgID, sub_datap->subsResultCallback, - fname); - return SIP_ERROR; - } - - // Reject this if there is no way to get back to the subscriber - if (!((sub_datap->subsResultCallback) || - ((sub_datap->subsNotCallbackTask != CC_SRC_MIN) && - sub_datap->subsResCallbackMsgID))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No callback info provided by the App\n", fname); - subs_result_data.u.subs_result_data.status_code = - SUBSCRIBE_FAILED_BADINFO; - sip_send_error_message(&subs_result_data, - sub_datap->subsNotCallbackTask, - sub_datap->subsResCallbackMsgID, - sub_datap->subsResultCallback, - fname); - return SIP_ERROR; - } - - // If this is a presence request - check if sufficient SCBs will still - // be available for other "more important" functions - if (sub_datap->eventPackage == CC_SUBSCRIPTIONS_PRESENCE) { - if (currentScbsAllocated >= LIMIT_SCBS_USAGE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"reached Presence SCBs threshold\n", fname); - subs_result_data.u.subs_result_data.status_code = - SUBSCRIBE_FAILED_NORESOURCE; - sip_send_error_message(&subs_result_data, - sub_datap->subsNotCallbackTask, - sub_datap->subsResCallbackMsgID, - sub_datap->subsResultCallback, fname); - return SIP_ERROR; - } - } - - // Allocate SCB and copy needed parameters - scbp = allocate_scb(&scb_index); - if (!scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ran out of SCBs\n", fname); - subs_result_data.u.subs_result_data.status_code = - SUBSCRIBE_FAILED_NORESOURCE; - sip_send_error_message(&subs_result_data, - sub_datap->subsNotCallbackTask, - sub_datap->subsResCallbackMsgID, - sub_datap->subsResultCallback, - fname); - show_scbs_inuse(); - return SIP_ERROR; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Allocated SCB for Sending Subscribe," - " event=%d scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), sub_datap->eventPackage, - scb_index, scbp->sub_id); - if (sub_datap->dn_line == 0 || sub_datap->dn_line > MAX_REG_LINES) { - // By not giving a DN line, the app is asking us to use - // device addressing and not line addressing - scbp->hb.dn_line = 1; - scbp->useDeviceAddressing = TRUE; - } else { - scbp->hb.dn_line = sub_datap->dn_line; - } - - scbp->gsm_id = sub_datap->call_id; - if (scbp->gsm_id != 0) { - ccbp = sip_sm_get_ccb_by_gsm_id(scbp->gsm_id); - } else { - ccbp = NULL; - } - scbp->ccbp = ccbp; - - scbp->hb.event_type = sub_datap->eventPackage; - scbp->hb.accept_type = sub_datap->acceptPackage; - if (sub_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG > -1 && - sub_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG < 5) { - sstrncpy(scbp->event_name, eventNames[sub_datap->eventPackage - CC_SUBSCRIPTIONS_DIALOG], MAX_EVENT_NAME_LEN); - } - sstrncpy(scbp->SubURIOriginal, sub_datap->subscribe_uri, - sizeof(scbp->SubURIOriginal)); - sstrncpy(scbp->SubscriberURI, sub_datap->subscriber_uri, - sizeof(scbp->SubscriberURI)); - scbp->subsResultCallback = sub_datap->subsResultCallback; - scbp->notifyIndCallback = sub_datap->notifyIndCallback; - scbp->subsTermCallback = sub_datap->subsTermCallback; - scbp->subsNotCallbackTask = sub_datap->subsNotCallbackTask; - scbp->subsResCallbackMsgID = sub_datap->subsResCallbackMsgID; - scbp->notIndCallbackMsgID = sub_datap->subsNotIndCallbackMsgID; - scbp->subsTermCallbackMsgID = sub_datap->subsTermCallbackMsgID; - - scbp->hb.dest_sip_addr = sub_datap->dest_sip_addr; - scbp->hb.dest_sip_port = sub_datap->dest_sip_port; - - scbp->auto_resubscribe = sub_datap->auto_resubscribe; - scbp->norefersub = sub_datap->norefersub; - scbp->request_id = sub_datap->request_id; - - // Set default value of subscribe duration, if not specified - if (sub_datap->duration < 0) { - config_get_value(CFGID_TIMER_SUBSCRIBE_EXPIRES, &subscription_expires, - sizeof(subscription_expires)); - sub_datap->duration = subscription_expires; - } - scbp->internal = TRUE; - } else { - /* SCB exists, it is a re-subscribe */ - reSubscribe = TRUE; - } - - scbp->hb.expires = sub_datap->duration; - scbp->hb.orig_expiration = sub_datap->duration; - - if (scbp->hb.event_data_p) { - free_event_data(scbp->hb.event_data_p); - scbp->hb.event_data_p = NULL; - } - - // Copy any body received - it will be framed later - if (sub_datap->eventData) { - scbp->hb.event_data_p = sub_datap->eventData; - sub_datap->eventData = NULL; - } - - //re-initialize cred_type - scbp->hb.authen.cred_type = 0; - - if (sipSPISendSubscribe(scbp, reSubscribe, FALSE /* auth */)) { - if (scbp->smState == SUBS_STATE_RCVD_NOTIFY) { - scbp->smState = SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY; - } else { - scbp->smState = SUBS_STATE_SENT_SUBSCRIBE; - } - outgoingSubscribes++; - if (!reSubscribe) { - outgoingSubscriptions++; - } - return (0); - } - // If unable to send subscribe, return error immediately - // and return scb to the pool if not resubscribing - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send SUBSCRIBE message\n", fname); - sip_send_error_message(&subs_result_data, scbp->subsNotCallbackTask, - scbp->subsResCallbackMsgID, - scbp->subsResultCallback, fname); - - if (!reSubscribe) { - free_scb(scb_index, fname); - } - return SIP_ERROR; -} - -/*********************************************************** - * Handle Application Response to a Remote Subscribe Request - ***********************************************************/ -int -subsmanager_handle_ev_app_subscribe_response (cprBuffer_t buf) -{ - const char *fname = "subsmanager_handle_ev_app_subscribe_response"; - sipspi_subscribe_resp_t *subres_datap; - sipSCB_t *scbp; - sipspi_msg_t *pSIPSPIMsg = NULL; - - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - subres_datap = &(pSIPSPIMsg->msg.subscribe_resp); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing an app subscribe response for" - " sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), subres_datap->sub_id); - /* - * Find SCB from the sub_id. - */ - scbp = find_scb_by_sub_id(subres_datap->sub_id, NULL); - if (scbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"no SCB for sub_id=%x found\n", - fname, subres_datap->sub_id); - return SIP_ERROR; - } - - scbp->hb.expires = subres_datap->duration; - if (sipSPISendSubscribeNotifyResponse - (scbp, subres_datap->response_code, scbp->last_recv_request_cseq)) { - if (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY) { - scbp->smState = SUBS_STATE_SENT_NOTIFY; - } else { - scbp->smState = SUBS_STATE_ACTIVE; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send SUBSCRIBE Response\n", fname); - return SIP_ERROR; - } - return (0); -} - -/******************************************************** - * Handle Application Generated NOTIFY - ********************************************************/ -int -subsmanager_handle_ev_app_notify (cprBuffer_t buf) -{ - const char *fname = "subsmanager_handle_ev_app_notify"; - sipspi_notify_t *not_datap; - sipSCB_t *scbp; - ccsip_sub_not_data_t notify_result_data; - sipspi_msg_t *pSIPSPIMsg = NULL; - sipspi_msg_t *temp_SIPSPIMsg = NULL; - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - not_datap = &(pSIPSPIMsg->msg.notify); - - // Fill in the return data structure in case we encounter any problems - notify_result_data.u.notify_result_data.status_code = NOTIFY_REQUEST_FAILED; - notify_result_data.msg_id = not_datap->subsNotResCallbackMsgID; - notify_result_data.sub_id = not_datap->sub_id; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing an app notify request for" - " sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), - not_datap->sub_id); - /* - * Find SCB from the sub_id. - */ - scbp = find_scb_by_sub_id(not_datap->sub_id, NULL); - if (scbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"no SCB for sub_id=%x found\n", fname, - not_datap->sub_id); - free_event_data(not_datap->eventData); - sip_send_error_message(¬ify_result_data, - not_datap->subsNotCallbackTask, - not_datap->subsNotResCallbackMsgID, - not_datap->notifyResultCallback, - fname); - return SIP_ERROR; - } - - notify_result_data.line_id = scbp->hb.dn_line; - - // Check state to see if we need to queue this request - if ((scbp->smState == SUBS_STATE_SENT_NOTIFY) || - (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY)) { - // This means we have sent a NOTIFY but have not received a response - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Queueing request for later transmission\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - temp_SIPSPIMsg = (sipspi_msg_t *) cpr_malloc(sizeof(sipspi_msg_t)); - if (temp_SIPSPIMsg) { - /* Copy the content so that we do not touch the pSIPSPImsg */ - (*temp_SIPSPIMsg) = (*pSIPSPIMsg); - - /* Append the request */ - if (append_pending_requests(scbp, temp_SIPSPIMsg, - SIPSPI_EV_CC_NOTIFY)) { - return SIP_DEFER; - } - cpr_free(temp_SIPSPIMsg); - } - /* We either do not have buffer or failed to append msg. */ - free_event_data(not_datap->eventData); - sip_send_error_message(¬ify_result_data, - not_datap->subsNotCallbackTask, - not_datap->subsNotResCallbackMsgID, - not_datap->notifyResultCallback, - fname); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to queue request\n", fname); - return SIP_ERROR; - } - - // Check state to see if we are in a position to send this NOTIFY - if (scbp->smState == SUBS_STATE_IDLE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad SCB State: %d\n", fname, scbp->smState); - free_event_data(not_datap->eventData); - sip_send_error_message(¬ify_result_data, - not_datap->subsNotCallbackTask, - not_datap->subsNotResCallbackMsgID, - not_datap->notifyResultCallback, fname); - return SIP_ERROR; - } - - // Copy the callback function, if not already copied - if (not_datap->notifyResultCallback == NULL && - not_datap->subsNotResCallbackMsgID == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No callback event or function\n", fname); - // Can't really send back any error ... - free_event_data(not_datap->eventData); - return SIP_ERROR; - } else { - scbp->notifyResultCallback = not_datap->notifyResultCallback; - scbp->notResCallbackMsgID = not_datap->subsNotResCallbackMsgID; - } - - if (scbp->hb.event_data_p) { - free_event_data(scbp->hb.event_data_p); - scbp->hb.event_data_p = NULL; - } - - // Copy any body received - it will be framed later - if (not_datap->eventData) { - scbp->hb.event_data_p = not_datap->eventData; - not_datap->eventData = NULL; - } - - // Find out if app wants to terminate this subscription - if (not_datap->subState == SUBSCRIPTION_TERMINATE) { - scbp->hb.expires = 0; - } - - //re-initialize cred_type - scbp->hb.authen.cred_type = 0; - - if (sipSPISendSubNotify((ccsip_common_cb_t *)scbp, FALSE) != TRUE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send Notify Message\n", fname); - sip_send_error_message(¬ify_result_data, scbp->subsNotCallbackTask, - scbp->notResCallbackMsgID, - scbp->notifyResultCallback, fname); - return SIP_ERROR; - } - - if (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE) { - scbp->smState = SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY; - } else { - scbp->smState = SUBS_STATE_SENT_NOTIFY; - } - outgoingNotifies++; - - return (0); -} - -/** - * This function will handle Application Generated unsolicited NOTIFY - * - * @param[in] buf - pointer to sipspi_msg_t - * @param[in] line - line id. - * - * @return none - */ -void subsmanager_handle_ev_app_unsolicited_notify (cprBuffer_t buf, line_t line) -{ - const char *fname = "subsmanager_handle_ev_app_unsolicited_notify"; - sipspi_msg_t *pSIPSPIMsg = NULL; - sipspi_notify_t *not_datap; - sipTCB_t *tcbp; - int nat_enable = 0; - static uint32_t trxn_id = 1; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing an outgoing unsolicited notify request\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - pSIPSPIMsg = (sipspi_msg_t *) buf; - not_datap = &(pSIPSPIMsg->msg.notify); - - /* - * If TCB list is not created yet, create the list. - */ - if (s_TCB_list == NULL) { - s_TCB_list = sll_create(NULL); - if (s_TCB_list == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc of TCBList failed\n", fname); - free_event_data(not_datap->eventData); - return; - } - } - - /* - * create a TCB (transaction control block) - */ - tcbp = cpr_malloc(sizeof(sipTCB_t)); - if (tcbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc of TCB failed\n", fname); - free_event_data(not_datap->eventData); - return; - } - memset(tcbp, 0, sizeof(sipTCB_t)); - tcbp->trxn_id = trxn_id; - trxn_id++; - if (trxn_id == 0) { - trxn_id = 1; - } - tcbp->timer = cprCreateTimer("Unsolicited transaction timer", - SIP_UNSOLICITED_TRANSACTION_TIMER, - TIMER_EXPIRATION, - sip_msgq); - if (tcbp->timer == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to create a timer\n", fname); - free_event_data(not_datap->eventData); - cpr_free(tcbp); - return; - } - tcbp->hb.cb_type = UNSOLICIT_NOTIFY_CB; - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 0) { - sip_config_get_net_device_ipaddr(&(tcbp->hb.src_addr)); - } else { - sip_config_get_nat_ipaddr(&(tcbp->hb.src_addr)); - } - tcbp->hb.dn_line = line; - tcbp->hb.local_port = sipTransportGetListenPort(tcbp->hb.dn_line, NULL); - - tcbp->hb.event_type = not_datap->eventPackage; - - // Copy any body received - it will be framed later - if (not_datap->eventData) { - tcbp->hb.event_data_p = not_datap->eventData; - not_datap->eventData = NULL; - } - (void) sll_append(s_TCB_list, tcbp); - - if (sipSPISendSubNotify((ccsip_common_cb_t *)tcbp, FALSE) != TRUE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send Notify Message\n", fname); - free_tcb(tcbp); - return; - } - - outgoingUnsolicitedNotifies++; - - return; -} - -/** - * This function will handle network generated response to unsolicited NOTIFY - * - * @param[in] pSipMessage - pointer to sipMessage_t - * @param[in] tcbp - pointer to associated trnsaction control block. - * - * @returns SIP_OK/SIP_ERROR - */ -int subsmanager_handle_ev_sip_unsolicited_notify_response (sipMessage_t *pSipMessage, sipTCB_t *tcbp) -{ - int response_code = 0; - const char *fname = "subsmanager_handle_ev_sip_unsolicited_notify_response"; - - // Parse the return code - (void) sipGetResponseCode(pSipMessage, &response_code); - - /* - * if the response is < 200, do nothing. - */ - if (response_code < 200) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), response_code); - return SIP_OK; - } - - if ((response_code == SIP_CLI_ERR_UNAUTH) || - (response_code == SIP_CLI_ERR_PROXY_REQD)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authentication Required\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (ccsip_common_util_generate_auth(pSipMessage, &tcbp->hb, SIP_METHOD_NOTIFY, - response_code, tcbp->full_ruri) == TRUE) { - if (sipSPISendSubNotify((ccsip_common_cb_t *)tcbp, TRUE) == TRUE) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with Auth header\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - return SIP_OK; - } - } - free_tcb (tcbp); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to auth challenge\n", fname); - return SIP_ERROR; - } - - free_tcb(tcbp); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), response_code); - return SIP_OK; -} - -/** - * This function will handle outgoing unsolicited NOTIFY transaction timeout. - * - * @param[in] data - pointer to an id that identifies the TCB. - * - * @returns none. - */ -void subsmanager_unsolicited_notify_timeout (void *data) -{ - const char *fname = "subsmanager_unsolicited_notify_timeout"; - uint32_t trxn_id = (long)data; - sipTCB_t *temp_tcbp = NULL; - - /* - * make sure that the TCB still exists. - */ - temp_tcbp = (sipTCB_t *)sll_next(s_TCB_list, NULL); - while (temp_tcbp != NULL) { - if (temp_tcbp->trxn_id == trxn_id) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"unsolicited notify transaction timedout\n", fname); - free_tcb(temp_tcbp); - return; - } - temp_tcbp = (sipTCB_t *)sll_next(s_TCB_list, temp_tcbp); - } -} - -/********************************************************** - * Handle Application Response to a received Notify request - **********************************************************/ -int -subsmanager_handle_ev_app_notify_response (cprBuffer_t buf) -{ - sipspi_notify_resp_t *notify_resp; - sipSCB_t *scbp = NULL; - sipspi_msg_t *pSIPSPIMsg = NULL; - uint32_t cseq; - const char *fname = "subsmanager_handle_ev_app_notify_response"; - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - notify_resp = &(pSIPSPIMsg->msg.notify_resp); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing an app notify response for" - " sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), - notify_resp->sub_id); - - // Retrieve response parameters - /* - * Find SCB from the sub_id. - */ - scbp = find_scb_by_sub_id(notify_resp->sub_id, NULL); - if (scbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"no SCB for sub_id=%x found\n", - fname, notify_resp->sub_id); - return SIP_ERROR; - } - - if (notify_resp->cseq == 0) { - cseq = scbp->last_recv_request_cseq; - } else { - cseq = notify_resp->cseq; - } - // Call function to make and send the response - if (sipSPISendSubscribeNotifyResponse(scbp, - (uint16_t)(notify_resp->response_code), cseq)) { - /* - * if the outstanding NOTIFY transaction is only one, - * then update the scbp->smState. - */ - if (scbp->outstandingIncomingNotifyTrxns == 1) { - if (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY) { - scbp->smState = SUBS_STATE_SENT_SUBSCRIBE; - } else { - scbp->smState = SUBS_STATE_ACTIVE; - } - } - scbp->outstandingIncomingNotifyTrxns -= 1; - return (0); - } - return SIP_ERROR; -} - -/******************************************************** - * Handle Application Request to Terminate Subscription - ********************************************************/ -int -subsmanager_handle_ev_app_subscription_terminated (cprBuffer_t buf) -{ - /* - * This function is used by the application to clean up a subscription - * whether internally or externally initiated. The application should have - * taken care of all the protocol related messaging before calling this - * function. - */ - const char *fname = "subsmanager_handle_ev_app_subscription_terminated"; - sipspi_subscribe_term_t *subs_term; - int scb_index; - sipSCB_t *scbp; - sipspi_msg_t *pSIPSPIMsg = NULL; - - - pSIPSPIMsg = (sipspi_msg_t *) buf; - - subs_term = &(pSIPSPIMsg->msg.subs_term); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing terminate request for sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), subs_term->sub_id); - /* - * Find SCB from the sub_id and allow matching with request ID and - * eventPackage if sub id is not known. - */ - if (subs_term->sub_id == CCSIP_SUBS_INVALID_SUB_ID) { - /* - * find scb based on request_id and event package. - * This scenario is possible if application decides to terminate a - * subscription before subsmanager provides app with sub_id. - */ - for (scb_index = 0; scb_index < MAX_SCBS; scb_index++) { - if ((subsManagerSCBS[scb_index].request_id == subs_term->request_id) && - (subsManagerSCBS[scb_index].hb.event_type == subs_term->eventPackage) && - (!subsManagerSCBS[scb_index].pendingClean)) { - break; - } - } - if (scb_index >= MAX_SCBS) { - scbp = NULL; - } else { - scbp = &(subsManagerSCBS[scb_index]); - } - } else { - /* Find SCB by sub_id */ - scbp = find_scb_by_sub_id(subs_term->sub_id, &scb_index); - } - if (scbp == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"no SCB for sub_id=%x or request id %d" - " and eventPackage %d found\n", fname, - subs_term->sub_id, subs_term->request_id, - subs_term->eventPackage); - return SIP_ERROR; - } - if (scbp->smState == SUBS_STATE_IDLE || scbp->pendingClean) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SCB: scb=%d sub_id=%x has already been" - " cleaned up\n", fname, - scb_index, subs_term->sub_id); - return 0; - } - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Cleaning out subscription for SCB: scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - - if (scbp->internal) { - outgoingSubscriptions--; - } else { - incomingSubscriptions--; - } - - // There could still be messages left to receive and flush, so if not - // immediate, we mark this SCB as pending deletion and we will clean it up - // later - if (subs_term->immediate) { - free_scb(scb_index, fname); - } else { - scbp->pendingClean = TRUE; - if (scbp->pendingRequests) - scbp->pendingCount = 2 * TMR_PERIODIC_SUBNOT_INTERVAL; - else - scbp->pendingCount = 1 * TMR_PERIODIC_SUBNOT_INTERVAL; - } - - return (0); -} - - -/******************************************************** - * Handle network response to a Sub/Not request - ********************************************************/ -int -subsmanager_handle_ev_sip_response (sipMessage_t *pSipMessage) -{ - const char *fname = "subsmanager_handle_ev_sip_response"; - sipSCB_t *scbp; - int scb_index; - ccsip_sub_not_data_t sub_not_result_data; - - // currently not used SysHdr *pSm = NULL; - int response_code = 0; - const char *pCallID = NULL; - const char *rsp_method = NULL; - sipMethod_t method = sipMethodInvalid; - sipStatusCodeClass_t code_class = codeClassInvalid; - const char *expires = NULL; - long expiry_time; - const char *to = NULL, *from = NULL; - const char *record_route = NULL; - sipLocation_t *to_loc = NULL; - sipCseq_t *resp_cseq_structure = NULL; - uint32_t cseq; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a response\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - if (sipGetResponseMethod(pSipMessage, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - return SIP_ERROR; - } - if (method == sipMethodSubscribe) { - rsp_method = SIP_METHOD_SUBSCRIBE; - } else if (method == sipMethodRefer) { - rsp_method = SIP_METHOD_REFER; - } else { - rsp_method = SIP_METHOD_NOTIFY; - } - - pCallID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!pCallID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.\n", fname); - return SIP_ERROR; - } - - if (!getCSeqInfo(pSipMessage, &resp_cseq_structure)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP CSEQ.\n", fname); - return SIP_ERROR; - } - cseq = resp_cseq_structure->number; - cpr_free(resp_cseq_structure); - - // Locate request scbp from that match the response - scbp = find_req_scb(pCallID, method, cseq, &scb_index); - if (!scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No matching request found\n", fname); - return SIP_ERROR; - } - // Cancel any outstanding retry timer - if (scbp->hb.retx_flag == TRUE) { - sip_platform_msg_timer_subnot_stop(&sipPlatformUISMSubNotTimers[scb_index]); - scbp->hb.retx_flag = FALSE; - } - // Parse the return code - (void) sipGetResponseCode(pSipMessage, &response_code); - code_class = sippmh_get_code_class((uint16_t) response_code); - - /* - * If it is a response (18x/2xx) to a dialog initiating SUBSCRIBE, - * parse the Record-Route header and set up Route set for this dialog. - * If the sip_to_tag is not yet populated and if there is no associated - * CCB, then this can be considered as a response to dialog - * initating SUBSCRIBE. - */ - if ((strcmp(rsp_method, SIP_METHOD_SUBSCRIBE) == 0) && - (scbp->ccbp == NULL) && (scbp->sip_to_tag[0] == '\0')) { - if (((response_code >= 180) && (response_code <= 189)) || - ((response_code >= 200) && (response_code <= 299))) { - record_route = sippmh_get_cached_header_val(pSipMessage, - RECORD_ROUTE); - if (record_route) { - if (scbp->record_route_info) { - sippmh_free_record_route(scbp->record_route_info); - } - scbp->record_route_info = sippmh_parse_record_route(record_route); - if (scbp->record_route_info == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_parse_record_route() failed", - fname); - return SIP_ERROR; - } - } - } - } - - if ((response_code == SIP_CLI_ERR_UNAUTH) || - (response_code == SIP_CLI_ERR_PROXY_REQD)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authentication Required\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (ccsip_common_util_generate_auth(pSipMessage, (ccsip_common_cb_t *)scbp, rsp_method, - response_code, scbp->SubURI) == TRUE) { - // Send Sub/Not message again - this time with authorization - if ((method == sipMethodSubscribe) || (method == sipMethodRefer)) { - (void) sipSPISendSubscribe(scbp, TRUE, TRUE); - } else { - (void) sipSPISendSubNotify((ccsip_common_cb_t *)scbp, TRUE); - } - } else { - // Return error to caller - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to generate Auth header", fname); - return SIP_ERROR; - } - return (0); - } - - // If this subscription has been cleaned by the application, then - // return SCB to IDLE state and discard this response - if (scbp->pendingClean) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recd msg for terminated sub\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (scbp->pendingRequests) { - scbp->pendingCount += TMR_PERIODIC_SUBNOT_INTERVAL; - scbp->smState = SUBS_STATE_ACTIVE; - handle_pending_requests(scbp); - } else { - free_scb(scb_index, fname); - } - return (0); - } - - /* - * if response code is 423, grab Min-Expires and let app know so - * that it can be used for subsequent subscriptions. - */ - if ((response_code == SIP_CLI_ERR_INTERVAL_TOO_SMALL) && - (strcmp(rsp_method, SIP_METHOD_SUBSCRIBE) == 0)) { - expires = sippmh_get_header_val(pSipMessage, - (const char *)SIP_HEADER_MIN_EXPIRES, - NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - //ensure new Min-Expires is > what we set before in Expires - if ((long) expiry_time > scbp->hb.expires) { - scbp->hb.expires = expiry_time; - } - } - } else { - // Get the expires header value and add to scb - expires = sippmh_get_header_val(pSipMessage, SIP_HEADER_EXPIRES, NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - scbp->hb.expires = expiry_time; - } - } - - // update to and from headers to capture the tag - if (strcmp(rsp_method, SIP_METHOD_SUBSCRIBE) == 0) { - to = sippmh_get_cached_header_val(pSipMessage, TO); - from = sippmh_get_cached_header_val(pSipMessage, FROM); - scbp->sip_to = strlib_update(scbp->sip_to, to); - // grab the to-tag if present, and if this is a response to a SUBSCRIBE - to_loc = sippmh_parse_from_or_to((char *) to, TRUE); - if (to_loc != NULL) { - if (to_loc->tag != NULL) { - scbp->sip_to_tag = strlib_update(scbp->sip_to_tag, - sip_sm_purify_tag(to_loc->tag)); - } - sippmh_free_location(to_loc); - } - scbp->sip_from = strlib_update(scbp->sip_from, from); - } - - // Delete body, if any, since it is no longer needed - if (code_class > codeClass1xx) { - if (scbp->hb.event_data_p) { - free_event_data(scbp->hb.event_data_p); - scbp->hb.event_data_p = NULL; - } - } - - if ((scbp->smState == SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY) || - (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE)) { - sub_not_result_data.u.subs_result_data.expires = scbp->hb.expires; - sub_not_result_data.u.subs_result_data.status_code = response_code; - sub_not_result_data.request_id = scbp->request_id; - sub_not_result_data.sub_id = scbp->sub_id; - sub_not_result_data.msg_id = scbp->subsResCallbackMsgID; - sub_not_result_data.gsm_id = scbp->gsm_id; - sub_not_result_data.line_id = scbp->hb.dn_line; - - if (code_class > codeClass1xx) { - if (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY) { - scbp->smState = SUBS_STATE_RCVD_NOTIFY; - } else { - scbp->smState = SUBS_STATE_ACTIVE; - } - } - - if (scbp->subsResultCallback) { - (scbp->subsResultCallback) (&sub_not_result_data); - } else if (scbp->subsNotCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(&sub_not_result_data, - scbp->subsNotCallbackTask, - scbp->subsResCallbackMsgID); - } - } else if ((scbp->smState == SUBS_STATE_SENT_NOTIFY) || - (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY)) { - sub_not_result_data.u.notify_result_data.status_code = response_code; - sub_not_result_data.request_id = scbp->request_id; - sub_not_result_data.sub_id = scbp->sub_id; - sub_not_result_data.msg_id = scbp->notResCallbackMsgID; - sub_not_result_data.gsm_id = scbp->gsm_id; - sub_not_result_data.line_id = scbp->hb.dn_line; - - if (code_class > codeClass1xx) { - if (scbp->smState == SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY) { - scbp->smState = SUBS_STATE_RCVD_SUBSCRIBE; - } else { - scbp->smState = SUBS_STATE_ACTIVE; - } - } - - if (scbp->notifyResultCallback) { - (scbp->notifyResultCallback) (&sub_not_result_data); - } else if (scbp->subsNotCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(&sub_not_result_data, - scbp->subsNotCallbackTask, - scbp->notResCallbackMsgID); - } - // If there are pending requests - handle them now - if (scbp->pendingRequests) { - handle_pending_requests(scbp); - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Incorrect SCB State\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - return SIP_ERROR; - } - - return (0); -} - -/******************************************************** - * Handle Network Received Subscribe Request - ********************************************************/ -int -subsmanager_handle_ev_sip_subscribe (sipMessage_t *pSipMessage, - sipMethod_t sipMethod, - boolean in_dialog) -{ - const char *fname = "subsmanager_handle_ev_sip_subscribe"; - const char *event = NULL; - cc_subscriptions_t eventPackage = CC_SUBSCRIPTIONS_NONE; - sipSCB_t *scbpReg = NULL, *scbp = NULL; - const char *callID = NULL, *via = NULL; - const char *contact = NULL; - const char *record_route = NULL; - const char *expires = NULL; - const char *require = NULL, *supported = NULL; - sipCseq_t *request_cseq_structure = NULL; - unsigned long request_cseq_number = 0, expiry_time = 0; - - // currently not used unsigned long diff_time = 0; - sipMethod_t request_cseq_method = sipMethodInvalid; - unsigned int content_length = 0; - line_t dn_line = 0; - boolean request_uri_error = FALSE; - sipReqLine_t *requestURI = NULL; - - // currently not used sipLocation_t *uri_loc = NULL; - genUrl_t *genUrl = NULL; - const char *sip_from = NULL; - const char *sip_to = NULL; - sipLocation_t *to_loc = NULL; - sipLocation_t *from_loc = NULL; - sipUrl_t *sipUriUrl = NULL, *sipFromUrl = NULL; - char *pUser = NULL; - char *sip_to_tag_temp, *sip_to_temp; - char *kpml_call_id = NULL, *from_tag, *to_tag; - ccsip_event_data_t *subDatap = NULL; - int scb_index; - boolean reSubscribe = FALSE; - ccsip_sub_not_data_t subs_ind_data; - ccsipCCB_t *ccb = NULL; - char *referToString = NULL; - uint32_t tags = 0; - int result; - int requestStatus = SIP_MESSAGING_ERROR; - uint8_t i; - char line_contact[MAX_LINE_CONTACT_SIZE]; - char line_name[MAX_LINE_NAME_SIZE]; - int noOfReferTo = 0; - sipServiceControl_t *scp=NULL; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a new SIP subscription request\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - if (!subsManagerRunning) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscription Manager Not Initialized!\n", fname); - return SIP_ERROR; - } - - /* Steps: - * * Check request for support by a registered app - * * If not, reject the request as unsupported - * * Decode the body, if any, and if understood - * * Allocate and fill in SCB - * * Call the callback function by registered application - */ - if (!in_dialog) { - requestStatus = sipSPICheckRequest(NULL, pSipMessage); - if (requestStatus != SIP_MESSAGING_OK) { - if (requestStatus == SIP_MESSAGING_DUPLICATE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Recieved duplicate request\n", fname); - } else { - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - } - return SIP_ERROR; - } - } - - memset(&subs_ind_data, 0, sizeof(ccsip_sub_not_data_t)); - - // Get relevant parameters from the SIP message - // These are: Event, Subscription-State, Accept, Content-Length besides - // To, From, Via, Call-ID, CSeq, and Contact - - event = sippmh_get_header_val(pSipMessage, SIP_HEADER_EVENT, - SIP_C_HEADER_EVENT); - - if (event) { - if (cpr_strcasecmp(event, "dialog") == 0) { - eventPackage = CC_SUBSCRIPTIONS_DIALOG; - } else if (cpr_strncasecmp(event, "kpml", 4) == 0) { - eventPackage = CC_SUBSCRIPTIONS_KPML; - } else if (cpr_strcasecmp(event, "presence") == 0) { - eventPackage = CC_SUBSCRIPTIONS_PRESENCE; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unsupported event=%s\n", fname, event); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - return SIP_ERROR; - } - } else if (sipMethod == sipMethodRefer) { - - } else if (sipMethod == sipMethodBye) { - - return SIP_ERROR; - - } else { - // Reached here in error - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No event header\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - SIP_WARN_MISC, - NULL, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - return SIP_ERROR; - } - - - // Parse Call-ID - callID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!callID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain request's " - "Call-ID header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CALLID_ABSENT, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - // Check content - content_length = sippmh_get_content_length(pSipMessage); - - if (pSipMessage->raw_body) { - if (content_length != strlen(pSipMessage->raw_body)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"\n Mismatched Content length and \ - Actual message body length:content length=%d \ - \n and message as %s \ - \n and strlenof messagebody = %d\n", fname, - content_length, pSipMessage->raw_body, - strlen(pSipMessage->raw_body)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - } else if (content_length != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"\n Mismatched Content length and \ - Actual message body length:content length=%d \ - \n and message is EMPTY \ - \n and strlenof messagebody = 0\n", fname, - content_length); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - // Parse CSEQ - if (getCSeqInfo(pSipMessage, &request_cseq_structure) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain or parse request's CSeq " - "header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - - request_cseq_number = request_cseq_structure->number; - request_cseq_method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - - // Parse From - sip_from = sippmh_get_cached_header_val(pSipMessage, FROM); - from_loc = sippmh_parse_from_or_to((char *) sip_from, TRUE); - if (!from_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_FROM)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROM_OR_TO_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - // Parse To - sip_to = sippmh_get_cached_header_val(pSipMessage, TO); - to_loc = sippmh_parse_from_or_to((char *) sip_to, TRUE); - if (!to_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - get_debug_string(DEBUG_FUNCTIONNAME_SIPPMH_PARSE_TO)); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_FROM_OR_TO_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_location(from_loc); - return SIP_ERROR; - } - // Parse Req-URI - requestURI = sippmh_get_request_line(pSipMessage); - if (requestURI) { - if (requestURI->url) { - genUrl = sippmh_parse_url(requestURI->url, TRUE); - if (genUrl) { - if (genUrl->schema != URL_TYPE_SIP) { - request_uri_error = TRUE; - } - } else { - request_uri_error = TRUE; - } - } else { - request_uri_error = TRUE; - } - - } else { - request_uri_error = TRUE; - } - if (request_uri_error) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid Request URI" "failed.\n", fname); - if (to_loc) - sippmh_free_location(to_loc); - if (from_loc) - sippmh_free_location(from_loc); - if (genUrl) - sippmh_genurl_free(genUrl); - if (requestURI) - SIPPMH_FREE_REQUEST_LINE(requestURI); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_URL_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - // Parse Expires header - expires = sippmh_get_header_val(pSipMessage, SIP_HEADER_EXPIRES, NULL); - if (expires) { - expiry_time = strtoul(expires, NULL, 10); - } else { - // No expires header, use default - expiry_time = 3600; - } - - scbp = find_scb_by_subscription(eventPackage, &scb_index, callID); - if (scbp && eventPackage == scbp->hb.event_type) { - // SCB is already there - must be a re-subscribe - reSubscribe = TRUE; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received a reSubscribe Message\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (scbp->pendingClean) { - // Oops, the application has already terminated this subscription - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Subscribe received for subscription " - "already terminated by application.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SUBSCRIPTION_DELETED, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - // Check continuity of CSeq numbers - if (request_cseq_number <= scbp->last_recv_request_cseq) { - // Return 500 Internal Server Error - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Out of order CSeq number received\n", - fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - } else { - // Check if this is a SUBSCRIBE request for an already terminated - // subscription. If this subscription is associated with an - // existing dialog, let it go - ccb = sip_sm_get_ccb_by_callid(callID); - if ((ccb == NULL) && - is_previous_sub(callID, from_loc->tag, eventPackage)) { - // Return 481 Internal Server Error - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SUBSCRIBE received for terminated " - "subscription\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SUBSCRIPTION_DELETED, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_CALLEG); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - // This is a valid new subscription - get all the params - scbpReg = find_scb_by_registration(eventPackage, &scb_index); - if (!scbpReg) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No application registered " - "to accept this event.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - - scbp = allocate_scb(&scb_index); - if (!scbp) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No SCB Available " - "to accept this event.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - show_scbs_inuse(); - return SIP_ERROR; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Allocated SCB for Received Subscribe, event=%d," - " scb=%d sub_id=%x\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), scbpReg->hb.event_type, - scb_index, scbp->sub_id); - scbp->hb.event_type = scbpReg->hb.event_type; - scbp->subsIndCallback = scbpReg->subsIndCallback; - scbp->subsIndCallbackTask = scbpReg->subsIndCallbackTask; - scbp->subsNotCallbackTask = scbpReg->subsNotCallbackTask; - scbp->subsIndCallbackMsgID = scbpReg->subsIndCallbackMsgID; - scbp->subsTermCallback = scbpReg->subsTermCallback; - scbp->subsTermCallbackMsgID = scbpReg->subsTermCallbackMsgID; - sstrncpy(scbp->event_name, scbpReg->event_name, MAX_EVENT_NAME_LEN); - - scbp->internal = FALSE; - - /* If the event package is KPML then check if the ID values - * are associated with it - */ - if (eventPackage == CC_SUBSCRIPTIONS_KPML) { - /* - * At this point from_tag and to_tag is never used. Since - * kpml_call_id, from_tag and to_tag just point to the - * appropriate location and does not allocate memory by itself. - */ - (void) sippmh_parse_kpml_event_id_params((char *)event, - &kpml_call_id, - &from_tag, - &to_tag); - } - - if (kpml_call_id) { - ccb = sip_sm_get_ccb_by_callid(kpml_call_id); - } else { - ccb = sip_sm_get_ccb_by_callid(callID); - scbp->ccbp = ccb; - } - if (ccb) { - scbp->gsm_id = ccb->gsm_id; - scbp->hb.dn_line = ccb->dn_line; - } else { - scbp->gsm_id = 0; - scbp->hb.dn_line = 0; - } - // Parse Supported and Required headers to see if there is the - // norefersub option tag specified - require = sippmh_get_cached_header_val(pSipMessage, REQUIRE); - if (require) { - tags = sippmh_parse_supported_require(require, NULL); - if (tags & norefersub_tag) { - scbp->norefersub = TRUE; - } - } - if ((eventPackage == CC_SUBSCRIPTIONS_CONFIGAPP) && - (scbp->norefersub == FALSE)) { - //noReferSub tag is required for OOD Refer for config change - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"noReferSub missing from Require header.\n", - fname); - if (sipSPISendErrorResponse(pSipMessage, - SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_REQUIRE_HDR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_scb(scb_index, fname); - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - supported = sippmh_get_cached_header_val(pSipMessage, SUPPORTED); - if (supported) { - tags = sippmh_parse_supported_require(supported, NULL); - if (tags & norefersub_tag) { - scbp->norefersub = TRUE; - } - } - // Check to see if the expires value is within the acceptable range, - // if any has been given to us - if (scbp->min_expires != 0) { - if (expiry_time < scbp->min_expires && expiry_time < 3600) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Too small expiry time: %d; " - "Min acceptable: %d.\n", fname, - expiry_time, scbp->min_expires); - - if (sipSPISendErrorResponse(pSipMessage, - SIP_CLI_ERR_INTERVAL_TOO_SMALL, - SIP_CLI_ERR_INTERVAL_TOO_SMALL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_INTERVAL_TOO_SMALL); - } - free_scb(scb_index, fname); - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - } - if (scbp->max_expires != 0) { - if (expiry_time > scbp->max_expires) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Too large expiry time: %d; " - "Max acceptable: %d.\n", fname, - expiry_time, scbp->max_expires); - // There doesn't seem to be any particular error code for - // maximum expiry time so just return the generic error - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_INTERVAL_TOO_LARGE_PHRASE, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Freeing SCB: scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - free_scb(scb_index, fname); - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_ERROR; - } - } - sipUriUrl = genUrl->u.sipUrl; - if (sipUriUrl) { - pUser = sippmh_parse_user(sipUriUrl->user); - if (pUser) { - sstrncpy(scbp->SubURI, pUser, sizeof(scbp->SubURI)); - cpr_free(pUser); - } else { - /* An error occurred, copy the whole thing.. */ - sstrncpy(scbp->SubURI, sipUriUrl->user, sizeof(scbp->SubURI)); - } - } - sippmh_genurl_free(genUrl); - SIPPMH_FREE_REQUEST_LINE(requestURI); - - scbp->sip_from = strlib_update(scbp->sip_from, sip_from); - if (from_loc->tag) { - scbp->sip_from_tag = strlib_update(scbp->sip_from_tag, - sip_sm_purify_tag(from_loc->tag)); - } - - if (from_loc->genUrl->schema == URL_TYPE_SIP) { - sipFromUrl = from_loc->genUrl->u.sipUrl; - } - if (sipFromUrl) { - if (sipFromUrl->user) { - char *pUserTemp, *target = NULL, addr_error; - uint32_t sip_address = 0; - - pUserTemp = sippmh_parse_user(sipFromUrl->user); - if (pUserTemp) { - scbp->callingNumber = strlib_update(scbp->callingNumber, - pUserTemp); - cpr_free(pUserTemp); - } else { - scbp->callingNumber = strlib_update(scbp->callingNumber, - sipFromUrl->user); - } - - target = cpr_strdup(sipFromUrl->host); - if (!target) { - sip_address = 0; - } else { -//CPR TODO: need reference for -//Should replace with a boolean util_check_ip_addr(char *addr) call - sip_address = IPNameCk(target, &addr_error); - cpr_free(target); - } - - if ((from_loc->genUrl->schema == URL_TYPE_SIP) && - (!sip_address)) { - if (scbp->callingNumber) { - scbp->callingNumber = strlib_append(scbp->callingNumber, "@"); - scbp->callingNumber = strlib_append(scbp->callingNumber, sipFromUrl->host); - } - } - } else { - scbp->callingNumber = strlib_update(scbp->callingNumber, - "Unknown Number"); - } - } - - scbp->sip_to = strlib_update(scbp->sip_to, sip_to); - if (to_loc->tag == NULL) { - // Create To tag - sip_to_tag_temp = strlib_open(scbp->sip_to_tag, MAX_SIP_TAG_LENGTH); - if (sip_to_tag_temp) { - sip_util_make_tag(sip_to_tag_temp); - } - scbp->sip_to_tag = strlib_close(sip_to_tag_temp); - sip_to_temp = strlib_open(scbp->sip_to, MAX_SIP_URL_LENGTH); - if (sip_to_temp) { - sstrncat(sip_to_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - if (scbp->sip_to_tag) { - sstrncat(sip_to_temp, scbp->sip_to_tag, - MAX_SIP_URL_LENGTH - strlen(sip_to_temp)); - } - } - scbp->sip_to = strlib_close(sip_to_temp); - } - - sippmh_free_location(to_loc); - sippmh_free_location(from_loc); - - sstrncpy(scbp->hb.sipCallID, callID, MAX_SIP_CALL_ID); - - // Parse Contact info - contact = sippmh_get_cached_header_val(pSipMessage, CONTACT); - if (contact) { - if (scbp->contact_info) { - sippmh_free_contact(scbp->contact_info); - } - scbp->contact_info = sippmh_parse_contact(contact); - - if ((scbp->contact_info == NULL) || // contact in msg, parse error - (sipSPICheckContact(contact) < 0)) { // If contact is invalid - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_scb(scb_index, fname); - return SIP_ERROR; - } - } - - if ((sipMethod == sipMethodSubscribe) && (scbp->ccbp == NULL)) { - record_route = sippmh_get_cached_header_val(pSipMessage, - RECORD_ROUTE); - if (record_route) { - if (scbp->record_route_info) { - sippmh_free_record_route(scbp->record_route_info); - } - scbp->record_route_info = sippmh_parse_record_route(record_route); - if (scbp->record_route_info == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_parse_record_route() failed", - fname); - free_scb(scb_index, fname); - return SIP_ERROR; - } - /* - * Store the Record-Route header value to be used - * in 18x or 2xx response - */ - scbp->cached_record_route = strlib_update(scbp->cached_record_route, - record_route); - } - } - - } // End of populating a new SCB - - scbp->hb.expires = expiry_time; - scbp->hb.orig_expiration = expiry_time; - scbp->last_recv_request_cseq = request_cseq_number; - scbp->last_recv_request_cseq_method = request_cseq_method; - - // Parse Refer-To - if (sipMethod == sipMethodRefer) { - sipReferTo_t *referto = NULL; - - noOfReferTo = sippmh_get_num_particular_headers(pSipMessage, - SIP_HEADER_REFER_TO, - SIP_C_HEADER_REFER_TO, - &referToString, - MAX_REFER_TO_HEADERS); - - if ((noOfReferTo == 0) || (noOfReferTo > 1)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - scb_index, scbp->hb.dn_line, fname, - "Incorrect number of Refer-To headers\n"); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO, - NULL); - return SIP_ERROR; - } - // Note that the refer-to header is not parsed for CCM mode since it was - // malformed in older versions of CCM - if (sip_regmgr_get_cc_mode(1) != REG_MODE_CCM) { - referto = sippmh_parse_refer_to(referToString); - if (referto == NULL) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - scb_index, scbp->hb.dn_line, fname, - "Refer-To header could not be parsed\n"); - (void) sipSPISendErrorResponse(pSipMessage, - SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO, - NULL); - return SIP_ERROR; - } else { - sippmh_free_refer_to(referto); - } - } - } - - // Parse and store Via Header - via = sippmh_get_cached_header_val(pSipMessage, VIA); - if (via) { - /* store the via header */ - if (store_incoming_trxn(via, request_cseq_number, scbp) == FALSE) { - (void) sipSPISendErrorResponse(pSipMessage, - SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, - NULL, - NULL); - return SIP_ERROR; - } - } - - // See if can determine dn_line from any of the parameters - // 1st try the REQ-URI - // CCM should send us - // SUBSCRIBE sip:@ SIP/2.0 - // and we should be able to get the line from its pkid - if (scbp->hb.dn_line == 0) { - for (dn_line = 1; dn_line <= MAX_REG_LINES; dn_line++) { - if (sip_config_check_line(dn_line) == FALSE) { - continue; - } - config_get_line_string(CFGID_LINE_CONTACT, line_contact, - dn_line, sizeof(line_contact)); - if (cpr_strcasecmp(line_contact, UNPROVISIONED) != 0) { - if (cpr_strcasecmp(scbp->SubURI, line_contact) == 0) { - scbp->hb.dn_line = dn_line; - break; - } - } - } - } - if (scbp->hb.dn_line == 0) { - // If no match there, check against the DN number - for (dn_line = 1; dn_line <= MAX_REG_LINES; dn_line++) { - config_get_line_string(CFGID_LINE_NAME, line_name, - dn_line, sizeof(line_name)); - if (!cpr_strcasecmp(scbp->SubURI, line_name)) { - scbp->hb.dn_line = dn_line; - break; - } - } - } - // If unable to determine dn_line, the SUBSCRIBE is directed to device - // Could make sure and check against the MAC address here - if (scbp->hb.dn_line == 0) { - scbp->useDeviceAddressing = TRUE; - } - // Parse Body - subs_ind_data.u.subs_ind_data.eventData = NULL; - i = 0; - while (i < HTTPISH_MAX_BODY_PARTS && pSipMessage->mesg_body[i].msgBody - != NULL) { - if (pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_DIALOG_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_KPML_REQUEST_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_CONFIGAPP_VALUE && - pSipMessage->mesg_body[i].msgContentTypeValue != SIP_CONTENT_TYPE_PRESENCE_VALUE) { - - if (pSipMessage->mesg_body[i].msgContentTypeValue == SIP_CONTENT_TYPE_CMXML_VALUE) { - // Body can not be parsed - send it up as it is - subDatap = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (subDatap == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc of subDatap failed.\n", - fname); - return (0); - } - - subDatap->u.raw_data.data = pSipMessage->mesg_body[i].msgBody; - subDatap->u.raw_data.length = pSipMessage->mesg_body[i].msgLength; - pSipMessage->mesg_body[i].msgBody = NULL; - pSipMessage->mesg_body[i].msgLength = 0; - subDatap->type = EVENT_DATA_RAW; - subDatap->next = NULL; - } else { - - /* There are other applications that has been handled like syncCheck - */ - - scp = sippmh_parse_service_control_body(pSipMessage->mesg_body[i].msgBody, - pSipMessage->mesg_body[i].msgLength); - - if (scp != NULL) { - // Hand over the event to platform - sip_platform_handle_service_control_notify(scp); - - sippmh_free_service_control_info(scp); - - } - - /* If this is the only body then have to send the response out as - * no other application will be requesting to send response - */ - if (i== 0 && pSipMessage->mesg_body[i+1].msgBody == NULL) { - - if (sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP); - } - if (!reSubscribe) { - free_scb(scb_index, fname); - } - return(0); - } - } - - } else { - result = parse_body(scbp->hb.event_type, pSipMessage->mesg_body[i].msgBody, - pSipMessage->mesg_body[i].msgLength, &subDatap, fname); - if (result == SIP_ERROR) { - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_BAD_BODY_ENCODING, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - if (!reSubscribe) { - free_scb(scb_index, fname); - } - free_event_data(subDatap); - free_event_data(subs_ind_data.u.subs_ind_data.eventData); - return SIP_ERROR; - } - } - if (subs_ind_data.u.subs_ind_data.eventData == NULL && - subDatap != NULL) { - subs_ind_data.u.subs_ind_data.eventData = subDatap; - subDatap->next = NULL; - } else if (subs_ind_data.u.subs_ind_data.eventData != NULL && - subDatap != NULL){ - append_event_data(subs_ind_data.u.subs_ind_data.eventData, - subDatap); - } - i++; - } - - // Prepare subscription indication data - subs_ind_data.event = eventPackage; - subs_ind_data.u.subs_ind_data.expires = scbp->hb.expires; - subs_ind_data.u.subs_ind_data.from = scbp->sip_from; - subs_ind_data.u.subs_ind_data.to = scbp->sip_to; - subs_ind_data.u.subs_ind_data.line = scbp->hb.dn_line; - subs_ind_data.sub_duration = scbp->hb.expires; - subs_ind_data.sub_id = scbp->sub_id; - subs_ind_data.msg_id = scbp->subsIndCallbackMsgID; - subs_ind_data.gsm_id = scbp->gsm_id; - subs_ind_data.line_id = scbp->hb.dn_line; - subs_ind_data.norefersub = scbp->norefersub; - subs_ind_data.request_id = -1; - - // Eventually let the subscribing application know - if (scbp->subsIndCallback) { - (scbp->subsIndCallback) (&subs_ind_data); - } else if ((scbp->subsIndCallbackTask != CC_SRC_MIN) && (scbp->subsIndCallbackMsgID != 0)) { - (void) sip_send_message(&subs_ind_data, scbp->subsIndCallbackTask, - scbp->subsIndCallbackMsgID); - } - - if (scbp->smState == SUBS_STATE_SENT_NOTIFY) { - scbp->smState = SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY; - } else { - scbp->smState = SUBS_STATE_RCVD_SUBSCRIBE; - } - incomingSubscribes++; - if (!reSubscribe) { - incomingSubscriptions++; - } - return (0); -} - -/** - * This function will decode the xml bodies. - * - * @param[in] event_type - event type. - * @param[in] pSipMessage - pointer to sipMessage_t - * @param[out] dataPP - pointer to pointer to decoded data. - * - * @returns TRUE/FALSE - * - * @pre (pSipMessage != NULL) && (dataPP != NULL) - */ -static boolean -decode_message_body (cc_subscriptions_t event_type, sipMessage_t *pSipMessage, ccsip_event_data_t **dataPP) -{ - const char *fname = "decode_message_body"; - uint8_t i = 0; - ccsip_event_data_t *notDatap = NULL; - int result; - - // Decode the body, if any - while (i < HTTPISH_MAX_BODY_PARTS && pSipMessage->mesg_body[i].msgBody - != NULL) { - if (pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_DIALOG_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_KPML_REQUEST_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_PRESENCE_VALUE) { - - // Body can not be parsed - send it up as it is - notDatap = (ccsip_event_data_t *) cpr_malloc(sizeof(ccsip_event_data_t)); - if (notDatap == NULL) { - CCSIP_DEBUG_ERROR("%s: Error - malloc of notDatap failed.\n", - fname); - return FALSE; - } - - notDatap->u.raw_data.data = pSipMessage->mesg_body[0].msgBody; - notDatap->u.raw_data.length = pSipMessage->mesg_body[0].msgLength; - pSipMessage->mesg_body[0].msgBody = NULL; - pSipMessage->mesg_body[0].msgLength = 0; - notDatap->type = EVENT_DATA_RAW; - notDatap->next = NULL; - - } else { - - result = parse_body(event_type, pSipMessage->mesg_body[i].msgBody, - pSipMessage->mesg_body[i].msgLength, ¬Datap, fname); - if (result == SIP_ERROR) { - free_event_data(notDatap); - free_event_data(*dataPP); - return FALSE; - } - } - if ((*dataPP) == NULL) { - (*dataPP) = notDatap; - notDatap->next = NULL; - } else { - append_event_data((*dataPP), notDatap); - } - i++; - } - return TRUE; -} - -/******************************************************** - * Handle Network Received Notify Request - ********************************************************/ -int -subsmanager_handle_ev_sip_subscribe_notify (sipMessage_t *pSipMessage) -{ - const char *fname = "subsmanager_handle_ev_sip_subscribe_notify"; - cc_subscriptions_t eventPackage; - sipSCB_t *scbp = NULL; - const char *callID = NULL; - const char *event = NULL; - int scb_index; - sipCseq_t *request_cseq_structure = NULL; - unsigned long request_cseq_number = 0; - sipMethod_t request_cseq_method = sipMethodInvalid; - ccsip_sub_not_data_t notify_ind_data; - int16_t requestStatus = SIP_MESSAGING_ERROR; - const char *from = NULL, *to = NULL; - const char *subs_state = NULL; - boolean subs_header_found = FALSE; - sipLocation_t *to_loc = NULL; - const char *via = NULL; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Processing a network generated NOTIFY\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - - memset(¬ify_ind_data, 0, sizeof(notify_ind_data)); - requestStatus = (uint16_t) sipSPICheckRequest(NULL, pSipMessage); - if (requestStatus != SIP_MESSAGING_OK) { - if (requestStatus == SIP_MESSAGING_DUPLICATE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Received duplicate request\n", fname); - } else { - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - } - return SIP_ERROR; - } - // Get fields from NOTIFY - event = sippmh_get_header_val(pSipMessage, SIP_HEADER_EVENT, - SIP_C_HEADER_EVENT); - if (event) { - if (cpr_strcasecmp(event, SIP_EVENT_DIALOG) == 0) { - eventPackage = CC_SUBSCRIPTIONS_DIALOG; - } else if (cpr_strcasecmp(event, SIP_EVENT_KPML) == 0) { - eventPackage = CC_SUBSCRIPTIONS_KPML; - } else if (cpr_strcasecmp(event, SIP_EVENT_CONFIG) == 0) { - eventPackage = CC_SUBSCRIPTIONS_CONFIG; - } else if (cpr_strcasecmp(event, SIP_EVENT_PRESENCE) == 0) { - eventPackage = CC_SUBSCRIPTIONS_PRESENCE; - } else if ((cpr_strcasecmp(event, SIP_EVENT_REFER) == 0) && - (pSipMessage->mesg_body[0].msgContentTypeValue == SIP_CONTENT_TYPE_DIALOG_VALUE)) { - eventPackage = CC_SUBSCRIPTIONS_DIALOG; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unsupported event=%s\n", fname, event); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - return SIP_ERROR; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Missing Event header\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_EVENT, - SIP_CLI_ERR_BAD_EVENT_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_EVENT); - } - return SIP_ERROR; - } - - callID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!callID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain request's " - "Call-ID header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CALLID_ABSENT, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - return SIP_ERROR; - } - - // Find the proper SCB - scbp = find_scb_by_subscription(eventPackage, &scb_index, callID); - if (!scbp) { - /* - * check if it is an unsolicited dialog/presence event NOTIFY - * check if it has a to-tag. if so, then it is not considered unsolicited NOTIFY. - * Presence of to-tag could be because it is a final NOTIFY of a subscription which - * we have just terminated. - */ - to = sippmh_get_cached_header_val(pSipMessage, TO); - to_loc = sippmh_parse_from_or_to((char *) to, TRUE); - if ((to_loc == NULL) || (to_loc->tag == NULL)) { - if (eventPackage == CC_SUBSCRIPTIONS_DIALOG) { - notify_ind_data.line_id = 1; - /* decode the body */ - if (decode_message_body(CC_SUBSCRIPTIONS_DIALOG, pSipMessage, - &(notify_ind_data.u.notify_ind_data.eventData)) == FALSE) { - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - return SIP_ERROR; - } - } - if (sipSPISendErrorResponse(pSipMessage, SIP_STATUS_SUCCESS, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_STATUS_SUCCESS); - } - - incomingUnsolicitedNotifies++; - sippmh_free_location(to_loc); - return (0); - } else if (eventPackage == CC_SUBSCRIPTIONS_PRESENCE) { - /* decode the body */ - if (decode_message_body(CC_SUBSCRIPTIONS_PRESENCE, pSipMessage, - &(notify_ind_data.u.notify_ind_data.eventData)) == FALSE) { - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - return SIP_ERROR; - } - } - pres_unsolicited_notify_ind(¬ify_ind_data); - if (sipSPISendErrorResponse(pSipMessage, SIP_STATUS_SUCCESS, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_STATUS_SUCCESS); - } - - incomingUnsolicitedNotifies++; - sippmh_free_location(to_loc); - return (0); - } - } - sippmh_free_location(to_loc); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No prior subscription", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_SUBS_DOES_NOT_EXIST_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_CALLEG); - } - return SIP_ERROR; - } - - - if (scbp->pendingClean) { - // Oops, the application has already terminated this subscription - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Notify received for subscription " - "already terminated by application.\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - if (sipSPISendErrorResponse(pSipMessage, SIP_SUCCESS_SETUP, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP); - } - return (0); - } - // Check SCB state - if (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE) { - // Have just sent a SUBSCRIBE but have not received a response - // This could happen if the NOTIFY from the remote side comes in - // before its 2xx response to SUBSCRIBE does - // Should still process this as if received a 2xx response - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Bad subscription state: " - "But still processing out-of-turn NOTIFY.\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - } - // Copy stuff from the message into the SCB - the parts that we - // need to keep to respond to this request. This includes: Via&Branch - // (From and To & Tags, CallID are simply inverse of the ones in - // SUBSCRIBE), and CSeq - - // Parse subscription state header - subs_state = sippmh_get_header_val(pSipMessage, - SIP_HEADER_SUBSCRIPTION_STATE, - SIP_HEADER_SUBSCRIPTION_STATE); - if (subs_state) { - sipSubscriptionStateInfo_t subsStateInfo; - - memset(&subsStateInfo, 0, sizeof(sipSubscriptionStateInfo_t)); - // Get the state, expires, retry-after and reason - if (sippmh_parse_subscription_state(&subsStateInfo, subs_state) == 0) { - // Store values in SCB - scbp->hb.expires = subsStateInfo.expires; - scbp->subscription_state = subsStateInfo.state; - scbp->retry_after = subsStateInfo.retry_after; - scbp->subscription_state_reason = subsStateInfo.reason; - subs_header_found = TRUE; - } - } - if (!subs_header_found) { - // Subscription-State header not present - reject - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain or parse request's " - "Subs-state header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_NO_SUBSCRIPTION_HEADER, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - // Send message to the app and let it decide what it wants - // to do with a bad NOTIFY - sip_subsManager_send_protocol_error(scbp, scb_index, FALSE); - return SIP_ERROR; - } - // Parse CSEQ - if (getCSeqInfo(pSipMessage, &request_cseq_structure) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to obtain or parse request's CSeq " - "header.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - // Send message to the app and let it decide what it wants - // to do with a bad NOTIFY - sip_subsManager_send_protocol_error(scbp, scb_index, FALSE); - return SIP_ERROR; - } - - request_cseq_number = request_cseq_structure->number; - request_cseq_method = request_cseq_structure->method; - cpr_free(request_cseq_structure); - - // Check continuity of CSeq numbers - if (request_cseq_number <= scbp->last_recv_request_cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Out of order CSeq number received\n", - fname); - } else { - scbp->last_recv_request_cseq = request_cseq_number; - scbp->last_recv_request_cseq_method = request_cseq_method; - } - - // Parse and store Via Header - via = sippmh_get_cached_header_val(pSipMessage, VIA); - if (via) { - /* store the via header */ - if (store_incoming_trxn(via, request_cseq_number, scbp) == FALSE) { - (void) sipSPISendErrorResponse(pSipMessage, - SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, - NULL, - NULL); - return SIP_ERROR; - } - } - - // Update from/to headers - note this is reversed - // as we generated the initial SUBSCRIBE - to = sippmh_get_cached_header_val(pSipMessage, TO); - from = sippmh_get_cached_header_val(pSipMessage, FROM); - - if (to) { - scbp->sip_from = strlib_update(scbp->sip_from, to); - } - if (from) { - scbp->sip_to = strlib_update(scbp->sip_to, from); - } - - if ((scbp->smState == SUBS_STATE_SENT_SUBSCRIBE) || - (scbp->smState == SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY)) { - scbp->smState = SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY; - } else { - scbp->smState = SUBS_STATE_RCVD_NOTIFY; - } - - // Decode the body, if any - if (decode_message_body(eventPackage, pSipMessage, &(notify_ind_data.u.notify_ind_data.eventData)) == FALSE) { - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - // Send message to the app and let it decide what it - // wants to do with a bad NOTIFY - sip_subsManager_send_protocol_error(scbp, scb_index, FALSE); - return SIP_ERROR; - } - - // Fill out the return structure and call the callback routine - notify_ind_data.event = eventPackage; - notify_ind_data.sub_id = scbp->sub_id; - notify_ind_data.msg_id = scbp->notIndCallbackMsgID; - notify_ind_data.gsm_id = scbp->gsm_id; - notify_ind_data.line_id = scbp->hb.dn_line; - notify_ind_data.request_id = scbp->request_id; - notify_ind_data.u.notify_ind_data.subscription_state = - scbp->subscription_state; - notify_ind_data.u.notify_ind_data.expires = scbp->hb.expires; - notify_ind_data.u.notify_ind_data.retry_after = scbp->retry_after; - notify_ind_data.u.notify_ind_data.subscription_state_reason = - scbp->subscription_state_reason; - notify_ind_data.u.notify_ind_data.cseq = request_cseq_number; - - if (scbp->notifyIndCallback) { - (scbp->notifyIndCallback) (¬ify_ind_data); - } else if (scbp->subsNotCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(¬ify_ind_data, scbp->subsNotCallbackTask, - scbp->notIndCallbackMsgID); - } - - scbp->outstandingIncomingNotifyTrxns += 1; - incomingNotifies++; - return (0); -} - -static sipRet_t -sm_add_contact (ccsip_common_cb_t *cbp, sipMessage_t *msg) -{ - - char src_addr_str[MAX_IPADDR_STR_LEN]; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - char contact[MAX_LINE_CONTACT_SIZE]; - char contact_str[MAX_SIP_URL_LENGTH]; - size_t escaped_char_str_len; - sipSCB_t *scbp = (sipSCB_t *)cbp; - - if (!cbp || !msg) { - return HSTATUS_FAILURE; - } - - ipaddr2dotted(src_addr_str, &cbp->src_addr); - - if ((cbp->cb_type == SUBNOT_CB) && (scbp->useDeviceAddressing)) { - platform_get_wired_mac_address(mac_address); - snprintf(contact_str, MAX_SIP_URL_LENGTH, "", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - src_addr_str, scbp->hb.local_port); - } else { - snprintf(contact_str, 6, "dn_line, sizeof(contact)); - if ((cpr_strcasecmp(contact, UNPROVISIONED) == 0) || - (contact[0] == '\0')) { - // pk-id has not been provisioned, use line name instead - config_get_line_string(CFGID_LINE_NAME, contact, - cbp->dn_line, sizeof(contact)); - } - escaped_char_str_len = sippmh_convertURLCharToEscChar(contact, - strlen(contact), - contact_str + 5, - (MAX_SIP_URL_LENGTH - 5), - FALSE); - snprintf(contact_str + 5 + escaped_char_str_len, - sizeof(contact_str) - 5 - escaped_char_str_len, - "@%s:%d;transport=%s>", src_addr_str, cbp->local_port, - sipTransportGetTransportType(cbp->dn_line, TRUE, NULL)); - } - - return sippmh_add_text_header(msg, SIP_HEADER_CONTACT, contact_str); -} - -static sipRet_t -sm_add_cseq (sipSCB_t *scbp, sipMethod_t method, sipMessage_t *msg) -{ - uint32_t cseq_number; - - if (!scbp || !msg) { - return HSTATUS_FAILURE; - } - if (scbp->ccbp) { - // Use cseq from CCB - cseq_number = ++(scbp->ccbp->last_used_cseq); - /* - * Remember CSEQ for the request aside from ccb so that - * CSEQ can be match when response is received (can not. - * depend on last CSEQ stored on CCB since it can be - * changed). - */ - scbp->last_sent_request_cseq = cseq_number; - } else if (scbp->last_sent_request_cseq == 0) { - cseq_number = scbp->last_sent_request_cseq = CCSIP_SUBS_START_CSEQ; - } else { - cseq_number = ++(scbp->last_sent_request_cseq); - } - - return (sippmh_add_cseq(msg, sipGetMethodString(method), cseq_number)); -} - -static boolean -sipSPIAddRouteHeadersToSubNot (sipMessage_t *msg, sipSCB_t * scbp, - char *result_route, int result_route_length) -{ - const char *fname = "sipSPIAddRouteHeadersToSubNot"; - static char route[MAX_SIP_HEADER_LENGTH * NUM_INITIAL_RECORD_ROUTE_BUFS]; - static char Contact[MAX_SIP_HEADER_LENGTH]; - boolean lr = FALSE; - sipRecordRoute_t *rr_info; - - /* Check args */ - if (!msg) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "msg"); - return (FALSE); - } - if (!scbp) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_BADARGUMENT), - fname, "scbp"); - return (FALSE); - } - - if (scbp->ccbp) { - rr_info = scbp->ccbp->record_route_info; - } else { - rr_info = scbp->record_route_info; - } - if (!rr_info) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Route info not available; will not" - " add Route header.\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - return (TRUE); - } - - memset(route, 0, MAX_SIP_HEADER_LENGTH * NUM_INITIAL_RECORD_ROUTE_BUFS); - memset(Contact, 0, MAX_SIP_HEADER_LENGTH); - - if (scbp->internal == FALSE) { /* incoming subscription */ - /* - * For Incoming dialog (UAS), Copy the RR headers as it is - * If Contact is present, append it at the end - */ - if (sipSPIGenerateRouteHeaderUAS(rr_info, route, sizeof(route), &lr) - == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateRouteHeaderUAS()"); - return (FALSE); - } - } else { - /* - * For Outgoing dialog (UAC), Copy the RR headers in the reverse - * order. If Contact is present, append it at the end - */ - if (sipSPIGenerateRouteHeaderUAC(rr_info, route, sizeof(route), &lr) - == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateRouteHeaderUAC()"); - return (FALSE); - } - } - /* - * If loose_routing is TRUE, then the contact header is NOT appended - * to the Routeset but is instead used in the Req-URI^M - */ - if (!lr) { - Contact[0] = '\0'; - if (sipSPIGenerateContactHeader(scbp->contact_info, Contact, - sizeof(Contact)) == FALSE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipSPIGenerateContactHeader()"); - return (FALSE); - } - /* Append Contact to the Route Header, if Contact is available */ - if (Contact[0] != '\0') { - if (route[0] != '\0') { - sstrncat(route, ", ", sizeof(route) - strlen(route)); - } - sstrncat(route, Contact, MIN((sizeof(route) - strlen(route)), sizeof(Contact))); - } - } - - if (route[0] != '\0') { - if (STATUS_SUCCESS == sippmh_add_text_header(msg, SIP_HEADER_ROUTE, - route)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Adding route = %s\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname), route); - if (result_route) { - sstrncpy(result_route, route, result_route_length); - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_add_text_header(ROUTE)"); - return (FALSE); - } - } else { - /* Having nothing in Route header is a legal case. - * This would happen when the Record-Route header has - * a single entry and Contact was NULL - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Not adding route \n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - } - - return (TRUE); -} - -/************************************************************** - * Format and Send an application generated SUBSCRIBE - **************************************************************/ -boolean -sipSPISendSubscribe (sipSCB_t *scbp, boolean renew, boolean authen) -{ - const char *fname = "SIPSPISendSubscribe"; - sipMessage_t *request = NULL; - sipMethod_t method = sipMethodInvalid; - sipRet_t flag = STATUS_SUCCESS; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char addr[MAX_IPADDR_STR_LEN]; - char *sip_from_temp, *sip_from_tag, *sip_to_temp; - char via[SIP_MAX_VIA_LENGTH]; - char display_name[MAX_LINE_NAME_SIZE]; - char line_name[MAX_LINE_NAME_SIZE]; - uint8_t mac_address[MAC_ADDRESS_LENGTH]; - static uint16_t count = 1; - int timeout = 0, max_forwards_value = 70; -#define CID_LENGTH 9 - char cid[CID_LENGTH]; - char tmp_header[MAX_SIP_URL_LENGTH + 2]; - char *remvtag = NULL; - char *domainloc = NULL; - char allow[MAX_SIP_HEADER_LENGTH]; - - /* - * This function builds and sends a SUBSCRIBE message. - * Specific subscription information including the encoded body, if any, - * is taken from the SCB pointer passed. The renew flag indicates that the - * SUBSCRIBE message is to be sent to renew a previous subscription - */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), fname, "SUBSCRIBE"); - - if (!scbp) { - return FALSE; - } - // Fill in source and destination addresses - // Destination address should be the current CCM that is serving us - // In the future, this part of the code will be using the tables provided - // by the connection manager - - // First check if the application gave us any forwarding address - if (scbp->hb.dest_sip_addr.type == CPR_IP_ADDR_INVALID) { - sipTransportGetPrimServerAddress(scbp->hb.dn_line, addr); - dns_error_code = sipTransportGetServerAddrPort(addr, - &scbp->hb.dest_sip_addr, - (uint16_t *)&scbp->hb.dest_sip_port, - &scbp->hb.SRVhandle, - FALSE); - if (dns_error_code == 0) { - util_ntohl(&(scbp->hb.dest_sip_addr), &(scbp->hb.dest_sip_addr)); - } else { - sipTransportGetServerIPAddr(&(scbp->hb.dest_sip_addr), scbp->hb.dn_line); - } - scbp->hb.dest_sip_port = ((dns_error_code == 0) && - (scbp->hb.dest_sip_port)) ? - ntohs((uint16_t) scbp->hb.dest_sip_port) : (sipTransportGetPrimServerPort(scbp->hb.dn_line)); - } - ipaddr2dotted(src_addr_str, &scbp->hb.src_addr); - ipaddr2dotted(dest_sip_addr_str, &scbp->hb.dest_sip_addr); - - // Get the MAC address once - since need it in several places - platform_get_wired_mac_address(mac_address); - - // If there is a related dialog, use the From header + tag, - // To header + tag, and the call-id from that dialog - if (scbp->ccbp) { - if (scbp->ccbp->flags & INCOMING) { - // If the call was incoming - reverse the headers for an - // outgoing request - scbp->sip_to = strlib_copy(scbp->ccbp->sip_from); - scbp->sip_to_tag = strlib_copy(scbp->ccbp->sip_from_tag); - scbp->sip_from = strlib_copy(scbp->ccbp->sip_to); - scbp->sip_from_tag = strlib_copy(scbp->ccbp->sip_to_tag); - } else { - // Otherwise copy then in order - scbp->sip_from = strlib_copy(scbp->ccbp->sip_from); - scbp->sip_from_tag = strlib_copy(scbp->ccbp->sip_from_tag); - scbp->sip_to = strlib_copy(scbp->ccbp->sip_to); - scbp->sip_to_tag = strlib_copy(scbp->ccbp->sip_to_tag); - } - - if (scbp->ccbp && - (scbp->ccbp->state >= SIP_STATE_SENT_INVITE_CONNECTED)) { - sstrncpy(scbp->SubURI, scbp->ccbp->ReqURI, MAX_SIP_URL_LENGTH); - } else { - sstrncpy(scbp->SubURI, "sip:", MAX_SIP_URL_LENGTH); - domainloc = scbp->SubURI + strlen(scbp->SubURI); - sstrncpy(domainloc, dest_sip_addr_str, - MAX_SIP_URL_LENGTH - (domainloc - (scbp->SubURI))); - } - sstrncpy(scbp->hb.sipCallID, scbp->ccbp->sipCallID, MAX_SIP_CALL_ID); - } else if (!renew) { - // Create the From header - sip_from_temp = strlib_open(scbp->sip_from, MAX_SIP_URL_LENGTH); - if (sip_from_temp) { - // Use the subscriberURI, if present - if (scbp->SubscriberURI[0] != '\0') { - if (scbp->hb.src_addr.type == CPR_IP_ADDR_IPV6) { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "", - scbp->SubscriberURI, src_addr_str); - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, "", - scbp->SubscriberURI, src_addr_str); - } - } else if (scbp->useDeviceAddressing) { - if (scbp->hb.src_addr.type == CPR_IP_ADDR_IPV6) { - - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, - "", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - src_addr_str); - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, - "", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], - src_addr_str); - } - } else { - sip_config_get_display_name(scbp->hb.dn_line, display_name, - sizeof(display_name)); - config_get_line_string(CFGID_LINE_NAME, line_name, - scbp->hb.dn_line, sizeof(line_name)); - if (scbp->hb.src_addr.type == CPR_IP_ADDR_IPV6) { - - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, - "\"%s\" ", display_name, - line_name, src_addr_str); - } else { - snprintf(sip_from_temp, MAX_SIP_URL_LENGTH, - "\"%s\" ", display_name, - line_name, src_addr_str); - } - } - - // Add tag to the From header (need to allocate and fill in scbp->sip_from_tag - sip_from_tag = strlib_open(scbp->sip_from_tag, MAX_SIP_URL_LENGTH); - if (sip_from_tag) { - sip_util_make_tag(sip_from_tag); - sstrncat(sip_from_temp, ";tag=", - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - sstrncat(sip_from_temp, sip_from_tag, - MAX_SIP_URL_LENGTH - strlen(sip_from_temp)); - } - scbp->sip_from_tag = strlib_close(sip_from_tag); - } - scbp->sip_from = strlib_close(sip_from_temp); - - // Create the Call-ID header - For now create own call-id - count++; - - snprintf(scbp->hb.sipCallID, MAX_SIP_CALL_ID, - "%.4x%.4x-%.4x%.4x-%.8x-%.8x@%s", - mac_address[0] * 256 + mac_address[1], - mac_address[2] * 256 + mac_address[3], - mac_address[4] * 256 + mac_address[5], count, - (unsigned int) cpr_rand(), - (unsigned int) cpr_rand(), - src_addr_str); - - // Create the ReqURI - sstrncpy(scbp->SubURI, "sip:", MAX_SIP_URL_LENGTH); - - /* Indialog requests should contain suburi only - */ - sstrncat(scbp->SubURI, scbp->SubURIOriginal, MAX_SIP_URL_LENGTH - sizeof("sip:")); - domainloc = strchr(scbp->SubURI, '@'); - if (domainloc == NULL) { - domainloc = scbp->SubURI + strlen(scbp->SubURI); - if ((domainloc - scbp->SubURI) < (MAX_SIP_URL_LENGTH - 1)) { - /* Do not include @ when there is no user part */ - if (scbp->SubURIOriginal[0] != '\0') { - *domainloc++ = '@'; - } - sstrncpy(domainloc, dest_sip_addr_str, - MAX_SIP_URL_LENGTH - (domainloc - (scbp->SubURI))); - } - } - // Create the To header - sip_to_temp = strlib_open(scbp->sip_to, MAX_SIP_URL_LENGTH); - if (sip_to_temp) { - snprintf(sip_to_temp, MAX_SIP_URL_LENGTH, "<%s>", scbp->SubURI); - scbp->sip_to = strlib_close(sip_to_temp); - } - } - - method = sipMethodSubscribe; - - - scbp->last_sent_request_cseq_method = method; - - // Get a blank SIP message template and fill it in - request = GET_SIP_MESSAGE(); - if (!request) { - return FALSE; - } - // Can't use CreateRequest to fill in the message since not using CCB. So - // do the following: - // 1. Add request line (sipSPIAddRequestLine). - if (HSTATUS_SUCCESS != sippmh_add_request_line(request, - sipGetMethodString(method), - scbp->SubURI, SIP_VERSION)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Request line\n", fname); - free_sip_message(request); - return (FALSE); - } - // 2. Add local Via (sipSPIAddLocalVia) - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s%.8x", - sipTransportGetTransportType(scbp->hb.dn_line, TRUE, NULL), - src_addr_str, scbp->hb.local_port, VIA_BRANCH, - VIA_BRANCH_START, (unsigned int) cpr_rand()); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_VIA, via)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding VIA header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // 3. Add common headers (sipSPIAddCommonHeaders) - if ((HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_FROM, scbp->sip_from)) || - (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_TO, scbp->sip_to)) || - (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CALLID, scbp->hb.sipCallID)) || - (HSTATUS_SUCCESS != sipAddDateHeader(request)) || - (HSTATUS_SUCCESS != sm_add_cseq(scbp, method, request))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding either From, To, CallID, " - "Date or Cseq header\n", fname); - free_sip_message(request); - return (FALSE); - } - // 4. Add text headers (sippmh_add_text_header) - (void) sippmh_add_text_header(request, SIP_HEADER_USER_AGENT, - sipHeaderUserAgent); - - // 5. Add general headers (AddGeneralHeaders) - // Event header is not needed for Refer msg - if (method != sipMethodRefer) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_EVENT, - scbp->event_name)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Event header\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - if (scbp->hb.accept_type == CC_SUBSCRIPTIONS_DIALOG) { - flag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - dialogAcceptHeader); - } else if (scbp->hb.event_type == CC_SUBSCRIPTIONS_KPML) { - flag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - kpmlResponseAcceptHeader); - } else if (scbp->hb.event_type == CC_SUBSCRIPTIONS_DIALOG) { - flag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - dialogAcceptHeader); - } else if (scbp->hb.event_type == CC_SUBSCRIPTIONS_PRESENCE) { - flag = sippmh_add_text_header(request, SIP_HEADER_ACCEPT, - presenceAcceptHeader); - } - if (HSTATUS_SUCCESS != flag) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Accept header\n", fname); - free_sip_message(request); - return (FALSE); - } - - if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_EXPIRES, - scbp->hb.expires)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Expires header\n", fname); - free_sip_message(request); - return (FALSE); - } - // Add max-forwards header - config_get_value(CFGID_SIP_MAX_FORWARDS, &max_forwards_value, - sizeof(max_forwards_value)); - if (HSTATUS_SUCCESS != - sippmh_add_int_header(request, SIP_HEADER_MAX_FORWARDS, - max_forwards_value)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Max-Forwards header\n", fname); - free_sip_message(request); - return (FALSE); - } - // Add Contact header - if (HSTATUS_SUCCESS != sm_add_contact(&(scbp->hb), request)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Contact header\n", fname); - free_sip_message(request); - return (FALSE); - } - - if (authen) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, AUTHOR_HDR(scbp->hb.authen.status_code), - scbp->hb.authen.authorization)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Authorization header\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - if (scbp->norefersub) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_REQUIRE, "norefersub")) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Require header\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - if (method == sipMethodRefer) { - // Add Refer-To, Referred-By, and Content-ID headers - sstrncpy(tmp_header, (const char *) (scbp->sip_from), MAX_SIP_URL_LENGTH + 1); - remvtag = strstr(tmp_header, ";tag="); - if (remvtag) { - *remvtag = '\0'; - } - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_REFERRED_BY, tmp_header)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Referred-By header\n", fname); - free_sip_message(request); - return (FALSE); - } - - snprintf(cid, sizeof(cid), "%.8x", (unsigned int)cpr_rand()); - snprintf(tmp_header, sizeof(tmp_header), "cid:%s@%s", cid, src_addr_str); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_REFER_TO, tmp_header)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Refer-To header\n", fname); - free_sip_message(request); - return (FALSE); - } - - snprintf(tmp_header, sizeof(tmp_header), "<%s@%s>", cid, src_addr_str); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CONTENT_ID, tmp_header)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content-ID header\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - // Add Allow - snprintf(allow, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, SIP_METHOD_OPTIONS, - SIP_METHOD_REFER, SIP_METHOD_REGISTER, SIP_METHOD_UPDATE, - SIP_METHOD_SUBSCRIBE); - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_ALLOW, allow)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Allow header\n", fname); - free_sip_message(request); - return (FALSE); - } - - /* - * Add route header if needed. - */ - if (FALSE == sipSPIAddRouteHeadersToSubNot(request, scbp, NULL, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Route header\n", fname); - free_sip_message(request); - return (FALSE); - } - // Add content, if any - if (scbp->hb.event_data_p) { - if (add_content(scbp->hb.event_data_p, request, fname) == FALSE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content\n", fname); - free_sip_message(request); - return (FALSE); - } - } else { - if (HSTATUS_SUCCESS != sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content-Len\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - ccsip_common_util_set_retry_settings((ccsip_common_cb_t *)scbp, &timeout); - if (sipTransportCreateSendMessage(NULL, request, method, - &(scbp->hb.dest_sip_addr), - (int16_t) scbp->hb.dest_sip_port, - FALSE, TRUE, timeout, scbp, - RELDEV_NO_STORED_MSG) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send message\n", fname); - return (FALSE); - } - - return (TRUE); -} - -/************************************************************** - * Format and send a response to a network received SUBSCRIBE - **************************************************************/ -boolean -sipSPISendSubscribeNotifyResponse (sipSCB_t *scbp, - uint16_t response_code, - uint32_t cseq) -{ - const char *fname = "sipSPISendSubscribeNotifyResponse"; - sipMessage_t *response = NULL; - sipVia_t *via = NULL; - sub_not_trxn_t *trxn_p; - int status_code = 0; - - // currently not used const char *request_callid = NULL; - cpr_ip_addr_t cc_remote_ipaddr; - uint16_t cc_remote_port = 0; - - // currently not used int timeout = 0; - char *pViaHeaderStr = NULL; - char *dest_ip_addr_str = 0; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char response_text[MAX_SIP_URL_LENGTH]; - boolean port_present = FALSE; - int reldev_stored_msg; - - sipRet_t tflag = HSTATUS_SUCCESS; - - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_RESPONSE), fname, response_code); - - memset(&cc_remote_ipaddr, 0, sizeof(cpr_ip_addr_t)); - cc_remote_ipaddr = ip_addr_invalid; - if (!scbp) { - return FALSE; - } - - /* - * In the response to Subscribe: - * The Via header gets a ";received" addition (...;received: 192.168.0.7) - * The From header is the same as in the subscribe request - * The To header is the same as in the subscribe request but has a tag - * The call-id is the same as in the request - * Content Length is set to 0 - */ - response = GET_SIP_MESSAGE(); - if (!response) { - return FALSE; - } - - get_sip_error_string(response_text, response_code); - - tflag = sippmh_add_response_line(response, SIP_VERSION, response_code, - response_text); - if (tflag != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding response line", fname); - free_sip_message(response); - return FALSE; - } - - /* - * find the transaction and fetch the via header - */ - trxn_p = sll_find(scbp->incoming_trxns, &cseq); - if (trxn_p) { - pViaHeaderStr = trxn_p->via; - /* remove the transaction because we are done with it */ - (void)sll_remove(scbp->incoming_trxns, trxn_p); - cpr_free(trxn_p); - } - if (pViaHeaderStr) { - via = sippmh_parse_via(pViaHeaderStr); - } - if (!via || !pViaHeaderStr) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "No or Bad Via Header present in Message!"); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in parsing Via header", fname); - if (via) - sippmh_free_via(via); - free_sip_message(response); - cpr_free(pViaHeaderStr); - return (FALSE); - } - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_VIA, pViaHeaderStr)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Via header", fname); - sippmh_free_via(via); - free_sip_message(response); - cpr_free(pViaHeaderStr); - return (FALSE); - } - /* free the via header because we will not need it anymore */ - cpr_free(pViaHeaderStr); - - // Add common headers: From, To, CallID, Date, CSeq, Contact - // Note: If this is a response to a NOTIFY, then from and to headers - // must be reversed - if (scbp->last_recv_request_cseq_method == sipMethodNotify) { - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_FROM, scbp->sip_to)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding From header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_TO, scbp->sip_from)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding To header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - } else { - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_FROM, scbp->sip_from)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding From header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_TO, scbp->sip_to)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding To header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - } - - if (STATUS_SUCCESS != sippmh_add_text_header(response, SIP_HEADER_CALLID, scbp->hb.sipCallID)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CallID header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - if (HSTATUS_SUCCESS != sipAddDateHeader(response)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Date header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - if (HSTATUS_SUCCESS != sippmh_add_cseq(response, - sipGetMethodString(scbp-> - last_recv_request_cseq_method), - cseq)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CSeq header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - - tflag = sippmh_add_text_header(response, SIP_HEADER_SERVER, sipHeaderServer); - if (tflag != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Server header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - ipaddr2dotted(src_addr_str, &scbp->hb.src_addr); - - tflag = sm_add_contact(&(scbp->hb), response); - - if (tflag != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Contact header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - // Add expires header - only for a SUBSCRIBE response - if (scbp->last_recv_request_cseq_method == sipMethodSubscribe) { - if (sippmh_add_int_header(response, SIP_HEADER_EXPIRES, scbp->hb.expires) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Expires header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - /* - * add Record-Route Header, if it is a response (18x/2xx) to - * dialog initiating SUBSCRIBE. - */ - if ((scbp->cached_record_route[0] != '\0') && - (((response_code >= 180) && (response_code <= 189)) || - ((response_code >= 200) && (response_code <= 299)))) { - tflag = sippmh_add_text_header(response, SIP_HEADER_RECORD_ROUTE, - scbp->cached_record_route); - if (tflag != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Record-Route header", - fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - } - /* free the cached record_route, once the final resp is sent */ - if (response_code >= 200) { - strlib_free(scbp->cached_record_route); - scbp->cached_record_route = strlib_empty(); - } - } - // Add other headers such as content-length, content-type - if (HSTATUS_SUCCESS != sippmh_add_int_header(response, SIP_HEADER_CONTENT_LENGTH, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Content-Length header", fname); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } - // Send Response - // Get information on where to send the response from via headers - if (via->remote_port) { - cc_remote_port = via->remote_port; - port_present = TRUE; - } else { - /* Use default 5060 if via does not have port */ - cc_remote_port = SIP_WELL_KNOWN_PORT; - } - - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Via host: %s, port: %d, rcvd host: %s\n", - fname, via->host, via->remote_port, via->recd_host); - - if (via->maddr) { - if (!port_present) { - dns_error_code = sipTransportGetServerAddrPort(via->maddr, - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(via->maddr, &cc_remote_ipaddr, - 100, 1); - } - - if (dns_error_code != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - "sipTransportGetServerAddrPort or dnsGetHostByName()"); - } else { - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } - } - // If all else fails send the response to where we got the request from - if (cc_remote_ipaddr.type == CPR_IP_ADDR_INVALID) { - if (via->recd_host) { - dest_ip_addr_str = via->recd_host; - } else { - dest_ip_addr_str = via->host; - } - - if (!port_present) { - dns_error_code = sipTransportGetServerAddrPort(dest_ip_addr_str, - &cc_remote_ipaddr, - &cc_remote_port, - NULL, FALSE); - } else { - dns_error_code = dnsGetHostByName(dest_ip_addr_str, - &cc_remote_ipaddr, 100, 1); - } - - if (dns_error_code != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, - "sipTransportGetServerAddrPort or dnsGetHostByName()"); - // cpr_free(request_cseq_structure); - sippmh_free_via(via); - free_sip_message(response); - return (FALSE); - } else { - util_ntohl(&cc_remote_ipaddr, &cc_remote_ipaddr); - } - } - // Store cc_remote_ipaddr and cc_remote_port values in SCB for later use - // in the corresponding NOTIFY, if any - scbp->hb.dest_sip_addr = cc_remote_ipaddr; - scbp->hb.dest_sip_port = cc_remote_port; - - reldev_stored_msg = sipRelDevCoupledMessageStore(response, scbp->hb.sipCallID, - cseq, - scbp->last_recv_request_cseq_method, - FALSE, - status_code, - &cc_remote_ipaddr, - cc_remote_port, TRUE); - - sippmh_free_via(via); - - scbp->hb.retx_flag = FALSE; - if (sipTransportCreateSendMessage(NULL, response, sipMethodSubscribe, - &cc_remote_ipaddr, cc_remote_port, - FALSE, TRUE, 0, scbp, reldev_stored_msg) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send message", fname); - return (FALSE); - } - - return (TRUE); -} - -/************************************************************** - * Format and send a locally generated NOTIFY - **************************************************************/ -boolean -sipSPISendSubNotify (ccsip_common_cb_t *cbp, boolean authen) -{ - const char *fname = "SIPSPISendSubNotify"; - sipMessage_t *request = NULL; - static uint32_t cseq = 0; - - // currently not used char *message_body = NULL; - // currently not used sipRet_t flag = STATUS_SUCCESS; - char src_addr_str[MAX_IPADDR_STR_LEN]; - char dest_sip_addr_str[MAX_IPADDR_STR_LEN]; - char addr[MAX_IPADDR_STR_LEN]; - - // currently not used uint32_t nbytes = SIP_UDP_MESSAGE_SIZE; - char via[SIP_MAX_VIA_LENGTH]; - - // currently not used short send_to_proxy_handle = INVALID_SOCKET; - static char ReqURI[MAX_SIP_URL_LENGTH]; - static char sip_temp_str[MAX_SIP_URL_LENGTH]; - static char sip_temp_tag[MAX_SIP_URL_LENGTH]; - sipSubscriptionStateInfo_t subs_state; - int timeout = 0, max_forwards_value = 70; - char allow[MAX_SIP_HEADER_LENGTH]; - sipSCB_t *scbp = (sipSCB_t *)cbp; - sipTCB_t *tcbp = (sipTCB_t *)cbp; - - /* - * This function builds and sends a NOTIFY message as a follow up to - * a previously received SUBSCRIBE - */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_MSG_SENDING_REQUEST), fname, "NOTIFY"); - - if (!cbp) { - return FALSE; - } - - if (util_check_if_ip_valid(&cbp->dest_sip_addr)== FALSE) { - sipTransportGetPrimServerAddress(scbp->hb.dn_line, addr); - - dns_error_code = sipTransportGetServerAddrPort(addr, - &cbp->dest_sip_addr, - (uint16_t *)&cbp->dest_sip_port, - &cbp->SRVhandle, - FALSE); - - if (dns_error_code == 0) { - util_ntohl(&(cbp->dest_sip_addr), &(cbp->dest_sip_addr)); - } else { - sipTransportGetServerIPAddr(&(cbp->dest_sip_addr), cbp->dn_line); - } - - cbp->dest_sip_port = ((dns_error_code == 0) && - (cbp->dest_sip_port)) ? - ntohs(cbp->dest_sip_port) : (sipTransportGetPrimServerPort(cbp->dn_line)); - - } - - ipaddr2dotted(src_addr_str, &cbp->src_addr); - ipaddr2dotted(dest_sip_addr_str, &cbp->dest_sip_addr); - - // Create the request - request = GET_SIP_MESSAGE(); - - /* - * Determine the Request-URI - */ - memset(ReqURI, 0, sizeof(ReqURI)); - - if (cbp->cb_type == SUBNOT_CB) { - if (scbp->contact_info) { - // Build Req-URI from contact info - sipContact_t *response_contact_info; - sipUrl_t *sipUrl = NULL; - cpr_ip_addr_t request_uri_addr; - uint16_t request_uri_port = 0; - - request_uri_addr = ip_addr_invalid; - - response_contact_info = scbp->contact_info; - if (response_contact_info->locations[0]->genUrl->schema == URL_TYPE_SIP) { - sipUrl = response_contact_info->locations[0]->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"URL is not SIP\n", fname); - free_sip_message(request); - return (FALSE); - } - - request_uri_port = sipUrl->port; - dns_error_code = sipTransportGetServerAddrPort(sipSPIUrlDestination(sipUrl), - &request_uri_addr, - &request_uri_port, NULL, FALSE); - if (dns_error_code == 0) { - util_ntohl(&request_uri_addr, &request_uri_addr); - } else { - request_uri_addr = ip_addr_invalid; - } - - if (sipUrl->user != NULL) { - if (sipUrl->password) { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? - "sip:%s:%s@%s:%d;user=phone" : - "sip:%s:%s@%s:%d", - sipUrl->user, sipUrl->password, - sipUrl->host, sipUrl->port); - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? - "sip:%s@%s:%d;user=phone" : - "sip:%s@%s:%d", - sipUrl->user, sipUrl->host, - sipUrl->port); - } - } else { - snprintf(ReqURI, sizeof(ReqURI), - sipUrl->is_phone ? - "sip:%s:%d;user=phone" : - "sip:%s:%d", - sipUrl->host, sipUrl->port); - } - } else { - // Build Req-URI from FROM field - sipLocation_t *request_uri_loc = NULL; - char sip_from[MAX_SIP_URL_LENGTH]; - sipUrl_t *request_uri_url = NULL; - - sstrncpy(sip_from, scbp->sip_from, MAX_SIP_URL_LENGTH); - request_uri_loc = sippmh_parse_from_or_to(sip_from, TRUE); - if (!request_uri_loc) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_parse_from_or_to(TO)"); - free_sip_message(request); - return (FALSE); - } - - if (!sippmh_valid_url(request_uri_loc->genUrl)) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_valid_url()"); - sippmh_free_location(request_uri_loc); - free_sip_message(request); - return (FALSE); - } - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Forming Req-URI (Caller): using original " - "Req-URI\n", DEB_F_PREFIX_ARGS(SIP_SUB, fname)); - /* - * if (request_uri_loc->name) { - * if (request_uri_loc->name[0]) { - * sstrncat(ReqURI, "\"", sizeof(ReqURI)-strlen(ReqURI)); - * sstrncat(ReqURI, request_uri_loc->name, - * sizeof(ReqURI)-strlen(ReqURI)); - * sstrncat(ReqURI, "\" ", sizeof(ReqURI)-strlen(ReqURI)); - * } - * } - */ - sstrncat(ReqURI, "sip:", sizeof(ReqURI) - strlen(ReqURI)); - if (request_uri_loc->genUrl->schema == URL_TYPE_SIP) { - request_uri_url = request_uri_loc->genUrl->u.sipUrl; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"URL is not SIP\n", fname); - sippmh_free_location(request_uri_loc); - free_sip_message(request); - return (FALSE); - } - - if (request_uri_url->user) { - sstrncat(ReqURI, request_uri_url->user, - sizeof(ReqURI) - strlen(ReqURI)); - sstrncat(ReqURI, "@", sizeof(ReqURI) - strlen(ReqURI)); - } - if (request_uri_url->is_phone) { - sstrncat(ReqURI, ";user=phone", - sizeof(ReqURI) - strlen(ReqURI)); - } - sstrncat(ReqURI, request_uri_url->host, - sizeof(ReqURI) - strlen(ReqURI)); - // sstrncat(ReqURI, ">", sizeof(ReqURI)-strlen(ReqURI)); - sippmh_free_location(request_uri_loc); - } - } else { //Unsolicited NOTIFY - char line_name[MAX_LINE_NAME_SIZE]; - config_get_line_string(CFGID_LINE_NAME, line_name, cbp->dn_line, sizeof(line_name)); - snprintf(ReqURI, MAX_SIP_URL_LENGTH, "sip:%s@%s", line_name, dest_sip_addr_str); - sstrncpy(tcbp->full_ruri, ReqURI, MAX_SIP_URL_LENGTH); - } - (void) sippmh_add_request_line(request, - sipGetMethodString(sipMethodNotify), - ReqURI, SIP_VERSION); - - // The Via header has the local URI and a new branch - snprintf(via, sizeof(via), "SIP/2.0/%s %s:%d;%s=%s%.8x", - sipTransportGetTransportType(cbp->dn_line, TRUE, NULL), - src_addr_str, cbp->local_port, VIA_BRANCH, - VIA_BRANCH_START, (unsigned int) cpr_rand()); - - if (STATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_VIA, via)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding VIA header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // The To field including the tag is the same as the From field in the - // response to SUBSCRIBE - if (cbp->cb_type != SUBNOT_CB) { - snprintf(sip_temp_str, MAX_SIP_URL_LENGTH, "<%s>", ReqURI); - } - if (STATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_TO, - ((cbp->cb_type == SUBNOT_CB) ? scbp->sip_from : sip_temp_str))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding To header\n", fname); - free_sip_message(request); - return (FALSE); - } - - // The From field including the tag is the same as the To field in the - // response to SUBSCRIBE - if (cbp->cb_type != SUBNOT_CB) { - sstrncat(sip_temp_str, ";tag=", MAX_SIP_URL_LENGTH - strlen(sip_temp_str)); - sip_util_make_tag(sip_temp_tag); - sstrncat(sip_temp_str, sip_temp_tag, MAX_SIP_URL_LENGTH - strlen(sip_temp_str)); - } - if (STATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_FROM, - ((cbp->cb_type == SUBNOT_CB) ? scbp->sip_to : sip_temp_str))) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding From header\n", fname); - free_sip_message(request); - return (FALSE); - } - // The call-id used is the same as in the SCB - if (cbp->sipCallID[0] == 0) { - snprintf(tcbp->hb.sipCallID, sizeof(tcbp->hb.sipCallID), "%.8x-%.8x@%s", // was MAX_SIP_URL_LENGTH - (unsigned int) cpr_rand(), - (unsigned int) cpr_rand(), - src_addr_str); - } - if (STATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_CALLID, cbp->sipCallID)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CallID header\n", fname); - free_sip_message(request); - return (FALSE); - } - - if (HSTATUS_SUCCESS != sipAddDateHeader(request)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Date header\n", fname); - free_sip_message(request); - return (FALSE); - } - - if (cbp->cb_type == SUBNOT_CB) { - if (sm_add_cseq(scbp, sipMethodNotify, request) != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CSeq header\n", fname); - free_sip_message(request); - return (FALSE); - } - } else { - cseq++; - if (cseq == 0) { - cseq = 1; - } - if (HSTATUS_SUCCESS != sippmh_add_cseq(request, sipGetMethodString(sipMethodNotify), cseq)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding CSEQ header\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - // Event is the event name - // The subscription-state header is active - if (cbp->event_type - CC_SUBSCRIPTIONS_DIALOG > -1 && - cbp->event_type - CC_SUBSCRIPTIONS_DIALOG < 5) { - if (HSTATUS_SUCCESS != sippmh_add_text_header(request, SIP_HEADER_EVENT, - eventNames[cbp->event_type - CC_SUBSCRIPTIONS_DIALOG])) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Event header\n", fname); - free_sip_message(request); - return (FALSE); - } - } - - subs_state.expires = cbp->expires; - if (cbp->cb_type == SUBNOT_CB) { - if (subs_state.expires > 0) { - subs_state.state = SUBSCRIPTION_STATE_ACTIVE; - } else { - subs_state.state = SUBSCRIPTION_STATE_TERMINATED; - } - } else { - subs_state.state = SUBSCRIPTION_STATE_ACTIVE; - } - if (sippmh_add_subscription_state(request, &subs_state) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Subscription-State header", fname); - free_sip_message(request); - return (FALSE); - } - // Add max-forwards header - config_get_value(CFGID_SIP_MAX_FORWARDS, &max_forwards_value, - sizeof(max_forwards_value)); - (void) sippmh_add_int_header(request, SIP_HEADER_MAX_FORWARDS, - max_forwards_value); - - // Add contact header - if (sm_add_contact(cbp, request) != HSTATUS_SUCCESS) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Contact header\n", fname); - free_sip_message(request); - return (FALSE); - } - - if (authen) { - (void) sippmh_add_text_header(request, - AUTHOR_HDR(scbp->hb.authen.status_code), - scbp->hb.authen.authorization); - } - // Add Allow - snprintf(allow, MAX_SIP_HEADER_LENGTH, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", - SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, - SIP_METHOD_INVITE, SIP_METHOD_NOTIFY, SIP_METHOD_OPTIONS, - SIP_METHOD_REFER, SIP_METHOD_REGISTER, SIP_METHOD_UPDATE, - SIP_METHOD_SUBSCRIBE); - (void) sippmh_add_text_header(request, SIP_HEADER_ALLOW, allow); - - if (cbp->cb_type == SUBNOT_CB) { - /* keep the request method to be sent */ - scbp->last_sent_request_cseq_method = sipMethodNotify; - /* - * Add route header if needed. - */ - if (FALSE == sipSPIAddRouteHeadersToSubNot(request, scbp, NULL, 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in adding Route header\n", fname); - free_sip_message(request); - return (FALSE); - } - ccsip_common_util_set_retry_settings((ccsip_common_cb_t *)scbp, &timeout); - } - - // Add content, if any - if (cbp->event_data_p) { - if (add_content(cbp->event_data_p, request, fname) == FALSE) { - free_sip_message(request); - return (FALSE); - } - } else { - (void) sippmh_add_int_header(request, SIP_HEADER_CONTENT_LENGTH, 0); - } - - if (sipTransportCreateSendMessage(NULL, request, sipMethodNotify, - &(scbp->hb.dest_sip_addr), - (int16_t) scbp->hb.dest_sip_port, - FALSE, TRUE, timeout, cbp, - RELDEV_NO_STORED_MSG) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in sending message\n", fname); - return (FALSE); - } - - return (TRUE); -} - -/************************************************************** - * Handle message retries - *************************************************************/ -int -subsmanager_handle_retry_timer_expire (int scb_index) -{ - const char *fname = "subsmanager_handle_retry_timer_expire"; - sipSCB_t *scbp = NULL; - uint32_t max_retx = 0; - ccsip_sub_not_data_t sub_not_result_data; - uint32_t time_t1 = 0; - uint32_t time_t2 = 0; - uint32_t timeout = 0; - - CCSIP_DEBUG_TASK("Entering %s. scb_index: %d\n", fname, scb_index); - - if (scb_index < 0 || scb_index >= MAX_SCBS) { - return (-1); - } - scbp = &(subsManagerSCBS[scb_index]); - - if (scbp->hb.retx_flag == TRUE) { - config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); - if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { - max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - if (scbp->hb.retx_counter < max_retx) { - config_get_value(CFGID_TIMER_T1, &time_t1, sizeof(time_t1)); - scbp->hb.retx_counter++; - timeout = time_t1 * (1 << scbp->hb.retx_counter); - config_get_value(CFGID_TIMER_T2, &time_t2, sizeof(time_t2)); - if (timeout > time_t2) { - timeout = time_t2; - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Resending message #%d\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scbp->hb.retx_counter); - if (sipTransportSendMessage(NULL, - sipPlatformUISMSubNotTimers[scb_index].message_buffer, - sipPlatformUISMSubNotTimers[scb_index].message_buffer_len, - sipPlatformUISMSubNotTimers[scb_index].message_type, - &(sipPlatformUISMSubNotTimers[scb_index].ipaddr), - sipPlatformUISMSubNotTimers[scb_index].port, - FALSE, TRUE, timeout, scbp) < 0) { - return (-1); - } - } else { - // Should we terminate this dialog? At the very least - stop - // the timer block, display error, and send a message to the app - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Either exceeded max retries for UDP" - " or Timer F fired for TCP\n", fname); - sip_platform_msg_timer_subnot_stop(&sipPlatformUISMSubNotTimers[scb_index]); - scbp->hb.retx_flag = FALSE; - scbp->hb.retx_counter = 0; - - memset(&sub_not_result_data, 0, sizeof(sub_not_result_data)); - sub_not_result_data.request_id = scbp->request_id; - sub_not_result_data.sub_id = scbp->sub_id; - sub_not_result_data.gsm_id = scbp->gsm_id; - sub_not_result_data.line_id = scbp->hb.dn_line; - - if ((scbp->last_sent_request_cseq_method == sipMethodSubscribe) || - (scbp->last_sent_request_cseq_method == sipMethodRefer)) { - sub_not_result_data.u.subs_result_data.status_code = REQUEST_TIMEOUT; - sip_send_error_message(&sub_not_result_data, - scbp->subsNotCallbackTask, - scbp->subsResCallbackMsgID, - scbp->subsResultCallback, fname); - } else { - sub_not_result_data.u.notify_result_data.status_code = REQUEST_TIMEOUT; - // Set the state to ACTIVE, so we can go on appropriately. Note that - // this assignment below should be placed before sip_send_error_message() so - // that in case of callback running on same thread freed the scb, we will not - // set it back to active and try to use it later. - scbp->smState = SUBS_STATE_ACTIVE; - sip_send_error_message(&sub_not_result_data, - scbp->subsNotCallbackTask, - scbp->notResCallbackMsgID, - scbp->notifyResultCallback, fname); - } - // If there are any pending requests, execute them now - if (scbp->pendingRequests) { - handle_pending_requests(scbp); - } - } - } - - return (0); -} - -/************************************************************** - * Handle periodic timer - *************************************************************/ -void -subsmanager_handle_periodic_timer_expire (void) -{ - const char *fname = "subsmanager_handle_periodic_timer_expire"; - sipSCB_t *scbp = NULL; - int scb_index; - ccsip_sub_not_data_t subs_term_data; - sipspi_msg_t subscribe; - int subscription_delta = 0; - - // static char count = 0; - /* - * Go through the list of SCBs and pick out the ones for - * which some action needs to be taken. This action may include: - * 1. If an incoming SUBSCRIBE has expired, inform the application - * 2. If auto-subscribe is set on an outgoing subscribe, send - * a re-SUBSCRIBE message - */ - config_get_value(CFGID_TIMER_SUBSCRIBE_DELTA, &subscription_delta, - sizeof(subscription_delta)); - for (scb_index = 0; scb_index < MAX_SCBS; scb_index++) { - scbp = &(subsManagerSCBS[scb_index]); - if (scbp->pendingClean) { - if (scbp->pendingCount > 0) { - scbp->pendingCount -= TMR_PERIODIC_SUBNOT_INTERVAL; - } else { - free_scb(scb_index, fname); - } - continue; - } - if (scbp->smState == SUBS_STATE_REGISTERED) { - continue; - } - if (scbp->smState != SUBS_STATE_IDLE) { - if (scbp->hb.expires > 0) { - scbp->hb.expires -= TMR_PERIODIC_SUBNOT_INTERVAL; - } - if (scbp->hb.expires > (subscription_delta + TMR_PERIODIC_SUBNOT_INTERVAL)) { - continue; - } - - if (scbp->internal) { - // Subscription was internally generated - if (scbp->auto_resubscribe) { - if (scbp->smState != SUBS_STATE_SENT_SUBSCRIBE) { - // Send re-SUBSCRIBE message - but not if we just sent one - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Auto reSubscribing:" - " scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - memset(&subscribe, 0, sizeof(sipspi_msg_t)); - subscribe.msg.subscribe.sub_id = scbp->sub_id; - subscribe.msg.subscribe.duration = scbp->hb.orig_expiration; - (void) subsmanager_handle_ev_app_subscribe(&subscribe); - } - } else { - // Let app know its own SUBSCRIBE is about to expire - // Application SHOULD renew its own subscription - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Notifying App of internal" - " expiry: scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - subs_term_data.sub_id = scbp->sub_id; - subs_term_data.event = scbp->hb.event_type; - subs_term_data.msg_id = scbp->subsTermCallbackMsgID; - subs_term_data.request_id = scbp->request_id; - subs_term_data.reason_code = SM_REASON_CODE_NORMAL; - subs_term_data.u.subs_term_data.status_code = - APPLICATION_SUBSCRIPTION_EXPIRED; - if (scbp->subsTermCallback) { - scbp->subsTermCallback(&subs_term_data); - } else if (scbp->subsIndCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(&subs_term_data, scbp->subsIndCallbackTask, - scbp->subsTermCallbackMsgID); - } - } - - } else { - // Subscription was received from network - if (scbp->hb.expires <= 0) { - // Let app know this SUBSCRIBE has expired - // App SHOULD send final NOTIFY and terminate the session - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Notifying App of external" - " expiry: scb=%d sub_id=%x\n", - DEB_F_PREFIX_ARGS(SIP_SUB, fname), scb_index, scbp->sub_id); - subs_term_data.sub_id = scbp->sub_id; - subs_term_data.event = scbp->hb.event_type; - subs_term_data.msg_id = scbp->subsTermCallbackMsgID; - subs_term_data.line_id = scbp->hb.dn_line; - subs_term_data.gsm_id = scbp->gsm_id; - subs_term_data.reason_code = SM_REASON_CODE_NORMAL; - subs_term_data.u.subs_term_data.status_code = - NETWORK_SUBSCRIPTION_EXPIRED; - if (scbp->subsTermCallback) { - scbp->subsTermCallback(&subs_term_data); - } else if (scbp->subsIndCallbackTask != CC_SRC_MIN) { - (void) sip_send_message(&subs_term_data, scbp->subsIndCallbackTask, - scbp->subsTermCallbackMsgID); - } - } - } - } - } - // Re-start periodic timer - (void) sip_platform_subnot_periodic_timer_start(TMR_PERIODIC_SUBNOT_INTERVAL * 1000); - - /* - * Comment out the periodic show since now we have a show-subscription-statistics CLI - * Do not want to completely remove this code since the CLI is not available in - * IP-Communicator where this could be enabled for debugging - */ - /* - * if (count == 50) { - * // Show the stats for the Subsmanager - * CCSIP_DEBUG_TASK("Reg - RecdSubs RecdNots ActiveExtSubs - SentSubs SentNots ActiveIntSubs - CurSCBs MaxSCBs\n"); - * CCSIP_DEBUG_TASK("-----------------------------------------------------------------------------------\n"); - * CCSIP_DEBUG_TASK("%d - %d %d %d - %d %d %d - %d %d\n", - * internalRegistrations, incomingSubscribes, - * incomingNotifies, incomingSubscriptions, - * outgoingSubscribes, outgoingNotifies, - * outgoingSubscriptions, currentScbsAllocated, - * maxScbsAllocated); - * count = 0; - * } else { - * count ++; - * } - */ -} - -/************************************************************** - * Format and send a response to a network received NOTIFY - * Currently this action is handled together with the response - * to SUBSCRIBE - **************************************************************/ -boolean -sipSPISendSubNotifyResponse (sipSCB_t *scbp, int response_code) -{ - return TRUE; -} - -static void -show_scbs_inuse () -{ - int i; - sipSCB_t *scbp = NULL; - - if (subsManagerRunning == 0) { - return; - } - - debugif_printf("---------SCB DUMP----------\n"); - for (i = 0; i < MAX_SCBS; i++) { - scbp = &(subsManagerSCBS[i]); - if (scbp->smState == SUBS_STATE_IDLE) { - debugif_printf("SCB# %d, State = %d (IDLE)\n", i, scbp->smState); - continue; - } - if (scbp->smState == SUBS_STATE_REGISTERED) { - debugif_printf("SCB# %d, State = %d (REGISTERED) sub_id=%x\n", - i, scbp->smState, scbp->sub_id); - debugif_printf("SCB# %d, eventPackage=%d\n", - i, scbp->hb.event_type); - continue; - } - debugif_printf("SCB# %d, State = %d sub_id=%x\n", i, scbp->smState, - scbp->sub_id); - debugif_printf("SCB# %d, pendingClean=%d, internal=%d, eventPackage=%d, " - "norefersub=%d, subscriptionState=%d, expires=%d\n", i, - scbp->pendingClean, scbp->internal, scbp->hb.event_type, - scbp->norefersub, scbp->subscription_state, scbp->hb.expires); - debugif_printf("-----------------------------\n"); - } -} - -cc_int32_t -show_subsmanager_stats (cc_int32_t argc, const char *argv[]) -{ - debugif_printf("------ Current Subsmanager Statistics ------\n"); - debugif_printf("Internal Registrations: %d\n", internalRegistrations); - debugif_printf("Total Incoming Subscribes: %d\n", incomingSubscribes); - debugif_printf("Total Incoming Notifies: %d\n", incomingNotifies); - debugif_printf("Total Incoming Unsolicited Notifies: %d\n", incomingUnsolicitedNotifies); - debugif_printf("Active Incoming Subscriptions: %d\n", incomingSubscriptions); - debugif_printf("Total Outgoing Subscribes: %d\n", outgoingSubscribes); - debugif_printf("Total Outgoing Notifies: %d\n", outgoingNotifies); - debugif_printf("Total Outgoing Unsolicited Notifies: %d\n", outgoingUnsolicitedNotifies); - debugif_printf("Active Outgoing Subscriptions: %d\n", outgoingSubscriptions); - debugif_printf("Current SCBs Allocated: %d\n", currentScbsAllocated); - debugif_printf("Total Maximum SCBs Ever Allocated: %d\n", maxScbsAllocated); - debugif_printf("------ End of Subsmanager Statistics ------\n"); - - // Now print out the status of all SCBs - show_scbs_inuse(); - return 0; -} - diff --git a/libs/sipcc/core/sipstack/ccsip_task.c b/libs/sipcc/core/sipstack/ccsip_task.c deleted file mode 100644 index 318f2af83a..0000000000 --- a/libs/sipcc/core/sipstack/ccsip_task.c +++ /dev/null @@ -1,3032 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_socket.h" -#include "cpr_timers.h" -#include "cpr_memory.h" -#include "cpr_in.h" -#include "cpr_ipc.h" -#include "phntask.h" -#include "util_string.h" -#include "task.h" -#include "phone.h" -#include "text_strings.h" -#include "ccsip_task.h" -#include "ccsip_core.h" -#include "ccsip_macros.h" -#include "ccsip_messaging.h" -#include "ccsip_sim.h" -#include "ccsip_platform_udp.h" -#include "ccsip_platform.h" -#include "phone_debug.h" -#include "ccsip_register.h" -#include "debug.h" -#include "ccsip_reldev.h" -#include "ccsip_cc.h" -#include "gsm.h" -#include "fim.h" -#include "ccapi.h" -#include "lsm.h" -#include "config.h" -#include "check_sync.h" -#include "sip_common_transport.h" -#include "uiapi.h" -#include "sip_csps_transport.h" -#include "sip_common_regmgr.h" -#include "sip_platform_task.h" -#include "platform_api.h" -#include "sip_interface_regmgr.h" -#include "ccsip_publish.h" -#include "platform_api.h" - -#ifdef SAPP_SAPP_GSM -#define SAPP_APP_GSM 3 -#define SAPP_APP SAPP_APP_GSM -#include "sapp.h" -#endif - -#if defined SIP_OS_WINDOWS -#include "../win32/cpr_win_defines.h" -#endif - - - -extern sipSCB_t *find_scb_by_callid(const char *callID, int *scb_index); -extern int platThreadInit(char *); -void sip_platform_handle_service_control_notify(sipServiceControl_t *scp); -short SIPTaskProcessTimerExpiration(void *msg, uint32_t *cmd); -extern cprMsgQueue_t sip_msgq; -extern cprMsgQueue_t gsm_msgq; -extern void ccsip_dump_recv_msg_info(sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port); -void destroy_sip_thread(void); - -// Global variables - - -/*--------------------------------------------------------- - * - * Definitions - * - */ - -#define MESSAGE_WAITING_STR_SIZE 5 - -#define MAC_ADDR_STR_LENGTH 16 -#define SIP_HEADER_SERVER_LEN 80 -#define SIP_HEADER_USER_AGENT_LEN 80 -#define SIP_PHONE_MODEL_NUMBER_LEN 32 - -/* The maximun number of gsm_msgq depth to allow new incoming call, - */ -/* - * for RT, the threshold of 60 is not based on testing. - * As discussed in CSCsz33584 Code Review, it is better to drop the heavy load as it enters the system than let it go deep into the system. - * So we add the same logic into RT, but RT still cannot pass the test in CSCsz33584. - * Bottleneck of RT might be ccapp_msgq instead of gsm_msgq. - * A more complex solution should be studied to prevent RT phone from overload. - */ -#define MAX_DEPTH_OF_GSM_MSGQ_TO_ALLOW_NEW_INCOMING_CALL 60 - -/* Internal request structure for restart/re-init request from platform */ -typedef enum { - SIP_RESTART_REQ_NONE, - SIP_RESTART_REQ_RESTART, /* to restart */ - SIP_RESTART_REQ_REINIT /* to re-init */ -} ccsip_restart_cmd; - -typedef enum { - SIP_SHUTDOWN_REQ_NONE, - SIP_SHUTDOWN_REQ_SHUT -} ccsip_shutdown_cmd; - -typedef struct ccsip_restart_req_t_ { - ccsip_restart_cmd cmd; /* restart command */ -} ccsip_restart_req; - -typedef struct ccsip_shutdown_req_t_ { - ccsip_shutdown_cmd cmd; /* shutdown command */ - int action; - int reason; -} ccsip_shutdown_req_t; - - -extern cprThread_t sip_thread; - - -/*--------------------------------------------------------- - * - * Local Variables - * - */ -// static uint16_t nfds = 0; No reference. Should this be removed? -extern fd_set read_fds; -extern fd_set write_fds; -// static cpr_socket_t listenSocket = INVALID_SOCKET; No reference. Should this be removed? -// static sip_connection_t sipConn; Set in ccsip_task.c but never used. Should this be removed? -// static cprMsgQueue_t sip_msg_queue; No reference. Should this be removed? -// static cprRegion_t sip_region; No reference. Should this be removed? -// static cprPool_t sip_pool; No reference. Should this be removed? - - - -/*--------------------------------------------------------- - * - * Global Variables - * - */ -sipGlobal_t sip; -boolean sip_mode_quiet = FALSE; -char sipHeaderServer[SIP_HEADER_SERVER_LEN]; -char sipHeaderUserAgent[SIP_HEADER_SERVER_LEN]; -char sipPhoneModelNumber[SIP_PHONE_MODEL_NUMBER_LEN]; -char sipUnregisterReason[MAX_SIP_REASON_LENGTH]; - -boolean Is794x = FALSE; - -/*--------------------------------------------------------- - * - * External Variables - * TODO reference through proper header files - */ -extern sipCallHistory_t gCallHistory[]; - - -/*--------------------------------------------------------- - * - * Function declarations - * - */ -static void SIPTaskProcessSIPMessage(sipMessage_t *message); -static int SIPTaskProcessSIPNotify(sipMessage_t *pSipMessage); -static int SIPTaskProcessSIPNotifyMWI(sipMessage_t *pSipMessage, - line_t dn_line); -static void SIPTaskProcessSIPNotifyCheckSync(sipMessage_t *pSipMessage); -static void SIPTaskProcessSIPPreviousCallByeResponse(sipMessage_t *pSipMessage, - int response_code, - line_t previous_call_index); -static void SIPTaskProcessSIPPreviousCallInviteResponse(sipMessage_t *pResponse, - int response_code, - line_t previous_call_index); -static void SIPTaskProcessSIPNotifyRefer(sipMessage_t *pSipMessage); -static int SIPTaskProcessSIPNotifyServiceControl(sipMessage_t *pSipMessage); -static void SIPTaskProcessRestart(ccsip_restart_cmd cmd); -static void SIPTaskProcessShutdown(int action, int reason); - -/*--------------------------------------------------------- - * - * Functions - * - */ -void -get_ua_model_and_device (char sipHdrUserAgent[]) -{ - const char fname[] = "get_ua_model_and_device"; - char *model = NULL; - - model = (char *)platGetModel(); - - if (model) { - if (strncmp(model, CSF_MODEL, 3) == 0) { - sstrncat(sipHdrUserAgent, CCSIP_SIP_CSF_USER_AGENT, - SIP_HEADER_SERVER_LEN - strlen(sipHdrUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER_CSF, - SIP_PHONE_MODEL_NUMBER_LEN); - } else if (strcmp(model, PHONE_MODEL) == 0) { - //if phone model is any of vendor defined, set as is. - sstrncat(sipHdrUserAgent, CCSIP_SIP_USER_AGENT, - SIP_HEADER_SERVER_LEN - strlen(sipHdrUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER, - SIP_PHONE_MODEL_NUMBER_LEN); - } else { - // Default to 7970 - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"unknown model,defaulting to model 7970: %s\n", fname, model); - sstrncat(sipHdrUserAgent, CCSIP_SIP_7970_USER_AGENT, - SIP_HEADER_SERVER_LEN - strlen(sipHdrUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER_7970, - SIP_PHONE_MODEL_NUMBER_LEN); - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"could not obtain model information\n", fname); - sstrncat(sipHdrUserAgent, CCSIP_SIP_7970_USER_AGENT, - SIP_HEADER_SERVER_LEN - strlen(sipHdrUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER_7970, - SIP_PHONE_MODEL_NUMBER_LEN); - } -} - -extern void ccsip_debug_init(void); - -/** - * - * SIPTaskInit - * - * Initialize the SIP Task - * - * Parameters: None - * - * Return Value: SIP_OK - * - */ -void -SIPTaskInit (void) -{ - /* - * Initialize platform specific parameters - */ - - // sipConn is set but never used. Should this be removed? - // for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - // sipConn.read[i] = INVALID_SOCKET; - // sipConn.write[i] = INVALID_SOCKET; - //} - - /* - * Initialize cprSelect call parameters - */ - // XXX already did in sip_platform_task_init(), like, two instructions ago - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - /* - * Do the debug init right here so that we can enable - * sip debugs during startup and not wait for sip stack - * to initialize. - */ - ccsip_debug_init(); - - /************************ - // Move all initialization to sip_sm_init called after config - if (ccsip_register_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccsip_register_init() failed.\n", fname); - return SIP_ERROR; - } - - * - * Allocate timers for CCBs - * - if (sip_platform_timers_init() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_platform_timers_init() failed\n", fname); - return SIP_ERROR; - } - *************************/ - // Initialize the value of the UA and Server headers - sipHeaderUserAgent[0] = '\0'; - sipPhoneModelNumber[0] = '\0'; - sipHeaderServer[0] = '\0'; - -#if defined _COMMUNICATOR_ - sstrncat(sipHeaderUserAgent, CCSIP_SIP_COMMUNICATOR_USER_AGENT, - sizeof(sipHeaderUserAgent) - strlen(sipHeaderUserAgent)); - sstrncpy(sipPhoneModelNumber, PHONE_MODEL_NUMBER_COMMUNICATOR, - SIP_PHONE_MODEL_NUMBER_LEN); -#else - get_ua_model_and_device(sipHeaderUserAgent); -#endif - - // Now add the firmware version - sstrncat(sipHeaderUserAgent, "/", - sizeof(sipHeaderUserAgent) - strlen(sipHeaderUserAgent)); - sstrncat(sipHeaderUserAgent, gVersion, - sizeof(sipHeaderUserAgent) - strlen(sipHeaderUserAgent)); - sstrncpy(sipHeaderServer, sipHeaderUserAgent, - SIP_HEADER_SERVER_LEN); -} - - -/** - * - * SIPTaskSendMsg (API) - * - * The API to send a message to the SIP task - * - * Parameters: cmd - the message type - * msg - the message buffer to send - * len - length of the message buffer - * usr - user pointer TEMPORARY VALUE TO MOVE INTO msg - * - * Return Value: SIP_OK or SIP_ERROR - * - */ -cpr_status_e -SIPTaskSendMsg (uint32_t cmd, void *msg, uint16_t len, void *usr) -{ - phn_syshdr_t *syshdr; - - syshdr = (phn_syshdr_t *) cprGetSysHeader(msg); - if (!syshdr) { - return CPR_FAILURE; - } - syshdr->Cmd = cmd; - syshdr->Len = len; - syshdr->Usr.UsrPtr = usr; - - /* - * If we send a message to the task too soon the sip variable is not set yet. - * so just use the global for now. This happens if we create sip thread - * and immediately send a CFG_DONE message to sip thread from the main thread. - * This can be solved by waiting for an echo roundtrip from Thread before sending - * any other message. Will do someday. - */ - if (cprSendMessage(sip_msgq /*sip.msgQueue */ , (cprBuffer_t)msg, (void **)&syshdr) - == CPR_FAILURE) { - cprReleaseSysHeader(syshdr); - return CPR_FAILURE; - } - return CPR_SUCCESS; -} - -/** - * - * SIPTaskGetBuffer (API) - * - * The API to grab a buffer from the SIP buffer pool - * - * Parameters: size - size of the buffer requested - * - * Return Value: requested buffer or NULL - * - */ -cprBuffer_t -SIPTaskGetBuffer (uint16_t size) -{ - return cpr_malloc(size); -} - -/** - * - * SIPTaskProcessListEvent (Internal API) - * - * Process a SIP event/message - * - * Parameters: cmd - the type of event - * msg - the event message - * pUsr- a user pointer (TEMPORARY FIELD to be put into msg) - * len - the length of the message - * - * Return Value: None - * - */ -void -SIPTaskProcessListEvent (uint32_t cmd, void *msg, void *pUsr, uint16_t len) -{ - static const char *fname = "SIPTaskProcessListEvent"; - sipSMEvent_t sip_sm_event; - int idx; - int p2psip = 0; - int sdpmode = 0; - cprCallBackTimerMsg_t *timerMsg; - line_t last_available_line; - CCM_ID ccm_id; - - timerMsg = (cprCallBackTimerMsg_t *) msg; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"cmd = 0x%x\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname), cmd); - - /* - * Loop and wait until we get a TCP_PHN_CFG_TCP_DONE or a RESTART - * message from the phone before we finish - * initializing the SIPTask and SIP state machine - * (note this can happen any time the network stack is re-spun) - */ - if ((sip.taskInited == FALSE) && - ((cmd != TCP_PHN_CFG_TCP_DONE) && - (cmd != SIP_RESTART) && - (cmd != SIP_TMR_SHUTDOWN_PHASE2) && - (cmd != SIP_SHUTDOWN) && - (cmd != TIMER_EXPIRATION) && - (cmd != THREAD_UNLOAD)) ) { - cpr_free(msg); - DEF_DEBUG(DEB_F_PREFIX" !!!sip.taskInited is false. So not executing cmd=0x%x\n", - DEB_F_PREFIX_ARGS(SIP_EVT, fname), cmd); - return; - } - - memset(&sip_sm_event, 0, sizeof(sipSMEvent_t)); - - /* - * Before CPR used to call the timer callback function out of its' - * timer tick so quite a few of the SIP timers would just post - * a timer expiration event back to its' queue to release the - * CPR thread. Now CPR just sends a timer expiration event - * to the SIP task so we don't want to double post a timer - * expiration event. Therefore check to see if this is a timer - * expiration event and if so possibly update the command before - * switching on it. If the function returns false it means all - * it did was update the command so we need to process the switch - * statement, if it returns true the timer event has been handled. - */ - if (cmd == TIMER_EXPIRATION) { - if (SIPTaskProcessTimerExpiration(msg, &cmd)) { - cpr_free(msg); - return; - } - /* - * No need to release the buffer if we overwrote the command - * as the code that handles the new command below will release - * the buffer. - */ - } - - config_get_value(CFGID_P2PSIP, &p2psip, sizeof(p2psip)); - config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - - switch (cmd) { - /* - * See comment above - */ - case TCP_PHN_CFG_TCP_DONE: - /* - * Ignore any TCP_PHN_CFG_TCP_DONE message since it is only used to - * determine when the SIP sm should be initialized - */ - cpr_free(msg); - - // If P2P set transport to UDP - if (p2psip == TRUE) - CC_Config_setIntValue(CFGID_TRANSPORT_LAYER_PROT, 2); - - - if (sip_sm_init() < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_init() failed ", fname); - return; - } - - sip_mode_quiet = FALSE; - - /* - * If P2P or SDP only do not register with SIP Server - */ - if (!p2psip && !sdpmode) - sip_platform_init(); - else - ui_set_sip_registration_state(CC_ALL_LINES, TRUE); - - sip.taskInited = TRUE; - DEF_DEBUG(SIP_F_PREFIX"sip.taskInited is set to true ", fname); -#ifdef SAPP_SAPP_GSM - /* - * Initialize SAPP. - */ - if (sapp_init() != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sapp_init() failed.\n", fname); - break; - } - /* - * Start SAPP. SAPP will register with the CCM. - */ - if (sapp_test() != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sapp_test() failed.\n", fname); - break; - } -#endif - break; - - case SIP_GSM: - /* - * GSM CC Events - */ - -#ifdef SAPP_SAPP_GSM - if (sapp_process_cc_event(msg) == 0) { - return; - } -#endif - - if (p2psip == TRUE) - sipTransportSetSIPServer(); - - if (sip_sm_process_cc_event(msg) != SIP_OK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_process_cc_event() " - "failed.\n", fname); - } - break; - - case SIP_TMR_INV_EXPIRE: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - cpr_free(msg); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"usrData does not point to a valid ccb " - "discarding SIP_TMR_INV_EXPIRE event\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - sip_sm_event.type = E_SIP_INV_EXPIRES_TIMER; - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_SUPERVISION_DISCONNECT: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - cpr_free(msg); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"usrData does not point to a valid ccb " - "discarding SIP_TMR_SUPERVISION_DISCONNECT event.\n", - DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - sip_sm_event.type = E_SIP_SUPERVISION_DISCONNECT_TIMER; - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_INV_LOCALEXPIRE: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - cpr_free(msg); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"usrData does not point to valid ccb " - "discarding SIP_TMR_INV_LOCALEXPIRE " - "event.\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - sip_sm_event.type = E_SIP_INV_LOCALEXPIRES_TIMER; - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - /* - * UsrInfo is set to the IP address that bounced when an - * IMCP Unreachable. -1 means we had a timeout, not a bounce. - */ - case SIP_TMR_MSG_RETRY: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = E_SIP_TIMER; - sip_sm_event.u.UsrInfo = ip_addr_invalid; - cpr_free(msg); - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_ICMP_UNREACHABLE: - { - sipMethod_t retxMessageType; - - idx = msg ? (line_t) (*((uint32_t *)msg)) : 0; - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - /* IP address that bounced */ - sip_sm_event.u.UsrInfo = (*(cpr_ip_addr_t *)pUsr); - cpr_free(msg); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"event does not point to valid ccb " - "SIP_ICMP_UNREACHABLE event.\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - /* - * Retrieve message type and cancel outstanding - * timer and remove ICMP Handler - */ - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - sip_sm_event.ccb->index, - sip_sm_event.ccb->dn_line, - fname, "ICMP_UNREACHABLE"); - - /* Do not need to process the ICMP_UNREACHABLE for fallback ccbs */ - if (sip_sm_event.ccb->index <= REG_BACKUP_CCB) { - retxMessageType = - sip_platform_msg_timer_messageType_get(sip_sm_event.ccb->index); - sip_platform_msg_timer_stop(sip_sm_event.ccb->index); - - if (retxMessageType == sipMethodInvite) { - config_get_value(CFGID_SIP_INVITE_RETX, - &sip_sm_event.ccb->retx_counter, - sizeof(sip_sm_event.ccb->retx_counter)); - if (sip_sm_event.ccb->retx_counter > MAX_INVITE_RETRY_ATTEMPTS) { - sip_sm_event.ccb->retx_counter = MAX_INVITE_RETRY_ATTEMPTS; - } - } else { - config_get_value(CFGID_SIP_RETX, - &sip_sm_event.ccb->retx_counter, - sizeof(sip_sm_event.ccb->retx_counter)); - if (sip_sm_event.ccb->retx_counter > MAX_NON_INVITE_RETRY_ATTEMPTS) { - sip_sm_event.ccb->retx_counter = MAX_NON_INVITE_RETRY_ATTEMPTS; - } - } - - /* - * If REG CCB send into registration state machine else send - * into sip call processing machine - */ - if (retxMessageType == sipMethodRegister) { - /* - * UsrInfo is set to the IP address that bounced when an - * ICMP Unreachable. -1 means we had a timeout, not a bounce. - */ - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_RETRY; - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - } else { - sip_sm_event.type = E_SIP_ICMP_UNREACHABLE; - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - } - } - } - break; - - case SIP_TMR_REG_EXPIRE: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_EXPIRE; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_REG_ACK: - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_ACK; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_REG_WAIT: - idx = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_WAIT; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - /* - * UsrInfo is set to the IP address that bounced when an - * ICMP Unreachable. -1 means we had a timeout, not a bounce. - */ - /* - * currently, we only look for ccm_id for SIP_TMR_REG_RETRY. for rest - * of the REG msg, existing code will work because first field of - * ccsip_registration_msg_t is uint32_t. - */ - case SIP_TMR_REG_RETRY: - idx = msg ? (line_t) ((ccsip_registration_msg_t *)msg)->ccb_index : CC_NO_LINE; - ccm_id = msg ? ((ccsip_registration_msg_t *)msg)->ccm_id : UNUSED_PARAM; - sip_sm_event.ccb = sip_sm_get_ccb_by_ccm_id_and_index(ccm_id, (line_t) idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_RETRY; - sip_sm_event.u.UsrInfo = ip_addr_invalid; - cpr_free(msg); - if (sip_sm_event.ccb == NULL || sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_REG_REQ: - idx = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - cpr_free(msg); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t) idx); - if (!sip_sm_event.ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"event data does not point to a valid ccb" - "SIP_REG_REQ event.\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - break; - } - (void) sip_sm_ccb_init(sip_sm_event.ccb, (line_t)idx, idx, SIP_REG_STATE_IDLE); - sip_sm_event.ccb->state = (sipSMStateType_t) SIP_REG_STATE_IDLE; - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_REG_REQ; - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_REG_CANCEL: - idx = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t) idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_CANCEL; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_REG_CLEANUP: - idx = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t) idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_CLEANUP; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - case SIP_TMR_STANDBY_KEEPALIVE: - sip_sm_event.ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_TMR_WAIT; - cpr_free(msg); - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - - // Subscribe/Notify Events - case SIPSPI_EV_CC_SUBSCRIBE_REGISTER: - if (subsmanager_handle_ev_app_subscribe_register(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_subscribe_register() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_SUBSCRIBE: - if (subsmanager_handle_ev_app_subscribe(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_subscribe() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_SUBSCRIBE_RESPONSE: - if (subsmanager_handle_ev_app_subscribe_response(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_subscribe_response() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_NOTIFY: - { - int ret; - - ret = subsmanager_handle_ev_app_notify(msg); - if (ret == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_notify() " - "returned error.\n", fname); - } else if (ret == SIP_DEFER) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_notify() " - "deferred request.\n", fname); - } - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_NOTIFY_RESPONSE: - if (subsmanager_handle_ev_app_notify_response(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_notify_response() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - case SIPSPI_EV_CC_SUBSCRIPTION_TERMINATED: - if (subsmanager_handle_ev_app_subscription_terminated(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_ev_app_subscription_terminated() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - - case SIPSPI_EV_CC_PUBLISH_REQ: - if (publish_handle_ev_app_publish(msg) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"publish_handle_ev_app_publish() " - "returned error.\n", fname); - } - cpr_free(msg); - break; - - case SIP_REG_UPDATE: - last_available_line = msg ? (line_t) (*((uint32_t *)msg)) : CC_NO_LINE; - cpr_free(msg); - regmgr_handle_register_update(last_available_line); - break; - case REG_MGR_STATE_CHANGE: - - sip_regmgr_rsp(((cc_regmgr_t *)msg)->rsp_id, - ((cc_regmgr_t *)msg)->rsp_type, - ((cc_regmgr_t *)msg)->wait_flag); - cpr_free(msg); - break; - - - // Retry timer expired for Sub/Not - case SIP_TMR_MSG_RETRY_SUBNOT: - idx = (long) (timerMsg->usrData); - cpr_free(msg); - if (subsmanager_handle_retry_timer_expire(idx) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"subsmanager_handle_retry_timer_expire() " - "returned error.\n", fname); - } - break; - // Sub/Not periodic timer - case SIP_TMR_PERIODIC_SUBNOT: - cpr_free(msg); - subsmanager_handle_periodic_timer_expire(); - publish_handle_periodic_timer_expire(); - break; - - case SIP_RESTART: - { - ccsip_restart_req *req = (ccsip_restart_req *) msg; - ccsip_restart_cmd restartCmd; - - restartCmd = req->cmd; - // Handle restart event from platform - cpr_free(msg); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received SIP_RESTART event restartCmd = (%d)\n", - DEB_F_PREFIX_ARGS(SIP_EVT, fname), restartCmd); - SIPTaskProcessRestart(restartCmd); - break; - } - - case SIP_TMR_SHUTDOWN_PHASE2: - { - // Handle shutdown phase 2 event (after unregistration) - // Note: boolean is 8 bits, but 32 bits have been allocated for it - // so we need to dereference msg with 32 bits - int action; - - if (msg) { - action = (*((uint32_t *)msg)); - } else { - action = SIP_INTERNAL; - } - - cpr_free(msg); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received SIP_TMR_SHUTDOWN_PHASE2 event action= (%d)\n", - DEB_F_PREFIX_ARGS(SIP_EVT, fname), action); - sip_shutdown_phase2(action); - } - break; - - case SIP_SHUTDOWN: - { - ccsip_shutdown_req_t *req = (ccsip_shutdown_req_t *) msg; - int action; - int reason; - - action = req->action; - reason = req->reason; - cpr_free(msg); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received SIP_SHUTDOWN message\n", - DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - SIPTaskProcessShutdown(action, reason); - } - break; - - case THREAD_UNLOAD: - { - destroy_sip_thread(); - } - break; - - case SIP_TMR_GLARE_AVOIDANCE: - // Handle glare retry timer expiry - idx = (long) (timerMsg->usrData); - sip_sm_event.ccb = sip_sm_get_ccb_by_index((line_t)idx); - sip_sm_event.type = (sipSMEventType_t) E_SIP_GLARE_AVOIDANCE_TIMER; - cpr_free(msg); - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - } - break; - - default: - cpr_free(msg); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unknown message\n, fname"); - break; - } - return; -} - -/** - * SIPTaskCheckSource - * - * Ensure that sender is a trusted source - * - * Parameters: from - the source address for the message - * - * Return Value: SIP_OK if message can be processed further - */ -int -SIPTaskCheckSource (cpr_sockaddr_storage from) -{ - static const char fname[] = "SIPTaskCheckSource"; - int regConfigValue; - line_t line_index, line_end; - cpr_ip_addr_t fromIPAddr; - int retval = SIP_ERROR; - char fromIPAddrStr[MAX_IPADDR_STR_LEN]; - ccsipCCB_t *ccb = NULL; - uint32_t data, *data_p; - - // If not registered, return ok - config_get_value(CFGID_PROXY_REGISTER, ®ConfigValue, sizeof(regConfigValue)); - if (regConfigValue == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"CFGID_PROXY_REGISTER is false\n", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname)); - return SIP_OK; - } - - line_end = 1; - line_end += TEL_CCB_END; - - util_extract_ip(&fromIPAddr,&from); - util_ntohl(&fromIPAddr, &fromIPAddr); - - fromIPAddrStr[0] = '\0'; - ipaddr2dotted(fromIPAddrStr, &fromIPAddr); - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Attempting to recognize \"%s\"\n", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname), fromIPAddrStr); - // Get the proxy configured for all lines and check against those - for (line_index = REG_CCB_START; line_index <= line_end; line_index++) { - // Check the binary from-IP address with the ccb->reg.addr value - if (sip_config_check_line((line_t)(line_index - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(line_index); - if (ccb && util_compare_ip(&(ccb->reg.addr), &fromIPAddr)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Found server IP match\n", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname)); - retval = SIP_OK; - break; - } - } - } - if (retval == SIP_OK) { - return retval; - } - // Not found - continue to check backup CCBs - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (ccb && util_compare_ip(&(ccb->reg.addr), &fromIPAddr)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Found backup server IP match\n", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname)); - retval = SIP_OK; - } - if (retval == SIP_OK) { - return retval; - } - // Not found - continue to check with fallback CCBs - data = 0x00; - data_p = &data; - ccb = sip_regmgr_get_fallback_ccb_list(data_p); - while ((ccb != NULL) && (retval != SIP_OK)) { - if (util_compare_ip(&(ccb->reg.addr), &fromIPAddr)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Found fallback server IP match\n", - DEB_F_PREFIX_ARGS(SIP_IP_MATCH, fname)); - retval = SIP_OK; - } - ccb = sip_regmgr_get_fallback_ccb_list(data_p); - } - return retval; -} - -/** - * - * SIPTaskProcessUDPMessage (Internal API) - * - * Process the received (via UDP) SIP message - * - * Parameters: msg - the message buffer - * len - length of the message buffer - * from - the source address for the message - * - * Return Value: SIP_OK if message could be processed (though this itself - * may fail) or SIP_ERROR - * - */ -int -SIPTaskProcessUDPMessage (cprBuffer_t msg, - uint16_t len, - cpr_sockaddr_storage from) -{ - static const char *fname = "SIPProcessUDPMessage"; - sipMessage_t *pSipMessage = NULL; - static char buf[SIP_UDP_MESSAGE_SIZE + 1]; - char remoteIPAddrStr[MAX_IPADDR_STR_LEN]; - uint32_t bytes_used = 0; - int accept_msg = SIP_OK; - cpr_ip_addr_t ip_addr; - int p2psip = 0; - /* - * Convert IP address to string, for debugs - */ - util_extract_ip(&ip_addr, &from); - - util_ntohl(&ip_addr, &ip_addr); - - if (SipDebugMessage) { - ipaddr2dotted(remoteIPAddrStr, &ip_addr); - } - - util_extract_ip(&ip_addr, &from); - - if (len > SIP_UDP_MESSAGE_SIZE) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Received UDP message from <%s>:<%d>: " - "message too big: msg size = %d, max SIP " - "pkt size = %d\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), remoteIPAddrStr, - util_get_port(&from), bytes_used, SIP_UDP_MESSAGE_SIZE); - cpr_free(msg); - return SIP_ERROR; - } - - /* - * Copy message to a local memory and release the system buffer - */ - memcpy(buf, (char *)msg, len); - buf[len] = '\0'; /* NULL terminate for debug printing */ - cpr_free(msg); - - /* - * Print the received UDP packet info - */ - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"recv UDP message from <%s>:<%d>, length=<%d>, " - "message=\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), remoteIPAddrStr, - util_get_port(&from), len); - CCSIP_DEBUG_MESSAGE_PKT(buf); - - /* - * Determine whether we want to process this packet - * Initially just do this if we are talking to CCM - can be expanded later - */ - - - - config_get_value(CFGID_P2PSIP, &p2psip, sizeof(p2psip)); - - if (p2psip == 0) { - if (sip_regmgr_get_cc_mode(1) == REG_MODE_CCM) { - accept_msg = SIPTaskCheckSource(from); - if (accept_msg != SIP_OK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIPTaskCheckSource() failed - Sender not " - "recognized\n", fname); - return SIP_ERROR; - } - } - } - - /* - * Convert to SIP representation - */ - pSipMessage = sippmh_message_create(); - if (!pSipMessage) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_message_create() failed\n", fname); - return SIP_ERROR; - } - - bytes_used = len; - - if (sippmh_process_network_message(pSipMessage, buf, &bytes_used) - == STATUS_FAILURE) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_process_network_message() " - "failed. discarding the message.\n", fname); - free_sip_message(pSipMessage); - return SIP_ERROR; - } - /* - * Add processing here to append received= to the first Via - * field if the IP address we received this message from is not the same - * as the IP address in the Via field or if it contains a domain name - */ - sippmh_process_via_header(pSipMessage, &ip_addr); - - ccsip_dump_recv_msg_info(pSipMessage, &ip_addr, 0); - - /* Process SIP message */ - SIPTaskProcessSIPMessage(pSipMessage); - return SIP_OK; -} - -/** - * - * SIPTaskProcessTCPMessage (Internal API) - * - * Process the received (via TCP) SIP message - * - * Parameters: msg - the message buffer - * len - length of the message buffer - * from - the source address for the message - * - * Return Value: SIP_OK if message could be processed (though this itself - * may fail) or SIP_ERROR - * - */ -void -SIPTaskProcessTCPMessage (sipMessage_t *pSipMessage, cpr_sockaddr_storage from) -{ - cpr_ip_addr_t ip_addr; - - CPR_IP_ADDR_INIT(ip_addr); - /* - * Convert IP address to string, for debugs - */ - util_extract_ip(&ip_addr, &from); - - /* - * Add processing here to append received= to the first Via - * field if the IP address we received this message from is not the same - * as the IP address in the Via field or if it contains a domain name - */ - sippmh_process_via_header(pSipMessage, &ip_addr); - - /* Process SIP message */ - SIPTaskProcessSIPMessage(pSipMessage); -} - -int -SIPTaskRetransmitPreviousResponse (sipMessage_t *pSipMessage, - const char *fname, - const char *pCallID, - sipCseq_t *sipCseq, - int response_code, - boolean is_request) -{ - sipRelDevMessageRecord_t *pRequestRecord = NULL; - int handle = -1; - const char *reldev_to = NULL; - const char *reldev_from = NULL; - sipLocation_t *reldev_to_loc = NULL; - sipLocation_t *reldev_from_loc = NULL; - - pRequestRecord = (sipRelDevMessageRecord_t *) - cpr_calloc(1, sizeof(sipRelDevMessageRecord_t)); - if (!pRequestRecord) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to allocate " - "mem for pRequestRecord.\n", fname); - return SIP_ERROR; - } - - // Copy to-tag - reldev_to = sippmh_get_cached_header_val(pSipMessage, TO); - if (reldev_to) { - reldev_to_loc = sippmh_parse_from_or_to((char *)reldev_to, TRUE); - if ((reldev_to_loc) && (reldev_to_loc->tag)) { - sstrncpy(pRequestRecord->tag, - sip_sm_purify_tag(reldev_to_loc->tag), - MAX_SIP_TAG_LENGTH); - } - - // Copy to-user - if (reldev_to_loc) { - sstrncpy(pRequestRecord->to_user, - reldev_to_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sippmh_free_location(reldev_to_loc); - } - } - - // Copy from-user and from-host - reldev_from = sippmh_get_cached_header_val(pSipMessage, FROM); - if (reldev_from) { - reldev_from_loc = sippmh_parse_from_or_to((char *)reldev_from, TRUE); - if (reldev_from_loc) { - sstrncpy(pRequestRecord->from_user, - reldev_from_loc->genUrl->u.sipUrl->user, - RELDEV_MAX_USER_NAME_LEN); - sstrncpy(pRequestRecord->from_host, - reldev_from_loc->genUrl->u.sipUrl->host, - RELDEV_MAX_HOST_NAME_LEN); - - sippmh_free_location(reldev_from_loc); - } - } - - pRequestRecord->is_request = is_request; - pRequestRecord->response_code = response_code; - - // Copy Call-id - sstrncpy(pRequestRecord->call_id, (pCallID) ? pCallID : "", - MAX_SIP_CALL_ID); - - // Copy CSeq values - pRequestRecord->cseq_method = sipCseq->method; - pRequestRecord->cseq_number = sipCseq->number; - - if (sipRelDevMessageIsDuplicate(pRequestRecord, &handle)) { - cpr_free(pRequestRecord); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Previous " - "Call ID. Resending stored " - "response...\n", DEB_F_PREFIX_ARGS(SIP_MSG, fname)); - if (sipRelDevCoupledMessageSend(handle) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipRelDevCoupledMessageSend(%d)" - "returned error.\n", fname, handle); - } - return SIP_OK; - } else { - cpr_free(pRequestRecord); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Previous Call " - "ID. Message not in reTx list.\n", DEB_F_PREFIX_ARGS(SIP_MSG, fname)); - } - return SIP_ERROR; -} - -/** - * - * SIPTaskProcessTimerExpiration - * - * Process a msg indicating a timer has expired - * - * Parameters: msg - the timer callback msg - * cmd - allows us to overwrite the cmd if needed - * - * Return Value: boolean, if true return as timer has been processed. - * - */ -short -SIPTaskProcessTimerExpiration (void *msg, uint32_t *cmd) -{ - static const char fname[] = "SIPTaskProcessTimerExpiration"; - cprCallBackTimerMsg_t *timerMsg; - boolean returnCode = TRUE; - uint32_t handle; - - timerMsg = (cprCallBackTimerMsg_t *) msg; - TMR_DEBUG(DEB_F_PREFIX"Timer %s expired. Id is %d\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname), - timerMsg->expiredTimerName, timerMsg->expiredTimerId); - - /* The REGALLFAIL Timer message could come in before the task has - * been initialized. Need to handle this timer, in order to restart - * the system. */ - if ((sip.taskInited == FALSE) && (timerMsg->expiredTimerId != SIP_REGALLFAIL_TIMER)) { - return returnCode; - } - - switch (timerMsg->expiredTimerId) { - case SIP_ACK_TIMER: - *cmd = SIP_TMR_REG_ACK; - returnCode = FALSE; - break; - - case SIP_WAIT_TIMER: - sip_regmgr_wait_timeout_expire(timerMsg->usrData); - break; - - case SIP_RETRY_TIMER: - sip_regmgr_retry_timeout_expire(timerMsg->usrData); - break; - - case SIP_MSG_TIMER: - *cmd = SIP_TMR_MSG_RETRY; - returnCode = FALSE; - break; - - case SIP_EXPIRES_TIMER: - *cmd = SIP_TMR_INV_EXPIRE; - returnCode = FALSE; - break; - - case SIP_REG_TIMEOUT_TIMER: - ccsip_register_timeout_retry(timerMsg->usrData); - break; - - case SIP_REG_EXPIRES_TIMER: - *cmd = SIP_TMR_REG_EXPIRE; - returnCode = FALSE; - break; - - case SIP_LOCAL_EXPIRES_TIMER: - *cmd = SIP_TMR_INV_LOCALEXPIRE; - returnCode = FALSE; - break; - - case SIP_SUPERVISION_TIMER: - *cmd = SIP_TMR_SUPERVISION_DISCONNECT; - returnCode = FALSE; - break; - - case SIP_GLARE_AVOIDANCE_TIMER: - *cmd = SIP_TMR_GLARE_AVOIDANCE; - returnCode = FALSE; - break; - - case SIP_KEEPALIVE_TIMER: - *cmd = SIP_TMR_STANDBY_KEEPALIVE; - returnCode = FALSE; - break; - - case SIP_UNREGISTRATION_TIMER: - sip_platform_unregistration_callback(timerMsg->usrData); - break; - - case SIP_SUBNOT_TIMER: - *cmd = SIP_TMR_MSG_RETRY_SUBNOT; - returnCode = FALSE; - break; - - case SIP_SUBNOT_PERIODIC_TIMER: - sip_platform_subnot_periodic_timer_callback(timerMsg->usrData); - break; - - case SIP_PUBLISH_RETRY_TIMER: - handle = (long)(timerMsg->usrData); - if (publish_handle_retry_timer_expire(handle) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"publish_handle_retry_timer_expire() " - "returned error.\n", fname); - } - break; - - case SIP_UNSOLICITED_TRANSACTION_TIMER: - subsmanager_unsolicited_notify_timeout(timerMsg->usrData); - break; - - case SIP_NOTIFY_TIMER: - sip_regmgr_notify_timer_callback(timerMsg->usrData); - break; - - case SIP_PASSTHROUGH_TIMER: - CCSIP_DEBUG_ERROR("%s: Pass Through Timer fired ! \n", fname); - break; - - case SIP_REGALLFAIL_TIMER: - sip_regmgr_regallfail_timer_callback(timerMsg->usrData); - break; - - default: - err_msg("%s: unknown timer %s\n", fname, timerMsg->expiredTimerName); - break; - } - return (returnCode); -} - - -/** - * - * SIPTaskProcessSIPMessage - * - * Process a received SIP message - * - * Parameters: pSipMessage - the SIP message - * - * Return Value: SIP_OK or SIP_ERROR - * - */ -static void -SIPTaskProcessSIPMessage (sipMessage_t *pSipMessage) -{ - static const char *fname = "SIPTaskProcessSIPMessage"; - sipSMEvent_t sip_sm_event; - ccsipCCB_t *reg_ccb = NULL,*ccb = NULL; - sipStatusCodeClass_t code_class = codeClassInvalid; - sipMethod_t method = sipMethodInvalid; - const char *pCallID = NULL; - line_t line_index = 1; - boolean is_request = FALSE; - int regConfigValue, response_code = 0; - int requestStatus = SIP_MESSAGING_ERROR; - char errortext[MAX_SIP_URL_LENGTH]; - const char *cseq = NULL; - sipCseq_t *sipCseq = NULL; - uint16_t result_code = 0; - const char *max_fwd_hdr = NULL; - int32_t max_fwd_hdr_val; - int rc; - char tmp_str[STATUS_LINE_MAX_LEN]; - sipSCB_t *scbp = NULL; - sipTCB_t *tcbp = NULL; - int scb_index; - //ccsip_event_data_t * evt_data_ptr = NULL; - - sip_sm_event.u.pSipMessage = pSipMessage; - /* - * is_complete will be FALSE if we received fewer bytes than - * specified in the content_length field. If that happens, we - * want to return a 400 Bad Request message. - */ - if (!sippmh_is_message_complete(pSipMessage)) { - /* Send 400 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_SDP_ERROR, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sippmh_is_message_complete()"); - return; - } - - /* - * Determine Type, Method, and Call ID of this SIP message - * If the SIP message is a response, also get the response code. - */ - is_request = sippmh_is_request(pSipMessage); - if (is_request) { - /* - * Check the value of the max-forwards header - if present - */ - max_fwd_hdr = sippmh_get_header_val(pSipMessage, - SIP_HEADER_MAX_FORWARDS, NULL); - if (max_fwd_hdr) { - max_fwd_hdr_val = sippmh_parse_max_forwards(max_fwd_hdr); - if (max_fwd_hdr_val < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid Max Fwd Value detected\n", - fname); - /* Send 483 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_MANY_HOPS, - SIP_CLI_ERR_MANY_HOPS_PHRASE, - SIP_WARN_MISC, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - return; - } - } - - sipGetRequestMethod(pSipMessage, &method); - - switch (method) { - case sipMethodInvalid: - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - /* Send 400 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_METHOD_UNKNOWN, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - return; - - case sipMethodUnknown: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP method not implemented\n", fname); - // Send 501 error - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_NOT_IMPLEM, - SIP_SERV_ERR_NOT_IMPLEM_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_NOT_IMPLEM); - } - free_sip_message(pSipMessage); - return; - - case sipMethodRegister: - case sipMethodPrack: - case sipMethodComet: - case sipMethodMessage: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"SIP method not allowed\n", fname); - // Send 405 error - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_NOT_ALLOWED, - SIP_CLI_ERR_NOT_ALLOWED_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_NOT_ALLOWED); - } - free_sip_message(pSipMessage); - return; - - default: - break; - } - } else { - if (sipGetResponseMethod(pSipMessage, &method) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseMethod"); - free_sip_message(pSipMessage); - return; - } - if (sipGetResponseCode(pSipMessage, &response_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipGetResponseCode"); - free_sip_message(pSipMessage); - return; - } - code_class = sippmh_get_code_class((uint16_t) response_code); - } - - /* Get the CSeq */ - cseq = sippmh_get_cached_header_val(pSipMessage, CSEQ); - if (!cseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to extract " - "CSeq from message.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - return; - } - sipCseq = sippmh_parse_cseq(cseq); - if (!sipCseq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to parse " - "CSeq from message.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ, - NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - free_sip_message(pSipMessage); - return; - } - - pCallID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!pCallID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.\n", fname); - /* - * Since we have no Call-ID, we can't create a response; - * therefore, we drop it. - */ - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - /* - * Unsolicited NOTIFY processing - */ - if ((is_request) && (method == sipMethodNotify)) { - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_NOTIFY); - rc = SIPTaskProcessSIPNotify(pSipMessage); - if (rc != SIP_DEFER) { - if (rc != 0) { - // This Notify is in response to a previous SUBSCRIBE or REFER - (void) subsmanager_handle_ev_sip_subscribe_notify(pSipMessage); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - - /* - * SUBSCRIBE processing. Subscription requests received from the network, - * are processed here and do not interact with the main call processing - * states. All SUBSCRIBE requests and responses are directed to the - * subscription manager. However NOTIFY responses need to be testes to - * see whether the NOTIFY request was generated via CC or SM - */ - if ((is_request) && (method == sipMethodSubscribe)) { - - config_get_value(CFGID_PROXY_REGISTER, ®ConfigValue, sizeof(regConfigValue)); - - reg_ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - - if ((regConfigValue == 0) || (reg_ccb && reg_ccb->reg.registered)) { - - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_SUBSCRIBE); - (void) subsmanager_handle_ev_sip_subscribe(pSipMessage, method, FALSE); - } else { - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - if (is_request == FALSE) { - switch (method) { - case sipMethodSubscribe: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Subs Response.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case sipMethodNotify: - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Notify response\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } else { - tcbp = find_tcb_by_sip_callid(pCallID); - if (tcbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Unsolicited Notify response\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_unsolicited_notify_response(pSipMessage, tcbp); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - break; - - case sipMethodPublish: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv PUBLISH Response.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) publish_handle_ev_sip_response(pSipMessage); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case sipMethodInfo: - // XXX FIXME see the comments in sipSPISendInfo() - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv INFO Response (silently dropped).\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - default: - break; - - } - } - - - /* - * Determine which line this SIP message is for. - */ - result_code = sip_sm_determine_ccb(pCallID, sipCseq, pSipMessage, - is_request, &ccb); - if (result_code != 0) { - if (is_request) { - if (result_code == SIP_CLI_ERR_LOOP_DETECT) { - /* Send 482 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_LOOP_DETECT, - SIP_CLI_ERR_LOOP_DETECT_PHRASE, - SIP_WARN_MISC, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_LOOP_DETECT); - } - } else { - /* Send 400 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - } - } else { //is response - // This may be a response for a request generated via sub/not i/f - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Refer Response.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_determine_ccb(): " - "bad response. Dropping message.\n", fname); - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - if (ccb) { - sip_sm_event.ccb = ccb; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match: Destination line = " - "<%d/%d>.\n", DEB_F_PREFIX_ARGS(SIP_ID, fname), ccb->index, ccb->dn_line); - - } else { - - boolean is_previous_call_id = FALSE; - line_t previous_call_index = 0; - - /* - * Unsolicited options processing - */ - if ((is_request) && (method == sipMethodOptions)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"recv SIP OPTIONS (outside of dialog) message.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); // - /* - * Send an options request to the gsm for this out of call - * options request. pSipMessage will be freed on return. - */ - sip_cc_options(CC_NO_CALL_ID, CC_NO_LINE, pSipMessage); - cpr_free(sipCseq); - return; - } - - /* - * Unsolicited INFO processing - */ - if ((is_request) && (method == sipMethodInfo)) { - CCSIP_DEBUG_ERROR("%s: Error: recv out-of-dialog SIP INFO message.\n", fname); // - /* Send 481 Call Leg/Transaction Does Not Exist */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_NOT_ALLOWED); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - - /* + If this is a request and method is INVITE, obtain - * the next available line and forward the request to - * that state machine. This is a new incoming call. - * + Otherwise, this message is spurious -- reject it. - * Do not accept an incoming INVITE for a new call - * if in quiet mode - */ - is_previous_call_id = sip_sm_is_previous_call_id(pCallID, - &previous_call_index); - if ((method == sipMethodInvite) && (is_request)) { - if (sip_mode_quiet) { - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_NOT_AVAIL, - SIP_CLI_ERR_NOT_AVAIL_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_NOT_AVAIL); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - else if (cprGetDepth(gsm_msgq) > MAX_DEPTH_OF_GSM_MSGQ_TO_ALLOW_NEW_INCOMING_CALL) { - /* - * CSCsz33584 - * if gsm_msgq depth is larger than MAX_DEPTH_OF_GSM_MSGQ_TO_ALLOW_NEW_INCOMING_CALL, - * it's risky to accept new incoming call. - * just ignore the INVITE message to save CPU time so that the messages in gsm_msgq can be processed faster. - */ - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"gsm msgq depth too large, drop incoming INVITEs!!!\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - ccb = sip_sm_get_ccb_next_available(&line_index); - if (!ccb) { - /* All lines are busy. Return 486 BUSY */ - if (platGetPhraseText(STR_INDEX_NO_FREE_LINES, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1) == CPR_SUCCESS) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match not " - "found: INVITE: %s\n Sending 486 BUSY\n", - DEB_F_PREFIX_ARGS(SIP_ID, fname), tmp_str); - } - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BUSY_HERE, - SIP_CLI_ERR_BUSY_HERE_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BUSY_HERE); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - sip_sm_event.ccb = ccb; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match not " - "found: INVITE: free ccb index = %d.\n", - DEB_F_PREFIX_ARGS(SIP_ID, fname), line_index); - - } else if (is_previous_call_id && (method != sipMethodAck) && - is_request) { - /* - * Detect whether the message is a non-ACK request addressing the - * previous call. If so, reTx the stored response. - */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Previous Call ID.\n", - DEB_F_PREFIX_ARGS(SIP_ID, fname)); - if (SipRelDevEnabled) { - if (SIPTaskRetransmitPreviousResponse(pSipMessage, fname, - pCallID, sipCseq, 0, TRUE) == SIP_OK) { - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Previous Call ID. " - "Reliable Delivery is OFF.\n", DEB_F_PREFIX_ARGS(SIP_ID, fname)); - } - - if (method == sipMethodBye) { - (void) sipSPISendErrorResponse(pSipMessage, 200, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL); - } else { - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, NULL); - } - - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } else if (is_previous_call_id && (method == sipMethodAck) && - is_request) { - /* - * Detect whether the message is an ACK addressing the previous - * call. If so, stop any outstanding reTx timers. - */ - if (SipRelDevEnabled) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Stopping any outstanding " - "reTx timers...\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname)); - sip_sm_check_retx_timers(sip_sm_get_ccb_by_index(previous_call_index), - pSipMessage); - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Not forwarding response to SIP SM.\n", - DEB_F_PREFIX_ARGS(SIP_FWD, fname)); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } else if (is_previous_call_id && (!is_request)) { - /* - * Detect whether the message is a response addressing the previous - * call. If the request is 200 OK, stop any outstanding reTx timers. - * This will prevent extraneous reTx of BYE/CANCEL messages at the - * the end of the call. - */ - if (SipRelDevEnabled) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Stopping any outstanding " - "reTx timers...\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname)); - sip_sm_check_retx_timers(sip_sm_get_ccb_by_index(previous_call_index), - pSipMessage); - // Check for stored responses - if (SIPTaskRetransmitPreviousResponse(pSipMessage, fname, - pCallID, sipCseq, - response_code, FALSE) == SIP_OK) { - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Not forwarding response to SIP SM.\n", - DEB_F_PREFIX_ARGS(SIP_FWD, fname)); - - if (method == sipMethodBye) { - SIPTaskProcessSIPPreviousCallByeResponse(pSipMessage, - response_code, - previous_call_index); - } - if (method == sipMethodInvite) { - SIPTaskProcessSIPPreviousCallInviteResponse(pSipMessage, - response_code, - previous_call_index); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - } else { - if (method == sipMethodRefer) { - if (is_request) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received OOD Refer.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - if (subsmanager_handle_ev_sip_subscribe(pSipMessage, sipMethodRefer, FALSE) != SIP_ERROR) { - // Successfully handled - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Successfully handled OOD Refer.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Not able to handle OOD Refer.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - } - } else { - // This is a response to an OOD REFER generated via sub/not - // interface - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Refer Response\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - } - } - } else { - if (SipRelDevEnabled) { - // Check for stored responses - if (SIPTaskRetransmitPreviousResponse(pSipMessage, fname, - pCallID, sipCseq, - response_code, - FALSE) == SIP_OK) { - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match not " - "found: Rejecting.\n", DEB_F_PREFIX_ARGS(SIP_ID, fname)); - if (is_request && (method != sipMethodAck)) { - /* Send 481 error */ - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_CALLEG, - SIP_CLI_ERR_CALLEG_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_CALLEG); - } - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } - - if (is_request) { - /* - * Process request - */ - requestStatus = sipSPICheckRequest(ccb, pSipMessage); - switch (requestStatus) { - case SIP_MESSAGING_OK: - break; - - case SIP_MESSAGING_NEW_CALLID: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() returned " - "SIP_MESSAGING_NEW_CALLID.\n", fname); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_CLI_ERR_FORBIDDEN: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() returned " - "SIP_CLI_ERR_FORBIDDEN.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_FORBIDDEN, - SIP_CLI_ERR_FORBIDDEN_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_FORBIDDEN); - } - - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_MESSAGING_DUPLICATE: - if (method == sipMethodInvite) { - char test_mac[MAC_ADDR_STR_LENGTH]; - uint8_t mac_addr[MAC_ADDRESS_LENGTH]; - - platform_get_wired_mac_address(mac_addr); - - /* - * See if the call id has our mac address in it. - * If so, then we called ourselves. Report back busy. - */ - snprintf(test_mac, MAC_ADDR_STR_LENGTH, "%.4x%.4x-%.4x", - mac_addr[0] * 256 + mac_addr[1], - mac_addr[2] * 256 + mac_addr[3], - mac_addr[4] * 256 + mac_addr[5]); - if ((ccb->state == SIP_STATE_SENT_INVITE) && - (strncmp(test_mac, ccb->sipCallID, 13) == 0)) { - get_sip_error_string(errortext, SIP_CLI_ERR_BUSY_HERE); - (void) sipSPISendErrorResponse(pSipMessage, - SIP_CLI_ERR_BUSY_HERE, - errortext, 0, NULL, NULL); - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_SERV_ERR_INTERNAL: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() returned " - "SIP_SERV_ERR_INTERNAL.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_SERV_ERR_INTERNAL, - SIP_SERV_ERR_INTERNAL_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_CLI_ERR_BAD_REQ: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() returned " - "SIP_CLI_ERR_BAD_REQ.\n", fname); - if (sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - - case SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA: - default: - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckRequest() " - "returned error.\n", fname); - /* Send error response */ - if (method != sipMethodAck) { - if (requestStatus == SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA) { - requestStatus = SIP_CLI_ERR_MEDIA; - } else if (requestStatus == SIP_MESSAGING_ENDPOINT_NOT_FOUND) { - requestStatus = SIP_CLI_ERR_NOT_FOUND; - } else if (requestStatus == SIP_MESSAGING_NOT_ACCEPTABLE) { - requestStatus = SIP_CLI_ERR_NOT_ACCEPT; - } else if (requestStatus != SIP_CLI_ERR_CALLEG) { - requestStatus = 400; - } - get_sip_error_string(errortext, requestStatus); - if (sipSPISendErrorResponse(pSipMessage, (uint16_t)requestStatus, - errortext, 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_CLI_ERR_BAD_REQ); - } - if (method == sipMethodInvite) { - ccb->wait_for_ack = TRUE; - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - switch (method) { - case sipMethodInvite: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_INVITE); - sip_sm_event.type = E_SIP_INVITE; - break; - - case sipMethodAck: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_ACK); - sip_sm_check_retx_timers(ccb, pSipMessage); - sip_sm_event.type = E_SIP_ACK; - break; - - case sipMethodBye: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_BYE); - sip_sm_event.type = E_SIP_BYE; - break; - - case sipMethodCancel: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_CANCEL); - sip_sm_event.type = E_SIP_CANCEL; - break; - - case sipMethodSubscribe: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_SUBSCRIBE); - sip_sm_event.type = E_SIP_SUBSCRIBE; - break; - - case sipMethodNotify: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_NOTIFY); - sip_sm_event.type = E_SIP_NOTIFY; - break; - - case sipMethodRefer: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_REFER); - sip_sm_event.type = E_SIP_REFER; - break; - case sipMethodOptions: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_OPTIONS); - sip_sm_event.type = E_SIP_OPTIONS; - break; - case sipMethodUpdate: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_UPDATE); - sip_sm_event.type = E_SIP_UPDATE; - break; - case sipMethodInfo: - CCSIP_DEBUG_TASK(get_debug_string(DEBUG_SIP_MSG_RECV), - fname, SIP_METHOD_INFO); - (void) ccsip_handle_info_package(ccb, pSipMessage); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - break; - default: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received unknown SIP request message.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - /* The message must be deallocated here */ - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - } else { - int responseStatus = SIP_MESSAGING_ERROR; - - /* - * Process response - */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Received SIP response.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - responseStatus = sipSPICheckResponse(ccb, pSipMessage); - if (responseStatus != SIP_MESSAGING_OK) { - if (responseStatus == SIP_MESSAGING_DUPLICATE) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Duplicate response detected. " - "Discarding...\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - } else if (responseStatus == SIP_MESSAGING_ERROR_STALE_RESP) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Stale response detected. " - "Discarding...\n", DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - } else if (responseStatus == SIP_MESSAGING_ERROR_NO_TRX) { - // This may be a response for a request generated via sub/not i/f - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Refer Response.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - (void) subsmanager_handle_ev_sip_response(pSipMessage); - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPICheckResponse() " - "returned error. Discarding response\n", - fname); - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - /* Response is ok. Cancel the outstanding reTx timer if any */ - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Stopping any outstanding reTx " - "timers...\n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname)); - sip_sm_check_retx_timers(ccb, pSipMessage); - - /* got a response, re-set re-transmit flag */ - ccb->retx_flag = FALSE; - ccb->last_recvd_response_code = response_code; - /* - * TEL_CCB_START equates to zero and line_t is an unsigned type, - * so just check the end condition - */ - if (ccb->index <= TEL_CCB_END) { - gCallHistory[ccb->index].last_rspcode_rcvd = code_class; - } - - switch (code_class) { - case codeClass1xx: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv 1xx message.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - sip_sm_event.type = E_SIP_1xx; - break; - - case codeClass2xx: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv 2xx message.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - sip_sm_event.type = E_SIP_2xx; - break; - - case codeClass3xx: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv 3xx message.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - sip_sm_event.type = E_SIP_3xx; - break; - - case codeClass4xx: - case codeClass5xx: - case codeClass6xx: - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv 4xx/5xx/6xx message.\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname)); - sip_sm_event.type = E_SIP_FAILURE_RESPONSE; - switch (response_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - if (sipCseq->method == sipMethodAck) { - sipSPISendFailureResponseAck(ccb, pSipMessage, FALSE, 0); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - break; - - default: - break; - } - break; - - default: - /* unknown response, keep re-transmitting */ - ccb->retx_flag = TRUE; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unknown response class.\n", fname); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - // Change the event type for the UPDATE method since there is only one - // handler for this - if (method == sipMethodUpdate) { - sip_sm_event.type = E_SIP_UPDATE_RESPONSE; - } - } - - /* - * Send event to the SIP SM or the SIP REGISTRATION SM - */ - if (sip_sm_event.ccb->type == SIP_REG_CCB) { - sip_sm_event.type = (sipSMEventType_t) - ccsip_register_sip2sipreg_event(sip_sm_event.type); - - if ((!is_request) && ((code_class == codeClass5xx) || - (code_class == codeClass6xx))) { - sip_sm_event.type = (sipSMEventType_t) E_SIP_REG_FAILURE_RESPONSE; - } - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Register response does not have a body %d\n", - DEB_F_PREFIX_ARGS(SIP_MSG_RECV, fname), - (pSipMessage->mesg_body[0].msgBody == NULL) ? -1: pSipMessage->mesg_body[0].msgContentTypeValue); - - if (sip_sm_event.type != (int) E_SIP_REG_NONE) { - if (sip_reg_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(REG_SM_PROCESS_EVENT_ERROR), fname, sip_sm_event.type); - if (is_request && (method != sipMethodAck)) { - /* Send 500 error */ - if (sipSPISendErrorResponse(pSipMessage, 500, - SIP_SERV_ERR_INTERNAL_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } else { - cpr_free(sipCseq); - return; - } - } - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Ignoring non-register event= %d\n", - DEB_F_PREFIX_ARGS(SIP_EVT, fname), sip_sm_event.type); - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - if (sip_sm_process_event(&sip_sm_event) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_sm_process_event() returned " - "error.\n", fname); - if (is_request && (method != sipMethodAck)) { - /* Send 500 error */ - if (sipSPISendErrorResponse(pSipMessage, 500, - SIP_SERV_ERR_INTERNAL_PHRASE, 0, - NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SERV_ERR_INTERNAL); - } - } - cpr_free(sipCseq); - free_sip_message(pSipMessage); - return; - } - - cpr_free(sipCseq); -} - -/** - * - * SIPTaskProcessConfigChangeNotify - * - * ??? - * - * Parameters: ??? - * - * Return Value: zero(0) - * - */ -int -SIPTaskProcessConfigChangeNotify (int32_t notify_type) -{ - static const char *fname = "SIPTaskProcessConfigChangeNotify"; - int retval = 0; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Notify received type=%d\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), notify_type); - - if (notify_type & AA_RELOAD) { - if ((PHNGetState() == STATE_CONNECTED) || - (PHNGetState() == STATE_UNPROVISIONED)) { - /* - * If the phone state isn't in STATE_CONNECTED then this change - * notify is being called because of bootup and not just a SIP - * menu configuration hang. We only want to handle updates - * to the number of lines if the phone is already connected, - * the other case, booting, is handled by the boot code - */ - (void) sipTransportInit(); - - /* need to unregister the phone */ - ccsip_register_cancel(FALSE, TRUE); - ccsip_register_reset_proxy(); - (void) sip_platform_ui_restart(); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"PHNGetState() is not in STATE_CONNECTED, " - "bypassing restart\n", fname); - } - } else if (notify_type & AA_REGISTER) { - ccsip_register_commit(); - } else if (notify_type & AA_BU_REG) { - (void) sipTransportInit(); - ccsip_backup_register_commit(); - } - - return (retval); -} - - - -/** - * - * SIPTaskProcessSIPNotify - * - * The function processes the unsolicited NOTIFY. - * - * Parameters: pSipMessage - pointer to sipMessage_t. - * - * Return Value: SIP_OK, SIP_ERROR, SIP_DEFER. - * - * Note: The parameter pSipMessage is expected by the caller to be - * preserved i.e. it can not be freed by this - * function or the functions called by this function. - */ -static int -SIPTaskProcessSIPNotify (sipMessage_t *pSipMessage) -{ - static const char *fname = "SIPTaskProcessSIPNotify"; - sipReqLine_t *requestURI = NULL; - char *pRequestURIUserStr = NULL; - boolean request_uri_error = TRUE; - line_t i = 0; - line_t dn_line = 0; - const char *event = NULL; - sipLocation_t *uri_loc = NULL; - char line_name[MAX_LINE_NAME_SIZE]; - char line_contact[MAX_LINE_CONTACT_SIZE]; - const char *to = NULL; - sipLocation_t *to_loc = NULL; - sipUrl_t *sipToUrl = NULL; - boolean to_header_error = TRUE; - char *pUser = NULL; - - - /* - * Parse the Event header - */ - event = sippmh_get_header_val(pSipMessage, SIP_HEADER_EVENT, - SIP_C_HEADER_EVENT); - - if (event == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Missing Event header\n", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL); - return SIP_OK; - } - - /* - * Find the destination DN - */ - requestURI = sippmh_get_request_line(pSipMessage); - if (requestURI) { - if (requestURI->url) { - uri_loc = sippmh_parse_from_or_to(requestURI->url, TRUE); - if (uri_loc) { - if (uri_loc->genUrl->schema == URL_TYPE_SIP) { - if (uri_loc->genUrl->u.sipUrl->user) { - pRequestURIUserStr = uri_loc->genUrl->u.sipUrl->user; - request_uri_error = FALSE; - } else { - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - } else { - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - } else { - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - } else { - SIPPMH_FREE_REQUEST_LINE(requestURI); - } - } - - if (request_uri_error) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"NOTIFY has error in Req-URI!\n", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_REQLINE_ERROR, NULL); - return SIP_OK; - } - - if (cpr_strncasecmp(event, "refer", 5) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: refer\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - SIPTaskProcessSIPNotifyRefer(pSipMessage); - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_OK; - } - - for (i = 1; i <= 1; i++) { - if (sip_config_check_line(i)) { - config_get_string((CFGID_LINE_NAME + i - 1), line_name, sizeof(line_name)); - config_get_string((CFGID_LINE_CONTACT + i - 1), line_contact, sizeof(line_contact)); - if ((sippmh_cmpURLStrings(pRequestURIUserStr, line_name, TRUE) == 0) || - (sippmh_cmpURLStrings(pRequestURIUserStr, line_contact, TRUE) == 0)) { - dn_line = i; - break; - } - } - } - - if (dn_line == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"NOTIFY has unknown user in Req-URI!\n", - fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_NOT_FOUND, - SIP_CLI_ERR_NOT_FOUND_PHRASE, - 0, NULL, NULL); - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - return SIP_OK; - } - - sippmh_free_location(uri_loc); - SIPPMH_FREE_REQUEST_LINE(requestURI); - - /* - * Sanity check To header by parsing the header. Note it is not used, just sanitized. - */ - to = sippmh_get_cached_header_val(pSipMessage, TO); - if (to) { - to_loc = sippmh_parse_from_or_to((char *)to, TRUE); - if (to_loc) { - if (to_loc->genUrl->schema == URL_TYPE_SIP) { - sipToUrl = to_loc->genUrl->u.sipUrl; - if (sipToUrl) { - if (sipToUrl->user) { - pUser = sippmh_parse_user(sipToUrl->user); - if (pUser) { - if (pUser[0] != '\0') { - // To header is good. - to_header_error = FALSE; - } - cpr_free(pUser); - } - } - } - sippmh_free_location(to_loc); - } else { - sippmh_free_location(to_loc); - } - } - } - - if (to_header_error) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"NOTIFY has error in To header\n", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - SIP_CLI_ERR_BAD_REQ_ToURL_ERROR, NULL); - return SIP_OK; - } - - /* - * Request-URI and To header check out. Check Event to determine which - * Notify function to invoke. - */ - if ((cpr_strcasecmp(event, "message-summary") == 0) || - (cpr_strcasecmp(event, "simple-message-summary") == 0)) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: MWI\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - if (SIPTaskProcessSIPNotifyMWI(pSipMessage, dn_line) != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad MWI NOTIFY!\n", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - SIP_WARN_MISC, - "Bad MWI NOTIFY", NULL); - return SIP_OK; - } - } else if (cpr_strcasecmp(event, "check-sync") == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: check-sync\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - SIPTaskProcessSIPNotifyCheckSync(pSipMessage); - } else if (cpr_strcasecmp(event, "service-control") == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: service-control\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - return SIPTaskProcessSIPNotifyServiceControl(pSipMessage); - } else if (cpr_strcasecmp(event, SIP_EVENT_DIALOG) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: %s\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), SIP_EVENT_DIALOG); - return (2); - } else if (cpr_strcasecmp(event, SIP_EVENT_CONFIG) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: %s\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), SIP_EVENT_CONFIG); - return (2); - } else if (cpr_strcasecmp(event, SIP_EVENT_KPML) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: %s\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), SIP_EVENT_KPML); - return (2); - } else if (cpr_strcasecmp(event, SIP_EVENT_PRESENCE) == 0) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"NOTIFY: %s\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname), SIP_EVENT_PRESENCE); - return (2); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unrecognized Event header\n", fname); - (void) sipSPISendErrorResponse(pSipMessage, SIP_CLI_ERR_BAD_REQ, - SIP_CLI_ERR_BAD_REQ_PHRASE, - 0, NULL, NULL); - } - - return SIP_OK; -} - -/** - * - * SIPTaskProcessSIPNotifyMWI - * - * ??? - * - * Parameters: ??? - * - * Return Value: SIP_OK or SIP_ERROR - * - */ -static int -SIPTaskProcessSIPNotifyMWI (sipMessage_t* pSipMessage, line_t dn_line) -{ - sipMessageSummary_t mesgSummary; - - if (!pSipMessage->mesg_body[0].msgBody || - (pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_MWI_VALUE && - pSipMessage->mesg_body[0].msgContentTypeValue != SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE)) { - return SIP_ERROR; - } - - memset(&mesgSummary, 0, sizeof(sipMessageSummary_t)); - - if (sippmh_parse_message_summary(pSipMessage, &mesgSummary) < 0) { - return SIP_ERROR; - } - - sip_cc_mwi(CC_NO_CALL_ID, dn_line, mesgSummary.mesg_waiting_on, mesgSummary.type, - mesgSummary.newCount, mesgSummary.oldCount, mesgSummary.hpNewCount, mesgSummary.hpOldCount); - - /* - * Send 200 OK back - */ - (void) sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL); - - return SIP_OK; -} -/** - * - * SIPTaskProcessSIPNotifyRefer - * - * The function processes NOTIFY refer. - * - * Parameters: pSipMessage - pointer to the sipMessage_t. - * - * Return Value: None - * - */ -static void -SIPTaskProcessSIPNotifyRefer (sipMessage_t *pSipMessage) -{ - static const char *fname = "SIPTaskProcessSIPNotifyRefer"; - ccsipCCB_t *ccb = NULL; - const char *pCallID = NULL; - sipSCB_t *scbp = NULL; - int scb_index; - - pCallID = sippmh_get_cached_header_val(pSipMessage, CALLID); - if (!pCallID) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.\n", fname); - return; - } - - /* - * Determine which line this SIP message is for. - */ - ccb = sip_sm_get_ccb_by_callid(pCallID); - if (ccb) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Line filter: Call ID match: Destination line = " - "<%d/%d>.\n", DEB_F_PREFIX_ARGS(SIP_ID, fname), ccb->index, ccb->dn_line); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccb is NULL\n", fname); - // Check if this should be sent to the SM by looking up its callid - // If found, the we return from here - scbp = find_scb_by_callid(pCallID, &scb_index); - if (scbp != NULL) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Recv Notify.\n", DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - (void) subsmanager_handle_ev_sip_subscribe_notify(pSipMessage); - return; - } - } - (void) sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL); - - if (NULL != ccb) { - cc_feature_data_t data; - - /* for some reason pingtel decided they were going to send - * Notify messages with call progression in the body. Let's - * just send the 200 back for these and not process them. - * We should only process a Notify with a final response - * in the body (ie. 200, 3xx, 4xx, 5xx, 6xx). - */ - if (pSipMessage->mesg_body[0].msgBody == NULL) { - data.notify.cause = CC_CAUSE_OK; - - if (fsmxfr_get_xcb_by_call_id(ccb->gsm_id) && - (fsmxfr_get_xfr_type(ccb->gsm_id) == FSMXFR_TYPE_BLND_XFR)) { - data.notify.cause = CC_CAUSE_ERROR; - data.notify.method = CC_XFER_METHOD_REFER; - } - } else if ((strstr(pSipMessage->mesg_body[0].msgBody, "100")) || - (strstr(pSipMessage->mesg_body[0].msgBody, "180")) || - (strstr(pSipMessage->mesg_body[0].msgBody, "181")) || - (strstr(pSipMessage->mesg_body[0].msgBody, "182")) || - (strstr(pSipMessage->mesg_body[0].msgBody, "183"))) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Ignoring Notify w/Progression\n", - DEB_F_PREFIX_ARGS(SIP_NOTIFY, fname)); - return; - } else if (strstr(pSipMessage->mesg_body[0].msgBody, "200")) { - data.notify.cause = CC_CAUSE_OK; - data.notify.method = CC_XFER_METHOD_REFER; - } else { - data.notify.cause = CC_CAUSE_ERROR; - data.notify.method = CC_XFER_METHOD_REFER; - } - data.notify.subscription = CC_SUBSCRIPTIONS_XFER; - data.notify.blind_xferror_gsm_id = 0; - sip_cc_feature(ccb->gsm_id, ccb->dn_line, CC_FEATURE_NOTIFY, - (void *)&data); - } -} - - -/** - * - * SIPTaskProcessSIPNotifyCheckSync - * - * ??? - * - * Parameters: pSipMessage - - * - * Return Value: None - * - */ -static void -SIPTaskProcessSIPNotifyCheckSync (sipMessage_t *pSipMessage) -{ - /* - * Send 200 OK back - */ - (void) sipSPISendErrorResponse(pSipMessage, 200, SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL); -} - -/** - * - * SIPTaskProcessSIPNotifyServiceControl - * - * Handles an incoming unsolicited NOTIFY service control message - * - * Parameters: Incoming pSipMessage - * - * Return Value: SIP_OK if request processed. - * SIP_DEFER if request is deferred for processing - * by ccsip_core.c. - * - */ -static int -SIPTaskProcessSIPNotifyServiceControl (sipMessage_t *pSipMessage) -{ - const char *fname = "SIPTaskProcessSIPNotifyServiceControl"; - sipServiceControl_t *scp; - int rc = SIP_OK; - - scp = ccsip_get_notify_service_control(pSipMessage); - - if (scp != NULL) { - // The platform code should not alter scp or its fields - if (scp->action == SERVICE_CONTROL_ACTION_CALL_PRESERVATION) { - rc = SIP_DEFER; - } else { - if (sipSPISendErrorResponse(pSipMessage, 200, - SIP_SUCCESS_SETUP_PHRASE, - 0, NULL, NULL) != TRUE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_SPI_SEND_ERROR), - fname, SIP_SUCCESS_SETUP); - } - - // Hand over the event to platform - sip_platform_handle_service_control_notify(scp); - } - sippmh_free_service_control_info(scp); - } - - return rc; -} - -/** - * - * SIPTaskProcessSIPPreviousCallByeResponse - * - * ??? - * - * Parameters: pResponse - - * response_code - - * previous_call_index - - * - * Return Value: None - * - */ -static void -SIPTaskProcessSIPPreviousCallByeResponse (sipMessage_t *pResponse, - int response_code, - line_t previous_call_index) -{ - static const char *fname = "SIPTaskProcessSIPPreviousCallByeResponse"; - uint32_t responseCSeqNumber = 0; - sipMethod_t responseCSeqMethod = sipMethodInvalid; - boolean bad_authentication = FALSE; - credentials_t credentials; - sipAuthenticate_t authen; - const char *authenticate = NULL; - int nc_count = 0; - - memset(&authen, 0, sizeof(authen)); // Initialize - - switch (response_code) { - case SIP_CLI_ERR_UNAUTH: - case SIP_CLI_ERR_PROXY_REQD: - /* Check CSeq */ - if (sipGetMessageCSeq(pResponse, &responseCSeqNumber, - &responseCSeqMethod) < 0) { - return; - } - if (responseCSeqNumber != - gCallHistory[previous_call_index].last_bye_cseq_number) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"CSeq# mismatch: BYE CSeq=%d, " - "%d CSeq:%d\n", fname, - gCallHistory[previous_call_index].last_bye_cseq_number, - response_code, responseCSeqNumber); - return; - } - - /* Obtain credentials */ - cred_get_line_credentials(gCallHistory[previous_call_index].dn_line, - &credentials, - sizeof(credentials.id), - sizeof(credentials.pw)); - /* Compute Authentication information */ - authenticate = sippmh_get_header_val(pResponse, - AUTH_HDR(response_code), NULL); - if (authenticate != NULL) { - sip_authen_t *sip_authen = NULL; - - sip_authen = sippmh_parse_authenticate(authenticate); - if (sip_authen) { - char *author_str = NULL; - - if (sipSPIGenerateAuthorizationResponse(sip_authen, - gCallHistory[previous_call_index]. - last_route_request_uri, - SIP_METHOD_BYE, - credentials.id, - credentials.pw, - &author_str, - &nc_count, NULL)) { - if (author_str != NULL) - { - authen.authorization = (char *) - cpr_malloc(strlen(author_str) * sizeof(char) + 1); - if (authen.authorization != NULL) { - sstrncpy(authen.authorization, author_str, - strlen(author_str) * sizeof(char) + 1); - authen.status_code = response_code; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc() failed " - "for authen.authorization\n", fname); - bad_authentication = TRUE; - } - cpr_free(author_str); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"author_str returned by sipSPIGenerateAuthorizationResponse" - "is NULL", fname); - bad_authentication = TRUE; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sipSPIGenerateAuthorizationResponse()" - " returned null.\n", fname); - bad_authentication = TRUE; - } - sippmh_free_authen(sip_authen); - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_parse_authenticate() " - "returned null.\n", fname); - bad_authentication = TRUE; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_get_header_val(AUTH_HDR) " - "returned null.\n", fname); - bad_authentication = TRUE; - } - - if (bad_authentication) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Bad authentication header " - "in %d\n", fname, response_code); - if (authen.authorization) - cpr_free(authen.authorization); - return; - } - - /* Resend BYE with authorization */ - (void) sipSPISendByeAuth(pResponse, - authen, - &(gCallHistory[previous_call_index].last_bye_dest_ipaddr), - gCallHistory[previous_call_index].last_bye_dest_port, - ++gCallHistory[previous_call_index].last_bye_cseq_number, - gCallHistory[previous_call_index].last_bye_also_string, - gCallHistory[previous_call_index].last_route, - gCallHistory[previous_call_index].last_route_request_uri, - previous_call_index); - if (authen.authorization) { - cpr_free(authen.authorization); - } - break; - - default: - break; - } -} - -/** - * - * SIPTaskProcessSIPPreviousCallInviteResponse - * - * ??? - * - * Parameters: pResponse - - * response_code - - * previous_call_index - - * - * Return Value: None - * - */ -static void -SIPTaskProcessSIPPreviousCallInviteResponse (sipMessage_t *pResponse, - int response_code, - line_t previous_call_index) -{ - static const char *fname = "SIPTaskProcessSIPPreviousCallInviteResponse"; - uint32_t responseCSeqNumber = 0; - sipMethod_t responseCSeqMethod = sipMethodInvalid; - - if ((response_code >= SIP_CLI_ERR_BAD_REQ) && (response_code < 700)) { - /* Check CSeq */ - if (sipGetMessageCSeq(pResponse, &responseCSeqNumber, - &responseCSeqMethod) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED), - fname, "Invalid CSeq"); - return; - } - if (responseCSeqNumber != - gCallHistory[previous_call_index].last_bye_cseq_number) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Last Bye CSeq=%d, Failure Code = %d, " - "CSeq:%d\n", fname, - gCallHistory[previous_call_index].last_bye_cseq_number, - response_code, responseCSeqNumber); - return; - } - - /* Send ACK */ - sipSPISendFailureResponseAck(NULL, pResponse, TRUE, previous_call_index); - - } -} - -void -SIPTaskPostRestart (boolean restart) -{ - ccsip_restart_req *msg; - static const char fname[] = "SIPTaskPostRestart"; - - msg = (ccsip_restart_req *) SIPTaskGetBuffer(sizeof(ccsip_restart_req)); - if (msg == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to allocate IPC msg ccip_restart_req\n", fname); - return; - } - if (restart) { - /* This is a restart request from the platform */ - msg->cmd = SIP_RESTART_REQ_RESTART; - } else { - /* This is a re-init request from the platform */ - msg->cmd = SIP_RESTART_REQ_REINIT; - } - /* send a restart message to the SIP Task */ - if (SIPTaskSendMsg(SIP_RESTART, (cprBuffer_t)msg, - sizeof(ccsip_restart_req), NULL) == CPR_FAILURE) { - cpr_free(msg); - } - return; -} - -static void -SIPTaskProcessRestart (ccsip_restart_cmd cmd) -{ - static const char fname[] = "SIPTaskProcessRestart"; - - if (cmd == SIP_RESTART_REQ_RESTART) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Starting Restart Process\n", - DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - - /* Restart SIP task */ - sip_restart(); - } else if (cmd == SIP_RESTART_REQ_REINIT) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Starting Re-init Process\n", - DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - - // Re-initialize the various components - SIPTaskReinitialize(FALSE); - - /* Clear the quite mode */ - sip_mode_quiet = FALSE; - } -} - -/* - * If checkConfig is 0/FALSE, process as a config change without checking - */ -void -SIPTaskReinitialize (boolean checkConfig) -{ - static const char fname[] = "SIPTaskReinitialize"; - - // Initialize all GSM modules - cc_fail_fallback_gsm(CC_SRC_SIP, CC_RSP_COMPLETE, CC_REG_FAILOVER_RSP); - - // If the config has changed, or if the check is being bypassed, re-init reg-mgr - if ( !checkConfig || sip_regmgr_check_config_change() ) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Config change detected: Restarting\n", - DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - sip_regmgr_process_config_change(); - return; - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"No config change detected\n", - DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - } -} - -void -SIPTaskPostShutdown (int action, int reason, const char *reasonInfo) -{ - ccsip_shutdown_req_t *msg; - static const char fname[] = "SIPTaskPostShutdown"; - - msg = (ccsip_shutdown_req_t *) SIPTaskGetBuffer(sizeof(ccsip_shutdown_req_t)); - if (msg == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to allocate IPC msg SIP_SHUTDOWN_REQ_SHUT\n", fname); - return; - } - msg->cmd = SIP_SHUTDOWN_REQ_SHUT; - msg->action = action; - msg->reason = reason; - if (reasonInfo) { - sstrncpy(sipUnregisterReason, reasonInfo, MAX_SIP_REASON_LENGTH); - } - - /* send a restart message to the SIP Task */ - if (SIPTaskSendMsg(SIP_SHUTDOWN, (cprBuffer_t)msg, - sizeof(ccsip_shutdown_req_t), NULL) == CPR_FAILURE) { - cpr_free(msg); - } - return; -} - -static void -SIPTaskProcessShutdown (int action, int reason) -{ - static const char fname[] = "SIPTaskProcessShutdown"; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Starting Shutdown Process\n", DEB_F_PREFIX_ARGS(SIP_TASK, fname)); - sip_mode_quiet = TRUE; - /* Shutdown SIP components */ - sip_shutdown_phase1(action, reason); -} -/* - * Function: destroy_sip_thread - * Description: kill sip msgQ and sip thread - * Parameters: none - * Returns: none - */ -void destroy_sip_thread() -{ - static const char fname[] = "destroy_sip_thread"; - DEF_DEBUG(DEB_F_PREFIX"Unloading SIP and destroying sip thread\n", - DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname)); - - /* kill msgQ thread first, then itself */ - (void) cprDestroyThread(sip_thread); -} diff --git a/libs/sipcc/core/sipstack/h/ccsip_callinfo.h b/libs/sipcc/core/sipstack/h/ccsip_callinfo.h deleted file mode 100644 index 3619a89883..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_callinfo.h +++ /dev/null @@ -1,86 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_CALLINFO_H_ -#define _CCSIP_CALLINFO_H_ - -#include "cpr_types.h" -#include "ccapi.h" -#include "ccsip_core.h" - -#define MAX_SIP_HEADER_LENGTH 1024 -#define MAX_URI_LENGTH 256 -#define URN_REMOTECC "urn:x-cisco-remotecc:" -#define LAQUOT '<' -#define RAQUOT '>' -#define SPACE ' ' -#define TAB '\t' -#define SEMI_COLON ';' - -// Feature string that appear in the feature-urn. For example in -// , "hold" is the feature string. -#define SIP_CI_HOLD_STR "hold" -#define SIP_CI_RESUME_STR "resume" -#define SIP_CI_BARGE_STR "barge" -#define SIP_CI_CBARGE_STR "cbarge" -#define SIP_CI_CALL_INFO_STR "callinfo" -#define SIP_CI_SILENT_STR "silent" -#define SIP_CI_COACHING_STR "coaching" - - -// Definitions relating to the hold-resume feature urn. -#define SIP_CI_HOLD_REASON "reason=" -#define SIP_CI_HOLD_REASON_XFER "transfer" -#define SIP_CI_HOLD_REASON_CONF "conference" - -// Definitions relating to the callinfo feature urn. -#define SIP_CI_SECURITY "security=" -#define SIP_CI_SECURITY_UNKNOWN "unknown" -#define SIP_CI_SECURITY_NOT_AUTH "NotAuthenticated" -#define SIP_CI_SECURITY_AUTH "Authenticated" -#define SIP_CI_SECURITY_ENCRYPTED "Encrypted" -#define SIP_CI_ORIENTATION "orientation=" -#define SIP_CI_ORIENTATION_TO "to" -#define SIP_CI_ORIENTATION_FROM "from" -#define SIP_CI_POLICY "policy=" -#define SIP_CI_POLICY_UNKNOWN "unknown" -#define SIP_CI_POLICY_CHAPERONE "chaperone" -#define SIP_CI_CALL_INSTANCE "call-instance=" -#define SIP_CI_CTI_CALLID "cti-callid=" -#define SIP_CI_UI_STATE "ui-state=" -#define SIP_CI_UI_STATE_RINGOUT "ringout" -#define SIP_CI_UI_STATE_CONNECTED "connected" -#define SIP_CI_PRIORITY "priority=" -#define SIP_CI_PRIORITY_URGENT "urgent" -#define SIP_CI_PRIORITY_EMERGENCY "emergency" -#define SIP_CI_UI_STATE_BUSY "busy" -#define SIP_CI_GCID "gci=" -#define SIP_CI_DUSTINGCALL "isDustingCall" - -// Definitions relating to a generic feature parm. -#define SIP_CI_GENERIC "purpose=" -#define SIP_CI_GENERIC_ICON "icon" -#define SIP_CI_GENERIC_INFO "info" -#define SIP_CI_GENERIC_CARD "card" - -#define SKIP_LWS(p) while (*p == SPACE || *p == TAB) { \ - p++; \ - } -#define SKIP_WHITE_SPACE(p) while (*p == SPACE || *p == TAB || \ - *p == '\n') { \ - p++; \ - } - -/* - * Encoding function - */ -char* ccsip_encode_call_info_hdr(cc_call_info_t *call_info_p, - const char *misc_parms_p); - -void ccsip_free_call_info_header(cc_call_info_t *call_info_p); - -void ccsip_store_call_info(cc_call_info_t *call_info_p, ccsipCCB_t* ccb); -void ccsip_process_call_info_header(sipMessage_t *request_p, ccsipCCB_t* ccb); - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_cc.h b/libs/sipcc/core/sipstack/h/ccsip_cc.h deleted file mode 100755 index be7ea6860b..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_cc.h +++ /dev/null @@ -1,41 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_CC_H_ -#define _CCSIP_CC_H_ - -#include "ccapi.h" - - -void sip_cc_setup(int gsm_call_id, int line, string_t calling_name, - string_t calling_number, string_t alt_calling_number, boolean display_calling_number, - string_t called_name, string_t called_number, - boolean display_called_number, string_t orig_called_name, - string_t orig_called_number, string_t last_redirect_name, - string_t last_redirect_number, cc_call_type_e call_type, - cc_alerting_type alert_info, vcm_ring_mode_t alerting_ring, - vcm_tones_t alerting_tone, cc_call_info_t *call_info_p, - boolean replaces, string_t recv_info_list, sipMessage_t *sip_msg); -void sip_cc_setup_ack(int call_id, int line, cc_msgbody_info_t *msg_body); -void sip_cc_proceeding(int gsm_call_id, int line); -void sip_cc_alerting(int gsm_call_id, int line, sipMessage_t *sip_msg, - int inband); -void sip_cc_connected(int gsm_call_id, int line, string_t recv_info_list, sipMessage_t *sip_msg); -void sip_cc_connected_ack(int gsm_call_id, int line, sipMessage_t *sip_msg); -void sip_cc_release(int gsm_call_id, int line, cc_causes_t cause, - const char *dialstring); -void sip_cc_release_complete(int gsm_call_id, int line, cc_causes_t cause); -void sip_cc_feature(int call_id, int line, int feature, void *data); -void sip_cc_feature_ack(int call_id, int line, int feature, void *data, - cc_causes_t cause); -void sip_cc_mwi(int call_id, int line, boolean on, int type, - int newCount, int oldCount, int hpNewCount, int hpOldCount); -void sip_cc_mv_msg_body_to_cc_msg(cc_msgbody_info_t *cc_msg, - sipMessage_t *sip_msg); -boolean sip_cc_create_cc_msg_body_from_sip_msg(cc_msgbody_info_t *cc_msg, - sipMessage_t *sip_msg); -void sip_cc_options(callid_t call_id, line_t line, sipMessage_t *pSipMessage); -void sip_cc_audit(callid_t call_id, line_t line, boolean apply_ringout); - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_common_cb.h b/libs/sipcc/core/sipstack/h/ccsip_common_cb.h deleted file mode 100644 index 3547596800..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_common_cb.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_COMMON_CB_H_ -#define _CCSIP_COMMON_CB_H_ - -#include "cpr_types.h" -#include "phone_types.h" -#include "ccapi.h" -#include "dns_utils.h" -#include "ccsip_platform.h" -#include "ccsip_pmh.h" -#include "ccsip_core.h" -#include "xml_parser_defines.h" - - -#define HOOK_STATUS_STR "hook status" -#define BLF_SPEEDDIAL_STR "blf speed dial" - -typedef enum { - SUBNOT_CB, - PUBLISH_CB, - UNSOLICIT_NOTIFY_CB -} ccsip_cb_type_e; - - -typedef struct { - ccsip_cb_type_e cb_type; - line_t dn_line; - cpr_ip_addr_t dest_sip_addr; - uint32_t dest_sip_port; /* Destination port */ - cpr_ip_addr_t src_addr; /* Source address */ - uint32_t local_port; /* Source port */ - srv_handle_t SRVhandle; /* handle for dns_gethostbysrv() */ - unsigned int retx_counter; - boolean retx_flag; - char sipCallID[MAX_SIP_CALL_ID]; - sipAuthenticate_t authen; - long orig_expiration; /* Original time to expire */ - long expires; /* Running expiry timer */ - ccsip_event_data_t *event_data_p; - cc_subscriptions_t event_type; /* event type, such as presence */ - cc_subscriptions_t accept_type; /* accept type, such as presence */ -} ccsip_common_cb_t; - - -extern void ccsip_common_util_set_dest_ipaddr_port(ccsip_common_cb_t *cb_p); -extern void ccsip_common_util_set_src_ipaddr(ccsip_common_cb_t *cb_p); -extern void ccsip_common_util_set_retry_settings(ccsip_common_cb_t *cb_p, int *timeout_p); -extern boolean ccsip_common_util_generate_auth(sipMessage_t *pSipMessage, ccsip_common_cb_t *cb_p, - const char *rsp_method, int response_code, char *uri); -extern void ccsip_util_extract_user(char *url, char *user); -extern void ccsip_util_get_from_entity(sipMessage_t *pSipMessage, char *entity); - -#endif //_CCSIP_COMMON_CB_H_ diff --git a/libs/sipcc/core/sipstack/h/ccsip_core.h b/libs/sipcc/core/sipstack/h/ccsip_core.h deleted file mode 100644 index 39525b2bb1..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_core.h +++ /dev/null @@ -1,866 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_CORE_H_ -#define _CCSIP_CORE_H_ - -#include "cpr_types.h" -#include "cpr_memory.h" -#include "task.h" -//#include "network.h" -#include "ccapi.h" -#include "ccsip_sdp.h" -#include "ccsip_pmh.h" -#include "config.h" -#include "dns_utils.h" -#include "ccsip_platform.h" -#include "ccsip_platform_timers.h" -#include "cc_constants.h" -#include "sessionConstants.h" - -#define SIP_DEFER (-2) -#define SIP_ERROR (-1) -#define SIP_OK (0) - -#define SIP_L_C_F_PREFIX "SIP : %d/%d : %s : " // requires 3 args: line_id, call_id, fname -#define SIP_F_PREFIX "SIP : %s : " // requires 1 arg: fname - -#define SUPERVISION_DISCONNECT_TIMEOUT 32000 -#define SIP_WARNING_LENGTH 100 - -#define RPID_DISABLED 0 -#define RPID_ENABLED 1 - -#define MAX_INVITE_RETRY_ATTEMPTS 6 -#define MAX_NON_INVITE_RETRY_ATTEMPTS 10 - -typedef enum { - SIP_STATE_NONE = -1, - SIP_STATE_BASE = 0, - - SIP_STATE_IDLE = SIP_STATE_BASE, - - SIP_STATE_SENT_INVITE, - SIP_STATE_SENT_INVITE_CONNECTED, - - SIP_STATE_RECV_INVITE, - SIP_STATE_RECV_INVITE_PROCEEDING, - SIP_STATE_RECV_INVITE_ALERTING, - SIP_STATE_RECV_INVITE_CONNECTED, - - SIP_STATE_ACTIVE, - SIP_STATE_SENT_MIDCALL_INVITE, - SIP_STATE_RECV_MIDCALL_INVITE_CCFEATUREACK_PENDING, - SIP_STATE_RECV_MIDCALL_INVITE_SIPACK_PENDING, - - SIP_STATE_RELEASE, - SIP_STATE_BLIND_XFER_PENDING, - SIP_STATE_IDLE_MSG_TIMER_OUTSTANDING, - - SIP_STATE_SENT_OOD_REFER, - SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING, - - SIP_STATE_END = SIP_STATE_RECV_UPDATEMEDIA_CCFEATUREACK_PENDING -} sipSMStateType_t; - -typedef enum -{ - SIP_REG_STATE_INV = -1, - SIP_REG_STATE_NONE = 0, - SIP_REG_STATE_BASE = 1, - - SIP_REG_STATE_IDLE = SIP_REG_STATE_BASE, - SIP_REG_STATE_REGISTERING, - SIP_REG_STATE_REGISTERED, - SIP_REG_STATE_UNREGISTERING, - SIP_REG_STATE_IN_FALLBACK, - SIP_REG_STATE_STABILITY_CHECK, - SIP_REG_STATE_TOKEN_WAIT, - SIP_REG_STATE_END = SIP_REG_STATE_TOKEN_WAIT -} sipRegSMStateType_t; - -typedef enum { - SIPSPI_EV_INVALID = -1, - SIPSPI_EV_BASE = 0, - - E_SIP_INVITE = SIPSPI_EV_BASE, - E_SIP_ACK, - E_SIP_BYE, - E_SIP_CANCEL, - E_SIP_1xx, - E_SIP_2xx, - E_SIP_3xx, - E_SIP_NOTIFY, - E_SIP_FAILURE_RESPONSE, - E_SIP_REFER, - E_SIP_OPTIONS, - E_SIP_SUBSCRIBE, - E_SIP_UPDATE, - - E_CC_SETUP, - E_CC_SETUP_ACK, - E_CC_PROCEEDING, - E_CC_ALERTING, - E_CC_CONNECTED, - E_CC_CONNECTED_ACK, - E_CC_RELEASE, - E_CC_RELEASE_COMPLETE, - E_CC_FEATURE, - E_CC_FEATURE_ACK, - E_CC_CAPABILITIES, - E_CC_CAPABILITIES_ACK, - E_CC_SUBSCRIBE, - E_CC_NOTIFY, - E_CC_INFO, - - E_SIP_INV_EXPIRES_TIMER, - E_SIP_INV_LOCALEXPIRES_TIMER, - E_SIP_SUPERVISION_DISCONNECT_TIMER, - E_SIP_TIMER, - E_SIP_GLARE_AVOIDANCE_TIMER, - - E_SIP_UPDATE_RESPONSE, - E_SIP_ICMP_UNREACHABLE, - SIPSPI_EV_END = E_SIP_ICMP_UNREACHABLE -} sipSMEventType_t; - -typedef enum { - H_INVALID_EVENT = -1, - SIPSPI_EV_INDEX_BASE = 0, -/*0*/H_IDLE_EV_SIP_INVITE = SIPSPI_EV_INDEX_BASE, /* ccsip_handle_idle_ev_sip_invite, */ -/*1*/H_IDLE_EV_CC_SETUP, /* ccsip_handle_idle_ev_cc_setup, */ -/*2*/H_SENTINVITE_EV_SIP_1XX, /* ccsip_handle_sentinvite_ev_sip_1xx, */ -/*3*/H_SENTINVITE_EV_SIP_2XX, /* ccsip_handle_sentinvite_ev_sip_2xx, */ -/*4*/H_SENTINVITE_EV_SIP_FXX, /* ccsip_handle_sentinvite_ev_sip_fxx, */ -/*5*/H_DISCONNECT_LOCAL_EARLY, /* ccsip_handle_disconnect_local_early, */ -/*6*/H_DISCONNECT_REMOTE, /* ccsip_handle_disconnect_remote, */ -/*7*/H_SENTINVITECONNECTED_EV_CC_CONNECTED_ACK, /* ccsip_handle_sentinviteconnected_ev_cc_connected_ack, */ -/*8*/H_DISCONNECT_LOCAL, /* ccsip_handle_disconnect_local, */ -/*9*/H_RECVINVITE_EV_CC_SETUP_ACK, /* ccsip_handle_recvinvite_ev_cc_setup_ack, */ -/*10*/H_RECVINVITE_EV_CC_PROCEEDING, /* ccsip_handle_recvinvite_ev_cc_proceeding, */ -/*11*/H_RECVINVITE_EV_CC_ALERTING, /* ccsip_handle_recvinvite_ev_cc_alerting, */ -/*12*/H_RECVINVITE_EV_CC_CONNECTED, /* ccsip_handle_recvinvite_ev_cc_connected, */ -/*13*/H_DISCONNECT_LOCAL_UNANSWERED, /* ccsip_handle_disconnect_local_unanswered, */ -/*14*/H_RECVINVITE_EV_SIP_ACK, /* ccsip_handle_recvinvite_ev_sip_ack, */ -/*15*/H_ACTIVE_EV_SIP_INVITE, /* ccsip_handle_active_ev_sip_invite, */ -/*16*/H_ACTIVE_EV_CC_FEATURE, /* ccsip_handle_active_ev_cc_feature, */ -/*17*/H_ACCEPT_2XX, /* ccsip_handle_accept_2xx, */ -/*18*/H_REFER_SIP_MESSAGE, /* ccsip_handle_refer_sip_message, */ -/*19*/H_ACTIVE_EV_CC_FEATURE_ACK, /* ccsip_handle_active_ev_cc_feature_ack, */ -/*20*/H_SENTINVITE_MIDCALL_EV_SIP_2XX, /* ccsip_handle_sentinvite_midcall_ev_sip_2xx */ -/*21*/H_SENTINVITE_MIDCALL_EV_CC_FEATURE, /* ccsip_handle_sentinvite_midcall_ev_cc_feature */ -/*22*/H_RECVMIDCALLINVITE_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK, /* ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack */ -/*23*/H_RECVMIDCALLINVITE_SIPACKPENDING_EV_SIP_ACK, /* ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack, */ -/*24*/H_DEFAULT_SIP_MESSAGE, /* ccsip_handle_default_sip_message, */ -/*25*/H_DEFAULT_SIP_RESPONSE, /* ccsip_handle_default_sip_response, */ -/*26*/H_DEFAULT, /* ccsip_handle_default, */ -/*27*/H_SIP_INV_EXPIRES_TIMER, /* ccsip_handle_disconnect_local_early, */ -/*28*/H_SIP_OPTIONS, /* ccsip_handle_answer_options_request, */ -/*29*/H_SENTINVITE_EV_SIP_3XX, /* ccsip_handle_sentinvite_ev_sip_3xx, */ -/*30*/H_RECV_ERR_EV_SIP_ACK, /* ccsip_handle_recv_error_response_ev_sip_ack,*/ -/*31*/H_SENTBYE_EV_SIP_2XX, /* ccsip_handle_sentbye_ev_sip_2xx,*/ -/*32*/H_SENTBYE_EV_SIP_1XX, /* ccsip_handle_sentbye_ev_sip_1xx,*/ -/*33*/H_SENTBYE_EV_SIP_FXX, /* ccsip_handle_sentbye_ev_sip_fxx,*/ -/*34*/H_SENTBYE_EV_SIP_INVITE, /* ccsip_handle_sentbye_recvd_invite,*/ -/*35*/H_SENTBYE_SUPERVISION_DISCONNECT_TIMER, /* ccsip_handle_sendbye_ev_supervision_disconnect*/ -/*36*/H_RELEASE_COMPLETE, /* ccsip_handle_release_complete, */ -/*37*/H_ACTIVE_2xx, /* ccsip_handle_Active_2xx*/ -/*38*/H_BLIND_NOTIFY, /* ccsip_handle_send_blind_notify, */ -/*39*/H_SENT_BLINDNTFY, /* ccsip_handle_sentblindntfy_ev_sip_2xx, */ -/*40*/H_BYE_RELEASE, /* ccsip_handle_release_ev_sip_bye, */ -/*41*/H_HANDLE_LOCALEXPIRES_TIMER, /* ccsip_handle_localexpires_timer */ -/*42*/H_DEFAULT_SIP_TIMER, /* ccsip_handle_default_sip_timer */ -/*43*/H_EARLY_EV_SIP_UPDATE, /* ccsip_handle_early_ev_sip_update */ -/*44*/H_EARLY_EV_SIP_UPDATE_RESPONSE, /* ccsip_handle_early_ev_sip_update_response */ -/*45*/H_EARLY_EV_CC_FEATURE, /* ccsip_handle_early_ev_cc_feature */ -/*46*/H_EARLY_EV_CC_FEATURE_ACK, /* ccsip_handle_early_ev_cc_feature_ack */ -/*47*/H_CONFIRM_EV_SIP_UPDATE, /* ccsip_handle_active_ev_sip_update */ -/*48*/H_RECVUPDATEMEDIA_CCFEATUREACKPENDING_EV_CC_FEATURE_ACK, /* ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack */ -/*49*/H_SIP_GLARE_AVOIDANCE_TIMER, /* ccsip_handle_timer_glare_avoidance */ -/*50*/H_RECVINVITE_SENTOK_NO_SIP_ACK, /* ccsip_handle_recvinvite_ev_expires_timer */ -/*51*/H_EV_SIP_UNSOLICITED_NOTIFY, /* ccsip_handle_unsolicited_notify */ -/*52*/H_RECVINVITE_EV_SIP_2XX, /* ccsip_handle_recvinvite_ev_sip_2xx */ -/*53*/H_ICMP_UNREACHABLE, /* ccsip_handle_icmp_unreachable */ -/*54*/H_DISCONNECT_MEDIA_CHANGE, /* ccsip_handle_disconnect_media_change*/ -/*55*/H_DEFAULT_EV_CC_FEATURE, /* ccsip_handle_default_ev_cc_feature */ -/*56*/H_DEFAULT_RECVREQ_ACK_PENDING_EV_CC_FEATURE, /* ccsip_handle_default_recvreq_ack_pending_ev_cc_feature */ -/*57*/H_OOD_REFER_RESPONSE_EV_SIP_1xx, /* ccsip_handle_sent_ood_refer_ev_sip_1xx */ -/*58*/H_OOD_REFER_RESPONSE_EV_SIP_2xx, /* ccsip_handle_sent_ood_refer_ev_sip_2xx */ -/*59*/H_OOD_REFER_RESPONSE_EV_SIP_fxx, /* ccsip_handle_sent_ood_refer_ev_sip_fxx */ -/*60*/H_RELEASE_EV_CC_FEATURE, /* ccsip_handle_release_ev_cc_feature */ -/*61*/H_EV_CC_INFO, /* ccsip_handle_ev_cc_info */ -/*62*/H_RELEASE_EV_RELEASE, /* ccsip_handle_release_ev_release */ - SIPSPI_EV_INDEX_END = H_RELEASE_EV_RELEASE -} sipSMAction_t; - - - -/* - * This structure defines TCP/UDP Connection - * Parameters. - * This is used during processing Contact - * and Route headers received in the SIP - * messages - */ -typedef enum { - SIP_SM_DIS_METHOD_BYE = 0, - SIP_SM_DIS_METHOD_CANCEL -} sipSMDisMethod_t; - -typedef struct { - char last_call_id[MAX_SIP_CALL_ID]; - uint32_t last_bye_cseq_number; - cpr_ip_addr_t last_bye_dest_ipaddr; - uint16_t last_bye_dest_port; - cpr_ip_addr_t proxy_dest_ipaddr; - line_t dn_line; - char last_bye_also_string[MAX_SIP_URL_LENGTH]; - char last_route[MAX_SIP_URL_LENGTH]; - char last_route_request_uri[MAX_SIP_URL_LENGTH]; - char via_branch[VIA_BRANCH_LENGTH]; - sipStatusCodeClass_t last_rspcode_rcvd; -} sipCallHistory_t; - -typedef enum { - SIP_SM_NO_XFR = 0, - SIP_SM_BLND_XFR, - SIP_SM_ATTN_XFR -} sipSMXfrType_t; - -typedef struct sipRedirectInfo_ { - sipContact_t *sipContact; /* Contact header received in the 3xx */ - uint16_t next_choice; /* Index of next Contact location to use */ -} sipRedirectInfo_t; - -typedef struct { - int retries_401_407; - int cred_type; - char *authorization; - int status_code; - sip_authen_t *sip_authen; - char cnonce[9]; - int nc_count; - boolean new_flag; -} sipAuthenticate_t; - -/* SIP REGISTER method info */ -typedef struct { - int registered; - int tmr_expire; - int act_time; - char proxy[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t addr; - uint16_t port; - uint8_t rereg_pending; -} sipRegister_t; - -/* AVT payload info */ -typedef struct { - int payload_type; //TODO BLASBERG: uint8_t or uint16_t should be acceptable -} sipAvtPayloadType_t; - -/* Identifies CCB type because registration & call control use the same CCBs */ -typedef enum { - SIP_NONE_CCB, - SIP_REG_CCB, - SIP_CALL_CCB -} sipCCBTypes_t; - -/* - * Define the types of CC's - */ -typedef enum { - CC_CCM = CC_MODE_CCM, - CC_OTHER = CC_MODE_NONCCM, - MAX_CC_TYPES -} CC_ID; - -/* - * Offer/answer state - */ -typedef enum { - OA_IDLE, - OA_OFFER_SENT, - OA_OFFER_RECEIVED, - OA_ANSWER_SENT, - OA_ANSWER_RECEIVED -} sipOfferAnswerState; - -/* Indentifies how proxy selection is being done */ -typedef enum { - SIP_PROXY_DEFAULT, /* Current selection is configured proxy */ - SIP_PROXY_BACKUP, /* Current selection is configured backup proxy */ - SIP_PROXY_DO_NOT_CHANGE_MIDCALL /* Do not select a different proxy even on failure*/ -} sipCCBProxySelection; - -typedef struct -{ - union { - string_t sip_via_header; // For received requests - string_t sip_via_branch; // For sent requests - } u; - string_t sip_via_sentby; - sipMethod_t cseq_method; - uint32_t cseq_number; -} sipTransaction_t; - -typedef struct -{ - char sipCallID[MAX_SIP_CALL_ID]; - callid_t gsm_id; - callid_t con_call_id; - callid_t blind_xfer_call_id; - - sipSMStateType_t state; - line_t index; - line_t dn_line; - boolean hold_initiated; - uint32_t retx_counter; - sipCCBTypes_t type; - - /* - * first_backup indicates whether or not the backup proxy has just been - * activated. After the first message is retransmitted, the flag will be - * reset to FALSE. - */ - boolean first_backup; - sipCCBProxySelection proxySelection; /* Indicates how proxy selection is being done */ - cpr_ip_addr_t outBoundProxyAddr; /* IP address of outbound proxy for this call */ -// uint16_t outBoundProxyPort; /* Outbound proxy port for this call */ - uint32_t outBoundProxyPort; /* Outbound proxy port for this call */ - - srv_handle_t SRVhandle; /* handle for dns_gethostbysrv() */ - srv_handle_t ObpSRVhandle; /* SRVhandle for the outbound proxy */ - int routeMode; /* Current routemode set by UIMatchDialTemplate() */ - void *udpId; /* handle to UDPApplIcmpHandler */ - - /* - * An INVITE/ACK/1xx/2xx can be accompanied with a Contact header. - * Future requests should go there. This field is used to store the - * parsed Contact header received with any of these messages. - */ - sipContact_t *contact_info; - - /* Refer To and refere by headers Needed for next generated call */ - - /* - * Any SIP request such as INVITE, BYE, CANCEL etc and INVITE 200 OK, - * 401 & 484 responses can have a Record-Route header. This field is - * used to store the parsed Record-Route header received in any of - * these messages. - */ - sipRecordRoute_t *record_route_info; - - string_t calledDisplayedName; - string_t callingNumber; - string_t altCallingNumber; - string_t callingDisplayName; - string_t calledNumber; - boolean displayCalledNumber; - boolean displayCallingNumber; - uint16_t calledNumberLen; - boolean calledNumberFirstDigitDialed; - - /* - * The following field encodes boolean bit flags (on or off) for - * loopback, inband_alerting, sip_tcp, incoming, added_to_table, - * do_call_history, rsvp_reserved, msgPassthru, sigoCall, - * sent_bye, sent_cancel, sent_bye_response, sent_3456xx, recd_456xx, - * harikiri, timed_out, sd_in_ack - */ - uint32_t flags; - -#define LOOPBACK 1 -#define INBAND_ALERTING (1<<1) -#define SIP_TCP (1<<2) -#define INCOMING (1<<3) -#define ADDED_TO_TABLE (1<<4) -#define DO_CALL_HISTORY (1<<5) -#define RSVP_RESERVED (1<<6) -#define SENT_BYE (1<<7) -#define SENT_CANCEL (1<<8) -#define RECD_BYE (1<<9) -#define SENT_3456XX (1<<10) -#define RECD_456XX (1<<11) -#define HARIKIRI (1<<12) -#define TIMED_OUT (1<<13) -#define SD_IN_ACK (1<<14) -#define MSG_PASSTHRU (1<<15) -#define SIGO_CALL (1<<16) -#define RECD_1xx (1<<17) -#define SEND_CANCEL (1<<18) -#define FINAL_NOTIFY (1<<19) -#define SENT_INVITE_REPLACE (1<<20) - - /* - * SIP signalling channel info: source and destination - */ - cpr_ip_addr_t src_addr; /* Source address */ - cpr_ip_addr_t dest_sip_addr; /* Destination address */ -// uint16_t local_port; /* Source port */ -// uint16_t dest_sip_port; /* Destination port */ - uint32_t local_port; /* Source port */ - uint32_t dest_sip_port; /* Destination port */ - int16_t sip_socket_handle; - - /* - * RTP/SDP - */ - cc_msgbody_info_t local_msg_body; /* store local sent msg bodies */ -// sipSdp_t *src_sdp; -// ushort src_port; -// sipSdp_t *dest_sdp; -// uint16_t dest_port; -// uint32_t dest_addr; - char *old_session_id; - char *old_version_id; -// ushort dest_sdp_media; -// boolean rtp_rx_opened; -// boolean rtp_tx_opened; -// cc_sdp_t cc_sdp; - - /* - * Headers - */ - char ReqURI[MAX_SIP_URL_LENGTH]; /* "Working" Req-URI */ - string_t ReqURIOriginal; /* Original outgoing call Req-URI */ - string_t sip_from; - string_t sip_to; - string_t sip_to_tag; - string_t sip_from_tag; - string_t sip_contact; - string_t sip_remote_party_id; - string_t sip_reqby; - string_t sip_require; - string_t sip_unsupported; - char *diversion[MAX_DIVERSION_HEADERS]; -#define MAX_REQ_OUTSTANDING 3 - sipTransaction_t sent_request[MAX_REQ_OUTSTANDING]; - sipTransaction_t recv_request[MAX_REQ_OUTSTANDING]; - uint32_t last_recv_request_cseq; - sipMethod_t last_recv_request_cseq_method; - uint32_t last_used_cseq; - uint32_t last_recv_invite_cseq; - string_t sip_referTo; - string_t sip_referredBy; - string_t referto; - string_t sipxfercallid; - boolean wastransferred; - boolean blindtransferred; - unsigned int xfer_status; - /* Store all of the parsed diversion header info */ - sipDiversionInfo_t *div_info; - - cc_call_type_e call_type; - - /* Store all of the parsed Remote-Party-ID headers */ - sipRemotePartyIdInfo_t *rpid_info; - /* Shallow pointer to the "best" parsed Remote-Party-ID header */ - sipRemotePartyId_t *best_rpid; - - /* To save the Via headers on the INVITE */ - sipMessage_t *last_request; - - /* - * Features - */ - sipSMXfrType_t xfr_inprogress; - cc_features_t featuretype; - - sipAvtPayloadType_t avt; - - /* - * Registration/Authentication - */ - sipRegister_t reg; - sipAuthenticate_t authen; - - /* - * Two fields that can be sent with the Refer-To header - */ - char *refer_proxy_auth; -#ifdef SIP_ACC_CONT - char *refer_acc_cont; -#endif - /* - * This struct would be allocated when the call is actually redirected - * Idea is to save memory in the ccb for non-redirected calls. - */ - sipRedirectInfo_t *redirect_info; - - /* - * Enum of what was in the alert-info header. - */ - cc_alerting_type alert_info; - - /* - * Contents of incoming and outgoing call-info headers - */ - cc_call_info_t *in_call_info; - cc_call_info_t *out_call_info; - - /* - * Ringing/tone pattern to play - */ - vcm_ring_mode_t alerting_ring; - vcm_tones_t alerting_tone; - - /* - * Personal Directory - */ - boolean call_entered_into_pd; - boolean wait_for_ack; - boolean send_delayed_bye; - boolean retx_flag; - boolean early_transfer; - boolean first_pass_3xx; - CC_ID cc_type; - void *cc_cfg_table_entry; - /* - * Contents of supported and required headers - */ -#define replaces_tag 1 -#define rel_tag (1<<1) -#define early_session_tag (1<<2) -#define join_tag (1<<3) -#define path_tag (1<<4) -#define precondition_tag (1<<5) -#define pref_tag (1<<6) -#define privacy_tag (1<<7) -#define sec_agree_tag (1<<8) -#define timer_tag (1<<9) -#define norefersub_tag (1<<10) -#define cisco_callinfo_tag (1<< 11) -#define cisco_srtp_fallback_tag (1<< 12) -#define extended_refer_tag (1<<16) -#define cisco_serviceuri_tag (1<<18) -#define cisco_escapecodes_tag (1<<19) -#define cisco_service_control_tag (1<<20) -#define sdp_anat_tag (1<< 21) -#define unrecognized_tag (1<<31) - - uint32_t supported_tags; - uint32_t required_tags; - -#define SUPPORTED_TAGS replaces_tag | join_tag | sdp_anat_tag | norefersub_tag - - - /* - * Contents of the the allow header accepted by the remote side - */ -#define ALLOW_ACK 1 -#define ALLOW_BYE (1<<1) -#define ALLOW_CANCEL (1<<2) -#define ALLOW_INFO (1<<3) -#define ALLOW_INVITE (1<<4) -#define ALLOW_MESSAGE (1<<5) -#define ALLOW_NOTIFY (1<<6) -#define ALLOW_OPTIONS (1<<7) -#define ALLOW_PRACK (1<<8) -#define ALLOW_PUBLISH (1<<9) -#define ALLOW_REFER (1<<10) -#define ALLOW_REGISTER (1<<11) -#define ALLOW_SUBSCRIBE (1<<12) -#define ALLOW_UPDATE (1<<13) - - uint16_t allow_methods; - - sipOfferAnswerState oa_state; - int last_recvd_response_code; - sipJoinInfo_t *join_info; - cc_feature_data_t *feature_data; - int dup_flags; - void *mother_ccb; - -#define DUP_NO_FLAGS 0x00 -#define DUP_CCB 0x01 -#define DUP_CCB_NEW_CALLID 0x02 -#define DUP_CCB_INIT_STATE 0x04 -#define DUP_CCB_REINIT_DNS 0x08 -#define DUP_CCB_STOLEN_FEAT_DATA 0x10 - - cc_kfact_t *kfactor_ptr; - - boolean send_reason_header; - - uint32_t callref; - -} ccsipCCB_t; - - -typedef struct { - ccsipCCB_t ccbs[MAX_CCBS]; - int backup_active; /* Currently use reduce invite retry count */ -} ccsipGlobInfo_t; - - -typedef struct { - sipSMEventType_t type; - ccsipCCB_t *ccb; - union { - sipMessage_t *pSipMessage; - cc_msg_t *cc_msg; - cpr_ip_addr_t UsrInfo; - } u; -} sipSMEvent_t; - -typedef void (*sipSMEventActionFn_t)(ccsipCCB_t *ccb, sipSMEvent_t *event); -typedef void (*shutdown_callback_fn)(void *data); - -typedef struct { - shutdown_callback_fn callback; - void *data; -} shutdown_t; - -typedef enum { - SIP_SDP_SUCCESS = 0, - SIP_SDP_SESSION_AUDIT, - SIP_SDP_DNS_FAIL, - SIP_SDP_NO_MEDIA, - SIP_SDP_ERROR, - SIP_SDP_NOT_PRESENT -} sipsdp_status_t; - -extern ccsipGlobInfo_t gGlobInfo; -sipSMAction_t get_handler_index(sipSMStateType_t isipsmstate, - sipSMEventType_t isipsmevent); - -void ccsip_handle_idle_ev_sip_invite(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_idle_ev_cc_setup(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_sentinvite_ev_sip_1xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentinvite_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentinvite_ev_sip_3xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentinvite_ev_sip_fxx(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_sentinviteconnected_ev_cc_connected_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_recvinvite_ev_cc_setup_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_cc_proceeding(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_cc_alerting(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_cc_connected(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_sip_ack(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_active_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_active_ev_cc_feature_hold(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_active_ev_cc_feature_resume_or_media(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_active_ev_cc_feature_other(ccsipCCB_t *ccb, - sipSMEvent_t event); -void ccsip_handle_active_ev_sip_invite(ccsipCCB_t *ccb, sipSMEvent_t *event); - - -void ccsip_handle_recvmidcallinvite_ccfeatureackpending_ev_cc_feature_ack( - ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_recvmidcallinvite_sipackpending_ev_sip_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_accept_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_active_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); - - -void ccsip_handle_default(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_sip_message(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_sip_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_sip_timer(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_disconnect_local(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_disconnect_local_early(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_disconnect_local_unanswered(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_disconnect_remote(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_refer_sip_message(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_active_ev_cc_feature_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_active_ev_cc_feature_xfer(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_active_ev_cc_feature_indication(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_sentbye_recvd_invite(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentbye_ev_sip_fxx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentbye_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentbye_ev_sip_1xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sendbye_ev_supervision_disconnect(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_recv_error_response_ev_sip_ack(ccsipCCB_t *ccb, - sipSMEvent_t *event); - -void ccsip_handle_release_complete(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_send_blind_notify(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentblindntfy_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_release_ev_sip_bye(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_process_in_call_options_request(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_cc_answer_options_request(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_cc_answer_audit_request(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_localexpires_timer(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void ccsip_handle_early_ev_sip_update(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_early_ev_sip_update_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_early_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_early_ev_cc_feature_ack(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_active_ev_sip_update(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_recvupdatemedia_ccfeatureackpending_ev_cc_feature_ack( - ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_timer_glare_avoidance(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_expires_timer(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_unsolicited_notify(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_recvinvite_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_icmp_unreachable(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_disconnect_media_change(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sent_ood_refer_ev_sip_1xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sent_ood_refer_ev_sip_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sent_ood_refer_ev_sip_fxx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_default_recvreq_ack_pending_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_sentinvite_midcall_ev_cc_feature(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_sentinvite_midcall_ev_sip_2xx(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void ccsip_handle_release_ev_cc_feature(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_ev_cc_info(ccsipCCB_t *ccb, sipSMEvent_t *event); -void ccsip_handle_release_ev_release(ccsipCCB_t *ccb, sipSMEvent_t *event); - -int sip_sm_init(void); -void sip_shutdown(void); -void sip_shutdown_phase1(int, int reason); -void sip_shutdown_phase2(int); -void sip_restart(void); -int sip_sm_ccb_init(ccsipCCB_t *ccb, line_t index, int DN, - sipRegSMStateType_t initial_state); -ccsipCCB_t *sip_sm_get_ccb_by_index(line_t index); -ccsipCCB_t *sip_sm_get_ccb_by_ccm_id_and_index(int ccm_id, line_t idx); -ccsipCCB_t *sip_sm_get_ccb_by_callid(const char *callid); -ccsipCCB_t *sip_sm_get_ccb_next_available(line_t *line_number); -ccsipCCB_t *sip_sm_get_ccb_by_gsm_id(callid_t gsm_id); -ccsipCCB_t *sip_sm_get_ccb_by_target_call_id(callid_t con_id); -ccsipCCB_t *sip_sm_get_target_call_by_gsm_id(callid_t gsm_id); -ccsipCCB_t *sip_sm_get_target_call_by_con_call_id(callid_t con_call_id); -boolean sip_is_releasing(ccsipCCB_t* ccb); -callid_t sip_sm_get_blind_xfereror_ccb_by_gsm_id(callid_t gsm_id); -uint16_t sip_sm_determine_ccb(const char *callid, - sipCseq_t *sipCseq, - sipMessage_t *pSipMessage, - boolean is_request, - ccsipCCB_t **ccb); -void sip_sm_call_cleanup(ccsipCCB_t *ccb); -void free_duped(ccsipCCB_t *dupCCB); - - -int sip_sm_process_event(sipSMEvent_t *pEvent); -int sip_sm_process_cc_event(cprBuffer_t buf); -void sip_sm_util_normalize_name(ccsipCCB_t *ccb, char *dialString); - - -const char *sip_util_state2string(sipSMStateType_t state); -const char *sip_util_event2string(sipSMEventType_t event); -const char *sip_util_method2string(sipMethod_t method); -boolean sip_sm_is_bye_or_cancel_response(sipMessage_t *response); - -sipSMEventType_t sip_util_ccevent2sipccevent(cc_msgs_t cc_msg_type); -const char *sip_util_feature2string(cc_features_t feature); - -void sip_create_new_sip_call_id(char *sipCallID, uint8_t *mac_address, - char *pSrcAddrStr); -void sip_util_get_new_call_id(ccsipCCB_t *ccb); -boolean sip_sm_is_previous_call_id(const char *pCallID, - line_t *pPreviousCallLine); -boolean sip_sm_util_is_timeinterval(const char *pStr); - -void sip_decrement_backup_active_count(ccsipCCB_t *ccb); -//int sip_sm_active_calls(void); -#ifdef DEBUG -void print_ccb_memoryusage(ccsipCCB_t *ccb); -#endif - -void sip_sm_200and300_update(ccsipCCB_t *ccb, sipMessage_t *response, - int response_code); -char *sip_sm_purify_tag(char *tag); -boolean sip_sm_is_invite_response(sipMessage_t *response); -boolean sip_sm_is_refer_response(sipMessage_t *response); -boolean sip_sm_is_notify_response(sipMessage_t *response); - -void sip_sm_dequote_string(char *str, int max_size); -void sip_sm_check_retx_timers(ccsipCCB_t *ccb, sipMessage_t *message); -int strcasecmp_ignorewhitespace(const char *cs, const char *ct); - -void sip_util_make_ccmsgsdp(cc_sdp_t *pCcMsgSdp, ccsipCCB_t *ccb); - -int sip_dns_gethostbysrv(char *domain, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, - srv_handle_t *srv_order, - boolean retried_addr); -int sip_dns_gethostbysrvorname(char *hname, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port); -void sip_util_make_tag(char *tag_str); -void get_sip_error_string(char *errortext, int response); -int ccsip_cc_to_sip_cause(cc_causes_t cause, char **phrase); -void sip_sm_update_to_on_midcall_200(ccsipCCB_t *ccb, sipMessage_t *response); - -sipServiceControl_t *ccsip_get_notify_service_control(sipMessage_t *pSipMessage); -boolean ccsip_is_special_name_to_mask_display_number(const char *name); -void sip_sm_change_state(ccsipCCB_t *ccb, sipSMStateType_t new_state); - -#define SIP_SM_CALL_SETUP_NOT_COMPLETED(x) \ - ((x->state == SIP_STATE_RECV_INVITE) || \ - (x->state == SIP_STATE_RECV_INVITE_PROCEEDING) || \ - (x->state == SIP_STATE_RECV_INVITE_ALERTING) || \ - (x->state == SIP_STATE_RECV_INVITE_CONNECTED)) -#define SIP_SM_CALL_SETUP_RESPONDING(x) \ - ((x->state == SIP_STATE_RECV_INVITE_PROCEEDING) || \ - (x->state == SIP_STATE_RECV_INVITE_ALERTING)) - -#define ccsip_is_replace_setup(replace) (replace) - -extern char *ccsip_find_preallocated_sip_local_tag(line_t dn_line); -extern void ccsip_free_preallocated_sip_local_tag(line_t dn_line); -extern char *getPreallocatedSipCallID(line_t dn_line); -extern char *getPreallocatedSipLocalTag(line_t dn_line); -extern ccsipCCB_t* create_dupCCB(ccsipCCB_t *origCCB, int dup_flags); - -/* Info Package stuff */ -#define MAX_INFO_HANDLER 32 - -/* - * g_registered_info[] contains the Info Package strings (such as - * "conference") for the registered handlers. - * - * The index of g_registered_info[] goes from 0 to MAX_INFO_HANDLER - 1. - */ -extern char *g_registered_info[]; - -typedef void (*info_package_handler_t)(line_t line, callid_t call_id, - const char *info_package, - const char *content_type, - const char *message_body); - -int ccsip_info_package_handler_init(void); -void ccsip_info_package_handler_shutdown(void); -int ccsip_register_info_package_handler(const char *info_package, - const char *content_type, - info_package_handler_t handler); -int ccsip_deregister_info_package_handler(const char *info_package, - const char *content_type, - info_package_handler_t handler); -void ccsip_parse_send_info_header(sipMessage_t *pSipMessage, string_t *recv_info_list); -int ccsip_handle_info_package(ccsipCCB_t *ccb, sipMessage_t *pSipMessage); - - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_credentials.h b/libs/sipcc/core/sipstack/h/ccsip_credentials.h deleted file mode 100644 index e23a43372f..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_credentials.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_CREDENTIALS_H_ -#define _CCSIP_CREDENTIALS_H_ - -#include "cpr_types.h" -#include "prot_configmgr.h" - -#define CRED_MAX_ID_LEN AUTH_NAME_SIZE -#define CRED_MAX_PW_LEN 32 - -#define CRED_USER 0x00000001 -#define CRED_LINE 0x00000002 - - -typedef struct _credentials { - char id[CRED_MAX_ID_LEN]; - char pw[CRED_MAX_PW_LEN]; -} credentials_t; - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_macros.h b/libs/sipcc/core/sipstack/h/ccsip_macros.h deleted file mode 100644 index 40a560bb54..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_macros.h +++ /dev/null @@ -1,24 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_MACROS_H_ -#define _CCSIP_MACROS_H_ - - -#define EVENT_ACTION_SM(x) \ - (gSIPHandlerTable[x]) - -#define UPDATE_FLAGS(x, y) \ - (x = (x == STATUS_SUCCESS) ? y : x) - -#define GET_SIP_MESSAGE() sippmh_message_create() - -#define REG_CHECK_EVENT_SANITY(x, y) \ - ((x - SIP_REG_STATE_BASE >= 0) && (x <= SIP_REG_STATE_END) && \ - (y - SIPSPI_REG_EV_BASE >=0) && (y <= SIPSPI_REG_EV_END)) - -#define REG_EVENT_ACTION(x, y) \ - (gSIPRegSMTable[x - SIP_REG_STATE_BASE][y - SIPSPI_REG_EV_BASE]) - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_messaging.h b/libs/sipcc/core/sipstack/h/ccsip_messaging.h deleted file mode 100644 index 0ee3b4d832..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_messaging.h +++ /dev/null @@ -1,290 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_MESSAGING_H_ -#define _CCSIP_MESSAGING_H_ - -#include "ccsip_sdp.h" -#include "ccsip_pmh.h" -#include "ccsip_credentials.h" -#include "ccsip_core.h" -#include "ccsip_subsmanager.h" -#include "ccapi.h" - -#define SIP_MESSAGING_OK (0) -#define SIP_MESSAGING_ERROR (1) -#define SIP_MESSAGING_DUPLICATE (2) -#define SIP_MESSAGING_NEW_CALLID (3) -#define SIP_MESSAGING_ERROR_STALE_RESP (4) -#define SIP_MESSAGING_ERROR_UNSUPPORTED_MEDIA (5) -#define SIP_MESSAGING_ERROR_NO_TRX (6) -#define SIP_MESSAGING_NOT_ACCEPTABLE (7) -#define SIP_MESSAGING_ENDPOINT_NOT_FOUND (8) -#define NUM_INITIAL_RECORD_ROUTE_BUFS 4 - -typedef enum { - SIP_INVITE_TYPE_INVALID = 0, - SIP_INVITE_TYPE_NORMAL, - SIP_INVITE_TYPE_MIDCALL, - SIP_INVITE_TYPE_TRANSFER, - SIP_INVITE_TYPE_AUTHORIZATION, - SIP_INVITE_TYPE_REDIRECTED -} sipInviteType_t; - -typedef enum { - SIP_RTP_INCLUDE_MEDIA_INVALID = 0, - SIP_RTP_INCLUDE_MEDIA_ALL, - SIP_RTP_INCLUDE_MEDIA_PREFERRED, - SIP_RTP_INCLUDE_MEDIA_MATCHING -} sipRTPIncludeMedia_t; - -typedef enum { - SIP_REF_NONE = 0, - SIP_REF_XFER, - SIP_REF_DIR_XFER, - SIP_REF_TOKEN, - SIP_REF_UNKNOWN -} sipRefEnum_e; - -typedef struct { - unsigned int flags; - unsigned int extflags; -} sipMessageFlag_t; - - -#define SIP_HEADER_CONTACT_BIT 1 -#define SIP_HEADER_RECORD_ROUTE_BIT (1<<1) -#define SIP_HEADER_ROUTE_BIT (1<<2) -#define SIP_HEADER_SPARE_BIT0 (1<<3) -#define SIP_HEADER_REQUESTED_BY_BIT (1<<4) -#define SIP_HEADER_DIVERSION_BIT (1<<5) -#define SIP_HEADER_AUTHENTICATION_BIT (1<<6) -#define SIP_HEADER_REFER_TO_BIT (1<<7) -#define SIP_HEADER_REFERRED_BY_BIT (1<<8) -#define SIP_HEADER_REPLACES_BIT (1<<9) -#define SIP_HEADER_EVENT_BIT (1<<10) -#define SIP_HEADER_EXPIRES_BIT (1<<11) -#define SIP_HEADER_ACCEPT_BIT (1<<12) -#define SIP_HEADER_ALLOW_BIT (1<<13) -#define SIP_HEADER_CISCO_GUID_BIT (1<<14) -#define SIP_HEADER_SPARE_BIT1 (1<<15) -#define SIP_HEADER_UNSUPPORTED_BIT (1<<16) -#define SIP_HEADER_REMOTE_PARTY_ID_BIT (1<<17) -#define SIP_HEADER_PROXY_AUTH_BIT (1<<18) -#define SIP_HEADER_REQUIRE_BIT (1<<19) -#define SIP_HEADER_CALL_INFO_BIT (1<<20) -#define SIP_HEADER_SUPPORTED_BIT (1<<21) -#define SIP_HEADER_RETRY_AFTER_BIT (1<<22) -#define SIP_HEADER_ALLOW_EVENTS_BIT (1<<23) -#define SIP_HEADER_CONTENT_TYPE_BIT (1<<24) -#define SIP_HEADER_CONTENT_LENGTH_BIT (1<<25) -#define SIP_HEADER_JOIN_INFO_BIT (1<<26) -#define SIP_HEADER_ACCEPT_ENCODING_BIT (1<<27) -#define SIP_HEADER_ACCEPT_LANGUAGE_BIT (1<<28) -#define SIP_HEADER_OPTIONS_CONTENT_TYPE_BIT (1<<29) -#define SIP_HEADER_REASON_BIT (1<<30) -#define SIP_HEADER_RECV_INFO_BIT (1U<<31) - - -#define SIP_RFC_SUPPORTED_TAGS REQ_SUPP_PARAM_REPLACES "," \ - REQ_SUPP_PARAM_JOIN "," \ - REQ_SUPP_PARAM_SDP_ANAT "," \ - REQ_SUPP_PARAM_NOREFERSUB - -/* - * The REQ_SUPP_PARAM_EXTENED_REFER is only used in Cisco CCM environment. - * The tag is no longer in IANA. - */ -#define SIP_CISCO_SUPPORTED_TAGS REQ_SUPP_PARAM_EXTENED_REFER "," \ - REQ_SUPP_PARAM_CISCO_CALLINFO "," \ - REQ_SUPP_PARAM_CISCO_ESCAPECODES "," \ - REQ_SUPP_PARAM_CISCO_MONREC - -#define SIP_CISCO_SUPPORTED_REG_TAGS \ - SIP_RFC_SUPPORTED_TAGS "," \ - SIP_CISCO_SUPPORTED_TAGS - - -boolean sipSPISendInvite(ccsipCCB_t *ccb, - sipInviteType_t inviteType, - boolean initInvite); -boolean sipSPISendInviteMidCall(ccsipCCB_t *ccb, boolean expires); -void sipSPISendInviteResponse100(ccsipCCB_t *ccb, boolean remove_to_tag); -void sipSPISendInviteResponse180(ccsipCCB_t *ccb); -void sipSPISendInviteResponse200(ccsipCCB_t *ccb); -void sipSPISendInviteResponse302(ccsipCCB_t *ccb); - -boolean sipSPISendOptionResponse(ccsipCCB_t *ccb, sipMessage_t *); -boolean sipSPIsendNonActiveOptionResponse(sipMessage_t *msg, - cc_msgbody_info_t *local_msg_body); -void sipSPISendInviteResponse(ccsipCCB_t *ccb, - uint16_t statusCode, - const char *reason_phrase, - uint16_t warnCode, - const char *warn_phrase, - boolean send_sd, - boolean retx); -void sipSPISendBye(ccsipCCB_t *ccb, - char *alsoString, - sipMessage_t *pForked200); -void sipSPISendCancel(ccsipCCB_t *ccb); -boolean sipSPISendByeOrCancelResponse(ccsipCCB_t *ccb, - sipMessage_t *request, - sipMethod_t sipMethodByeorCancel); -boolean sipSPISendAck(ccsipCCB_t *ccb, sipMessage_t *response); -boolean sipSPISendRegister(ccsipCCB_t *ccb, - boolean no_dns_lookup, - const char *user, - int expires_int); - -boolean sipSPISendErrorResponse(sipMessage_t *msg, uint16_t status_code, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - ccsipCCB_t *ccb); -boolean sipSPISendLastMessage(ccsipCCB_t *ccb); -boolean sipSPIGenerateAuthorizationResponse(sip_authen_t * sip_authen, - const char *uri, - const char *method, - const char *user_name, - const char *user_password, - char **author_str, - int *nc_count, - ccsipCCB_t *ccb); -void sipSPIGenerateGenAuthorizationResponse(ccsipCCB_t *ccb, - sipMessage_t *request, - sipRet_t *flag, - char *method); - -void sipSPIGenerateTargetUrl(genUrl_t *genUrl, char *sipurlstr); -void sipSPIGenerateSipUrl(sipUrl_t *sipUrl, char *sipurlstr); - -boolean sipSPISendRefer(ccsipCCB_t *ccb, char *referto, - sipRefEnum_e referto_type); -boolean sipSPISendReferResponse202(ccsipCCB_t *ccb); -boolean sipSPISendNotify(ccsipCCB_t *ccb, int referto); -boolean sipSPISendInfo(ccsipCCB_t *ccb, const char *info_package, - const char *content_type, const char *message_body); -boolean sipSPISendUpdate(ccsipCCB_t *ccb); -boolean sipSPISendUpdateResponse(ccsipCCB_t *ccb, - boolean send_sdp, - cc_causes_t cause, - boolean retx); -boolean sipSPISendNotifyResponse(ccsipCCB_t *ccb, cc_causes_t cause); -boolean sipSPIAddStdHeaders(sipMessage_t *msg, - ccsipCCB_t *ccb, - boolean isResponse); -sipMessage_t *sipSPIBuildRegisterHeaders(ccsipCCB_t *ccb, - const char *user, - int expires_int); -boolean sipSPIAddLocalVia(sipMessage_t *msg, - ccsipCCB_t *ccb, - sipMethod_t method); -boolean sipSPIAddRequestVia(ccsipCCB_t *ccb, - sipMessage_t *response, - sipMessage_t *request, - sipMethod_t method); -boolean sipSPIAddCiscoGuid(sipMessage_t *msg, ccsipCCB_t *ccb); -boolean sipSPIAddRouteHeaders(sipMessage_t *msg, - ccsipCCB_t *ccb, - char *result_route, - int result_route_length); -sipRet_t sipAddDateHeader(sipMessage_t *sip_message); - -const char *sipGetMethodString(sipMethod_t methodname); - -void sip_option_response_rtp_media_get_info(cc_sdp_t *src_sdp); - -//sipSdp_t* CreateSDPtext(); - - -sipRet_t sipSPIAddContactHeader(ccsipCCB_t *ccb, sipMessage_t *request); -sipRet_t sipSPIAddReasonHeader (ccsipCCB_t *ccb, sipMessage_t *request); -boolean sipSPIGenerateReferredByHeader(ccsipCCB_t *ccb); -boolean sipSPIGenRequestURI(ccsipCCB_t *ccb, - sipMethod_t sipmethod, - boolean initInvite); - -// Message Factory -sipRet_t sipSPIAddCommonHeaders(ccsipCCB_t *ccb, - sipMessage_t *request, - boolean isResponse, - sipMethod_t method, - uint32_t response_cseq_number); -boolean CreateRequest(ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - sipMethod_t sipmethod, - sipMessage_t *request, - boolean initInvite, - uint32_t response_cseq_number); -boolean CreateResponse(ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - uint16_t status_code, - sipMessage_t *response, - const char *reason_phrase, - uint16_t status_code_warning, - const char *reason_phrase_warning, - sipMethod_t); -boolean SendRequest(ccsipCCB_t *ccb, - sipMessage_t *request, - sipMethod_t method, - boolean midcall, - boolean reTx, - boolean timer); -boolean AddGeneralHeaders(ccsipCCB_t *ccb, - sipMessageFlag_t messageflag, - sipMessage_t *request, - sipMethod_t method); -boolean getCSeqInfo(sipMessage_t *request, - sipCseq_t **request_cseq_structure); -int sipSPICheckRequest(ccsipCCB_t *ccb, sipMessage_t *request); -int sipSPICheckResponse(ccsipCCB_t *ccb, sipMessage_t *response); -int sipSPICheckContact(const char *pContactStr); - -void sipGetRequestMethod(sipMessage_t *pRequest, sipMethod_t *pMethod); -int sipGetResponseMethod(sipMessage_t *pResponse, sipMethod_t *pMethod); -int sipGetResponseCode(sipMessage_t *pResponse, int *pResponseCode); -int sipSPIIncomingCallSDP(ccsipCCB_t *ccb, - boolean call_hold, - boolean udpate_ver); -char *sipSPIUrlDestination(sipUrl_t *sipUrl); -int sipGetMessageCSeq(sipMessage_t *pMessage, uint32_t *pResultCSeqNumber, - sipMethod_t * pResultCSeqMethod); -void sipGetMessageToTag(sipMessage_t *pMessage, char *to_tag, - int to_tag_max_length); -boolean sipSPISendByeAuth(sipMessage_t *pResponse, - sipAuthenticate_t authen, - cpr_ip_addr_t *dest_ipaddr, - uint16_t dest_port, - uint32_t cseq_number, - char *alsoString, - char *last_call_route, - char *last_call_route_request_uri, - line_t previous_call_line); -void free_sip_message(sipMessage_t *message); -void sipSPISendFailureResponseAck(ccsipCCB_t *ccb, - sipMessage_t *response, - boolean prevcall, - line_t previous_call_line); -/* ICMP Unreachable handler routine */ -void sip_platform_icmp_unreachable_callback(void *ccyb, uint32_t ipaddr); -cc_disposition_type_t sip2ccdisp(uint8_t type); -cc_content_type_t sip2cctype(uint8_t type); - -/* Transaction record manipulation methods */ -int16_t get_last_request_trx_index(ccsipCCB_t *ccb, boolean sent); -int16_t get_next_request_trx_index(ccsipCCB_t *ccb, boolean sent); -int16_t get_method_request_trx_index(ccsipCCB_t *ccb, sipMethod_t method, - boolean sent); -void clean_method_request_trx(ccsipCCB_t *ccb, sipMethod_t method, boolean sent); -line_t get_dn_line_from_dn(const char *watcher); -boolean sipSPIGenerateRouteHeaderUAC(sipRecordRoute_t *, char *, int, - boolean *loose_routing); -boolean sipSPIGenerateRouteHeaderUAS(sipRecordRoute_t *, char *, int, - boolean *loose_routing); -boolean sipSPIGenerateContactHeader(sipContact_t *, char *, int); - -void get_reason_string(int unreg_reason, char *unreg_reason_str, int len); - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_platform.h b/libs/sipcc/core/sipstack/h/ccsip_platform.h deleted file mode 100644 index 36b8c92568..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_platform.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PLATFORM_H_ -#define _CCSIP_PLATFORM_H_ - -#include "phone_platform_constants.h" - -// SIP standard defines the max to be the path MTU if it is -// known, otherwise it should be 1500 -// We are defining the max message size to be 2560, 1500 + 1060 bytes of -// extended buffer space (which is also the same as the PacketBuffer size -// #define PKTBUF_SIZ 3072 defined in phone.h -#define SIP_UDP_MESSAGE_SIZE 3072 /* Max size of a SIP message */ - -/* Constants */ -#define MAX_SIP_URL_LENGTH 512 -#define MAX_SIP_TAG_LENGTH 256 -#define MAX_SIP_DISPLAYNAME_LENGTH 64 -#define VIA_BRANCH_LENGTH 16 - -/* - * MAX_SIP_DATE_LENGTH is used in ccsip_messaging for - * the SIP Date header routine. - * It has been defined here to be consistent with the rest - * of the defines for the SIP message - */ -#define MAX_SIP_DATE_LENGTH 63 //Extended for foreign language -#define CCSIP_START_CSEQ 100 -#define MAX_SIP_CALL_ID 128 /* Max size of a Call ID header string */ -#define MAX_DIVERSION_HEADERS 25 - -/********************************************************* - * - * - * Phone constants - * - * - *********************************************************/ -#define MAX_REG_BACKUP 1 // Max number of backup registration CCBs -#define MIN_TEL_LINES 0 // Min number of lines -#define MAX_TEL_LINES MAX_CALLS // Max number of calls -#define MAX_PHYSICAL_DIR_NUM 6 // Max number of physical directory numbers -#define MAX_UI_LINES_PER_DN (MAX_LINES_PER_DN + 1) // Max number of lines per DN -#define MAX_CCBS (MAX_TEL_LINES + MAX_REG_LINES + MAX_REG_BACKUP) -#define TEL_CCB_START (MIN_TEL_LINES) -#define TEL_CCB_END (TEL_CCB_START + MAX_TEL_LINES -1) -#define REG_CCB_START (TEL_CCB_END + 1) -#define REG_CCB_END (REG_CCB_START + MAX_REG_LINES -1) -#define REG_BACKUP_CCB (REG_CCB_END + 1) -#define REG_FALLBACK_CCB_START (REG_BACKUP_CCB + 1) -#define REG_FALLBACK_CCB_END (REG_FALLBACK_CCB_START +4) -#define REG_BACKUP_DN 1 -#define REG_BACKUP_LINE 7 -#define MAX_LINES_7940 2 -#define INVALID_DN_LINE (REG_FALLBACK_CCB_END + 1) -#define INIT_DN_LINE 0 - - -void sip_platform_init(void); -int sip_platform_ui_restart(void); -extern void platform_print_sip_msg(const char *msg); - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_platform_tcp.h b/libs/sipcc/core/sipstack/h/ccsip_platform_tcp.h deleted file mode 100644 index 21c0b0342d..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_platform_tcp.h +++ /dev/null @@ -1,99 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CCSIP_PLATFORM_TCP__H__ -#define __CCSIP_PLATFORM_TCP__H__ - -/* The maximum number of connections allowed */ -#define MAX_SIP_CONNECTIONS (64 - 2) - -#define SIP_TCP_SEND_OK 0 -#define SIP_TCP_SIZE_ERROR 1 -#define SIP_TCP_SEND_ERROR 2 -#define SIP_SOC_TCP 0 -#define SIP_SOC_TLS 1 - -#define SIP_TCP_NOT_CONNECTED 0 -#define SIP_TCP_CONNECTED 1 - -typedef struct _sendData -{ - struct _sendData *next; - char *data; - uint16_t bytesLeft; - uint16_t bytesSent; - void *context; - boolean msg_display; - uint8_t ip_sig_tos; -} ccsipTCPSendData_t; - -typedef struct -{ - uint16 connectionId; -} sipTCPTimerContext_t; - -typedef struct -{ - cpr_socket_t fd; /* Socket file descriptor */ - cpr_sockaddr_storage addr; - cpr_ip_addr_t ipaddr; /* Remote IP address */ - uint16_t port; /* Remote port # */ - sock_state_t state; - char *prev_msg; - uint32_t prev_bytes; - void *context; /* Connection Manager's context */ - /* queue for partial socket writes */ - sll_handle_t sendQueue; - boolean dirtyFlag; - boolean pend_closure; /* Indicates to close the connection - * entry on completion of partial - * socket message writes - */ - int error_cause; - int soc_type; -} sip_tcp_conn_t; - -typedef struct -{ - cpr_socket_t read[MAX_SIP_CONNECTIONS]; - cpr_socket_t write[MAX_SIP_CONNECTIONS]; -} sip_connection_t; - - -extern sip_connection_t sip_conn; -extern uint32_t nfds; -extern fd_set read_fds; -extern fd_set write_fds; -extern sip_tcp_conn_t sip_tcp_conn_tab[MAX_CONNECTIONS]; - -/* - * - * Function declarations - * - */ -int sip_tcp_fd_to_connid(cpr_socket_t fd); -cpr_socket_t sip_tcp_create_connection(sipSPIMessage_t *spi_msg); -void sip_tcp_read_socket(cpr_socket_t this_fd); -int sip_tcp_channel_send(cpr_socket_t s, - char *buf, - uint32_t len); -void sip_tcp_createconnfailed_to_spi(cpr_ip_addr_t *ipaddr, - uint16_t port, - void *context, - ccsipSockErrCodes_e errcode, - int connid); -void sip_tcp_purge_entry(sipSPIConnId_t connid); -void sipTcpFlushRetrySendQueue(sip_tcp_conn_t *entry); -void sip_tcp_resend(int connid); -extern int sip_tcp_get_free_conn_entry(void); -extern int sip_tcp_attach_socket(cpr_socket_t s); -extern void sip_tcp_init_conn_table(void); -extern boolean sip_tcp_set_sock_options(int fd); -void sipTransportClearServerHandle(cpr_ip_addr_t *ipaddr, - uint16_t port, - int connid); -void sipTcpFreeSendQueue(int connid); -extern cpr_socket_t sip_tcp_create_conn_using_blocking_socket (sipSPIMessage_t *spi_msg); - -#endif /* __CCSIP_PLATFORM_TCP__H__ */ diff --git a/libs/sipcc/core/sipstack/h/ccsip_platform_timers.h b/libs/sipcc/core/sipstack/h/ccsip_platform_timers.h deleted file mode 100644 index 06a6f54a26..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_platform_timers.h +++ /dev/null @@ -1,164 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PLATFORM_TIMERS_H_ -#define _CCSIP_PLATFORM_TIMERS_H_ - -#include "cpr_types.h" -#include "cpr_timers.h" -#include "ccsip_platform.h" -#include "ccsip_pmh.h" - -#define LINE_NOT_FOUND -1 - -/* - * Defintions - */ -typedef void (*sipTimerCallbackFn_t)(cprTimer_t pTmrBlk); - -typedef struct -{ - cprTimer_t timer; - cprTimer_t reg_timer; - int line; - char* message_buffer; - int message_buffer_len; - sipMethod_t message_type; - cpr_ip_addr_t ipaddr; - uint16_t port; - boolean outstanding; -} sipPlatformUITimer_t; - -typedef struct -{ - cprTimer_t timer; - int line; - cpr_ip_addr_t ipaddr; - uint16_t port; -} sipPlatformUIExpiresTimer_t; - -typedef struct -{ - cprTimer_t timer; - int line; - boolean started; -} sipPlatformSupervisionTimer_t; - - -extern sipPlatformUITimer_t sipPlatformUISMSubNotTimers[]; // Array of timers - -/* - * Prototypes - */ -int -sip_platform_timers_init(void); -void -sip_platform_post_timer(uint32_t cmd, void *data); -void -sip_platform_msg_timers_init(void); -int -sip_platform_msg_timer_start(uint32_t msec, - void *data, - int line, - char *message_buffer, - int message_buffer_len, - int message_type, - cpr_ip_addr_t *ipaddr, - uint16_t port, - boolean isRegister); -void -sip_platform_msg_timer_stop(int line); -boolean -sip_platform_msg_timer_outstanding_get(int line); -void -sip_platform_msg_timer_outstanding_set(int line, boolean value); -void -sip_platform_msg_timer_callback(void *data); -int -sip_platform_expires_timer_start(uint32_t msec, - int line, - cpr_ip_addr_t *ipaddr, - uint16_t port); -int -sip_platform_expires_timer_stop(int line); -void -sip_platform_expires_timer_callback(void *data); -int -sip_platform_register_expires_timer_start(uint32_t msec, - int line); -int -sip_platform_register_expires_timer_stop(int line); -int -sip_platform_localexpires_timer_start(uint32_t msec, - int line, - cpr_ip_addr_t *ipaddr, - uint16_t port); -int -sip_platform_localexpires_timer_stop(int line); -void -sip_platform_localexpires_timer_callback(void *data); -int -sip_platform_msg_timer_update_destination(int line, - cpr_ip_addr_t *ipaddr, - uint16_t port); -sipMethod_t -sip_platform_msg_timer_messageType_get(int line); - -// Supervision timer -int -sip_platform_supervision_disconnect_timer_start(uint32_t msec, - int line); -int -sip_platform_supervision_disconnect_timer_stop(int line); -void -sip_platform_supervision_disconnect_timer_callback(void *data); - -// Sub/Not Timers -int -sip_platform_msg_timer_subnot_start(uint32_t msec, - sipPlatformUITimer_t *, - uint32_t index, - char *message_buffer, - int message_buffer_len, - int message_type, - cpr_ip_addr_t *ipaddr, - uint16_t port); -void -sip_platform_msg_timer_subnot_stop(sipPlatformUITimer_t *); -void -sip_platform_subnot_msg_timer_callback(void *data); -int -sip_platform_subnot_periodic_timer_start(uint32_t msec); -int -sip_platform_subnot_periodic_timer_stop(void); -void -sip_platform_subnot_periodic_timer_callback(void *data); -int -sip_platform_standby_keepalive_timer_start(uint32_t msec); -int -sip_platform_standby_keepalive_timer_stop(); -void -sip_platform_standby_keepalive_callback(void *data); -int -sip_platform_unregistration_timer_start(uint32_t msec, boolean external); -int -sip_platform_unregistration_timer_stop(); -void -sip_platform_unregistration_callback(void *data); -void -sip_platform_timers_shutdown(void); -int -sip_platform_notify_timer_start(uint32_t msec); -int -sip_platform_notify_timer_stop(); -int -sip_platform_reg_all_fail_timer_start(uint32_t msec); -int -sip_platform_reg_all_fail_timer_stop(void); -int -sip_platform_pass_through_timer_start(uint32_t sec); -int -sip_platform_pass_through_timer_stop(void); - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_platform_tls.h b/libs/sipcc/core/sipstack/h/ccsip_platform_tls.h deleted file mode 100644 index 6d6fba9378..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_platform_tls.h +++ /dev/null @@ -1,12 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __CCSIP_PLATFORM_TLS__H__ -#define __CCSIP_PLATFORM_TLS__H__ - -extern cpr_socket_t sip_tls_create_connection(sipSPIMessage_t *spi_msg, - boolean blocking, - sec_level_t sec); - -#endif /* __CCSIP_PLATFORM_TLS__H__ */ diff --git a/libs/sipcc/core/sipstack/h/ccsip_platform_udp.h b/libs/sipcc/core/sipstack/h/ccsip_platform_udp.h deleted file mode 100644 index 9eddc2094b..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_platform_udp.h +++ /dev/null @@ -1,46 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PLATFORM_UDP_H_ -#define _CCSIP_PLATFORM_UDP_H_ - -#include "cpr_types.h" -#include "cpr_socket.h" -#include "cpr_memory.h" - -int -sip_platform_udp_channel_listen(cpr_ip_mode_e ip_mode, cpr_socket_t *s, - cpr_ip_addr_t *local_ipaddr, - uint16_t local_port); -int -sip_platform_udp_channel_accept(cpr_socket_t listenSoc, - cpr_socket_t *s); -int -sip_platform_udp_channel_create(cpr_ip_mode_e ip_mode, cpr_socket_t *s, - cpr_ip_addr_t *remote_ipaddr, - uint16_t remote_port, - uint32_t local_udp_port); -int -sip_platform_udp_channel_destroy(cpr_socket_t s); -int -sip_platform_udp_channel_send(cpr_socket_t s, - char *buf, - uint16_t buf_len); -void -sip_platform_udp_read_socket(cpr_socket_t s); - -int -sip_platform_udp_channel_sendto(cpr_socket_t s, - char *buf, - uint32_t buf_len, - cpr_ip_addr_t *dst_addr, - uint16_t dst_port); -int -sip_platform_udp_channel_read(cpr_socket_t s, - cprBuffer_t buf, - uint16_t *len, - cpr_sockaddr_t *soc_addr, - cpr_socklen_t *soc_addr_len); - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_pmh.h b/libs/sipcc/core/sipstack/h/ccsip_pmh.h deleted file mode 100644 index 303eddde74..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_pmh.h +++ /dev/null @@ -1,827 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PMH_H_ -#define _CCSIP_PMH_H_ - -#include "cpr_types.h" -#include "pmhdefs.h" -#include "httpish.h" -#include "ccsip_protocol.h" -#include "string_lib.h" -#include "ccsip_platform.h" -#include "ccapi.h" - -#define MAX_REFER_TO_HEADER_CONTENTS 6 -#define MAX_REMOTE_PARTY_ID_HEADERS 10 -#define MAX_REPLACES_HEADERS 1 -#define MAX_REFER_TO_HEADERS 2 -#define MAX_REFER_BY_HEADERS 1 -#define MAX_CALL_INFO_HEADERS 4 - -#define MAX_SUB_STATE_HEADER_SIZE 96 -#define TEMP_PARSE_BUFFER_SIZE 10 - -/* - * Maximum number of Location/Contact headers we will parse. These - * specify the locations to try to contact the called party, and I figure - * the user is not going to wait for ever, and simplicity helps. - */ -#define SIP_MAX_LOCATIONS 6 - -/* Used when we create Via headers. Does not apply to incoming messages.*/ -#define SIP_MAX_VIA_LENGTH 128 - -/* Broadsoft: Max length of "other" parameters in 3xx messages. */ -#define SIP_MAX_OTHER_PARAM_LENGTH 256 - -#define TWO_POWER_31 2147483648UL - -/* - * Some of this corresponds directly to HTTP/1.1 message structure. - */ -typedef httpish_header sip_header; -typedef httpishMsg_t sipMessage_t; -typedef httpishReqLine_t sipReqLine_t; -typedef httpishRespLine_t sipRespLine_t; - -typedef httpishStatusCodeClass_t sipStatusCodeClass_t; - -typedef hStatus_t sipRet_t; - -typedef enum -{ - sipMethodInvalid = 0, - sipMethodRegister = 100, - sipMethodOptions, - sipMethodInvite, - sipMethodBye, - sipMethodCancel, - sipMethodPrack, - sipMethodComet, - sipMethodNotify, - sipMethodRefer, - sipMethodAck, - sipMethodMessage, - sipMethodSubscribe, - sipMethodPublish, - sipMethodUpdate, - sipMethodResponse, - sipMethodInfo, - sipMethodUnknown -} sipMethod_t; - -typedef enum -{ - SIP_BASIC = 1, - SIP_DIGEST, - SIP_UNKNOWN -} sip_scheme_t; - -typedef enum -{ - SIP_SUCCESS, - SIP_FAILURE, - SIP_INTERNAL_ERR, - SIP_UNACCEPTABLE_MEDIA_ERR, - SIP_PRE_CONDITION_FAIL_ERR, - SIP_NO_RESOURCE, - SIP_MSG_CREATE_ERR, - SIP_MSG_PARSE_ERR, - SIP_MSG_INCOMPLETE_ERR, - SIP_SUCCESS_DNS_PENDING, - SIP_SUCCESS_QOS_PENDING, - SIP_VIA_DNS_QUERY_REQUIRED, - SIP_SUCCESS_QOS_DNS_PENDING, - SIP_SUCCESS_DELAYED_MEDIA, - SIP_SUCCESS_QOS_DELAYED_MEDIA, - SIP_ADDR_UNAVAILABLE, - SIP_MAX_RC -} ccsipRet_e; - -/* This is used to store the parsed attribute/value pair */ -typedef struct { - char *attr; - char *value; -} attr_value_pair_t; - -typedef struct -{ - /* - * Not storing the schema because we don't deal with non-SIP URLs. - * The rest of the fields do not have any meaning if the URL - * in question is non-SIP. Our parse routine itself would return - * failure. - */ - char *user; - char *password; - char *host; - char *maddr; - char *other; - char *method; - uint16_t port; - boolean port_present; - int16_t transport; - uint8_t is_phone; - uint8_t ttl_val; - char num_headers; /* number of headers in the avpair below */ - attr_value_pair_t *headerp; /* everything after the '?' */ - boolean lr_flag; - boolean is_ipv6; -} sipUrl_t; - -typedef struct -{ - char *user; - char *isdn_subaddr; - char *post_dial; - char *unparsed_tsp; - char *future_ext; -} telUrl_t; - -typedef enum -{ - URL_TYPE_SIP = 1, - URL_TYPE_TEL, - URL_TYPE_CID, - URL_TYPE_UNKNOWN -} urlType_t; - -typedef struct -{ - urlType_t schema; - boolean sips; - char *str_start; - char *phone_context; - char *other_params[SIP_MAX_LOCATIONS]; - union { - sipUrl_t *sipUrl; - telUrl_t *telUrl; - } u; -} genUrl_t; - -typedef struct -{ - char *str_start; /* beginning of duplicated string */ - sip_scheme_t scheme; - char *user_pass; - char *realm; - char *d_username; - char *unparsed_uri; - char *response; - char *algorithm; - char *cnonce; - char *opaque; - char *qop; - char *nc_count; - char *auth_param; /* for future extension */ - char *nonce; -} sip_author_t; - -typedef struct -{ - /* Could be Basic or PGP */ - char *str_start; /* beginning of duplicated string */ - sip_scheme_t scheme; - char *user_pass; - char *realm; - char *version; - char *algorithm; - char *nonce; - char *unparsed_domain; - char *opaque; - char *stale; - char *qop; -} sip_authen_t; - -typedef struct _sipLocation_t -{ - char *loc_start; - char *name; - genUrl_t *genUrl; - char *tag; -} sipLocation_t; - -typedef sipLocation_t sipFrom_t; -typedef sipLocation_t sipTo_t; - -/* - * Definition of the flags in the sipContactParams_t. - * The flags in the sipContact_t is used to store boolean - * parameters (not numerical value). - */ -#define SIP_CONTACT_PARM_X_CISCO_NEWREG (1 << 0) /* new reg parameter */ -typedef struct -{ - int action; /* Proxy or Redirect */ - char *qval; - uint32_t expires; - char *expires_gmt; - char *extn_attr; - uint32_t flags; -} sipContactParams_t; - -typedef struct -{ - sipLocation_t *locations[SIP_MAX_LOCATIONS]; - sipContactParams_t params[SIP_MAX_LOCATIONS]; - uint16_t num_locations; - boolean new_flag; -} sipContact_t; - -typedef struct -{ - sipLocation_t *locations[SIP_MAX_LOCATIONS]; - uint16_t num_locations; - boolean new_flag; -} sipRecordRoute_t; - -typedef enum -{ - sipTransportTypeUDP = 2345, - sipTransportTypeTCP -} sipTransportType_t; - -/* DIVERSION HEADER STRUCTURE */ - -typedef struct -{ - sipLocation_t *locations; -// char *reason; - uint32_t limit; - uint32_t counter; - char *privacy; - char *screen; -} sipDiversion_t; - -typedef struct -{ - string_t orig_called_name; - string_t orig_called_number; - string_t last_redirect_name; - string_t last_redirect_number; -} sipDiversionInfo_t; - - -typedef struct -{ - /* - * We are not storing the protocol ( should be SIP always ) - */ - char *version; - char *transport; - char *host; - char *ttl; - char *maddr; - char *recd_host; - char *branch_param; - /* Remaining Via header(s) if any in the input string */ - char *more_via; - uint16_t remote_port; - uint8_t flags; - boolean is_ipv6; -#define VIA_IS_HIDDEN (0x01) -} sipVia_t; - -typedef struct -{ - uint32_t number; - sipMethod_t method; -} sipCseq_t; - - -typedef struct -{ - uint32_t response_num; - uint32_t cseq_num; - sipMethod_t method; -} sipRack_t; - -typedef enum -{ - sipSessionTypeInvalid = 0, - sipSessionTypeMedia, - sipSessionTypeQoS, - sipSessionTypeSecurity -} sipSessionType_t; - -/* Data structure for Replaces header */ -typedef struct -{ - char *str_start; - char *callid; - char *toTag; - char *fromTag; - char *signature_scheme; -} sipReplaces_t; - -/* Data structure for Refer-To header */ -typedef struct -{ - char *ref_to_start; - genUrl_t *targetUrl; - char *sip_replaces_hdr; - char *sip_acc_cont; - char *sip_proxy_auth; -} sipReferTo_t; - -/* Data structure for Refer method */ -typedef struct -{ - sipReferTo_t *refer_to_info; /* Refer-To header */ - const char *referred_by_info; /* Referred-by header */ -} sipRefer_t; - -/* Data structures for Remote-Party-Id */ -typedef struct -{ - sipLocation_t *loc; - char *screen; - char *party_type; - char *id_type; - char *privacy; - char *np; -} sipRemotePartyId_t; - -typedef struct -{ - unsigned int num_rpid; /* Number of rpid instantiations present */ - sipRemotePartyId_t *rpid[MAX_REMOTE_PARTY_ID_HEADERS]; -} sipRemotePartyIdInfo_t; - -typedef enum -{ - SUBSCRIPTION_STATE_INVALID = 0, - SUBSCRIPTION_STATE_ACTIVE, - SUBSCRIPTION_STATE_PENDING, - SUBSCRIPTION_STATE_TERMINATED -} sip_subs_state_e; - -typedef enum -{ - SUBSCRIPTION_STATE_REASON_INVALID = 0, - SUBSCRIPTION_STATE_REASON_DEACTIVATED, - SUBSCRIPTION_STATE_REASON_PROBATION, - SUBSCRIPTION_STATE_REASON_REJECTED, - SUBSCRIPTION_STATE_REASON_TIMEOUT, - SUBSCRIPTION_STATE_REASON_GIVEUP, - SUBSCRIPTION_STATE_REASON_NORESOURCE -} sip_subs_state_reason_e; - -typedef struct -{ - sip_subs_state_e state; - uint32_t expires; - sip_subs_state_reason_e reason; - uint32_t retry_after; -} sipSubscriptionStateInfo_t; - -typedef enum { - SERVICE_CONTROL_ACTION_INVALID = 0, - SERVICE_CONTROL_ACTION_RESET, - SERVICE_CONTROL_ACTION_RESTART, - SERVICE_CONTROL_ACTION_CHECK_VERSION, - SERVICE_CONTROL_ACTION_CALL_PRESERVATION, - SERVICE_CONTROL_ACTION_APPLY_CONFIG -} sip_service_control_action_e; - -typedef struct -{ - sip_service_control_action_e action; - char *registerCallID; - char *configVersionStamp; - char *dialplanVersionStamp; - char *softkeyVersionStamp; - char *fcpVersionStamp; - char *cucm_result; - char *firmwareLoadId; - char *firmwareInactiveLoadId; - char *loadServer; - char *logServer; - boolean ppid; -} sipServiceControl_t; - -typedef struct -{ - char *call_id; - char *from_tag; - char *to_tag; -} sipJoinInfo_t; - -typedef enum { - mwiVoiceType = 1, - mwiFaxType, - mwiTextMessage -} messageCountType_t; - -typedef struct { - boolean mesg_waiting_on; - int32_t type; - int32_t newCount; - int32_t oldCount; - int32_t hpNewCount; - int32_t hpOldCount; -} sipMessageSummary_t; - -/* - * Returns a sipMethod_t value given a character method name. - * Returns sipMethodUnknown if the method is not on the list of recognized - * methods. - */ -PMH_EXTERN sipMethod_t sippmh_get_method_code(const char *); - -PMH_EXTERN genUrl_t *sippmh_parse_url(char *url, boolean dup_flag); - -/* - * See comment above. - */ -PMH_EXTERN void sippmh_genurl_free(genUrl_t *); - -PMH_EXTERN sipLocation_t *sippmh_parse_from_or_to(char *from, boolean dup_flag); - -PMH_EXTERN sipLocation_t *sippmh_parse_nameaddr_or_addrspec(char *input_loc_ptr, - char *start_ptr, - boolean dup_flag, - boolean name_addr_only_flag, - char **more_ptr); - -/* - * See comment above. - */ -PMH_EXTERN void sippmh_free_location(sipLocation_t *); - -/* - * Same comments as parse_location - */ -PMH_EXTERN sipContact_t *sippmh_parse_contact(const char *contact); - - -/* - * Same comments as parse_location - */ -PMH_EXTERN sipDiversion_t *sippmh_parse_diversion(const char *diversion, - char *diversionhead); - - -/* - * Same comments as free_location. - */ -PMH_EXTERN void sippmh_free_diversion(sipDiversion_t *); - -PMH_EXTERN void sippmh_free_diversion_info(sipDiversionInfo_t *div_info); - -/* - * Same comments as free_location. - */ -PMH_EXTERN void sippmh_free_contact(sipContact_t *); - -/* - * Same comments as parse_location - */ -PMH_EXTERN sipVia_t *sippmh_parse_via(const char *via); - -/* - * Same comments as free_location. - */ -PMH_EXTERN void sippmh_free_via(sipVia_t *via); - -PMH_EXTERN void sippmh_process_via_header(sipMessage_t *sip_message, - cpr_ip_addr_t *source_ip_address); - -/* - * Same comments as parse_location - */ -PMH_EXTERN sipCseq_t *sippmh_parse_cseq(const char *cseq); - -PMH_EXTERN boolean sippmh_parse_rseq(const char *rseq, uint32_t *rseq_val); - -PMH_EXTERN sipRack_t *sippmh_parse_rack(const char *rack); - -/* - * Does a proper comparison of From: headers.(kind of like - * a URL comparison. - * TRUE if equal, FALSE if not. - */ -PMH_EXTERN boolean sippmh_are_froms_equal(sipFrom_t *from1, sipFrom_t *from2); - -/* - * Does a proper comparison of To: headers.(kind of like - * a URL comparison. - * TRUE if equal, FALSE if not. - * At this time, sipTo is really the sipLocation struct, but - * this is kept different in case things change. - */ -PMH_EXTERN boolean sippmh_are_tos_equal(sipTo_t *to1, sipTo_t *to2); - -/* - * Does a comparison of SIP URLs. - * TRUE if equal, FALSE if not. - */ -PMH_EXTERN boolean sippmh_are_urls_equal(sipUrl_t *url1, sipUrl_t *url2); - -/* - * Utility to get the callid of a message. - * Returns NULL if the header is not found. - * Returned pointer should not be freed. - */ -//PMH_EXTERN const char *sippmh_get_callid(sipMessage_t *msg); - -/* - * Adds a Cseq: header to the message. - * msg = sipMessage_t struct - * method, seq = method, seq in the Cseq eg Cseq: 428 INVITE - * Assumes that the maximum length of the resulting header is - * less than 32 characters. - */ -PMH_EXTERN sipRet_t sippmh_add_cseq(sipMessage_t *msg, const char *method, - uint32_t seq); - -PMH_EXTERN sipRet_t sippmh_add_rack(sipMessage_t *msg, uint32_t rseq, - uint32_t cseq, const char *method); - -/* - * Utility to check whether the URL is valid. - * TRUE if yes, FALSE if not. - */ -PMH_EXTERN boolean sippmh_valid_url(genUrl_t *genUrl); - -PMH_EXTERN boolean sippmh_valid_reqline_url(genUrl_t *genUrl); - -PMH_EXTERN sipRecordRoute_t *sippmh_parse_record_route(const char *); - -PMH_EXTERN sipRecordRoute_t *sippmh_copy_record_route (sipRecordRoute_t *rr); - -PMH_EXTERN void sippmh_free_record_route(sipRecordRoute_t *); - -PMH_EXTERN cc_content_disposition_t *sippmh_parse_content_disposition(const char *input_content_disp); - -PMH_EXTERN sipReferTo_t *sippmh_parse_refer_to(char *ref_to); - -PMH_EXTERN sipReplaces_t *sippmh_parse_replaces(char *replcs, boolean dup_flag); - -PMH_EXTERN void sippmh_free_replaces(sipReplaces_t *repl); - -PMH_EXTERN void sippmh_free_refer_to(sipReferTo_t *ref); - -PMH_EXTERN void sippmh_free_refer(sipRefer_t *ref); - -PMH_EXTERN void sippmh_convertEscCharToChar(const char *inputStr, - size_t inputStrLen, - char *outputStr); - -PMH_EXTERN int sippmh_cmpURLStrings(const char *s1, const char *s2, - boolean ignore_case); - -PMH_EXTERN sip_author_t *sippmh_parse_authorization(const char *); - -PMH_EXTERN char *sippmh_generate_authorization(sip_author_t *); - -PMH_EXTERN void sippmh_free_author(sip_author_t *); - -PMH_EXTERN sip_authen_t *sippmh_parse_authenticate(const char *); - -PMH_EXTERN void sippmh_free_authen(sip_authen_t *); - -PMH_EXTERN sip_author_t *sippmh_parse_proxy_author(const char *); - -PMH_EXTERN sip_authen_t *sippmh_parse_proxy_authen(const char *); - -PMH_EXTERN sipRemotePartyId_t *sippmh_parse_remote_party_id( - const char *input_remote_party_id); - -PMH_EXTERN boolean sippmh_parse_kpml_event_id_params(char *params, - char **call_id, - char **from_tag, - char **to_tag); - -PMH_EXTERN void sippmh_free_remote_party_id_info(sipRemotePartyIdInfo_t *rpid_info); - -PMH_EXTERN char *sippmh_parse_user(char *url); - -PMH_EXTERN int sippmh_parse_subscription_state(sipSubscriptionStateInfo_t *subsStateInfo, - const char *subs_state); - -PMH_EXTERN int sippmh_add_subscription_state(sipMessage_t *msg, - sipSubscriptionStateInfo_t *subsStateInfo); - -string_t sippmh_parse_displaystr(string_t displaystr); - -#define sippmh_parse_to(x) sippmh_parse_location(x) - -#define sippmh_free_to(x) sippmh_free_location(x) - -#define sippmh_parse_from(x) sippmh_parse_location(x) - -#define sippmh_free_from(x) sippmh_free_location(x) - -PMH_EXTERN int sippmh_add_call_info(sipMessage_t *sipMessage, - cc_call_info_t *callInfo); - -PMH_EXTERN uint32_t sippmh_parse_supported_require(const char *header, - char **punsupported_options); - -PMH_EXTERN uint16_t sippmh_parse_allow_header(const char *header); - -PMH_EXTERN uint16_t sippmh_parse_accept_header(const char *header); - -PMH_EXTERN sipServiceControl_t - *sippmh_parse_service_control_body(char *msgBody, int msgLength); - -PMH_EXTERN void sippmh_free_service_control_info(sipServiceControl_t *scp); - -PMH_EXTERN sipJoinInfo_t *sippmh_parse_join_header(const char *header); - -PMH_EXTERN void sippmh_free_join_info(sipJoinInfo_t *join); - -PMH_EXTERN sipRet_t sippmh_add_join_header(sipMessage_t *message, - sipJoinInfo_t *join); - -PMH_EXTERN int32_t sippmh_parse_max_forwards(const char *max_fwd_hdr); - -PMH_EXTERN string_t sippmh_get_url_from_hdr(char *string); - -PMH_EXTERN int32_t sippmh_parse_message_summary(sipMessage_t *pSipMessage, sipMessageSummary_t *mesgSummary); - -/* - * The following SIP parser functions are the same as corresponding - * HTTP/1.1 message parser functions. - */ -#define sippmh_message_create() httpish_msg_create() - -#define sippmh_message_free( x ) httpish_msg_free( x ) - -#define sippmh_is_request( x ) httpish_msg_is_request( x , SIP_SCHEMA, SIP_SCHEMA_LEN) - -#define sippmh_is_message_complete( x ) httpish_msg_is_complete( x ) - -#define sippmh_get_request_line( x ) httpish_msg_get_reqline( x ) - -#define sippmh_get_response_line( x ) httpish_msg_get_respline( x ) - -#define sippmh_free_request_line( x ) httpish_msg_free_reqline( x ) - -#define sippmh_free_response_line( x ) httpish_msg_free_respline( x ) - -#define sippmh_process_network_message( x, y, z) \ - httpish_msg_process_network_msg( x, y, z) - -#define sippmh_get_code_class( x ) httpish_msg_get_code_class( x ) - -#define sippmh_add_request_line( x, y, a, b ) \ - httpish_msg_add_reqline( x, y, a, b ) - -#define sippmh_add_response_line( x, y , a, b) \ - httpish_msg_add_respline( x, y , a, b) - -#define sippmh_add_text_header( x, y, z ) \ - httpish_msg_add_text_header( x, y, z ) - -#define sippmh_add_int_header( x, y, z ) \ - httpish_msg_add_int_header( x, y, z ) - -#define sippmh_add_message_body( x, y, z, a, b, c, d) \ - httpish_msg_add_body(x, y, z, a, b, c, d) - -#define sippmh_remove_header( x, y ) \ - httpish_msg_remove_header( x, y ) - -#define sippmh_msg_header_present( x, y ) \ - httpish_msg_header_present(x, y) - -#define sippmh_get_header_val( x, y, c_y ) \ - httpish_msg_get_header_val( x, y, c_y ) - -#define sippmh_get_cached_header_val(x, y) \ - httpish_msg_get_cached_header_val(x, y) - -#define sippmh_get_content_length( x ) \ - httpish_msg_get_content_length( x ) - -#define sippmh_get_all_headers( x, y ) \ - httpish_msg_get_all_headers( x, y ) - -#define sippmh_write_to_buf( x, y ) \ - httpish_msg_write_to_buf( x, y ) - -#define sippmh_write( x, y, z ) \ - httpish_msg_write( x, y, z ) - -#define sippmh_write_to_string( x ) \ - httpish_msg_write_to_string( x ) - -#define sippmh_get_num_headers( x ) \ - httpish_msg_get_num_headers( x ) - -#define sippmh_get_num_particular_headers( a, b, c, d, e ) \ - httpish_msg_get_num_particular_headers( a, b, c, d, e ) - -#define sippmh_get_header_vals( a, b, c, d, e) \ - httpish_msg_get_header_vals( a, b, c, d, e) - - -#define SIPPMH_VERSIONS_EQUAL(a, b) \ - (cpr_strcasecmp(a, b) == 0) - -/* - * Utility to compare From: header values, given the values rather - * than the sipFrom_t struct. - * Returns TRUE if the same, FALSE if not. - * Expects NULL terminated strings. - */ -PMH_EXTERN boolean sippmh_compare_fromto(const char *a1, const char *a2); - -/* - * Same as compare_fromto, but for URL strings. - */ -PMH_EXTERN boolean sippmh_compare_urls(const char *u1, const char *u2); - -#define PARSE_ERR_NON_SIP_URL 1 -#define ERROR_1 SIP_F_PREFIX"Non-SIP URL\n" - -#define PARSE_ERR_NO_MEMORY 2 -#define ERROR_2 SIP_F_PREFIX"Out of memory\n" - -#define PARSE_ERR_SYNTAX 3 -#define ERROR_3 SIP_F_PREFIX"Syntax error at %s\n" -#define ERROR_3_1 SIP_F_PREFIX"Unexpected char %c\n" - -#define PARSE_ERR_UNEXPECTED_EOS 4 -#define ERROR_4 SIP_F_PREFIX"Unexpected end of string\n" - -#define PARSE_ERR_UNTERMINATED_STRING 5 -#define ERROR_5 SIP_F_PREFIX"Unmatched \"\n" - -#define PARSE_ERR_UNMATCHED_BRACKET 6 -#define ERROR_6 SIP_F_PREFIX"Unmatched <>\n" - -#define PARSE_ERR_INVALID_TTL_VAL 7 -#define ERROR_7 SIP_F_PREFIX"%d: Invalid ttl value(range 0-255)\n" - -#define PARSE_ERR_NULL_PTR 8 -#define ERROR_8 SIP_F_PREFIX"NULL Pointer\n" - -#define AT_SIGN '@' -#define SEMI_COLON ';' -#define COLON ':' -#define EQUAL_SIGN '=' -#define ESCAPE_CHAR '\\' -#define TILDA '~' -#define PERCENT '%' -#define STAR '*' -#define UNDERSCORE '_' -#define PLUS '+' -#define SINGLE_QUOTE '\'' -#define DOUBLE_QUOTE '"' -#define LEFT_ANGULAR_BRACKET '<' -#define RIGHT_ANGULAR_BRACKET '>' -#define LEFT_SQUARE_BRACKET '[' -#define RIGHT_SQUARE_BRACKET ']' -#define LEFT_PARENTHESIS '(' -#define RIGHT_PARENTHESIS ')' -#define DOLLAR_SIGN '$' -#define FORWARD_SLASH '/' -#define DOT '.' -#define DASH '-' -#define EXCLAMATION '!' -#define AMPERSAND '&' -#define COMMA ',' -#define QUESTION_MARK '?' -#define SPACE ' ' -#define TAB '\t' -#define NUMBER_SIGN '#' -#define LEFT_CURLY_BRACE '{' -#define RIGHT_CURLY_BRACE '}' -#define OR_SIGN '|' -#define CARET '^' -#define OPENING_SINGLE_QUOTE '`' - -#define PROXY 1 -#define REDIRECT 2 -#define TRANSPORT_UNSPECIFIED 0 -#define TRANSPORT_UDP 1 -#define TRANSPORT_TCP 2 -#define TRANSPORT_TLS 3 -#define TRANSPORT_SCTP 4 - -#define MAX_TTL_VAL 255 - -#define SIPPMH_FREE_REQUEST_LINE(x) sippmh_free_request_line(x); UTILFREE(x) -#define SIPPMH_FREE_RESPONSE_LINE(x) sippmh_free_response_line(x); UTILFREE(x) -#define SIPPMH_FREE_URL(x) sippmh_genurl_free(x); UTILFREE(x) -#define SIPPMH_FREE_MESSAGE(x) sippmh_free_message(x) ; UTILFREE(x) - -size_t sippmh_convertURLCharToEscChar(const char *inputStr, size_t inputStrLen, - char *outputStr, size_t outputStrSize, - boolean null_terminate); - -size_t sippmh_converQuotedStrToEscStr(const char *inputStr, size_t inputStrLen, - char *outputStr, size_t outputStrSize, - boolean null_terminate); - -ccsipRet_e ccsip_process_network_message(sipMessage_t **sipmsg_p, char **buf, - unsigned long *nbytes_used, - char **display_msg); - - -#endif /* _CCSIP_PMH_H_ */ diff --git a/libs/sipcc/core/sipstack/h/ccsip_protocol.h b/libs/sipcc/core/sipstack/h/ccsip_protocol.h deleted file mode 100644 index ca6033553b..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_protocol.h +++ /dev/null @@ -1,645 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PROTOCOL_H_ -#define _CCSIP_PROTOCOL_H_ - -#include "httpish_protocol.h" - -typedef struct sip_header_ -{ - char *hname; - char *c_hname; -} sip_header_t; - - -#define SIP_VERSION "SIP/2.0" -#define SIP_SCHEMA "SIP/" -#define SIP_SCHEMA_LEN 4 /* length of the SIP_SCHEMA as defined above */ - -/* Methods */ - -#define SIP_METHOD_OPTIONS "OPTIONS" -#define SIP_METHOD_INVITE "INVITE" -#define SIP_METHOD_BYE "BYE" -#define SIP_METHOD_CANCEL "CANCEL" -#define SIP_METHOD_REGISTER "REGISTER" -#define SIP_METHOD_ACK "ACK" -#define SIP_METHOD_PRACK "PRACK" -#define SIP_METHOD_COMET "COMET" -#define SIP_METHOD_NOTIFY "NOTIFY" -#define SIP_METHOD_REFER "REFER" -#define SIP_METHOD_UPDATE "UPDATE" -#define SIP_METHOD_INFO "INFO" -#define SIP_METHOD_MESSAGE "MESSAGE" -#define SIP_METHOD_PUBLISH "PUBLISH" -#define SIP_METHOD_SUBSCRIBE "SUBSCRIBE" - - -/* Headers */ -/* - * We maintain a direct pointer to the header value for the following - * headers. - * Cached headers : Begin - */ -#define FROM 0 -#define TO 1 -#define VIA 2 -#define CALLID 3 -#define CSEQ 4 -#define CONTACT 5 -#define CONTENT_LENGTH 6 -#define CONTENT_TYPE 7 -#define RECORD_ROUTE 8 -#define REQUIRE 9 -#define ROUTE 10 -#define SUPPORTED 11 -/* Cached headers : End */ - -#define SESSION 24 -#define EXPIRES 41 -#define LOCATION 42 -#define TIMESTAMP 43 -#define MAX_FORWARDS 44 -#define UNSUPPORTED 45 -#define ACCEPT 46 -#define ACCEPT_ENCODING 47 -#define ACCEPT_LANGUAGE 48 -#define ALLOW 49 -#define USER_AGENT 50 -#define SERVER 51 -#define DATE 52 -#define CISCO_GUID 53 -#define DIVERSION 54 -#define EVENT 55 -#define SESSION 24 -#define CALL_INFO 61 -#define JOIN 62 - -/* Session Header Types - indicates the purpose of SDP bodies */ -#define SESSION_MEDIA "Media" -#define SESSION_QOS "QoS" -#define SESSION_SECURITY "Security" - -/* Content-Disposition Types */ -#define SIP_CONTENT_DISPOSITION_UNKNOWN_VALUE 0 -#define SIP_CONTENT_DISPOSITION_RENDER_VALUE 1 -#define SIP_CONTENT_DISPOSITION_RENDER "render" -#define SIP_CONTENT_DISPOSITION_SESSION_VALUE 2 -#define SIP_CONTENT_DISPOSITION_SESSION "session" -#define SIP_CONTENT_DISPOSITION_ICON_VALUE 3 -#define SIP_CONTENT_DISPOSITION_ICON "icon" -#define SIP_CONTENT_DISPOSITION_ALERT_VALUE 4 -#define SIP_CONTENT_DISPOSITION_ALERT "alert" -#define SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE 5 -#define SIP_CONTENT_DISPOSITION_PRECONDITION "precondition" - -/* Content-Disposition Handling */ -#define DISPOSITION_HANDLING "handling" -#define DISPOSITION_HANDLING_REQUIRED "required" -#define DISPOSITION_HANDLING_OPTIONAL "optional" - -/* Some headers common to HTTP .some of the headers can be received - in compact form ( SIP_C_ .. indicates compact header form ) */ - -#define SIP_HEADER_CONTENT_LENGTH HTTPISH_HEADER_CONTENT_LENGTH -#define SIP_C_HEADER_CONTENT_LENGTH HTTPISH_C_HEADER_CONTENT_LENGTH -#define SIP_HEADER_CONTENT_TYPE HTTPISH_HEADER_CONTENT_TYPE -#define SIP_C_HEADER_CONTENT_TYPE "c" -#define SIP_HEADER_CONTENT_ENCODING HTTPISH_HEADER_CONTENT_ENCODING -#define SIP_C_HEADER_CONTENT_ENCODING "e" -#define SIP_HEADER_CONTENT_ID HTTPISH_HEADER_CONTENT_ID - -#define SIP_HEADER_USER_AGENT HTTPISH_HEADER_USER_AGENT -#define SIP_HEADER_SERVER HTTPISH_HEADER_SERVER -#define SIP_HEADER_DATE HTTPISH_HEADER_DATE - -#define SIP_HEADER_VIA HTTPISH_HEADER_VIA -#define SIP_C_HEADER_VIA "v" -#define SIP_HEADER_MAX_FORWARDS HTTPISH_HEADER_MAX_FORWARDS -#define SIP_HEADER_EXPIRES HTTPISH_HEADER_EXPIRES -#define SIP_HEADER_LOCATION HTTPISH_HEADER_LOCATION -#define SIP_C_HEADER_LOCATION "m" - -/* Headers specific to SIP .Some of the headers can be received in - compact form */ - -#define SIP_HEADER_FROM "From" -#define SIP_C_HEADER_FROM "f" -#define SIP_HEADER_TO "To" -#define SIP_C_HEADER_TO "t" -#define SIP_HEADER_CSEQ "CSeq" -#define SIP_HEADER_TIMESTAMP "Timestamp" -#define SIP_HEADER_CALLID "Call-ID" -#define SIP_C_HEADER_CALLID "i" -#define SIP_HEADER_REQUIRE "Require" -#define SIP_HEADER_SUPPORTED "Supported" -#define SIP_C_HEADER_SUPPORTED "k" -#define SIP_HEADER_UNSUPPORTED "Unsupported" -#define SIP_HEADER_CONTACT "Contact" -#define SIP_C_HEADER_CONTACT SIP_C_HEADER_LOCATION -#define SIP_HEADER_CISCO_GUID "Cisco-Guid" -#define SIP_HEADER_WARN "Warning" - -#define SIP_HEADER_ACCEPT "Accept" -#define SIP_HEADER_ACCEPT_ENCODING "Accept-Encoding" -#define SIP_HEADER_ACCEPT_LANGUAGE "Accept-Language" -#define SIP_HEADER_ALLOW "Allow" - -#define SIP_HEADER_RECORD_ROUTE "Record-Route" -#define SIP_HEADER_ROUTE "Route" -#define SIP_HEADER_SESSION "Session" -#define SIP_HEADER_ALSO "Also" -#define SIP_HEADER_REQUESTED_BY "Requested-By" -#define SIP_HEADER_DIVERSION "Diversion" -#define SIP_HEADER_CC_DIVERSION "CC-Diversion" -#define SIP_HEADER_CC_REDIRECT "CC-Redirect" -#define SIP_HEADER_ALERT_INFO "Alert-Info" - -#define SIP_HEADER_RSEQ "RSeq" -#define SIP_HEADER_RACK "RAck" -#define SIP_HEADER_CONTENT_DISP "Content-Disposition" - -/* call stats */ -#define SIP_RX_CALL_STATS "RTP-RxStat" -#define SIP_TX_CALL_STATS "RTP-TxStat" - -/* Spam Specific */ -#define SIP_HEADER_AUTHORIZATION "Authorization" -#define SIP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization" -#define SIP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate" -#define SIP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate" - -/* Refer parameters */ -#define SIP_HEADER_REFER_TO "Refer-To" -#define SIP_C_HEADER_REFER_TO "r" -#define SIP_HEADER_REFERRED_BY "Referred-By" -#define SIP_C_HEADER_REFERRED_BY "b" - -#define SIP_HEADER_REPLACES "Replaces" -#define SIP_HEADER_PROXY_AUTH "Proxy-Authorization" -#define SIP_HEADER_ACCEPT_CONTACT "Accept-Contact" -#define SIP_C_HEADER_ACCEPT_CONTACT "a" - -#define SIP_HEADER_REMOTE_PARTY_ID "Remote-Party-ID" - -#define SIP_HEADER_EVENT "Event" -#define SIP_C_HEADER_EVENT "o" - -#define SIP_HEADER_SIPIFMATCH "SIP-If-Match" -#define SIP_HEADER_SIPETAG "SIP-ETag" -#define SIP_HEADER_RETRY_AFTER "Retry-After" -#define SIP_HEADER_MIN_EXPIRES "Min-Expires" -#define SIP_HEADER_REASON "Reason" - -/* Event values */ -#define SIP_EVENT_REFER "refer" -#define SIP_EVENT_DIALOG "dialog" -#define SIP_EVENT_KPML "kpml" -#define SIP_EVENT_PRESENCE "presence" -#define SIP_EVENT_CONFIG "sip-profile" -#define SIP_EVENT_MWI "message-summary" - -/* Event param */ -#define SIP_EVENT_ID "id" - -/* Subscription states */ -#define SIP_HEADER_SUBSCRIPTION_STATE "Subscription-State" -#define SIP_SUBSCRIPTION_STATE_ACTIVE "active" -#define SIP_SUBSCRIPTION_STATE_PENDING "pending" -#define SIP_SUBSCRIPTION_STATE_TERMINATED "terminated" -/* Subscription state params */ -#define SIP_SUBSCRIPTION_STATE_EXPIRES "expires" -#define SIP_SUBSCRIPTION_STATE_REASON "reason" -#define SIP_SUBSCRIPTION_STATE_RETRY_AFTER "retry-after" -/* Subscription state reason values */ -#define SIP_SUBSCRIPTION_STATE_REASON_DEACTIVATED "deactivated" -#define SIP_SUBSCRIPTION_STATE_REASON_PROBATION "probation" -#define SIP_SUBSCRIPTION_STATE_REASON_REJECTED "rejected" -#define SIP_SUBSCRIPTION_STATE_REASON_TIMEOUT "timeout" -#define SIP_SUBSCRIPTION_STATE_REASON_GIVEUP "giveup" -#define SIP_SUBSCRIPTION_STATE_REASON_NORESOURCE "noresource" - -/* Content-Type values */ -#define SIP_CONTENT_TYPE_UNKNOWN_VALUE 0 -#define SIP_CONTENT_TYPE_UNKNOWN "application/unknown" - -#define SIP_CONTENT_TYPE_SDP_VALUE 1 -#define SIP_CONTENT_TYPE_SDP "application/sdp" - -#define SIP_CONTENT_TYPE_SIP_VALUE 2 -#define SIP_CONTENT_TYPE_SIP "application/sip" - -#define SIP_CONTENT_TYPE_SIPFRAG_VALUE 3 -#define SIP_CONTENT_TYPE_SIPFRAG "message/sipfrag" - -#define SIP_CONTENT_TYPE_DIALOG_VALUE 4 -#define SIP_CONTENT_TYPE_DIALOG "application/dialog-info+xml" - -#define SIP_CONTENT_TYPE_MWI_VALUE 5 -#define SIP_CONTENT_TYPE_MWI "application/simple-message-summary" - -#define SIP_CONTENT_TYPE_KPML_REQUEST_VALUE 6 -#define SIP_CONTENT_TYPE_KPML_REQUEST "application/kpml-request+xml" - -#define SIP_CONTENT_TYPE_KPML_RESPONSE_VALUE 7 -#define SIP_CONTENT_TYPE_KPML_RESPONSE "application/kpml-response+xml" - -#define SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE 8 -#define SIP_CONTENT_TYPE_REMOTECC_REQUEST "application/x-cisco-remotecc-request+xml" - -#define SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE 9 -#define SIP_CONTENT_TYPE_REMOTECC_RESPONSE "application/x-cisco-remotecc-response+xml" - -#define SIP_CONTENT_TYPE_CTI_VALUE 10 -#define SIP_CONTENT_TYPE_CTI "application/x-cisco-cti+xml" - -#define SIP_CONTENT_TYPE_CMXML_VALUE 11 -#define SIP_CONTENT_TYPE_CMXML "application/x-cisco-remotecc-cm+xml" - -#define SIP_CONTENT_TYPE_MULTIPART_MIXED_VALUE 12 -#define SIP_CONTENT_TYPE_MULTIPART_MIXED "multipart/mixed" - -#define SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE_VALUE 13 -#define SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE "multipart/alternative" - -#define SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE 14 -#define SIP_CONTENT_TYPE_TEXT_PLAIN "text/plain" - -#define SIP_CONTENT_TYPE_PRESENCE_VALUE 15 -#define SIP_CONTENT_TYPE_PRESENCE "application/pidf+xml" - -#define SIP_CONTENT_TYPE_CONFIGAPP_VALUE 16 -#define SIP_CONTENT_TYPE_CONFIGAPP "application/x-cisco-config+xml" - -#define SIP_CONTENT_TYPE_MEDIA_CONTROL "application/media_control+xml" - -/* Content-Type for multipart-mime */ -#define SIP_CONTENT_TYPE_MULTIPART "multipart/mixed" -#define SIP_CONTENT_BOUNDARY "boundary" -#define SIP_CONTENT_BOUNDARY_TEXT "uniqueBoundary" - -/* Content-Encoding */ -/* At this time identity is the only one recognize */ -#define SIP_CONTENT_ENCODING_IDENTITY "identity" -#define SIP_CONTENT_ENCODING_IDENTITY_VALUE 0 -#define SIP_CONTENT_ENCODING_UNKNOWN_VALUE 1 - -/* Call-info header */ -#define SIP_HEADER_CALL_INFO "Call-Info" -#define SIP_CALL_INFO_PURPOSE "Purpose" -#define SIP_CALL_INFO_PURPOSE_INFO "info" -#define SIP_CALL_INFO_PURPOSE_ICON "icon" -#define SIP_CALL_INFO_PURPOSE_CARD "card" -#define SIP_CALL_INFO_ORIENTATION "Orientation" -#define SIP_CALL_INFO_ORIENTATION_TO "To" -#define SIP_CALL_INFO_ORIENTATION_FROM "From" -#define SIP_CALL_INFO_SECURITY "Security" -#define SIP_CALL_INFO_SECURITY_UNKNOWN "Unknown" -#define SIP_CALL_INFO_SECURITY_AUTHENTICATED "Authenticated" -#define SIP_CALL_INFO_SECURITY_NOT_AUTHENTICATED "NotAuthenticated" - -/* via-params */ -#define MAX_TTL_VAL 255 -#define SIP_WELL_KNOWN_PORT 5060 -#define SIP_WELL_KNOWN_PORT_STR "5060" -#define VIA_HIDDEN "hidden" -#define VIA_TTL "ttl" -#define VIA_MADDR "maddr" -#define VIA_RECEIVED "received" -#define VIA_BRANCH "branch" -#define VIA_BRANCH_START "z9hG4bK" - -/* CC-Diversion Parameters */ -#define DIVERSION_REASON "reason" -#define DIVERSION_COUNTER "counter" -#define DIVERSION_LIMIT "limit" -#define DIVERSION_PRIVACY "privacy" -#define DIVERSION_SCREEN "screen" - -/* CC-Redirect Parameters */ -#define CC_REDIRECT_REASON "redir-reason" -#define CC_REDIRECT_COUNTER "redir-counter" -#define CC_REDIRECT_LIMIT "redir-limit" - -/* CC-Diversion Reason Parameter values */ -// REASON_UNKNOWN conflicts with winreg.h on Windows. -#ifdef REASON_UNKNOWN -#undef REASON_UNKNOWN -#endif -#define REASON_UNKNOWN "unknown" -#define REASON_USER_BUSY "user-busy" -#define REASON_NO_ANSWER "no-answer" -#define REASON_UNCONDITIONAL "unconditional" -#define REASON_DEFLECTION "deflection" -#define REASON_FOLLOW_ME "follow-me" -#define REASON_OUT_OF_SERVICE "out-of-service" -#define REASON_TIME_OF_DAY "time-of-day" -#define REASON_DO_NOT_DISTURB "do-not-disturb" -#define REASON_UNAVAILABLE "unavailable" -#define REASON_AWAY "away" - -/* Replaces parameters */ -#define SIGNATURE_SCHEME "scheme" -#define TO_TAG "to-tag" -#define FROM_TAG "from-tag" - -/* Remote-Party-Id parameters */ -#define RPID_SCREEN "screen" -#define RPID_PARTY_TYPE "party" -#define RPID_ID_TYPE "id-type" -#define RPID_PRIVACY "privacy" -#define RPID_NP "np" - -#define RPID_CALLBACK "x-cisco-callback-number=" - -#define RPID_SCREEN_LEN (sizeof(RPID_SCREEN) - 1) -#define RPID_PARTY_TYPE_LEN (sizeof(RPID_PARTY_TYPE) - 1) -#define RPID_ID_TYPE_LEN (sizeof(RPID_ID_TYPE) - 1) -#define RPID_PRIVACY_LEN (sizeof(RPID_PRIVACY) - 1) -#define RPID_NP_LEN (sizeof(RPID_NP) - 1) -#define RPID_CALLBACK_LEN (sizeof(RPID_CALLBACK) - 1) - -#define KPML_ID_CALLID "call-id" -#define KPML_ID_FROM_TAG "from-tag" -#define KPML_ID_TO_TAG "to-tag" -#define KPML_ID_CALLID_LEN (sizeof(SIP_HEADER_CALLID)-1) -#define KPML_ID_FROM_TAG_LEN (sizeof(FROM_TAG)-1) -#define KPML_ID_TO_TAG_LEN (sizeof(TO_TAG)-1) - -#define PRIVACY_OFF "off" -#define PRIVACY_NAME "name" -#define PRIVACY_URI "uri" -#define PRIVACY_FULL "full" -#define SCREEN_NO "no" -#define SCREEN_YES "yes" -#define PARTY_TYPE_CALLING "calling" -#define PARTY_TYPE_CALLED "called" - -#define SIP_HEADER_ALLOW_EVENTS "Allow-Events" -#define SIP_HEADER_MIME_VERSION "MIME-Version" -#define SIP_MIME_VERSION_VALUE "1.0" - -/* Require and Supported header params */ -#define REQ_SUPP_PARAM_REPLACES "replaces" -#define REQ_SUPP_PARAM_100REL "100rel" -#define REQ_SUPP_PARAM_EARLY_SESSION "early-session" -#define REQ_SUPP_PARAM_JOIN "join" -#define REQ_SUPP_PARAM_PATH "path" -#define REQ_SUPP_PARAM_PRECONDITION "precondition" -#define REQ_SUPP_PARAM_PREF "pref" -#define REQ_SUPP_PARAM_PRIVACY "privacy" -#define REQ_SUPP_PARAM_SEC_AGREE "sec-agree" -#define REQ_SUPP_PARAM_TIMER "timer" -#define REQ_SUPP_PARAM_NOREFERSUB "norefersub" -#define REQ_SUPP_PARAM_EXTENED_REFER "extended-refer" -#define REQ_SUPP_PARAM_CISCO_CALLINFO "X-cisco-callinfo" -#define REQ_SUPP_PARAM_CISCO_SERVICEURI "X-cisco-serviceuri" -#define REQ_SUPP_PARAM_CISCO_ESCAPECODES "X-cisco-escapecodes" -#define REQ_SUPP_PARAM_CISCO_SERVICE_CONTROL "X-cisco-service-control" -#define REQ_SUPP_PARAM_CISCO_SRTP_FALLBACK "X-cisco-srtp-fallback" -#define REQ_SUPP_PARAM_CISCO_CONFIG "X-cisco-config" -#define REQ_SUPP_PARAM_SDP_ANAT "sdp-anat" -/* Add defines for the SIP Interfcae Specification (SIS) protocol version tags*/ -#define REQ_SUPP_PARAM_CISCO_SISTAG "X-cisco-sis-" -#define SIS_CURRENT_PROTOCOL_VERSION "5.2.0" -#define SIS_PROTOCOL_MAJOR_VERSION_SEADRAGON 1 -#define SIS_PROTOCOL_MAJOR_VERSION_MUSTER 2 -#define SIS_PROTOCOL_MAJOR_VERSION_UNISON 3 -#define SIS_PROTOCOL_MAJOR_VERSION_GUILD 4 -#define SIS_PROTOCOL_MAJOR_VERSION_ANGELFIRE 5 -#define SIS_PROTOCOL_MINOR_VERSION_ANGELFIRE 1 -#define SIS_PROTOCOL_MINOR_VERSION_MONTBLANC 1 -#define REQ_SUPP_PARAM_CISCO_SIPVER REQ_SUPP_PARAM_CISCO_SISTAG SIS_CURRENT_PROTOCOL_VERSION -#define REQ_SUPP_PARAM_CISCO_MONREC "X-cisco-monrec" -/* Add define for CME version negotiation */ -#define REQ_SUPP_PARAM_CISCO_CME_SISTAG "X-cisco-cme-sis-" - -/* Contact parameters */ -#define REQ_CONT_PARAM_CISCO_NEWREG "X-cisco-newreg" - -/* Max-forwards header */ -#define SIP_MAX_FORWARDS_DEFAULT_STR "70" -#define SIP_MAX_FORWARDS_DEFAULT_VALUE 70 - -/* Join header */ -#define SIP_HEADER_JOIN "Join" -#define SIP_HEADER_JOIN_FROM_TAG "from-tag" -#define SIP_HEADER_JOIN_TO_TAG "to-tag" - -/* Info-Package headers */ -#define SIP_HEADER_SEND_INFO "Send-Info" -#define SIP_HEADER_RECV_INFO "Recv-Info" -#define SIP_HEADER_INFO_PACKAGE "Info-Package" - -/* - * ALERT : If you are defining a compact header more than 2 bytes long, modify - * routine compact_hdr_cmp() in file httpish.c - */ - -/* - * Revised SIP drafts say that we use Contact and not Location in the header. - * But we are supporting both currently for MCI - */ - -/* S T A T U S C O D E S */ - -/* Informational Status Codes 1xx */ - -#define SIP_1XX_TRYING 100 /* "Trying" */ -#define SIP_1XX_RINGING 180 /* "Ringing" */ -#define SIP_1XX_CALL_FWD 181 /* "Call is being forwaded" */ -#define SIP_1XX_QUEUED 182 /* "Queued" */ -#define SIP_1XX_SESSION_PROGRESS 183 /* "Session Progress" */ - -/* Success Status Code 2xx */ -#define SIP_SUCCESS_SETUP 200 /* OK/Success */ -#define SIP_ACCEPTED 202 /* Accepted */ -#define SIP_STATUS_SUCCESS SIP_SUCCESS_SETUP - -/* Redirection Status Codes 3xx */ -#define SIP_RED_MULT_CHOICES 300 /* Multiple Choices */ -#define SIP_RED_MOVED_PERM 301 /* Moved Permanently */ -#define SIP_RED_MOVED_TEMP 302 /* Moved Temporarily */ -#define SIP_RED_SEE_OTHER 303 /* See Other */ -#define SIP_RED_USE_PROXY 305 /* Use Proxy */ -#define SIP_RED_ALT_SERVICE 380 /* Alternative Service */ - -/* Client Error Status Codes 4xx */ -#define SIP_CLI_ERR_BAD_REQ 400 /* Bad Request */ -#define SIP_CLI_ERR_UNAUTH 401 /* Unauthorized */ -#define SIP_CLI_ERR_PAY_REQD 402 /* Payment Required */ -#define SIP_CLI_ERR_FORBIDDEN 403 /* Forbidden */ -#define SIP_CLI_ERR_NOT_FOUND 404 /* Not Found */ -#define SIP_CLI_ERR_NOT_ALLOWED 405 /* Method Not Allowed */ -#define SIP_CLI_ERR_NOT_ACCEPT 406 /* Not Acceptable */ -#define SIP_CLI_ERR_PROXY_REQD 407 /* Proxy Authentication Required */ - -#define SIP_CLI_ERR_REQ_TIMEOUT 408 /* Request Timeout */ -#define SIP_CLI_ERR_CONFLICT 409 /* Conflict */ -#define SIP_CLI_ERR_GONE 410 /* Gone */ -#define SIP_CLI_ERR_LEN_REQD 411 /* Length Required */ -#define SIP_CLI_ERR_COND_FAIL 412 /* Conditional req failed */ -#define SIP_CLI_ERR_LARGE_MSG 413 /* Request Message Body Too Large */ -#define SIP_CLI_ERR_LARGE_URI 414 /* Request-URI Too Large */ -#define SIP_CLI_ERR_MEDIA 415 /* Unsupported Media Type */ -#define SIP_CLI_ERR_EXTENSION 420 /* Bad Extension */ -#define SIP_CLI_ERR_INTERVAL_TOO_SMALL 423 /* Duration too small */ -#define SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED 433 /* Anonymity Disallowed */ -#define SIP_CLI_ERR_NOT_AVAIL 480 /* Temporarily Not Available */ -#define SIP_CLI_ERR_CALLEG 481 /* Call Leg/Transaction Does Not Exist */ -#define SIP_CLI_ERR_LOOP_DETECT 482 /* Loop Detected */ -#define SIP_CLI_ERR_MANY_HOPS 483 /* Too Many Hops */ -#define SIP_CLI_ERR_ADDRESS 484 /* Address Incomplete */ -#define SIP_CLI_ERR_AMBIGUOUS 485 /* Ambiguous */ -#define SIP_CLI_ERR_BUSY_HERE 486 /* Busy here */ -#define SIP_CLI_ERR_REQ_CANCEL 487 /* Request Cancelled */ -#define SIP_CLI_ERR_NOT_ACCEPT_HERE 488 /* Not Acceptable Here */ -#define SIP_CLI_ERR_BAD_EVENT 489 /* Bad Event */ -#define SIP_CLI_ERR_REQ_PENDING 491 /* Request Pending */ - -/* Server Error Status Codes 5xx */ -#define SIP_SERV_ERR_INTERNAL 500 /* Internal Server Error */ -#define SIP_SERV_ERR_NOT_IMPLEM 501 /* Not Implemented */ -#define SIP_SERV_ERR_BAD_GW 502 /* Bad Gateway */ -#define SIP_SERV_ERR_UNAVAIL 503 /* Service Unavailable */ -#define SIP_SERV_ERR_GW_TIMEOUT 504 /* Gateway Timeout */ -#define SIP_SERV_ERR_SIP_VER 505 /* SIP Version not supported */ -#define SIP_SERV_ERR_PRECOND_FAILED 580 /* Precondition Failed */ - -/* Global Failure Status Codes 6xx */ -#define SIP_FAIL_BUSY 600 /* Busy */ -#define SIP_FAIL_DECLINE 603 /* Decline */ -#define SIP_FAIL_NOT_EXIST 604 /* Does not exist anywhere */ -#define SIP_FAIL_NOT_ACCEPT 606 /* Not Acceptable */ - -/* SIP Warning Codes 3xx */ -#define SIP_WARN_INCOMPAT_NETWORK_PROT 300 /* Incompatible Network Protocol */ -#define SIP_WARN_INCOMPAT_NETWORK_ADDR 301 /* Incompatible Network Address */ -#define SIP_WARN_INCOMPAT_TRANS_PROT 302 /* Incompatible Transport Protocol */ -#define SIP_WARN_INCOMPAT_BANDW_UNITS 303 /* Incompatible Bandwidth Units */ -#define SIP_WARN_MEDIA_TYPE_UNAVAIL 304 /* Media Type(s) Unavailable */ -#define SIP_WARN_INCOMPAT_MEDIA_FORMAT 305 /* Incompatible Media Formats */ -#define SIP_WARN_UNKNOWN_MEDIA_ATTRIB 306 /* Media Attribute not understood */ -#define SIP_WARN_UNKNOWN_SDP_PARAM 307 /* SDP Parameter not understood */ -#define SIP_WARN_MISC 399 /* Miscellaneous */ - -/* Other warnings */ -#define SIP_WARN_PROCESSING_PREVIOUS_REQUEST 901 - -/* R E A S O N P H R A S E S */ - -/* Informational 1xx */ - -#define SIP_1XX_TRYING_PHRASE "Trying" -#define SIP_1XX_RINGING_PHRASE "Ringing" -#define SIP_1XX_CALL_FWD_PHRASE "Call is being forwaded" -#define SIP_1XX_QUEUED_PHRASE "Queued" -#define SIP_1XX_SESSION_PROGRESS_PHRASE "Session Progress" - -/* Success 2xx */ -#define SIP_SUCCESS_SETUP_PHRASE "OK" -#define SIP_ACCEPTED_PHRASE "Accepted" - -/* Redirection 3xx */ -#define SIP_RED_MULT_CHOICES_PHRASE "Multiple Choices" -#define SIP_RED_MOVED_PERM_PHRASE "Moved Permanently" -#define SIP_RED_MOVED_TEMP_PHRASE "Moved Temporarily" -#define SIP_RED_SEE_OTHER_PHRASE "See Other" -#define SIP_RED_USE_PROXY_PHRASE "Use Proxy" -#define SIP_RED_ALT_SERVICE_PHRASE "Alternative Service" - -/* Client Error 4xx */ -#define SIP_CLI_ERR_BAD_REQ_PHRASE "Bad Request" -#define SIP_CLI_ERR_UNAUTH_PHRASE "Unauthorized" -#define SIP_CLI_ERR_PAY_REQD_PHRASE "Payment Required" -#define SIP_CLI_ERR_FORBIDDEN_PHRASE "Forbidden" -#define SIP_CLI_ERR_NOT_FOUND_PHRASE "Not Found" -#define SIP_CLI_ERR_NOT_ALLOWED_PHRASE "Method Not Allowed" -#define SIP_CLI_ERR_NOT_ACCEPT_PHRASE "Not Acceptable" -#define SIP_CLI_ERR_PROXY_REQD_PHRASE "Proxy Authentication Required" - -#define SIP_CLI_ERR_REQ_TIMEOUT_PHRASE "Request Timeout" -#define SIP_CLI_ERR_CONFLICT_PHRASE "Conflict" -#define SIP_CLI_ERR_GONE_PHRASE "Gone" -#define SIP_CLI_ERR_LEN_REQD_PHRASE "Length Required" -#define SIP_CLI_ERR_LARGE_MSG_PHRASE "Request Message Body Too Large" -#define SIP_CLI_ERR_LARGE_URI_PHRASE "Request-URI Too Large" -#define SIP_CLI_ERR_MEDIA_PHRASE "Unsupported Media Type" -#define SIP_CLI_ERR_EXTENSION_PHRASE "Bad Extension" -#define SIP_CLI_ERR_NOT_AVAIL_PHRASE "Temporarily Not Available" -#define SIP_CLI_ERR_CALLEG_PHRASE "Call Leg/Transaction Does Not Exist" -#define SIP_CLI_ERR_SUBS_DOES_NOT_EXIST_PHRASE "Subscription Does Not Exist" -#define SIP_CLI_ERR_LOOP_DETECT_PHRASE "Loop Detected" -#define SIP_CLI_ERR_MANY_HOPS_PHRASE "Too Many Hops" -#define SIP_CLI_ERR_ADDRESS_PHRASE "Address Incomplete" -#define SIP_CLI_ERR_AMBIGUOUS_PHRASE "Ambiguous" -#define SIP_CLI_ERR_BUSY_HERE_PHRASE "Busy here" -#define SIP_CLI_ERR_REQ_CANCEL_PHRASE "Request Cancelled" -#define SIP_CLI_ERR_NOT_ACCEPT_HERE_PHRASE "Not Acceptable Here" -#define SIP_CLI_ERR_BAD_EVENT_PHRASE "Bad Event" -#define SIP_CLI_ERR_INTERVAL_TOO_SMALL_PHRASE "Interval too small" -#define SIP_CLI_ERR_INTERVAL_TOO_LARGE_PHRASE "Interval too large" -#define SIP_CLI_ERR_ANONYMITY_NOT_ALLOWED_PHRASE "Anonymity Disallowed" -#define SIP_CLI_ERR_REQ_PENDING_PHRASE "Request Pending" - -/* Server Error 5xx */ -#define SIP_SERV_ERR_INTERNAL_PHRASE "Internal Server Error" -#define SIP_SERV_ERR_NOT_IMPLEM_PHRASE "Not Implemented" -#define SIP_SERV_ERR_BAD_GW_PHRASE "Bad Gateway" -#define SIP_SERV_ERR_UNAVAIL_PHRASE "Service Unavailable" -#define SIP_SERV_ERR_GW_TIMEOUT_PHRASE "Gateway Timeout" -#define SIP_SERV_ERR_SIP_VER_PHRASE "SIP Version not supported" -#define SIP_SERV_ERR_PRECOND_FAILED_PHRASE "Precondition Failed" - -/* Global Failure 6xx */ -#define SIP_FAIL_BUSY_PHRASE "Busy" -#define SIP_FAIL_DECLINE_PHRASE "Decline" -#define SIP_FAIL_NOT_EXIST_PHRASE "Does not exist anywhere" -#define SIP_FAIL_NOT_ACCEPT_PHRASE "Not Acceptable" - -/* SIP Warning Codes 3xx Phrases */ -#define SIP_WARN_INCOMPAT_NETWORK_PROT_PHRASE "\"Incompatible Network Protocol\"" -#define SIP_WARN_INCOMPAT_NETWORK_ADDR_PHRASE "\"Incompatible Network Address\"" -#define SIP_WARN_INCOMPAT_TRANS_PROT_PHRASE "\"Incompatible Transport Protocol\"" -#define SIP_WARN_INCOMPAT_BANDW_UNITS_PHRASE "\"Incompatible Bandwidth Units\"" -#define SIP_WARN_MEDIA_TYPE_UNAVAIL_PHRASE "\"Media Type(s) Unavailable\"" -#define SIP_WARN_INCOMPAT_MEDIA_FORMAT_PHRASE "\"Incompatible Media Formats\"" -#define SIP_WARN_UNKNOWN_MEDIA_ATTRIB_PHRASE "\"Media Attribute not understood\"" -#define SIP_WARN_UNKNOWN_SDP_PARAM_PHRASE "\"SDP Parameter not understood\"" -#define SIP_WARN_REFER_AMBIGUOUS_PHRASE "\"Ambiguous.Multiple Contacts Found.\"" - -#define SIP_STATUS_PHRASE_NONE "Unknown" - -/* Client Error 400 Bad Request detailed explaination */ -#define SIP_CLI_ERR_BAD_REQ_MEDIA_COMP_FAILED "Bad Request - 'Media info comparison failed'" -#define SIP_CLI_ERR_BAD_REQ_SDP_ERROR "Bad Request - 'Invalid SDP information'" -#define SIP_CLI_ERR_BAD_REQ_RECORD_ROUTE "Bad Request - 'Malformed/Missing Record Route'" -#define SIP_CLI_ERR_BAD_REQ_CONTACT_FIELD "Bad Request - 'Malformed/Missing Contact field'" -#define SIP_CLI_ERR_BAD_REQ_CALLID_ABSENT "Bad Request - 'Callid absent'" -#define SIP_CLI_ERR_BAD_REQ_CSEQ_FIELD "Bad Request - 'Error in Cseq field'" -#define SIP_CLI_ERR_BAD_REQ_FROM_OR_TO_FIELD "Bad Request - 'Error in From and/or To field'" -#define SIP_CLI_ERR_BAD_REQ_MEDIA_NEGOTIATION "Bad Request - 'Media Negotiation Failed'" -#define SIP_CLI_ERR_BAD_REQ_URL_ERROR "Bad Request - 'Malformed/Missing URL'" -#define SIP_CLI_ERR_BAD_REQ_ToURL_ERROR "Bad Request - 'Malformed/Missing TO: field'" -#define SIP_CLI_ERR_BAD_REQ_FROMURL_ERROR "Bad Request - 'Malformed/Missing FROM: field'" -#define SIP_CLI_ERR_BAD_REQ_CALLID_ERROR "Bad Request - 'Malformed/Missing CALLID field'" -#define SIP_CLI_ERR_BAD_REQ_REQLINE_ERROR "Bad Request - 'Malformed/Missing REQUEST LINE'" -#define SIP_CLI_ERR_BAD_REQ_IPADDRESS_ERROR "Bad Request - 'Invalid IP Address'" -#define SIP_CLI_ERR_BAD_REQ_CONTENT_LENGTH_ERROR "Bad Request - 'Content length Error'" -#define SIP_CLI_ERR_BAD_REQ_CONTENT_TYPE_ERROR "Bad Request - 'Malformed/Missing SIP CONTENT TYPE field'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_DIVERSION "Bad Request - 'Malformed CC-Diversion Header'" -#define SIP_CLI_ERR_BAD_REQ_VIA_OR_CSEQ "Bad Request - 'Malformed/Missing VIA OR CSEQ'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_REFER "Bad Request - 'Malformed REFER Request'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_TO "Bad Request - 'Malformed Refer-To Header'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_REFER_BY "Bad Request - 'Missing Refer-By Header'" -#define SIP_CLI_ERR_BAD_REQ_PHRASE_REPLACES "Bad Request - 'Malformed Replaces Header'" -#define SIP_CLI_ERR_BAD_REQ_METHOD_UNKNOWN "Bad Request - 'Unable to obtain SIP method'" -#define SIP_CLI_ERR_BAD_REQ_BAD_BODY_ENCODING "Bad Request - 'Unable to decode body'" -#define SIP_CLI_ERR_BAD_REQ_SUBSCRIPTION_DELETED "Bad Request - 'Subscription Terminated'" -#define SIP_CLI_ERR_BAD_REQ_NO_BODY "Bad Request - 'Body Expected'" -#define SIP_CLI_ERR_BAD_REQ_NO_SUBSCRIPTION_HEADER "Bad Request - 'Malformed/Missing Subscription-State Header'" -#define SIP_CLI_ERR_BAD_REQ_CONTENT_ID_ERROR "Bad Request - 'Invalid Content-Id field'" -#define SIP_CLI_ERR_BAD_REQ_REQUIRE_HDR "Bad Request - 'Malformed/Missing Require header'" -#endif /*_CCSIP_PROTOCOL_H_*/ diff --git a/libs/sipcc/core/sipstack/h/ccsip_publish.h b/libs/sipcc/core/sipstack/h/ccsip_publish.h deleted file mode 100644 index 3e823e1e8c..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_publish.h +++ /dev/null @@ -1,44 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_PUBLISH_H_ -#define _CCSIP_PUBLISH_H_ - -#include "publish_int.h" -#include "ccsip_common_cb.h" -#include "ccsip_subsmanager.h" - -/* the following is to take advantage of SUB/NOT periodic timer */ -#define TMR_PERIODIC_PUBLISH_INTERVAL TMR_PERIODIC_SUBNOT_INTERVAL - -#define PUBLISH_FAILED_START (1000) -#define PUBLISH_FAILED_NOCONTEXT (PUBLISH_FAILED_START + 1) -#define PUBLISH_FAILED_NORESOURCE (PUBLISH_FAILED_START + 2) -#define PUBLISH_FAILED_SEND (PUBLISH_FAILED_START + 3) -#define PUBLISH_FAILED_RESET (PUBLISH_FAILED_START + 4) - -typedef struct { - ccsip_common_cb_t hb; /* this MUST be the first member */ - - cc_srcs_t callback_task; // CallBack Task ID - int resp_msg_id; //Response Msg ID - char *entity_tag; - pub_handle_t pub_handle; - pub_handle_t app_handle; - char ruri[MAX_URI_LENGTH]; // Address of the resource - char full_ruri[MAX_SIP_URL_LENGTH]; - char esc[MAX_URI_LENGTH]; // Event State Compositor - boolean outstanding_trxn; - sipPlatformUITimer_t retry_timer; - sll_handle_t pending_reqs; //holds pending requests -} ccsip_publish_cb_t; //PUBLISH Control Block data structure - -extern int publish_handle_ev_app_publish(cprBuffer_t buf); -extern int publish_handle_retry_timer_expire(uint32_t handle); -extern void publish_handle_periodic_timer_expire(void); -extern int publish_handle_ev_sip_response(sipMessage_t *pSipMessage); -extern void publish_reset(void); -extern cc_int32_t show_publish_stats(cc_int32_t argc, const char *argv[]); - -#endif // _CCSIP_PUBLISH_H_ diff --git a/libs/sipcc/core/sipstack/h/ccsip_register.h b/libs/sipcc/core/sipstack/h/ccsip_register.h deleted file mode 100644 index 4148bdb314..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_register.h +++ /dev/null @@ -1,157 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_REGISTER_H_ -#define _CCSIP_REGISTER_H_ - -#include "cpr_types.h" -#include "cpr_timers.h" -#include "phone.h" -#include "ccsip_core.h" -#include "ccsip_credentials.h" -#include "platform_api.h" - -#define MAX_REG_EXPIRES 3600 -#include "ccsip_subsmanager.h" -#include "platform_api.h" - -#define MAX_RETRIES_401 3 - -#define AUTH_HDR(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - (SIP_HEADER_WWW_AUTHENTICATE) : (SIP_HEADER_PROXY_AUTHENTICATE)) - -#define AUTH_HDR_STR(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - ("WWW-Authenticate") : ("Proxy-Authenticate")) - -#define AUTH_BUGINF(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - ("SIP 401 Unauthorized") : ("SIP 407 Proxy Authentication required")) - -#define AUTH_NOTIFY(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - (" 401 <---") : (" 407 <---")) - -#define AUTHOR_HDR(status_code) \ - (((status_code) == SIP_CLI_ERR_UNAUTH) ? \ - (SIP_HEADER_AUTHORIZATION) : (SIP_HEADER_PROXY_AUTHORIZATION)) - - -/* - These numbers need to match up - with whats defined on the J-Side - The Master copy should be here because - the reason needs to be sent out in the register - message -*/ -#define UNREG_REASON_UNSPECIFIED 0 -//Common with what SCCP uses...need to match with J-Side -//Important! should be defined in plat_api.h for thirdparty application to use. -#define UNREG_REASON_TCP_TIMEOUT CC_UNREG_REASON_TCP_TIMEOUT // 10 -#define UNREG_REASON_CM_RESET_TCP CC_UNREG_REASON_CM_RESET_TCP //12 -#define UNREG_REASON_CM_ABORTED_TCP CC_UNREG_REASON_CM_ABORTED_TCP //13 -#define UNREG_REASON_CM_CLOSED_TCP CC_UNREG_REASON_CM_CLOSED_TCP //14 -#define UNREG_REASON_REG_TIMEOUT CC_UNREG_REASON_REG_TIMEOUT //17 -#define UNREG_REASON_FALLBACK CC_UNREG_REASON_FALLBACK //18 -#define UNREG_REASON_PHONE_KEYPAD CC_UNREG_REASON_PHONE_KEYPAD //20 -#define UNREG_REASON_RESET_RESET CC_UNREG_REASON_RESET_RESET //22 -#define UNREG_REASON_RESET_RESTART CC_UNREG_REASON_RESET_RESTART //23 -#define UNREG_REASON_PHONE_REG_REJ CC_UNREG_REASON_PHONE_REG_REJ //24 -#define UNREG_REASON_PHONE_INITIALIZED CC_UNREG_REASON_PHONE_INITIALIZED //25 -#define UNREG_REASON_VOICE_VLAN_CHANGED CC_UNREG_REASON_VOICE_VLAN_CHANGED //26 - -//sip specific ones...need to match with J-Side -#define UNREG_REASON_VERSION_STAMP_MISMATCH CC_UNREG_REASON_VERSION_STAMP_MISMATCH //100 -#define UNREG_REASON_VERSION_STAMP_MISMATCH_CONFIG CC_UNREG_REASON_VERSION_STAMP_MISMATCH_CONFIG //101 -#define UNREG_REASON_VERSION_STAMP_MISMATCH_SOFTKEY CC_UNREG_REASON_VERSION_STAMP_MISMATCH_SOFTKEY //102 -#define UNREG_REASON_VERSION_STAMP_MISMATCH_DIALPLAN CC_UNREG_REASON_VERSION_STAMP_MISMATCH_DIALPLAN //103 -#define UNREG_REASON_APPLY_CONFIG_RESTART CC_UNREG_REASON_APPLY_CONFIG_RESTART //104 -#define UNREG_REASON_CONFIG_RETRY_RESTART CC_UNREG_REASON_CONFIG_RETRY_RESTART //105 -#define UNREG_REASON_TLS_ERROR CC_UNREG_REASON_TLS_ERROR //106 -#define UNREG_REASON_RESET_TO_INACTIVE_PARTITION CC_UNREG_REASON_RESET_TO_INACTIVE_PARTITION //107 -#define UNREG_REASON_VPN_CONNECTIVITY_LOST CC_UNREG_REASON_VPN_CONNECTIVITY_LOST //108 - - -#define PRIMARY_LINE (1) - -typedef enum { - SIP_REG_ERROR, - SIP_REG_OK -} sip_reg_return_code; - -typedef enum -{ - SIP_REG_INVALID=-1, - SIP_REG_IDLE, - SIP_REG_REGISTERING, - SIP_REG_REGISTERED, - SIP_REG_UNREGISTERING, - SIP_REG_PRE_FALLBACK, - SIP_REG_IN_FAILOVER, - SIP_REG_POST_FAILOVER, - SIP_REG_STANDBY_FAILOVER, - SIP_REG_NO_CC, - SIP_REG_NO_STANDBY, - SIP_REG_NO_REGISTER -} ccsip_register_states_t; - -typedef enum -{ - E_SIP_REG_NONE = 0, - SIPSPI_REG_EV_BASE = 1, - - E_SIP_REG_REG_REQ = SIPSPI_REG_EV_BASE, - E_SIP_REG_CANCEL, - E_SIP_REG_1xx, - E_SIP_REG_2xx, - E_SIP_REG_3xx, - E_SIP_REG_4xx, - E_SIP_REG_FAILURE_RESPONSE, - E_SIP_REG_TMR_ACK, - E_SIP_REG_TMR_EXPIRE, - E_SIP_REG_TMR_WAIT, - E_SIP_REG_TMR_RETRY, - E_SIP_REG_CLEANUP, - SIPSPI_REG_EV_END = E_SIP_REG_CLEANUP -} sipRegSMEventType_t; - - -typedef struct -{ - int line; - boolean cancel; -} ccsip_register_msg_t; - - -int sip_reg_sm_process_event(sipSMEvent_t *pEvent); -sipRegSMEventType_t ccsip_register_sip2sipreg_event(int sip_event); -int ccsip_register_init(void); -void ccsip_register_timeout_retry(void *data); -void ccsip_register_all_lines(void); -void ccsip_register_cancel(boolean cancel_reg, boolean backup_proxy); -void ccsip_ccm_register_cancel(boolean cancel_reg); -void ccsip_register_set_state(ccsip_register_states_t state); -ccsip_register_states_t ccsip_register_get_state(void); -ccsip_register_states_t ccsip_register_get_register_state(void); -void ccsip_register_reset_proxy(void); -void cred_get_line_credentials(line_t line, credentials_t *pcredentials, - int id_len, int pw_len); -boolean cred_get_user_credentials(line_t line, credentials_t *pcredentials); -boolean cred_get_credentials_r(ccsipCCB_t *ccb, credentials_t *pcredentials); -void ccsip_register_commit(void); -void ccsip_backup_register_commit(void); -void ccsip_register_cleanup(ccsipCCB_t *ccb, boolean start); -void ccsip_register_set_register_state(ccsip_register_states_t state); -int ccsip_register_send_msg(uint32_t cmd, line_t line); -void ccsip_handle_ev_default(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_reg_sm_change_state(ccsipCCB_t *ccb, sipRegSMStateType_t new_state); -boolean ccsip_register_all_unregistered(); -void sip_stop_ack_timer(ccsipCCB_t *ccb); -void ccsip_register_shutdown(void); -boolean ccsip_get_ccm_date(char *date_value); -boolean ccsip_is_line_registered(line_t line); -boolean process_retry_after(ccsipCCB_t *ccb, sipMessage_t *response); - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_reldev.h b/libs/sipcc/core/sipstack/h/ccsip_reldev.h deleted file mode 100644 index cf6a76431e..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_reldev.h +++ /dev/null @@ -1,63 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_RELDEV_H_ -#define _CCSIP_RELDEV_H_ - -#include "cpr_types.h" -#include "ccsip_pmh.h" -#include "ccsip_core.h" - -#define RELDEV_MAX_USER_NAME_LEN 64 -#define RELDEV_MAX_HOST_NAME_LEN 64 -#define RELDEV_NO_STORED_MSG (-1) - -typedef struct -{ - char message_buf[SIP_UDP_MESSAGE_SIZE]; - uint32_t message_buf_len; - cpr_ip_addr_t dest_ipaddr; - uint16_t dest_port; -} sipRelDevCoupledMessage_t; - -typedef struct -{ - boolean is_request; - char call_id[MAX_SIP_CALL_ID]; - uint32_t cseq_number; - sipMethod_t cseq_method; - char tag[MAX_SIP_TAG_LENGTH]; - char from_user[RELDEV_MAX_USER_NAME_LEN]; - char from_host[RELDEV_MAX_HOST_NAME_LEN]; - char to_user[RELDEV_MAX_USER_NAME_LEN]; - int response_code; - sipRelDevCoupledMessage_t coupled_message; - boolean valid_coupled_message; - //int line; -} sipRelDevMessageRecord_t; - -void sipRelDevMessageStore(sipRelDevMessageRecord_t *pMessageRecord); -boolean sipRelDevMessageIsDuplicate(sipRelDevMessageRecord_t *pMessageRecord, - int *index); -int sipRelDevCoupledMessageStore(sipMessage_t *pCoupledMessage, - const char *call_id, - uint32_t cseq_number, - sipMethod_t cseq_method, - boolean is_request, - int status_code, - cpr_ip_addr_t *dest_ipaddr, - uint16_t dest_port, - boolean ignore_tag); -int sipRelDevCoupledMessageSend(int index); -void sipRelDevMessagesClear(const char *call_id, - const char *from_user, - const char *from_host, - const char *to_user); -void sipRelDevAllMessagesClear(); -uint32_t sipRelDevGetStoredCoupledMessage(int index, - char *dest_buffer, - uint32_t max_buff); - - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_sdp.h b/libs/sipcc/core/sipstack/h/ccsip_sdp.h deleted file mode 100644 index b927a83460..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_sdp.h +++ /dev/null @@ -1,159 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_SDP_H_ -#define _CCSIP_SDP_H_ - - -#include "cpr_types.h" -#include "pmhutils.h" -#include "sdp.h" -#include "ccapi.h" - - -/* SDP bitmask values */ -#define CCSIP_SRC_SDP_BIT 0x1 -#define CCSIP_DEST_SDP_BIT 0x2 - -/* - * Create a description or a SIP SDP (sip_info) with - * appropriate values initialized - */ -PMH_EXTERN boolean sip_sdp_init(void); -PMH_EXTERN sdp_t *sipsdp_create(const char *peerconnection); -PMH_EXTERN cc_sdp_t *sipsdp_info_create(void); -PMH_EXTERN void sipsdp_src_dest_free(uint16_t flags, cc_sdp_t **sdp_info); -PMH_EXTERN void sipsdp_src_dest_create(const char *peerconnection, - uint16_t flags, cc_sdp_t **sdp_info); -PMH_EXTERN void sipsdp_free(cc_sdp_t **sip_sdp); - -/* - * Stream related sdp utility functions - */ -//PMH_EXTERN sip_sdp_stream_t *sipsdp_stream_create(void); -//PMH_EXTERN void sipsdp_add_stream_to_list(sip_sdp_stream_t *stream, -// sip_sdp_t *sip_sdp); -//PMH_EXTERN void sipsdp_remove_stream_from_list(sip_sdp_stream_t **stream); -//PMH_EXTERN void sipsdp_remove_streams_list(sip_sdp_stream_t **stream_list); - -#define SIPSDP_MAX_SESSION_VERSION_LENGTH 32 - -/* - * Standard session-level parameters - */ -#define SIPSDP_VERSION 0 -// RAMC_DEBUG #define SIPSDP_ORIGIN_USERNAME "CiscoSystemsSIP-GW-UserAgent" -#define SIPSDP_ORIGIN_USERNAME "Mozilla-SIPUA" -#define SIPSDP_SESSION_NAME "SIP Call" - -/* Possible encoding names fo static payload types*/ -#define SIPSDP_ATTR_ENCNAME_PCMU "PCMU" -#define SIPSDP_ATTR_ENCNAME_PCMA "PCMA" -#define SIPSDP_ATTR_ENCNAME_G729 "G729" -#define SIPSDP_ATTR_ENCNAME_G723 "G723" -#define SIPSDP_ATTR_ENCNAME_G726 "G726-32" -#define SIPSDP_ATTR_ENCNAME_G728 "G728" -#define SIPSDP_ATTR_ENCNAME_GSM "GSM" -#define SIPSDP_ATTR_ENCNAME_CN "CN" -#define SIPSDP_ATTR_ENCNAME_G722 "G722" -#define SIPSDP_ATTR_ENCNAME_ILBC "iLBC" -#define SIPSDP_ATTR_ENCNAME_H263v2 "H263-1998" -#define SIPSDP_ATTR_ENCNAME_H264 "H264" -#define SIPSDP_ATTR_ENCNAME_VP8 "VP8" -#define SIPSDP_ATTR_ENCNAME_L16_256K "L16" -#define SIPSDP_ATTR_ENCNAME_ISAC "ISAC" -#define SIPSDP_ATTR_ENCNAME_OPUS "opus" - -/* Possible encoding names for DTMF tones dynamic payload types */ -#define SIPSDP_ATTR_ENCNAME_TEL_EVENT "telephone-event" -#define SIPSDP_ATTR_ENCNAME_FRF_DIGIT "frf-dialed-digit" - -/* Possible encoding names for other dynamic payload types */ -#define SIPSDP_ATTR_ENCNAME_CLEAR_CH "X-CCD" -#define SIPSDP_ATTR_ENCNAME_G726R16 "G726-16" -#define SIPSDP_ATTR_ENCNAME_G726R24 "G726-24" -#define SIPSDP_ATTR_ENCNAME_GSMEFR "GSM-EFR" - -/* RTPMAP encoding names added from MGCP for compatibility with MGCP - * These could be coming in from Cisco MGCP gateway's SDP via a - * softswitch and SIP GW must interoperate. - */ - -#define SIPSDP_ATTR_ENCNAME_G729_A_STR_DOTTED "G.729a" -#define SIPSDP_ATTR_ENCNAME_G729_B_STR_DOTTED "G.729b" -#define SIPSDP_ATTR_ENCNAME_G729_B_LOW_COMPLEXITY_STR_DOTTED "G.729b-L" -#define SIPSDP_ATTR_ENCNAME_G729_A_B_STR_DOTTED "G.729ab" - -#define SIPSDP_ATTR_ENCNAME_G7231_HIGH_RATE_STR_DOTTED "G.723.1-H" -#define SIPSDP_ATTR_ENCNAME_G7231_A_HIGH_RATE_STR_DOTTED "G.723.1a-H" -#define SIPSDP_ATTR_ENCNAME_G7231_LOW_RATE_STR_DOTTED "G.723.1-L" -#define SIPSDP_ATTR_ENCNAME_G7231_A_LOW_RATE_STR_DOTTED "G.723.1a-L" - -/* - * NSE/XNSE encoding names - */ -#define SIPSDP_ATTR_ENCNAME_XNSE "X-NSE" -#define SIPSDP_ATTR_ENCNAME_NSE "NSE" - - -/* Possible clock rates */ -#define RTPMAP_CLOCKRATE 8000 -#define RTPMAP_VIDEO_CLOCKRATE 90000 -#define RTPMAP_L16_CLOCKRATE 16000 -#define RTPMAP_ISAC_CLOCKRATE 16000 -#define RTPMAP_OPUS_CLOCKRATE 48000 -#define FMTP_MAX_AVERAGE_BIT_RATE 40000 -#define ATTR_PTIME 20 -#define ATTR_MAXPTIME 120 -#define WEBRTC_DATA_CHANNEL_PROT "webrtc-datachannel" - -#define SIPSDP_CONTENT_TYPE "application/sdp" - -#define MAX_RTP_PAYLOAD_TYPES 7 - -#define BITRATE_5300_BPS 5300 -#define BITRATE_6300_BPS 6300 - -/* - * T.38 attribute parameters - */ -#define SIPSDP_ATTR_T38_VERSION_DEF 0 -#define SIPSDP_ATTR_T38_FILL_BIT_REMOVAL_DEF FALSE -#define SIPSDP_ATTR_T38_TRANSCODING_MMR_DEF FALSE -#define SIPSDP_ATTR_T38_TRANSCODING_JBIG_DEF FALSE -/* the following two definitions are from VSIToH245BuildFastStartT38OLC() */ -#define SIPSDP_ATTR_T38_MAX_BUFFER_DEF 200 -#define SIPSDP_ATTR_T38_MAX_DATAGRAM_DEF 72 - -/* - * Supported NTE range. Note that if the supported NTEs ever becomes a - * non-contiguous set of values, then it will have to be stored as an - * sdp. See the definition of negotiated_nte_sdp for an example. Further, - * where Sdp_ne_cmp_range() is invoked, Sdp_ne_cmp_list() will have to be - * used instead. - */ -#define SIPSDP_NTE_SUPPORTED_LOW 0 /* Min value of DTMF event table */ -#define SIPSDP_FRF_SUPPORTED_HIGH 15 /* for dtmf-relay cisco-rtp */ -#define SIPSDP_NTE_SUPPORTED_HIGH 16 /* for dtmf-relay rtp-nse */ - -/* - * Create the "on-wire" version, i.e. ready to put into a SIP message. - * Memory is allocated and should be freed by the user when done - * Returns NULL on failure. - */ -PMH_EXTERN char *sipsdp_write_to_buf(cc_sdp_t *, uint32_t *); - -#define SIPSDP_FREE(x) \ -if (x) \ -{ \ - sdp_free_description(x); \ -} - -#define SIPSDP_MAX_PAYLOAD_TYPES 15 -#define MAX_RTP_MEDIA_TYPES 6 -#define SIPSDP_NTE_DTMF_MIN 0 /* Min value of DTMF event table */ -#define SIPSDP_NTE_DTMF_MAX 15 /* Max DTMF event value supported here */ - - -#endif /*_CCSIP_SDP_H_*/ diff --git a/libs/sipcc/core/sipstack/h/ccsip_sim.h b/libs/sipcc/core/sipstack/h/ccsip_sim.h deleted file mode 100644 index 89cff0a3d9..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_sim.h +++ /dev/null @@ -1,14 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_SIM_H_ -#define _CCSIP_SIM_H_ - - -void SIPTaskTestUdpSend(void); -void SIPTaskSimulateInviteRecv(void); -void SIPTaskSimulateOffhook(void); -void SIPTaskSimulateAckRecv(void); - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_spi_utils.h b/libs/sipcc/core/sipstack/h/ccsip_spi_utils.h deleted file mode 100755 index 95aeb51216..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_spi_utils.h +++ /dev/null @@ -1,22 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_UTILS_H_ -#define _CCSIP_UTILS_H_ - -#include "cpr_types.h" -#include "ccsip_pmh.h" - -boolean -sipSPI_validate_hostname(char *); - -boolean -sipSPI_validate_ip_addr_name(char *); - -extern int -sipSPICheckDomainToken(char *token); - -boolean -sipSPI_validate_hostname (char *str); -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_subsmanager.h b/libs/sipcc/core/sipstack/h/ccsip_subsmanager.h deleted file mode 100644 index fe66ac9e55..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_subsmanager.h +++ /dev/null @@ -1,433 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_SUBSMANAGER_H_ -#define _CCSIP_SUBSMANAGER_H_ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_timers.h" -#include "cpr_socket.h" -#include "ccsip_core.h" -#include "phone_platform_constants.h" -#include "singly_link_list.h" -#include "ccsip_common_cb.h" - -/* - * States - */ -typedef enum { - SUBS_STATE_IDLE = 0, // Initial state of the SCB - SUBS_STATE_REGISTERED, - - /* out going subscribe SCB states */ - SUBS_STATE_SENT_SUBSCRIBE, // Sent SUBSCRIBE - SUBS_STATE_RCVD_NOTIFY, // Received NOTIFY - SUBS_STATE_SENT_SUBSCRIBE_RCVD_NOTIFY, // Sent SUBSCRIBE & Received NOTIFY - - /* incoming subscribe SCB states */ - SUBS_STATE_RCVD_SUBSCRIBE, // Received SUBSCRIBE - SUBS_STATE_SENT_NOTIFY, // Sent NOTIFY - SUBS_STATE_RCVD_SUBSCRIBE_SENT_NOTIFY, // Received SUBSCRIBE & Sent NOTIFY - - /* - * No outstanding outgoing/incoming messages to handle. - * This state is after all outstanding SUBSCRIBE/NOTIFY - * transactions are complete. - */ - SUBS_STATE_ACTIVE, - - SUBS_STATE_INVALID -} subsStateType_t; - -typedef enum { - SUBSCRIPTION_NULL = 0, - SUBSCRIPTION_TERMINATE -} subscriptionState; - -/* - * Subscription ID data type - */ -typedef uint32_t sub_id_t; - -#define MAX_EVENT_NAME_LEN 32 -#define CCSIP_SUBS_START_CSEQ 1000 - -/* There may be multiple subscription pending on given call - * the subcription for KPML, remote-cc, offhook notification etc. - */ -#define MAX_SCBS ((MAX_TEL_LINES * 2) < 32 ? 32 : (MAX_TEL_LINES * 2)) -#define LIMIT_SCBS_USAGE (MAX_SCBS - ((MAX_SCBS * 20) / 100)) -#define TMR_PERIODIC_SUBNOT_INTERVAL 5 -#define CCSIP_SUBS_INVALID_SUB_ID (sub_id_t)(-1) -#define MAX_SCB_HISTORY 10 - -typedef enum { - SM_REASON_CODE_NORMAL = 0, - SM_REASON_CODE_ERROR, - SM_REASON_CODE_SHUTDOWN, - SM_REASON_CODE_ROLLOVER, - SM_REASON_CODE_RESET_REG -} ccsip_reason_code_e; - - -// Application defined callback functions - -// Data to app to indicate response to a sent SUBSCRIBE -typedef struct { - int status_code; - long expires; -} ccsip_subs_result_data_t; - -// Data to app to indicate a received SUBSCRIBE -typedef struct { - ccsip_event_data_t *eventData; - int expires; - int line; - string_t from; - string_t to; -} ccsip_subs_ind_data_t; - -// Data to app to indicate a received NOTIFY -typedef struct { - ccsip_event_data_t *eventData; - sip_subs_state_e subscription_state; // From the subs-state header - sip_subs_state_reason_e subscription_state_reason; - uint32_t expires; - uint32_t retry_after; - uint32_t cseq; - char entity[CC_MAX_DIALSTRING_LEN]; // used to store From user for incoming unsolicited NOTIFY. -} ccsip_notify_ind_data_t; - -// Data to app to indicate response to a sent NOTIFY -typedef struct { - int status_code; -} ccsip_notify_result_data_t; - -// Data to app to indicate incoming subscription terminated -typedef struct { - int status_code; -} ccsip_subs_terminate_data_t; - -// Containing structure for all stack->app messages -typedef struct ccsip_sub_not_data_t { - int msg_id; - sub_id_t sub_id; - int sub_duration; - cc_subscriptions_t event; - line_t line_id; - callid_t gsm_id; - boolean norefersub; - long request_id; - ccsip_reason_code_e reason_code; - union { - ccsip_subs_ind_data_t subs_ind_data; - ccsip_subs_result_data_t subs_result_data; - ccsip_notify_ind_data_t notify_ind_data; - ccsip_notify_result_data_t notify_result_data; - ccsip_subs_terminate_data_t subs_term_data; - } u; -} ccsip_sub_not_data_t; - - -// Function to pass an incoming subscribe request -typedef void (*ccsipSubsIndCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - -// Function to pass response to a subscribe request -typedef void (*ccsipSubsResultCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - -// Function to pass an incoming Notify request -typedef void (*ccsipNotifyIndCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - -// Function to pass results of notify request -typedef void (*ccsipNotifyResultCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - -// Function to pass general errors -typedef void (*ccsipSubsTerminateCallbackFn_t)(ccsip_sub_not_data_t *msg_data); -typedef void (*ccsipGenericCallbackFn_t)(ccsip_sub_not_data_t *msg_data); - - - -// Return status code -#define SUBSCRIPTION_IN_PROGRESS 1010 -#define SUBSCRIPTION_SUCCEEDED 1020 -#define SUBSCRIPTION_REJECTED 1030 -#define SUBSCRIPTION_FAILED 1040 -#define NOTIFY_REQUEST_FAILED 1050 -#define SUBSCRIBE_REQUEST_FAILED 1060 -#define SUBSCRIBE_FAILED_NORESOURCE 1061 -#define SUBSCRIBE_FAILED_BADEVENT 1062 -#define SUBSCRIBE_FAILED_BADINFO 1062 -#define NETWORK_SUBSCRIPTION_EXPIRED 1070 -#define APPLICATION_SUBSCRIPTION_EXPIRED 1080 -#define REQUEST_TIMEOUT 1090 - -// Data passed by app to register for incoming SUBSCRIBE -typedef struct sipspi_subscribe_reg_t_ { - cc_subscriptions_t eventPackage; // Registering for which event - ccsipSubsIndCallbackFn_t subsIndCallback; // Callback function - cc_srcs_t subsIndCallbackTask; // Callback task - int subsIndCallbackMsgID; // msg_id to use in callback - ccsipSubsTerminateCallbackFn_t subsTermCallback; // Callback function when remote side terminates subs - int subsTermCallbackMsgID; // Terminate msg-id - long min_duration; // Min duration for which SUB should be accepted - long max_duration; // Max duration for which SUB should be accepted -} sipspi_subscribe_reg_t; - -// Data passed by app to initiate a SUBSCRIBE -typedef struct sipspi_subscribe_t_ { - sub_id_t sub_id; // ID for reSubscribe - cc_subscriptions_t eventPackage; // Event package to send subscribe for - cc_subscriptions_t acceptPackage; // Accept header - long duration; // subscription duration (0=unsubscribe) - char subscribe_uri[CC_MAX_DIALSTRING_LEN]; - char subscriber_uri[CC_MAX_DIALSTRING_LEN]; // From field - long request_id; // Returned to subscriber in response - - ccsipSubsResultCallbackFn_t subsResultCallback; - ccsipNotifyIndCallbackFn_t notifyIndCallback; - ccsipSubsTerminateCallbackFn_t subsTermCallback; - - cc_srcs_t subsNotCallbackTask; - int subsResCallbackMsgID; - int subsNotIndCallbackMsgID; - int subsTermCallbackMsgID; - - cpr_ip_addr_t dest_sip_addr; // Destination address - uint16_t dest_sip_port; // Destination port - - callid_t call_id; - line_t dn_line; // Associated line, if any - - boolean auto_resubscribe; // stack reSubscribes at expiry - boolean norefersub; - ccsip_event_data_t *eventData; // Determined by the eventPackage value - -} sipspi_subscribe_t; - -// Data by app to respond to a received SUBSCRIBE -typedef struct sipspi_subscribe_resp_t_ { - sub_id_t sub_id; // Subscription id - uint16_t response_code; // Response that should be sent - int duration; // Max duration for the subscribe -} sipspi_subscribe_resp_t; - -// Data by app to initiate a NOTIFY -typedef struct sipspi_notify_t_ { - sub_id_t sub_id; // Subscription id - // Info for different notify bodies - ccsipNotifyResultCallbackFn_t notifyResultCallback; - int subsNotResCallbackMsgID; - ccsip_event_data_t *eventData; // Determined by the eventPackage value - cc_subscriptions_t eventPackage; // Event package - subscriptionState subState; - cc_srcs_t subsNotCallbackTask; // Opt.: If not already specified -} sipspi_notify_t; - -// Data by app to respond to a received NOTIFY -typedef struct sipspi_notify_resp_t_ { - sub_id_t sub_id; - int response_code; - int duration; - uint32_t cseq; -} sipspi_notify_resp_t; - -// Data by app to terminate an existing subscription -typedef struct sipspi_subscribe_term_t_ { - sub_id_t sub_id; - long request_id; - cc_subscriptions_t eventPackage; // Event package - boolean immediate; -} sipspi_subscribe_term_t; - -/* -typedef struct sipspi_remotecc_reg_t_{ -} sipspi_remotecc_reg_t; - -typedef struct sipspi_remotecc_refer_t_{ -} sipspi_remotecc_refer_t; - -typedef struct sipspi_remotecc_refer_resp_t_{ -} sipspi_remotecc_refer_resp_t; - -typedef struct sipspi_remotecc_notify_t_{ -} sipspi_remotecc_notify_t; - -typedef struct sipspi_remotecc_notify_resp_t_{ -} sipspi_remotecc_notify_resp_t; - -typedef struct sipspi_remotecc_term_t_{ -} sipspi_remotecc_term_t; -*/ - -typedef struct sipspi_msg_t_ { - union { - sipspi_subscribe_reg_t subs_reg; - sipspi_subscribe_t subscribe; - sipspi_subscribe_resp_t subscribe_resp; - sipspi_notify_t notify; - sipspi_notify_resp_t notify_resp; - sipspi_subscribe_term_t subs_term; - /* - * sipspi_remotecc_reg_t remotecc_reg; - * sipspi_remotecc_refer_t remotecc_refer; - * sipspi_remotecc_refer_resp_t remotecc_refer_resp; - * sipspi_remotecc_notify_t remotecc_notify; - * sipspi_remotecc_notify_resp_t remotecc_notify_resp; - * sipspi_remotecc_term_t remotecc_term; - */ - } msg; -} sipspi_msg_t; - -// List of app->stack messages -typedef struct sipspi_msg_list_t_ { - uint32_t cmd; - sipspi_msg_t *msg; - struct sipspi_msg_list_t_ *next; -} sipspi_msg_list_t; - -// Subscription Control Block -typedef struct { - ccsip_common_cb_t hb; /* this MUST be the first memeber in the struct */ - - line_t line; - // Subscription ID - sub_id_t sub_id; - - // SCB State - boolean pendingClean; - unsigned char pendingCount; - - // Subscriber details - boolean internal; // Internal or external - - // Callback and messaging details - ccsipSubsIndCallbackFn_t subsIndCallback; - cc_srcs_t subsIndCallbackTask; - cc_srcs_t subsNotCallbackTask; - int subsIndCallbackMsgID; - ccsipSubsResultCallbackFn_t subsResultCallback; - int subsResCallbackMsgID; - ccsipNotifyIndCallbackFn_t notifyIndCallback; - int notIndCallbackMsgID; - ccsipSubsTerminateCallbackFn_t subsTermCallback; - int subsTermCallbackMsgID; - ccsipNotifyResultCallbackFn_t notifyResultCallback; - int notResCallbackMsgID; - - short sip_socket_handle; - boolean useDeviceAddressing; - callid_t gsm_id; - long request_id; - - // Subscription details - subsStateType_t smState; - subsStateType_t outstandingIncomingNotifyTrxns; // only used for incoming NOTIFYs - unsigned long min_expires; - unsigned long max_expires; - ccsipCCB_t *ccbp; /* associated CCB, if any */ - char event_name[MAX_EVENT_NAME_LEN]; - boolean auto_resubscribe; /* Resubscribe automatically */ - boolean norefersub; - - // Messaging details - uint32_t last_sent_request_cseq; - sipMethod_t last_sent_request_cseq_method; - uint32_t last_recv_request_cseq; - sipMethod_t last_recv_request_cseq_method; - - // Saved headers - char SubURI[MAX_SIP_URL_LENGTH]; - char SubURIOriginal[MAX_SIP_URL_LENGTH]; - char SubscriberURI[MAX_SIP_URL_LENGTH]; - string_t sip_from; - string_t sip_to; - string_t sip_to_tag; - string_t sip_from_tag; - string_t sip_contact; - string_t cached_record_route; - sipContact_t *contact_info; - sipRecordRoute_t *record_route_info; - sll_handle_t incoming_trxns; // to store via (branch attribute) to track transactions. - string_t callingNumber; - - // Subscription headers - sip_subs_state_e subscription_state; - sip_subs_state_reason_e subscription_state_reason; - uint32_t retry_after; - - - // Linked list of pending app messages - sipspi_msg_list_t *pendingRequests; -} sipSCB_t; - -// Transaction Control Block -typedef struct { - ccsip_common_cb_t hb; /* this MUST be the first memeber in the struct */ - char full_ruri[MAX_SIP_URL_LENGTH]; - cprTimer_t timer; /* transaction timer */ - uint32_t trxn_id; -} sipTCB_t; - -// Structure to keep track of recent subscriptions -typedef struct { - char last_call_id[MAX_SIP_CALL_ID]; - char last_from_tag[MAX_SIP_TAG_LENGTH]; - cc_subscriptions_t eventPackage; -} sipSubsHistory_t; - -#define MAX_SUB_EVENTS 5 -#define MAX_SUB_EVENT_NAME_LEN 16 -extern const char eventNames[MAX_SUB_EVENTS][MAX_SUB_EVENT_NAME_LEN]; - -/* - * Externally called function headers - */ -// For initializing and shutting down -int sip_subsManager_init(); -int sip_subsManager_shut(); - -// Function to handle subscription requests from applications -int subsmanager_handle_ev_cc_feature_subscribe(sipSMEvent_t *); -int subsmanager_handle_ev_cc_feature_notify(sipSMEvent_t *); - -int subsmanager_handle_ev_app_subscribe_register(cprBuffer_t buf); -int subsmanager_handle_ev_app_subscribe(cprBuffer_t buf); -int subsmanager_handle_ev_app_subscribe_response(cprBuffer_t buf); -int subsmanager_handle_ev_app_notify(cprBuffer_t buf); -void subsmanager_handle_ev_app_unsolicited_notify(cprBuffer_t buf, line_t line); -int subsmanager_handle_ev_app_notify_response(cprBuffer_t buf); -int subsmanager_handle_ev_app_subscription_terminated(cprBuffer_t buf); -int subsmanager_handle_retry_timer_expire(int scb_index); -void subsmanager_handle_periodic_timer_expire(void); -int subsmanager_test_start_routine(); - -// Functions to handle remotecc requests from applications -// int subsmanager_handle_ev_app_remotecc_register(); -// int subsmanager_handle_ev_app_remotecc_refer(); -// int subsmanager_handle_ev_app_remotecc_refer_response(); -// int subsmanager_handle_ev_app_remotecc_notify(); -// int subsmanager_handle_ev_app_remotecc_notify_response(); -// int subsmanager_handle_ev_app_remotecc_terminated(); - -// Functions to handle requests from network -int subsmanager_handle_ev_sip_subscribe(sipMessage_t *pSipMessage, - sipMethod_t sipMethod, - boolean in_dialog); -int subsmanager_handle_ev_sip_subscribe_notify(sipMessage_t *pSipMessage); - -// Function to handle response from network -int subsmanager_handle_ev_sip_response(sipMessage_t *pSipMessage); - -void free_event_data(ccsip_event_data_t *event_data); -int sip_subsManager_rollover(void); -int sip_subsManager_reset_reg(void); -void submanager_update_ccb_addr(ccsipCCB_t *ccb); -boolean add_content(ccsip_event_data_t *eventData, sipMessage_t *request, const char *fname); -void pres_unsolicited_notify_ind(ccsip_sub_not_data_t * msg_data); -sipTCB_t *find_tcb_by_sip_callid(const char *callID_p); -int subsmanager_handle_ev_sip_unsolicited_notify_response(sipMessage_t *pSipMessage, sipTCB_t *tcbp); -void subsmanager_unsolicited_notify_timeout(void *data); - -#endif diff --git a/libs/sipcc/core/sipstack/h/ccsip_task.h b/libs/sipcc/core/sipstack/h/ccsip_task.h deleted file mode 100644 index 801168e168..0000000000 --- a/libs/sipcc/core/sipstack/h/ccsip_task.h +++ /dev/null @@ -1,89 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CCSIP_TASK_H_ -#define _CCSIP_TASK_H_ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_socket.h" -#include "cpr_memory.h" - -/* - * List of timers that the SIP task is responsible for. - * CPR will send a msg to the SIP task when these - * timers expire. CPR expects a timer id when the timer - * is created, this enum serves that purpose. - */ -typedef enum { - SIP_ACK_TIMER, - SIP_WAIT_TIMER, - SIP_RETRY_TIMER, - SIP_MSG_TIMER, - SIP_EXPIRES_TIMER, - SIP_REG_TIMEOUT_TIMER, - SIP_REG_EXPIRES_TIMER, - SIP_LOCAL_EXPIRES_TIMER, - SIP_SUPERVISION_TIMER, - SIP_GLARE_AVOIDANCE_TIMER, - SIP_KEEPALIVE_TIMER, - SIP_SUBNOT_TIMER, - SIP_SUBNOT_PERIODIC_TIMER, - SIP_PUBLISH_RETRY_TIMER, - SIP_UNSOLICITED_TRANSACTION_TIMER, - SIP_DIAL_TIMEOUT_TIMER, - SIP_FAIL_OVER_START_TIMER, - SIP_FAIL_OVER_COMPLETE_TIMER, - SIP_FALL_BACK_START_TIMER, - SIP_FALL_BACK_COMPLETE_TIMER, - SIP_UNREGISTRATION_TIMER, - SIP_REGALLFAIL_TIMER, - SIP_NOTIFY_TIMER, - SIP_PASSTHROUGH_TIMER -} sipTimerList_t; - - -/* Action Values for SIPTaskPostShutdown function */ -#define SIP_INTERNAL 0 -#define SIP_EXTERNAL 1 -#define SIP_STOP 2 - -#define MAX_SIP_REASON_LENGTH 64 -#define UNREG_NO_REASON 0 -#define VERSION_STAMP_MISMATCH 1 -/* - * The code creating the SIP timers needs to have - * access to the sip_msgq variable since CPR - * needs to know where to send the timer expiration - * message. - */ -extern cprMsgQueue_t sip_msgq; - -typedef struct -{ - boolean taskInited; // FALSE - cprMsgQueue_t msgQueue; -} sipGlobal_t; - -/* - * External Data - */ -extern sipGlobal_t sip; -extern char sipHeaderServer[]; -extern char sipHeaderUserAgent[]; -extern char sipUnregisterReason[]; - -/* - * Prototypes - */ -void SIPTaskInit(void); -void SIPTaskProcessListEvent(uint32_t cmd, void *msg, void *pUsr, uint16_t len); -int SIPTaskProcessUDPMessage(cprBuffer_t msg, uint16_t len, cpr_sockaddr_storage from); -int SIPTaskProcessConfigChangeNotify(int32_t notify_type); -cpr_status_e SIPTaskSendMsg(uint32_t cmd, cprBuffer_t msg, uint16_t len, void *usr); -cprBuffer_t SIPTaskGetBuffer(uint16_t size); -void SIPTaskReinitialize(boolean checkConfig); -void SIPTaskPostShutdown(int, int reason, const char *reasonInfo); - -#endif diff --git a/libs/sipcc/core/sipstack/h/httpish.h b/libs/sipcc/core/sipstack/h/httpish.h deleted file mode 100644 index 23c8e875a2..0000000000 --- a/libs/sipcc/core/sipstack/h/httpish.h +++ /dev/null @@ -1,302 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _HTTPISH_H_ -#define _HTTPISH_H_ - -#include "cpr_types.h" -#include "pmhdefs.h" -#include "httpish_protocol.h" -#include "pmhutils.h" -#include "util_ios_queue.h" - -#define HTTPISH_MIN_STATUS_CODE 100 -#define HTTPISH_HEADER_CACHE_SIZE 12 -#define HTTPISH_HEADER_NAME_SIZE 256 - -typedef struct h_header -{ - struct h_header *next; - char *header; -} httpish_header; - -typedef struct { - char *hdr_start; - char *val_start; -} httpish_cache_t; - -#define HTTPISH_MAX_BODY_PARTS 6 -typedef struct { - uint8_t msgContentDisp; - boolean msgRequiredHandling; - uint8_t msgContentTypeValue; - char *msgContentType; - char *msgBody; - uint32_t msgLength; - char *msgContentId; - uint8_t msgContentEnc; -} msgBody_t; - -typedef struct _httpMsg -{ - struct _httpMsg *next; - boolean retain_flag; /* If TRUE, Do not free the msg */ - char *mesg_line; - queuetype *headers; - msgBody_t mesg_body[HTTPISH_MAX_BODY_PARTS]; - char *raw_body; - int32_t content_length; - uint8_t num_body_parts; - boolean is_complete; - boolean headers_read; - /* Cache the most commonly used headers */ - httpish_cache_t hdr_cache[HTTPISH_HEADER_CACHE_SIZE]; - /* this is the complete message received/sent at the socket */ - char *complete_message; -} httpishMsg_t; - -typedef struct -{ - char *method; - char *url; - char *version; -} httpishReqLine_t; - - -typedef struct -{ - char *reason_phrase; - uint16_t status_code; - char *version; -} httpishRespLine_t; - -typedef enum -{ - STATUS_SUCCESS = 0, - STATUS_FAILURE, - STATUS_UNKNOWN, - HSTATUS_SUCCESS = STATUS_SUCCESS, - HSTATUS_FAILURE = STATUS_FAILURE, - HSTATUS_UNKNOWN = STATUS_UNKNOWN -} hStatus_t; - -typedef enum -{ - codeClassInvalid = 0, - codeClass1xx = 1, - codeClass2xx = 2, - codeClass3xx = 3, - codeClass4xx = 4, - codeClass5xx = 5, - codeClass6xx = 6 -} httpishStatusCodeClass_t; - - -/* Creates a message and initializes its internal members */ -PMH_EXTERN httpishMsg_t *httpish_msg_create(void); - -/* Frees internal members of the message, such as headers */ -PMH_EXTERN void httpish_msg_free(httpishMsg_t *); - -/* - * Returns TRUE if the message is a HTTPish Request, FALSE if not. - * Return value will be wrong if the function is called before the - * message is complete(see message_is_complete) - */ -PMH_EXTERN boolean httpish_msg_is_request(httpishMsg_t *, const char *, int); - -/* - * A message may be complete or incomplete at a point in time, since - * one message may be formed of multiple network packets. This function - * returns TRUE if the message is in fact complete, FALSE if not - */ -PMH_EXTERN boolean httpish_msg_is_complete(httpishMsg_t *); - -/* - * Gets a request line structure out of the message i.e parses the message - * line. Null on failure, incomplete message etc. User should call - * httpish_msg_free_reqline when done to free the allocated memory - * inside the structure. - */ -PMH_EXTERN httpishReqLine_t *httpish_msg_get_reqline(httpishMsg_t *); - -/* Frees internal members of the request line structure */ -PMH_EXTERN void httpish_msg_free_reqline(httpishReqLine_t *); - -/* - * Gets a response line structure out of the message i.e parses the message - * line. Null on failure, incomplete message etc. User should call - * httpish_msg_free_respline when done to free the allocated memory - * inside the structure. - */ -PMH_EXTERN httpishRespLine_t *httpish_msg_get_respline(httpishMsg_t *); - -/* Frees internal members of the response line structure */ -PMH_EXTERN void httpish_msg_free_respline(httpishRespLine_t *); - -/* - * Adds a message line to the message given a request line elements. - * This makes it a Request message - * This routine allocates memory internally, which is freed on - * calling httpish_msg_free() - */ -PMH_EXTERN hStatus_t httpish_msg_add_reqline(httpishMsg_t *, - const char *method, - const char *url, - const char *version); - -/* - * Adds a message line to the message given response line elements. - * This makes it a Response message - * This routine allocates memory internally, which is freed on - * calling httpish_msg_free(). Status codes are assumed to be a - * maximum of 6 characters long ie <= 999999 - */ -PMH_EXTERN hStatus_t httpish_msg_add_respline(httpishMsg_t *, - const char *version, - uint16_t status_code, - const char *reason_phrase); - -/* - * Adds a header with a text value to message. - * hname = name of the header for eg. "Content-Type" - * hval = value of the header for eg. "application/sdp" - * This routine allocates memory internally, which is freed on - * calling httpish_msg_free() - */ -PMH_EXTERN hStatus_t httpish_msg_add_text_header(httpishMsg_t *msg, - const char *hname, - const char *hval); - -/* - * Adds a header with a integer value to message. - * hname = name of the header for eg. "Content-Length" - * hval = value of the header for eg. 234 - * This routine allocates memory internally, which is freed on - * calling httpish_msg_free() - */ -/* Assumes the int is less than 10 characters*/ -PMH_EXTERN hStatus_t httpish_msg_add_int_header(httpishMsg_t *msg, - const char *hname, - int32_t hvalue); - -/* - * Removes a header from the message. - * hname = name of the header. eg. hname = "From" - * Memory for that header string is freed. - */ -PMH_EXTERN hStatus_t httpish_msg_remove_header(httpishMsg_t *msg, - const char *hname); - - -/* - * Returns the value of the header if found, NULL if not. - * hname = name of the header, eg. "Content-Length" - * The pointer should not be freed by the user. (It will be - * freed on freeing the message) - */ -PMH_EXTERN const char *httpish_msg_get_header_val(httpishMsg_t *, - const char *hname, - const char *c_hname); - -PMH_EXTERN hStatus_t httpish_msg_get_header_vals(httpishMsg_t *, - const char *hname, - const char *c_hname, - uint16_t *nheaders, - char **header_vals); - -PMH_EXTERN const char *httpish_msg_get_cached_header_val(httpishMsg_t *, int); - - -/* - * Gets an array of pointers to all the headers. The number of - * headers is returned in num_headers. - * If invoked such : - * all_the_headers = httpish_msg_get_all_headers(...), - * memory is allocated only for "all_the_headers" array, not for - * its individual elements. Hence only the pointer to the all_the_headers - * array should be freed. - */ -PMH_EXTERN char **httpish_msg_get_all_headers(httpishMsg_t *msg, uint32_t *num_headers); - -PMH_EXTERN uint32_t httpish_msg_get_num_headers(httpishMsg_t *msg); - - -PMH_EXTERN uint16_t httpish_msg_get_num_particular_headers(httpishMsg_t *msg, - const char *hname, - const char *c_hname, - char *header_val[], - uint16_t max_headers); - -/* - * Utility function to get value of the Content-Length header. Returns -1 - * if the header is not present. - */ -PMH_EXTERN int32_t httpish_msg_get_content_length(httpishMsg_t *); - - -/* - * Adds the content body to the message. Results in the addition of the - * Content-Length header as well. - */ -PMH_EXTERN hStatus_t httpish_msg_add_body(httpishMsg_t *msg, - char *body, - uint32_t nbytes, - const char *content_type, - uint8_t msg_disposition, - boolean required, - char *content_id); - -PMH_EXTERN boolean httpish_msg_header_present(httpishMsg_t *, - const char *hname); - - - -/* - * Allocates a buffer and writes the message into it in the network - * format i.e ready to send. On return, nbytes is filled in with - * the number of bytes contained in the message buffer. Returns - * NULL on failure. User needs to free memory when done. - */ -PMH_EXTERN char *httpish_msg_write_to_buf(httpishMsg_t * msg, uint32_t *nbytes); - -/* Writes it out as a null terminated string. Expected use is debug */ -PMH_EXTERN char *httpish_msg_write_to_string(httpishMsg_t * msg); - -/* - * Writes out a message in the network format(ie ready to send), - * in a user provided buffer. nbytes is filled in with the number - * of bytes in buf on entry and filled in with the - * actual number of bytes written if the return value is SUCCESS. - * There is no attempt to grow or realloc the buffer ie FAILURE - * is returned if the buffer is not large enough. - */ -PMH_EXTERN hStatus_t httpish_msg_write(httpishMsg_t *msg, - char *buf, - uint32_t *nbytes); - -/* - * This function is used to read bytes from a network packet into the - * message structure. - * msg = previously created httpishMsg using httpish_msg_create() - * nmsg = network message - * bytes_read = Number of bytes read from nmsg is filled in when the - * function returns. - * It is expected that after this returns HSTATUS_SUCCESS, - * httpish_is_message_complete() is called to see whether a complete - * message was received(or a previously started message was completed, - * at which point it can be processed further. - */ -PMH_EXTERN hStatus_t httpish_msg_process_network_msg(httpishMsg_t *msg, - char *nmsg, - uint32_t *bytes_read); - -/* - * Utility to get the class of status codes in http like responses. - * For eg., the class for a code 480 is 4, as currently defined. - */ -PMH_EXTERN httpishStatusCodeClass_t httpish_msg_get_code_class(uint16_t statusCode); - - -#endif /* _HTTPISH_H_ */ diff --git a/libs/sipcc/core/sipstack/h/httpish_protocol.h b/libs/sipcc/core/sipstack/h/httpish_protocol.h deleted file mode 100644 index 3a1751d0e5..0000000000 --- a/libs/sipcc/core/sipstack/h/httpish_protocol.h +++ /dev/null @@ -1,32 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _HTTPISH_PROTOCOL_H_ -#define _HTTPISH_PROTOCOL_H_ - -/* - * Some common headers only. There does not seem a whole lot of - * sense in defining error codes since they tend to have different - * semantics - */ - -#define HTTPISH_HEADER_CONTENT_LENGTH "Content-Length" -#define HTTPISH_C_HEADER_CONTENT_LENGTH "l" -#define HTTPISH_HEADER_CONTENT_TYPE "Content-Type" -#define HTTPISH_HEADER_CONTENT_ENCODING "Content-Encoding" -#define HTTPISH_HEADER_CONTENT_ID "Content-Id" - -#define HTTPISH_HEADER_USER_AGENT "User-Agent" -#define HTTPISH_HEADER_SERVER "Server" -#define HTTPISH_HEADER_DATE "Date" - -#define HTTPISH_HEADER_VIA "Via" -#define HTTPISH_HEADER_MAX_FORWARDS "Max-Forwards" -#define HTTPISH_HEADER_EXPIRES "Expires" -#define HTTPISH_HEADER_LOCATION "Location" - -#define HTTPISH_HEADER_MIME_VERSION "Mime-Version" -#define uniqueBoundary "uniqueBoundary" - -#endif /* _HTTPISH_PROTOCOL_H_ */ diff --git a/libs/sipcc/core/sipstack/h/pmhdefs.h b/libs/sipcc/core/sipstack/h/pmhdefs.h deleted file mode 100644 index 5e1338be96..0000000000 --- a/libs/sipcc/core/sipstack/h/pmhdefs.h +++ /dev/null @@ -1,12 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _PMH_DEFS_H_ -#define _PMH_DEFS_H_ - -#define UTILFREE(x) cpr_free(x) - -#define PMH_EXTERN extern - -#endif /* _PMH_DEFS_H_ */ diff --git a/libs/sipcc/core/sipstack/h/pmhutils.h b/libs/sipcc/core/sipstack/h/pmhutils.h deleted file mode 100644 index 0ffe1487c6..0000000000 --- a/libs/sipcc/core/sipstack/h/pmhutils.h +++ /dev/null @@ -1,163 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _PMH_UTILS_H_ -#define _PMH_UTILS_H_ - -#include "cpr_types.h" -#include "pmhdefs.h" - -/* - * Define a "stream" created from an input packet. We have to do this - * since SIP * messages may come in over TCP or UDP, so we cannot use - * TCP stream semantics. It is expected that a client interfaces to - * these streams via the API functions defined below, rather than - * directly. - */ -typedef struct -{ - char *buff; - char *loc; /* This points to the next byte that will be read */ - int32_t nbytes; - int32_t bytes_read; - boolean eof; - boolean error; -} pmhRstream_t; - - -/* - * Defines a write stream to write things to and finally create an - * "output packet". It is expected that a client interfaces to - * these streams via the API functions defined below, rather than - * directly. - */ -typedef struct -{ - char *buff; - int32_t nbytes; - int32_t total_bytes; - boolean growable; -} pmhWstream_t; - -typedef struct -{ - uint16_t num_tokens; - char **tokens; -} pmhTokens_t; - -/* - * Buf is the input buffer holding data that you want to use a "stream". - * The stream uses buf as is, so dont free it. Free it only when done - * ie. by calling pmhutils_rstream_delete. Returns NULL on failure. - * buf = Input buffer containing data. - * nbytes = Number of bytes in buf. - */ -PMH_EXTERN pmhRstream_t *pmhutils_rstream_create(char *buf, uint32_t nbytes); - - -/* - * Frees internal memory. If freebuf is TRUE, it frees the - * buffer it was created with. If not TRUE, the internal buffer - * should be held by the user and freed when appropriate. - */ -PMH_EXTERN void pmhutils_rstream_delete(pmhRstream_t *rs, boolean freebuf); - - -/* - * Returns a character from the stream, and advances internal pointer. - * If no characters are left, returns '\0' and sets the eof to TRUE. - */ -PMH_EXTERN char pmhutils_rstream_read_byte(pmhRstream_t *); - - -/* - * Returns a character buffer from the stream, - * and advances internal pointer. - * If no characters are left, returns NULL and sets the eof to TRUE. - * This routine allocates memory which should be freed by the user. - * nbytes = Number of bytes asked for. - */ -PMH_EXTERN char *pmhutils_rstream_read_bytes(pmhRstream_t *rs, int32_t nbytes); - -/* - * Returns a string created from a line(as terminated by \r or \n or \r\n) - * in the stream. This will actually allocate memory for the string, - * which should be freed by the user when done. Empty lines are returned - * as empty strings - ie. first char is \0. - * Updates internal pointer in the stream. - * Returns NULL if eof has been reached on the stream - */ -PMH_EXTERN char *pmhutils_rstream_read_line(pmhRstream_t *); - -/* Creates a write stream with an internal buffer of default size */ -PMH_EXTERN pmhWstream_t *pmhutils_wstream_create(void); - -/* Creates a write stream with a user provided buffer */ -PMH_EXTERN pmhWstream_t *pmhutils_wstream_create_with_buf(char *buf, - uint32_t nbytes); - -/* - * Grows the write streams internal buffer by a default step. - * Mostly used internally by the write functions - */ -PMH_EXTERN boolean pmhutils_wstream_grow(pmhWstream_t *); - -/* - * Frees the internal elements of the write stream, - * including its internal buffer if freebuf is TRUE. If freebuf - * is FALSE, the buffer should be held by the user and freed - * when appropriate. - */ -PMH_EXTERN void pmhutils_wstream_delete(pmhWstream_t *ws, boolean freebuf); - - -/* - * Writes the input string, followed by a SIP New line - * ie. \r\n - * Returns FALSE on failure. - * Expects a NULL terminated string in "line". - * Returns FALSE on failure(ie no memory etc.) - * May result in creation of memory, which will - * be freed when pmhutils_wstream_free_internal is called. - */ -PMH_EXTERN boolean pmhutils_wstream_write_line(pmhWstream_t *ws, char *line); - -/* - * Writes a single character to the output stream. - * Returns FALSE on failure, TRUE on success. - */ -PMH_EXTERN boolean pmhutils_wstream_write_byte(pmhWstream_t *, char); - -/* - * Writes a buffer(of length len pointed to by buf) to - * the stream. May result in creation of memory, which will - * be freed when pmhutils_wstream_free_internal is called. - * Returns FALSE on failure(ie no memory etc.) - */ -PMH_EXTERN boolean pmhutils_wstream_write_bytes(pmhWstream_t *ws, char *buf, - uint32_t len); - -/* - * Returns the internal buffer, and fills in its length in nbytes. - * This would be used just before wstream_delete(.., FALSE) in order - * to hold the buffer. - */ -PMH_EXTERN char *pmhutils_wstream_getbuf(pmhWstream_t *, uint32_t *nbytes); - -PMH_EXTERN uint32_t pmhutils_wstream_get_length(pmhWstream_t *ws); - -/* - * A tokenizer like strtok, but creates memory for every token. - * Use only when you have to create the memory anyway. - * Returns NULL if no tokens are found or incase memory allocation - * fails. - */ -PMH_EXTERN pmhTokens_t *pmh_tokenize(const char *str, const char *tokens); - -/* - * Util to free all the tokens - */ -PMH_EXTERN void pmh_tokens_free(pmhTokens_t *tokens); - -#endif /*_PMH_UTILS_H_*/ diff --git a/libs/sipcc/core/sipstack/h/regmgrapi.h b/libs/sipcc/core/sipstack/h/regmgrapi.h deleted file mode 100755 index b4a7e51f55..0000000000 --- a/libs/sipcc/core/sipstack/h/regmgrapi.h +++ /dev/null @@ -1,17 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _REGMGRAPI_H_ -#define _REGMGRAPI_H_ - -#include "sessionConstants.h" - -typedef enum reg_mode_t_ { - REG_MODE_CCM = CC_MODE_CCM, - REG_MODE_NON_CCM = CC_MODE_NONCCM, -} reg_mode_t; - -reg_mode_t sip_regmgr_get_cc_mode(line_t line); - -#endif /* _REGMGRAPI_H_ */ diff --git a/libs/sipcc/core/sipstack/h/sip_ccm_transport.h b/libs/sipcc/core/sipstack/h/sip_ccm_transport.h deleted file mode 100644 index e200cdcd8b..0000000000 --- a/libs/sipcc/core/sipstack/h/sip_ccm_transport.h +++ /dev/null @@ -1,20 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_CCM_TRANSPORT_H__ -#define __SIP_CCM_TRANSPORT_H__ - -#include "cpr_types.h" -#include "cpr_socket.h" -#include "phone_types.h" - -#define CCM_ID_PRINT(arg) \ - (arg == PRIMARY_CCM ? "PRIMARY_CCM" : \ - arg == SECONDARY_CCM ? "SECONDARY_CCM" : \ - arg == TERTIARY_CCM ? "TERTIARY_CCM" : \ - arg == MAX_CCM ? "MAX_CCM" : \ - arg == UNUSED_PARAM ? "UNUSED_PARAM" : "Unknown")\ - - -#endif /* __SIP_CCM_TRANSPORT_H__ */ diff --git a/libs/sipcc/core/sipstack/h/sip_common_regmgr.h b/libs/sipcc/core/sipstack/h/sip_common_regmgr.h deleted file mode 100644 index cb88fe7bfd..0000000000 --- a/libs/sipcc/core/sipstack/h/sip_common_regmgr.h +++ /dev/null @@ -1,157 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_COMMON_REGMGR_H__ -#define __SIP_COMMON_REGMGR_H__ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_timers.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "ccsip_core.h" -#include "singly_link_list.h" -#include "ccsip_platform.h" -#include "sip_common_transport.h" - -#define LINE1 0 -#define LINE2 1 -#define LINE3 2 -#define LINE4 3 -#define LINE5 4 -#define LINE6 5 -#define LINE7 6 -#define LINE8 7 -#define LINE9 8 -#define LINE10 9 -#define LINE11 10 -#define LINE12 11 -#define LINE13 12 -#define LINE14 13 -#define LINE15 14 -#define LINE16 15 -#define LINE17 16 -#define LINE18 17 -#define LINE19 18 -#define LINE20 19 - -#define RSP_START 1 -#define RSP_COMPLETE 2 -#define FAILOVER_RSP 0 -#define MAX_FALLBACK_MONITOR_PERIOD 300 -#define TLS_CONNECT_TIME 8 - -#define TOKEN_REFER_TO "" - -typedef enum { - ACTIVE_FD = 0, - STANDBY_FD, - MAX_FALLBACK_FDs -} CC_FDs; - -typedef enum { - RET_SUCCESS = 0, - RET_NO_STANDBY, - RET_START_FALLBACK, - RET_INIT_REBOOT -} RET_CODE; - -typedef struct fallback_ccb_t_ { - ccsipCCB_t *ccb; - sipPlatformUIExpiresTimer_t WaitTimer; - sipPlatformUIExpiresTimer_t RetryTimer; - uint32_t StabilityMsgCount; - boolean tls_socket_waiting; -} fallback_ccb_t; - -typedef struct ccm_fd_table_t_ { - ti_config_table_t *active_ccm_entry; - ti_config_table_t *standby_ccm_entry; -} ccm_act_stdby_table_t; - -//ccm_act_stdby_table_t CCM_Active_Standby_Table[MAX_TEL_LINES+1]; - -typedef struct ccm_failover_table_t_ { - ti_config_table_t *failover_ccm_entry; - ti_config_table_t *fallback_ccm_entry; - boolean prime_registered; - boolean failover_started; -} ccm_failover_table_t; - -typedef struct ccm_fallback_table_t_ { - ti_config_table_t *fallback_ccm_entry; - boolean is_idle; - boolean is_resp; - ccsipCCB_t *ccb; -} ccm_fallback_table_t; - -typedef struct { - uint32_t ccb_index; /* ccb index for which this msg is intended for */ - CCM_ID ccm_id; /* cucm id */ -} ccsip_registration_msg_t; - -void notify_register_update(int availableLine); -fallback_ccb_t *sip_regmgr_get_fallback_ccb_by_index(line_t index); -int sip_regmgr_destroy_cc_conns(void); -int sip_regmgr_init(void); -void sip_regmgr_register_lines(boolean prime_only, boolean skip_prime); -void sipRegmgrSendRegisterMsg(uint8_t line, ccsipCCB_t *ccb); -void sip_regmgr_ev_cancel(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_in_fallback_any_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_failure_response(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_tmr_ack_retry(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_tmr_expire_standby(ccsipCCB_t *ccb, sipSMEvent_t *event); - -void sip_regmgr_ev_unreg_tmr_ack(ccsipCCB_t *cb); -void sip_regmgr_trigger_fallback_monitor(void); -void sip_regmgr_setup_new_standby_ccb(CCM_ID ccm_id); -void sip_regmgr_free_fallback_ccb(ccsipCCB_t *ccb); -void sip_regmgr_retry_timeout_expire(void *data); -void sip_regmgr_stability_timeout_expire(void *data); -void sip_regmgr_find_fallback_ccb_by_callid(const char *callid, - ccsipCCB_t **ccb_ret); -boolean sip_regmgr_find_fallback_ccb_by_addr_port(cpr_ip_addr_t *ipaddr, - uint16_t port, - ccsipCCB_t **ccb_ret); -sll_match_e sip_regmgr_fallback_ccb_find(void *find_by_p, void *data_p); -void sip_regmgr_retry_timer_start(fallback_ccb_t *fallback_ccb); -ti_config_table_t *sip_regmgr_ccm_get_conn(line_t dn, - ti_config_table_t *ccm_entry); -void sip_regmgr_check_and_transition(ccsipCCB_t *ccb); -void sip_regmgr_ev_default(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_fallback_retry(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_wait_timeout_expire(void *data); -void sip_regmgr_ev_in_fallback_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_stability_check_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_stability_check_tmr_stable(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void sip_regmgr_ev_stability_check_tmr_wait(ccsipCCB_t *ccb, - sipSMEvent_t *event); -void sip_regmgr_ev_token_wait_2xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_cleanup(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_token_wait_4xx_n_5xx(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_ev_token_wait_tmr_wait(ccsipCCB_t *ccb, sipSMEvent_t *event); -void sip_regmgr_shutdown(void); - -void sip_regmgr_rsp(int rsp_id, int rsp_type, boolean waited); - -boolean sip_regmgr_check_config_change(void); - -void sip_regmgr_process_config_change(void); -void sip_regmgr_send_refer(ccsipCCB_t *ccb); -void sip_regmgr_ccm_restarted(ccsipCCB_t *new_reg_ccb); -void sip_regmgr_notify_timer_callback(void *data); -ccsipCCB_t *sip_regmgr_get_fallback_ccb_list(uint32_t *previous_data_p); -void sip_regmgr_replace_standby(ccsipCCB_t *ccb); -void sip_regmgr_regallfail_timer_callback(void *data); -void sip_regmgr_handle_reg_all_fail(void); -void sip_regmgr_get_config_addr(int ccm_id, char *add_str); - -extern boolean g_disable_mass_reg_debug_print; - -void regmgr_handle_register_update(line_t last_available_line); - - -#endif /* __SIP_COMMON_REGMGR_H__ */ diff --git a/libs/sipcc/core/sipstack/h/sip_common_transport.h b/libs/sipcc/core/sipstack/h/sip_common_transport.h deleted file mode 100644 index e6b4bf0d70..0000000000 --- a/libs/sipcc/core/sipstack/h/sip_common_transport.h +++ /dev/null @@ -1,223 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_COMMON_TRANSPORT_H__ -#define __SIP_COMMON_TRANSPORT_H__ - -#include "cpr_types.h" -#include "cpr_socket.h" -#include "ccsip_pmh.h" -#include "sip_csps_transport.h" -#include "sip_ccm_transport.h" -#include "singly_link_list.h" - - -#define MAX_CONNECTIONS 5 - -/* Macro definition for chacking a valid connid (TCP/UDP) */ -#define VALID_CONNID(connid) \ - (connid >= 0 && connid < MAX_CONNECTIONS) - -typedef enum { - NONE_CC = 0, - ACTIVE_CC = 1, - STANDBY_CC -} CC_POSITION; - -/* - * Define the types of connections - */ -/* - * NOTE: Need to match the values in the config matrix - */ -typedef enum { - CONN_NONE = 0, - CONN_TCP, - CONN_UDP, - CONN_TLS, - CONN_TCP_TMP, - CONN_MAX_TYPES -} CONN_TYPE; - -// Device Security Modes -typedef enum sec_level_t_ { - NON_SECURE = 0, // Normal, no security - AUTHENTICATED, // Use TLS, server will use NULL encryption - ENCRYPTED, // Use TLS, server will use AES encryption - NOT_IN_CTL // Not in CTL should not be seen by SIP. -} sec_level_t; - -typedef enum conn_create_status_t_ { - CONN_INVALID = -1, - CONN_SUCCESS, - CONN_FAILURE -} conn_create_status_t; - -typedef struct ti_common_t_ { - uint16_t listen_port; - char addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t addr; - uint16_t port; - uint16_t sec_port; - CONN_TYPE conn_type; - CONN_TYPE configured_conn_type; - cpr_socket_t handle; -} ti_common_t; - -typedef struct ti_ccm_t_ { - CCM_ID ccm_id; - int32_t sec_level; - int32_t is_valid; -} ti_ccm_t; - -typedef struct ti_csps_t_ { - char bkup_pxy_addr_str[MAX_IPADDR_STR_LEN]; - cpr_ip_addr_t bkup_pxy_addr; - uint16_t bkup_pxy_port; - char emer_pxy_addr_str[MAX_IPADDR_STR_LEN]; - uint16_t emer_pxy_port; - char outb_pxy_addr_str[MAX_IPADDR_STR_LEN]; - uint16_t outb_pxy_port; -} ti_csps_t; - -typedef struct ti_config_table_t_ { - CC_ID cc_type; - ti_common_t ti_common; - union { - ti_ccm_t ti_ccm; - ti_csps_t *ti_csps; - } ti_specific; -} ti_config_table_t; - -extern ti_config_table_t *CCM_Config_Table[MAX_REG_LINES + 1][MAX_CCM]; -extern ti_config_table_t CCM_Dummy_Entry; -extern ti_config_table_t CSPS_Config_Table[MAX_REG_LINES]; -typedef struct cc_config_table_t_ { - CC_ID cc_type; - void *cc_table_entry; // Needs to deferenced as - // ti_config_table_t* -} cc_config_table_t; - -typedef long sipSPIConnId_t; - -typedef enum { - SOCKET_NO_ERROR = -1, - SOCKET_SEND_ERROR, - SOCKET_RECV_ERROR, - SOCKET_OPEN_ERROR, - SOCKET_OPT_ERROR, - SOCKET_CONNECT_ERROR, - SOCKET_CONN_REFUSED_ERROR, - SOCKET_BIND_ERROR, - SOCKET_REMOTE_CLOSURE, - SOCKET_ADMIN_CLOSURE, - SIP_TCP_CONN_TABLE_FULL -} ccsipSockErrCodes_e; - -/* All the possible state of the TCP/UDP sockets */ -typedef enum { - SOCK_IDLE, /* not inuse */ - SOCK_LISTENING, /* fd is listening on the well-known port */ - SOCK_ACCEPTED, /* connection accepted */ - SOCK_CONNECTED, /* connection made */ - SOCK_CONNECT_PENDING, /* connection is pending */ - SOCK_FAILED /* failed, will be closed when all calls fail */ -} sock_state_t; - -typedef struct { - cpr_ip_addr_t addr; - uint16_t port; - CONN_TYPE transport; /* Specifies UDP, Multicast UDP, TCP */ - uint8_t ip_sig_tos; - uint16_t local_listener_port; -} sipSPICreateConnection_t; - -typedef struct { - void *context; - sipSPICreateConnection_t createConnMsg; -} sipSPIMessage_t; - - -void sipTransportSetServerHandleAndPort(cpr_socket_t socket_handle, - uint16_t listen_port, - ti_config_table_t *ccm_table_entry); -int sip_dns_gethostbysrv(char *domain, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, - srv_handle_t *srv_order, - boolean retried_addr); -int sip_dns_gethostbysrvorname(char *hname, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port); - -conn_create_status_t sip_transport_setup_cc_conn(line_t dn, CCM_ID ccm_id); -int sip_transport_destroy_cc_conn(line_t dn, CCM_ID ccm_id); - -int16_t SIPTaskGetProxyPortByDN(line_t dn); -uint32_t SIPTaskGetProxyAddressByDN(line_t dn); -cpr_socket_t SIPTaskGetProxyHandleByDN(line_t dn); - -int sipTransportCreateSendMessage(ccsipCCB_t *ccb, - sipMessage_t *pSIPMessage, - sipMethod_t message_type, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port, - boolean isRegister, - boolean reTx, - int timeout, void *scbp, - int reldev_stored_msg); -#define sipTransportChannelCreateSend(a, b, m, c, d, e, f) \ -sipTransportCreateSendMessage(a, b, m, c, d, FALSE, TRUE, e, NULL, f) - -int sipTransportSendMessage(ccsipCCB_t *ccb, - char *pOutMessageBuf, - uint32_t nbytes, - sipMethod_t message_type, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port, - boolean isRegister, - boolean reTx, - int timeout, - void *scbp); -#define sipTransportChannelSend(a, b, c, m, d, e, f) \ -sipTransportSendMessage(a, b, c, m, d, e, FALSE, TRUE, f, NULL) - -int sipTransportGetServerAddrPort(char *domain, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, - srv_handle_t *psrv_order, - boolean retried_addr); -int sipTransportGetPrimServerPort(line_t line); -int sipTransportGetBkupServerPort(line_t line); -int sipTransportGetEmerServerPort(line_t line); -int sipTransportGetOutbProxyPort(line_t line); -cpr_ip_type sipTransportGetPrimServerAddress(line_t line, char *buffer); -uint16_t sipTransportGetBkupServerAddress(cpr_ip_addr_t *pip_addr, - line_t line, char *buffer); -void sipTransportGetEmerServerAddress(line_t line, char *buffer); -void sipTransportGetOutbProxyAddress(line_t line, char *buffer); -void sipTransportGetServerIPAddr(cpr_ip_addr_t *pip_addr, line_t line); -int sipTransportInit(void); -uint16_t sipTransportGetServerAddress(cpr_ip_addr_t *pip_addr, line_t dn, line_t index); -short sipTransportGetServerPort(line_t dn, line_t index); - -int sipTransportGetCCType(int line, void *cc_table_entry); -void sip_regmgr_set_cc_info(line_t line, line_t dn_line, - CC_ID *cc_type, void *cc_table_entry); -uint16_t sipTransportGetListenPort(line_t line, ccsipCCB_t *ccb); -const char *sipTransportGetTransportType(line_t line, boolean upper_case, - ccsipCCB_t *ccb); - -void sipTransportShutdown(void); -extern void ccsip_dump_send_msg_info(char *msg, sipMessage_t *pSIPMessage, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port); -void SIPTaskProcessTCPMessage(sipMessage_t *pSipMessage, - cpr_sockaddr_storage from); - -void -sipTransportSetSIPServer(); - - -#endif /* __SIP_COMMON_TRANSPORT_H__ */ diff --git a/libs/sipcc/core/sipstack/h/sip_csps_transport.h b/libs/sipcc/core/sipstack/h/sip_csps_transport.h deleted file mode 100644 index 0797985e9b..0000000000 --- a/libs/sipcc/core/sipstack/h/sip_csps_transport.h +++ /dev/null @@ -1,47 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __SIP_CSPS_TRANSPORT_H__ -#define __SIP_CSPS_TRANSPORT_H__ - -#include "cpr_types.h" -#include "phone_types.h" -#include "phone_debug.h" -#include "cfgfile_utils.h" -#include "configmgr.h" -#include "ccsip_protocol.h" -#include "ccsip_pmh.h" -#include "ccsip_platform_timers.h" -#include "ccsip_platform_udp.h" -#include "ccsip_messaging.h" - -/* - * Defines for Primary, Secondary and Tertiary CC - */ -typedef enum { - PRIMARY_CSPS = 0, - MAX_CSPS -} CSPS_ID; - -//extern csps_config_info_t CSPS_Config_Table; - -cpr_socket_t sipTransportCSPSGetProxyHandleByDN(line_t dn); -short sipTransportCSPSGetProxyPortByDN(line_t dn); -uint16_t sipTransportCSPSGetProxyAddressByDN(cpr_ip_addr_t *pip_addr, - line_t dn); - -uint16_t sip_config_get_proxy_port(line_t line); -uint16_t sip_config_get_backup_proxy_port(void); -void sip_config_get_proxy_addr(line_t line, char *buffer, int buffer_len); -uint16_t sip_config_get_backup_proxy_addr(cpr_ip_addr_t *IPAddress, - char *buffer, int buffer_len); - -extern sipPlatformUITimer_t sipPlatformUISMTimers[]; -extern ccsipGlobInfo_t gGlobInfo; - -extern int dns_error_code; // DNS errror code global -void sipTransportCSPSClearProxyHandle(cpr_ip_addr_t *ipaddr, uint16_t port, - cpr_socket_t this_fd); - -#endif /* __SIP_CSPS_TRANSPORT_H__ */ diff --git a/libs/sipcc/core/sipstack/h/sip_interface_regmgr.h b/libs/sipcc/core/sipstack/h/sip_interface_regmgr.h deleted file mode 100644 index a12d17901c..0000000000 --- a/libs/sipcc/core/sipstack/h/sip_interface_regmgr.h +++ /dev/null @@ -1,64 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SIP_INTERFACE_REGMGR_H_ -#define _SIP_INTERFACE_REGMGR_H_ - -#include "cpr_types.h" -#include "phone_types.h" -#include "sip_common_transport.h" -#include "regmgrapi.h" - -typedef enum reg_rcs_t_ { - REG_RC_SUCCESS, - REG_RC_ERROR, - REG_RC_MAX -} reg_rcs_t; - -typedef enum reg_srcs_t_ { - REG_SRC_GSM, - REG_SRC_SIP, - REG_SRC_MAX -} reg_srcs_t; - -typedef enum reg_status_t_ { - REG_FAIL, - REG_ALL_FAIL -} reg_status_t; - -typedef struct reg_status_msg_t_ { - reg_srcs_t src_id; - reg_status_t msg_id; -} reg_status_msg_t; - -typedef enum { - CCM_STATUS_NONE = 0, - CCM_STATUS_STANDBY, - CCM_STATUS_ACTIVE -} reg_ccm_status; - -void sip_regmgr_send_status(reg_srcs_t src_id, reg_status_t msg_id); -sec_level_t sip_regmgr_get_sec_level(line_t line); -boolean sip_regmgr_srtp_fallback_enabled(line_t line); -void sip_platform_set_ccm_status(); -void sip_platform_cc_mode_notify(void); -void sip_platform_failover_ind(CCM_ID ccm_id); -void sip_platform_fallback_ind(CCM_ID ccm_id); -extern CCM_ID sip_regmgr_get_ccm_id(ccsipCCB_t *ccb); -boolean sip_platform_is_phone_idle(void); -extern void platform_reg_failover_ind(void *to_id); -extern void platform_reg_fallback_ind(void *from_id); -extern void sip_regmgr_phone_idle(boolean waited); -extern void sip_regmgr_fallback_rsp(); -extern void sip_regmgr_failover_rsp_start(); -extern void sip_regmgr_failover_rsp_complete(); -extern void ui_set_ccm_conn_status(const char *addr_str, int status); -extern void platform_cc_mode_notify(int mode); -extern void ui_reg_all_failed(void); -extern void platform_reg_fallback_cfm(void); -extern void platform_regallfail_ind(void *); -extern void sip_platform_logout_reset_req(void); -extern void platform_logout_reset_req (void); - -#endif /* _SIP_INTERFACE_REGMGR_H_ */ diff --git a/libs/sipcc/core/sipstack/h/sip_platform_task.h b/libs/sipcc/core/sipstack/h/sip_platform_task.h deleted file mode 100644 index 2521906873..0000000000 --- a/libs/sipcc/core/sipstack/h/sip_platform_task.h +++ /dev/null @@ -1,20 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _SIP_PLATFORM_TASK_H_ -#define _SIP_PLATFORM_TASK_H_ - -#include "cpr_socket.h" - -/* - * Prototypes - */ -void sip_platform_task_loop(void *arg); -void sip_platform_task_set_listen_socket(cpr_socket_t s); -void sip_platform_task_set_read_socket(cpr_socket_t s); -void sip_platform_task_clr_read_socket(cpr_socket_t s); - -void sip_platform_task_reset_listen_socket(cpr_socket_t s); - -#endif diff --git a/libs/sipcc/core/sipstack/httpish.c b/libs/sipcc/core/sipstack/httpish.c deleted file mode 100644 index f909a7baf2..0000000000 --- a/libs/sipcc/core/sipstack/httpish.c +++ /dev/null @@ -1,1642 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Functions that parse and create HTTP/1.1-like messages(RFC 2068). Basically - * code that converts from network(ie text) form to a usable structure - * and vice-versa. - */ - -#include -#include - -#include "plstr.h" -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "httpish.h" -#include "ccsip_protocol.h" -#include "phone_debug.h" -#include "ccsip_core.h" - -//#define HTTPISH_DEBUG if (1) -#define MSG_DELIMIT_SIZE 80 -#define TMP_BODY_BUF_SIZE 200 -#define CMPC_HEADER_SIZE 256 - -extern sip_header_t sip_cached_headers[]; -httpishMsg_t * -httpish_msg_create (void) -{ - int i; - httpishMsg_t *msg; - - msg = (httpishMsg_t *) cpr_calloc(1, sizeof(httpishMsg_t)); - if (!msg) { - return NULL; - } - - msg->headers = (queuetype *) cpr_calloc(1, sizeof(queuetype)); - - if (!msg->headers) { - cpr_free(msg); - return NULL; - } - - msg->retain_flag = FALSE; - msg->mesg_line = NULL; - msg->content_length = 0; - msg->is_complete = FALSE; - msg->headers_read = FALSE; - - for (i = 0; i < HTTPISH_MAX_BODY_PARTS; i++) { - msg->mesg_body[i].msgContentType = NULL; - msg->mesg_body[i].msgBody = NULL; - msg->mesg_body[i].msgLength = 0; - msg->mesg_body[i].msgContentId = NULL; - msg->mesg_body[i].msgContentEnc = SIP_CONTENT_ENCODING_IDENTITY_VALUE; - msg->mesg_body[i].msgContentDisp = SIP_CONTENT_DISPOSITION_SESSION_VALUE; - msg->mesg_body[i].msgRequiredHandling = TRUE; - msg->mesg_body[i].msgContentTypeValue = SIP_CONTENT_TYPE_UNKNOWN_VALUE; - } - - msg->num_body_parts = 0; - msg->raw_body = NULL; - - queue_init(msg->headers, 0); - - return msg; -} - -int -httpish_strncasecmp(const char *s1, const char* s2, size_t len) -{ - /*This routine is an enhanced version of strncasecmp(). - *It ensures that the two strings being compared for size "len" - *don't have trailing characters beyond "len" chars. - *The trailing whitespaces beyond "len" chars is ignored. - */ - const unsigned char *us1 = (const unsigned char *) s1; - const unsigned char *us2 = (const unsigned char *) s2; - - /* No match if only one ptr is NULL */ - if ((!s1 && s2) || (s1 && !s2)) - return ((int) (s1 - s2)); - - if ((len == 0) || (s1 == s2)) - return 0; - - while (len-- > 0 && toupper(*us1) == toupper(*us2)) { - if (len == 0 || *us1 == '\0' || *us2 == '\0') - break; - us1++; - us2++; - } - - if (len == 0 && toupper(*us1) == toupper(*us2)) { - //all "len" chars are compared, need to look for trailing - //chars beyond "len" string size. Ignore white spaces. - while (*(++us1) != '\0') { - if (*us1 != ' ' && *us1 != '\t') { - break; - } - } - - while (*(++us2) != '\0') { - if (*us2 != ' ' && *us2 != '\t') { - break; - } - } - } - - - return (toupper(*us1) - toupper(*us2)); -} - -void -httpish_msg_free (httpishMsg_t *msg) -{ - int i; - - if ((!msg) || (msg->retain_flag == TRUE)) { - return; - } - - UTILFREE(msg->mesg_line); - - // Free all body parts - for (i = 0; i < HTTPISH_MAX_BODY_PARTS; i++) { - UTILFREE(msg->mesg_body[i].msgContentType); - UTILFREE(msg->mesg_body[i].msgBody); - UTILFREE(msg->mesg_body[i].msgContentId); - } - UTILFREE(msg->raw_body); - - if (msg->headers) { - httpish_header *this_header; - - this_header = (httpish_header *) dequeue(msg->headers); - while (this_header != NULL) { - UTILFREE(this_header->header); - UTILFREE(this_header); - this_header = (httpish_header *) dequeue(msg->headers); - } - } - - UTILFREE(msg->headers); - msg->headers = NULL; - - /* Free the header cache */ - for (i = 0; i < HTTPISH_HEADER_CACHE_SIZE; ++i) { - if (msg->hdr_cache[i].hdr_start) { - cpr_free(msg->hdr_cache[i].hdr_start); - } - } - - /* Free the httpishMsg_t struct itself */ - cpr_free(msg); -} - -boolean -httpish_msg_is_request (httpishMsg_t *msg, - const char *schema, - int schema_len) -{ - char *loc; - - loc = msg->mesg_line; - - if (!msg->is_complete || !msg->mesg_line) { - return FALSE; - } - - /* - * There might be a couple of leading spaces. Not allowed, - * but still be friendly - */ - while ((*loc == ' ') && (*loc != '\0')) { - loc++; - } - - if (strncmp(loc, schema, schema_len)) { - return TRUE; - } else { - return FALSE; - } -} - - -boolean -httpish_msg_is_complete (httpishMsg_t *msg) -{ - return msg->is_complete; -} - - -hStatus_t -httpish_msg_add_reqline (httpishMsg_t *msg, - const char *method, - const char *url, - const char *version) -{ - - uint32_t linesize = 0; - - if (!msg || !method || !url || !version) { - return HSTATUS_FAILURE; - } - - if (msg->mesg_line) { - cpr_free(msg->mesg_line); - } - - linesize = strlen(method) + 1 + strlen(url) + 1 + strlen(version) + 1; - - msg->mesg_line = (char *) cpr_malloc(linesize * sizeof(char)); - if (!msg->mesg_line) { - return HSTATUS_FAILURE; - } - - snprintf(msg->mesg_line, linesize, "%s %s %s", method, url, version); - - return HSTATUS_SUCCESS; -} - -hStatus_t -httpish_msg_add_respline (httpishMsg_t *msg, - const char *version, - uint16_t status_code, - const char *reason_phrase) -{ - uint32_t linesize = 0; - - if (!msg || !reason_phrase || !version || - (status_code < HTTPISH_MIN_STATUS_CODE)) { - return HSTATUS_FAILURE; - } - - if (msg->mesg_line) { - cpr_free(msg->mesg_line); - } - - /* Assumes status codes are max 6 characters long */ - linesize = strlen(version) + 1 + 6 + 1 + strlen(reason_phrase) + 1; - - msg->mesg_line = (char *) cpr_malloc(linesize * sizeof(char)); - if (!msg->mesg_line) { - return HSTATUS_FAILURE; - } - - snprintf(msg->mesg_line, linesize, "%s %d %s", - version, status_code, reason_phrase); - - return HSTATUS_SUCCESS; -} - - -httpishReqLine_t * -httpish_msg_get_reqline (httpishMsg_t *msg) -{ - char *this_token; - char *msgline; - httpishReqLine_t *hreq = NULL; - char *strtok_state; - - if (!msg || !msg->mesg_line || !(msgline = cpr_strdup(msg->mesg_line))) { - return NULL; - } - - hreq = (httpishReqLine_t *) cpr_malloc(sizeof(httpishReqLine_t)); - if (!hreq) { - cpr_free(msgline); - return NULL; - } - - this_token = PL_strtok_r(msgline, " ", &strtok_state); - - if (!this_token) { - cpr_free(hreq); - cpr_free(msgline); - return NULL; - } - - hreq->method = cpr_strdup(this_token); - - this_token = PL_strtok_r(NULL, " ", &strtok_state); - - if (!this_token) { - cpr_free(hreq->method); - cpr_free(hreq); - cpr_free(msgline); - return NULL; - } - - hreq->url = cpr_strdup(this_token); - - this_token = PL_strtok_r(NULL, " ", &strtok_state); - - if (!this_token) { - cpr_free(hreq->method); - cpr_free(hreq->url); - cpr_free(hreq); - cpr_free(msgline); - return NULL; - } - - hreq->version = cpr_strdup(this_token); - cpr_free(msgline); - return hreq; -} - - -httpishRespLine_t * -httpish_msg_get_respline (httpishMsg_t *msg) -{ - char *this_token; - char *msgline; - httpishRespLine_t *hrsp = NULL; - char *strtok_state; - unsigned long strtoul_result; - char *strtoul_end; - - if (!msg || !msg->mesg_line) { - return NULL; - } - - msgline = cpr_strdup(msg->mesg_line); - if (!msgline) { - return NULL; - } - - hrsp = (httpishRespLine_t *) cpr_malloc(sizeof(httpishRespLine_t)); - - if (!hrsp) { - cpr_free(msgline); - return NULL; - } - - this_token = PL_strtok_r(msgline, " ", &strtok_state); - - if (!this_token) { - cpr_free(hrsp); - cpr_free(msgline); - return NULL; - } - - hrsp->version = cpr_strdup(this_token); - - this_token = PL_strtok_r(NULL, " ", &strtok_state); - - if (!this_token) { - cpr_free(hrsp->version); - cpr_free(hrsp); - cpr_free(msgline); - return NULL; - } - - errno = 0; - strtoul_result = strtoul(this_token, &strtoul_end, 10); - - if (errno || this_token == strtoul_end || strtoul_result > USHRT_MAX) { - cpr_free(hrsp->version); - cpr_free(hrsp); - cpr_free(msgline); - return NULL; - } - - hrsp->status_code = (uint16_t) strtoul_result; - - this_token = PL_strtok_r(NULL, " ", &strtok_state); - - /* reason phrase is optional */ - if (this_token) { - hrsp->reason_phrase = cpr_strdup(this_token); - } else { - hrsp->reason_phrase = NULL; - } - - cpr_free(msgline); - return (hrsp); -} - - - -void -httpish_msg_free_reqline (httpishReqLine_t *rqline) -{ - if (!rqline) { - return; - } - - UTILFREE(rqline->method); - UTILFREE(rqline->url); - UTILFREE(rqline->version); -} - - -void -httpish_msg_free_respline (httpishRespLine_t *rspline) -{ - if (!rspline) { - return; - } - - UTILFREE(rspline->reason_phrase); - UTILFREE(rspline->version); -} - -hStatus_t -httpish_msg_add_text_header (httpishMsg_t *msg, - const char *hname, - const char *hval) -{ - uint32_t linesize = 0; - httpish_header *this_header = NULL; - char *header_line = NULL; - - if (!msg || !hname || !hval) { - return HSTATUS_FAILURE; - } - - linesize = strlen(hname) + 2 + strlen(hval) + 1; - - header_line = (char *) cpr_malloc(linesize * sizeof(char)); - if (!header_line) - return HSTATUS_FAILURE; - - this_header = (httpish_header *) cpr_malloc(sizeof(httpish_header)); - if (!this_header) { - cpr_free(header_line); - return HSTATUS_FAILURE; - } - - snprintf(header_line, linesize, "%s: %s", hname, hval); - - this_header->header = header_line; - this_header->next = NULL; - - enqueue(msg->headers, (void *) this_header); - - return HSTATUS_SUCCESS; -} - - -hStatus_t -httpish_msg_add_int_header (httpishMsg_t *msg, - const char *hname, - int32_t hval) -{ - uint32_t linesize = 0; - char *header_line = NULL; - httpish_header *this_header = NULL; - - if (!msg || !hname) { - return HSTATUS_FAILURE; - } - - /* Assumes the int is less than 10 characters */ - linesize = strlen(hname) + 2 + 10 + 1; - - header_line = (char *) cpr_malloc(linesize * sizeof(char)); - if (!header_line) { - return HSTATUS_FAILURE; - } - - this_header = (httpish_header *) cpr_malloc(sizeof(httpish_header)); - if (!this_header) { - cpr_free(header_line); - return HSTATUS_FAILURE; - } - - snprintf(header_line, linesize, "%s: %d", hname, hval); - - this_header->header = header_line; - this_header->next = NULL; - - enqueue(msg->headers, (void *) this_header); - - return HSTATUS_SUCCESS; -} - -const char * -httpish_msg_get_cached_header_val (httpishMsg_t *msg, - int cache_index) -{ - return msg->hdr_cache[cache_index].val_start; -} - -int -compact_hdr_cmp (char *this_line, - const char *c_hname) -{ - char cmpct_hdr[CMPC_HEADER_SIZE]; - - if (c_hname) { - sstrncpy(cmpct_hdr, c_hname, CMPC_HEADER_SIZE); - return cpr_strcasecmp(this_line, cmpct_hdr); - } - return -1; -} - -int -httpish_header_name_val (char *sipHeaderName, char *this_line) -{ - unsigned int x = 0; - boolean nameFound = FALSE; - - if (!sipHeaderName || !this_line) { - return (SIP_ERROR); - } - - sipHeaderName[0] = '\0'; - - /* Remove the leading white spaces eg: ......From: or .....From....: */ - while ((*this_line==' ' || *this_line=='\t') ) { - this_line++; - } - - /* Copy the allowed characters for header field name */ - while ((*this_line > 32) && (*this_line < 127) && (x < HTTPISH_HEADER_NAME_SIZE)) { - if (*this_line == ':') { - nameFound = TRUE; - sipHeaderName[x] = '\0'; - break; - } - sipHeaderName[x] = *this_line; - this_line++; - x++; - } - - /* Remove trailing white spaces */ - if (nameFound == FALSE && x < HTTPISH_HEADER_NAME_SIZE) { - while ((*this_line == ' ' || *this_line=='\t') ){ - this_line++; - if (*this_line == ':') { - nameFound = TRUE; - sipHeaderName[x] = '\0'; - break; - } - } - } - sipHeaderName[HTTPISH_HEADER_NAME_SIZE-1] = '\0'; - - if (nameFound) { - return (SIP_OK); - } else { - return (SIP_ERROR); - } -} - -boolean -httpish_msg_header_present (httpishMsg_t *msg, - const char *hname) -{ - nexthelper *p; - char *this_line = NULL; - - /* - * To allow case-insensitive compact headers, we need to compare 2 - * characters before we can decide, what the header name is. - * e.g. Call-ID and Content-Type both start with C. - * For now assume there is no white space between header name and ":" - */ - - if (!msg || !hname || (msg->headers->count == 0)) { - return FALSE; - } - - p = (nexthelper *) msg->headers->qhead; - while (p) { - this_line = ((httpish_header *)p)->header; - if (this_line) { - /* Remove leading spaces */ - while ((*this_line == ' ') && (*this_line != '\0')) - this_line++; - if ((strlen(this_line) >= strlen(hname)) && - (cpr_strncasecmp(this_line, hname, strlen(hname))) == 0) { - return TRUE; - } - } - p = p->next; - } - - return FALSE; -} -const char * -httpish_msg_get_header_val (httpishMsg_t *msg, - const char *hname, - const char *c_hname) -{ - static const char fname[] = "httpish_msg_get_header_val"; - nexthelper *p; - char *this_line = NULL; - char headerName[HTTPISH_HEADER_NAME_SIZE]; - - headerName[0] = '\0'; - - /* - * To allow case-insensitive compact headers, we need to compare 2 - * characters before we can decide, what the header name is. - * e.g. Call-ID and Content-Type both start with C. - * For now assume there is no white space between header name and ":" - */ - - if (!msg || !hname || (msg->headers->count == 0)) { - return NULL; - } - - p = (nexthelper *) msg->headers->qhead; - while (p) { - this_line = ((httpish_header *)p)->header; - - if (httpish_header_name_val(headerName, this_line)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Invalid Header Passed %s\n", DEB_F_PREFIX_ARGS(HTTPISH, fname), this_line); - return (NULL); - } - - if (this_line) { - if ((cpr_strcasecmp(headerName, hname) == 0 || - compact_hdr_cmp(headerName, c_hname) == 0)) { - this_line = strchr(this_line, ':'); - if (this_line) { - this_line++; - /* Remove leading spaces */ - while ((*this_line == ' ') && (*this_line != '\0')) - this_line++; - if (*this_line == '\0') - return (NULL); - else - return ((const char *) this_line); - } - } - } - p = p->next; - } - return NULL; -} - -int32_t -httpish_msg_get_content_length (httpishMsg_t *msg) -{ - return msg->content_length; -} - -static boolean -httpish_msg_to_wstream (pmhWstream_t *ws, - httpishMsg_t *msg) -{ - nexthelper *p; - char tmp_body_buf[TMP_BODY_BUF_SIZE]; - int buf_len, total_length = 0, i, boundary_size; - - if (!pmhutils_wstream_write_line(ws, msg->mesg_line)) { - return (FALSE); - } - - p = (nexthelper *) msg->headers->qhead; - while (p) { - if (!pmhutils_wstream_write_line(ws, - (char *) (((httpish_header *)p)->header))) { - return (FALSE); - } - p = p->next; - } - if (msg->num_body_parts > 0) { - if (msg->num_body_parts > 1) { - // Write out the special Content-Type header and the - // Mime-Version header and the aggregate Content-Length header - // followed by the unique boundary - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, - "%s: multipart/mixed; boundary=%s\r\n", - HTTPISH_HEADER_CONTENT_TYPE, uniqueBoundary); - - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "%s: 1.0\r\n", - HTTPISH_HEADER_MIME_VERSION); - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - // Traverse the list and calculate the total size of the - // body - boundary_size = strlen("\r\n--\r\n") + strlen(uniqueBoundary); - for (i = 0; i < msg->num_body_parts; i++) { - total_length += boundary_size; - total_length += msg->mesg_body[i].msgLength; - total_length += sizeof(HTTPISH_HEADER_CONTENT_TYPE) + 1; - switch (msg->mesg_body[i].msgContentTypeValue) { - default: - case SIP_CONTENT_TYPE_UNKNOWN_VALUE: - total_length += strlen(msg->mesg_body[i].msgContentType) + 2; - break; - case SIP_CONTENT_TYPE_SDP_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_SDP) + 1; - break; - case SIP_CONTENT_TYPE_SIPFRAG_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_SIPFRAG) + 1; - break; - case SIP_CONTENT_TYPE_DIALOG_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_DIALOG) + 1; - break; - case SIP_CONTENT_TYPE_KPML_REQUEST_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_KPML_REQUEST) + 1; - break; - case SIP_CONTENT_TYPE_KPML_RESPONSE_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_KPML_RESPONSE) + 1; - break; - case SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_REMOTECC_REQUEST) + 1; - break; - case SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_REMOTECC_RESPONSE) + 1; - break; - case SIP_CONTENT_TYPE_CTI_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_CTI) + 1; - break; - case SIP_CONTENT_TYPE_CMXML_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_CMXML) + 1; - break; - case SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_TEXT_PLAIN) + 1; - break; - case SIP_CONTENT_TYPE_PRESENCE_VALUE: - total_length += sizeof(SIP_CONTENT_TYPE_PRESENCE) + 1; - break; - } - // Now estimate size of Content-Disposition header - total_length += sizeof(SIP_HEADER_CONTENT_DISP) + 1; - switch (msg->mesg_body[i].msgContentDisp) { - case SIP_CONTENT_DISPOSITION_RENDER_VALUE: - total_length += sizeof(SIP_CONTENT_DISPOSITION_RENDER) - 1; - break; - case SIP_CONTENT_DISPOSITION_SESSION_VALUE: - default: - total_length += sizeof(SIP_CONTENT_DISPOSITION_SESSION) - 1; - break; - case SIP_CONTENT_DISPOSITION_ICON_VALUE: - total_length += sizeof(SIP_CONTENT_DISPOSITION_ICON) - 1; - break; - case SIP_CONTENT_DISPOSITION_ALERT_VALUE: - total_length += sizeof(SIP_CONTENT_DISPOSITION_ALERT) - 1; - break; - case SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE: - total_length += sizeof(SIP_CONTENT_DISPOSITION_PRECONDITION) - 1; - break; - } - // Now the handling attribute - total_length += sizeof(";handling=") - 1; - if (msg->mesg_body[i].msgRequiredHandling) { - total_length += sizeof("required") + 1; - } else { - total_length += sizeof("optional") + 1; - } - // Now the content id - if (msg->mesg_body[i].msgContentId) { - total_length += sizeof(HTTPISH_HEADER_CONTENT_ID) + 1 + - strlen(msg->mesg_body[i].msgContentId) + 2; - - } - } - // Now account for the closing boundary which is 2+boundary_size - total_length += 2 + boundary_size + 2; - - // Now write it out - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "%s: %d\r\n", - HTTPISH_HEADER_CONTENT_LENGTH, total_length); - - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "\r\n--%s\r\n", uniqueBoundary); - - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - } else { - // Write out Content-Length for the first body - total_length = msg->mesg_body[0].msgLength; - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "%s: %d\r\n", - HTTPISH_HEADER_CONTENT_LENGTH, total_length); - - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - } - for (i = 0; i < msg->num_body_parts; i++) { - if (i > 0) { - // If there is another body to come, write the unique boundary - buf_len = snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "\r\n--%s\r\n", uniqueBoundary); - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - } - snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "Content-Type: %s\r\n", - msg->mesg_body[i].msgContentType); - sstrncat(tmp_body_buf, "Content-Disposition: ", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - - switch (msg->mesg_body[i].msgContentDisp) { - case SIP_CONTENT_DISPOSITION_RENDER_VALUE: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_RENDER, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - case SIP_CONTENT_DISPOSITION_SESSION_VALUE: - default: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_SESSION, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - case SIP_CONTENT_DISPOSITION_ICON_VALUE: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_ICON, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - case SIP_CONTENT_DISPOSITION_ALERT_VALUE: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_ALERT, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - case SIP_CONTENT_DISPOSITION_PRECONDITION_VALUE: - sstrncat(tmp_body_buf, SIP_CONTENT_DISPOSITION_PRECONDITION, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - break; - } - if (msg->mesg_body[i].msgRequiredHandling) { - sstrncat(tmp_body_buf, ";handling=required\r\n", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - } else { - sstrncat(tmp_body_buf, ";handling=optional\r\n", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - } - if (msg->mesg_body[i].msgContentId) { - sstrncat(tmp_body_buf, "Content-Id: ", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - sstrncat(tmp_body_buf, msg->mesg_body[i].msgContentId, - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - sstrncat(tmp_body_buf, "\r\n", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - } - sstrncat(tmp_body_buf, "\r\n", - sizeof(tmp_body_buf) - strlen(tmp_body_buf)); - buf_len = strlen(tmp_body_buf); - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - - // Now write the body - if (!pmhutils_wstream_write_bytes(ws, msg->mesg_body[i].msgBody, - msg->mesg_body[i].msgLength)) { - return (FALSE); - } - } - // After writing out the last body part, write out the last unique - // boundary line - if (msg->num_body_parts > 1) { - snprintf(tmp_body_buf, TMP_BODY_BUF_SIZE, "\r\n--%s--\r\n", uniqueBoundary); - buf_len = strlen(tmp_body_buf); - if (!pmhutils_wstream_write_bytes(ws, tmp_body_buf, buf_len)) { - return (FALSE); - } - } - } else { - if (!pmhutils_wstream_write_byte(ws, '\r')) { - return (FALSE); - } - if (!pmhutils_wstream_write_byte(ws, '\n')) { - return (FALSE); - } - } - - return (TRUE); -} - -hStatus_t -httpish_msg_write (httpishMsg_t *msg, - char *buf, - uint32_t *nbytes) -{ - pmhWstream_t *ws = NULL; - - ws = pmhutils_wstream_create_with_buf(buf, *nbytes); - if (!ws) { - return (HSTATUS_FAILURE); - } - - if (!httpish_msg_to_wstream(ws, msg)) { - pmhutils_wstream_delete(ws, FALSE); - cpr_free(ws); - return (HSTATUS_FAILURE); - } - - *nbytes = pmhutils_wstream_get_length(ws); - pmhutils_wstream_delete(ws, FALSE); - cpr_free(ws); - return HSTATUS_SUCCESS; -} - -int -httpish_cache_header_val (httpishMsg_t *hmsg, - char *this_line) -{ - static const char fname[] = "httpish_cache_header_val"; - char *hdr_start; - httpish_cache_t *hdr_cache; - int i; - char headerName[HTTPISH_HEADER_NAME_SIZE]; - - headerName[0] = '\0'; - - hdr_cache = hmsg->hdr_cache; - hdr_start = this_line; - - if (httpish_header_name_val(headerName, this_line)) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Invalid Header %s\n", DEB_F_PREFIX_ARGS(HTTPISH, fname), this_line); - return (SIP_ERROR); - } - - for (i = 0; i < HTTPISH_HEADER_CACHE_SIZE; ++i) { - sip_header_t *tmp = sip_cached_headers + i; - - if (cpr_strcasecmp(headerName, tmp->hname) == 0 || - compact_hdr_cmp(headerName, tmp->c_hname) == 0) { - this_line = strchr(this_line, ':'); - if (this_line) { - this_line++; /* Skip the ':' */ - - /* Remove leading spaces */ - while (*this_line == ' ' || *this_line == '\t') { - this_line++; - } - if (*this_line) { - if (hdr_cache[i].hdr_start) { - int org_len, offset; - int size; - char *newbuf; - - /* Multiple instances of a header, concatenate the - * header values with a ',' - */ - org_len = strlen(hdr_cache[i].hdr_start); - offset = hdr_cache[i].val_start - hdr_cache[i].hdr_start; - size = org_len + 2 + strlen(this_line); - newbuf = (char *) cpr_realloc(hdr_cache[i].hdr_start, - size); - if (newbuf == NULL) { - cpr_free(hdr_cache[i].hdr_start); - hdr_cache[i].hdr_start = NULL; - break; - } - hdr_cache[i].hdr_start = newbuf; - hdr_cache[i].val_start = hdr_cache[i].hdr_start + offset; - hdr_cache[i].hdr_start[org_len] = ','; - sstrncpy(hdr_cache[i].hdr_start + org_len + 1, this_line, - size - org_len - 1); - cpr_free(hdr_start); - } else { - hdr_cache[i].hdr_start = hdr_start; - hdr_cache[i].val_start = this_line; - } - } else { // this line is blank - cpr_free(hdr_start); - } - } else { // this line does not have a ':' - cpr_free(hdr_start); - } - return 0; - } - } - return -1; -} - -/* - * Return -1 for invalid/empty content-length value - * else return the content length - */ -int32_t -get_content_length (httpishMsg_t *hmsg) -{ - int i; - const char *hdr_val; - long strtol_result; - char *strtol_end; - - hdr_val = httpish_msg_get_cached_header_val(hmsg, CONTENT_LENGTH); - if (hdr_val == NULL) { - return -1; - } - - for (i = 0; hdr_val[i]; ++i) { - if (!isdigit((int) hdr_val[i])) { - return -1; - } - } - - /* If the string was empty then the content length is still invalid */ - if (!i) { - return -1; - } - - errno = 0; - strtol_result = strtol(hdr_val, &strtol_end, 10); - - if (errno || hdr_val == strtol_end || strtol_result > INT_MAX) { - return -1; - } else { - return (int) strtol_result; - } -} - -uint8_t -get_content_type_value (const char *content_type) -{ - if (!content_type) { - return SIP_CONTENT_TYPE_UNKNOWN_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_SDP, - sizeof(SIP_CONTENT_TYPE_SDP) - 1)) { - return SIP_CONTENT_TYPE_SDP_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_SIPFRAG, - sizeof(SIP_CONTENT_TYPE_SIPFRAG) - 1)) { - return SIP_CONTENT_TYPE_SIPFRAG_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_TEXT_PLAIN, - sizeof(SIP_CONTENT_TYPE_TEXT_PLAIN) - 1)) { - return SIP_CONTENT_TYPE_TEXT_PLAIN_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_SIP, - sizeof(SIP_CONTENT_TYPE_SIP) - 1)) { - return SIP_CONTENT_TYPE_SIP_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_MWI, - sizeof(SIP_CONTENT_TYPE_MWI) - 1)) { - return SIP_CONTENT_TYPE_MWI_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_MULTIPART_MIXED, - sizeof(SIP_CONTENT_TYPE_MULTIPART_MIXED) - 1)) { - return SIP_CONTENT_TYPE_MULTIPART_MIXED_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE, - sizeof(SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE) - 1)) { - return SIP_CONTENT_TYPE_MULTIPART_ALTERNATIVE_VALUE; - } - else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_DIALOG, - sizeof(SIP_CONTENT_TYPE_DIALOG) - 1)) { - return SIP_CONTENT_TYPE_DIALOG_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_KPML_REQUEST, - sizeof(SIP_CONTENT_TYPE_KPML_REQUEST) - 1)) { - return SIP_CONTENT_TYPE_KPML_REQUEST_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_KPML_RESPONSE, - sizeof(SIP_CONTENT_TYPE_KPML_RESPONSE) - 1)) { - return SIP_CONTENT_TYPE_KPML_RESPONSE_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_REMOTECC_REQUEST, - sizeof(SIP_CONTENT_TYPE_REMOTECC_REQUEST) - 1)) { - return SIP_CONTENT_TYPE_REMOTECC_REQUEST_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_CONFIGAPP, - sizeof(SIP_CONTENT_TYPE_CONFIGAPP) - 1)) { - return SIP_CONTENT_TYPE_CONFIGAPP_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_REMOTECC_RESPONSE, - sizeof(SIP_CONTENT_TYPE_REMOTECC_RESPONSE) - 1)) { - return SIP_CONTENT_TYPE_REMOTECC_RESPONSE_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_PRESENCE, - sizeof(SIP_CONTENT_TYPE_PRESENCE) - 1)) { - return SIP_CONTENT_TYPE_PRESENCE_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_CMXML, - sizeof(SIP_CONTENT_TYPE_CMXML) - 1)) { - return SIP_CONTENT_TYPE_CMXML_VALUE; - } else if (!httpish_strncasecmp(content_type, SIP_CONTENT_TYPE_CTI, - sizeof(SIP_CONTENT_TYPE_CTI) - 1)) { - return SIP_CONTENT_TYPE_CTI_VALUE; - } - return SIP_CONTENT_TYPE_UNKNOWN_VALUE; -} - -/****************************************************************** - * msg_process_one_body - * This function will process one of the body parts of the whole body - * Headers not understood will be ignored - * - msg_start should be pointing at the first header of the body part - * - msg_end at its last character - ******************************************************************/ -int -msg_process_one_body (httpishMsg_t *hmsg, - char *msg_start, - char *msg_end, - int current_body_part) -{ - static const char fname[] = "msg_process_one_body"; - pmhRstream_t *rstream = NULL; - char *content_type = NULL, *content_disp = NULL; - char *line = NULL, *body = NULL; - char *content_enc = NULL; - char *content_id = NULL; int nbytes = 0; - boolean body_read = FALSE; - - // Adjust msg_start to point to the first valid character - while (*msg_start == '\r' || *msg_start == '\n') { - msg_start++; - } - - // Convert this chunk of data into a more parse-able format - rstream = pmhutils_rstream_create(msg_start, (uint32_t)(msg_end - msg_start)); - - while (!body_read) { - if (rstream) { - line = pmhutils_rstream_read_line(rstream); - } - - if (line) { - // Look for the kind of line it is - if (!cpr_strncasecmp(line, HTTPISH_HEADER_CONTENT_TYPE, - sizeof(HTTPISH_HEADER_CONTENT_TYPE) - 1)) { - // Its Content-Type, read in the value - // XXX what if the line looks like "Content-Type-Garbage: some-value"? - content_type = line + sizeof(HTTPISH_HEADER_CONTENT_TYPE); - // XXX what if the line looks like "Content-Type : some-value"? - while (*content_type == ' ') { - content_type++; - } - hmsg->mesg_body[current_body_part].msgContentTypeValue = get_content_type_value(content_type); - nbytes = strlen(content_type) + 1; - hmsg->mesg_body[current_body_part].msgContentType = - (char *) cpr_malloc((nbytes)*sizeof(char)); - if (hmsg->mesg_body[current_body_part].msgContentType == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed\n", fname); - } else { - memcpy(hmsg->mesg_body[current_body_part].msgContentType, - content_type, nbytes); - } - } else if (!cpr_strncasecmp(line, HTTPISH_HEADER_CONTENT_ID, - sizeof(HTTPISH_HEADER_CONTENT_ID) - 1)) { - //Its Content-Id, read the value - content_id = line + sizeof(HTTPISH_HEADER_CONTENT_ID); - while(*content_id == ' ') { - content_id++; - } - nbytes = strlen(content_id) + 1; - hmsg->mesg_body[current_body_part].msgContentId = - (char *) cpr_malloc((nbytes)*sizeof(char)); - if (hmsg->mesg_body[current_body_part].msgContentId == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"malloc failed\n", fname); - } - memcpy(hmsg->mesg_body[current_body_part].msgContentId, - content_id, nbytes); - } else if (!cpr_strncasecmp(line, SIP_HEADER_CONTENT_DISP, - sizeof(SIP_HEADER_CONTENT_DISP) - 1)) { - // Its Content-Disposition, read in the value - content_disp = line + sizeof(SIP_HEADER_CONTENT_DISP); - while (*content_disp == ' ') { - content_disp++; - } - if (!cpr_strncasecmp(content_disp, SIP_CONTENT_DISPOSITION_SESSION, - sizeof(SIP_CONTENT_DISPOSITION_SESSION) - 1)) { - hmsg->mesg_body[current_body_part].msgContentDisp = - SIP_CONTENT_DISPOSITION_SESSION_VALUE; - content_disp += sizeof(SIP_CONTENT_DISPOSITION_SESSION) - 1; - } else { - hmsg->mesg_body[current_body_part].msgContentDisp = - SIP_CONTENT_DISPOSITION_UNKNOWN_VALUE; - content_disp = strchr(line, ';'); - } - if (content_disp && *content_disp == ';') { - content_disp++; - if (!cpr_strncasecmp(content_disp, "handling", 8)) { - content_disp += 9; - if (!cpr_strncasecmp(content_disp, "required", 8)) { - hmsg->mesg_body[current_body_part].msgRequiredHandling = TRUE; - } else if (!cpr_strncasecmp(content_disp, "optional", 8)) { - hmsg->mesg_body[current_body_part].msgRequiredHandling = FALSE; - } - } - } - } else if (!cpr_strncasecmp(line, HTTPISH_HEADER_CONTENT_ENCODING, - sizeof(HTTPISH_HEADER_CONTENT_ENCODING) - 1)) { - content_enc = line + sizeof(HTTPISH_HEADER_CONTENT_ENCODING); - while (*content_enc == ' ') { - content_enc++; - } - if (!cpr_strcasecmp(content_enc, SIP_CONTENT_ENCODING_IDENTITY)) { - hmsg->mesg_body[current_body_part].msgContentEnc = - SIP_CONTENT_ENCODING_IDENTITY_VALUE; - } else { - hmsg->mesg_body[current_body_part].msgContentEnc = - SIP_CONTENT_ENCODING_UNKNOWN_VALUE; - } - } else if (!(*line)) { - body_read = TRUE; - // The rest of the bytes are the body - hmsg->mesg_body[current_body_part].msgLength = - rstream->nbytes - rstream->bytes_read; - body = pmhutils_rstream_read_bytes(rstream, rstream->nbytes - rstream->bytes_read); - if (body) { - hmsg->mesg_body[current_body_part].msgBody = body; - } - } else { - // Unhandled header type - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Unrecognized header in body\n", DEB_F_PREFIX_ARGS(HTTPISH, fname)); - } - // Free the read line - cpr_free(line); - line = NULL; - } else { - body_read = TRUE; - } - } - // Free the created stream structure - pmhutils_rstream_delete(rstream, FALSE); - cpr_free(rstream); - return 0; -} - -/****************************************************************** - * msg_process_multiple_bodies - * This function will process multiple body parts of the whole body - * boundary should point to the delimiter string, raw body points to - * the beginning of the whole body structure in the message - * - * The algorithm here is to find the beginning and the end of each - * body part and send it off for further header and body extraction - ******************************************************************/ -int -msg_process_multiple_bodies (httpishMsg_t *hmsg, - char *boundary, - char *raw_body) -{ - char msg_delimit[MSG_DELIMIT_SIZE]; - int i, body_part = 0; - boolean end_of_proc = FALSE; - char *msg_start, *msg_end; - - // First copy the boundary in an array - msg_delimit[0] = '-'; - msg_delimit[1] = '-'; - for (i = 0; boundary[i] != '\r' && boundary[i] != '\n' && - boundary[i] != ';' && boundary[i] != '\0'; i++) { - if (i + 2 >= MSG_DELIMIT_SIZE) { - return body_part; - } - msg_delimit[i + 2] = boundary[i]; - } - msg_delimit[i + 2] = '\0'; - - // Loop through the body segments - while (!end_of_proc && body_part < HTTPISH_MAX_BODY_PARTS) { - msg_start = strstr(raw_body, msg_delimit); - if (msg_start) { - msg_start += strlen(msg_delimit) + 1; - msg_end = strstr(msg_start, msg_delimit); - if (msg_end) { - (void) msg_process_one_body(hmsg, msg_start, msg_end - 1, - body_part); - } else { - // No boundary found for message end, return error - end_of_proc = TRUE; - continue; - } - } else { - // No boundary found for message start, return error - end_of_proc = TRUE; - continue; - } - raw_body = msg_end; - // Check if this is the last boundary - if (*(raw_body + strlen(msg_delimit)) == '-') { - end_of_proc = TRUE; - } - body_part++; - } - return body_part; -} - -hStatus_t -httpish_msg_process_network_msg (httpishMsg_t *hmsg, - char *nmsg, - uint32_t *nbytes) -{ - static const char fname[] = "httpish_msg_process_network_msg"; - pmhRstream_t *rs = NULL; - int32_t bytes_remaining, delta; - char *mline; - hStatus_t retval; - char *raw_body = NULL; - const char *content_type = NULL; - const char *content_id = NULL; - int32_t contentid_len; - int32_t contenttype_len; - - if (!hmsg || !nmsg || (*nbytes <= 0)) { - return HSTATUS_FAILURE; - } - - if (hmsg->is_complete == TRUE) { - *nbytes = 0; - return HSTATUS_SUCCESS; - } - - if ((rs = pmhutils_rstream_create(nmsg, *nbytes)) == NULL) - return HSTATUS_FAILURE; - - /* Try to read message line */ - while (!hmsg->mesg_line) { - mline = pmhutils_rstream_read_line(rs); - if (!mline) { - *nbytes = rs->bytes_read; - if (rs->eof == TRUE) { - retval = HSTATUS_SUCCESS; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Msg line read failure due to RS->EOF\n", fname); - } else { - retval = HSTATUS_FAILURE; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Msg line read failure\n", fname); - } - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return retval; - } - if (!(*mline)) { - cpr_free(mline); - } else { - hmsg->mesg_line = mline; - } - } - - /* There is a message line. We could have a header or a message body */ - while (!hmsg->headers_read) { - char *this_header; - - this_header = pmhutils_rstream_read_line(rs); - if (!this_header) { - *nbytes = rs->bytes_read; - if (rs->eof == TRUE) { - retval = HSTATUS_SUCCESS; - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Header line read failure due to RS->EOF\n", DEB_F_PREFIX_ARGS(HTTPISH, fname)); - } else { - retval = HSTATUS_FAILURE; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Header line read failure\n", fname); - } - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return retval; - } - if (!(*this_header)) { - cpr_free(this_header); - hmsg->headers_read = TRUE; - } else { - httpish_header *h; - - if (httpish_cache_header_val(hmsg, this_header) == -1) { - /* - * For a non-cacheable header or error in caching routine, - * use the header linked list. - */ - h = (httpish_header *) cpr_malloc(sizeof(httpish_header)); - if (!h) { - *nbytes = rs->bytes_read; - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - cpr_free(this_header); - return HSTATUS_FAILURE; - } - - h->next = NULL; - h->header = this_header; - enqueue(hmsg->headers, (void *)h); - } - - } - } - - /* Calculate the bytes remaining in the read stream */ - bytes_remaining = rs->nbytes - rs->bytes_read; - - /* Now get the content length header value */ - hmsg->content_length = get_content_length(hmsg); - if (hmsg->content_length == -1) { - /* Bad or missing content-length header - * For UDP, assume remaining msg is message body. - * For TCP, message is not complete without content-length header - * but we will ignore this possibility for now (assume content-length will always be there) - * since we don't know if we have a complete message or a fragmented one - */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Content-Length header not received\n", fname); - hmsg->content_length = bytes_remaining; - } - - delta = bytes_remaining - hmsg->content_length; - if (delta) { - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX "Content Length %d, Bytes Remaining %d.\n", DEB_F_PREFIX_ARGS(HTTPISH, fname), - hmsg->content_length, bytes_remaining); - } - if (delta < 0) { - /* We have fewer bytes than specified by Content-Length header */ - hmsg->content_length = bytes_remaining; - hmsg->is_complete = FALSE; - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Partial body received\n", DEB_F_PREFIX_ARGS(HTTPISH, fname)); - } else { - hmsg->is_complete = TRUE; - } - - if (hmsg->content_length > 0) { - raw_body = pmhutils_rstream_read_bytes(rs, hmsg->content_length); - if (!raw_body) { - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return HSTATUS_FAILURE; - } - } - - // If message is not complete we should not parse the message any more - if (!hmsg->is_complete) { - *nbytes = rs->bytes_read; - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - UTILFREE(raw_body); - return HSTATUS_SUCCESS; - } - - // Figure out whether more parsing of the received body is necessary - content_type = httpish_msg_get_cached_header_val(hmsg, CONTENT_TYPE); - if (content_type && (hmsg->content_length > 0)) { - if (!cpr_strncasecmp(content_type, "multipart/mixed", 15)) { - - char *boundary = NULL; - int num_bodies = 0; - - // find the boundary tag - boundary = strchr(content_type, '='); - if (boundary) { - boundary++; - if (raw_body) { - num_bodies = msg_process_multiple_bodies(hmsg, boundary, raw_body); - } - - if (num_bodies == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in decoding multipart messages\n", fname); - } else { - hmsg->num_body_parts = (uint8_t) num_bodies; - } - } else { - // No boundary specified! - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Error in decoding multipart messages: No body delimiter\n", fname); - } - hmsg->raw_body = raw_body; - - } else { - // All of the body is of a single type - // hmsg->mesg_body[0].msgBody = raw_body; - hmsg->mesg_body[0].msgBody = (char *) - cpr_malloc(hmsg->content_length + 1); - if (hmsg->mesg_body[0].msgBody == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to get memory\n", fname); - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - cpr_free(raw_body); - return HSTATUS_FAILURE; - } - - if (raw_body) { - memcpy(hmsg->mesg_body[0].msgBody, raw_body, - hmsg->content_length + 1); - } - - content_id = httpish_msg_get_header_val(hmsg, HTTPISH_HEADER_CONTENT_ID, NULL); - if (content_id) { - contentid_len = strlen(content_id) + 1; - hmsg->mesg_body[0].msgContentId = (char *) - cpr_malloc(contentid_len * sizeof(char)); - if (hmsg->mesg_body[0].msgContentId == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to get memory\n", fname); - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - cpr_free(raw_body); - return HSTATUS_FAILURE; - } - memcpy(hmsg->mesg_body[0].msgContentId, - content_id, contentid_len); - } - - hmsg->mesg_body[0].msgContentTypeValue = get_content_type_value(content_type); - contenttype_len = strlen(content_type) + 1; - hmsg->mesg_body[0].msgContentType = (char *) - cpr_malloc(contenttype_len * sizeof(char)); - if (hmsg->mesg_body[0].msgContentType == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to get memory\n", fname); - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - cpr_free(raw_body); - return HSTATUS_FAILURE; - } - memcpy(hmsg->mesg_body[0].msgContentType, - content_type, contenttype_len); - - hmsg->mesg_body[0].msgContentDisp = - SIP_CONTENT_DISPOSITION_SESSION_VALUE; - hmsg->mesg_body[0].msgRequiredHandling = TRUE; - hmsg->mesg_body[0].msgLength = hmsg->content_length; - hmsg->num_body_parts = 1; - hmsg->raw_body = raw_body; - } - } else if (hmsg->content_length > 0) { - // No content-type specified but there is a body present. Treat this - // as an error - hmsg->is_complete = FALSE; - hmsg->content_length = -1; - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Body found without content-type\n", fname); - UTILFREE(raw_body); - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return HSTATUS_SUCCESS; - } - - *nbytes = rs->bytes_read; - pmhutils_rstream_delete(rs, FALSE); - cpr_free(rs); - return HSTATUS_SUCCESS; -} - - -hStatus_t -httpish_msg_add_body (httpishMsg_t *msg, - char *body, - uint32_t nbytes, - const char *content_type, - uint8_t msg_disposition, - boolean required, - char *content_id) -{ - static const char fname[] = "httpish_msg_add_body"; - uint8_t current_body_part; - uint32_t contenttype_len; - - if (!msg || !body || (nbytes == 0)) { - return HSTATUS_FAILURE; - } - - if (msg->num_body_parts == HTTPISH_MAX_BODY_PARTS) { - return HSTATUS_FAILURE; - } - - // Add body at the next available index - current_body_part = msg->num_body_parts; - - contenttype_len = strlen(content_type) + 1; - msg->mesg_body[current_body_part].msgContentType = (char *) - cpr_malloc(contenttype_len * sizeof(char)); - if (msg->mesg_body[current_body_part].msgContentType == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to get memory\n", fname); - return HSTATUS_FAILURE; - } - - msg->mesg_body[current_body_part].msgBody = body; - memcpy(msg->mesg_body[current_body_part].msgContentType, - content_type, contenttype_len); - msg->mesg_body[current_body_part].msgContentTypeValue = get_content_type_value(content_type); - msg->mesg_body[current_body_part].msgContentDisp = msg_disposition; - msg->mesg_body[current_body_part].msgRequiredHandling = required; - msg->mesg_body[current_body_part].msgLength = nbytes; - msg->mesg_body[current_body_part].msgContentId = content_id; - - msg->num_body_parts++; - - return HSTATUS_SUCCESS; -} - - -httpishStatusCodeClass_t -httpish_msg_get_code_class (uint16_t statusCode) -{ - httpishStatusCodeClass_t retval; - int fc = statusCode / 100; - - switch (fc) { - case 1: - retval = codeClass1xx; - break; - case 2: - retval = codeClass2xx; - break; - case 3: - retval = codeClass3xx; - break; - case 4: - retval = codeClass4xx; - break; - case 5: - retval = codeClass5xx; - break; - case 6: - retval = codeClass6xx; - break; - default: - retval = codeClassInvalid; - break; - } - - return retval; -} - - -uint16_t -httpish_msg_get_num_particular_headers (httpishMsg_t *msg, - const char *hname, - const char *c_hname, - char *header_val[], - uint16_t max_headers) -{ - nexthelper *p; - char *this_line = NULL; - uint16_t found = 0; - - if (!msg || !hname) { - return 0; - } - - p = (nexthelper *) msg->headers->qhead; - - while (p && found < max_headers) { - this_line = ((httpish_header *)p)->header; - if (this_line) { - /* Remove leading spaces */ - while ((*this_line == ' ') && (*this_line != '\0')) - this_line++; - if ((strlen(this_line) > strlen(hname) + 1) && - (cpr_strncasecmp(this_line, hname, strlen(hname)) == 0 || - compact_hdr_cmp(this_line, c_hname) == 0)) { - this_line = strchr(this_line, ':'); - if (this_line) { - this_line++; - /* Remove leading spaces */ - while ((*this_line == ' ') && (*this_line != '\0')) - this_line++; - if (*this_line == '\0') { - p = p->next; - continue; - } else { - header_val[found] = this_line; - found++; - } - } - } - } - p = p->next; - } - return found; -} - - diff --git a/libs/sipcc/core/sipstack/pmhutils.c b/libs/sipcc/core/sipstack/pmhutils.c deleted file mode 100644 index 57c83d784c..0000000000 --- a/libs/sipcc/core/sipstack/pmhutils.c +++ /dev/null @@ -1,308 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "pmhutils.h" -#include "phone.h" - - -#define WSTREAM_START_SIZE 1024 - -pmhRstream_t * -pmhutils_rstream_create (char *buf, uint32_t nbytes) -{ - pmhRstream_t *pmhRstream; - - if (!buf || (nbytes == 0)) { - return NULL; - } - - pmhRstream = (pmhRstream_t *) cpr_malloc(sizeof(pmhRstream_t)); - if (!pmhRstream) { - return NULL; - } - - pmhRstream->eof = pmhRstream->error = FALSE; - pmhRstream->buff = pmhRstream->loc = buf; - pmhRstream->nbytes = nbytes; - pmhRstream->bytes_read = 0; - - return pmhRstream; -} - -void -pmhutils_rstream_delete (pmhRstream_t *pmhRstream, boolean freebuf) -{ - if (!pmhRstream) { - return; - } - - pmhRstream->error = TRUE; - - if (freebuf && pmhRstream->buff) { - cpr_free(pmhRstream->buff); - } -} - -char * -pmhutils_rstream_read_bytes (pmhRstream_t *pmhRstream, int32_t nbytes) -{ - char *ret; - - if (!pmhRstream || !pmhRstream->loc || (pmhRstream->eof == TRUE)) { - return NULL; - } - - if (pmhRstream->bytes_read >= pmhRstream->nbytes) { - pmhRstream->eof = TRUE; - return NULL; - } - - if ((pmhRstream->nbytes - pmhRstream->bytes_read) < (int32_t) nbytes) { - return NULL; - } - ret = (char *) cpr_malloc((nbytes + 1) * sizeof(char)); - if (ret == NULL) { - // Addition of 1 byte (NULL) will save us from strlen errr - return NULL; - } - memcpy(ret, pmhRstream->loc, nbytes); - ret[nbytes] = 0; /* ensure null terminating character */ - pmhRstream->bytes_read += nbytes; - pmhRstream->loc += nbytes; - - return (ret); -} - - -#define SANITY_LINE_SIZE PKTBUF_SIZ - -unsigned short linesize = 80; -unsigned short incr_size = 32; - -char * -pmhutils_rstream_read_line (pmhRstream_t *pmhRstream) -{ - char *ret_line; - char *new_loc = NULL; - int offset, bytes_allocated; - boolean line_break; - - if (!pmhRstream || !pmhRstream->loc || (pmhRstream->eof == TRUE)) { - return NULL; - } - - if (pmhRstream->bytes_read >= pmhRstream->nbytes) { - pmhRstream->eof = TRUE; - return NULL; - } - - new_loc = pmhRstream->loc; - - ret_line = (char *) cpr_malloc(linesize); - if (ret_line == NULL) { - return NULL; - } - offset = 0; - bytes_allocated = linesize; - /* Search for the first occurrence of a line break */ - while (1) { - line_break = FALSE; - if (*new_loc == '\r') { - line_break = TRUE; - new_loc++; - } - if (*new_loc == '\n') { - line_break = TRUE; - new_loc++; - } - if (line_break) { - if (*new_loc != ' ' && *new_loc != '\t') { - break; - } - } - - if (offset == (bytes_allocated - 1)) { - char *newbuf; - - bytes_allocated += incr_size; - newbuf = (char *) cpr_realloc(ret_line, bytes_allocated); - if (newbuf == NULL) { - if (bytes_allocated != 0) { - cpr_free(ret_line); - } - return NULL; - } - ret_line = newbuf; - } - ret_line[offset++] = *new_loc++; - if (*new_loc == '\0') { - /* We hit the end of buffer before hitting a line break */ - pmhRstream->eof = TRUE; - pmhRstream->bytes_read += (new_loc - pmhRstream->loc); - pmhRstream->loc = new_loc; - cpr_free(ret_line); - return NULL; - } - } - - pmhRstream->bytes_read += (new_loc - pmhRstream->loc); - /* Update the internal location pointer and bytes read */ - - if (pmhRstream->bytes_read >= pmhRstream->nbytes) { - pmhRstream->loc = pmhRstream->buff + pmhRstream->nbytes; - pmhRstream->eof = TRUE; - } else { - pmhRstream->loc = pmhRstream->buff + pmhRstream->bytes_read; - } - - ret_line[offset] = 0; - return ret_line; -} - -pmhWstream_t * -pmhutils_wstream_create_with_buf (char *buf, uint32_t nbytes) -{ - pmhWstream_t *pmhWstream = NULL; - - if (buf && nbytes && (nbytes > 0)) { - pmhWstream = (pmhWstream_t *) cpr_malloc(sizeof(pmhWstream_t)); - if (!pmhWstream) { - return (NULL); - } - pmhWstream->buff = buf; - pmhWstream->nbytes = 0; - pmhWstream->total_bytes = nbytes; - pmhWstream->growable = FALSE; - } - return (pmhWstream); -} - - -uint32_t -pmhutils_wstream_get_length (pmhWstream_t *ws) -{ - if (ws) { - return (ws->nbytes); - } else { - return (0); - } -} - - -void -pmhutils_wstream_delete (pmhWstream_t *pmhWstream, boolean freebuf) -{ - if (pmhWstream && freebuf && pmhWstream->buff) { - cpr_free(pmhWstream->buff); - } -} - - -boolean -pmhutils_wstream_write_line (pmhWstream_t *pmhWstream, char *this_line) -{ - - /* Sanity check */ - if (this_line == NULL || strlen(this_line) > SANITY_LINE_SIZE) { - return FALSE; - } - - if (!(pmhWstream && this_line)) { - return FALSE; - } - - while ((pmhWstream->nbytes + (int32_t)strlen(this_line)) > - pmhWstream->total_bytes) { - if (!pmhWstream->growable || - (FALSE == pmhutils_wstream_grow(pmhWstream))) { - return FALSE; - } - } - - memcpy(&pmhWstream->buff[pmhWstream->nbytes], this_line, - strlen(this_line)); - - pmhWstream->nbytes += strlen(this_line); - if (!pmhutils_wstream_write_byte(pmhWstream, '\r')) { - return FALSE; - } - - if (!pmhutils_wstream_write_byte(pmhWstream, '\n')) { - return FALSE; - } - - return TRUE; -} - -boolean -pmhutils_wstream_write_byte (pmhWstream_t *pmhWstream, char c) -{ - if (!pmhWstream) { - return FALSE; - } - - if ((pmhWstream->nbytes + 1) > pmhWstream->total_bytes) { - if (!pmhWstream->growable || - (FALSE == pmhutils_wstream_grow(pmhWstream))) { - return FALSE; - } - } - - pmhWstream->buff[pmhWstream->nbytes] = c; - pmhWstream->nbytes++; - - return TRUE; -} - -boolean -pmhutils_wstream_write_bytes (pmhWstream_t *pmhWstream, - char *inbuf, uint32_t nbytes) -{ - - if (!pmhWstream) { - return FALSE; - } - - while ((pmhWstream->nbytes + (int32_t) nbytes) > pmhWstream->total_bytes) { - if (!pmhWstream->growable || - (FALSE == pmhutils_wstream_grow(pmhWstream))) { - return FALSE; - } - } - - memcpy(&pmhWstream->buff[pmhWstream->nbytes], inbuf, nbytes); - - pmhWstream->nbytes += nbytes; - - return TRUE; -} - -boolean -pmhutils_wstream_grow (pmhWstream_t *pmhWstream) -{ - char *newbuf; - - if (!pmhWstream || !pmhWstream->buff || !pmhWstream->growable) { - return FALSE; - } - - newbuf = (char *) cpr_realloc((void *) pmhWstream->buff, - pmhWstream->total_bytes + WSTREAM_START_SIZE); - if (newbuf == NULL) { - if ((pmhWstream->total_bytes + WSTREAM_START_SIZE) != 0) { - cpr_free(pmhWstream->buff); - } - pmhWstream->buff = NULL; - return FALSE; - } - - pmhWstream->buff = newbuf; - - pmhWstream->total_bytes += WSTREAM_START_SIZE; - - return TRUE; -} diff --git a/libs/sipcc/core/sipstack/sip_common_regmgr.c b/libs/sipcc/core/sipstack/sip_common_regmgr.c deleted file mode 100644 index 72c14fb1b2..0000000000 --- a/libs/sipcc/core/sipstack/sip_common_regmgr.c +++ /dev/null @@ -1,3471 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "phntask.h" -#include "phone_types.h" -#include "phone_debug.h" -#include "util_string.h" -#include "dns_utils.h" -#include "cpr_socket.h" -#include "util_string.h" -#include "sip_common_transport.h" -#include "sip_ccm_transport.h" -#include "ccsip_messaging.h" -#include "ccsip_register.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "singly_link_list.h" -#include "uiapi.h" -#include "text_strings.h" -#include "ccsip_callinfo.h" -#include "sip_interface_regmgr.h" -#include "ccsip_task.h" -#include "cpr_rand.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_subsmanager.h" -#include "ccsip_publish.h" -#include "ccsip_platform_tls.h" - -#define REGALL_FAIL_TIME 100 -boolean regall_fail_attempt = FALSE; -boolean registration_reject = FALSE; - -int retry_times = 0; - -boolean config_update_required = FALSE; -void *new_standby_available = NULL; -sll_handle_t fallback_ccb_list; -static boolean wan_failure = FALSE; -extern ti_config_table_t CCM_Device_Specific_Config_Table[MAX_CCM]; -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; -extern uint16_t ccm_config_id_addr_str[MAX_CCM]; -#ifdef IPV6_STACK_ENABLED - -extern uint16_t ccm_config_id_ipv6_addr_str[MAX_CCM]; -#endif - -extern boolean sip_reg_all_failed; -extern void sip_platform_handle_service_control_notify(sipServiceControl_t * scp); -extern void ui_update_registration_state_all_lines(boolean registered); -extern int phone_local_tcp_port[UNUSED_PARAM]; - -ccm_failover_table_t CCM_Failover_Table; -ccm_fallback_table_t CCM_Fallback_Table; -cc_config_table_t CC_Config_Table[MAX_REG_LINES + 1]; -typedef struct fallback_line_num_t_ { - line_t line; - boolean available; -} fallback_line_num_t; - -static fallback_line_num_t fallback_lines_available[MAX_CCM - 1] = -{ - {MAX_CCBS, TRUE}, - {MAX_CCBS + 1, TRUE}, -}; - -static void sip_regmgr_update_call_ccb(void); -void sip_regmgr_fallback_generic_timer_stop(cprTimer_t timer); -boolean sip_regmgr_find_fallback_ccb_by_ccmid (CCM_ID ccm_id, ccsipCCB_t **ccb_ret); - -void sip_regmgr_clean_standby_ccb(ccsipCCB_t *ccb); -static void sip_regmgr_tls_retry_timer_start (fallback_ccb_t *fallback_ccb); -static void -sip_regmgr_generic_timer_start_failure (fallback_ccb_t *fallback_ccb, - uint32_t event) -{ - -} - -static void -sip_regmgr_generic_message_post_failure (fallback_ccb_t *fallback_ccb, - uint32_t event) -{ - -} - -/** sip_regmgr_get_fallback_ccb_list - * - * PARAMETERS: NULL, or fallback_ccb - * - * DESCRIPTION: Returns the ccb and fallback_ccb from linked list - * The first call to this function should pass in NULL - * Subsequent calls should pass the opaque (for the caller) - * token so that the next ccb is returned - * - * RETURNS: fallback_ccb as the opaque token, ccb as the return value - * - */ -ccsipCCB_t * -sip_regmgr_get_fallback_ccb_list (uint32_t *previous_data_p) -{ - fallback_ccb_t *this_fallback_ccb = NULL; - uint32_t data; - - data = (uint32_t) (*previous_data_p); - this_fallback_ccb = (fallback_ccb_t *) - sll_next(fallback_ccb_list, (void *)(long) (data)); - if (this_fallback_ccb) { - *previous_data_p = (long) (this_fallback_ccb); - return (this_fallback_ccb->ccb); - } - return NULL; -} - -/* - ** sip_regmgr_get_fallback_ccb_by_index - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: line number - * - * DESCRIPTION: Searches the linked list of fallback ccb's and - * returns the ccb that matches the line number. - * - * RETURNS: fallback_ccb if match, NULL if not. - * - */ -fallback_ccb_t * -sip_regmgr_get_fallback_ccb_by_index (line_t ndx) -{ - return (fallback_ccb_t *)(sll_find(fallback_ccb_list, (void *)(long)ndx)); -} - -/* - ** sip_regmgr_find_fallback_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: find_by_p is the dn line number that is the used to - * match with the fallback ccb's. data_p is the ccb that - * from the linked list that is checked to see if it has - * the dn number that is being searched for. - * - * DESCRIPTION: finds the fallback ccb that matched a dn line value - * This is the match routine provided while the singly - * linked list for fallback ccb's is created. sll_find() - * used this routine to perform the find. - * - * RETURNS: Indicates if match was found or not. - * - */ -sll_match_e -sip_regmgr_find_fallback_ccb (void *find_by_p, void *data_p) -{ - int to_find_ccb_index = (long) find_by_p; - fallback_ccb_t *fallback_ccb = (fallback_ccb_t *) data_p; - ccsipCCB_t *list_ccb = (ccsipCCB_t *) fallback_ccb->ccb; - - if (to_find_ccb_index == list_ccb->index) { - return (SLL_MATCH_FOUND); - } else { - return (SLL_MATCH_NOT_FOUND); - } -} - -/* - ** sip_regmgr_find_fallback_ccb_by_callid - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: Callid string and the container for the matching - * ccb, if found. - * - * DESCRIPTION: Searches the linked list of fallback ccb's and - * returns the ccb that matches the callid. - * - * RETURNS: void - * - */ -void -sip_regmgr_find_fallback_ccb_by_callid (const char *callid, - ccsipCCB_t **ccb_ret) -{ - const char fname[] = "sip_regmgr_find_fallback_ccb_by_callid"; - fallback_ccb_t *fallback_ccb = NULL; - ccsipCCB_t *list_ccb = NULL; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Trying to find match for %s\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), callid); - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, - fallback_ccb)) != NULL) { - list_ccb = (ccsipCCB_t *) fallback_ccb->ccb; - if (strcmp(callid, list_ccb->sipCallID) == 0) { - *ccb_ret = list_ccb; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Found ccb to match callid" - " line %d/%d\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - list_ccb->index, - list_ccb->dn_line); - break; - } - } -} - -/* - ** sip_regmgr_find_fallback_ccb_by_addr_port - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ipaddr and port to match and container for the ccb - * if found. - * - * DESCRIPTION: finds the fallback ccb that matched a addr:port value - * - * RETURNS: Indicates if match was found or not. - * - */ -boolean -sip_regmgr_find_fallback_ccb_by_addr_port (cpr_ip_addr_t *ipaddr, uint16_t port, - ccsipCCB_t **ccb_ret) -{ - fallback_ccb_t *fallback_ccb = NULL; - ccsipCCB_t *list_ccb = NULL; - ti_config_table_t *cfg_table_entry; - ti_common_t *ti_common; - boolean found_ccb = FALSE; - - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, - fallback_ccb)) != NULL) { - list_ccb = (ccsipCCB_t *) fallback_ccb->ccb; - cfg_table_entry = (ti_config_table_t *) - list_ccb->cc_cfg_table_entry; - ti_common = &cfg_table_entry->ti_common; - if (util_compare_ip(&(ti_common->addr), ipaddr) && ti_common->port == port) { - *ccb_ret = list_ccb; - found_ccb = TRUE; - break; - } - } - return (found_ccb); -} - -/** - ** sip_regmgr_find_fallback_ccb_by_ccmid - * finds the fallback ccb that matched a ccm id - * - * @param ccm_id ccm id to match and ccb_ret - ccb if found - * - * @return TRUE if found; else FALSE - * - */ -boolean -sip_regmgr_find_fallback_ccb_by_ccmid (CCM_ID ccm_id, ccsipCCB_t **ccb_ret) -{ - fallback_ccb_t *fallback_ccb = NULL; - ccsipCCB_t *list_ccb = NULL; - ti_config_table_t *cfg_table_entry; - boolean found_ccb = FALSE; - - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, - fallback_ccb)) != NULL) { - list_ccb = (ccsipCCB_t *) fallback_ccb->ccb; - if (list_ccb) { - cfg_table_entry = (ti_config_table_t *) - list_ccb->cc_cfg_table_entry; - if (cfg_table_entry && - (cfg_table_entry->ti_specific.ti_ccm.ccm_id == ccm_id)) { - if(ccb_ret != NULL){ - *ccb_ret = list_ccb; - } - found_ccb = TRUE; - break; - } - } - } - return (found_ccb); -} - -/* - ** sip_regmgr_get_fallback_line_num - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void - * - * DESCRIPTION: returns the fallback line number to use during - * failover while creating fallback ccb's - * - * RETURNS: line number to use. - * - */ -line_t -sip_regmgr_get_fallback_line_num () -{ - const char fname[] = "sip_regmgr_get_fallback_line_num"; - int ndx; - line_t line = 0; - - for (ndx = 0; ndx < (MAX_CCM - 1); ndx++) { - if (fallback_lines_available[ndx].available) { - fallback_lines_available[ndx].available = FALSE; - line = fallback_lines_available[ndx].line; - break; - } - } - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Allocated fallback line %d at index %d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), line, (int) (line - MAX_CCBS)); - return (line); -} - -/* - ** sip_regmgr_return_fallback_line_num - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void - * - * DESCRIPTION: returns the fallback line number for reuse during - * failover while creating fallback ccb's - * - * RETURNS: line number to use. - * - */ -void -sip_regmgr_return_fallback_line_num (line_t num) -{ - const char fname[] = "sip_regmgr_return_fallback_line_num"; - - if (((num - MAX_CCBS) > -1) && - ((num - MAX_CCBS) < (MAX_CCM - 1))) { - fallback_lines_available[(int)(num - MAX_CCBS)].available = TRUE; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Returned fallback line %d at index %d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), num, (int) (num - MAX_CCBS)); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Invalid index for fallback_lines_available %d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), (int) (num - MAX_CCBS)); - } -} - -/* - ** sip_regmgr_clean_fallback_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: pointer to the fallback ccb - * - * DESCRIPTION: Clean fallback CCBs - * - * RETURNS: - * - */ -void -sip_regmgr_clean_fallback_ccb (fallback_ccb_t *fallback_ccb) -{ - if (fallback_ccb == NULL) { - return; - } - - if (fallback_ccb->ccb) { - sip_regmgr_return_fallback_line_num(fallback_ccb->ccb->index); - } - (void) cprCancelTimer(fallback_ccb->WaitTimer.timer); - (void) cprDestroyTimer(fallback_ccb->WaitTimer.timer); - fallback_ccb->WaitTimer.timer = NULL; - fallback_ccb->tls_socket_waiting = FALSE; - - (void) cprCancelTimer(fallback_ccb->RetryTimer.timer); - (void) cprDestroyTimer(fallback_ccb->RetryTimer.timer); - fallback_ccb->RetryTimer.timer = NULL; - - if (fallback_ccb->ccb) { - sip_sm_call_cleanup(fallback_ccb->ccb); - cpr_free(fallback_ccb->ccb); - fallback_ccb->ccb = NULL; - } -} - -/* - ** sip_regmgr_free_fallback_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: The fallback ccb to be deleted. - * - * DESCRIPTION: Delete a fallback ccb and its associated timers - * and removes it from the linked list - * - * RETURNS: none - */ -void -sip_regmgr_free_fallback_ccb (ccsipCCB_t *ccb) -{ - const char fname[] = "sip_regmgr_free_fallback_ccb"; - fallback_ccb_t *fallback_ccb; - - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - - if (!fallback_ccb) { - return; - } - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Freed fallback ccb for %s:%d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccb->reg.proxy, ccb->reg.port); - sip_regmgr_clean_fallback_ccb(fallback_ccb); - if (sll_remove(fallback_ccb_list, fallback_ccb) != SLL_RET_SUCCESS) { - CCSIP_DEBUG_ERROR("%s: sll_remove error for fallback_ccb\n", fname); - } - cpr_free(fallback_ccb); -} - -/* - ** sip_regmgr_cleanup_fallback_ccb_list - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: none - * - * DESCRIPTION: Delete fallback ccbs and its associated timers - * and removes it from the linked list - * - * RETURNS: none - */ -void -sip_regmgr_free_fallback_ccb_list () -{ - fallback_ccb_t *fallback_ccb = NULL; - - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, NULL)) - != NULL) { - sip_regmgr_clean_fallback_ccb(fallback_ccb); - (void) sll_remove(fallback_ccb_list, fallback_ccb); - cpr_free(fallback_ccb); - } - sll_destroy(fallback_ccb_list); - fallback_ccb_list = NULL; -} - -/* - ** sip_regmgr_create_fallback_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccm_id, dn_line of the new fallback - * ccb to be created. - * - * DESCRIPTION: Creates a new fallback ccb and its associated timers - * and adds it to the linked list. - * - * RETURNS: Indicates if the fallback ccb was created successfully - * or not. - * - */ -boolean -sip_regmgr_create_fallback_ccb (CCM_ID ccm_id, line_t dn_line) -{ - const char fname[] = "sip_regmgr_create_fallback_ccb"; - ccsipCCB_t *ccb = NULL; - boolean ccb_created = FALSE; - fallback_ccb_t *fallback_ccb; - static const char sipWaitTimerName[] = "sipWait"; - static const char sipRegRetryTimerName[] = "sipRetry"; - line_t fallback_line; - - if (((int)dn_line < 1) || ((int)dn_line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, dn_line); - return(FALSE); - } - - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.\n", - fname, ccm_id); - return(FALSE); - } - /* Check if fallback ccb exists. If so, return */ - if (sip_regmgr_find_fallback_ccb_by_ccmid(ccm_id, NULL)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"fallback ccb exists for ccmid %d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - return(TRUE); - } - fallback_line = sip_regmgr_get_fallback_line_num(); - if (!fallback_line) { - /* Couldn't get fallback line number */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"couldn't get fallback line for ccmid %d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - return(FALSE); - } - fallback_ccb = (fallback_ccb_t *) cpr_calloc(1, sizeof(fallback_ccb_t)); - if (fallback_ccb) { - fallback_ccb->WaitTimer.timer = cprCreateTimer(sipWaitTimerName, - SIP_WAIT_TIMER, - TIMER_EXPIRATION, - sip_msgq); - - fallback_ccb->RetryTimer.timer = cprCreateTimer(sipRegRetryTimerName, - SIP_RETRY_TIMER, - TIMER_EXPIRATION, - sip_msgq); - fallback_ccb->tls_socket_waiting = FALSE; - if (!fallback_ccb->WaitTimer.timer || !fallback_ccb->RetryTimer.timer) { - CCSIP_DEBUG_ERROR("%s: failed to create one or more" - " UISM timers\n", fname); - if (fallback_ccb->WaitTimer.timer) { - (void) cprCancelTimer(fallback_ccb->WaitTimer.timer); - (void) cprDestroyTimer(fallback_ccb->WaitTimer.timer); - fallback_ccb->WaitTimer.timer = NULL; - } - if (fallback_ccb->RetryTimer.timer) { - (void) cprCancelTimer(fallback_ccb->RetryTimer.timer); - (void) cprDestroyTimer(fallback_ccb->RetryTimer.timer); - fallback_ccb->RetryTimer.timer = NULL; - } - ccb_created = FALSE; - } - ccb = (ccsipCCB_t *) cpr_calloc(1, sizeof(ccsipCCB_t)); - if (ccb != NULL) { - (void) sip_sm_ccb_init(ccb, fallback_line, dn_line, - SIP_REG_STATE_IN_FALLBACK); - ccb->cc_type = CC_CCM; - ccb->cc_cfg_table_entry = CCM_Config_Table[dn_line - 1][ccm_id]; - sstrncpy(ccb->reg.proxy, - CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.addr_str, - MAX_IPADDR_STR_LEN); - ccb->reg.addr = CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.addr; - ccb->reg.port = (uint16_t) - CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.port; - ccb->dest_sip_addr = - CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.addr; - ccb->dest_sip_port = - CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.port; - ccb->local_port = CCM_Config_Table[dn_line - 1][ccm_id]->ti_common.listen_port; - fallback_ccb->ccb = ccb; - (void) sll_append(fallback_ccb_list, fallback_ccb); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Created fallback ccb for %s:%d with line %d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccb->reg.proxy, ccb->reg.port, - fallback_line); - ccb_created = TRUE; - } else { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Memalloc failed for ccb for CCM-id %d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - sip_regmgr_clean_fallback_ccb(fallback_ccb); - if (fallback_ccb) { - cpr_free(fallback_ccb); - } - } - } else { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Memalloc failed for fallback ccb for CCM-id %d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - sip_regmgr_return_fallback_line_num(fallback_line); - } - return (ccb_created); -} - -/* - ** sip_regmgr_trigger_fallback_monitor - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:void - * - * DESCRIPTION: Walks through the linked list of fallback ccbs - * and starts the retry timer on them and starts - * sending keepalive messages to monitor the failed - * ccms. - * - * RETURNS: void. - * - */ -void -sip_regmgr_trigger_fallback_monitor (void) -{ - const char fname[] = "sip_regmgr_trigger_fallback_monitor"; - fallback_ccb_t *fallback_ccb = NULL; - ccsipCCB_t *ccb = NULL; - - /* - * Go through the linked list of failed ccm's and - * start monitoring them. - */ - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Looking to trigger fallback " - "if any available\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - do { - fallback_ccb = (fallback_ccb_t *) sll_next(fallback_ccb_list, - (void *)fallback_ccb); - if (fallback_ccb) { - ti_config_table_t *ccm_table_entry; - ccb = fallback_ccb->ccb; - if (ccb->state == (int) SIP_REG_PRE_FALLBACK) { - char user[MAX_LINE_NAME_SIZE]; - - /* - * If state is TokenWait, - * Then transition back into InFallback state. - * Else send out a keepalive message to the registration server. - */ - sip_util_get_new_call_id(ccb); - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, sizeof(user)); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - ccm_table_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_entry->ti_common.handle != INVALID_SOCKET) { - (void) sipSPISendRegister(ccb, 0, user, 0); - } - - /* - * Start the ack, retry timer - */ - sip_regmgr_retry_timer_start(fallback_ccb); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Started monitoring %s:%d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - ccb->reg.proxy, ccb->reg.port); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"fallback is in progress ccb idx=%d", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname),ccb->index); - } - } - } while (fallback_ccb); -} - -void set_active_ccm(ti_config_table_t *cfg_table_entry) { - CCM_Active_Standby_Table.active_ccm_entry = cfg_table_entry; - if (cfg_table_entry != NULL) { - DEF_DEBUG("set_active_ccm: ccm=%s port=%d", - CCM_ID_PRINT(cfg_table_entry->ti_specific.ti_ccm.ccm_id), - phone_local_tcp_port[cfg_table_entry->ti_specific.ti_ccm.ccm_id]); - } else { - DEF_DEBUG("set_active_ccm: ccm=PRIMARY port=-1"); - } -} - - -/* - ** sip_regmgr_setup_new_active_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: pointer to the cfg table entry of the call manager - * that is going to become the new active ccm. - * - * DESCRIPTION: Sets up the reg ccb's for all the lines to point - * to the new call manager during failover/fallback. - * - * RETURNS: void. - * - */ -void -sip_regmgr_setup_new_active_ccb (ti_config_table_t *cfg_table_entry) -{ - const char fname[] = "sip_regmgr_setup_new_active_ccb"; - line_t ndx; - ccsipCCB_t *line_ccb; - - for (ndx = REG_CCB_START; ndx < REG_CCB_END; ndx++) { - line_ccb = sip_sm_get_ccb_by_index(ndx); - ui_set_sip_registration_state(line_ccb->dn_line, FALSE); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling timers, line= %d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), line_ccb->index); - (void) sip_platform_register_expires_timer_stop(line_ccb->index); - sip_stop_ack_timer(line_ccb); - line_ccb->reg.registered = 0; - sip_reg_sm_change_state(line_ccb, SIP_REG_STATE_IDLE); - sip_sm_call_cleanup(line_ccb); - // Since we are going to point this CCB to a new CCM, get a new call-id - line_ccb->sipCallID[0] = '\0'; - sip_util_get_new_call_id(line_ccb); - line_ccb->cc_cfg_table_entry = (void *) cfg_table_entry; - - if (cfg_table_entry == NULL) { - CCSIP_DEBUG_REG_STATE("%s: param cfg_table_entry is NULL!!!\n", fname); - continue; - } - else { - sstrncpy(line_ccb->reg.proxy, cfg_table_entry->ti_common.addr_str, - MAX_IPADDR_STR_LEN); - line_ccb->dest_sip_addr = cfg_table_entry->ti_common.addr; - line_ccb->dest_sip_port = (uint16_t) cfg_table_entry->ti_common.port; - line_ccb->reg.addr = cfg_table_entry->ti_common.addr; - line_ccb->reg.port = (uint16_t) cfg_table_entry->ti_common.port; - /* - * Modify destination fields in call back timer struct - */ - (void) sip_platform_msg_timer_update_destination(line_ccb->index, - &(line_ccb->reg.addr), - line_ccb->reg.port); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Updated active to %s:%d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - line_ccb->reg.proxy, line_ccb->reg.port); - } - } - set_active_ccm(cfg_table_entry); -} - -/* - ** sip_regmgr_setup_new_standby_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: pointer to the cfg table entry of the call manager - * that is going to become the new standby ccm. - * - * DESCRIPTION: Sets up the reg backup ccb for all the lines to point - * to the new call manager during failover/fallback. - * - * RETURNS: void. - * - */ -void -sip_regmgr_setup_new_standby_ccb (CCM_ID ccm_index) -{ - const char fname[] = "sip_regmgr_setup_new_standby_ccb"; - ccsipCCB_t *ccb; - ti_config_table_t *cfg_table_entry; - - - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (((int)ccb->dn_line < 1) || ((int)ccb->dn_line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, ccb->dn_line); - return; - } - if (ccm_index >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.\n", - fname, ccm_index); - return; - } - cfg_table_entry = CCM_Config_Table[ccb->dn_line - 1][ccm_index]; - - ccsip_register_cleanup(ccb, FALSE); - // Since we are going to point this CCB to a new CCM, get a new call-id - ccb->sipCallID[0] = '\0'; - sip_util_get_new_call_id(ccb); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_UNREGISTERING); - ccb->cc_cfg_table_entry = (void *) cfg_table_entry; - sstrncpy(ccb->reg.proxy, cfg_table_entry->ti_common.addr_str, - MAX_IPADDR_STR_LEN); - ccb->reg.addr = cfg_table_entry->ti_common.addr; - ccb->reg.port = (uint16_t) - cfg_table_entry->ti_common.port; - ccb->dest_sip_addr = cfg_table_entry->ti_common.addr; - ccb->dest_sip_port = cfg_table_entry->ti_common.port; - ccb->local_port = cfg_table_entry->ti_common.listen_port; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"For ccb_index=REG_BACKUP_CCB=%d, updated standby to %s:%d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - REG_BACKUP_CCB, ccb->reg.proxy, ccb->reg.port); - CCM_Active_Standby_Table.standby_ccm_entry = cfg_table_entry; -} - -/* - ** sip_regmgr_ccm_get_next - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb pointer - * - * DESCRIPTION: Gets the next ccm in the list for failover. - * - * RETURNS: pointer to the config table of the next ccm in line. - * - */ -ti_config_table_t * -sip_regmgr_ccm_get_next (ccsipCCB_t *ccb, CC_POSITION from_cc) -{ - /* - * If from_cc is ACTIVE_CC, then check to see if the current - * standby is valid. If it is then set that to be the ACTIVE_CC, - * and return that. If there is no current standby, then see if - * we have WAN failure. - * Add the failed units in the fallback ccm list and trigger - * fallback algorithm on them. - */ - const char fname[] = "sip_regmgr_ccm_get_next"; - ti_config_table_t *ccm_table_ptr = NULL, - *ccm_table_active_entry = NULL, - *ccm_table_standby_entry = NULL; - CCM_ID ccm_id, ccm_index; - CC_POSITION from_cc_save = NONE_CC; - - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - - if (!ccm_table_ptr) { - return (NULL); - } - ccm_id = (ccm_table_ptr->ti_specific.ti_ccm.ccm_id); - - /* - * Update the cfg table to invalidate the current ccm that - * has gone down in the case of tcp and create the fallback - * ccb. - * Already taken care of in the ccsip_platform_tcp.c function - * sip_tcp_createconnfailed_to_spi() - */ - if (ccm_table_ptr->ti_common.conn_type != CONN_UDP) { - int connid; - - connid = sip_tcp_fd_to_connid(ccm_table_ptr->ti_common.handle); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"clear the socket and port for " - "current active cucm_id=%d connid=%d\n", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname),ccm_id, connid ); - sip_tcp_purge_entry(connid); - sipTransportSetServerHandleAndPort(INVALID_SOCKET, 0, - ccm_table_ptr); - } - - // Update CCM status - - ui_set_ccm_conn_status(ccm_table_ptr->ti_common.addr_str, CCM_STATUS_NONE); - - - (void) sip_regmgr_create_fallback_ccb(ccm_id, ccb->dn_line); - - if (from_cc == ACTIVE_CC) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Came here from cucm\n", DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname)); - if (CCM_Active_Standby_Table.standby_ccm_entry) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"old ccm_id=%d new_ccm_id=%d Standby=NULL\n", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname), ccm_id, - CCM_Active_Standby_Table.standby_ccm_entry->ti_specific.ti_ccm.ccm_id); - ccm_table_ptr = CCM_Active_Standby_Table.standby_ccm_entry; - ccm_id = (ccm_table_ptr->ti_specific.ti_ccm.ccm_id); - /* - * The current standby is going to be tried for the ACTIVE CC - * role, so fill the standby_ccm_entry with the next valid cc - * info. - */ - set_active_ccm(ccm_table_ptr); - CCM_Active_Standby_Table.standby_ccm_entry = NULL; - /* - * Save the ccm_table_ptr to return the correct value - */ - ccm_table_active_entry = ccm_table_ptr; - /* - * We have used the entry of the current standby for our - * active cc. So go ahead and find the new standby entry - */ - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - - ccm_table_ptr = NULL; - from_cc_save = ACTIVE_CC; - } else { - /* - * There is no Standby available and the Acitve has - * failed. No CC available. Initiate Reboot ! - */ - ccsip_register_set_register_state(SIP_REG_NO_CC); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"NO CC AVAILABLE. NEED TO REBOOT !\n", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname)); - set_active_ccm(NULL); - - return (NULL); - } - } - - for (ccm_index = (CCM_ID) (ccm_id + 1); ccm_index < MAX_CCM; ccm_index++) { - ti_ccm_t *ti_ccm = &CCM_Config_Table[ccb->dn_line - 1][ccm_index]-> - ti_specific.ti_ccm; - - if (ti_ccm->is_valid) { - ccm_table_standby_entry = sip_regmgr_ccm_get_conn(ccb->dn_line, - (ti_config_table_t *) CCM_Config_Table[ccb->dn_line - 1][ccm_index]); - if (ccm_table_standby_entry == NULL) { - /* - * Create a fallback_ccm ccb and put it in a queue to use - * later (POST_FAILOVER) - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Could not set transport" - "connection to this standby. Ignore this. Continue search \n", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname) ); - - (void) sip_regmgr_create_fallback_ccb(ccm_index, ccb->dn_line); - } else { - /* - * Will always be REG_BACKUP_CCB - * Found our 'next' ccm - */ - CCM_Active_Standby_Table.standby_ccm_entry = - ccm_table_standby_entry; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"new standby ccm id %d ip=%s ccm_id=%d\n", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname), ccm_index, - ccm_table_standby_entry->ti_common.addr_str, ti_ccm->ccm_id); - break; - } - } - } - - /* - * We can wait until the active line re-registers to trigger - * this but doing it as soon as we find there is no backup - * available - */ - if (ccm_table_standby_entry == NULL) { - /* - * regmgr - FAILOVER Trigger fallback monitoring - */ - ccsip_register_set_register_state(SIP_REG_NO_STANDBY); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Setting register state to SIP_REG_NO_STANDBY \n", - DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname) ); - - ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - - sip_sm_call_cleanup(ccb); - // No new standby ccm. Cleanup standby ccm address, port and timers - sip_regmgr_clean_standby_ccb(ccb); - } - if (from_cc_save == ACTIVE_CC) { - ccm_table_ptr = ccm_table_active_entry; - } else { - ccm_table_ptr = ccm_table_standby_entry; - } - return (ccm_table_ptr); -} - -/* - ** sip_regmgr_tls_retry_timer_start - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: fallback ccb pointer - * - * DESCRIPTION: Starts the tls retry timer on the fallback ccb - * Normally secd takes 3-6 secs to establish a connection. Start - * timer to check the status after 8s. Restart keep alive timer for the - * remaining time if socket is invalid after 8s - * - * RETURNS: void - * - */ -static void -sip_regmgr_tls_retry_timer_start (fallback_ccb_t *fallback_ccb) -{ - const char fname[] = "sip_regmgr_tls_retry_timer_start"; - ccsipCCB_t *ccb = NULL; - int timeout; - - if (!fallback_ccb) { - return; - } - ccb = fallback_ccb->ccb; - if (fallback_ccb->tls_socket_waiting) { - /* socket invalid after TLS_CONNECT_TIME(8s) - * Restart timer for the remaining time(eg:120-8 s) - */ - timeout = sip_config_get_keepalive_expires(); - - if (timeout > MAX_FALLBACK_MONITOR_PERIOD) { - timeout = MAX_FALLBACK_MONITOR_PERIOD; - } - if (timeout > TLS_CONNECT_TIME) { - timeout -= TLS_CONNECT_TIME; - } - fallback_ccb->tls_socket_waiting = FALSE; - } else { - /* start timer to monitor the socket status */ - timeout = TLS_CONNECT_TIME; - fallback_ccb->tls_socket_waiting = TRUE;; - } - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting TLS timer (%d sec)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), timeout); - if (cprStartTimer(fallback_ccb->RetryTimer.timer, timeout * 1000, - fallback_ccb) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, 0, fname, "cprStartTimer"); - sip_regmgr_generic_timer_start_failure(fallback_ccb, SIP_TMR_REG_RETRY); - } -} - -/* - ** sip_regmgr_retry_timer_start - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: fallback ccb pointer - * - * DESCRIPTION: Starts the retry timer on the fallback ccb - * - * RETURNS: void - * - */ -void -sip_regmgr_retry_timer_start (fallback_ccb_t *fallback_ccb) -{ - const char fname[] = "sip_regmgr_retry_timer_start"; - ccsipCCB_t *ccb = NULL; - int timeout; - - if (!fallback_ccb) { - return; - } - - ccb = fallback_ccb->ccb; - - timeout = sip_config_get_keepalive_expires(); - - if (timeout > MAX_FALLBACK_MONITOR_PERIOD) { - timeout = MAX_FALLBACK_MONITOR_PERIOD; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting fallback timer (%d sec)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), timeout); - - ccb->retx_flag = TRUE; - if (cprStartTimer(fallback_ccb->RetryTimer.timer, timeout * 1000, - fallback_ccb) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, 0, fname, "cprStartTimer"); - sip_regmgr_generic_timer_start_failure(fallback_ccb, SIP_TMR_REG_RETRY); - ccb->retx_flag = FALSE; - } -} - -/* - ** sip_regmgr_retry_timeout_expire - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void *data (fallback ccb) - * - * DESCRIPTION: Is the callback function for retry timer - * - * RETURNS: void - * - */ -void -sip_regmgr_retry_timeout_expire (void *data) -{ - static const char fname[] = "sip_regmgr_retry_timeout_expire"; - fallback_ccb_t *fallback_ccb; - ccsipCCB_t *ccb; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - fallback_ccb = (fallback_ccb_t *) data; - if (!fallback_ccb) { - return; - } - ccb = (ccsipCCB_t *) fallback_ccb->ccb; - if (ccsip_register_send_msg(SIP_TMR_REG_RETRY, ccb->index) != SIP_REG_OK) { - sip_regmgr_generic_message_post_failure(fallback_ccb, - SIP_TMR_REG_RETRY); - } -} - -/* - ** sip_regmgr_set_stability_total_msgs - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: fallback ccb pointer and a boolean indicating if - * it is in a state where we are waiting for the - * phone to get idle before transitioning into token - * wait state. - * - * DESCRIPTION: Starts the stability timer on the fallback ccb - * - * RETURNS: void - * - */ -void -sip_regmgr_set_stability_total_msgs (fallback_ccb_t *fallback_ccb) -{ - const char fname[] = "sip_regmgr_set_stability_total_msgs"; - ccsipCCB_t *ccb = NULL; - int timer_keepalive_expires; - int connection_mode_duration; - - if (!fallback_ccb) { - return; - } - ccb = fallback_ccb->ccb; - - config_get_value(CFGID_CONN_MONITOR_DURATION, - &connection_mode_duration, sizeof(connection_mode_duration)); - - timer_keepalive_expires = sip_config_get_keepalive_expires(); - - /* Stability count is used to wait to make sure that wan is not flapping */ - fallback_ccb->StabilityMsgCount = connection_mode_duration / timer_keepalive_expires; - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting stability msg count as %d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), - fallback_ccb->StabilityMsgCount); -} - -/* - ** sip_regmgr_wait_timer_start - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: fallback ccb pointer - * - * DESCRIPTION: Starts the wait timer on the fallback ccb - * - * RETURNS: void - * - */ -void -sip_regmgr_wait_timer_start (fallback_ccb_t *fallback_ccb) -{ - const char fname[] = "sip_regmgr_wait_timer_start"; - ccsipCCB_t *ccb = NULL; - int timeout; - - if (!fallback_ccb) { - return; - } - ccb = fallback_ccb->ccb; - - timeout = sip_config_get_keepalive_expires(); - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Starting wait timer (%d sec)\n", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), timeout); - - if (cprStartTimer(fallback_ccb->WaitTimer.timer, timeout * 1000, - fallback_ccb) == CPR_FAILURE) { - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, 0, fname, "cprStartTimer"); - sip_regmgr_generic_timer_start_failure(fallback_ccb, SIP_TMR_REG_WAIT); - } -} - -/* - ** sip_regmgr_wait_timeout_expire - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void *data (fallback ccb) - * - * DESCRIPTION: Is the callback function for wait timer - * - * RETURNS: void - * - */ -void -sip_regmgr_wait_timeout_expire (void *data) -{ - static const char fname[] = "sip_regmgr_wait_timeout_expire"; - fallback_ccb_t *fallback_ccb; - ccsipCCB_t *ccb; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - fallback_ccb = (fallback_ccb_t *) data; - ccb = (ccsipCCB_t *) fallback_ccb->ccb; - - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->WaitTimer.timer); - - if (ccsip_register_send_msg(SIP_TMR_REG_WAIT, ccb->index) != SIP_REG_OK) { - sip_regmgr_generic_message_post_failure(fallback_ccb, SIP_TMR_REG_WAIT); - } -} - -void -sip_regmgr_fallback_generic_timer_stop (cprTimer_t timer) -{ - static const char fname[] = "sip_regmgr_fallback_generic_timer_stop"; - - if (cprCancelTimer(timer) == CPR_FAILURE) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"%s failed!\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), "cprCancelTimer"); - } - - return; -} - - -/* - ** sip_regmgr_ev_fallback_retry - * - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: Event handler for 4xx, 5xx, 6xx responses in fallback state - * Start retry timer to monitor the fallback ccm - * Wait for the timer to pop to send the next keepalive. - * - * - * RETURNS: void - * - */ -void -sip_regmgr_ev_fallback_retry (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_fallback_retry"; - fallback_ccb_t *fallback_ccb = NULL; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Recd retry event for LINE %d/%d in state %d\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccb->index, ccb->dn_line, ccb->state); - - sip_stop_ack_timer(ccb); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } - free_sip_message(event->u.pSipMessage); -} - -void -sip_regmgr_ev_default (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_default"; - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a default event in state %d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname), ccb->state); - - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - sip_regmgr_ev_tmr_ack_retry(ccb, event); - /* only free SIP messages, timeouts are internal */ - if (event->type < (int) E_SIP_REG_TMR_ACK) { - free_sip_message(event->u.pSipMessage); - } -} - -/* - ** sip_regmgr_ev_tmr_ack_retry - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: Event handler for ack and retry timers. Please - * see inline comments for the description. - * - * RETURNS: void - * - */ -void -sip_regmgr_ev_tmr_ack_retry (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_tmr_ack_retry"; - ti_config_table_t *ccm_table_ptr; - fallback_ccb_t *fallback_ccb; - CCM_ID current_standby_ccm_id, fallback_ccm_id; - - /* - * If state is REGISTERING, set state to IN_FAILOVER. - * Mark all lines as unregistered and IDLE state. - * Create fallback ccb for the failed ccm and put it in - * a queue to be triggered post failover. - * Find the "next" ccm and set the values in the ccb. - * Need change state to IDLE and post REG_REQ, make sure - * we set the no_dns_lookup parameter to 1. - * If state is IN_FALLBACK, send register message - * If state is STABILITY_CHECK, transition back to IN_FALLBACK - * and send register with expire 0. - * If state is TOKEN_WAIT, transition back to IN_FALLBACK - * and send register with expire 0. - */ - ccb->retx_counter = 0; - switch ((sipRegSMStateType_t) ccb->state) { - case SIP_REG_STATE_REGISTERED: - /* - * A send failure on a tcp for active cc could have caused - * this message. - * Fall through and do the same as what is done when in - * REGISTERING State. - */ - case SIP_REG_STATE_REGISTERING: - /* - * Get the next ccm to use as active. - */ - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr != CCM_Active_Standby_Table.active_ccm_entry) { - break; - } - ccm_table_ptr = NULL; - - ccm_table_ptr = sip_regmgr_ccm_get_next(ccb, ACTIVE_CC); - - if (ccm_table_ptr == NULL) { - /* - * Send indication of REG_ALLFAIL so platform can - * initiate a reboot. - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Unable to get next ccm!\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - // Cleanup fallback CCB list - sip_regmgr_free_fallback_ccb_list(); - sip_reg_all_failed = TRUE; - sip_regmgr_handle_reg_all_fail(); - break; - } - - CCSIP_DEBUG_REG_STATE("%s: ccb information: ccb->dn_line=%d, ccb->index=%d, retry_times=%d\n", - fname, ccb->dn_line, ccb->index, retry_times); - - CCM_Failover_Table.failover_ccm_entry = ccm_table_ptr; - CCM_Failover_Table.failover_started = TRUE; - CCM_Failover_Table.prime_registered = FALSE; - CCM_Fallback_Table.fallback_ccm_entry = NULL; - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - sip_platform_msg_timer_stop(ccb->index); - sip_platform_failover_ind(ccm_table_ptr->ti_specific.ti_ccm.ccm_id); - - /* - * Notes for case: (CSCsx60672) - * We should change the info in REG_BACKUP_CCB for the case that: - * Active CCB failover - * previous standby CCM is set as CCM_Active_Standby_Table.active_ccm_entry (#1 IPAddr A) - * Third CCM would be set as CCM_Active_Standby_Table.standby_ccm_entry (#2 IPAddr B) - * - * if (#2) failover before Jphone callback, - * The REG_BACKUP_CCB would still store the #1's info - * So the call flows would prompt the wrong info(#1 IPAddr A) to Jphone, in this case, (#2 IPAddr B) - * should be prompted - * - * We need to update the REG_BACKUP_CCB's info here - */ - if (CCM_Active_Standby_Table.standby_ccm_entry) - { - ti_ccm_t *ti_ccm = &(CCM_Active_Standby_Table.standby_ccm_entry->ti_specific.ti_ccm); - sip_regmgr_setup_new_standby_ccb(ti_ccm->ccm_id); - CCSIP_DEBUG_REG_STATE("%s: Setup new standby ccb, ccm_id is %d\n", fname, ti_ccm->ccm_id); - } - - break; - case SIP_REG_STATE_UNREGISTERING: - - if (ccb->index == REG_BACKUP_CCB) { - sip_stop_ack_timer(ccb); - sip_platform_msg_timer_stop(ccb->index); - ccm_table_ptr = sip_regmgr_ccm_get_next(ccb, STANDBY_CC); - if (ccm_table_ptr) { - /* - * New standby, start monitoring it. - * Change the ip addr and port to point to the new ccm - * Set the CC_CONFIG_TABLE entry for all the lines to - * point to the new ccm. - * Set the ccb->cc_cfg_table_entry with the new entry. - */ - ti_ccm_t *ti_ccm; - - ti_ccm = &ccm_table_ptr->ti_specific.ti_ccm; - sip_regmgr_setup_new_standby_ccb(ti_ccm->ccm_id); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Start monitoring new standby cc\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index); - - ui_set_ccm_conn_status(ccm_table_ptr->ti_common.addr_str, - CCM_STATUS_STANDBY); - - } else { - CCM_Active_Standby_Table.standby_ccm_entry = NULL; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Unable to get next standby ccm !\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - } - sip_regmgr_trigger_fallback_monitor(); - } else { - /* - * Received a timeout when the active tried to unregister - * after the expires timer. - */ - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - if (ccsip_register_all_unregistered() == TRUE) { - ccsip_register_set_register_state(SIP_REG_IDLE); - } - - /* - * Always check how sip_sm_call_cleanup is implemented. - * The function has a tendency to change. - */ - sip_sm_call_cleanup(ccb); - } - - break; - case SIP_REG_STATE_STABILITY_CHECK: - /* - * We getting here means that the wan link could have gone - * down again. We stop the timers associated with the - * carefree algorithm and transition back to the - * IN_FALLBACK state. - */ - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->WaitTimer.timer); - } - /* - * FALL THROUGH ALERT to the next state. - */ - /*sa_ignore FALL_THROUGH*/ - case SIP_REG_STATE_TOKEN_WAIT: - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - /* - * FALL THROUGH ALERT ! get into the next case and - * start sending of keepalives to the newly failed - * ccm. - */ - /*sa_ignore FALL_THROUGH*/ - case SIP_REG_STATE_IN_FALLBACK: - /* - * Send Register msg with expiry set to zero (poll) - */ - { - char user[MAX_LINE_NAME_SIZE]; - fallback_ccb_t *fallback_ccb2; - ti_config_table_t *ccm_table_entry; - - fallback_ccb2 = (fallback_ccb_t *) sll_find(fallback_ccb_list, - (void *)(long)ccb->index); - ccm_table_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - /* - * Check here to see if we still need this fallback ccb - * to be polling its ccm. The reason is that one of the - * ccms that has a higher precedence to this ccm could have - * come back online, in which case we can stop monitoring - * this ccm. - */ - if (CCM_Active_Standby_Table.standby_ccm_entry) { - current_standby_ccm_id = CCM_Active_Standby_Table. - standby_ccm_entry->ti_specific.ti_ccm.ccm_id; - fallback_ccm_id = ccm_table_entry->ti_specific.ti_ccm.ccm_id; - - if (current_standby_ccm_id < fallback_ccm_id) { - /* - * Clean the current fallback ccb and free it - */ - DEF_DEBUG(DEB_F_PREFIX"Freeing the fallback ccb for %d ccm as current standby" - " is %d ccm!\n", - DEB_F_PREFIX_ARGS(SIP_REG_FREE_FALLBACK, fname), - fallback_ccm_id, current_standby_ccm_id); - sip_regmgr_free_fallback_ccb(ccb); - break; - } - } - - /* - * For the TCP case where a connection has gone down, - * We need to first try and setup the connection as - * part of the recovery process. After that is when we - * can start sending the keepalive messages. The following - * 'if' block handles that case. The socket handle of the - * config table is inited to INVALID_SOCKET when the connection - * goes down. - */ - if ((ccb->cc_type == CC_CCM) - && (ccm_table_entry->ti_common.handle == INVALID_SOCKET)) { - ti_common_t *ti_common; - sipSPIMessage_t sip_msg; - uint16_t listener_port; - ti_ccm_t *ti_ccm; - CONN_TYPE conn_type = CONN_NONE; - cpr_socket_t server_conn_handle = INVALID_SOCKET; - - ti_common = &ccm_table_entry->ti_common; - sip_msg.createConnMsg.addr = ti_common->addr; - sip_msg.createConnMsg.port = ti_common->port; - sip_msg.context = NULL; - ti_ccm = &ccm_table_entry->ti_specific.ti_ccm; - - if (((ti_ccm->sec_level == AUTHENTICATED) || - (ti_ccm->sec_level == ENCRYPTED)) && - (ti_common->conn_type == CONN_TLS)) { - sip_msg.context = NULL; - if (fallback_ccb2 && (fallback_ccb2->tls_socket_waiting)) { - /* socket invalid after TLS_CONN_TIME - * Restart timer for the remaining time - */ - sip_regmgr_tls_retry_timer_start(fallback_ccb2); - break; - } - server_conn_handle = sip_tls_create_connection(&sip_msg, - FALSE, - ti_ccm->sec_level); - conn_type = CONN_TLS; - } else { - server_conn_handle = sip_tcp_create_connection(&sip_msg); - } - phone_local_tcp_port[ccm_table_entry->ti_specific.ti_ccm.ccm_id] = - sip_msg.createConnMsg.local_listener_port; - if (server_conn_handle != INVALID_SOCKET) { - listener_port = sip_msg.createConnMsg.local_listener_port; - sipTransportSetServerHandleAndPort(server_conn_handle, - listener_port, - ccm_table_entry); - ccb->local_port = listener_port; - if ((conn_type == CONN_TLS) && fallback_ccb2) { - /* start timer to monitor the tls connect status */ - sip_regmgr_tls_retry_timer_start(fallback_ccb2); - break; - } - } else { - CCSIP_DEBUG_ERROR("%s: Error: " - "sip_platform_tcp_channel_create(" - "server addr=%s, server port=%d) " - "failed.\n", fname, ti_common->addr_str, - ti_common->port); - if (fallback_ccb2) { - sip_regmgr_retry_timer_start(fallback_ccb2); - } - break; - } - } - /* - * Send a keepalive message and hope to get a reply back - */ - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - sip_util_get_new_call_id(ccb); - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, sizeof(user)); - /* - * Start the retry timer - */ - (void) sipSPISendRegister(ccb, 0, user, 0); - if (fallback_ccb2) { - sip_regmgr_retry_timer_start(fallback_ccb2); - } - break; - } - default: - break; - } -} - -/* - ** sip_regmgr_ev_in_fallback_2xx - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Event handler for the all responses - * - * RETURNS: - * - */ -void -sip_regmgr_ev_in_fallback_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_in_fallback_2xx"; - sipMessage_t *response = event->u.pSipMessage; - int status_code = 0; - fallback_ccb_t *fallback_ccb; - - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), ccb->index, - ccb->dn_line, fname); - free_sip_message(response); - return; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a %d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), status_code); - - sip_stop_ack_timer(ccb); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->RetryTimer.timer); - } - sip_regmgr_check_and_transition(ccb); - free_sip_message(response); -} - -/* - ** sip_regmgr_ev_stability_check_2xx - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Event handler for the all responses - * - * RETURNS: - * - */ -void -sip_regmgr_ev_stability_check_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_stability_check_2xx"; - fallback_ccb_t *fallback_ccb; - sipMessage_t *response = event->u.pSipMessage; - int status_code = 0; - - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), ccb->index, - ccb->dn_line, fname); - free_sip_message(response); - return; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a %d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_FALLBACK, ccb->index, ccb->dn_line, fname), status_code); - - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (!fallback_ccb) { - free_sip_message(response); - return; - } - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->RetryTimer.timer); - /* - * Update stats here ? - */ - if (fallback_ccb->StabilityMsgCount > 0) { - fallback_ccb->StabilityMsgCount--; - } - if (fallback_ccb->StabilityMsgCount) { - sip_regmgr_wait_timer_start(fallback_ccb); - } else { - wan_failure = FALSE; - sip_regmgr_check_and_transition(ccb); - } - free_sip_message(response); -} - -/* - ** sip_regmgr_ev_stability_check_tmr_wait - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_ev_stability_check_tmr_wait (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_stability_check_tmr_wait"; - fallback_ccb_t *fallback_ccb; - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } -} - -/* - ** sip_regmgr_ev_token_wait_2xx - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: TOKEN_WAIT state, set expire timer and transition - * to IDLE state. - * - * RETURNS: none - */ -void -sip_regmgr_ev_token_wait_2xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "sip_regmgr_ev_token_wait_2xx"; - fallback_ccb_t *fallback_ccb; - sipMessage_t *response; - int status_code = 0; - CCM_ID fallback_ccm_id; - ti_config_table_t *fallback_ccb_entry; - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), ccb->index, - ccb->dn_line, fname); - free_sip_message(response); - return; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a %d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname), status_code); - - sip_stop_ack_timer(ccb); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->WaitTimer.timer); - - } - fallback_ccb_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - fallback_ccm_id = fallback_ccb_entry->ti_specific.ti_ccm.ccm_id; - - if (CCM_Fallback_Table.fallback_ccm_entry == NULL) { - CCM_Fallback_Table.fallback_ccm_entry = (ti_config_table_t *) - ccb->cc_cfg_table_entry; - CCM_Fallback_Table.is_idle = FALSE; - CCM_Fallback_Table.is_resp = FALSE; - CCM_Fallback_Table.ccb = ccb; - sip_platform_fallback_ind(fallback_ccm_id); - - } else { - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } - } - - free_sip_message(response); -} - -/* - ** sip_regmgr_ev_cleanup - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: cleanup primary - * - * RETURNS: none - */ -void -sip_regmgr_ev_cleanup (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "sip_regmgr_ev_cleanup"; - CCM_ID ccm_id; - ti_config_table_t *cfg_table_entry; - ccsipCCB_t *line_ccb = NULL; - ti_common_t *ti_common; - - CCSIP_DEBUG_REG_STATE("%s:\n", fname); - line_ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - if (ccb == NULL || line_ccb == NULL) { - CCSIP_DEBUG_REG_STATE("%s: invalid ccb or line_ccb\n", fname); - return; - } - - cfg_table_entry = (ti_config_table_t *) line_ccb->cc_cfg_table_entry; - /* - * Setup the new active cc - */ - sip_regmgr_setup_new_active_ccb((ti_config_table_t *) - ccb->cc_cfg_table_entry); - sip_regmgr_free_fallback_ccb(ccb); - /* - * Initiate registering with the new active cc - */ - if (CCM_Fallback_Table.is_resp) { - CCSIP_DEBUG_REG_STATE("%s: Register all lines\n", fname); - ccsip_register_all_lines(); - CCM_Fallback_Table.fallback_ccm_entry = NULL; - } else { - CCSIP_DEBUG_REG_STATE("%s: Register prime line\n", fname); - sip_regmgr_register_lines(TRUE, FALSE); - CCM_Failover_Table.prime_registered = TRUE; - } - //set status of current standby to NONE - if (CCM_Active_Standby_Table.standby_ccm_entry) { - ti_config_table_t *standby_table_entry; - - standby_table_entry = CCM_Active_Standby_Table.standby_ccm_entry; - - ui_set_ccm_conn_status(standby_table_entry->ti_common.addr_str, - CCM_STATUS_NONE); - - } - /* - * Setup the new standby. - * CCM will close the TCP connection after unregistering from the - * current active ccm if connection type is TCP/TLS - * Close the TCP connection if one exists and open a new one - */ - if (cfg_table_entry != NULL) { - ti_common = &cfg_table_entry->ti_common; - if (ti_common->conn_type != CONN_UDP) { - if (ti_common->handle != INVALID_SOCKET) { - int connid; - - CCSIP_DEBUG_REG_STATE("%s: Close the TCP connection\n", fname); - connid = sip_tcp_fd_to_connid(ti_common->handle); - sip_tcp_purge_entry(connid); - ti_common->handle = INVALID_SOCKET; - } - CCSIP_DEBUG_REG_STATE("%s: Open a new connection\n", fname); - (void) sip_regmgr_ccm_get_conn(line_ccb->dn_line, cfg_table_entry); - } - ccm_id = cfg_table_entry->ti_specific.ti_ccm.ccm_id; - sip_regmgr_setup_new_standby_ccb(ccm_id); - } - /* - * Trigger monitoring the new standby - */ - (void) ccsip_register_send_msg(SIP_REG_CANCEL, REG_BACKUP_CCB); - - sip_platform_set_ccm_status(); -} - -/* - ** sip_regmgr_ev_token_wait_4xx_n_5xx - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: ccb and event - * - * DESCRIPTION: TOKEN_WAIT state, set expire timer and transition - * to IDLE state. - * - * RETURNS: none - */ -void -sip_regmgr_ev_token_wait_4xx_n_5xx (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "sip_regmgr_ev_token_wait_4xx_n_5xx"; - fallback_ccb_t *fallback_ccb; - sipMessage_t *response; - int status_code = 0; - uint32_t retry_after = 0; - const char *msg_ptr = NULL; - int timeout = 0; - - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - response = event->u.pSipMessage; - clean_method_request_trx(ccb, sipMethodRegister, TRUE); - - if (sipGetResponseCode(response, &status_code) < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_REG_SIP_RESP_CODE), ccb->index, - ccb->dn_line, fname); - free_sip_message(response); - return; - } - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received a %d\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname), status_code); - - sip_stop_ack_timer(ccb); - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (!fallback_ccb) { - return; - } - sip_regmgr_fallback_generic_timer_stop(fallback_ccb->WaitTimer.timer); - // Look for retry-after tag - if (status_code == SIP_CLI_ERR_BUSY_HERE || - status_code == SIP_SERV_ERR_UNAVAIL) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Received a 486/503 response!\n", - DEB_F_PREFIX_ARGS(SIP_RESP, fname)); - msg_ptr = sippmh_get_header_val(response, - (const char *)SIP_HEADER_RETRY_AFTER, - NULL); - if (msg_ptr) { - retry_after = strtoul(msg_ptr, NULL, 10); - } - /* - * Start timer with the retry-after value - */ - if (retry_after > 0) { - timeout = retry_after; - } else { - // use keep alive timer if retry_after in 486 is missing or 0 - timeout = sip_config_get_keepalive_expires(); - } - if (cprStartTimer(fallback_ccb->WaitTimer.timer, timeout * 1000, - fallback_ccb) == CPR_FAILURE) { - CCSIP_DEBUG_REG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb->index, 0, fname, "cprStartTimer"); - sip_regmgr_generic_timer_start_failure(fallback_ccb, - SIP_TMR_REG_WAIT); - } - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Started timer with retry-after for %d secs\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), timeout); - } else { - /* - * Unhandled 4xx message. start monitoring fallback ccb - */ - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - sip_regmgr_retry_timer_start(fallback_ccb); - } -} - -void -sip_regmgr_ev_token_wait_tmr_wait (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - static const char fname[] = "sip_regmgr_ev_token_wait_tmr_wait"; - fallback_ccb_t *fallback_ccb; - - /* - * Send a REFER message requesting for registering with - * the callmanager that has come back up. Cleanup any - * pending REFER transaction as new REFER is created for - * next transmission. - */ - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - if (sipSPISendRefer(ccb, TOKEN_REFER_TO, SIP_REF_TOKEN)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Successfully sent a REFER" - " for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - } else { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Error while trying to send" - " REFER for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - } - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } -} - -/* - ** sip_regmgr_check_and_transition - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Check and transition states - * - * RETURNS: void - * - */ -void -sip_regmgr_check_and_transition (ccsipCCB_t *ccb) -{ - static const char fname[] = "sip_regmgr_check_and_transition"; - - /* - * This routine gets called from IN_FALLBACK state when we - * receive a response to a keepalive message -or- from the - * STABILITY Check state when the Carefree algorithm successfully - * completes. - * If state is IN_FALLBACK and wan_failure is TRUE, transition - * to STABILITY_CHECK state and start the CAREFREE Algorithm. - * Else transition to the TOKEN_WAIT State.and send the refer - * message requesting for a token to register. - */ - if (!ccb) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Received event for invalid ccb\n", DEB_F_PREFIX_ARGS(SIP_EVT, fname)); - return; - } - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - if (wan_failure) { - /* - * Kick off the Carefree algorithm. Transition to STABILITY CHECK - * state - */ - sip_reg_sm_change_state(ccb, SIP_REG_STATE_STABILITY_CHECK); - sip_regmgr_set_stability_total_msgs( - sip_regmgr_get_fallback_ccb_by_index(ccb->index)); - sip_regmgr_wait_timer_start( - sip_regmgr_get_fallback_ccb_by_index(ccb->index)); - } else { - /* - * Check to see if the ccm coming backup is going to - * replace the current active, if not just replace the - * current Standby - */ - ti_config_table_t *ccm_table_entry, *fallback_ccb_entry; - CCM_ID current_ccm_id, fallback_ccm_id; - fallback_ccb_t *fallback_ccb; - - fallback_ccb = sip_regmgr_get_fallback_ccb_by_index(ccb->index); - ccm_table_entry = CCM_Active_Standby_Table.active_ccm_entry; - current_ccm_id = ccm_table_entry->ti_specific.ti_ccm.ccm_id; - - fallback_ccb_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - fallback_ccm_id = fallback_ccb_entry->ti_specific.ti_ccm.ccm_id; - /* - * Check to see if the current ccm coming back up is going to - * replace the current active ccm - */ - if (current_ccm_id > fallback_ccm_id) { - if ((sip_platform_is_phone_idle()) && - (CCM_Fallback_Table.fallback_ccm_entry == NULL)) { - /* - * Send a REFER message requesting for registering with - * the callmanager that has come back up. Cleanup any - * existing REFER transactions before creating a new - * REFER - */ - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - if (sipSPISendRefer(ccb, TOKEN_REFER_TO, SIP_REF_TOKEN)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Successfully sent a REFER" - " for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_TOKEN_WAIT); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } - } else { - CCSIP_DEBUG_ERROR(DEB_F_PREFIX"Error while trying to send" - " REFER for token registration!\n", - DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - } - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"phone not idle or fallback ccm entry non NULL \n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - // Send keep alive if phone not idle - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IN_FALLBACK); - if (fallback_ccb) { - sip_regmgr_retry_timer_start(fallback_ccb); - } - return; - } - } else if (current_ccm_id == fallback_ccm_id) { - CCSIP_DEBUG_REG_STATE("%s: Current ccm coming back up is the current active ccm\n", fname); - // Do nothing - } else { - /* - * Falling back as the standby. - * Any CCM coming back up will either replace the - * active or standby ccm. In this case it is not the - * active, so replace the standby ccm. - */ - ccsipCCB_t *backup_ccb; - ti_config_table_t *ccm_table_entry2; - ti_ccm_t *ti_ccm; - CCM_ID ccm_id; - - ccm_table_entry2 = (ti_config_table_t *) - ccb->cc_cfg_table_entry; - ti_ccm = &ccm_table_entry2->ti_specific.ti_ccm; - ccm_id = ti_ccm->ccm_id; - - backup_ccb = sip_sm_get_ccb_by_index(REG_BACKUP_CCB); - if (CCM_Active_Standby_Table.standby_ccm_entry) { - int16_t trx_index; - ti_config_table_t *standby_ccm_entry = NULL; - CCM_ID standby_ccmid; - - standby_ccm_entry = CCM_Active_Standby_Table.standby_ccm_entry; - standby_ccmid = standby_ccm_entry->ti_specific.ti_ccm.ccm_id; - - // Check to see if the ccm coming back up is going to - // replace the current standby ccm. - if (standby_ccmid < ccm_id) { - /* - * Clean the current fallback ccb and free it - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Freeing the fallback ccb" - " for %d ccm as current standby" - " is %d ccm!\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), - ccm_id, standby_ccmid); - sip_regmgr_free_fallback_ccb(ccb); - return; - } - /* - * Check to see if there is a transaction pending. - * If so wait for the final response, else proceed. - */ - trx_index = get_method_request_trx_index(backup_ccb, - sipMethodRegister, - TRUE); - if (trx_index >= 0) { - if (new_standby_available == NULL) { - new_standby_available = (void *) ccm_table_entry2; - } else { - /* - * There is already a ccm waiting to - * transition into being the standby ccm. - * Check current ccm id with the one - * waiting to see who is a better fit. - */ - ti_config_table_t *waiting_standby; - CCM_ID this_ccm_id, waiting_ccm_id; - - waiting_standby = (ti_config_table_t *) - new_standby_available; - waiting_ccm_id = waiting_standby-> - ti_specific.ti_ccm.ccm_id; - this_ccm_id = ccm_table_entry2-> - ti_specific.ti_ccm.ccm_id; - if (waiting_ccm_id > this_ccm_id) { - new_standby_available = (void *) - ccm_table_entry2; - } - } - } else { - - ti_config_table_t *standby_ccm_entry2; - - standby_ccm_entry2 = (ti_config_table_t *) - backup_ccb->cc_cfg_table_entry; - // Update CCM Status - ui_set_ccm_conn_status(standby_ccm_entry2->ti_common.addr_str, - CCM_STATUS_NONE); - if (standby_ccm_entry2->ti_common.conn_type == CONN_TCP) { - /* - * Clean up the socket of the current standby - * if tcp. - */ - int connid; - - connid = sip_tcp_fd_to_connid(standby_ccm_entry2-> - ti_common.handle); - sip_tcp_purge_entry(connid); - sipTransportSetServerHandleAndPort(INVALID_SOCKET, 0, - (ti_config_table_t *)(backup_ccb->cc_cfg_table_entry)); - } - ui_set_ccm_conn_status(ccm_table_entry2->ti_common.addr_str, - CCM_STATUS_STANDBY); - - sip_regmgr_setup_new_standby_ccb(ccm_id); - sip_regmgr_free_fallback_ccb(ccb); - /* - * New standby, start monitoring it. - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Start monitoring new" - " standby cc \n", DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, - backup_ccb->index); - } - } else { - /* - * Here there is no current standby, so simply - * make the current ccm the standby ccm and start - * monitoring it. - */ - - ui_set_ccm_conn_status(ccm_table_entry2->ti_common.addr_str, - CCM_STATUS_STANDBY); - - sip_regmgr_setup_new_standby_ccb(ccm_id); - sip_regmgr_free_fallback_ccb(ccb); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Start monitoring new" - " standby cc \n", DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, - backup_ccb->index); - } - } - } -} - -/* - ** sip_regmgr_ev_failure_response - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_ev_failure_response (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_failure_response"; - int timeout; - - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - if (ccb->index == REG_BACKUP_CCB) { - /* - * Keep monitoring. - * Stay in unregistering state and wait for the - * expires timer to pop to send the next keepalive. - */ - - timeout = sip_config_get_keepalive_expires(); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Starting keep alive timer %d sec\n", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), timeout); - (void) sip_platform_standby_keepalive_timer_start(timeout * 1000); - - } else { - // Do not Initiate failover; Need not wait for the the ack_timer - if (sip_regmgr_get_cc_mode(1) == REG_MODE_CCM) { - config_update_required = TRUE; - } - - /* - * Send indication of REG_ALLFAIL so platform can - * initiate a reboot. - */ - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Registration rejected.\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - // Cleanup fallback CCB list - sip_regmgr_free_fallback_ccb_list(); - sip_reg_all_failed = TRUE; - sip_regmgr_handle_reg_all_fail(); - - } -} - -/* - ** sip_regmgr_ev_cancel - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_ev_cancel (ccsipCCB_t *ccb, sipSMEvent_t *event) -{ - const char *fname = "sip_regmgr_ev_cancel"; - char user[MAX_LINE_NAME_SIZE]; - - /* - * If state is TokenWait, - * Then transition back into InFallback state. - * Else send out a keepalive message to the registration server. - * Note: Need to rename the event ??? - */ - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"Received event\n", - DEB_L_C_F_PREFIX_ARGS(SIP_EVT, ccb->index, ccb->dn_line, fname)); - sip_util_get_new_call_id(ccb); - ccb->authen.cred_type = 0; - ccb->retx_counter = 0; - ccb->reg.tmr_expire = 0; - ccb->reg.act_time = 0; - config_get_line_string(CFGID_LINE_NAME, user, ccb->dn_line, sizeof(user)); - - (void) sipSPISendRegister(ccb, 0, user, 0); -} - -/* - ** sip_regmgr_ccm_get_conn - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -ti_config_table_t * -sip_regmgr_ccm_get_conn (line_t dn, ti_config_table_t *ccm_entry) -{ - /* - * Just check for the validity of the cpr_socket - * and return the entry. - */ - if (ccm_entry->ti_common.handle != INVALID_SOCKET) { - return (ccm_entry); - } else { - /* - * Create a socket to the ccm - */ - conn_create_status_t conn_status; - - conn_status = sip_transport_setup_cc_conn(dn, ccm_entry-> - ti_specific.ti_ccm.ccm_id); - if (conn_status == CONN_SUCCESS) { - return (ccm_entry); - } else { - return (NULL); - } - } -} - -/* - ** sip_regmgr_setup_cc_conns - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: void - * - * DESCRIPTION: Replaces SIPTaskConnectToSipProxies - * - * RETURNS: - * - */ -static int -sip_regmgr_setup_cc_conns () -{ - const char *fname = "sip_regmgr_setup_cc_conns"; - RET_CODE ret_code = RET_SUCCESS; - CCM_ID cc_index; - cpr_socket_t active_fd = INVALID_SOCKET, - standby_fd = INVALID_SOCKET; - line_t line; - conn_create_status_t conn_status; - - /* - * We assume only one type of call control in the phone - * either ccm / csps. That is the reason for only one check - * When we support both ccm and csps on the same phone (on - * multiple lines we will need to check each line's cc_type - * and take the appropriate action. - */ - if (CC_Config_Table[0].cc_type == CC_CCM) { - /* - * Find the active and standby connections for - * ccm. - */ - for (cc_index = PRIMARY_CCM; cc_index < MAX_CCM; cc_index++) { - line = 1; - - /* - * Note: The opening of sockets will fail only in the - * case of tcp/tls connections. In the case of udp, - * the socket will get opened and the failure to reach - * the destination will come in the form of timeouts/ - * icmp unreachable messages. - */ - conn_status = sip_transport_setup_cc_conn(line, cc_index); - if (conn_status == CONN_SUCCESS) { - if (active_fd == INVALID_SOCKET) { - /* - * Found Active fd and active_fd is not set - * Save it for all lines. - */ - active_fd = CCM_Config_Table[line - 1][cc_index]->ti_common.handle; - set_active_ccm(CCM_Config_Table[line - 1][cc_index]); - } else { - /* - * Found Standby fd. Save it in the local table. - * and break out of loop. - */ - standby_fd = CCM_Config_Table[line - 1] - [cc_index]->ti_common.handle; - CCM_Active_Standby_Table.standby_ccm_entry = - CCM_Config_Table[line - 1][cc_index]; - break; - } - } else if (conn_status == CONN_FAILURE) { - /* - * We can get this return code when connecting to - * a server that uses UDP such as Asterisk. If that is the - * case we then change the connection type to UDP and - * attempt reconnection. - * - */ - - // change trans layer protocol to UDP - CC_Config_setIntValue(CFGID_TRANSPORT_LAYER_PROT, 2); - CCSIP_DEBUG_ERROR("%s: Attempting reconnection using UDP\n", fname); - - // attempt re-connection - sipTransportInit(); - - conn_status = sip_transport_setup_cc_conn(line, cc_index); - if (conn_status == CONN_SUCCESS) { - if (active_fd == INVALID_SOCKET) { - /* - * Found Active fd and active_fd is not set - * Save it for all lines. - */ - active_fd = CCM_Config_Table[line - 1][cc_index]->ti_common.handle; - set_active_ccm(CCM_Config_Table[line - 1][cc_index]); - } else { - /* - * Found Standby fd. Save it in the local table. - * and break out of loop. - */ - standby_fd = CCM_Config_Table[line - 1] - [cc_index]->ti_common.handle; - CCM_Active_Standby_Table.standby_ccm_entry = - CCM_Config_Table[line - 1][cc_index]; - break; - } - } else if (conn_status == CONN_FAILURE) { - - /* - * We get this return code when we have the address - * configured and we are not able to setup the - * connection to the ccm. - * Candidate for fallback monitoring. Note it in the - * ccm_config_table and add it to a fallback monitor - * table. - * - */ - CCSIP_DEBUG_ERROR("%s: Socket open failure: DN <%d> CCM <%d>\n", - fname, line, cc_index); - (void) sip_regmgr_create_fallback_ccb(cc_index, line); - ret_code = RET_START_FALLBACK; - } - } - } - if (active_fd == INVALID_SOCKET) { - /* - * No CC present for any calls from this phone. - */ - CCSIP_DEBUG_ERROR("%s: NO CALL CONTROL AVAILABLE! Init a reboot!\n", - fname); - set_active_ccm(&CCM_Dummy_Entry); - - /* - * RegMgr Interface call, ALL_FAIL - */ - ret_code = RET_INIT_REBOOT; - } else if (standby_fd == INVALID_SOCKET) { - /* - * No Standby CC present for this phone. - */ - CCSIP_DEBUG_ERROR("%s: NO VALID STANDBY CALL CONTROL AVAILABLE!\n", - fname); - ret_code = RET_NO_STANDBY; - } - } else { - /* - * Non CCM Case - */ - for (line = 1; line <= MAX_REG_LINES; line++) { - conn_status = sip_transport_setup_cc_conn(line, UNUSED_PARAM); - } - } - return (ret_code); -} - -/* - ** sip_regmgr_destroy_cc_conns - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Replaces SIPTaskDisconnectFromSipProxies - * - * RETURNS: - * - */ -int -sip_regmgr_destroy_cc_conns (void) -{ - const char *fname = "sip_regmgr_destroy_cc_conns"; - line_t dn, max_iteration; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Destroying connections\n", DEB_F_PREFIX_ARGS(SIP_CC_CONN, fname)); - if (CC_Config_Table[LINE1].cc_type == CC_CCM) { - /* - * The first iteration of calling sip_transport_destroy_cc_conn - * will close all the connections entries for pri, sec, tertiary - * connections. - */ - max_iteration = 1; - } else { - max_iteration = MAX_REG_LINES; - } - - for (dn = 1; dn <= max_iteration; dn++) { - /* - * Not checking if it is the active ccm connection that is getting torn down. - * Here we are killing everything so does'nt matter. - * Something else has triggered the closing of the tcp conns. - * So the unreg reason should be set by now. - * In theory we should never see this getting set. - */ - sip_transport_destroy_cc_conn(dn, PRIMARY_CCM); - } - return (0); -} - -/* - ** sip_regmgr_init - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -int -sip_regmgr_init (void) -{ - RET_CODE ret_code = RET_SUCCESS; - - /* - * Create the fallback ccb link list, that will hold - * the fallback ccb's of the failed ccm's - */ - fallback_ccb_list = sll_create(sip_regmgr_find_fallback_ccb); - ret_code = (RET_CODE) sip_regmgr_setup_cc_conns(); - if (ret_code == RET_START_FALLBACK || ret_code == RET_NO_STANDBY) { - sip_regmgr_trigger_fallback_monitor(); - } else if (ret_code == RET_INIT_REBOOT) { - /* - * Send indication of REG_ALLFAIL so platform can - * initiate a reboot. - */ - // Cleanup fallback CCB list - sip_regmgr_free_fallback_ccb_list(); - sip_reg_all_failed = TRUE; - sip_regmgr_handle_reg_all_fail(); - return (SIP_ERROR); - } - CCM_Fallback_Table.fallback_ccm_entry = NULL; - CCM_Fallback_Table.is_idle = FALSE; - CCM_Fallback_Table.is_resp = FALSE; - CCM_Failover_Table.failover_started = FALSE; - sip_reg_all_failed = FALSE; - retry_times = 0; - - return (SIP_OK); -} - - -/* - ** sip_regmgr_shutdown - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: Unregister all lines and clean CCBs - * - * RETURNS: none - * - */ -void -sip_regmgr_shutdown (void) -{ - const char *fname = "sip_regmgr_shutown"; - fallback_ccb_t *fallback_ccb = NULL; - line_t ndx = 0; - ccsipCCB_t *ccb; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - - // Shutdown registration - ccsip_register_shutdown(); - - // Cleanup fallback CCB list - while ((fallback_ccb = (fallback_ccb_t *)sll_next(fallback_ccb_list, - NULL)) != NULL) { - sip_regmgr_clean_fallback_ccb(fallback_ccb); - (void) sll_remove(fallback_ccb_list, fallback_ccb); - cpr_free(fallback_ccb); - } - sll_destroy(fallback_ccb_list); - fallback_ccb_list = NULL; - - for (ndx = REG_CCB_START; ndx <= REG_BACKUP_CCB; ndx++) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - ccb->sipCallID[0] = '\0'; - } - } - - retry_times = 0; - set_active_ccm(NULL); - CCM_Active_Standby_Table.standby_ccm_entry = NULL; -} - -/* - ** sip_regmgr_failover_rsp_start - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: none - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -void -sip_regmgr_failover_rsp_start (void) -{ - const char *fname = "sip_regmgr_failover_rsp_start"; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - /* - * Received response start - * Change the ip addr and port to point to the new ccm - * Set the CC_CONFIG_TABLE entry for all the lines to - * point to the new ccm. - * Set the ccb->cc_cfg_table_entry with the new entry. - */ - sip_regmgr_setup_new_active_ccb(CCM_Failover_Table.failover_ccm_entry); - /* - * Monitoring of standby node will start when we get a 200 ok for the new - * active cucm, or, in case new active fails, then the stanby will be moved - * up to become new active cucm, and will come to this function again. - */ - if (ccsip_register_get_register_state() == SIP_REG_NO_STANDBY) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Unable to get new standby ccm !\n", DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - } - - sip_regmgr_register_lines(TRUE, FALSE); - // start notify timer - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"START TIMER \n", DEB_F_PREFIX_ARGS(SIP_TIMER, fname)); - (void) sip_platform_notify_timer_start(5000); - CCM_Failover_Table.prime_registered = TRUE; -} - -/* - ** sip_regmgr_failover_rsp_complete - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -void -sip_regmgr_failover_rsp_complete (void) -{ - const char *fname = "sip_regmgr_failover_complete"; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname)); - /* - * Received response complete - */ - // stop notify timer - (void) sip_platform_notify_timer_stop(); - CCM_Failover_Table.failover_started = FALSE; - sip_platform_cc_mode_notify(); - sip_regmgr_register_lines(FALSE, FALSE); - sip_regmgr_update_call_ccb(); - sip_platform_set_ccm_status(); - sip_regmgr_trigger_fallback_monitor(); - CCM_Failover_Table.prime_registered = FALSE; -} - -void -sip_regmgr_register_lines (boolean prime_only, boolean skip_prime) -{ - static const char fname[] = "sip_regmgr_register_lines"; - ccsipCCB_t *ccb = 0; - line_t ndx; - line_t line_end; - line_t line_start; - char address[MAX_IPADDR_STR_LEN]; - ti_config_table_t *standby_ccm; - - line_end = 1; - if ((!CCM_Failover_Table.prime_registered && !skip_prime) || prime_only) { - line_start = REG_CCB_START; - } else { - line_start = REG_CCB_START + 1; - } - if (prime_only) { - line_end = REG_CCB_START; - } else { - line_end += TEL_CCB_END; - ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - if (ccb->reg.registered ) { - ui_set_sip_registration_state(ccb->dn_line, TRUE); - } - } - - if (line_start == REG_CCB_START) { - ccsip_register_set_register_state(SIP_REG_REGISTERING); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"registering prime line \n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - /* - * regmgr - Set the Backup (standby ccm) info. - */ - standby_ccm = CCM_Active_Standby_Table.standby_ccm_entry; - if (standby_ccm) { - ti_ccm_t *ti_ccm = &standby_ccm->ti_specific.ti_ccm; - - sip_regmgr_setup_new_standby_ccb(ti_ccm->ccm_id); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"ERROR: Standby ccm entry is NULL\n", - DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - } - } - - for (ndx = line_start; ndx <= line_end; ndx++) { - if (sip_config_check_line((line_t) (ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d, 0x%x\n", - DEB_L_C_F_PREFIX_ARGS(SIP_REG, ccb->index, ccb->dn_line, fname), - ndx, ccb); - - ui_set_sip_registration_state(ccb->dn_line, FALSE); - - sip_sm_call_cleanup(ccb); - sipTransportGetPrimServerAddress(ccb->dn_line, address); - - sstrncpy(ccb->reg.proxy, address, MAX_IPADDR_STR_LEN); - - ccb->reg.addr = ccb->dest_sip_addr; - ccb->reg.port = (uint16_t) ccb->dest_sip_port; - - if (ccb->index == REG_CCB_START) { - ui_update_registration_state_all_lines(FALSE); - ccb->send_reason_header = TRUE; - } else { - ccb->send_reason_header = FALSE; - } - - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } - } - } - sip_platform_set_ccm_status(); -} - -/* - ** sip_regmgr_phone_idle - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_phone_idle (boolean waited) -{ - const char *fname = "sip_regmgr_phone_idle"; - ccsipCCB_t *ccb; - - /* - * Received response - */ - CCM_Fallback_Table.is_idle = TRUE; - // if waited = TRUE send refer and change to token wait - // and send ui unlock - // otherwise start fallback - if (waited) { - platform_reg_fallback_cfm(); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX" waited TRUE\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - CCM_Fallback_Table.fallback_ccm_entry = NULL; - sip_regmgr_send_refer(CCM_Fallback_Table.ccb); - - } else { - /* - * Cancel reg from current active ccm - */ - ccsip_register_cancel(TRUE, FALSE); - - ccb = CCM_Fallback_Table.ccb; - if (ccsip_register_send_msg(SIP_REG_CLEANUP, ccb->index) != SIP_REG_OK) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"failed to send SIP_REG_CLEANUP\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - (void) sip_platform_notify_timer_start(5000); - } -} - -/* - ** sip_regmgr_fallback_rsp - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -void -sip_regmgr_fallback_rsp (void) -{ - const char *fname = "sip_regmgr_fallback_rsp"; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Entered\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - /* - * Received response - */ - (void) sip_platform_notify_timer_stop(); - CCM_Fallback_Table.is_resp = TRUE; - sip_platform_cc_mode_notify(); - if (CCM_Fallback_Table.fallback_ccm_entry) { - sip_regmgr_register_lines(FALSE, FALSE); - CCM_Fallback_Table.fallback_ccm_entry = NULL; - } - sip_regmgr_update_call_ccb(); - CCM_Failover_Table.prime_registered = FALSE; -} - -void -sip_regmgr_rsp (int rsp_id, int rsp_type, boolean waited) -{ - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"rsp id=%s rsp type=%s waited=%d\n", - DEB_F_PREFIX_ARGS(SIP_RESP, "sip_regmgr_rsp"), - rsp_id == FAILOVER_RSP ? "FAILOVER_RSP" : "FALLBACK_RSP", - rsp_type == RSP_START ? "RSP_START" : "RSP_COMPLETE", waited); - - if (rsp_type == RSP_START) { - if (rsp_id == FAILOVER_RSP) { - sip_regmgr_failover_rsp_start(); - // Inform the Sub/Not manager that platform is about to failover. - (void) sip_subsManager_rollover(); - publish_reset(); - } else { - sip_regmgr_phone_idle(waited); - /* - * Inform the Sub/Not manager that platform is about to fallback. - * so that applications can clean up before re-register with the - * primary CCM. - */ - (void) sip_subsManager_rollover(); - publish_reset(); - } - } else if (rsp_type == RSP_COMPLETE) { - - SIPTaskReinitialize(TRUE); - - if (rsp_id == FAILOVER_RSP) { - sip_regmgr_failover_rsp_complete(); - } else { - sip_regmgr_fallback_rsp(); - } - } -} - -/* - * Get the config address based on call manager id - * - * @param ccm_id : callmanager idex - * addr_str: address of allocated space to return - * the address in string format. - * - * @return none - * - * @pre (addr_str != NULL) (1< ccm_id < 4) - * - */ - -void sip_regmgr_get_config_addr (int ccm_id, char *addr_str) { - -#ifdef IPV6_STACK_ENABLED - int ip_mode = CPR_IP_MODE_IPV4; - - - - config_get_value(CFGID_IP_ADDR_MODE, - &ip_mode, sizeof(ip_mode)); - if (ip_mode == CPR_IP_MODE_IPV4) { -#endif - config_get_value(ccm_config_id_addr_str[ccm_id], addr_str, - MAX_IPADDR_STR_LEN); -#ifdef IPV6_STACK_ENABLED - } else if (ip_mode == CPR_IP_MODE_IPV6) { - - config_get_value(ccm_config_id_ipv6_addr_str[ccm_id], addr_str, - MAX_IPADDR_STR_LEN); - } else if (ip_mode == CPR_IP_MODE_DUAL) { - - config_get_value(ccm_config_id_ipv6_addr_str[ccm_id], addr_str, - MAX_IPADDR_STR_LEN); - /* Both mode get IPv6 first if not available get ipv4 */ - if (addr_str[0] == NUL) { - config_get_value(ccm_config_id_addr_str[ccm_id], addr_str, - MAX_IPADDR_STR_LEN); - } - } -#endif -} - -/* - ** sip_regmgr_check_config_change - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:None - * - * DESCRIPTION: Check if there is a config change in transport protocol - * or CCM address - * - * RETURNS: TRUE if config changed - * - */ -boolean -sip_regmgr_check_config_change (void) -{ - const char *fname = "sip_regmgr_check_config_change"; - ti_common_t ti_common; - CCM_ID ccm_id; - ti_common_t *active_ti_common; -#ifdef IPV6_STACK_ENABLED - int ip_mode = CPR_IP_MODE_IPV4; - - config_get_value(CFGID_IP_ADDR_MODE, - &ip_mode, sizeof(ip_mode)); -#endif - - { - uint32_t transport_prot; - CONN_TYPE configured_conn = CONN_NONE; - - config_get_value(CFGID_TRANSPORT_LAYER_PROT, &transport_prot, - sizeof(transport_prot)); - configured_conn = CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.configured_conn_type; - if (transport_prot != (uint32_t) configured_conn) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"protocol%d conn type %d\n", DEB_F_PREFIX_ARGS(SIP_CONFIG, fname), - transport_prot, configured_conn); - return (TRUE); - } - } - for (ccm_id = PRIMARY_CCM; ccm_id < MAX_CCM; ccm_id++) { - - sip_regmgr_get_config_addr(ccm_id, ti_common.addr_str); - - active_ti_common = &CCM_Device_Specific_Config_Table[ccm_id].ti_common; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"CCM config%s active %s\n", DEB_F_PREFIX_ARGS(SIP_CONFIG, fname), - ti_common.addr_str, active_ti_common->addr_str); - if (strncmp(ti_common.addr_str, active_ti_common->addr_str, - strlen(active_ti_common->addr_str)) != 0) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"CCM changed\n", DEB_F_PREFIX_ARGS(SIP_CONFIG, fname)); - return (TRUE); - } - - } - return (FALSE); -} - -/* - ** sip_regmgr_process_config_change - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:None - * - * DESCRIPTION: Shut down and re-init sip - * - * RETURNS: None - * - */ -void -sip_regmgr_process_config_change (void) -{ - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"!!!Process_config_change\n", - DEB_F_PREFIX_ARGS(SIP_CONFIG, "sip_regmgr_process_config_change")); - - /* Register manager configuration changes need to restart sip task */ - sip_shutdown_phase1(FALSE, UNREG_NO_REASON); -} - -/* - ** sip_regmgr_clean_standby_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: None - * - * DESCRIPTION: Clean standby CCB - * - * RETURNS: None - * - */ -void -sip_regmgr_clean_standby_ccb (ccsipCCB_t *ccb) -{ - - if (ccb) { - ccb->reg.proxy[0] = '\0'; - (void) sip_platform_register_expires_timer_stop(ccb->index); - sip_stop_ack_timer(ccb); - ccb->reg.port = 0; - } -} - -/* - ** sip_regmgr_send_refer - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:ccb - * - * DESCRIPTION:Send a REFER message requesting for registering with the CCM - * - * RETURNS: None - * - */ -void -sip_regmgr_send_refer (ccsipCCB_t *ccb) -{ - static const char fname[] = "sip_regmgr_send_refer"; - - /* - * Send a REFER message requesting for registering with - * the callmanager. Cleanup any - * pending REFER transaction as new REFER is created for - * next transmission. - */ - clean_method_request_trx(ccb, sipMethodRefer, TRUE); - if (sipSPISendRefer(ccb, TOKEN_REFER_TO, SIP_REF_TOKEN)) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Successfully sent a REFER" - " for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - sip_reg_sm_change_state(ccb, SIP_REG_STATE_TOKEN_WAIT); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Error while trying to send" - " REFER for token registration!\n", DEB_F_PREFIX_ARGS(SIP_MSG_SEND, fname)); - } -} - -/* - ** sip_regmgr_update_call_ccb - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS:ccb - * - * DESCRIPTION:Update call ccb after failover/fallback - * - * RETURNS: None - * - */ -static void -sip_regmgr_update_call_ccb (void) -{ - line_t i; - ccsipCCB_t *ccb = NULL; - - for (i = TEL_CCB_START; i <= TEL_CCB_END; i++) { - ccb = sip_sm_get_ccb_by_index(i); - if (ccb) { - ccb->local_port = sipTransportGetListenPort(ccb->dn_line, NULL); - sipTransportGetServerIPAddr(&(ccb->dest_sip_addr), ccb->dn_line); - ccb->dest_sip_port = sipTransportGetPrimServerPort(ccb->dn_line); - } - } -} - -/* - * Function: sip_regmgr_ccm_restarted - * - * Parameters: - * new_reg_ccb - pointer to ccsipCCB_t of REG CCB that has seen - * by CCM as a new REG. - * - * Description: - * The function handles CCM has restarted condition. - * The phone needs to clean up internal state that may be left - * before CCM has gone down and come right up. This condition can - * be seen when using UDP for transport and the CCM has gone down - * between REG refresh cycles. - * - * Returns: - * None - */ -void -sip_regmgr_ccm_restarted (ccsipCCB_t *new_reg_ccb) -{ - const char *fname = "sip_regmgr_ccm_restarted"; - ccsipCCB_t *ccb; - line_t ndx, line_end; - - if ((new_reg_ccb == NULL) || (new_reg_ccb->index == REG_BACKUP_CCB)) { - /* No ccb or it is back up CCB, ignore this one */ - return; - } - - /* Inform all applications that hat may subscribe to the CCM/Proxy */ - (void) sip_subsManager_reset_reg(); - /* - * If there are more than one line registered to this CCM/Proxy, - * start re-register the rest of the lines quickly. - */ - line_end = 1; - /* - * REG CCBs start after the TEL CCBs. - * So, line_end equals the number of lines and then add the TEL_CCB_END - * to get the ending of the REG CCBs - */ - line_end += TEL_CCB_END; - - for (ndx = REG_CCB_START; ndx <= line_end; ndx++) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (!sip_config_check_line((line_t)(ndx - TEL_CCB_END)) || - !ccb || (ccb == new_reg_ccb) || - (ccb->state != (int) SIP_REG_STATE_REGISTERED) || - (util_compare_ip(&(ccb->reg.addr), &(new_reg_ccb->reg.addr)) == FALSE)) { - /* - * Skip the CCB for the line that - * 1) is not configured or - * 2) is the same as the one that detects restarts or - * 3) is not registered or - * 4) the proxy/CCM address is not the same one as the - * one that is seeing new registration indication. - * (do not restart other that is not register to the - * same server). - */ - continue; - } - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Re-register %d\n", DEB_F_PREFIX_ARGS(SIP_REG, fname), ccb->dn_line); - /* - * This line still registers before the CCM went down and came back - * up. Do minimum resetting to the ccb just enough for it to - * send REG out to the CCM. - */ - - /* Set state back to idle */ - sip_reg_sm_change_state(ccb, SIP_REG_STATE_IDLE); - - /* Clear Registered flag */ - ccb->reg.registered = 0; - - /* Restart the register timer */ - (void) sip_platform_register_expires_timer_start(ccb->reg.tmr_expire * - 1000, ccb->index); - - /* Update UI to indicates that this line is not register */ - ui_set_sip_registration_state(ccb->dn_line, FALSE); - - /* Send REG out to the CCM */ - if (ccsip_register_send_msg(SIP_REG_REQ, ndx) != SIP_REG_OK) { - ccsip_register_cleanup(ccb, TRUE); - } - } -} - -/* - ** sip_regmgr_notify_timer_callback - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: None - * - * DESCRIPTION: Missed notify from CCM during failover/fallback - * - * RETURNS: None - * - */ -void -sip_regmgr_notify_timer_callback (void *data) -{ - const char *fname = "sip_regmgr_notify_timer_callback"; - ccsipCCB_t *ccb; - sipServiceControl_t *scp = NULL; - const char *versionStamp = "0"; - int versionStampLen; - - ccb = sip_sm_get_ccb_by_index(REG_CCB_START); - if (ccb->reg.registered) { - // Prime line in registered state. Missed notify from ccm. - // fake a notify message to unlock UI, Use value 0 so that - // platform will download the config - scp = (sipServiceControl_t *) - cpr_calloc(1, sizeof(sipServiceControl_t)); - if (scp) { - versionStampLen = strlen(versionStamp); - scp->action = SERVICE_CONTROL_ACTION_CHECK_VERSION; - scp->configVersionStamp = (char *) - cpr_calloc(1, versionStampLen + 1); - scp->dialplanVersionStamp = (char *) - cpr_calloc(1, versionStampLen + 1); - scp->softkeyVersionStamp = (char *) - cpr_calloc(1, versionStampLen + 1); - - if (!scp->configVersionStamp || - !scp->dialplanVersionStamp || - !scp->softkeyVersionStamp) { - CCSIP_DEBUG_ERROR("%s: malloc failed\n", fname); - } else { - sstrncpy(scp->configVersionStamp, versionStamp, versionStampLen + 1); - sstrncpy(scp->dialplanVersionStamp, versionStamp, versionStampLen + 1); - sstrncpy(scp->softkeyVersionStamp, versionStamp, versionStampLen + 1); - sip_platform_handle_service_control_notify(scp); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Fake NOTIFY TO Platform\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - } - sippmh_free_service_control_info(scp); - } - } else { - // We should not get here. If so then some problem - // Add debug message for the time being - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"PRIME LINE UNREGISTRED STATE, UI LOCK!!!\n", - DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - } -} - - -/* - ** sip_regmgr_replace_standby - * - * PARAMETERS: ccb - * - * DESCRIPTION: Replace current standby with new one - * - * RETURNS: None - * - */ -void -sip_regmgr_replace_standby (ccsipCCB_t *ccb) -{ - const char *fname = "sip_regmgr_replace_standby"; - ti_config_table_t *cfg_table_entry; - ti_common_t *ti_common; - ccsipCCB_t *ccb_of_fallback; - ti_config_table_t *standby_ccm_entry; - - if (!new_standby_available) { - return; - } - /* - * Will get in here if a fallback of standby - * occurs when the current standby has an - * outstanding transaction in process. We wait - * till the transaction is complete. - */ - - // Update CCM Status - standby_ccm_entry = (ti_config_table_t *) ccb->cc_cfg_table_entry; - - ui_set_ccm_conn_status(standby_ccm_entry->ti_common.addr_str, - CCM_STATUS_NONE); - - cfg_table_entry = (ti_config_table_t *) new_standby_available; - ti_common = &cfg_table_entry->ti_common; - sip_regmgr_setup_new_standby_ccb(cfg_table_entry->ti_specific.ti_ccm.ccm_id); - if (sip_regmgr_find_fallback_ccb_by_addr_port(&(ti_common->addr), - ti_common->port, &ccb_of_fallback)) { - sip_regmgr_free_fallback_ccb(ccb_of_fallback); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Unable to find fallback" - " ccb to free\n", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname)); - } - /* - * New standby, start monitoring it. - */ - - ui_set_ccm_conn_status(cfg_table_entry->ti_common.addr_str, - CCM_STATUS_STANDBY); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Start monitoring new standby ccb\n", DEB_F_PREFIX_ARGS(SIP_STANDBY, fname)); - (void) ccsip_register_send_msg(SIP_REG_CANCEL, ccb->index); - new_standby_available = NULL; -} -/** - ** sip_regmgr_regallfail_timer_callback - * Callback function called when the reg-all-fail timer expires - * - * @param void* data - * - * @return void - * - */ -void -sip_regmgr_regallfail_timer_callback (void *data) -{ - const char *fname = "sip_regmgr_regallfail_timer_callback"; - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"Registration Failed. Restarting the System now!\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname)); - sip_regmgr_send_status(REG_SRC_SIP, REG_ALL_FAIL); -} - -/** - ** sip_regmgr_handle_reg_all_fail - * Handles the scenario when all the Registration attempts fail. - * - * @param none - * - * @return void - * - */ -void -sip_regmgr_handle_reg_all_fail (void) -{ - const char *fname = "sip_regmgr_handle_reg_all_fail"; - line_t line_end, ndx; - CCM_ID ccm_index; - ccsipCCB_t *ccb; - unsigned long msec; - unsigned long high_regfailtime = 180000; - unsigned long low_regfailtime = 120000; - char tmp_str[STATUS_LINE_MAX_LEN]; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"All registration attempts failed.\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - - /* Start the timer and update UI only if no calls are in progress on the - * phone.*/ - if (sip_platform_is_phone_idle()) { - for (ccm_index = PRIMARY_CCM; ccm_index < MAX_CCM; ccm_index++) { - if (0 != strcmp (CCM_Config_Table[0][ccm_index]->ti_common.addr_str, - "")) { - ui_set_ccm_conn_status(CCM_Config_Table[0][ccm_index]-> - ti_common.addr_str, CCM_STATUS_NONE); - } - } - line_end = 1; - line_end += TEL_CCB_END; - for (ndx = REG_CCB_START; ndx <= line_end; ndx++){ - if (sip_config_check_line((line_t) (ndx - TEL_CCB_END))) { - ccb = sip_sm_get_ccb_by_index(ndx); - if (!ccb) { - continue; - } - ui_set_sip_registration_state(ccb->dn_line, FALSE); - } - } - - /* - * Start regallfial with 100 msec timer once, - * After that get a Random time between high (3 mins) - * and low (2 mins) and start the timer with that time. - */ - if (!regall_fail_attempt) { - msec = REGALL_FAIL_TIME; - } else { - msec = cpr_rand()%(high_regfailtime - low_regfailtime); - msec += low_regfailtime; - } - - regall_fail_attempt = TRUE; - - sip_platform_reg_all_fail_timer_start(msec); - if (platGetPhraseText(STR_INDEX_REGISTERING, - (char *)tmp_str, - STATUS_LINE_MAX_LEN - 1) == CPR_SUCCESS) { - ui_set_notification(CC_NO_LINE, CC_NO_CALL_ID, tmp_str, msec/1000, TRUE, DEF_NOTIFY_PRI); - } - } else { - /* Send the Indication to the platform immediately */ - sip_regmgr_send_status(REG_SRC_SIP, REG_ALL_FAIL); - } -} - -/* - ** notify_register_update - * - * PARAMETERS: last_available_line - last available line button on the phone - * - * DESCRIPTION: This function is used to notify the sip task to handle - * any registration updates when sidecars are plugged in or - * removed - * - * RETURNS: None - * - */ -void notify_register_update(int last_line_available) -{ - static const char fname[] = "notify_register_update"; - - if (ccsip_register_send_msg(SIP_REG_UPDATE, (line_t)last_line_available) != SIP_REG_OK) { - CCSIP_DEBUG_ERROR("%s : Unable to send register update message\n", fname); - } else { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"last_available_line: %d\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname), last_line_available); - } -} - -/* - ** update_ui_line_reg_state - * - * PARAMETERS: - * start_line - first line whose reg status need to be set - * end_line - last line whose reg status needs to be set - * registered - registered/unregistered - * - * DESCRIPTION: This function is used to set the ui line reg status - * - * RETURNS: None - * - */ -void update_ui_line_reg_state(int start_line, int end_line, boolean registered) -{ - line_t line_index = 0; - ccsipCCB_t *line_ccb = NULL; - - for (line_index = (TEL_CCB_END + (line_t)start_line + 1); - line_index <= (TEL_CCB_END + end_line); - line_index++) { - line_ccb = sip_sm_get_ccb_by_index(line_index); - if (line_ccb) { - if (sip_config_check_line(line_ccb->dn_line)) { - ui_set_sip_registration_state(line_ccb->dn_line, registered); - } - } - } -} - - -/* - ** regmgr_handle_register_update - * - * PARAMETERS: last_available_line - last available line button on the phone - * - * DESCRIPTION: This function is used to handle any registration updates needed - * when a sidecar is plugged in or unplugged - * - * RETURNS: None - * - */ -void regmgr_handle_register_update(line_t last_available_line) -{ - static const char fname[] = "regmgr_handle_register_update"; - ccsipCCB_t *line_ccb; - line_t line_index = 0; - char address[MAX_IPADDR_STR_LEN]; - int last_line_button_present; - //boolean reg_update_needed = TRUE; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"last_available_line: %d\n", - DEB_F_PREFIX_ARGS(SIP_REG, fname), last_available_line); - - if (last_available_line == 1) { - return; - } - - last_line_button_present = 1; - - /* added by cangchen fix CSCsz91640*/ - if (last_line_button_present > last_available_line) { - for (line_index = (TEL_CCB_END + (line_t)last_available_line + 1); - line_index <= (TEL_CCB_END + 1) && - line_index <= (TEL_CCB_END + (line_t)(last_line_button_present)); - line_index++) { - line_ccb = sip_sm_get_ccb_by_index(line_index); - if (line_ccb) { - if (sip_config_check_line(line_ccb->dn_line)) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d: 0x%x\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CONFIG, line_ccb->index, line_ccb->dn_line, fname), - line_index, line_ccb); - } - } - } - } - - if (last_available_line > last_line_button_present) { - //sidecar added - for (line_index = (TEL_CCB_END + (line_t)last_line_button_present + 1); - line_index <= (TEL_CCB_END + 1) && - line_index <= (TEL_CCB_END + (line_t)(last_available_line)); - line_index++) { - //sidecar added.register all the lines that have been newly added - line_ccb = sip_sm_get_ccb_by_index(line_index); - if (line_ccb) { - if (sip_config_check_line(line_ccb->dn_line)) { - CCSIP_DEBUG_REG_STATE(DEB_L_C_F_PREFIX"%d: 0x%x\n", - DEB_L_C_F_PREFIX_ARGS(SIP_CONFIG, line_ccb->index, line_ccb->dn_line, fname), - line_index, line_ccb); - - ui_set_sip_registration_state(line_ccb->dn_line, FALSE); - - sip_sm_call_cleanup(line_ccb); - sipTransportGetPrimServerAddress(line_ccb->dn_line, address); - - sstrncpy(line_ccb->reg.proxy, address, MAX_IPADDR_STR_LEN); - - line_ccb->reg.addr = line_ccb->dest_sip_addr; - line_ccb->reg.port = (uint16_t) line_ccb->dest_sip_port; - - if (ccsip_register_send_msg(SIP_REG_REQ, line_index) != SIP_REG_OK) { - ccsip_register_cleanup(line_ccb, TRUE); - } - } - } - } - } else if (last_line_button_present > last_available_line) { - for (line_index = (TEL_CCB_END + (line_t)last_available_line + 1); - line_index <= (TEL_CCB_END + 1) && - line_index <= (TEL_CCB_END + (line_t)(last_line_button_present)); - line_index++) { - //sidecar removed.unregister al the lines that were - //previously registered - line_ccb = sip_sm_get_ccb_by_index(line_index); - if (line_ccb) { - if (sip_config_check_line(line_ccb->dn_line)) { - ui_set_sip_registration_state(line_ccb->dn_line, FALSE); - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"cancelling timers, line= %d\n", - DEB_F_PREFIX_ARGS(SIP_TIMER, fname), line_ccb->index); - (void) sip_platform_register_expires_timer_stop(line_ccb->index); - sip_stop_ack_timer(line_ccb); - - if (ccsip_register_send_msg(SIP_REG_CANCEL, line_index) != SIP_REG_OK) { - ccsip_register_cleanup(line_ccb, TRUE); - } - } - } - } - } - - -} - - - - - - - - - diff --git a/libs/sipcc/core/sipstack/sip_common_transport.c b/libs/sipcc/core/sipstack/sip_common_transport.c deleted file mode 100644 index 86b5e690da..0000000000 --- a/libs/sipcc/core/sipstack/sip_common_transport.c +++ /dev/null @@ -1,2184 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_in.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_locks.h" -#include "phone_debug.h" -#include "dialplan.h" -#include "config.h" -#include "configmgr.h" -#include "ccsip_platform_udp.h" -#include "ccsip_platform_timers.h" -#include "ccsip_register.h" -#include "sip_platform_task.h" -#include "ccsip_task.h" -#include "ccsip_messaging.h" -#include "ccsip_reldev.h" -#include "sip_common_transport.h" -#include "sip_csps_transport.h" -#include "sip_ccm_transport.h" -#include "sip_common_regmgr.h" -#include "util_string.h" -#include "dns_utils.h" -#include "debug.h" -#include "phntask.h" -#include "ccsip_subsmanager.h" -#include "ccsip_publish.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_platform_tls.h" -#include "platform_api.h" -#include "sessionTypes.h" - -uint16_t ccm_config_id_addr_str[MAX_CCM] = { - CFGID_CCM1_ADDRESS, - CFGID_CCM2_ADDRESS, - CFGID_CCM3_ADDRESS -}; - -#ifdef IPV6_STACK_ENABLED - -uint16_t ccm_config_id_ipv6_addr_str[MAX_CCM] = { - CFGID_CCM1_IPV6_ADDRESS, - CFGID_CCM2_IPV6_ADDRESS, - CFGID_CCM3_IPV6_ADDRESS -}; - -#endif - -uint16_t ccm_config_id_port[MAX_CCM] = { - CFGID_CCM1_SIP_PORT, - CFGID_CCM2_SIP_PORT, - CFGID_CCM3_SIP_PORT -}; - -uint16_t ccm_config_id_sec_level[MAX_CCM] = { - CFGID_CCM1_SEC_LEVEL, - CFGID_CCM2_SEC_LEVEL, - CFGID_CCM3_SEC_LEVEL -}; - -uint16_t ccm_config_id_is_valid[MAX_CCM] = { - CFGID_CCM1_IS_VALID, - CFGID_CCM2_IS_VALID, - CFGID_CCM3_IS_VALID -}; - -ti_config_table_t CCM_Device_Specific_Config_Table[MAX_CCM]; -ti_config_table_t CCM_Dummy_Entry; -ti_config_table_t CSPS_Config_Table[MAX_REG_LINES]; -ti_config_table_t *CCM_Config_Table[MAX_REG_LINES + 1][MAX_CCM]; -int phone_local_tcp_port[UNUSED_PARAM]; -ti_csps_t CSPS_Device_Specific_Config_Table; - -sip_tcp_conn_t sip_tcp_conn_tab[MAX_CONNECTIONS]; - -char sent_string[] = "Sent:"; -char rcvd_string[] = "Rcvd:"; -char cseq_string[] = " Cseq:"; -char callid_string[] = " CallId:"; - -static cpr_socket_t listen_socket = INVALID_SOCKET; -extern cc_config_table_t CC_Config_Table[]; -extern sipCallHistory_t gCallHistory[]; -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; - -//extern uint16_t ccm_config_id_addr_str[MAX_CCM]; -//extern uint16_t ccm_config_id_port[MAX_CCM]; -extern void platAddCallControlClassifiers( - unsigned long myIPAddr, unsigned short myPort, - unsigned long cucm1IPAddr, unsigned short cucm1Port, - unsigned long cucm2IPAddr, unsigned short cucm2Port, - unsigned long cucm3IPAddr, unsigned short cucm3Port, - unsigned char protocol); -extern void platform_get_ipv4_address(cpr_ip_addr_t *ip_addr); - -#define SIP_IPPROTO_UDP 17 -#define SIP_IPPROTO_TCP 6 - -/* - * Function: ccsip_add_wlan_classifiers() - * - * Parameters: None - * - * Description: Add classifiers required for wlan - * - * Returns: None - * - */ -void ccsip_add_wlan_classifiers () -{ - cpr_ip_addr_t my_addr; - uint32_t local_port = 0; - uint32_t transport_prot = 0; - - platform_get_ipv4_address (&my_addr); - - config_get_value(CFGID_VOIP_CONTROL_PORT, &local_port, - sizeof(local_port)); - config_get_value(CFGID_TRANSPORT_LAYER_PROT, &transport_prot, - sizeof(transport_prot)); - - platAddCallControlClassifiers(my_addr.u.ip4, local_port , - ntohl(CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.addr.u.ip4), - CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.port, - ntohl(CCM_Device_Specific_Config_Table[SECONDARY_CCM].ti_common.addr.u.ip4), - CCM_Device_Specific_Config_Table[SECONDARY_CCM].ti_common.port, - ntohl(CCM_Device_Specific_Config_Table[TERTIARY_CCM].ti_common.addr.u.ip4), - CCM_Device_Specific_Config_Table[TERTIARY_CCM].ti_common.port, - (transport_prot==CONN_UDP)? SIP_IPPROTO_UDP:SIP_IPPROTO_TCP); -} - -void ccsip_remove_wlan_classifiers () -{ - platRemoveCallControlClassifiers(); - -} - -/* - ** sipTransportGetServerHandle - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: This function gets the server handle for a particular - * line id. - * - * RETURNS: The server handle - * - */ -static cpr_socket_t -sipTransportGetServerHandle (line_t dn, line_t ndx) -{ - - ti_config_table_t *ccm_table_ptr = NULL; - ti_common_t ti_common; - static const char *fname = "sipTransportGetServerHandle"; - - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, dn); - return (INVALID_SOCKET); - } - - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (ndx == REG_BACKUP_CCB) { - /* - * This is the reg backup ccb, so return the - * standby ccm handle - */ - ccm_table_ptr = CCM_Active_Standby_Table.standby_ccm_entry; - } else if (ndx > REG_BACKUP_CCB) { - ccsipCCB_t *ccb = NULL; - - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - } else { - return (INVALID_SOCKET); - } - } else { - ccm_table_ptr = CCM_Active_Standby_Table.active_ccm_entry; - } - if (ccm_table_ptr) { - ti_common = ccm_table_ptr->ti_common; - return (ti_common.handle); - } - } else { - /* - * Assume CSPS for now. - */ - return (sipTransportCSPSGetProxyHandleByDN(dn)); - } - return (INVALID_SOCKET); -} - -/* - ** sipTransportGetServerHandleWithAddr - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: IP addr - * - * DESCRIPTION: This function gets the server handle - * - * RETURNS: The server handle - * - */ -static cpr_socket_t -sipTransportGetServerHandleWithAddr (cpr_ip_addr_t *remote_ip_addr) -{ - - ti_config_table_t *ccm_table_ptr = NULL; - - ccm_table_ptr = CCM_Active_Standby_Table.active_ccm_entry; - - if (ccm_table_ptr && util_compare_ip(remote_ip_addr, &(ccm_table_ptr->ti_common.addr))) { - return (ccm_table_ptr->ti_common.handle); - } - ccm_table_ptr = CCM_Active_Standby_Table.standby_ccm_entry; - if (ccm_table_ptr && util_compare_ip(remote_ip_addr, &(ccm_table_ptr->ti_common.addr))) { - return (ccm_table_ptr->ti_common.handle); - } - return (INVALID_SOCKET); -} - -/* - ** sipTransportGetServerAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: This function gets the server address for a particular - * line id. - * - * RETURNS: 0 if successful - * - */ -uint16_t -sipTransportGetServerAddress (cpr_ip_addr_t *pip_addr, line_t dn, line_t ndx) -{ - static const char *fname = "sipTransportGetServerAddress"; - *pip_addr = ip_addr_invalid; - - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, dn); - return (0); - } - - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (ndx == REG_BACKUP_CCB) { - /* - * This is the reg backup ccb, so return the - * standby ccm addr - */ - if (CCM_Active_Standby_Table.standby_ccm_entry) { - *pip_addr = CCM_Active_Standby_Table.standby_ccm_entry-> - ti_common.addr; - } - return (0); - } else if (ndx > REG_BACKUP_CCB) { - ccsipCCB_t *ccb = NULL; - - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - ti_config_table_t *ccm_table_ptr = NULL; - ti_common_t ti_common; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr) { - ti_common = ccm_table_ptr->ti_common; - *pip_addr = ti_common.addr; - } - } - return (0); - } else { - if (CCM_Active_Standby_Table.active_ccm_entry) { - *pip_addr = CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.addr; - } - return (0); - } - } else { - /* - * Assume CSPS for now. - */ - return (sipTransportCSPSGetProxyAddressByDN(pip_addr, dn)); - } -} - -/* - ** sipTransportGetServerPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: This function gets the server port for a particular - * line id. - * - * RETURNS: Server port as a short - * - */ -short -sipTransportGetServerPort (line_t dn, line_t ndx) -{ - static const char *fname = "sipTransportGetServerPort"; - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, dn); - return (0); - } - - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (ndx == REG_BACKUP_CCB) { - /* - * This is the reg backup ccb, so return the - * standby ccm port - */ - if (CCM_Active_Standby_Table.standby_ccm_entry) { - return ((short) CCM_Active_Standby_Table.standby_ccm_entry-> - ti_common.port); - } - } else if (ndx > REG_BACKUP_CCB) { - ccsipCCB_t *ccb = NULL; - - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - ti_config_table_t *ccm_table_ptr = NULL; - ti_common_t ti_common; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr) { - ti_common = ccm_table_ptr->ti_common; - return (ti_common.port); - } - } - return (0); - } else { - if (CCM_Active_Standby_Table.active_ccm_entry) { - return ((short) CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.port); - } - return (0); - } - } - - /* - * Assume CSPS for now. - */ - return ((short) sipTransportCSPSGetProxyPortByDN(dn)); -} - -conn_create_status_t -sip_transport_setup_cc_conn (line_t dn, CCM_ID ccm_id) -{ - static const char *fname = "sip_transport_setup_cc_conn"; - int dnsErrorCode; - cpr_ip_addr_t server_ipaddr; - uint16_t server_port = 0, listener_port = 0; - cpr_socket_t server_conn_handle = INVALID_SOCKET; - conn_create_status_t status = CONN_INVALID; - uint32_t type; - ti_common_t *ti_common; - int ip_mode = CPR_IP_MODE_IPV4; - uint32_t s_port; - - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, dn); - return (status); - } - - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.\n", - fname, ccm_id); - return (status); - } - CPR_IP_ADDR_INIT(server_ipaddr); - -#ifdef IPV6_STACK_ENABLED - - config_get_value(CFGID_IP_ADDR_MODE, - &ip_mode, sizeof(ip_mode)); -#endif - - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - ti_ccm_t *ti_ccm; - - ti_ccm = &CCM_Config_Table[dn - 1][ccm_id]->ti_specific.ti_ccm; - if (!ti_ccm->is_valid) { - /* - * dont even attempt to create a connection if the - * platform has deemed the ccm info invalid - */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Admin has not configured a valid cucm for cucm index=%s=%d.\n", - fname, CCM_ID_PRINT(ccm_id), ccm_id); - return (status); - } - dnsErrorCode = dnsGetHostByName(CCM_Config_Table[dn - 1][ccm_id]-> - ti_common.addr_str, &server_ipaddr, - 100, 1); - if (dnsErrorCode != DNS_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "sip_transport_setup_cc_conn", - "dnsGetHostByName() returned error:%s", - CCM_Config_Table[dn - 1][ccm_id]->ti_common.addr_str); - return status; - } - - util_ntohl(&server_ipaddr, &server_ipaddr); - - - config_get_value(CFGID_VOIP_CONTROL_PORT, &s_port, sizeof(s_port)); - server_port = (uint16_t) s_port; - - if (CCM_Config_Table[dn - 1][ccm_id]->ti_common.conn_type == CONN_UDP) { - type = SOCK_DGRAM; - listener_port = CCM_Config_Table[dn - 1][ccm_id]->ti_common.listen_port; - } else { - type = SOCK_STREAM; - } - } else { - /* - * Assume CSPS for now. - */ - sipTransportGetServerIPAddr(&server_ipaddr, dn); - server_port = (uint16_t) sipTransportGetPrimServerPort(dn); - if (CSPS_Config_Table[dn - 1].ti_common.conn_type == CONN_UDP) { - type = SOCK_DGRAM; - listener_port = CSPS_Config_Table[dn - 1].ti_common.listen_port; - } else { - type = SOCK_STREAM; - } - } - if (util_check_if_ip_valid(&server_ipaddr) && server_port != 0) { - char server_ipaddr_str[MAX_IPADDR_STR_LEN]; - int ret_status = SIP_ERROR; - - ipaddr2dotted(server_ipaddr_str, &server_ipaddr); - if (type == SOCK_DGRAM) { - ret_status = sip_platform_udp_channel_create(ip_mode, &server_conn_handle, - &server_ipaddr, - server_port, 0); - if (ret_status == SIP_OK) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC UDP socket opened: " - "<%s>:<%d>, handle=<%d>\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn, - server_ipaddr_str, server_port, - server_conn_handle); - status = CONN_SUCCESS; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>:" - "udp channel error" - "server addr=%s, server port=%d) failed.\n", - fname, dn, server_ipaddr_str, server_port); - server_conn_handle = INVALID_SOCKET; - status = CONN_FAILURE; - } - } - else { - sipSPIMessage_t sip_msg; - - if (CC_Config_Table[dn - 1].cc_type != CC_CCM) { - /* We should not come here in non-ccm mode */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"TLS and TCP not supported in non-ccm" - " mode\n", fname); - return (CONN_INVALID); - } - - // TLS if tls and sec_level is not non secure - if (((CCM_Config_Table[dn - 1][ccm_id]->ti_specific.ti_ccm.sec_level - == AUTHENTICATED) || - (CCM_Config_Table[dn - 1][ccm_id]->ti_specific.ti_ccm.sec_level - == ENCRYPTED)) && - (CCM_Config_Table[dn - 1][ccm_id]->ti_common.conn_type == CONN_TLS)) { - uint32_t port = 0; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"server_ipaddr %d \n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), server_ipaddr); - sip_msg.createConnMsg.addr = server_ipaddr; - config_get_value(ccm_config_id_port[ccm_id], &port, - sizeof(port)); - sip_msg.createConnMsg.port = (uint16_t) port; - sip_msg.context = NULL; - server_conn_handle = sip_tls_create_connection(&sip_msg, TRUE, - CCM_Config_Table[dn - 1][ccm_id]->ti_specific.ti_ccm.sec_level); - if (server_conn_handle != INVALID_SOCKET) { - CCM_Config_Table[dn - 1][ccm_id]->ti_common.port = - (uint16_t) port; - } - } else { - sip_msg.createConnMsg.addr = server_ipaddr; - sip_msg.createConnMsg.port = server_port; - sip_msg.context = NULL; - server_conn_handle = sip_tcp_create_connection(&sip_msg); - } - if (server_conn_handle != INVALID_SOCKET) { - listener_port = sip_msg.createConnMsg.local_listener_port; - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC TCP socket opened: " - "to <%s>:<%d>, local_port: %d handle=<%d>\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn, server_ipaddr_str, - server_port, listener_port, - server_conn_handle); - status = CONN_SUCCESS; - phone_local_tcp_port[CCM_Config_Table[dn-1][ccm_id]->ti_specific.ti_ccm.ccm_id] = - sip_msg.createConnMsg.local_listener_port; - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>:" - "tcp channel create error " - "server addr=%s, server port=%d) failed.\n", - fname, dn, server_ipaddr_str, server_port); - status = CONN_FAILURE; - } - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>: CC address/port not configured.\n", - fname, dn); - status = CONN_INVALID; - } - - if ((status == CONN_SUCCESS) || (status == CONN_FAILURE)) { - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - /* - * Add the newly created socket to the CCM as the one - * we listen for incoming messages as well. - */ - ti_common = &CCM_Config_Table[dn - 1][ccm_id]->ti_common; - } else { - /* - * Non CCM Case - */ - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - } - ti_common->addr = server_ipaddr; - ti_common->port = server_port; - ti_common->handle = server_conn_handle; - ti_common->listen_port = listener_port; - } - - return (status); -} - - -int -sip_transport_destroy_cc_conn (line_t dn, CCM_ID ccm_id) -{ - static const char *fname = "sip_transport_destroy_cc_conn"; - int disconnect_status = 0; - cpr_socket_t cc_handle; - CONN_TYPE conn_type; - uint16_t max_cc_count, cc_index; - ti_common_t *ti_common; - CC_ID cc_type; - - /* - * Checking for dn < 1, since we dereference the Config_Tables using - * dn-1 - */ - if (((int)dn < 1) || ((int)dn > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, dn); - return (disconnect_status); - } - - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.\n", - fname, ccm_id); - return (disconnect_status); - } - - cc_type = CC_Config_Table[dn - 1].cc_type; - if (cc_type == CC_CCM) { - /* - * regmgr - */ - ti_common = &CCM_Config_Table[dn - 1][ccm_id]->ti_common; - max_cc_count = MAX_CCM; - } else { - /* - * Assume CSPS for now. - */ - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - max_cc_count = MAX_CSPS; - } - cc_index = 0; - do { - cc_handle = ti_common->handle; - conn_type = ti_common->conn_type; - if (cc_handle != INVALID_SOCKET) { - /* Close the UDP send channel to the proxy */ - if (sip_platform_udp_channel_destroy(cc_handle) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>:" - "handle=%d) \n", fname, dn, cc_handle); - disconnect_status = -1; - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC socket closed: " - "handle=<%d>\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn, cc_handle); - disconnect_status = 0; - } - if (conn_type != CONN_UDP) { - int connid; - - connid = sip_tcp_fd_to_connid(ti_common->handle); - sipTcpFreeSendQueue(connid); - sip_tcp_purge_entry(connid); - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC socket already closed.\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn); - disconnect_status = 0; - } - cc_index++; - ti_common = &CCM_Config_Table[dn - 1][cc_index]->ti_common; - /* - * Will break out for CSPS the first time in the loop. - */ - } while (cc_index < max_cc_count); - if (listen_socket != INVALID_SOCKET) { - if (sip_platform_udp_channel_destroy(listen_socket) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"DN <%d>:" - "(handle=%d)\n", fname, dn, listen_socket); - disconnect_status = -1; - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"DN <%d>: CC socket closed: handle=<%d>\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), dn, listen_socket); - disconnect_status = 0; - } - sip_platform_task_reset_listen_socket(listen_socket); - listen_socket = INVALID_SOCKET; - } - if (CC_Config_Table[dn - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - CCM_Config_Table[dn - 1][ccm_id]->ti_common.handle = INVALID_SOCKET; - } else { - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - ti_common->addr = ip_addr_invalid; - ti_common->port = 0; - ti_common->handle = INVALID_SOCKET; - } - return (disconnect_status); -} - -/* - ** sipTransportCreateSendMessage - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: This function first creates the char * sip message that - * needs to be sent out and then calls the - * sipTransportSendMessage() to send out the message. - * - * RETURNS: -1 if failure and 0 if it succeeds. - * - * NOTE: This function will be consolidated with the following function - * so that only the following function will be necessary. Also the - * signature of the new function that results will be made similar - * to that of the IOS sip stacks sipTransportSendMessage() call. - * That will make the port of IOS based Propel SIP stack into the - * phone easier. - * - */ -int -sipTransportCreateSendMessage (ccsipCCB_t *ccb, - sipMessage_t *pSIPMessage, - sipMethod_t message_type, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port, - boolean isRegister, - boolean reTx, - int timeout, - void *cbp, - int reldev_stored_msg) -{ - const char *fname = "sipTransportCreateSendMessage"; - static char aOutBuf[SIP_UDP_MESSAGE_SIZE + 1]; - uint32_t nbytes = SIP_UDP_MESSAGE_SIZE; - hStatus_t sippmh_write_status = STATUS_FAILURE; - - /* - * Check args - */ - if (!pSIPMessage) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args: pSIPMessage is null\n", fname); - return (-1); - } - - /* - * Get message from the reliable delivery stored msg first and - * if there is no message from the reliable delivery message storage - * then compose the SIP message. - */ - nbytes = sipRelDevGetStoredCoupledMessage(reldev_stored_msg, &aOutBuf[0], - nbytes); - if (nbytes == 0) { - nbytes = SIP_UDP_MESSAGE_SIZE; - sippmh_write_status = sippmh_write(pSIPMessage, aOutBuf, &nbytes); - } else { - sippmh_write_status = STATUS_SUCCESS; - } - ccsip_dump_send_msg_info(aOutBuf, pSIPMessage, cc_remote_ipaddr, - cc_remote_port); - - free_sip_message(pSIPMessage); - if (sippmh_write_status == STATUS_FAILURE) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), - ccb ? ccb->index : 0, ccb ? ccb->dn_line : 0, fname, - "sippmh_write()"); - return (-1); - } - if ((aOutBuf[0] == '\0') || (nbytes == 0)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sippmh_write() returned empty buffer " - "string\n", fname); - return (-1); - } - aOutBuf[nbytes] = '\0'; /* set NULL string for debug printing */ - - if (sipTransportSendMessage(ccb, aOutBuf, nbytes, message_type, - cc_remote_ipaddr, cc_remote_port, isRegister, - reTx, timeout, cbp) < 0) { - if (ccb) { - CCSIP_DEBUG_ERROR("SIPCC-ENTRY: LINE %d/%d: %-35s: message not " - "sent of type %s=%d. sipTransportSendMessage() failed.\n", - ccb->index, ccb->dn_line, fname, - message_type == sipMethodRegister ? "sipMethodRegister" : "", sipMethodRegister); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sipTransportSendMessage()"); - } - return (-1); - } - - return (0); -} - -/* - ** sipTransportSendMessage - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Sends out the sip message. - * - * RETURNS: -1 on failure and 0 on success. - * - * NOTE: This function will be consolidated with the following function - * so that only the following function will be necessary. Also the - * signature of the new function that results will be made similar - * to that of the IOS sip stacks sipTransportSendMessage() call. - * That will make the port of IOS based Propel SIP stack into the - * phone easier. - */ -int -sipTransportSendMessage (ccsipCCB_t *ccb, - char *pOutMessageBuf, - uint32_t nbytes, - sipMethod_t message_type, - cpr_ip_addr_t *cc_remote_ipaddr, - uint16_t cc_remote_port, - boolean isRegister, - boolean reTx, - int timeout, - void *cbp) -{ - const char *fname = "sipTransportSendMessage"; - char cc_config_ipaddr_str[MAX_IPADDR_STR_LEN]; - char cc_remote_ipaddr_str[MAX_IPADDR_STR_LEN]; - char obp_address[MAX_IPADDR_STR_LEN]; - cpr_socket_t send_to_proxy_handle = INVALID_SOCKET; - int nat_enable, dnsErrorCode; - const char *conn_type; - uint32_t local_udp_port = 0; - int tcp_error = SIP_TCP_SEND_OK; - int ip_mode = CPR_IP_MODE_IPV4; - - /* - * Check args - */ - if ((!pOutMessageBuf) || (pOutMessageBuf[0] == '\0')) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args: pOutMessageBuf is empty\n", fname); - return (-1); - } - -#ifdef IPV6_STACK_ENABLED - config_get_value(CFGID_IP_ADDR_MODE, - &ip_mode, sizeof(ip_mode)); -#endif - conn_type = sipTransportGetTransportType(1, TRUE, ccb); - if (ccb) { - /* Check to see whether the supplied address and port - * match those of the currently configured proxy. - * If not, open a new UDP channel, send the message, - * and close the channel. - */ - /* Check to see whether the supplied address and port - * match those of the currently configured proxy. - * If not, open a new UDP channel, send the message, - * and close the channel. - */ - cpr_ip_addr_t cc_config_ipaddr; - uint16_t cc_config_port; - - sipTransportGetServerAddress(&cc_config_ipaddr, ccb->dn_line, ccb->index); - cc_config_port = sipTransportGetServerPort(ccb->dn_line, ccb->index); - - /* - * Convert IP address to string, for debugs - */ - if (SipDebugMessage) { - ipaddr2dotted(cc_config_ipaddr_str, &cc_config_ipaddr); - ipaddr2dotted(cc_remote_ipaddr_str, cc_remote_ipaddr); - } - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"ccb <%d>: config <%s>:<%d> - remote <%s>:<%d>\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), ccb->index, - cc_config_ipaddr_str, cc_config_port, - cc_remote_ipaddr_str, cc_remote_port); - - if (conn_type != NULL) { - if (!cpr_strcasecmp(conn_type, "UDP")) { - if (util_compare_ip(&cc_config_ipaddr, cc_remote_ipaddr) && - (cc_config_port == cc_remote_port)) { - send_to_proxy_handle = sipTransportGetServerHandle(ccb->dn_line, - ccb->index); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Got handle %d\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - send_to_proxy_handle); - } - } else { /* TCP */ - if (util_compare_ip(&cc_config_ipaddr, cc_remote_ipaddr)) { - send_to_proxy_handle = sipTransportGetServerHandle(ccb->dn_line, - ccb->index); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Got handle %d\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - send_to_proxy_handle); - if (send_to_proxy_handle == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Invalid socket\n", fname); - return (-1); - } - } - } - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "Invalid Connection type returned"); - return (-1); - } - } - - /* - * Make the send code below believe that we do not have a connection to - * the remote side so that it creates a send port for each SIP message. - * This send port will have a source UDP port retrieved from the NAT - * configuration settings - */ - config_get_value(CFGID_NAT_ENABLE, &nat_enable, sizeof(nat_enable)); - if (nat_enable == 1) { - send_to_proxy_handle = INVALID_SOCKET; - config_get_value(CFGID_VOIP_CONTROL_PORT, &local_udp_port, - sizeof(local_udp_port)); - } - /* - * Check if we need to get the outbound proxy address and port. If we - * do then we will make the code below believe we do not have a - * connection to the remote side so it creates a send port for this - * message. This involves two checks, the first check is if outbound - * proxy support is enabled at all. The second check is that only - * REQUEST messages go to the outbound proxy. All other message - * types follow the normal rules for sending - */ - if (ccb) { - if (ccb->outBoundProxyPort == 0) { - sipTransportGetOutbProxyAddress(ccb->dn_line, obp_address); - if ((cpr_strcasecmp(obp_address, UNPROVISIONED) != 0) && - (obp_address[0] != 0) && (obp_address[0] != '0')) { - - /* Outbound proxy is configured, get it's IP address */ - dnsErrorCode = sipTransportGetServerAddrPort(obp_address, - &ccb->outBoundProxyAddr, - (uint16_t *)&ccb->outBoundProxyPort, - &ccb->ObpSRVhandle, - TRUE); - - if (dnsErrorCode != DNS_OK) { - /* - * SRV failed, do a DNS A record lookup - * on the outbound proxy - */ - if (util_check_if_ip_valid(&(ccb->outBoundProxyAddr)) == FALSE) { - dnsErrorCode = dnsGetHostByName(obp_address, - &ccb->outBoundProxyAddr, - 100, 1); - } - if (dnsErrorCode == DNS_OK) { - util_ntohl(&(ccb->outBoundProxyAddr),&(ccb->outBoundProxyAddr)); - } else { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - "sipTransportSendMessage", - "dnsGetHostByName() returned error"); - - ccb->outBoundProxyAddr = ip_addr_invalid; - ccb->outBoundProxyPort = 0; - return (-1); - } - } else { - util_ntohl(&(ccb->outBoundProxyAddr), &(ccb->outBoundProxyAddr)); - } - } - } - - /* - * only use outbound proxy if we have one configured, - * we are using the default proxy, we are not using the Emergency - * route, and it is not the backup proxy registration. - */ - if (util_check_if_ip_valid(&(ccb->outBoundProxyAddr)) && - (ccb->proxySelection == SIP_PROXY_DEFAULT) && - (ccb->routeMode != RouteEmergency) && (ccb->index != REG_BACKUP_CCB)) { - send_to_proxy_handle = INVALID_SOCKET; - switch (message_type) { - case sipMethodResponse: - case sipMethodUnknown: - ccb->outBoundProxyPort = cc_remote_port; - break; - default: - /* - * We have determined that this message is a REQUEST - * so we will change the one time outgoing port to - * the outbound proxy address and port - */ - *cc_remote_ipaddr = ccb->outBoundProxyAddr; - if (ccb->outBoundProxyPort != 0) { - cc_remote_port = (uint16_t) ccb->outBoundProxyPort; - } else { - cc_remote_port = (uint16_t) sipTransportGetOutbProxyPort(ccb->dn_line); - ccb->outBoundProxyPort = cc_remote_port; - } - break; - } - } - } - - if (SipDebugTask || SipDebugMessage) { - ipaddr2dotted(cc_remote_ipaddr_str, cc_remote_ipaddr); - } - - if ((conn_type != NULL) && (cpr_strcasecmp(conn_type, "UDP")) && - (send_to_proxy_handle == INVALID_SOCKET)) { - send_to_proxy_handle = sipTransportGetServerHandleWithAddr(cc_remote_ipaddr); - CCSIP_DEBUG_TASK(DEB_F_PREFIX"<%s> remote ip addr\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), cc_remote_ipaddr_str); - if (send_to_proxy_handle == INVALID_SOCKET) { - // for TCP and TLS return if we do not have a connection to the - // remote side - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No connection to ip addr <%s>\n", fname, cc_remote_ipaddr_str); - return (-1); - } - } - if (send_to_proxy_handle != INVALID_SOCKET) { - /* - * Get the connection type and call ...sendto() or - * ...send() appropriately (for udp and tcp respectively). - * Also this will need to change to send the correct line - * when we go with supporting CCM and proxy on the - * same EP. For now we can just pass '0' as line as the phone - * is only going to support either CSPS or CCM and not both at - * the same time. - */ - if (!cpr_strcasecmp(conn_type, "UDP")) { - if (sip_platform_udp_channel_sendto(send_to_proxy_handle, - pOutMessageBuf, - nbytes, - cc_remote_ipaddr, - cc_remote_port) == SIP_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_sendto()"); - return (-1); - } - } - else { - /* - * Assume TCP for now - */ - tcp_error = sip_tcp_channel_send(send_to_proxy_handle, - pOutMessageBuf, - (unsigned short)nbytes); - if (tcp_error == SIP_TCP_SEND_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_tcp_channel_send()"); - return (-1); - } - } - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Sent SIP message: handle=<%d>," - "length=<%d>, message=\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - send_to_proxy_handle, nbytes); - CCSIP_DEBUG_MESSAGE_PKT(pOutMessageBuf); - } else { - /* Create a new handle for the supplied address and port */ - cpr_socket_t one_time_handle = INVALID_SOCKET; - int status = -1; - - /* Open UDP send channel to the specified address and port */ - status = sip_platform_udp_channel_create(ip_mode, &one_time_handle, - cc_remote_ipaddr, - cc_remote_port, - local_udp_port); - if (status < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_create()"); - return (-1); - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Opened a one-time UDP send channel to server " - "<%s>:<%d>, handle = %d local port= %d\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - cc_remote_ipaddr_str, cc_remote_port, - one_time_handle, local_udp_port); - - /* Send the message */ - if (sip_platform_udp_channel_sendto(one_time_handle, - pOutMessageBuf, - nbytes, - cc_remote_ipaddr, - cc_remote_port) == SIP_ERROR) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_sendto()"); - /* Close the UDP send channel */ - status = sip_platform_udp_channel_destroy(one_time_handle); - if (status < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_destroy()"); - } - return (-1); - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Sent SIP message to <%s>:<%d>, " - "handle=<%d>, length=<%d>, message=\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), cc_remote_ipaddr_str, cc_remote_port, - one_time_handle, nbytes); - CCSIP_DEBUG_MESSAGE_PKT(pOutMessageBuf); - - /* Close the UDP send channel */ - status = sip_platform_udp_channel_destroy(one_time_handle); - if (status < 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_udp_channel_destroy()"); - return (-1); - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Closed a one-time UDP send channel " - "handle = %d\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), one_time_handle); - } - - if (ccb) { - // - // Cancel any outstanding reTx timers, if any - // - /* - * Dont do for fallback ccb's. - */ - if ((ccb->index <= REG_BACKUP_CCB) && reTx) { - CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_ENTRY), - ccb->index, ccb->dn_line, fname, - "Stopping reTx timer"); - sip_platform_msg_timer_stop(ccb->index); - - /* - * If the specified timeout value is not 0 and UDP, start the reTx timer - * When the phone is in remote location, then REG message send may fail - * for TCP. In that case, that message has to be retransmitted from the SIP - * layer. So if the error_no == CPR_ENOTCONN, then send the SIP message - * during next retry. - * - */ - if ((timeout > 0) && ((!cpr_strcasecmp(conn_type, "UDP") - || ((tcp_error == CPR_ENOTCONN) && (!cpr_strcasecmp(conn_type, "TCP")))))) { - void *data; - - data = isRegister ? (void *) ccb : (void *)(long)ccb->index; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"LINE %d/%d: Starting reTx timer (%d " - "msec)\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), ccb->index, ccb->dn_line, - timeout); - ccb->retx_flag = TRUE; - if (sip_platform_msg_timer_start(timeout, data, ccb->index, - pOutMessageBuf, nbytes, - (int) message_type, cc_remote_ipaddr, - cc_remote_port, isRegister) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED), ccb->index, - ccb->dn_line, fname, - "sip_platform_msg_timer_start()"); - ccb->retx_flag = FALSE; - } - } - } - - if (sipMethodCancel == message_type || sipMethodBye == message_type) { - gCallHistory[ccb->index].last_bye_dest_ipaddr = *cc_remote_ipaddr; - gCallHistory[ccb->index].last_bye_dest_port = cc_remote_port; - } - } - else { - sipSCB_t *scbptr = (sipSCB_t *)cbp; - ccsip_publish_cb_t *pcb_p = (ccsip_publish_cb_t *)cbp; - sipTCB_t *tcbp = (sipTCB_t *)cbp; - - if (cbp != NULL) { - sipPlatformUITimer_t *timer = NULL; - uint32_t id = 0; - - scbptr->hb.retx_flag = TRUE; - if (((ccsip_common_cb_t *)cbp)->cb_type == SUBNOT_CB) { - timer = &(sipPlatformUISMSubNotTimers[scbptr->line]); - id = scbptr->line; - } else if (((ccsip_common_cb_t *)cbp)->cb_type == PUBLISH_CB) { - timer = &(pcb_p->retry_timer); - id = pcb_p->pub_handle; - } else { // unsolicited NOTIFY - int temp_timeout = 0; - config_get_value(CFGID_TIMER_T1, &temp_timeout, sizeof(temp_timeout)); - temp_timeout = (64 * temp_timeout); - if (cprStartTimer(tcbp->timer, temp_timeout, (void *)(long)(tcbp->trxn_id)) == CPR_FAILURE) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"%s failed\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), "cprStartTimer"); - } - } - - if (timeout > 0 && timer != NULL) { - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Starting reTx timer for %d secs", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), timeout); - if (sip_platform_msg_timer_subnot_start(timeout, timer, id, - pOutMessageBuf, nbytes, - (int) message_type, - cc_remote_ipaddr, - cc_remote_port) != SIP_OK) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "sip_platform_msg_timer_subnot_start"); - } - } - } - - } - - return (0); -} - -/* - ** sipTransportGetListenPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: Reads and returns the Primary server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Primary Server port (Currently only SIP Proxy specific) - * - */ -uint16_t -sipTransportGetListenPort (line_t line, ccsipCCB_t *ccb) -{ - ti_config_table_t *ccm_table_ptr = NULL; - static const char *fname = "sipTransportGetListenPort"; - - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return 0; - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (ccb) { - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - } - if (ccm_table_ptr) { - CCM_ID ccm_id; - - ccm_id = ccm_table_ptr->ti_specific.ti_ccm.ccm_id; - if (ccm_id >= MAX_CCM) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"ccm id <%d> out of bounds.\n", - fname, ccm_id); - return 0; - } - return ((uint16_t) CCM_Config_Table[line - 1][ccm_id]-> - ti_common.listen_port); - } else if (CCM_Active_Standby_Table.active_ccm_entry != NULL) { - return ((uint16_t) CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.listen_port); - } else { - return ((uint16_t) CCM_Config_Table[line - 1][PRIMARY_CCM]-> - ti_common.listen_port); - } - } else { - /* - * Assume CSPS for now. - */ - return ((uint16_t) CSPS_Config_Table[line - 1].ti_common.listen_port); - } -} - -/* - ** sipTransportGetTransportType - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: Reads and returns the Primary server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Primary Server port (Currently only SIP Proxy specific) - * - */ -const char * -sipTransportGetTransportType (line_t line, boolean upper_case, - ccsipCCB_t *ccb) -{ - const char *tcp, *udp, *tls; - CONN_TYPE conn_type; - ti_config_table_t *ccm_table_ptr = NULL; - static const char *fname = "sipTransportGetTransportType"; - - tcp = (upper_case) ? "TCP" : "tcp"; - udp = (upper_case) ? "UDP" : "udp"; - tls = (upper_case) ? "TLS" : "tls"; - - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return udp; - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - // If ccb is not NULL get the conn type from cc_cfg_table_entry - // This would be the case for REGISTER/keep alive messages. - // else get from the active ccm entry if available. - if (ccb) { - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - } - if (ccm_table_ptr) { - conn_type = ccm_table_ptr->ti_common.conn_type; - } else if (CCM_Active_Standby_Table.active_ccm_entry != NULL) { - conn_type = CCM_Active_Standby_Table.active_ccm_entry->ti_common.conn_type; - } else { - conn_type = CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.conn_type; - } - } else { - /* - * Assume CSPS for now. - */ - conn_type = CSPS_Config_Table[line - 1].ti_common.conn_type; - } - switch (conn_type) { - case CONN_UDP: - return (udp); - case CONN_TCP: - case CONN_TCP_TMP: - return (tcp); - case CONN_TLS: - return (tls); - default: - return (NULL); - } -} - -/* - ** sipTransportGetServerAddrPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Wrapper function for the sip dns srv functions. - * Currently code only caters to SIP Proxies. But - * with CCM, the code will have handle the different - * scenarios of retries etc in the CCM environment as - * well. - * - * RETURNS: The dns error codes that the invoked functions return. - * - */ -int -sipTransportGetServerAddrPort (char *domain, cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, srv_handle_t *psrv_order, - boolean retried_addr) -{ - int rc; - - if (psrv_order == NULL) { - rc = sip_dns_gethostbysrvorname(domain, ipaddr_ptr, port); - } else { - rc = sip_dns_gethostbysrv(domain, ipaddr_ptr, port, psrv_order, - retried_addr); - } - return (rc); -} - -/* - ** sipTransportGetPrimServerPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: Reads and returns the Primary server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Primary Server port (Currently only SIP Proxy specific) - * - */ -int -sipTransportGetPrimServerPort (line_t line) -{ - static const char *fname = "sipTransportGetPrimServerPort"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (CCM_Active_Standby_Table.active_ccm_entry != NULL) { - return (CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.port); - } else { - return (0); - } - } else { - /* - * Assume CSPS for now. - */ - return (CSPS_Config_Table[line - 1].ti_common.port); - } -} - -/* - ** sipTransportGetBkupServerPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Backup server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Backup Server port (Currently only SIP Proxy specific) - * - */ -int -sipTransportGetBkupServerPort (line_t line) -{ - static const char *fname = "sipTransportGetBkupServerPort"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - - */ - return (0); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - return (ti_csps->bkup_pxy_port); - } -} - -/* - ** sipTransportGetEmerServerPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Emergency server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Emergency Server port (Currently only SIP Proxy specific) - * - */ -int -sipTransportGetEmerServerPort (line_t line) -{ - static const char *fname = "sipTransportGetEmerServerPort"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - return (0); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - return (ti_csps->emer_pxy_port); - } -} - -/* - ** sipTransportGetOutbProxyPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Outbound server port from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: Outbound Server port (Currently only SIP Proxy specific) - * - */ -int -sipTransportGetOutbProxyPort (line_t line) -{ - static const char *fname = "sipTransportGetOutbProxyPort"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - return (0); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - return (ti_csps->outb_pxy_port); - } -} - -/* - ** sipTransportGetPrimServerAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Primary server address from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: IP address in buffer (Currently only SIP Proxy specific) - * - */ -cpr_ip_type -sipTransportGetPrimServerAddress (line_t line, char *buffer) -{ - ti_common_t *ti_common; - cpr_ip_type ip_type = CPR_IP_ADDR_IPV4; - static const char *fname = "sipTransportGetPrimServerAddress"; - - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return (ip_type); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - if (CCM_Active_Standby_Table.active_ccm_entry != NULL) { - sstrncpy(buffer, CCM_Active_Standby_Table.active_ccm_entry-> - ti_common.addr_str, MAX_IPADDR_STR_LEN); - ip_type = CCM_Active_Standby_Table.active_ccm_entry->ti_common.addr.type; - - } else { - ti_common = &CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common; - sstrncpy(buffer, ti_common->addr_str, MAX_IPADDR_STR_LEN); - ip_type = ti_common->addr.type; - } - } else { - /* - * Assume CSPS for now. - */ - ti_common = &CSPS_Config_Table[line - 1].ti_common; - sstrncpy(buffer, ti_common->addr_str, MAX_IPADDR_STR_LEN); - ip_type = ti_common->addr.type; - } - - return(ip_type); -} - -/* - ** sipTransportGetBkupServerAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Backup server address from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: IP Address as uint32_t and str in buffer (Currently only - * SIP Proxy specific) - * - */ -uint16_t -sipTransportGetBkupServerAddress (cpr_ip_addr_t *pip_addr, - line_t line, char *buffer) -{ - static const char *fname = "sipTransportGetBkupServerAddress"; - *pip_addr = ip_addr_invalid; - - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return (0); - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - * This would be standby address for the ccm - */ - sstrncpy(buffer, "UNPROVISIONED", MAX_IPADDR_STR_LEN); - return (0); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - sstrncpy(buffer, ti_csps->bkup_pxy_addr_str, MAX_IPADDR_STR_LEN); - *pip_addr = ti_csps->bkup_pxy_addr; - return (1); - } -} - -/* - ** sipTransportGetEmerServerAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Emergency server address from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: IP address in buffer (Currently only SIP Proxy specific) - * - */ -void -sipTransportGetEmerServerAddress (line_t line, char *buffer) -{ - static const char *fname = "sipTransportGetEmerServerAddress"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return; - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - sstrncpy(buffer, "UNPROVISIONED", MAX_IPADDR_STR_LEN); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - sstrncpy(buffer, ti_csps->emer_pxy_addr_str, MAX_IPADDR_STR_LEN); - } -} - -/* - ** sipTransportGetOutbProxyAddress - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: Reads and returns the Outbound server address from the - * local UDP table that is filled at init time and during - * config change notifications. - * - * RETURNS: IP address in buffer (Currently only SIP Proxy specific) - * - */ -void -sipTransportGetOutbProxyAddress (line_t line, char *buffer) -{ - static const char *fname = "sipTransportGetOutbProxyAddress"; - /* - * Checking for line < 1, since we dereference the Config_Tables using - * line-1 - */ - if (((int)line < 1) || ((int)line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, line); - return; - } - - if (CC_Config_Table[line - 1].cc_type == CC_CCM) { - /* - * regmgr - */ - sstrncpy(buffer, "UNPROVISIONED", MAX_IPADDR_STR_LEN); - } else { - /* - * Assume CSPS for now. - */ - ti_csps_t *ti_csps; - - ti_csps = CSPS_Config_Table[line - 1].ti_specific.ti_csps; - sstrncpy(buffer, ti_csps->outb_pxy_addr_str, MAX_IPADDR_STR_LEN); - } -} - -/* - * sipTransportGetServerIPAddr() - * - * Perform DNS lookup on the primary proxy name and - * return its IP address. - * - * Note: the IP Address is returned in the non-Telecaster - * SIP format, which is not byte reversed. - * Eg. 0xac2c33f8 = 161.44.51.248 - */ -void -sipTransportGetServerIPAddr (cpr_ip_addr_t *pip_addr, line_t line) -{ - const char *fname = "sipTransportGetServerIPAddr"; - cpr_ip_addr_t IPAddress; - uint16_t port; - srv_handle_t srv_order = NULL; - int dnsErrorCode = 0; - char addr[MAX_IPADDR_STR_LEN]; - char obp_address[MAX_IPADDR_STR_LEN]; - - CPR_IP_ADDR_INIT(IPAddress); - - sipTransportGetOutbProxyAddress(line, obp_address); - if ((cpr_strcasecmp(obp_address, UNPROVISIONED) != 0) && - (obp_address[0] != 0) && (obp_address[0] != '0')) { - sstrncpy(addr, obp_address, MAX_IPADDR_STR_LEN); - } else { - sipTransportGetPrimServerAddress(line, addr); - } - dnsErrorCode = sipTransportGetServerAddrPort(addr, &IPAddress, &port, - &srv_order, FALSE); - if (srv_order) { - dnsFreeSrvHandle(srv_order); - } - - if (dnsErrorCode != DNS_OK) { - //CCSIP_DEBUG_TASK(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - // fname, "sipTransportGetServerAddrPort"); - dnsErrorCode = dnsGetHostByName(addr, &IPAddress, 100, 1); - } - - if (dnsErrorCode != 0) { - CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_FUNCTIONCALL_FAILED), - fname, "dnsGetHostByName()"); - } - *pip_addr = IPAddress; - util_ntohl(pip_addr, &IPAddress); -} - -/* - ** sip_regmgr_set_cc_info - * - * FILENAME: ip_phone\sip\sip_common_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sip_regmgr_set_cc_info (line_t line, line_t dn_line, - CC_ID *cc_type, void *cc_table_entry) -{ - static const char *fname = "sip_regmgr_set_cc_info"; - ti_config_table_t **active_standby_table_entry = - (ti_config_table_t **) cc_table_entry; - - /* - * Checking for dn_line < 1, since we dereference the Config_Tables using - * dn_line-1 - */ - if (((int)dn_line < 1) || ((int)dn_line > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN <%d> out of bounds.\n", - fname, dn_line); - return; - } - - *cc_type = CC_Config_Table[dn_line - 1].cc_type; - if (*cc_type == CC_CCM) { - if (line == REG_BACKUP_CCB) { - *active_standby_table_entry = - CCM_Active_Standby_Table.standby_ccm_entry; - } else { - *active_standby_table_entry = - CCM_Active_Standby_Table.active_ccm_entry; - } - } -} - -int -sipTransportGetCCType (int line, void *cc_table_entry) -{ - if (cc_table_entry != NULL) { - cc_table_entry = CC_Config_Table[line - 1].cc_table_entry; - } - return (CC_Config_Table[line - 1].cc_type); -} - -/** - * - * SIPTransportUDPListenForSipMessages - * - * Establish a UDP socket to listen to for incoming SIP messages - * - * Parameters: None - * - * Return Value: SIP_OK or SIP_ERROR - * - */ -int -SIPTransportUDPListenForSipMessages (void) -{ - static const char *fname = "SIPTransportUDPListenForSipMessages"; - uint32_t local_sip_control_port; - cpr_ip_addr_t local_sip_ip_addr; - int ip_mode = CPR_IP_MODE_IPV4; - - /* - * Start listening on port 5060 for incoming SIP messages - */ - CPR_IP_ADDR_INIT(local_sip_ip_addr); - - config_get_value(CFGID_VOIP_CONTROL_PORT, &local_sip_control_port, - sizeof(local_sip_control_port)); - -#ifdef IPV6_STACK_ENABLED - config_get_value(CFGID_IP_ADDR_MODE, &ip_mode, sizeof(ip_mode)); -#endif - switch (ip_mode) { - case CPR_IP_MODE_IPV4: - local_sip_ip_addr.type = CPR_IP_ADDR_IPV4; - local_sip_ip_addr.u.ip4 = 0; - break; - case CPR_IP_MODE_IPV6: - case CPR_IP_MODE_DUAL: - local_sip_ip_addr = ip_addr_invalid; - local_sip_ip_addr.type = CPR_IP_ADDR_IPV6; - break; - default: - break; - } - /* Based on mode type configure the IP address IPv4 or IPv6 */ - - - if (sip_platform_udp_channel_listen(ip_mode, &listen_socket, &local_sip_ip_addr, - (uint16_t) local_sip_control_port) - != SIP_OK) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_platform_udp_channel_listen(0, %d) " - "returned error.\n", fname, local_sip_control_port); - return SIP_ERROR; - } - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Listening for SIP messages on UDP port <%d>, handle=<%d>\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), local_sip_control_port, listen_socket); - - return SIP_OK; -} - -static void -sipTransportCfgTableInit (boolean *cc_udp) -{ -// int cc_num; - line_t line; - CC_ID dev_cc_type = CC_OTHER; - uint32_t transport_prot = CONN_UDP; - ti_common_t *ti_common; - static const char *fname = "sipTransportCfgTableInit"; - - - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"Transport Interface init\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname)); - - ti_common = &CSPS_Config_Table[0].ti_common; - sip_config_get_proxy_addr(1, ti_common->addr_str, sizeof(ti_common->addr_str)); - - if (!cpr_strcasecmp(ti_common->addr_str, "USECALLMANAGER")) { - dev_cc_type = CC_CCM; - } - if (dev_cc_type == CC_CCM) { - /* - * Initialize the ccm table - */ - uint32_t listen_port; - CCM_ID ccm_id; - ti_ccm_t *ti_ccm; - - memset(CCM_Config_Table, 0, - (sizeof(uint32_t) * MAX_CCM * (MAX_REG_LINES + 1))); - config_get_value(CFGID_VOIP_CONTROL_PORT, &listen_port, - sizeof(listen_port)); - config_get_value(CFGID_TRANSPORT_LAYER_PROT, &transport_prot, - sizeof(transport_prot)); - if (transport_prot != CONN_UDP) { - *cc_udp = FALSE; - } - - /* - * Initialize the dummy entry and point the Active - * and standby to it. - */ - CCM_Dummy_Entry.cc_type = CC_CCM; - CCM_Dummy_Entry.ti_specific.ti_ccm.ccm_id = MAX_CCM; - CCM_Dummy_Entry.ti_common.conn_type = (CONN_TYPE) transport_prot; - - for (ccm_id = PRIMARY_CCM; ccm_id < MAX_CCM; ccm_id++) { - uint32_t port; - phone_local_tcp_port[ccm_id] = 0; - ti_common = &CCM_Device_Specific_Config_Table[ccm_id].ti_common; - ti_ccm = &CCM_Device_Specific_Config_Table[ccm_id].ti_specific.ti_ccm; - - CCM_Device_Specific_Config_Table[ccm_id].cc_type = CC_CCM; - sip_regmgr_get_config_addr(ccm_id, ti_common->addr_str); - - config_get_value(ccm_config_id_port[ccm_id], &port, sizeof(port)); - ti_common->port = (uint16_t) port; - ti_common->conn_type = ti_common->configured_conn_type = (CONN_TYPE) transport_prot; - ti_common->listen_port = (uint16_t) listen_port; - ti_common->handle = INVALID_SOCKET; - /* - * CCM specific config variable read - */ - ti_ccm->ccm_id = (CCM_ID) ccm_id; - ti_ccm->sec_level = NON_SECURE; - ti_ccm->is_valid = 1; - config_get_value(ccm_config_id_sec_level[ccm_id], - &ti_ccm->sec_level, sizeof(ti_ccm->sec_level)); - config_get_value(ccm_config_id_is_valid[ccm_id], - &ti_ccm->is_valid, sizeof(ti_ccm->is_valid)); - if ((ti_ccm->sec_level == NON_SECURE) && - (transport_prot == CONN_TLS)) { - ti_common->conn_type = CONN_TCP; - } - for (line = 0; line < MAX_REG_LINES; line++) { - CCM_Config_Table[line][ccm_id] = - &CCM_Device_Specific_Config_Table[ccm_id]; - if (ccm_id == PRIMARY_CCM) { - CC_Config_Table[line].cc_type = CC_CCM; - CC_Config_Table[line].cc_table_entry = (void *) - CCM_Config_Table[ccm_id]; - } - } - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"For CCM%d: line %d Addr: %s Port: %d" - " listen Port: %d transport: %d" - " Sec Level: %d Is Valid: %d\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - ccm_id, line, ti_common->addr_str, - ti_common->port, ti_common->listen_port, - ti_common->conn_type, ti_ccm->sec_level, - ti_ccm->is_valid); - } - } else { - ti_csps_t *ti_csps = &CSPS_Device_Specific_Config_Table; - uint32_t bkup_pxy_port; - uint32_t emer_pxy_port; - uint32_t outb_pxy_port; - uint32_t listen_port; - - sip_config_get_backup_proxy_addr(&(ti_csps->bkup_pxy_addr), - ti_csps->bkup_pxy_addr_str, - sizeof(ti_csps->bkup_pxy_addr_str)); - config_get_value(CFGID_PROXY_BACKUP_PORT, &bkup_pxy_port, - sizeof(bkup_pxy_port)); - ti_csps->bkup_pxy_port = (uint16_t) bkup_pxy_port; - config_get_string(CFGID_PROXY_EMERGENCY, ti_csps->emer_pxy_addr_str, - sizeof(ti_csps->emer_pxy_addr_str)); - config_get_value(CFGID_PROXY_EMERGENCY_PORT, &emer_pxy_port, - sizeof(emer_pxy_port)); - ti_csps->emer_pxy_port = (uint16_t) emer_pxy_port; - config_get_string(CFGID_OUTBOUND_PROXY, ti_csps->outb_pxy_addr_str, - sizeof(ti_csps->outb_pxy_addr_str)); - config_get_value(CFGID_OUTBOUND_PROXY_PORT, &outb_pxy_port, - sizeof(outb_pxy_port)); - ti_csps->outb_pxy_port = (uint16_t) outb_pxy_port; - - config_get_value(CFGID_VOIP_CONTROL_PORT, &listen_port, - sizeof(listen_port)); - for (line = 0; line < MAX_REG_LINES; line++) { - ti_common = &CSPS_Config_Table[line].ti_common; - CSPS_Config_Table[line].ti_specific.ti_csps = ti_csps; - - sip_config_get_proxy_addr((line_t)(line + 1), ti_common->addr_str, - sizeof(ti_common->addr_str)); - ti_common->port = sip_config_get_proxy_port((line_t) (line + 1)); - ti_common->conn_type = CONN_UDP; - ti_common->listen_port = (uint16_t) listen_port; - ti_common->addr = ip_addr_invalid; - ti_common->handle = INVALID_SOCKET; - - CC_Config_Table[line].cc_table_entry = (void *) NULL; // NULL for now. - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"line %d Addr: %s Port: %d and listen Port: %d\n" - " transport: %d\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - line, ti_common->addr_str, ti_common->port, - ti_common->listen_port, ti_common->conn_type); - if (line == 0) { - ti_csps_t *ti_csps_cfg_table; - - ti_csps_cfg_table = CSPS_Config_Table[line].ti_specific.ti_csps; - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"bkup Addr: %s and Port: %d\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - ti_csps_cfg_table->bkup_pxy_addr_str, - ti_csps_cfg_table->bkup_pxy_port); - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"emer Addr: %s and Port: %d\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - ti_csps_cfg_table->emer_pxy_addr_str, - ti_csps_cfg_table->emer_pxy_port); - CCSIP_DEBUG_MESSAGE(DEB_F_PREFIX"outb Addr: %s and Port: %d\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, fname), - ti_csps_cfg_table->outb_pxy_addr_str, - ti_csps_cfg_table->outb_pxy_port); - } - } - } -} - - -/* - ** sipTransportInit - * - * FILENAME: sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * Note: Make sure this gets calls during config change notifications. - * from softphone\src-win\global_stub.c's and src-arm-79xx\config.c's - * config_commit() function that calls the prot_config_change_notify(). - * RETURNS: - * - */ -int -sipTransportInit (void) -{ - int result = 0; - static const char *fname = "sipTransportInit"; - boolean cc_udp = TRUE; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"Transport_interface: Init function " - "call !\n", DEB_F_PREFIX_ARGS(SIP_TRANS, fname)); - /* - * Init the cc related info into the cc config table - */ - sipTransportCfgTableInit(&cc_udp); - /* - * Make sure that the IP stack is up before trying to connect - */ - if (PHNGetState() > STATE_IP_CFG) { - if (cc_udp) { - /* - * By now we know the DHCP is up, so we can - * start open sockets for listening for SIP messages and - * the UDP channel to the SIP proxy server - */ - - if (SIPTransportUDPListenForSipMessages() == SIP_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"device unable to" - " receive SIP messages.\n", fname); - } - } else { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"CCM in non udp mode so not " - "opening separate listen socket.\n",DEB_F_PREFIX_ARGS(SIP_TRANS, fname)); - } - if (sip_regmgr_init() != SIP_OK) { - result = SIP_ERROR; - } - } else { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"IP Stack Not " - "Initialized.\n", fname); - result = -1; - } - return (result); -} - -/* - ** sipTransportShutdown - * - * FILENAME: sip_common_transport.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: - * - */ -void -sipTransportShutdown () -{ - CCSIP_DEBUG_STATE(DEB_F_PREFIX"Transport_interface: Shutting down!\n", DEB_F_PREFIX_ARGS(SIP_TRANS, "sipTransportShutdown")); - sip_regmgr_destroy_cc_conns(); -} - -/* - ** sipTransportClearServerHandle - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: ip addr, port, connid - * - * DESCRIPTION: This function clears the server handle and port - * - * RETURNS: none - * - */ -void -sipTransportClearServerHandle (cpr_ip_addr_t *ipaddr, uint16_t port, int connid) -{ - - ti_common_t *ti_common; - CCM_ID cc_index; - - CCSIP_DEBUG_TASK(DEB_F_PREFIX"addr 0x%x port %d connid %d\n", - DEB_F_PREFIX_ARGS(SIP_TRANS, "sipTransportClearServerHandle"), ipaddr, port, connid); - for (cc_index = PRIMARY_CCM; cc_index < MAX_CCM; cc_index++) { - ti_common = &CCM_Device_Specific_Config_Table[cc_index].ti_common; - if (util_compare_ip(&(ti_common->addr),ipaddr) && ti_common->port == port) { - sip_tcp_purge_entry(connid); - ti_common->handle = INVALID_SOCKET; - ti_common->listen_port = 0; - return; - } - } -} - -/* - ** sipTransportSetServerHandleAndPort - * - * FILENAME: ip_phone\sip\sip_common_transport.c - * - * PARAMETERS: Line id - * - * DESCRIPTION: This function gets the server handle for a particular - * line id. - * - * RETURNS: The server handle - */ -void -sipTransportSetServerHandleAndPort (cpr_socket_t socket_handle, - uint16_t listen_port, - ti_config_table_t *ccm_table_entry) -{ - ti_common_t *ti_common; - ti_ccm_t *ti_ccm; - - ti_ccm = &ccm_table_entry->ti_specific.ti_ccm; - - if (ti_ccm->ccm_id < MAX_CCM) { - ti_common = &CCM_Device_Specific_Config_Table[ti_ccm->ccm_id].ti_common; - ti_common->handle = socket_handle; - ti_common->listen_port = listen_port; - } -} - -void -sipTransportSetSIPServer() { - char addr_str[MAX_IPADDR_STR_LEN]; - init_empty_str(addr_str); - config_get_string(CFGID_CCM1_ADDRESS, addr_str, MAX_IPADDR_STR_LEN); - sstrncpy(CCM_Config_Table[0][0]->ti_common.addr_str, addr_str, MAX_IPADDR_STR_LEN); - sstrncpy(CCM_Device_Specific_Config_Table[PRIMARY_CCM].ti_common.addr_str, addr_str, MAX_IPADDR_STR_LEN); -} diff --git a/libs/sipcc/core/sipstack/sip_csps_transport.c b/libs/sipcc/core/sipstack/sip_csps_transport.c deleted file mode 100644 index 9982ab3cb8..0000000000 --- a/libs/sipcc/core/sipstack/sip_csps_transport.c +++ /dev/null @@ -1,206 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_in.h" -#include "cpr_types.h" -#include "phone_types.h" -#include "cpr_string.h" -#include "cpr_socket.h" -#include "ccsip_platform.h" -#include "sip_common_transport.h" -#include "sip_csps_transport.h" -#include "util_string.h" - -int -sip_dns_gethostbysrv (char *domain, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port, - srv_handle_t *psrv_order, - boolean retried_addr) -{ - int bLoopDeath = 0; - uint16_t tmp_port = 0; - int rc=DNS_ERR_NOHOST; - - while (!bLoopDeath) { - /* Try and fetch a proxy using DNS SRV records */ - rc = dnsGetHostBySRV("sip", "udp", (char *) domain, ipaddr_ptr, - &tmp_port, 100, 1, psrv_order); - switch (rc) { - case DNS_ERR_TTL_EXPIRED: - case DNS_ERR_NOHOST: - /* Re-try if all entries for this proxy have expired - * or the end of the call record list was reached. - */ - break; - default: - /* Run don't walk to the nearest exit */ - bLoopDeath = 1; - break; - } - } - if (tmp_port) { - *port = tmp_port; - } - return rc; -} - -int -sip_dns_gethostbysrvorname (char *hname, - cpr_ip_addr_t *ipaddr_ptr, - uint16_t *port) -{ - /* - * OK according to rfc2543bis-03 - * 1. If the destination is an IP address it is used. If no port is - * specified then use 5060 - * 2. If the destination specifies the default port (5060) or no port - * then try SRV - * 3. If the destination specifies a port number other than 5060 or - * there are no SRV records A record lookup - */ - srv_handle_t srv_order = NULL; - int rc=DNS_ERR_NOHOST; - - if ((*port == SIP_WELL_KNOWN_PORT) || (*port == 0)) { - rc = sip_dns_gethostbysrv(hname, ipaddr_ptr, port, &srv_order, FALSE); - } - if (rc != DNS_OK) { - rc = dnsGetHostByName(hname, ipaddr_ptr, 100, 1); - } - if (srv_order) { - dnsFreeSrvHandle(srv_order); - } - return rc; -} - -cpr_socket_t -sipTransportCSPSGetProxyHandleByDN (line_t dn) -{ - static const char *fname = "sipTransportCSPSGetProxyHandleByDN"; - ti_common_t *ti_common; - - if ((((int)dn) < 1) || (((int)dn) > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN %d out of " - "bounds.\n", fname, dn); - return INVALID_SOCKET; - } - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - return ((cpr_socket_t) ti_common->handle); -} - -short -sipTransportCSPSGetProxyPortByDN (line_t dn) -{ - static const char *fname = "sipTransportCSPSGetProxyPortByDN"; - ti_common_t *ti_common; - - if ((((int)dn) < 1) || (((int)dn) > MAX_REG_LINES)) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN %d out of " - "bounds.\n", fname, dn); - return (-1); - } - ti_common = &CSPS_Config_Table[dn - 1].ti_common; - return ((short) ti_common->port); -} - -// This function is broken -uint16_t -sipTransportCSPSGetProxyAddressByDN(cpr_ip_addr_t *ip_addr, line_t dn) -{ -// static const char *fname = "sipTransportCSPSGetProxyAddressByDN"; -// ti_common_t *ti_common; -// -// if ((((int)dn) < 1) || (((int)dn) > MAX_REG_LINES)) { -// CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Args check: DN out of " -// "bounds.\n", fname, dn); -// return (0); -// } -// -// ti_common = &CSPS_Config_Table[dn - 1].ti_common; -// -// ip_addr = &(ti_common->addr); -// - return(1); -} - -/* - * sip_config_get_proxy_port() - * - * Get table entry from the table string and option number - */ -uint16_t -sip_config_get_proxy_port (line_t line) -{ - uint32_t port; - - config_get_line_value(CFGID_PROXY_PORT, &port, sizeof(port), line); - - if (port == 0) { - config_get_line_value(CFGID_PROXY_PORT, &port, sizeof(port), DEFAULT_LINE); - } - - return ((uint16_t) port); -} - -/* - * sip_config_get_proxy_addr() - * - * Get table entry from the table string and option number - */ -void -sip_config_get_proxy_addr (line_t line, char *buffer, int buffer_len) -{ - config_get_line_string(CFGID_PROXY_ADDRESS, buffer, line, buffer_len); - - if ((strcmp(buffer, UNPROVISIONED) == 0) || (buffer[0] == '\0')) { - config_get_line_string(CFGID_PROXY_ADDRESS, buffer, DEFAULT_LINE, - buffer_len); - } -} - -/* - * sip_config_get_backup_proxy_addr() - * - * Get table entry from the table string and option number - */ -uint16_t -sip_config_get_backup_proxy_addr (cpr_ip_addr_t *IPAddress, char *buffer, int buffer_len) -{ - - *IPAddress = ip_addr_invalid; - - config_get_string(CFGID_PROXY_BACKUP, buffer, buffer_len); - - if ((cpr_strcasecmp(buffer, UNPROVISIONED) == 0) || (buffer[0] == 0)) { - buffer[0] = 0; - } else { - (void) str2ip(buffer, IPAddress); - } - return (1); -} - -/* - * sipTransportCSPSClearProxyHandle - * - * Clear Proxy handle from the table - */ -void -sipTransportCSPSClearProxyHandle (cpr_ip_addr_t *ipaddr, - uint16_t port, - cpr_socket_t this_fd) -{ - ti_common_t *ti_common; - int i; - - for (i = 0; i < MAX_REG_LINES; i++) { - ti_common = &CSPS_Config_Table[i].ti_common; - if ((ti_common->port == port) && - util_compare_ip(&(ti_common->addr),ipaddr) && - (ti_common->handle == this_fd)) { - ti_common->handle = INVALID_SOCKET; - return; - } - } -} diff --git a/libs/sipcc/core/sipstack/sip_interface_regmgr.c b/libs/sipcc/core/sipstack/sip_interface_regmgr.c deleted file mode 100644 index 952cc806d6..0000000000 --- a/libs/sipcc/core/sipstack/sip_interface_regmgr.c +++ /dev/null @@ -1,313 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdio.h" -#include "cpr_string.h" -#include "cpr_memory.h" -#include "ccsip_task.h" -#include "debug.h" -#include "phone_debug.h" -#include "phntask.h" -#include "phone.h" -#include "text_strings.h" -#include "string_lib.h" -#include "gsm.h" -#include "sip_common_transport.h" -#include "sip_common_regmgr.h" -#include "sip_interface_regmgr.h" -#include "ccsip_subsmanager.h" -#include "platform_api.h" - -extern ccm_act_stdby_table_t CCM_Active_Standby_Table; -extern cc_config_table_t CC_Config_Table[]; - -/* - ** sip_regmgr_send_status - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: msg id and the src task id. - * - * DESCRIPTION: Posts the message to the destination task as - * requested. - * - * RETURNS: - * - */ -void -sip_regmgr_send_status (reg_srcs_t src_id, reg_status_t msg_id) -{ - static const char fname[] = "sip_regmgr_send_status"; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"src_id: %d msg_id: %d", DEB_F_PREFIX_ARGS(SIP_REG, fname), src_id, msg_id); - - if (msg_id == REG_ALL_FAIL) { - //All failed ind to platform - ui_reg_all_failed(); - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"REG ALL FAILED \n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - } - return; -} - -/* - ** sip_regmgr_get_cc_mode - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETER: line number for which mode is requested. Initially - * for the ccm it will be same for all linesm, but - * will change when mixed mode support is added. - * DESCRIPTION: returns the current mode the phone is in i.e. - * talking to a ccm -or- not talking to a ccm. - * - * RETURNS: - * - */ -reg_mode_t -sip_regmgr_get_cc_mode (line_t line) -{ - if (CCM_Active_Standby_Table.active_ccm_entry) { - return (REG_MODE_CCM); - } else { - return (REG_MODE_NON_CCM); - } -} - - -boolean -sip_platform_is_phone_idle (void) -{ - if (gsm_is_idle()) { - return (TRUE); - } - return (FALSE); -} - -/* - ** sip_platform_fallback_ind - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * - * RETURNS: - * - */ -void -sip_platform_fallback_ind (CCM_ID ccm_id) -{ - static const char fname[] = "sip_platform_fallback_ind"; - int from_id = CC_TYPE_CCM; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"ccm-id: %d", DEB_F_PREFIX_ARGS(SIP_FALLBACK, fname), ccm_id); - - platform_reg_fallback_ind((void *)(long) from_id); -} - -/* - ** sip_platform_failover_ind - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -boolean plat_is_network_interface_changed(void ); -void -sip_platform_failover_ind (CCM_ID ccm_id) -{ - static const char fname[] = "sip_platform_failover_ind"; - int to_id = CC_TYPE_CCM; - - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"ccm-id=%s=%d", DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname), - ccm_id == PRIMARY_CCM ? "PRIMARY_CCM" : - ccm_id == SECONDARY_CCM ? "SECONDARY_CCM" : - ccm_id == TERTIARY_CCM ? "TERTIARY_CCM" : "Unknown", - ccm_id); - - if (plat_is_network_interface_changed()) { - CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"network i/f changed, sending REG_ALL_FAIL instead", DEB_F_PREFIX_ARGS(SIP_FAILOVER, fname)); - ui_reg_all_failed(); - return; - } - - if (ccm_id == UNUSED_PARAM){ - to_id = 3; - } - platform_reg_failover_ind((void *)(long) to_id); -} - -/* - ** sip_platform_logout_reset_req - * - * FILENAME: ip_phone\sip\sip_platform_logout_reset_req - * - * PARAMETERS: void - * - * DESCRIPTION: Trigger vPhone auto logout and re-DHCP - * - * RETURNS: none - * - */ -void -sip_platform_logout_reset_req(void) -{ - platform_logout_reset_req(); -} - -/* - ** sip_platform_set_ccm_status - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: - * - * DESCRIPTION: - * - * RETURNS: none - * - */ -void -sip_platform_set_ccm_status (void) -{ - static const char fname[] = "sip_platform_set_ccm_status"; - ti_config_table_t *ccm_table_entry; - char dest_addr_str[MAX_IPADDR_STR_LEN]; - - CCSIP_DEBUG_STATE(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(SIP_REG, fname)); - ccm_table_entry = CCM_Active_Standby_Table.active_ccm_entry; - if (ccm_table_entry) { - sstrncpy(dest_addr_str, ccm_table_entry->ti_common.addr_str, - MAX_IPADDR_STR_LEN); - CCSIP_DEBUG_STATE(DEB_F_PREFIX"addr str1 %s\n", DEB_F_PREFIX_ARGS(SIP_REG, fname), dest_addr_str); - - ui_set_ccm_conn_status(dest_addr_str, CCM_STATUS_ACTIVE); - } - ccm_table_entry = CCM_Active_Standby_Table.standby_ccm_entry; - if (ccm_table_entry) { - - ui_set_ccm_conn_status(ccm_table_entry->ti_common.addr_str, - CCM_STATUS_STANDBY); - } -} - -/* - ** sip_regmgr_get_ccm_id - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: ccb - * - * DESCRIPTION: get ccm id from ccb - * - * RETURNS: ccm id - */ -CCM_ID -sip_regmgr_get_ccm_id (ccsipCCB_t *ccb) -{ - ti_config_table_t *ccm_table_ptr = NULL; - - ccm_table_ptr = (ti_config_table_t *) ccb->cc_cfg_table_entry; - if (ccm_table_ptr) { - return (ccm_table_ptr->ti_specific.ti_ccm.ccm_id); - } - return (UNUSED_PARAM); -} - -/* - ** sip_platform_cc_mode_notify - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETERS: mode - * - * DESCRIPTION: notify cc mode - * - * RETURNS: None - */ -void -sip_platform_cc_mode_notify (void) -{ - int mode; - - if (CC_Config_Table[0].cc_type == CC_CCM) { - mode = REG_MODE_CCM; - } else { - mode = REG_MODE_NON_CCM; - } - platform_cc_mode_notify(mode); -} - -/* - ** sip_regmgr_get_sec_level - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETER: line number for which mode is requested. Initially - * for the ccm it will be same for all linesm, but - * will change when mixed mode support is added. - * DESCRIPTION: returns the current sec level for the phone - * values will be NON-SECURE, AUTHENTICATED and - * ENCRYPTED. - * - * RETURNS: sec level - * - */ -sec_level_t -sip_regmgr_get_sec_level (line_t line) -{ - ti_config_table_t *ccm_table_entry; - ti_ccm_t *ti_ccm; - - if (CCM_Active_Standby_Table.active_ccm_entry) { - ccm_table_entry = CCM_Active_Standby_Table.active_ccm_entry; - ti_ccm = &ccm_table_entry->ti_specific.ti_ccm; - return ((sec_level_t) ti_ccm->sec_level); - } else { - return (NON_SECURE); - } -} - -/* - ** sip_regmgr_srtp_fallback_enabled - * - * FILENAME: ip_phone\sip\sip_interface_regmgr.c - * - * PARAMETER: line number for which mode is requested. Initially - * for the ccm it will be same for all linesm, but - * will change when mixed mode support is added. - * DESCRIPTION: returns whether the SRTP fallback is enabled or not. - * - * RETURNS: sec level - */ -boolean -sip_regmgr_srtp_fallback_enabled (line_t line) -{ - ccsipCCB_t *ccb; - line_t ndx; - - if ((line == 0) || (line > MAX_REG_LINES)) { - /* Invalid Line, requested */ - return 0; - } - - /* Map the (dn)line number to registered CCB */ - ndx = line - 1 + REG_CCB_START; - ccb = sip_sm_get_ccb_by_index(ndx); - if (ccb != NULL) { - if (ccb->supported_tags & cisco_srtp_fallback_tag) { - return (TRUE); - } - } - return (FALSE); -} - diff --git a/libs/sipcc/core/sipstack/sip_platform_task.c b/libs/sipcc/core/sipstack/sip_platform_task.c deleted file mode 100644 index 853ae3de2b..0000000000 --- a/libs/sipcc/core/sipstack/sip_platform_task.c +++ /dev/null @@ -1,654 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include "cpr_rand.h" -#include "cpr_string.h" -#include "cpr_threads.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "sip_platform_task.h" -#include "ccsip_platform_udp.h" -#include "sip_common_transport.h" -#include "phntask.h" -#include "phone_debug.h" -#include "util_string.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_task.h" -#include "sip_socket_api.h" -#include "platform_api.h" - -/*--------------------------------------------------------- - * - * Definitions - * - */ - -/* The maximum number of messages parsed from the message queue at one time */ -#define MAX_SIP_MESSAGES 8 - -/* The maximum number of connections allowed */ -#define MAX_SIP_CONNECTIONS (64 - 2) - -/* SIP Message queue waiting thread and the main thread IPC names */ -#ifdef __ANDROID__ -#define SIP_MSG_IPC_PATH "/data/data/com.cisco.telephony.provider/" -#else -#define SIP_MSG_IPC_PATH "/tmp/" -#endif -#define SIP_MSG_SERV_NAME "SIP-Main-%d" -#define SIP_MSG_CLNT_NAME "SIP-MsgQ-%d" - -#define SIP_PAUSE_WAIT_IPC_LISTEN_READY_TIME 50 /* 50ms. */ -#define SIP_MAX_WAIT_FOR_IPC_LISTEN_READY 1200 /* 50 * 1200 = 1 minutes */ - - -/*--------------------------------------------------------- - * - * Local Variables - * - */ -fd_set read_fds; -fd_set write_fds; -static cpr_socket_t listen_socket = INVALID_SOCKET; -static cpr_socket_t sip_ipc_serv_socket = INVALID_SOCKET; -static cpr_socket_t sip_ipc_clnt_socket = INVALID_SOCKET; -static boolean main_thread_ready = FALSE; -uint32_t nfds = 0; -sip_connection_t sip_conn; - -/* - * Internal message structure between main thread and - * message queue waiting thread. - */ -typedef struct sip_int_msg_t_ { - void *msg; - phn_syshdr_t *syshdr; -} sip_int_msg_t; - -/* Internal message queue (array) */ -static sip_int_msg_t sip_int_msgq_buf[MAX_SIP_MESSAGES] = {{0,0},{0,0}}; - -/* Main thread and message queue waiting thread IPC names */ -static const char *sip_IPC_serv_name = SIP_MSG_IPC_PATH SIP_MSG_SERV_NAME; -static const char *sip_IPC_clnt_name = SIP_MSG_IPC_PATH SIP_MSG_CLNT_NAME; -static cpr_sockaddr_un_t sip_serv_sock_addr; -static cpr_sockaddr_un_t sip_clnt_sock_addr; - - -/*--------------------------------------------------------- - * - * Global Variables - * - */ -extern sipGlobal_t sip; -extern boolean sip_reg_all_failed; - - -/*--------------------------------------------------------- - * - * Function declarations - * - */ -//static void write_to_socket(cpr_socket_t s); -//static int read_socket(cpr_socket_t s); - -/*--------------------------------------------------------- - * - * Functions - * - */ - -/** - * - * sip_platform_task_init - * - * Initialize the SIP Task - * - * Parameters: None - * - * Return Value: None - * - */ -static void -sip_platform_task_init (void) -{ - uint16_t i; - - for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - sip_conn.read[i] = INVALID_SOCKET; - sip_conn.write[i] = INVALID_SOCKET; - } - - /* - * Initialize cprSelect call parameters - */ - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - return; -} - -/** - * sip_create_IPC_sock creates and bind the socket for IPC. - * - * @param[in]name - pointer to the const. character for the - * IPC address (name) to be bound when the - * IPC socket is successfully created. - * - * @return cpr_socket_t - Returns a valid CPR's socket if - * the socket is created sucessafully otherwise - * returns INVALID_SOCKET. - * @pre (name != NULL) - */ -static cpr_socket_t sip_create_IPC_sock (const char *name) -{ - const char *fname = "sip_create_IPC_sock"; - cpr_socket_t sock; - cpr_sockaddr_un_t addr; - - /* Create socket */ - sock = cprSocket(AF_LOCAL, SOCK_DGRAM, 0); - if (sock == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprSocket() returned error" - " errno=%d\n", fname, cpr_errno); - return (INVALID_SOCKET); - } - - /* Bind to the local socket */ - cpr_set_sockun_addr(&addr, name, getpid()); - - /* make sure file doesn't already exist */ - unlink( (char *)addr.sun_path); - - /* do the bind */ - if (cprBind(sock, (cpr_sockaddr_t *)&addr, - cpr_sun_len(addr)) == CPR_FAILURE) { - (void) sipSocketClose(sock, FALSE); - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprBind() failed" - " errno=%d\n", fname, cpr_errno); - return (INVALID_SOCKET); - } - return (sock); -} - -/** - * The function is a thread loop that waits on SIP message queue - * visible for the external components (sip_msgq). The thread is used - * to avoid having the main task loop from having to set a small time - * waiting on select() to poll inter-thread messages. The small waiting - * time on select() to poll internal messages queue increases the - * unnecessary of waking up when system is idle. On the platform that - * power conservative is critical such as handheld phone, waking up - * periodically is not good for battery life. - * - * This thread splits the message queue waiting function from the - * main thread waiting on select(). This thread simply listens on the - * internal message queue and signal to the main thread via IPC socket - * or local socket trigger. Therefore the main thread can uniformly - * process internal message event and the network event via select(). - * The small internal poll time on select() can be - * avoided. - * - * @param[in] arg - pointer to SIP main thread's message queue. - * - * @return None. - * - * @pre (arg != NULL) - */ -void sip_platform_task_msgqwait (void *arg) -{ - const char *fname = "sip_platform_task_msgqwait"; - cprMsgQueue_t *msgq = (cprMsgQueue_t *)arg; - unsigned int wait_main_thread = 0; - phn_syshdr_t *syshdr; - void *msg; - uint8_t num_messages = 0; - uint8_t response = 0; - boolean quit_thread = FALSE; - - if (msgq == NULL) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"task msgq is null, exiting\n", fname); - return; - } - - if (platThreadInit("SIP IPCQ task") != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to attach thread to JVM\n", fname); - return; - } - - /* - * Wait for SIP main thread ready for IPC connection. - */ - while (!main_thread_ready) { - /* Pause for other threads to run while waiting */ - cprSleep(SIP_PAUSE_WAIT_IPC_LISTEN_READY_TIME); - - wait_main_thread++; - if (wait_main_thread > SIP_MAX_WAIT_FOR_IPC_LISTEN_READY) { - /* Exceed the number of wait time */ - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"timeout waiting for listening IPC" - " socket ready, exiting\n", fname); - return; - } - } - - /* - * Adjust relative priority of SIP thread. - */ -#ifndef WIN32 - (void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY); -#else - /* Use default priority */ - (void) cprAdjustRelativeThreadPriority(0); -#endif - - /* - * The main thread is ready. set global client socket address - * so that the server can send back response. - */ - cpr_set_sockun_addr(&sip_clnt_sock_addr, sip_IPC_clnt_name, getpid()); - - sip_ipc_clnt_socket = sip_create_IPC_sock(sip_IPC_clnt_name); - - if (sip_ipc_clnt_socket == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_create_IPC_sock() failed," - " exiting\n", fname); - return; - } - - while (quit_thread == FALSE) { - msg = cprGetMessage(msgq, TRUE, (void **) &syshdr); - while (msg != NULL) { - /* - * There is a message to be forwarded to the main SIP - * thread for processing. - */ - sip_int_msgq_buf[num_messages].msg = msg; - sip_int_msgq_buf[num_messages].syshdr = syshdr; - num_messages++; - - switch (syshdr->Cmd) { - case THREAD_UNLOAD: - quit_thread = TRUE; - break; - default: - break; - } - - if (num_messages == MAX_SIP_MESSAGES) { - /* - * Limit the number of messages passed to the main SIP - * thread to MAX_SIP_MESSAGES since SIP main thread only - * process messages up to MAX_SIP_MESSAGES at a time. - */ - break; - } - /* - * Check to see if there is more message on the queue - * before sending IPC message trigger to the main SIP - * thread. This is to minimize the overhead of the - * the main SIP thread in processing select(). - */ - msg = cprGetMessage(msgq, 0, (void **) &syshdr); - } - - if (num_messages) { - CCSIP_DEBUG_TASK(DEB_F_PREFIX"%d msg available on msgq\n", DEB_F_PREFIX_ARGS(SIP_MSG_QUE, fname), num_messages); - /* - * There are some number of messages sent to the main thread, - * trigger the main SIP thread via IPC to process the message. - */ - if (cprSendTo(sip_ipc_clnt_socket, (void *)&num_messages, - sizeof(num_messages), 0, - (cpr_sockaddr_t *)&sip_serv_sock_addr, - cpr_sun_len(sip_serv_sock_addr)) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"send IPC failed errno=%d\n", fname, cpr_errno); - } - - if (FALSE == quit_thread) { - /* - * Wait for main thread to signal us to get more message. - */ - if (cprRecvFrom(sip_ipc_clnt_socket, &response, - sizeof(response), 0, NULL, NULL) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"read IPC failed:" - " errno=%d\n", fname, cpr_errno); - } - num_messages = 0; - } - } - } -} - -/** - * sip_process_int_msg - process internal IPC message from the - * the message queue waiting thread. - * - * @param - none. - * - * @return none. - */ -static void sip_process_int_msg (void) -{ - const char *fname = "sip_process_int_msg"; - ssize_t rcv_len; - uint8_t num_messages = 0; - uint8_t response = 0; - sip_int_msg_t *int_msg; - void *msg; - phn_syshdr_t *syshdr; - - /* read the msg count from the IPC socket */ - rcv_len = cprRecvFrom(sip_ipc_serv_socket, &num_messages, - sizeof(num_messages), 0, NULL, NULL); - - if (rcv_len < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"read IPC failed:" - " errno=%d\n", fname, cpr_errno); - return; - } - - if (num_messages == 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"message queue is empty!\n", fname); - return; - } - - if (num_messages > MAX_SIP_MESSAGES) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"number of messages on queue exceeds maximum %d\n", fname, - num_messages); - num_messages = MAX_SIP_MESSAGES; - } - - /* process messages */ - int_msg = &sip_int_msgq_buf[0]; - while (num_messages) { - msg = int_msg->msg; - syshdr = int_msg->syshdr; - if (msg != NULL && syshdr != NULL) { - SIPTaskProcessListEvent(syshdr->Cmd, msg, syshdr->Usr.UsrPtr, - syshdr->Len); - cprReleaseSysHeader(syshdr); - - int_msg->msg = NULL; - int_msg->syshdr = NULL; - } - - num_messages--; /* one less message to work on */ - int_msg++; /* advance to the next message */ - } - - /* - * Signal message queue waiting thread to get more messages. - */ - if (cprSendTo(sip_ipc_serv_socket, (void *)&response, - sizeof(response), 0, - (cpr_sockaddr_t *)&sip_clnt_sock_addr, - cpr_sun_len(sip_clnt_sock_addr)) < 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"%d sending IPC\n", fname); - } -} - -/** - * - * sip_platform_task_loop - * - * Run the SIP task - * - * Parameters: arg - SIP message queue - * - * Return Value: None - * - */ -void -sip_platform_task_loop (void *arg) -{ - static const char *fname = "sip_platform_task_loop"; - int pending_operations; - uint16_t i; - fd_set sip_read_fds; - fd_set sip_write_fds; - sip_tcp_conn_t *entry; - - sip_msgq = (cprMsgQueue_t) arg; - if (!sip_msgq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_msgq is null, exiting\n", fname); - return; - } - sip.msgQueue = sip_msgq; - - sip_platform_task_init(); - /* - * Initialize the SIP task - */ - SIPTaskInit(); - - if (platThreadInit("SIPStack Task") != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to attach thread to JVM\n", fname); - return; - } - - /* - * Adjust relative priority of SIP thread. - */ -#ifndef WIN32 - (void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY); -#else - /* Use default priority */ - (void) cprAdjustRelativeThreadPriority(0); -#endif - - /* - * Setup IPC socket addresses for main thread (server) - */ - cpr_set_sockun_addr(&sip_serv_sock_addr, sip_IPC_serv_name, getpid()); - - /* - * Create IPC between the message queue thread and this main - * thread. - */ - sip_ipc_serv_socket = sip_create_IPC_sock(sip_IPC_serv_name); - - if (sip_ipc_serv_socket == INVALID_SOCKET) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_create_IPC_sock() failed:" - " errno=%d\n", fname, cpr_errno); - return; - } - - /* - * On Win32 platform, the random seed is stored per thread; therefore, - * each thread needs to seed the random number. It is recommended by - * MS to do the following to ensure randomness across application - * restarts. - */ - cpr_srand((unsigned int)time(NULL)); - - /* - * Set read IPC socket - */ - sip_platform_task_set_read_socket(sip_ipc_serv_socket); - - /* - * Let the message queue waiting thread know that the main - * thread is ready. - */ - main_thread_ready = TRUE; - - /* - * Main Event Loop - */ - while (TRUE) { - /* - * Wait on events or timeout - */ - sip_read_fds = read_fds; - - // start off by init to zero - FD_ZERO(&sip_write_fds); - // now look for sockets where data has been queued up - for (i = 0; i < MAX_CONNECTIONS; i++) { - entry = sip_tcp_conn_tab + i; - if (-1 != entry->fd && entry->sendQueue && sll_count(entry->sendQueue)) { - FD_SET(entry->fd, &sip_write_fds); - } - } - - pending_operations = cprSelect((nfds + 1), - &sip_read_fds, - &sip_write_fds, - NULL, NULL); - if (pending_operations == SOCKET_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprSelect() failed: errno=%d." - " Recover by initiating sip restart\n", - fname, cpr_errno); - /* - * If we have come here, then either read socket related to - * sip_ipc_serv_socket has got corrupted, or one of the write - * socket related to cucm tcp/tls connection. - * We will recover, by first clearing all fds, then re-establishing - * the connection with sip-msgq by listening on - * sip_ipc_serv_socket. - */ - sip_platform_task_init(); /* this clear FDs */ - sip_platform_task_set_read_socket(sip_ipc_serv_socket); - - /* - * Since all sockets fds have been cleared above, we can not anyway - * send or receive msg from cucm. So, there is no point - * trying to send registration cancel msg to cucm. Also, a - * call may be active, and in that case we do not want to - * un-register. So, by setting sip_reg_all_failed to true, we - * make sure that no registration cancelation attempt is made. - */ - sip_reg_all_failed = TRUE; - platform_reset_req(DEVICE_RESTART); - continue; - } else if (pending_operations) { - /* - * Listen socket is set only if UDP transport has been - * configured. So see if the select return was for read - * on the listen socket. - */ - if ((listen_socket != INVALID_SOCKET) && - (sip.taskInited == TRUE) && - FD_ISSET(listen_socket, &sip_read_fds)) { - sip_platform_udp_read_socket(listen_socket); - pending_operations--; - } - - /* - * Check IPC for internal message queue - */ - if (FD_ISSET(sip_ipc_serv_socket, &sip_read_fds)) { - /* read the message to flush the buffer */ - sip_process_int_msg(); - pending_operations--; - } - - /* - * Check all sockets for stuff to do - */ - for (i = 0; ((i < MAX_SIP_CONNECTIONS) && - (pending_operations > 0)); i++) { - if ((sip_conn.read[i] != INVALID_SOCKET) && - FD_ISSET(sip_conn.read[i], &sip_read_fds)) { - /* - * Assume tcp - */ - sip_tcp_read_socket(sip_conn.read[i]); - pending_operations--; - } - if ((sip_conn.write[i] != INVALID_SOCKET) && - FD_ISSET(sip_conn.write[i], &sip_write_fds)) { - int connid; - - connid = sip_tcp_fd_to_connid(sip_conn.write[i]); - if (connid >= 0) { - sip_tcp_resend(connid); - } - pending_operations--; - } - } - } - } -} - -/** - * - * sip_platform_task_set_listen_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_set_listen_socket (cpr_socket_t s) -{ - listen_socket = s; - sip_platform_task_set_read_socket(s); -} - -/** - * - * sip_platform_task_set_read_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_set_read_socket (cpr_socket_t s) -{ - if (s != INVALID_SOCKET) { - FD_SET(s, &read_fds); - nfds = MAX(nfds, (uint32_t)s); - } -} - -/** - * - * sip_platform_task_reset_listen_socket - * - * Mark the socket as INVALID - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_reset_listen_socket (cpr_socket_t s) -{ - sip_platform_task_clr_read_socket(s); - listen_socket = INVALID_SOCKET; -} - -/** - * - * sip_platform_task_clr_read_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_clr_read_socket (cpr_socket_t s) -{ - if (s != INVALID_SOCKET) { - FD_CLR(s, &read_fds); - } -} - diff --git a/libs/sipcc/core/sipstack/sip_platform_win32_task.c b/libs/sipcc/core/sipstack/sip_platform_win32_task.c deleted file mode 100755 index c9760b1893..0000000000 --- a/libs/sipcc/core/sipstack/sip_platform_win32_task.c +++ /dev/null @@ -1,340 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_ipc.h" -#include "cpr_errno.h" -#include "cpr_socket.h" -#include "cpr_in.h" -#include "cpr_rand.h" -#include "cpr_string.h" -#include "cpr_threads.h" -#include "ccsip_core.h" -#include "ccsip_task.h" -#include "sip_platform_task.h" -#include "ccsip_platform_udp.h" -#include "sip_common_transport.h" -#include "sip_interface_regmgr.h" -#include "phntask.h" -#include "phone_debug.h" -#include "util_string.h" -#include "ccsip_platform_tcp.h" -#include "ccsip_task.h" - -/*--------------------------------------------------------- - * - * Definitions - * - */ - -/* The maximum number of messages parsed from the message queue at one time */ -#define MAX_SIP_MESSAGES 8 - -/* The maximum number of connections allowed */ -#define MAX_SIP_CONNECTIONS (64 - 2) - -/* The socket select waiting time out values */ -#define SIP_SELECT_NORMAL_TIMEOUT 25000 /* normal select timeout in usec*/ -#define SIP_SELECT_QUICK_TIMEOUT 0 /* quick select timeout in usec */ - -/*--------------------------------------------------------- - * - * Local Variables - * - */ -fd_set read_fds; -fd_set write_fds; -static cpr_socket_t listen_socket = INVALID_SOCKET; -uint32_t nfds = 0; -sip_connection_t sip_conn; - - -/*--------------------------------------------------------- - * - * Global Variables - * - */ -extern sipGlobal_t sip; - - -/*--------------------------------------------------------- - * - * Function declarations - * - */ -//static void write_to_socket(cpr_socket_t s); -//static int read_socket(cpr_socket_t s); - - -/*--------------------------------------------------------- - * - * Functions - * - */ - -/** - * - * sip_platform_task_init - * - * Initialize the SIP Task - * - * Parameters: None - * - * Return Value: None - * - */ -static void -sip_platform_task_init (void) -{ - uint16_t i; - - for (i = 0; i < MAX_SIP_CONNECTIONS; i++) { - sip_conn.read[i] = INVALID_SOCKET; - sip_conn.write[i] = INVALID_SOCKET; - } - - /* - * Initialize cprSelect call parameters - */ - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - return; -} - - -/** - * - * sip_platform_task_loop - * - * Run the SIP task - * - * Parameters: arg - SIP message queue - * - * Return Value: None - * - */ -void -sip_platform_task_loop (void *arg) -{ - static const char *fname = "sip_platform_task_loop"; - int pending_operations; - struct cpr_timeval timeout; - void *msg; - uint32_t cmd; - uint16_t len; - void *usr; - phn_syshdr_t *syshdr; - uint16_t i; - fd_set sip_read_fds; -// fd_set sip_write_fds; - - sip_msgq = (cprMsgQueue_t) arg; - if (!sip_msgq) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_msgq is null, exiting\n", fname); - return; - } - sip.msgQueue = sip_msgq; - - sip_platform_task_init(); - /* - * Initialize the SIP task - */ - SIPTaskInit(); - - if (platThreadInit("sip_platform_task_loop") != 0) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to attach thread to JVM\n", fname); - return; - } - - /* - * Adjust relative priority of SIP thread. - */ - (void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY); - - /* - * Set the SIP task timeout at 25 milliseconds - */ - timeout.tv_sec = 0; - timeout.tv_usec = SIP_SELECT_NORMAL_TIMEOUT; - - /* - * On Win32 platform, the random seed is stored per thread; therefore, - * each thread needs to seed the random number. It is recommended by - * MS to do the following to ensure randomness across application - * restarts. - */ - cpr_srand((unsigned int)time(NULL)); - - /* - * Main Event Loop - */ - while (TRUE) { - /* - * Wait on events or timeout - */ - sip_read_fds = read_fds; - -// sip_write_fds = write_fds; - pending_operations = cprSelect((nfds + 1), - &sip_read_fds, - NULL, - NULL, &timeout); - if (pending_operations == SOCKET_ERROR) { - CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprSelect() failed: errno=%d\n", - fname, cpr_errno); - } else if (pending_operations) { - /* - * Listen socket is set only if UDP transport has been - * configured. So see if the select return was for read - * on the listen socket. - */ - if ((listen_socket != INVALID_SOCKET) && - (sip.taskInited == TRUE) && - FD_ISSET(listen_socket, &sip_read_fds)) { - sip_platform_udp_read_socket(listen_socket); - pending_operations--; - } - /* - * Check all sockets for stuff to do - */ - for (i = 0; ((i < MAX_SIP_CONNECTIONS) && - (pending_operations != 0)); i++) { - if ((sip_conn.read[i] != INVALID_SOCKET) && - FD_ISSET(sip_conn.read[i], &sip_read_fds)) { - /* - * Assume tcp - */ - sip_tcp_read_socket(sip_conn.read[i]); - pending_operations--; - } - /* - if ((sip_conn.write[i] != INVALID_SOCKET) && - FD_ISSET(sip_conn.write[i], &sip_write_fds)) { - int connid; - - connid = sip_tcp_fd_to_connid(sip_conn.write[i]); - if (connid >= 0) { - sip_tcp_resend(connid); - } - pending_operations--; - } - */ - } - } - - /* - * Process all messages on the message queue - * (e.g. timer callbacks) - */ - i = 0; - while (i++ < MAX_SIP_MESSAGES) { - msg = cprGetMessage(sip_msgq, FALSE, (void **) &syshdr); - if (msg != NULL) { - cmd = syshdr->Cmd; - len = syshdr->Len; - usr = syshdr->Usr.UsrPtr; - SIPTaskProcessListEvent(cmd, msg, usr, len); - cprReleaseSysHeader(syshdr); - syshdr = NULL; - } else { - /* Stop checking for msgs if the queue is empty */ - if (syshdr != NULL) { - cprReleaseSysHeader(syshdr); - syshdr = NULL; - } - break; - } - } - - /* - * If message servicing loop reaches the maximum loop limit - * it is possible that there are more messages left on the message - * queue. Shorten the socket select time out to come back and - * check the message queue for the message that might be left on - * the queue. - */ - if (i >= MAX_SIP_MESSAGES) { - timeout.tv_usec = SIP_SELECT_QUICK_TIMEOUT; - } else { - /* set normal time out value to poll msg. queue */ - timeout.tv_usec = SIP_SELECT_NORMAL_TIMEOUT; - } - } -} - -/** - * - * sip_platform_task_set_listen_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_set_listen_socket (cpr_socket_t s) -{ - listen_socket = s; - sip_platform_task_set_read_socket(s); -} - -/** - * - * sip_platform_task_set_read_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_set_read_socket (cpr_socket_t s) -{ - if (s != INVALID_SOCKET) { - FD_SET(s, &read_fds); - nfds = MAX(nfds, (uint32_t)s); - } -} - -/** - * - * sip_platform_task_reset_listen_socket - * - * Mark the socket as INVALID - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_reset_listen_socket (cpr_socket_t s) -{ - sip_platform_task_clr_read_socket(s); - listen_socket = INVALID_SOCKET; -} - -/** - * - * sip_platform_task_clr_read_socket - * - * Mark the socket for cpr_select to be read - * - * Parameters: s - the socket - * - * Return Value: None - * - */ -void -sip_platform_task_clr_read_socket (cpr_socket_t s) -{ - if (s != INVALID_SOCKET) { - FD_CLR(s, &read_fds); - } -} - diff --git a/libs/sipcc/core/src-common/configapp.c b/libs/sipcc/core/src-common/configapp.c deleted file mode 100644 index 849a55fe72..0000000000 --- a/libs/sipcc/core/src-common/configapp.c +++ /dev/null @@ -1,145 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "cpr_types.h" -#include "cpr_stdlib.h" -#include "cpr_timers.h" -#include "cpr_strings.h" -#include "ccsip_subsmanager.h" -#include "subapi.h" -#include "debug.h" -#include "phone_debug.h" -#include "phntask.h" - -int32_t g_configappDebug = 1; - -extern void update_kpmlconfig (int kpmlVal); -/* - * Function: configapp_init() - * - * Parameters: none - * - * Description: Register with Subscription manager for any imcoming - * config subscribe messages - * - * Returns: None - */ -void -configapp_init (void) -{ - static const char fname[] = "configapp_init"; - - CONFIGAPP_DEBUG(DEB_F_PREFIX"Subscribing to SUB/NOT manager.\n", - DEB_F_PREFIX_ARGS(CONFIG_APP, fname)); - - (void) sub_int_subnot_register(CC_SRC_MISC_APP, CC_SRC_SIP, - CC_SUBSCRIPTIONS_CONFIGAPP, - NULL, CC_SRC_MISC_APP, - SUB_MSG_CONFIGAPP_SUBSCRIBE, NULL, - SUB_MSG_CONFIGAPP_TERMINATE, 0, 0); - -} - - -/* - * Function: configapp_shutdown() - * - * Parameters: none - * - * Description: Currently a no-op. - * - * Returns: None - */ -void -configapp_shutdown (void) -{ -} - - -/* - * Function: configapp_free_event_data() - * - * Parameters: ccsip_event_data_t* - * - * Description: Frees the event data after the processing is complete - * - * Returns: None - */ -void -configapp_free_event_data (ccsip_event_data_t *data) -{ - ccsip_event_data_t *next_data; - - while(data) { - next_data = data->next; - cpr_free(data); - data = next_data; - } -} - - -/* - * Function: configapp_process_request() - * - * Parameters: ccsip_sub_not_data_t* - * - * Description: Processes the kpml config update request. Invokes the - * jni update_kpmlconfig() so the java side can - * trigger the config - * change and also to initialize the dialplan. - * - * Returns: None - */ - -void -configapp_process_request (ccsip_sub_not_data_t *msg) -{ - static const char fname[] = "configapp_process_request"; - ConfigApp_req_data_t *configdata; - - configdata = &(msg->u.subs_ind_data.eventData->u.configapp_data); - - update_kpmlconfig(configdata->sip_profile.kpml_val); - CONFIGAPP_DEBUG(DEB_F_PREFIX"Updated kpml config value to %d.\n", - DEB_F_PREFIX_ARGS(CONFIG_APP, fname), - configdata->sip_profile.kpml_val); - - (void)sub_int_subscribe_ack(CC_SRC_MISC_APP, CC_SRC_SIP, msg->sub_id, - (uint16_t)SIP_SUCCESS_SETUP, 0); - - (void)sub_int_subscribe_term(msg->sub_id, TRUE, 0, CC_SUBSCRIPTIONS_CONFIGAPP); - configapp_free_event_data(msg->u.subs_ind_data.eventData); - return; -} - - - -/* - * Function: configapp_process_msg() - * - * Parameters: ccsip_sub_not_data_t* - * - * Description: Determines if it is kpmlconfig update request. - * - * Returns: None - */ -void -configapp_process_msg (uint32_t cmd, void *msg) -{ - static const char fname[] = "configapp_process_msg"; - - switch (cmd) { - case SUB_MSG_CONFIGAPP_SUBSCRIBE: - configapp_process_request((ccsip_sub_not_data_t *)msg); - break; - case SUB_MSG_CONFIGAPP_TERMINATE: - break; - default: - CONFIGAPP_DEBUG(DEB_F_PREFIX"Received invalid event.\n", - DEB_F_PREFIX_ARGS(CONFIG_APP, fname)); - break; - } -} - - diff --git a/libs/sipcc/core/src-common/dialplan.c b/libs/sipcc/core/src-common/dialplan.c deleted file mode 100755 index 36b1cd366c..0000000000 --- a/libs/sipcc/core/src-common/dialplan.c +++ /dev/null @@ -1,1207 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include - -#include "cpr_stdio.h" -#include "cpr_stdlib.h" -#include "cpr_string.h" -#include "xml_defs.h" -#include "logger.h" -#include "logmsg.h" -#include "util_parse.h" -#include "debug.h" -#include "phone_types.h" -#include "regmgrapi.h" - - -#include "upgrade.h" -#include "dialplan.h" - -extern char DirectoryBuffer[DIALPLAN_MAX_SIZE]; - -/* - * Tones with Bellcore- are Bellcore defined tones. - * Tones with Cisco- are our tones. - * The order of these names MUST match the order of - * the vcm_tones_t type in vcm.h - */ -const char *tone_names[] = { - "Bellcore-Inside", - "Bellcore-Outside", - "Bellcore-Busy", - "Bellcore-Alerting", - "Bellcore-BusyVerify", - "Bellcore-Stutter", - "Bellcore-MsgWaiting", - "Bellcore-Reorder", - "Bellcore-CallWaiting", - "Bellcore-Cw2", - "Bellcore-Cw3", - "Bellcore-Cw4", - "Bellcore-Hold", - "Bellcore-Confirmation", - "Bellcore-Permanent", - "Bellcore-Reminder", - "Bellcore-None", - "Cisco-ZipZip", - "Cisco-Zip", - "Cisco-BeepBonk" -}; - -static struct DialTemplate *basetemplate; -char DialTemplateFile[MAX_TEMPLATE_LENGTH]; -char g_dp_version_stamp[MAX_DP_VERSION_STAMP_LEN]; - -/* - * Function: addbytes() - * - * Parameters: - * - * Description: - * - * Returns: None - */ -static void -addbytes (char **output, int *outlen, const char *input, int inlen) -{ - char *target = *output; - - if (inlen == -1) { - inlen = strlen(input); - } - if (inlen >= *outlen) { - inlen = *outlen - 1; - } - memcpy(target, input, inlen); - target += inlen; - *outlen += inlen; - *output = target; - /* - * Null terminate the result - */ - *target = '\0'; -} - -/* - * Function: poundDialingEnabled() - * - * Parameters: None - * - * Description: Determines if '#' is treated as a "dial now" character - * - * Returns: TRUE if # is treated as end of dial signal - * FALSE if # is treated as a dialed digit - */ -static boolean -poundDialingEnabled (void) -{ - if (sip_regmgr_get_cc_mode(1) == REG_MODE_NON_CCM) { - /* - * Operating in Peer-to-Peer SIP mode, allow # dialing - */ - return (TRUE); - } else { - return (FALSE); - } -} - -/* - * Function: isDialedDigit() - * - * Parameters: input - single char - * - * Description: Determine if the char is 0-9 or +, * - * # is matched here unless it is set to - * be used as "dial immediately" - * - * Returns: DialMatchAction - */ -boolean -isDialedDigit (char input) -{ - boolean result = FALSE; - - if (!isdigit(input)) { - if ((input == '*') || (input == '+') || ((input == '#') && (!poundDialingEnabled()))) { - result = TRUE; - } - } else { - result = TRUE; - } - - return (result); -} - -/* - * Function: MatchLineNumber() - * - * Parameters: templateLine - line number specified in Dial Plan - * line - line number to match - * - * Description: The template line numbers are initialized to zero. - * Zero means that all lines match. If the Line parm - * is specified in the Dial Plan template, then its - * value must match the specified line. - *^M - * Returns: boolean - */ -static boolean -MatchLineNumber (const line_t templateLine, const line_t line) -{ - /* Zero in the template matches any line. */ - return (boolean) ((templateLine == line) || (templateLine == 0)); -} - -/* - * Function: MatchDialTemplate() - * - * Parameters: pattern - pattern string to match - * line - line number to match - * (May be 0 to match all lines) - * timeout - returned dial timeout in seconds - * (May be NULL to not get a timeout) - * rewrite - buffer to hold rewritten string - * (May be NULL for no rewrite) - * rewritelen - Bytes available in the buffer to write to - * routemode - pointer to location to hold route mode returned - * (May be NULL to not get a routemode) - * tone - pointer to location to hold tone returned - * - * Description: Find the best template to match a pattern - * - * Returns: DialMatchAction - */ -DialMatchAction -MatchDialTemplate (const char *pattern, - const line_t line, - int *timeout, - char *rewrite, - int rewritelen, - RouteMode *pRouteMode, - vcm_tones_t *pTone) -{ - DialMatchAction result = DIAL_NOMATCH; - struct DialTemplate *ptempl = basetemplate; - struct DialTemplate *pbestmatch = NULL; - boolean bestmatch_dialnow = FALSE; - int best_comma_count = 0; - DialMatchAction partialmatch_type = DIAL_NOMATCH; - boolean partialmatch = FALSE; - - int matchlen = 0; - int partialmatchlen = 0; - int givedialtone = 0; - int comma_counter = 0; - - /* - * We need to provide a default rewrite string in case we do not have any template matches. - * This happens when there is no template match (such as no * pattern) and when they have - * no dial plan file at all - */ - if (rewrite != NULL) { - char *output = rewrite; - int room = rewritelen; - - addbytes(&output, &room, pattern, -1); - } - - /* - * If the dialplan is empty, check to see if a # is in the pattern - * and return DIAL_IMMEDIATELY. If not go ahead and return - * DIAL_NOMATCH since there will be no template match in - * an empty dialplan. - */ - if (ptempl == NULL) { - if (strchr(pattern, '#') && (poundDialingEnabled())) { - return DIAL_IMMEDIATELY; - } else { - return DIAL_NOMATCH; - } - } - - /* - * Iterate through all the templates. Skip the this template if it's not - * for this line or all lines. - */ - while (ptempl != NULL) { - if (MatchLineNumber(ptempl->line, line)) { - char *pinput = (char *) pattern; - char *pmatch = ptempl->pattern; - int thismatchlen = 0; - DialMatchAction thismatch = DIAL_FULLMATCH; - char *subs[MAX_SUBTITUTIONS]; - int subslen[MAX_SUBTITUTIONS]; - int subscount = -1; - boolean dialnow = FALSE; - - while (*pinput) { - int idx; - - /* Since the code below combines multiple , - * in a row into "one" , only increment - * comma counter once instead of once - * for each comma combined. - */ - if (pmatch[0] == ',') { - comma_counter++; - } - - /* - * Skip over any dial tone characters - */ - while (pmatch[0] == ',') { - pmatch++; - } - /* - * If this is a pattern character, we need to capture the digits for the - * substitution strings - */ - if (((pmatch[0] == '.') && isDialedDigit(pinput[0])) || - (pmatch[0] == '*')) { - /* - * Get the next index in the substitution array (if any) - * Note that if they have more pattern sections in the pattern string - * the last one will get the counts for the characters. So for example - * with the MAX_SUBSTITUTIONS of 5 and a pattern of - * 1.2.3.4.5.6.7. - * and an input string of - * 1a2b3c4d5e6f7g - * the arrays of substitions would come out as follows: - * %0 = 1a2b3c4d5e6f7g (as expected) - * %1 = a (as expected) - * %2 = b (as expected) - * %3 = c (as expected) - * %4 = d (as expected) - * %5 = e6f NOT what they really wanted, but predictable from the algorithm - */ - if (subscount < (MAX_SUBTITUTIONS - 1)) { - subscount++; - subs[subscount] = pinput; - subslen[subscount] = 1; - } - if (pmatch[0] == '.') { - thismatch = DIAL_FULLPATTERN; - /* - * . in the pattern will match anything but doesn't contribute - * to our matching length for finding the best template - */ - while (isdigit(pinput[1]) && (pmatch[1] == '.')) { - pinput++; - pmatch++; - subslen[subscount]++; - } - } else { - thismatch = DIAL_WILDPATTERN; - /* - * '*' is a wild card to match 1 or more characters - * Do a hungry first match - * - * Note: If match is currently pointing to an escape character, - * we need to go past it to match the actual character. - */ - if (pmatch[1] == DIAL_ESCAPE) { - idx = 2; - } else { - idx = 1; - } - - /* - * The '*' will not match the '#' character since its' default use - * causes the phone to "dial immediately" - */ - if ((pinput[0] == '#') && (poundDialingEnabled())) { - dialnow = TRUE; - } else { - while ((pinput[1] != '\0') && - (pinput[1] != pmatch[idx])) { - /* - * If '#' is found and pound dialing is enabled, break out of the loop. - */ - if ((pinput[1] == '#') && - (poundDialingEnabled())) { - break; - } - pinput++; - subslen[subscount]++; - } - } - } - /* - * Any other character must match exactly - */ - } else { - /* - * Look for the Escape character '\' and remove it - * Right now, the only character that needs to be escaped is '*' - * Note that we treat \ at the end of a line as a non-special - * character - */ - if ((pmatch[0] == DIAL_ESCAPE) && (pmatch[1] != '\0')) { - pmatch++; - } - - if (pmatch[0] != pinput[0]) { - /* - * We found a '#' that doesn't match the current match template - * This means that the '#" should be interpreted as the dial - * termination character. - */ - if ((pinput[0] == '#') && (poundDialingEnabled())) { - dialnow = TRUE; - break; - } - /* - * No match, so abandon with no pattern to select - */ - thismatchlen = -1; - thismatch = DIAL_NOMATCH; - break; - - } else { - /* - * We matched one character, count it for the overall template match - */ - thismatchlen++; - } - } - pmatch++; - pinput++; - } - - /* - * *pinput = NULL means we matched everything that - * was dialed in this template - * Partial never matches * rules - * Since 97. should have precendence over 9.. - * also check matchlen. - * Since fullmatches (exact digits) have precendence - * over fullpattern (.) check matchtype - */ - if ((*pinput == NUL) || (dialnow)) { - if ((thismatchlen > partialmatchlen) || - ((thismatchlen == partialmatchlen) && - (thismatch > partialmatch_type))) { - partialmatch_type = thismatch; - partialmatchlen = thismatchlen; - pbestmatch = ptempl; - partialmatch = TRUE; - bestmatch_dialnow = dialnow; - best_comma_count = comma_counter; - result = DIAL_NOMATCH; - } - } - - /* - * If we exhausted the match string, then the template is a perfect match - * However, we don't want to take this as the best template unless it matched - * more digits than any other pattern. For example if we have a pattern of - * 9011* - * 9.11 - * We would want 9011 to match against the first one even though it is not complete - * - * We also have to be careful that a pattern such as - * * - * does not beat something like - * 9....... - * when you have 94694210 - */ - if (pmatch[0] == '\0') { - /* - * If this pattern is better, we want to adopt it - */ - if ((thismatchlen > matchlen) || - ((thismatchlen == matchlen) && (thismatch > result)) || - ((thismatch == DIAL_WILDPATTERN) && - ((result == DIAL_NOMATCH) && (partialmatch == FALSE)))) { - /* - * this is a better match than what we found before - */ - pbestmatch = ptempl; - bestmatch_dialnow = dialnow; - matchlen = thismatchlen; - result = thismatch; - /* - * Generate a rewrite string - * - *