Merge branch 'fsorig'

Conflicts:
	libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c
	libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
This commit is contained in:
David Yat Sin
2012-04-03 18:08:49 -04:00
940 changed files with 118344 additions and 11720 deletions
@@ -0,0 +1,95 @@
<profile name="external">
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!-- This profile is only for outbound registrations to providers -->
<gateways>
<X-PRE-PROCESS cmd="include" data="external/*.xml"/>
</gateways>
<aliases>
<!--
<alias name="outbound"/>
<alias name="nat"/>
-->
</aliases>
<domains>
<domain name="all" alias="false" parse="true"/>
</domains>
<settings>
<param name="debug" value="0"/>
<!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
<!-- <param name="shutdown-on-fail" value="true"/> -->
<param name="sip-trace" value="no"/>
<param name="sip-capture" value="no"/>
<param name="rfc2833-pt" value="101"/>
<!-- RFC 5626 : Send reg-id and sip.instance -->
<!--<param name="enable-rfc-5626" value="true"/> -->
<param name="sip-port" value="$${external_sip_port}"/>
<param name="dialplan" value="XML"/>
<param name="context" value="public"/>
<param name="dtmf-duration" value="2000"/>
<param name="inbound-codec-prefs" value="$${global_codec_prefs}"/>
<param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/>
<param name="hold-music" value="$${hold_music}"/>
<param name="rtp-timer-name" value="soft"/>
<!--<param name="enable-100rel" value="true"/>-->
<!--<param name="disable-srv503" value="true"/>-->
<!-- This could be set to "passive" -->
<param name="local-network-acl" value="localnet.auto"/>
<param name="manage-presence" value="false"/>
<!-- used to share presence info across sofia profiles
manage-presence needs to be set to passive on this profile
if you want it to behave as if it were the internal profile
for presence.
-->
<!-- Name of the db to use for this profile -->
<!--<param name="dbname" value="share_presence"/>-->
<!--<param name="presence-hosts" value="$${domain}"/>-->
<!--<param name="force-register-domain" value="$${domain}"/>-->
<!--all inbound reg will stored in the db using this domain -->
<!--<param name="force-register-db-domain" value="$${domain}"/>-->
<!-- ************************************************* -->
<!--<param name="aggressive-nat-detection" value="true"/>-->
<param name="inbound-codec-negotiation" value="generous"/>
<param name="nonce-ttl" value="60"/>
<param name="auth-calls" value="false"/>
<!--
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
-->
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="auto-nat"/>
<param name="ext-sip-ip" value="auto-nat"/>
<param name="rtp-timeout-sec" value="300"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<!--<param name="enable-3pcc" value="true"/>-->
<!-- TLS: disabled by default, set to "true" to enable -->
<param name="tls" value="$${external_ssl_enable}"/>
<!-- Set to true to not bind on the normal sip-port but only on the TLS port -->
<param name="tls-only" value="false"/>
<!-- additional bind parameters for TLS -->
<param name="tls-bind-params" value="transport=tls"/>
<!-- Port to listen on for TLS requests. (5081 will be used if unspecified) -->
<param name="tls-sip-port" value="$${external_tls_port}"/>
<!-- Location of the agent.pem and cafile.pem ssl certificates (needed for TLS server) -->
<param name="tls-cert-dir" value="$${external_ssl_dir}"/>
<!-- Optionally set the passphrase password used by openSSL to encrypt/decrypt TLS private key files -->
<param name="tls-passphrase" value=""/>
<!-- Verify the date on TLS certificates -->
<param name="tls-verify-date" value="true"/>
<!-- TLS verify policy, when registering/inviting gateways with other servers (outbound) or handling inbound registration/invite requests how should we verify their certificate -->
<!-- set to 'in' to only verify incoming connections, 'out' to only verify outgoing connections, 'all' to verify all connections, also 'in_subjects', 'out_subjects' and 'all_subjects' for subject validation. Multiple policies can be split with a '|' pipe -->
<param name="tls-verify-policy" value="none"/>
<!-- Certificate max verify depth to use for validating peer TLS certificates when the verify policy is not none -->
<param name="tls-verify-depth" value="2"/>
<!-- If the tls-verify-policy is set to subjects_all or subjects_in this sets which subjects are allowed, multiple subjects can be split with a '|' pipe -->
<param name="tls-verify-in-subjects" value=""/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
</settings>
</profile>
@@ -0,0 +1,38 @@
<include>
<!--<gateway name="asterlink.com">-->
<!--/// account username *required* ///-->
<!--<param name="username" value="cluecon"/>-->
<!--/// auth realm: *optional* same as gateway name, if blank ///-->
<!--<param name="realm" value="asterlink.com"/>-->
<!--/// username to use in from: *optional* same as username, if blank ///-->
<!--<param name="from-user" value="cluecon"/>-->
<!--/// domain to use in from: *optional* same as realm, if blank ///-->
<!--<param name="from-domain" value="asterlink.com"/>-->
<!--/// account password *required* ///-->
<!--<param name="password" value="2007"/>-->
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<!--<param name="extension" value="cluecon"/>-->
<!--/// proxy host: *optional* same as realm, if blank ///-->
<!--<param name="proxy" value="asterlink.com"/>-->
<!--/// send register to this proxy: *optional* same as proxy, if blank ///-->
<!--<param name="register-proxy" value="mysbc.com"/>-->
<!--/// expire in seconds: *optional* 3600, if blank ///-->
<!--<param name="expire-seconds" value="60"/>-->
<!--/// do not register ///-->
<!--<param name="register" value="false"/>-->
<!-- which transport to use for register -->
<!--<param name="register-transport" value="udp"/>-->
<!--How many seconds before a retry when a failure or timeout occurs -->
<!--<param name="retry-seconds" value="30"/>-->
<!--Use the callerid of an inbound call in the from field on outbound calls via this gateway -->
<!--<param name="caller-id-in-from" value="false"/>-->
<!--extra sip params to send in the contact-->
<!--<param name="contact-params" value="tport=tcp"/>-->
<!--send an options ping every x seconds, failure will unregister and/or mark it down-->
<!--<param name="ping" value="25"/>-->
<!--</gateway>-->
<!--rfc5626 : Abilitazione rfc5626 ///-->
<!--<param name="rfc-5626" value="true"/>-->
<!--rfc5626 : extra sip params to send in the contact-->
<!--<param name="reg-id" value="1"/>-->
</include>
@@ -0,0 +1,130 @@
<profile name="internal-ipv6">
<!--
This is an example of a sofia profile setup to listen on IPv6.
-->
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!--aliases are other names that will work as a valid profile name for this profile-->
<settings>
<!-- <param name="user-agent-string" value="FreeSWITCH Rocks!"/> -->
<param name="debug" value="0"/>
<param name="sip-trace" value="no"/>
<param name="context" value="public"/>
<param name="rfc2833-pt" value="101"/>
<!-- port to bind to for sip traffic -->
<param name="sip-port" value="$${internal_sip_port}"/>
<param name="dialplan" value="XML"/>
<param name="dtmf-duration" value="2000"/>
<param name="inbound-codec-prefs" value="$${global_codec_prefs}"/>
<param name="outbound-codec-prefs" value="$${global_codec_prefs}"/>
<param name="use-rtp-timer" value="true"/>
<param name="rtp-timer-name" value="soft"/>
<!-- ip address to use for rtp -->
<param name="rtp-ip" value="$${local_ip_v6}"/>
<!-- ip address to bind to -->
<param name="sip-ip" value="$${local_ip_v6}"/>
<param name="hold-music" value="$${hold_music}"/>
<!--<param name="enable-100rel" value="false"/>-->
<!--<param name="disable-srv503" value="true"/>-->
<param name="apply-inbound-acl" value="domains"/>
<!--<param name="apply-register-acl" value="domains"/>-->
<!--<param name="dtmf-type" value="info"/>-->
<param name="record-template" value="$${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
<!--enable to use presence and mwi -->
<param name="manage-presence" value="true"/>
<!-- This setting is for AAL2 bitpacking on G726 -->
<!-- <param name="bitpacking" value="aal2"/> -->
<!--max number of open dialogs in proceeding -->
<!--<param name="max-proceeding" value="1000"/>-->
<!--session timers for all call to expire after the specified seconds -->
<!--<param name="session-timeout" value="1800"/>-->
<!--<param name="multiple-registrations" value="true"/>-->
<!--set to 'greedy' if you want your codec list to take precedence -->
<param name="inbound-codec-negotiation" value="generous"/>
<!-- if you want to send any special bind params of your own -->
<!--<param name="bind-params" value="transport=udp"/>-->
<!--<param name="unregister-on-options-fail" value="true"/>-->
<!-- TLS: disabled by default, set to "true" to enable -->
<param name="tls" value="$${internal_ssl_enable}"/>
<!-- additional bind parameters for TLS -->
<param name="tls-bind-params" value="transport=tls"/>
<!-- Port to listen on for TLS requests. (5061 will be used if unspecified) -->
<param name="tls-sip-port" value="$${internal_tls_port}"/>
<!-- Location of the agent.pem and cafile.pem ssl certificates (needed for TLS server) -->
<param name="tls-cert-dir" value="$${internal_ssl_dir}"/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<!--If you don't want to pass through timestampes from 1 RTP call to another (on a per call basis with rtp_rewrite_timestamps chanvar)-->
<!--<param name="rtp-rewrite-timestamps" value="true"/>-->
<!--<param name="pass-rfc2833" value="true"/>-->
<!--If you have ODBC support and a working dsn you can use it instead of SQLite-->
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
<!--Uncomment to set all inbound calls to no media mode-->
<!--<param name="inbound-bypass-media" value="true"/>-->
<!--Uncomment to set all inbound calls to proxy media mode-->
<!--<param name="inbound-proxy-media" value="true"/>-->
<!--Uncomment to let calls hit the dialplan *before* you decide if the codec is ok-->
<!--<param name="inbound-late-negotiation" value="true"/>-->
<!-- this lets anything register -->
<!-- comment the next line and uncomment one or both of the other 2 lines for call authentication -->
<!-- <param name="accept-blind-reg" value="true"/> -->
<!-- accept any authentication without actually checking (not a good feature for most people) -->
<!-- <param name="accept-blind-auth" value="true"/> -->
<!-- suppress CNG on this profile or per call with the 'suppress_cng' variable -->
<!-- <param name="suppress-cng" value="true"/> -->
<!--TTL for nonce in sip auth-->
<param name="nonce-ttl" value="60"/>
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--<param name="disable-transcoding" value="true"/>-->
<!-- Used for when phones respond to a challenged ACK with method INVITE in the hash -->
<!--<param name="NDLB-broken-auth-hash" value="true"/>-->
<!-- add a ;received="<ip>:<port>" to the contact when replying to register for nat handling -->
<!--<param name="NDLB-received-in-nat-reg-contact" value="true"/>-->
<param name="auth-calls" value="$${internal_auth_calls}"/>
<!-- on authed calls, authenticate *all* the packets not just invite -->
<param name="auth-all-packets" value="false"/>
<!-- <param name="ext-rtp-ip" value="$${external_rtp_ip}"/> -->
<!-- <param name="ext-sip-ip" value="$${external_sip_ip}"/> -->
<!-- rtp inactivity timeout -->
<param name="rtp-timeout-sec" value="300"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<!-- VAD choose one (out is a good choice); -->
<!-- <param name="vad" value="in"/> -->
<!-- <param name="vad" value="out"/> -->
<!-- <param name="vad" value="both"/> -->
<!--<param name="alias" value="sip:10.0.1.251:5555"/>-->
<!--
These are enabled to make the default config work better out of the box.
If you need more than ONE domain you'll need to not use these options.
-->
<!--all inbound reg will look in this domain for the users -->
<param name="force-register-domain" value="$${domain}"/>
<!--all inbound reg will stored in the db using this domain -->
<param name="force-register-db-domain" value="$${domain}"/>
<!-- disable register and transfer which may be undesirable in a public switch -->
<!--<param name="disable-transfer" value="true"/>-->
<!--<param name="disable-register" value="true"/>-->
<!--<param name="enable-3pcc" value="true"/>-->
<!-- use stun when specified (default is true) -->
<!--<param name="stun-enabled" value="true"/>-->
<!-- use stun when specified (default is true) -->
<!-- set to true to have the profile determine stun is not useful and turn it off globally-->
<!--<param name="stun-auto-disable" value="true"/>-->
<!-- the following can be used as workaround with bogus SRV/NAPTR records -->
<!--<param name="disable-srv" value="false" />-->
<!--<param name="disable-naptr" value="false" />-->
</settings>
</profile>
@@ -0,0 +1,385 @@
<profile name="internal">
<!--
This is a sofia sip profile/user agent. This will service exactly one ip and port.
In FreeSWITCH you can run multiple sip user agents on their own ip and port.
When you hear someone say "sofia profile" this is what they are talking about.
-->
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!--aliases are other names that will work as a valid profile name for this profile-->
<aliases>
<!--
<alias name="default"/>
-->
</aliases>
<!-- Outbound Registrations -->
<gateways>
<X-PRE-PROCESS cmd="include" data="internal/*.xml"/>
</gateways>
<domains>
<!-- indicator to parse the directory for domains with parse="true" to get gateways-->
<!--<domain name="$${domain}" parse="true"/>-->
<!-- indicator to parse the directory for domains with parse="true" to get gateways and alias every domain to this profile -->
<!--<domain name="all" alias="true" parse="true"/>-->
<domain name="all" alias="true" parse="false"/>
</domains>
<settings>
<!--
When calls are in no media this will bring them back to media
when you press the hold button.
-->
<!--<param name="media-option" value="resume-media-on-hold"/> -->
<!--
This will allow a call after an attended transfer go back to
bypass media after an attended transfer.
-->
<!--<param name="media-option" value="bypass-media-after-att-xfer"/>-->
<!-- <param name="user-agent-string" value="FreeSWITCH Rocks!"/> -->
<param name="debug" value="0"/>
<!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
<!-- <param name="shutdown-on-fail" value="true"/> -->
<param name="sip-trace" value="no"/>
<param name="sip-capture" value="no"/>
<!-- Use presence_map.conf.xml to convert extension regex to presence protos for routing -->
<!-- <param name="presence-proto-lookup" value="true"/> -->
<!-- Don't be picky about negotiated DTMF just always offer 2833 and accept both 2833 and INFO -->
<!--<param name="liberal-dtmf" value="true"/>-->
<!--
Sometimes, in extremely rare edge cases, the Sofia SIP stack may stop
responding. These options allow you to enable and control a watchdog
on the Sofia SIP stack so that if it stops responding for the
specified number of milliseconds, it will cause FreeSWITCH to crash
immediately. This is useful if you run in an HA environment and
need to ensure automated recovery from such a condition. Note that if
your server is idle a lot, the watchdog may fire due to not receiving
any SIP messages. Thus, if you expect your system to be idle, you
should leave the watchdog disabled. It can be toggled on and off
through the FreeSWITCH CLI either on an individual profile basis or
globally for all profiles. So, if you run in an HA environment with a
master and slave, you should use the CLI to make sure the watchdog is
only enabled on the master.
If such crash occurs, FreeSWITCH will dump core if allowed. The
stacktrace will include function watchdog_triggered_abort().
-->
<param name="watchdog-enabled" value="no"/>
<param name="watchdog-step-timeout" value="30000"/>
<param name="watchdog-event-timeout" value="30000"/>
<param name="log-auth-failures" value="false"/>
<param name="forward-unsolicited-mwi-notify" value="false"/>
<param name="context" value="public"/>
<param name="rfc2833-pt" value="101"/>
<!-- port to bind to for sip traffic -->
<param name="sip-port" value="$${internal_sip_port}"/>
<param name="dialplan" value="XML"/>
<param name="dtmf-duration" value="2000"/>
<param name="inbound-codec-prefs" value="$${global_codec_prefs}"/>
<param name="outbound-codec-prefs" value="$${global_codec_prefs}"/>
<param name="rtp-timer-name" value="soft"/>
<!-- ip address to use for rtp, DO NOT USE HOSTNAMES ONLY IP ADDRESSES -->
<param name="rtp-ip" value="$${local_ip_v4}"/>
<!-- ip address to bind to, DO NOT USE HOSTNAMES ONLY IP ADDRESSES -->
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="hold-music" value="$${hold_music}"/>
<param name="apply-nat-acl" value="nat.auto"/>
<!-- (default true) set to false if you do not wish to have called party info in 1XX responses -->
<!-- <param name="cid-in-1xx" value="false"/> -->
<!-- extended info parsing -->
<!-- <param name="extended-info-parsing" value="true"/> -->
<!--<param name="aggressive-nat-detection" value="true"/>-->
<!--
There are known issues (asserts and segfaults) when 100rel is enabled.
It is not recommended to enable 100rel at this time.
-->
<!--<param name="enable-100rel" value="true"/>-->
<!-- uncomment if you don't wish to try a next SRV destination on 503 response -->
<!-- RFC3263 Section 4.3 -->
<!--<param name="disable-srv503" value="true"/>-->
<!-- Enable Compact SIP headers. -->
<!--<param name="enable-compact-headers" value="true"/>-->
<!--
enable/disable session timers
-->
<!--<param name="enable-timer" value="false"/>-->
<!--<param name="minimum-session-expires" value="120"/>-->
<param name="apply-inbound-acl" value="domains"/>
<!--
This defines your local network, by default we detect your local network
and create this localnet.auto ACL for this.
-->
<param name="local-network-acl" value="localnet.auto"/>
<!--<param name="apply-register-acl" value="domains"/>-->
<!--<param name="dtmf-type" value="info"/>-->
<!-- 'true' means every time 'first-only' means on the first register -->
<!--<param name="send-message-query-on-register" value="true"/>-->
<!-- 'true' means every time 'first-only' means on the first register -->
<!--<param name="send-presence-on-register" value="first-only"/> -->
<!-- Caller-ID type (choose one, can be overridden by inbound call type and/or sip_cid_type channel variable -->
<!-- Remote-Party-ID header -->
<!--<param name="caller-id-type" value="rpid"/>-->
<!-- P-*-Identity family of headers -->
<!--<param name="caller-id-type" value="pid"/>-->
<!-- neither one -->
<!--<param name="caller-id-type" value="none"/>-->
<param name="record-path" value="$${recordings_dir}"/>
<param name="record-template" value="${caller_id_number}.${target_domain}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
<!--enable to use presence -->
<param name="manage-presence" value="true"/>
<!-- send a presence probe on each register to query devices to send presence instead of sending presence with less info -->
<!--<param name="presence-probe-on-register" value="true"/>-->
<!--<param name="manage-shared-appearance" value="true"/>-->
<!-- used to share presence info across sofia profiles -->
<!-- Name of the db to use for this profile -->
<!--<param name="dbname" value="share_presence"/>-->
<param name="presence-hosts" value="$${domain},$${local_ip_v4}"/>
<param name="presence-privacy" value="$${presence_privacy}"/>
<!-- ************************************************* -->
<!-- This setting is for AAL2 bitpacking on G726 -->
<!-- <param name="bitpacking" value="aal2"/> -->
<!--max number of open dialogs in proceeding -->
<!--<param name="max-proceeding" value="1000"/>-->
<!--session timers for all call to expire after the specified seconds -->
<!--<param name="session-timeout" value="1800"/>-->
<!-- Can be 'true' or 'contact' -->
<!--<param name="multiple-registrations" value="contact"/>-->
<!--set to 'greedy' if you want your codec list to take precedence -->
<param name="inbound-codec-negotiation" value="generous"/>
<!-- if you want to send any special bind params of your own -->
<!--<param name="bind-params" value="transport=udp"/>-->
<!--<param name="unregister-on-options-fail" value="true"/>-->
<!-- TLS: disabled by default, set to "true" to enable -->
<param name="tls" value="$${internal_ssl_enable}"/>
<!-- Set to true to not bind on the normal sip-port but only on the TLS port -->
<param name="tls-only" value="false"/>
<!-- additional bind parameters for TLS -->
<param name="tls-bind-params" value="transport=tls"/>
<!-- Port to listen on for TLS requests. (5061 will be used if unspecified) -->
<param name="tls-sip-port" value="$${internal_tls_port}"/>
<!-- Location of the agent.pem and cafile.pem ssl certificates (needed for TLS server) -->
<param name="tls-cert-dir" value="$${internal_ssl_dir}"/>
<!-- Optionally set the passphrase password used by openSSL to encrypt/decrypt TLS private key files -->
<param name="tls-passphrase" value=""/>
<!-- Verify the date on TLS certificates -->
<param name="tls-verify-date" value="true"/>
<!-- TLS verify policy, when registering/inviting gateways with other servers (outbound) or handling inbound registration/invite requests how should we verify their certificate -->
<!-- set to 'in' to only verify incoming connections, 'out' to only verify outgoing connections, 'all' to verify all connections, also 'in_subjects', 'out_subjects' and 'all_subjects' for subject validation. Multiple policies can be split with a '|' pipe -->
<param name="tls-verify-policy" value="none"/>
<!-- Certificate max verify depth to use for validating peer TLS certificates when the verify policy is not none -->
<param name="tls-verify-depth" value="2"/>
<!-- If the tls-verify-policy is set to subjects_all or subjects_in this sets which subjects are allowed, multiple subjects can be split with a '|' pipe -->
<param name="tls-verify-in-subjects" value=""/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<!-- turn on auto-flush during bridge (skip timer sleep when the socket already has data)
(reduces delay on latent connections default true, must be disabled explicitly)-->
<!--<param name="rtp-autoflush-during-bridge" value="false"/>-->
<!--If you don't want to pass through timestamps from 1 RTP call to another (on a per call basis with rtp_rewrite_timestamps chanvar)-->
<!--<param name="rtp-rewrite-timestamps" value="true"/>-->
<!--<param name="pass-rfc2833" value="true"/>-->
<!--If you have ODBC support and a working dsn you can use it instead of SQLite-->
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
<!--Uncomment to set all inbound calls to no media mode-->
<!--<param name="inbound-bypass-media" value="true"/>-->
<!--Uncomment to set all inbound calls to proxy media mode-->
<!--<param name="inbound-proxy-media" value="true"/>-->
<!--Uncomment to let calls hit the dialplan *before* you decide if the codec is ok-->
<!--<param name="inbound-late-negotiation" value="true"/>-->
<!-- this lets anything register -->
<!-- comment the next line and uncomment one or both of the other 2 lines for call authentication -->
<!-- <param name="accept-blind-reg" value="true"/> -->
<!-- accept any authentication without actually checking (not a good feature for most people) -->
<!-- <param name="accept-blind-auth" value="true"/> -->
<!-- suppress CNG on this profile or per call with the 'suppress_cng' variable -->
<!-- <param name="suppress-cng" value="true"/> -->
<!--TTL for nonce in sip auth-->
<param name="nonce-ttl" value="60"/>
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--<param name="disable-transcoding" value="true"/>-->
<!-- Handle 302 Redirect in the dialplan -->
<!--<param name="manual-redirect" value="true"/> -->
<!-- Disable Transfer -->
<!--<param name="disable-transfer" value="true"/> -->
<!-- Disable Register -->
<!--<param name="disable-register" value="true"/> -->
<!-- Used for when phones respond to a challenged ACK with method INVITE in the hash -->
<!--<param name="NDLB-broken-auth-hash" value="true"/>-->
<!-- add a ;received="<ip>:<port>" to the contact when replying to register for nat handling -->
<!--<param name="NDLB-received-in-nat-reg-contact" value="true"/>-->
<param name="auth-calls" value="$${internal_auth_calls}"/>
<!-- Force the user and auth-user to match. -->
<param name="inbound-reg-force-matching-username" value="true"/>
<!-- on authed calls, authenticate *all* the packets not just invite -->
<param name="auth-all-packets" value="false"/>
<!-- external_sip_ip
Used as the public IP address for SDP.
Can be an one of:
ip address - "12.34.56.78"
a stun server lookup - "stun:stun.server.com"
a DNS name - "host:host.server.com"
auto - Use guessed ip.
auto-nat - Use ip learned from NAT-PMP or UPNP
-->
<param name="ext-rtp-ip" value="auto-nat"/>
<param name="ext-sip-ip" value="auto-nat"/>
<!-- rtp inactivity timeout -->
<param name="rtp-timeout-sec" value="300"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<!-- VAD choose one (out is a good choice); -->
<!-- <param name="vad" value="in"/> -->
<!-- <param name="vad" value="out"/> -->
<!-- <param name="vad" value="both"/> -->
<!--<param name="alias" value="sip:10.0.1.251:5555"/>-->
<!--
These are enabled to make the default config work better out of the box.
If you need more than ONE domain you'll need to not use these options.
-->
<!--all inbound reg will look in this domain for the users -->
<param name="force-register-domain" value="$${domain}"/>
<!--force the domain in subscriptions to this value -->
<param name="force-subscription-domain" value="$${domain}"/>
<!--all inbound reg will stored in the db using this domain -->
<param name="force-register-db-domain" value="$${domain}"/>
<!--<param name="delete-subs-on-register" value="false"/>-->
<!-- enable rtcp on every channel also can be done per leg basis with rtcp_audio_interval_msec variable set to passthru to pass it across a call-->
<!--<param name="rtcp-audio-interval-msec" value="5000"/>-->
<!--<param name="rtcp-video-interval-msec" value="5000"/>-->
<!--force suscription expires to a lower value than requested-->
<!--<param name="force-subscription-expires" value="60"/>-->
<!-- disable register and transfer which may be undesirable in a public switch -->
<!--<param name="disable-transfer" value="true"/>-->
<!--<param name="disable-register" value="true"/>-->
<!--
enable-3pcc can be set to either 'true' or 'proxy', true accepts the call
right away, proxy waits until the call has been answered then sends accepts
-->
<!--<param name="enable-3pcc" value="true"/>-->
<!-- use at your own risk or if you know what this does.-->
<!--<param name="NDLB-force-rport" value="true"/>-->
<!--
Choose the realm challenge key. Default is auto_to if not set.
auto_from - uses the from field as the value for the sip realm.
auto_to - uses the to field as the value for the sip realm.
<anyvalue> - you can input any value to use for the sip realm.
If you want URL dialing to work you'll want to set this to auto_from.
If you use any other value besides auto_to or auto_from you'll loose
the ability to do multiple domains.
Note: comment out to restore the behavior before 2008-09-29
-->
<param name="challenge-realm" value="auto_from"/>
<!--<param name="disable-rtp-auto-adjust" value="true"/>-->
<!-- on inbound calls make the uuid of the session equal to the sip call id of that call -->
<!--<param name="inbound-use-callid-as-uuid" value="true"/>-->
<!-- on outbound calls set the callid to match the uuid of the session -->
<!--<param name="outbound-use-uuid-as-callid" value="true"/>-->
<!-- set to false disable this feature -->
<!--<param name="rtp-autofix-timing" value="false"/>-->
<!-- set this param to false if your gateway for some reason hates X- headers that it is supposed to ignore-->
<!--<param name="pass-callee-id" value="false"/>-->
<!-- clear clears them all or supply the name to add or the name prefixed with ~ to remove
valid values:
clear
CISCO_SKIP_MARK_BIT_2833
SONUS_SEND_INVALID_TIMESTAMP_2833
-->
<!--<param name="auto-rtp-bugs" data="clear"/>-->
<!-- the following can be used as workaround with bogus SRV/NAPTR records -->
<!--<param name="disable-srv" value="false" />-->
<!--<param name="disable-naptr" value="false" />-->
<!-- The following can be used to fine-tune timers within sofia's transport layer
Those settings are for advanced users and can safely be left as-is -->
<!-- Initial retransmission interval (in milliseconds).
Set the T1 retransmission interval used by the SIP transaction engine.
The T1 is the initial duration used by request retransmission timers A and E (UDP) as well as response retransmission timer G. -->
<!-- <param name="timer-T1" value="500" /> -->
<!-- Transaction timeout (defaults to T1 * 64).
Set the T1x64 timeout value used by the SIP transaction engine.
The T1x64 is duration used for timers B, F, H, and J (UDP) by the SIP transaction engine.
The timeout value T1x64 can be adjusted separately from the initial retransmission interval T1. -->
<!-- <param name="timer-T1X64" value="32000" /> -->
<!-- Maximum retransmission interval (in milliseconds).
Set the maximum retransmission interval used by the SIP transaction engine.
The T2 is the maximum duration used for the timers E (UDP) and G by the SIP transaction engine.
Note that the timer A is not capped by T2. Retransmission interval of INVITE requests grows exponentially
until the timer B fires. -->
<!-- <param name="timer-T2" value="4000" /> -->
<!--
Transaction lifetime (in milliseconds).
Set the lifetime for completed transactions used by the SIP transaction engine.
A completed transaction is kept around for the duration of T4 in order to catch late responses.
The T4 is the maximum duration for the messages to stay in the network and the duration of SIP timer K. -->
<!-- <param name="timer-T4" value="4000" /> -->
<!-- Turn on a jitterbuffer for every call -->
<!-- <param name="auto-jitterbuffer-msec" value="60"/> -->
<!-- By default mod_sofia will ignore the codecs in the sdp for hold/unhold operations
Set this to true if you want to actually parse the sdp and re-negotiate the codec during hold/unhold.
It's probably not what you want so stick with the default unless you really need to change this.
-->
<!--<param name="renegotiate-codec-on-hold" value="true"/>-->
</settings>
</profile>
@@ -0,0 +1,37 @@
<include>
<!--<gateway name="asterlink.com">-->
<!--/// account username *required* ///-->
<!--<param name="username" value="cluecon"/>-->
<!--/// auth realm: *optional* same as gateway name, if blank ///-->
<!--<param name="realm" value="asterlink.com"/>-->
<!--/// username to use in from: *optional* same as username, if blank ///-->
<!--<param name="from-user" value="cluecon"/>-->
<!--/// domain to use in from: *optional* same as realm, if blank ///-->
<!--<param name="from-domain" value="asterlink.com"/>-->
<!--/// account password *required* ///-->
<!--<param name="password" value="2007"/>-->
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<!--<param name="extension" value="cluecon"/>-->
<!--/// proxy host: *optional* same as realm, if blank ///-->
<!--<param name="proxy" value="asterlink.com"/>-->
<!--/// send register to this proxy: *optional* same as proxy, if blank ///-->
<!--<param name="register-proxy" value="mysbc.com"/>-->
<!--/// expire in seconds: *optional* 3600, if blank ///-->
<!--<param name="expire-seconds" value="60"/>-->
<!--/// do not register ///-->
<!--<param name="register" value="false"/>-->
<!-- which transport to use for register -->
<!--<param name="register-transport" value="udp"/>-->
<!--How many seconds before a retry when a failure or timeout occurs -->
<!--<param name="retry-seconds" value="30"/>-->
<!--Use the callerid of an inbound call in the from field on outbound calls via this gateway -->
<!--<param name="caller-id-in-from" value="false"/>-->
<!--extra sip params to send in the contact-->
<!--<param name="contact-params" value="tport=tcp"/>-->
<!-- Put the extension in the contact -->
<!--<param name="extension-in-contact" value="true"/>-->
<!--send an options ping every x seconds, failure will unregister and/or mark it down-->
<!--<param name="ping" value="25"/>-->
<!--<param name="cid-type" value="rpid"/>-->
<!--</gateway>-->
</include>
+72 -40
View File
@@ -495,12 +495,16 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
val = switch_channel_get_variable(tech_pvt->channel, "disable_q850_reason");
if (!val || switch_false(val)) {
if (switch_channel_test_flag(channel, CF_INTERCEPT) || cause == SWITCH_CAUSE_PICKED_OFF || cause == SWITCH_CAUSE_LOSE_RACE) {
switch_snprintf(reason, sizeof(reason), "SIP;cause=200;text=\"Call completed elsewhere\"");
} else if (cause > 0 && cause < 128) {
switch_snprintf(reason, sizeof(reason), "Q.850;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_reason_str"))) {
switch_snprintf(reason, sizeof(reason), "%s", val);
} else {
switch_snprintf(reason, sizeof(reason), "%s;cause=%d;text=\"%s\"", tech_pvt->profile->username, cause, switch_channel_cause2str(cause));
if (switch_channel_test_flag(channel, CF_INTERCEPT) || cause == SWITCH_CAUSE_PICKED_OFF || cause == SWITCH_CAUSE_LOSE_RACE) {
switch_snprintf(reason, sizeof(reason), "SIP;cause=200;text=\"Call completed elsewhere\"");
} else if (cause > 0 && cause < 128) {
switch_snprintf(reason, sizeof(reason), "Q.850;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
} else {
switch_snprintf(reason, sizeof(reason), "%s;cause=%d;text=\"%s\"", tech_pvt->profile->username, cause, switch_channel_cause2str(cause));
}
}
}
@@ -1728,7 +1732,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
if ((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) && switch_true(var)) {
if ((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) &&
(switch_true(var) || !strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_32) || !strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_80))) {
sofia_set_flag_locked(tech_pvt, TFLAG_SECURE);
}
@@ -1917,13 +1922,18 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
{
switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options");
sofia_glue_set_image_sdp(tech_pvt, t38_options, msg->numeric_arg);
if (t38_options) {
sofia_glue_set_image_sdp(tech_pvt, t38_options, msg->numeric_arg);
if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
switch_channel_set_flag(channel, CF_REQ_MEDIA);
if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
switch_channel_set_flag(channel, CF_REQ_MEDIA);
}
sofia_set_flag_locked(tech_pvt, TFLAG_SENT_UPDATE);
sofia_glue_do_invite(session);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Request to send IMAGE on channel with not t38 options.\n",
switch_channel_get_name(channel));
}
sofia_set_flag_locked(tech_pvt, TFLAG_SENT_UPDATE);
sofia_glue_do_invite(session);
}
break;
@@ -2033,7 +2043,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
const char *uuid;
const char *call_id = NULL, *to_user = NULL, *to_host = NULL, *to_tag = NULL, *from_tag = NULL, *from_user = NULL, *from_host = NULL;
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) || (uuid = switch_channel_get_variable(channel, "originate_signal_bond"))) {
switch_core_session_t *rsession;
if ((rsession = switch_core_session_locate(uuid))) {
switch_channel_t *rchannel = switch_core_session_get_channel(rsession);
@@ -2103,12 +2113,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
number = tech_pvt->caller_profile->destination_number;
}
if (sofia_test_flag(tech_pvt, TFLAG_UPDATING_DISPLAY) || !switch_channel_test_flag(channel, CF_ANSWERED)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_WARNING,
"Cannot send display update to %s "
"Did not receive reply to last update or channel has not been answered yet.\n",
switch_channel_get_name(tech_pvt->channel));
} else {
if (!sofia_test_flag(tech_pvt, TFLAG_UPDATING_DISPLAY) && switch_channel_test_flag(channel, CF_ANSWERED)) {
if (zstr(tech_pvt->last_sent_callee_id_name) || strcmp(tech_pvt->last_sent_callee_id_name, name) ||
zstr(tech_pvt->last_sent_callee_id_number) || strcmp(tech_pvt->last_sent_callee_id_number, number)) {
@@ -2159,6 +2164,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
nua_update(tech_pvt->nh,
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
} else if ((ua && (switch_stristr("Yealink", ua)))) {
@@ -2168,6 +2174,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
nua_update(tech_pvt->nh,
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
}
@@ -2566,6 +2573,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
}
switch_channel_check_zrtp(tech_pvt->channel);
if ((status = sofia_glue_tech_choose_port(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
goto end_lock;
@@ -2803,8 +2812,29 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum
return 0;
}
static const char *status_names[] = { "DOWN", "UP", NULL };
static int sql2str_callback(void *pArg, int argc, char **argv, char **columnNames)
{
struct cb_helper_sql2str *cbt = (struct cb_helper_sql2str *) pArg;
switch_copy_string(cbt->buf, argv[0], cbt->len);
cbt->matches++;
return 0;
}
static uint32_t sofia_profile_reg_count(sofia_profile_t *profile)
{
struct cb_helper_sql2str cb;
char reg_count[80] = "";
char *sql;
cb.buf = reg_count;
cb.len = sizeof(reg_count);
sql = switch_mprintf("select count(*) from sip_registrations where profile_name = '%q'", profile->name);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sql2str_callback, &cb);
free(sql);
return strtoul(reg_count, NULL, 10);
}
static const char *status_names[] = { "DOWN", "UP", NULL };
static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t *stream)
{
@@ -2978,6 +3008,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
stream->write_function(stream, "FAILED-CALLS-IN \t%u\n", profile->ib_failed_calls);
stream->write_function(stream, "CALLS-OUT \t%u\n", profile->ob_calls);
stream->write_function(stream, "FAILED-CALLS-OUT \t%u\n", profile->ob_failed_calls);
stream->write_function(stream, "REGISTRATIONS \t%lu\n", sofia_profile_reg_count(profile));
}
cb.profile = profile;
@@ -3254,9 +3285,9 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
stream->write_function(stream, " <calls-out>%u</calls-out>\n", profile->ob_calls);
stream->write_function(stream, " <failed-calls-in>%u</failed-calls-in>\n", profile->ib_failed_calls);
stream->write_function(stream, " <failed-calls-out>%u</failed-calls-out>\n", profile->ob_failed_calls);
stream->write_function(stream, " <registrations>%lu</registrations>\n", sofia_profile_reg_count(profile));
stream->write_function(stream, " </profile-info>\n");
}
stream->write_function(stream, " <registrations>\n");
cb.profile = profile;
cb.stream = stream;
@@ -3275,6 +3306,13 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
" from sip_registrations where profile_name='%q' and contact like '%%%q%%'", profile->name, argv[3]);
}
if (!sql && argv[2] && !strcasecmp(argv[2], "reg")) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
" from sip_registrations where profile_name='%q'", profile->name);
}
if (!sql && argv[2] && !strcasecmp(argv[2], "user") && argv[3]) {
char *dup = strdup(argv[3]);
char *host = NULL, *user = NULL;
@@ -3305,17 +3343,15 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
switch_safe_free(sqlextra);
}
if (!sql) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
"rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
"network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host"
" from sip_registrations where profile_name='%q'", profile->name);
if (sql) {
stream->write_function(stream, " <registrations>\n");
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, show_reg_callback_xml, &cb);
switch_safe_free(sql);
stream->write_function(stream, " </registrations>\n");
}
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, show_reg_callback_xml, &cb);
switch_safe_free(sql);
stream->write_function(stream, " </registrations>\n");
stream->write_function(stream, "</profile>\n");
sofia_glue_release_profile(profile);
@@ -3684,15 +3720,6 @@ static int contact_callback(void *pArg, int argc, char **argv, char **columnName
return 0;
}
static int sql2str_callback(void *pArg, int argc, char **argv, char **columnNames)
{
struct cb_helper_sql2str *cbt = (struct cb_helper_sql2str *) pArg;
switch_copy_string(cbt->buf, argv[0], cbt->len);
cbt->matches++;
return 0;
}
SWITCH_STANDARD_API(sofia_count_reg_function)
{
char *data;
@@ -4650,8 +4677,8 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
}
now = switch_epoch_time_now(NULL);
sql = switch_mprintf("insert into sip_dialogs (uuid,presence_id,presence_data,profile_name,hostname,rcd) "
"values ('%q', '%q', '%q', '%q', '%q', %ld)", switch_core_session_get_uuid(nsession),
sql = switch_mprintf("insert into sip_dialogs (uuid,presence_id,presence_data,profile_name,hostname,rcd,call_info_state) "
"values ('%q', '%q', '%q', '%q', '%q', %ld, '')", switch_core_session_get_uuid(nsession),
switch_str_nil(presence_id), switch_str_nil(presence_data), profile->name, mod_sofia_globals.hostname, (long) now);
sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex);
switch_safe_free(sql);
@@ -5337,6 +5364,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
switch_chat_interface_t *chat_interface;
switch_api_interface_t *api_interface;
switch_management_interface_t *management_interface;
uint32_t cpus = switch_core_cpu_count();
struct in_addr in;
memset(&mod_sofia_globals, 0, sizeof(mod_sofia_globals));
@@ -5374,6 +5402,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for profiles to start\n");
switch_yield(1500000);
/* start one message thread per cpu */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting %u message threads.\n", cpus);
sofia_msg_thread_start(cpus);
if (switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL,
&mod_sofia_globals.custom_node) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
+3
View File
@@ -262,6 +262,7 @@ typedef enum {
PFLAG_SHUTDOWN,
PFLAG_PRESENCE_MAP,
PFLAG_OPTIONS_RESPOND_503_ON_BUSY,
PFLAG_PRESENCE_DISABLE_EARLY,
/* No new flags below this line */
PFLAG_MAX
} PFLAGS;
@@ -1116,6 +1117,7 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use
const char *body, const char *o_contact, const char *network_ip);
char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix);
void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *sip, const char *prefix);
char *sofia_glue_get_extra_headers_from_event(switch_event_t *event, const char *prefix);
void sofia_info_send_sipfrag(switch_core_session_t *aleg, switch_core_session_t *bleg);
void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t send);
void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number);
@@ -1149,3 +1151,4 @@ void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t
void sofia_process_dispatch_event(sofia_dispatch_event_t **dep);
char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool);
void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now);
void sofia_msg_thread_start(int idx);
+220 -107
View File
@@ -88,9 +88,9 @@ void sofia_handle_sip_r_notify(switch_core_session_t *session, int status,
sofia_dispatch_event_t *de, tagi_t tags[])
{
if (status >= 300 && sip && sip->sip_call_id && (!sofia_private || !sofia_private->is_call)) {
if (status == 481 && sip && !sip->sip_retry_after && sip->sip_call_id && (!sofia_private || !sofia_private->is_call)) {
char *sql;
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", sip->sip_call_id->i_id);
switch_assert(sql != NULL);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
@@ -239,21 +239,25 @@ static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip,
switch_stream_handle_t stream = { 0 };
int x = 0;
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
SWITCH_STANDARD_STREAM(stream);
SWITCH_STANDARD_STREAM(stream);
for(vp = sip->sip_via; vp; vp = vp->v_next) {
char *v = sip_header_as_string(nh->nh_home, (void *) vp);
stream.write_function(&stream, x == 0 ? "%s" : ",%s", v);
su_free(nh->nh_home, v);
x++;
}
for(vp = sip->sip_via; vp; vp = vp->v_next) {
char *v = sip_header_as_string(nh->nh_home, (void *) vp);
switch_channel_set_variable(channel, "sip_recover_via", (char *)stream.data);
free(stream.data);
stream.write_function(&stream, x == 0 ? "%s" : ",%s", v);
su_free(nh->nh_home, v);
x++;
}
switch_channel_set_variable(channel, "sip_full_via", (char *)stream.data);
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
switch_channel_set_variable(channel, "sip_recover_via", (char *)stream.data);
}
free(stream.data);
}
if (sip->sip_from) {
@@ -577,6 +581,14 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
sofia_set_flag_locked(tech_pvt, TFLAG_BYE);
call_info = switch_channel_get_variable(channel, "presence_call_info_full");
if (sip->sip_reason) {
char *reason_header = sip_header_as_string(nh->nh_home, (void *) sip->sip_reason);
if (!zstr(reason_header)) {
switch_channel_set_variable_partner(channel, "sip_reason", reason_header);
}
}
if (sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
|| !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
|| !strcasecmp(sip->sip_reason->re_protocol, profile->username)) && sip->sip_reason->re_cause) {
@@ -977,7 +989,6 @@ static void our_sofia_event_callback(nua_event_t event,
case nua_r_unregister:
case nua_r_unsubscribe:
case nua_r_publish:
case nua_i_cancel:
case nua_i_error:
case nua_i_active:
case nua_i_terminated:
@@ -985,6 +996,19 @@ static void our_sofia_event_callback(nua_event_t event,
case nua_i_prack:
case nua_r_prack:
break;
case nua_i_cancel:
if (sip && channel && sip->sip_reason) {
char *reason_header = sip_header_as_string(nh->nh_home, (void *) sip->sip_reason);
if (!zstr(reason_header)) {
switch_channel_set_variable_partner(channel, "sip_reason", reason_header);
}
}
break;
case nua_r_cancel:
{
if (status > 299 && nh) {
@@ -1228,7 +1252,7 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj
static int IDX = 0;
static void sofia_msg_thread_start(int idx)
void sofia_msg_thread_start(int idx)
{
if (idx >= SOFIA_MAX_MSG_QUEUE || (idx < mod_sofia_globals.msg_queue_len && mod_sofia_globals.msg_queue_thread[idx])) {
@@ -2618,8 +2642,9 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
gateway->ping = switch_epoch_time_now(NULL) + ping_freq;
gateway->options_to_uri = switch_core_sprintf(gateway->pool, "<sip:%s;transport=%s>",
!zstr(from_domain) ? from_domain : proxy, register_transport);
gateway->options_from_uri = switch_core_sprintf(gateway->pool, "<sip:%s;transport=%s>",
profile->extrtpip ? profile->extrtpip : profile->sipip, register_transport);
//gateway->options_from_uri = switch_core_sprintf(gateway->pool, "<sip:%s;transport=%s>",
// profile->extrtpip ? profile->extrtpip : profile->sipip, register_transport);
gateway->options_from_uri = gateway->options_to_uri;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: invalid ping!\n");
}
@@ -3031,6 +3056,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else {
sofia_clear_pflag(profile, PFLAG_T38_PASSTHRU);
}
} else if (!strcasecmp(var, "presence-disable-early")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
} else {
sofia_clear_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
}
} else if (!strcasecmp(var, "ignore-183nosdp")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_IGNORE_183NOSDP);
@@ -3356,7 +3387,7 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else if (!strcasecmp(var, "context")) {
profile->context = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "local-network-acl")) {
if (!strcasecmp(var, "none")) {
if (!strcasecmp(val, "none")) {
profile->local_network = NULL;
} else {
profile->local_network = switch_core_strdup(profile->pool, val);
@@ -3605,6 +3636,18 @@ switch_status_t config_sofia(int reload, char *profile_name)
mod_sofia_globals.debug_sla = atoi(val);
} else if (!strcasecmp(var, "auto-restart")) {
mod_sofia_globals.auto_restart = switch_true(val);
} else if (!strcasecmp(var, "message-threads")) {
int num = atoi(val);
if (num < 1 || num > SOFIA_MAX_MSG_QUEUE - 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "message-threads must be between 1 and %d", SOFIA_MAX_MSG_QUEUE -1);
}
if (num < 1) num = 1;
if (num > SOFIA_MAX_MSG_QUEUE - 1) num = SOFIA_MAX_MSG_QUEUE -1;
sofia_msg_thread_start(num);
} else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */
mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
if (switch_true(val)) {
@@ -3805,6 +3848,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_T38_PASSTHRU);
}
} else if (!strcasecmp(var, "presence-disable-early")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
} else {
sofia_clear_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
}
} else if (!strcasecmp(var, "ignore-183nosdp")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_IGNORE_183NOSDP);
@@ -3845,19 +3894,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_CID_IN_1XX);
}
} else if (!strcasecmp(var, "message-threads")) {
int num = atoi(val);
if (num < 1 || num > SOFIA_MAX_MSG_QUEUE - 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "message-threads must be between 1 and %d", SOFIA_MAX_MSG_QUEUE -1);
}
if (num < 1) num = 1;
if (num > SOFIA_MAX_MSG_QUEUE - 1) num = SOFIA_MAX_MSG_QUEUE -1;
sofia_msg_thread_start(num);
} else if (!strcasecmp(var, "disable-hold")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_DISABLE_HOLD);
@@ -4719,7 +4756,7 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
gateway->ping = switch_epoch_time_now(NULL) + gateway->ping_freq;
sofia_reg_release_gateway(gateway);
gateway->pinging = 0;
} else if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL) && status != 200 && sip && sip->sip_to) {
} else if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL) && (status != 200 && status != 486) && sip && sip->sip_to) {
char *sql;
time_t now = switch_epoch_time_now(NULL);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire registration '%s@%s' due to options failure\n",
@@ -4757,6 +4794,13 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
return;
}
if (status >= 500 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
|| !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
|| !strcasecmp(sip->sip_reason->re_protocol, profile->username)) && sip->sip_reason->re_cause) {
tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote Reason: %d\n", tech_pvt->q850_cause);
}
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
@@ -4789,6 +4833,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
if (channel && sip->sip_call_info) {
char *p;
call_info = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_call_info);
if (switch_stristr("appearance", call_info)) {
switch_channel_set_variable(channel, "presence_call_info_full", call_info);
if ((p = strchr(call_info, ';'))) {
@@ -4825,10 +4870,15 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
sip->sip_from->a_url->url_host, buf);
switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
switch_channel_set_variable(channel, "presence_call_info", buf);
}
}
}
}
}
@@ -5003,14 +5053,16 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
}
if (sofia_test_pflag(profile, PFLAG_MANUAL_REDIRECT)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Redirect: Transfering to %s %s %s\n",
p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
if (!(v = switch_channel_get_variable(channel, "outbound_redirect_info"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Redirect: Transfering to %s %s %s\n",
p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer"))) {
switch_core_media_bug_transfer_recordings(session, a_session);
if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer"))) {
switch_core_media_bug_transfer_recordings(session, a_session);
}
switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
}
switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION);
} else if ((!strcmp(profile->sipip, p_contact->m_url->url_host))
|| (profile->extsipip && !strcmp(profile->extsipip, p_contact->m_url->url_host))
@@ -5248,8 +5300,9 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
sql = switch_mprintf("insert into sip_dialogs "
"(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
"contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,call_info,rcd) "
"values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld)",
"contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
"call_info,rcd,call_info_state) "
"values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
call_id,
switch_core_session_get_uuid(session),
to_user, to_host, to_tag, from_user, from_host, from_tag, contact_user,
@@ -5672,11 +5725,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri");
nua_ack(nh,
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
TAG_IF(!zstr(invite_full_via), SIPTAG_VIA_STR(invite_full_via)),
TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)),
TAG_END());
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF((zstr(tech_pvt->user_via) && !zstr(invite_full_via)), SIPTAG_VIA_STR(invite_full_via)),
TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)),
TAG_END());
} else {
nua_ack(nh,
@@ -5788,11 +5843,11 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
} else {
if (sofia_test_pflag(profile, PFLAG_3PCC)) {
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc=yes cannot work with bypass or proxy media, hanging up.\n");
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED");
switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
} else {
} else {
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
sofia_glue_tech_choose_port(tech_pvt, 0);
sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
@@ -5812,23 +5867,23 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_END());
}
}
} else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
//3PCC proxy mode delays the 200 OK until the call is answered
} else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
//3PCC proxy mode delays the 200 OK until the call is answered
// so can be made to work with bypass media as we have time to find out what the other end thinks codec offer should be...
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
//sofia_glue_tech_choose_port(tech_pvt, 0);
//sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
sofia_set_flag(tech_pvt, TFLAG_LATE_NEGOTIATION);
//Moves into CS_INIT so call moves forward into the dialplan
switch_channel_set_state(channel, CS_INIT);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc not enabled, hanging up.\n");
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED");
switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
}
goto done;
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
//sofia_glue_tech_choose_port(tech_pvt, 0);
//sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
sofia_set_flag(tech_pvt, TFLAG_LATE_NEGOTIATION);
//Moves into CS_INIT so call moves forward into the dialplan
switch_channel_set_state(channel, CS_INIT);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc not enabled, hanging up.\n");
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED");
switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
}
goto done;
}
} else if (tech_pvt && sofia_test_flag(tech_pvt, TFLAG_SDP) && !r_sdp) {
sofia_set_flag_locked(tech_pvt, TFLAG_NOSDP_REINVITE);
@@ -5883,53 +5938,56 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_core_session_message_t *msg;
if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 && profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
tech_pvt->hold_laps = 1;
switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
switch_channel_clear_flag(channel, CF_PROXY_MODE);
sofia_glue_tech_set_local_sdp(tech_pvt, NULL, SWITCH_FALSE);
if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) {
tech_pvt->hold_laps = 1;
switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
switch_channel_clear_flag(channel, CF_PROXY_MODE);
sofia_glue_tech_set_local_sdp(tech_pvt, NULL, SWITCH_FALSE);
if (!switch_channel_media_ready(channel)) {
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
//const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
if (!switch_channel_media_ready(channel)) {
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
//const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
tech_pvt->num_codecs = 0;
tech_pvt->num_codecs = 0;
sofia_glue_tech_prepare_codecs(tech_pvt);
if (sofia_glue_tech_media(tech_pvt, r_sdp) != SWITCH_STATUS_SUCCESS) {
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
status = SWITCH_STATUS_FALSE;
switch_core_session_rwunlock(other_session);
goto done;
}
}
}
if (!switch_rtp_ready(tech_pvt->rtp_session)) {
sofia_glue_tech_prepare_codecs(tech_pvt);
if (sofia_glue_tech_media(tech_pvt, r_sdp) != SWITCH_STATUS_SUCCESS) {
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
status = SWITCH_STATUS_FALSE;
if ((status = sofia_glue_tech_choose_port(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
switch_core_session_rwunlock(other_session);
goto done;
}
}
}
sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 1);
if (!switch_rtp_ready(tech_pvt->rtp_session)) {
sofia_glue_tech_prepare_codecs(tech_pvt);
if ((status = sofia_glue_tech_choose_port(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
switch_core_session_rwunlock(other_session);
goto done;
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_END());
}
}
sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 1);
launch_media_on_hold(session);
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_END());
switch_core_session_rwunlock(other_session);
goto done;
}
launch_media_on_hold(session);
switch_core_session_rwunlock(other_session);
goto done;
}
if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
@@ -6212,6 +6270,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
if (match) {
switch_channel_check_zrtp(channel);
if (sofia_glue_tech_choose_port(tech_pvt, 0) == SWITCH_STATUS_SUCCESS) {
if (sofia_glue_activate_rtp(tech_pvt, 0) == SWITCH_STATUS_SUCCESS) {
switch_channel_mark_answered(channel);
@@ -8000,12 +8060,62 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
if ((call_info = sip_call_info(sip))) {
call_info_str = sip_header_as_string(nh->nh_home, (void *) call_info);
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE) && switch_stristr("appearance", call_info_str)) {
char *p;
switch_channel_set_variable(channel, "presence_call_info_full", call_info_str);
if ((p = strchr(call_info_str, ';'))) {
p++;
switch_channel_set_variable(channel, "presence_call_info", p);
}
}
if (call_info->ci_params && (msg_params_find(call_info->ci_params, "answer-after=0"))) {
switch_channel_set_variable(channel, "sip_auto_answer_detected", "true");
}
switch_channel_set_variable(channel, "sip_call_info", call_info_str);
} else if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
char buf[128] = "";
char *sql;
char *state = "progressing";
if (sip &&
sip->sip_from && sip->sip_from->a_url && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
sql =
switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
"sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
sip->sip_from->a_url->url_host);
sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf));
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
}
free(sql);
if (!zstr(buf)) {
sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
"where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
sip->sip_from->a_url->url_host, buf);
switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
switch_channel_set_variable(channel, "presence_call_info", buf);
call_info_str = switch_core_session_sprintf(session, "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
}
}
}
if (profile->pres_type) {
const char *presence_id = switch_channel_get_variable(channel, "presence_id");
if (zstr(presence_id)) {
@@ -8124,7 +8234,8 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
free(sql);
}
}
}
check_decode(displayname, session);
tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
@@ -8176,7 +8287,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
if (app && data && !strcasecmp(app, "conference")) {
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,conference:%s", data);
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,conference:%s+flags{dist-dtmf}", data);
tech_pvt->caller_profile->dialplan = "inline";
} else {
if (switch_core_session_check_interface(b_session, sofia_endpoint_interface)) {
@@ -8212,7 +8323,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
if (!one_leg &&
(!b_tech_pvt || !sofia_test_flag(b_tech_pvt, TFLAG_SIP_HOLD)) &&
(!c_tech_pvt || !sofia_test_flag(c_tech_pvt, TFLAG_SIP_HOLD))) {
char *ext = switch_core_session_sprintf(session, "answer,conference:%s@sla+flags{mintwo}", uuid);
char *ext = switch_core_session_sprintf(session, "answer,conference:%s@sla+flags{mintwo|dist-dtmf}", uuid);
switch_channel_set_flag(c_channel, CF_REDIRECT);
switch_ivr_session_transfer(b_session, ext, "inline", NULL);
@@ -8225,7 +8336,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
if (do_conf) {
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
"answer,conference:%s@sla+flags{mintwo}", uuid);
"answer,conference:%s@sla+flags{mintwo|dist-dtmf}", uuid);
} else {
if (one_leg && c_app) {
if (c_data) {
@@ -8426,8 +8537,9 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
sql = switch_mprintf("insert into sip_dialogs "
"(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
"contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,call_info,rcd) "
"values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld)",
"contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
"call_info,rcd,call_info_state) "
"values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
call_id,
tech_pvt->sofia_private->uuid,
to_user, to_host, to_tag, dialog_from_user, dialog_from_host, from_tag,
@@ -8493,7 +8605,8 @@ void sofia_handle_sip_i_options(int status,
(sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING) || !switch_core_ready_inbound())) {
nua_respond(nh, 503, "Maximum Calls In Progress", NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
} else {
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(sip->sip_record_route, SIPTAG_RECORD_ROUTE(sip->sip_record_route)), TAG_END());
}
}
+154 -43
View File
@@ -44,10 +44,10 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *
char buf[2048] = "";
char max_buf[128] = "";
char max_data[128] = "";
const char *ip = t38_options->local_ip;
uint32_t port = t38_options->local_port;
const char *ip;
uint32_t port;
const char *family = "IP4";
const char *username = tech_pvt->profile->username;
const char *username;
const char *bit_removal_on = "a=T38FaxFillBitRemoval\n";
const char *bit_removal_off = "";
@@ -59,6 +59,13 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *
const char *var;
int broken_boolean;
switch_assert(tech_pvt);
switch_assert(t38_options);
ip = t38_options->local_ip;
port = t38_options->local_port;
username = tech_pvt->profile->username;
//sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
var = switch_channel_get_variable(tech_pvt->channel, "t38_broken_boolean");
@@ -177,7 +184,8 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
int rate;
int already_did[128] = { 0 };
int ptime = 0, noptime = 0;
const char *zrtp;
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP",
port, secure ? "S" : "");
@@ -336,6 +344,10 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ptime:%d\n", cur_ptime);
}
if ((zrtp = switch_channel_get_variable(tech_pvt->channel, "sdp_zrtp_hash_string"))) {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=zrtp-hash:%s\n", zrtp);
}
if (sr) {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=%s\n", sr);
}
@@ -379,6 +391,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
switch_event_t *map = NULL, *ptmap = NULL;
const char *b_sdp = NULL;
int verbose_sdp = 0;
const char *zrtp;
sofia_glue_check_dtmf_type(tech_pvt);
@@ -532,6 +545,10 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=ptime:%d\n", ptime);
}
if ((zrtp = switch_channel_get_variable(tech_pvt->channel, "sdp_zrtp_hash_string"))) {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=zrtp-hash:%s\n", zrtp);
}
if (sr) {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=%s\n", sr);
}
@@ -558,13 +575,22 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
if (mult && switch_false(mult)) {
char *bp = buf;
int both = 1;
if ((!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE))) {
generate_m(tech_pvt, buf, sizeof(buf), port, 0, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 1);
bp = (buf + strlen(buf));
/* asterisk can't handle AVP and SAVP in sep streams, way to blow off the spec....*/
if (switch_true(switch_channel_get_variable(tech_pvt->channel, "sdp_secure_savp_only"))) {
both = 0;
}
}
generate_m(tech_pvt, bp, sizeof(buf) - strlen(buf), port, 0, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 0);
if (both) {
generate_m(tech_pvt, bp, sizeof(buf) - strlen(buf), port, 0, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 0);
}
} else {
@@ -583,14 +609,23 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
if (cur_ptime != this_ptime) {
char *bp = buf;
cur_ptime = this_ptime;
int both = 1;
cur_ptime = this_ptime;
if ((!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE))) {
generate_m(tech_pvt, buf, sizeof(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 1);
bp = (buf + strlen(buf));
/* asterisk can't handle AVP and SAVP in sep streams, way to blow off the spec....*/
if (switch_true(switch_channel_get_variable(tech_pvt->channel, "sdp_secure_savp_only"))) {
both = 0;
}
}
if (both) {
generate_m(tech_pvt, bp, sizeof(buf) - strlen(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 0);
}
generate_m(tech_pvt, bp, sizeof(buf) - strlen(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 0);
}
}
@@ -762,6 +797,11 @@ void sofia_glue_tech_prepare_codecs(private_object_t *tech_pvt)
switch_assert(tech_pvt->session != NULL);
if ((abs = switch_channel_get_variable(tech_pvt->channel, "absolute_codec_string"))) {
/* inherit_codec == true will implicitly clear the absolute_codec_string
variable if used since it was the reason it was set in the first place and is no longer needed */
if (switch_true(switch_channel_get_variable(tech_pvt->channel, "inherit_codec"))) {
switch_channel_set_variable(tech_pvt->channel, "absolute_codec_string", NULL);
}
codec_string = abs;
goto ready;
}
@@ -1968,6 +2008,30 @@ void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *s
switch_channel_api_on(channel, "api_on_sip_extra_headers");
}
char *sofia_glue_get_extra_headers_from_event(switch_event_t *event, const char *prefix)
{
char *extra_headers = NULL;
switch_stream_handle_t stream = { 0 };
switch_event_header_t *hp;
SWITCH_STANDARD_STREAM(stream);
for (hp = event->headers; hp; hp = hp->next) {
if (!zstr(hp->name) && !zstr(hp->value) && !strncasecmp(hp->name, prefix, strlen(prefix))) {
char *name = strdup(hp->name);
const char *hname = name + strlen(prefix);
stream.write_function(&stream, "%s: %s\r\n", hname, (char *)hp->value);
free(name);
}
}
if (!zstr((char *) stream.data)) {
extra_headers = stream.data;
} else {
switch_safe_free(stream.data);
}
return extra_headers;
}
switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
{
@@ -2291,6 +2355,29 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
switch_channel_set_variable(channel, "sip_to_host", sofia_glue_get_host(to_str, switch_core_session_get_pool(session)));
switch_channel_set_variable(channel, "sip_from_host", sofia_glue_get_host(from_str, switch_core_session_get_pool(session)));
if (!switch_channel_get_variable(channel, "presence_id")) {
char *from = switch_core_session_strdup(session, from_str);
const char *s;
if ((s = switch_stristr("<", from))) {
from = (char *)s + 1;
}
if (!strncasecmp(from, "sip:", 4)) {
from += 4;
}
if (!strncasecmp(from, "sips:", 5)) {
from += 5;
}
if ((p = strchr(from, ':')) || (p = strchr(from, ';')) || (p = strchr(from, '>'))) {
*p++ = '\0';
}
switch_channel_set_variable(channel, "presence_id", from);
}
if (!(tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL,
NUTAG_URL(url_str),
TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
@@ -2352,11 +2439,22 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
switch (cid_type) {
case CID_TYPE_PID:
if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)) {
tech_pvt->asserted_id = switch_core_session_sprintf(tech_pvt->session, "\"%s\"<sip:%s@%s>", use_name, use_number, rpid_domain);
if (zstr(tech_pvt->caller_profile->caller_id_name) || !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) {
tech_pvt->asserted_id = switch_core_session_sprintf(tech_pvt->session, "<sip:%s@%s>",
use_number, rpid_domain);
} else {
tech_pvt->asserted_id = switch_core_session_sprintf(tech_pvt->session, "\"%s\"<sip:%s@%s>",
use_name, use_number, rpid_domain);
}
} else {
tech_pvt->preferred_id = switch_core_session_sprintf(tech_pvt->session, "\"%s\"<sip:%s@%s>",
tech_pvt->caller_profile->caller_id_name,
tech_pvt->caller_profile->caller_id_number, rpid_domain);
if (zstr(tech_pvt->caller_profile->caller_id_name) || !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) {
tech_pvt->preferred_id = switch_core_session_sprintf(tech_pvt->session, "<sip:%s@%s>",
tech_pvt->caller_profile->caller_id_number, rpid_domain);
} else {
tech_pvt->preferred_id = switch_core_session_sprintf(tech_pvt->session, "\"%s\"<sip:%s@%s>",
tech_pvt->caller_profile->caller_id_name,
tech_pvt->caller_profile->caller_id_number, rpid_domain);
}
}
if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)) {
@@ -2503,7 +2601,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
} else {
tech_pvt->session_refresher = nua_no_refresher;
}
if (sofia_use_soa(tech_pvt)) {
nua_invite(tech_pvt->nh,
NUTAG_AUTOANSWER(0),
@@ -2517,8 +2615,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
TAG_IF(tech_pvt->redirected, NUTAG_URL(tech_pvt->redirected)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!zstr(recover_via), SIPTAG_VIA_STR(recover_via)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!zstr(tech_pvt->rpid), SIPTAG_REMOTE_PARTY_ID_STR(tech_pvt->rpid)),
TAG_IF(!zstr(tech_pvt->preferred_id), SIPTAG_P_PREFERRED_IDENTITY_STR(tech_pvt->preferred_id)),
TAG_IF(!zstr(tech_pvt->asserted_id), SIPTAG_P_ASSERTED_IDENTITY_STR(tech_pvt->asserted_id)),
@@ -2551,8 +2649,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
TAG_IF(tech_pvt->redirected, NUTAG_URL(tech_pvt->redirected)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!zstr(recover_via), SIPTAG_VIA_STR(recover_via)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!zstr(tech_pvt->rpid), SIPTAG_REMOTE_PARTY_ID_STR(tech_pvt->rpid)),
TAG_IF(!zstr(tech_pvt->preferred_id), SIPTAG_P_PREFERRED_IDENTITY_STR(tech_pvt->preferred_id)),
TAG_IF(!zstr(tech_pvt->asserted_id), SIPTAG_P_ASSERTED_IDENTITY_STR(tech_pvt->asserted_id)),
@@ -3475,6 +3573,14 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
if (switch_channel_test_flag(tech_pvt->channel, CF_ZRTP_PASS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_INFO, "Activating ZRTP PROXY MODE\n");
sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
switch_rtp_udptl_mode(tech_pvt->rtp_session);
}
video:
sofia_glue_check_video_codecs(tech_pvt);
@@ -3969,7 +4075,6 @@ int sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly)
}
sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
switch_channel_set_flag(tech_pvt->channel, CF_LEG_HOLDING);
switch_channel_mark_hold(tech_pvt->channel, SWITCH_TRUE);
switch_channel_presence(tech_pvt->channel, "unknown", msg, NULL);
changed = 1;
@@ -3997,7 +4102,6 @@ int sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly)
} else {
if (sofia_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) {
sofia_set_flag(tech_pvt, TFLAG_SIP_HOLD);
switch_channel_set_flag(tech_pvt->channel, CF_LEG_HOLDING);
switch_channel_mark_hold(tech_pvt->channel, SWITCH_TRUE);
changed = 1;
}
@@ -4030,7 +4134,6 @@ int sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly)
}
sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
switch_channel_clear_flag(tech_pvt->channel, CF_LEG_HOLDING);
switch_channel_mark_hold(tech_pvt->channel, SWITCH_FALSE);
switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL);
changed = 1;
@@ -4398,9 +4501,12 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
continue;
}
if (!strcasecmp(attr->a_name, "sendonly") || !strcasecmp(attr->a_name, "inactive")) {
if (!strcasecmp(attr->a_name, "sendonly")) {
sendonly = 1;
switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", "recvonly");
} else if (!strcasecmp(attr->a_name, "inactive")) {
sendonly = 1;
switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", "inactive");
} else if (!strcasecmp(attr->a_name, "recvonly")) {
switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", "sendonly");
recvonly = 1;
@@ -4580,12 +4686,13 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) {
switch_channel_set_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port", attr->a_value);
}
if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
} else if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
ptime = atoi(attr->a_value);
} else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
maxptime = atoi(attr->a_value);
} else if (!strcasecmp(attr->a_name, "zrtp-hash") && attr->a_value) {
switch_channel_set_variable(tech_pvt->channel, "sdp_zrtp_hash_string", attr->a_value);
switch_channel_set_flag(tech_pvt->channel, CF_ZRTP_HASH);
} else if (!got_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
int crypto_tag;
@@ -4599,7 +4706,8 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
crypto_tag = atoi(crypto);
if (tech_pvt->remote_crypto_key && switch_rtp_ready(tech_pvt->rtp_session)) {
if (crypto_tag && crypto_tag == tech_pvt->crypto_tag) {
/* Compare all the key. The tag may remain the same even if key changed */
if (crypto && !strcmp(crypto, tech_pvt->remote_crypto_key)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Existing key is still valid.\n");
} else {
const char *a = switch_stristr("AES", tech_pvt->remote_crypto_key);
@@ -5139,6 +5247,8 @@ char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup)
{
char *url = NULL, *e;
switch_assert(buf);
while(*buf == ' ') {
buf++;
}
@@ -5956,7 +6066,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
" presence_id VARCHAR(255),\n"
" presence_data VARCHAR(255),\n"
" call_info VARCHAR(255),\n"
" call_info_state VARCHAR(255),\n"
" call_info_state VARCHAR(255) default '',\n"
" expires INTEGER default 0,\n"
" status VARCHAR(255),\n"
" rpid VARCHAR(255),\n"
@@ -6868,24 +6978,6 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua
np->is_nat = NULL;
}
if (zstr(contact_host)) {
np->is_nat = "No contact host";
}
if (np->is_nat && !np->fs_path) {
contact_host = np->network_ip;
switch_snprintf(new_port, sizeof(new_port), ":%d", np->network_port);
port = NULL;
}
if (port) {
switch_snprintf(new_port, sizeof(new_port), ":%s", port);
}
ipv6 = strchr(contact_host, ':');
if (np->is_nat && np->fs_path) {
char *full_contact = sip_header_as_string(nh->nh_home, (void *) contact);
char *full_contact_dup;
@@ -6918,6 +7010,25 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua
free(path_val);
} else {
if (zstr(contact_host)) {
np->is_nat = "No contact host";
}
if (np->is_nat) {
contact_host = np->network_ip;
switch_snprintf(new_port, sizeof(new_port), ":%d", np->network_port);
port = NULL;
}
if (port) {
switch_snprintf(new_port, sizeof(new_port), ":%s", port);
}
ipv6 = strchr(contact_host, ':');
if (contact->m_url->url_params) {
contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s;%s>%s",
display, contact->m_url->url_user,
+384 -190
View File
@@ -55,7 +55,15 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t
static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char **columnNames);
static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv, char **columnNames);
struct pres_sql_cb {
sofia_profile_t *profile;
int ttl;
};
static int sofia_presence_send_sql(void *pArg, int argc, char **argv, char **columnNames);
struct dialog_helper {
char state[128];
char status[512];
char rpid[512];
char presence_id[1024];
@@ -115,6 +123,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
char header[256] = "";
char *route_uri = NULL;
const char *network_ip = NULL, *network_port = NULL, *from_proto;
char *extra_headers = NULL;
proto = switch_event_get_header(message_event, "proto");
from_proto = switch_event_get_header(message_event, "from_proto");
@@ -128,6 +137,8 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
network_ip = switch_event_get_header(message_event, "to_sip_ip");
network_port = switch_event_get_header(message_event, "to_sip_port");
extra_headers = sofia_glue_get_extra_headers_from_event(message_event, SOFIA_SIP_HEADER_PREFIX);
if (!to) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n");
goto end;
@@ -321,6 +332,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
SIPTAG_CONTENT_TYPE_STR(ct),
SIPTAG_PAYLOAD_STR(body),
SIPTAG_HEADER_STR(header),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_END());
sofia_glue_free_destination(dst);
@@ -454,16 +466,16 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
if ((pname = switch_event_get_header(event, "sofia-profile"))) {
profile = sofia_glue_find_profile(pname);
}
if (!profile) {
if (!host || !(profile = sofia_glue_find_profile(host))) {
char *sql;
char buf[512] = "";
switch_console_callback_match_t *matches;
sql = switch_mprintf("select profile_name from sip_registrations where hostname='%q' and profile_name='%q' and (sip_host='%s' or mwi_host='%s')",
mod_sofia_globals.hostname, profile->name, host, host);
sql = switch_mprintf("select profile_name from sip_registrations where hostname='%q' and (sip_host='%s' or mwi_host='%s')",
mod_sofia_globals.hostname, host, host);
if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
switch_console_callback_match_node_t *m;
@@ -481,7 +493,7 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
switch_console_free_matches(&matches);
}
switch_safe_free(sql);
if (!(profile = sofia_glue_find_profile(buf))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find profile %s\n", switch_str_nil(host));
@@ -491,6 +503,7 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
}
}
if (profile->domain_name && strcasecmp(profile->domain_name, host)) {
host = profile->domain_name;
}
@@ -547,8 +560,8 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
stream.data, mod_sofia_globals.hostname, profile->name, user, host);
} else if (call_id) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q' "
"from sip_registrations where hostname='%q' and profile_name='%q' and mwi_user='%q' and mwi_host='%q' and call_id='%q'",
mod_sofia_globals.hostname, profile->name, stream.data, user, host, call_id);
"from sip_registrations where hostname='%q' and profile_name='%q' and call_id='%q'",
stream.data, mod_sofia_globals.hostname, profile->name, call_id);
}
if (sql) {
@@ -570,14 +583,23 @@ static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, cha
{
struct dialog_helper *helper = (struct dialog_helper *) pArg;
if (argc == 3) {
switch_set_string(helper->status, argv[0]);
switch_set_string(helper->rpid, argv[1]);
switch_set_string(helper->presence_id, argv[2]);
if (argc >= 4) {
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK DIALOG state[%s] status[%s] rpid[%s] pres[%s]\n",
argv[0], argv[1], argv[2], argv[3]);
}
if (!helper->hits) {
switch_set_string(helper->state, argv[0]);
switch_set_string(helper->status, argv[1]);
switch_set_string(helper->rpid, argv[2]);
switch_set_string(helper->presence_id, argv[3]);
}
helper->hits++;
}
return -1;
return 0;
}
@@ -611,8 +633,8 @@ static void do_normal_probe(switch_event_t *event)
}
if (probe_euser && probe_host && (profile = sofia_glue_find_profile(probe_host))) {
sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs "
"where hostname='%q' and profile_name='%q' and "
sql = switch_mprintf("select state,status,rpid,presence_id from sip_dialogs "
"where hostname='%q' and profile_name='%q' and call_info_state != 'seized' and "
"((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host);
@@ -624,42 +646,42 @@ static void do_normal_probe(switch_event_t *event)
switch_safe_free(sql);
sql = switch_mprintf("select sip_registrations.sip_user, "
"sip_registrations.sub_host, "
"sip_registrations.status, "
"sip_registrations.rpid, "
"'', "
"sip_dialogs.uuid, "
"sip_dialogs.state, "
"sip_dialogs.direction, "
"sip_dialogs.sip_to_user, "
"sip_dialogs.sip_to_host, "
"sip_registrations.sub_host, "
"sip_registrations.status, "
"sip_registrations.rpid, "
"'', "
"sip_dialogs.uuid, "
"sip_dialogs.state, "
"sip_dialogs.direction, "
"sip_dialogs.sip_to_user, "
"sip_dialogs.sip_to_host, "
"sip_presence.status,"
"sip_presence.rpid,"
"sip_dialogs.presence_id, "
"sip_presence.open_closed,"
"'%q','%q','%q' "
"from sip_registrations "
"sip_presence.status,"
"sip_presence.rpid,"
"sip_dialogs.presence_id, "
"sip_presence.open_closed,"
"'%q','%q','%q' "
"from sip_registrations "
"left join sip_dialogs on "
"sip_dialogs.hostname = sip_registration.hostname and sip_dialogs.profile_name = sip_registration.profile_name and ("
"sip_dialogs.presence_id = sip_registrations.sip_user %q '@' %q sip_registrations.sub_host "
"or (sip_dialogs.sip_from_user = sip_registrations.sip_user "
"and sip_dialogs.sip_from_host = sip_registrations.sip_host)) "
"left join sip_dialogs on "
"sip_dialogs.hostname = sip_registrations.hostname and sip_dialogs.profile_name = sip_registrations.profile_name and ("
"sip_dialogs.presence_id = sip_registrations.sip_user %q '@' %q sip_registrations.sub_host "
"or (sip_dialogs.sip_from_user = sip_registrations.sip_user "
"and sip_dialogs.sip_from_host = sip_registrations.sip_host)) "
"left join sip_presence on "
"sip_presence.hostname=sip_registrations.hostname and "
"(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_server_host=sip_presence.sip_host and "
"sip_registrations.profile_name=sip_presence.profile_name) "
"where sip_registrations.hostname='%q' and sip_registrations.profile_name='%q' and sip_dialogs.call_info_state != 'seized' "
"and sip_dialogs.presence_id='%q@%q' or (sip_registrations.sip_user='%q' and "
"(sip_registrations.orig_server_host='%q' or sip_registrations.sub_host='%q' "
"))",
dh.status, dh.rpid, switch_str_nil(sub_call_id),
switch_sql_concat(), switch_sql_concat(),
mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host, probe_host);
"left join sip_presence on "
"sip_presence.hostname=sip_registrations.hostname and "
"(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_server_host=sip_presence.sip_host and "
"sip_registrations.profile_name=sip_presence.profile_name) "
"where sip_registrations.hostname='%q' and sip_registrations.profile_name='%q' and sip_dialogs.call_info_state != 'seized' "
"and sip_dialogs.presence_id='%q@%q' or (sip_registrations.sip_user='%q' and "
"(sip_registrations.orig_server_host='%q' or sip_registrations.sub_host='%q' "
"))",
dh.status, dh.rpid, switch_str_nil(sub_call_id),
switch_sql_concat(), switch_sql_concat(),
mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host, probe_host);
switch_assert(sql);
@@ -686,7 +708,7 @@ static void do_normal_probe(switch_event_t *event)
"from sip_dialogs "
"where hostname='%q' and profile_name='%q' and (presence_id='%q@%q' or "
"where call_info_state != 'seized' and hostname='%q' and profile_name='%q' and (presence_id='%q@%q' or "
"(sip_from_user='%q' and (sip_from_host='%q' or sip_to_host='%q')))",
mod_sofia_globals.hostname, profile->name,
dh.status, dh.rpid, probe_euser, probe_host, probe_euser, probe_host, probe_host);
@@ -854,8 +876,11 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
char *call_id = switch_event_get_header(event, "call-id");
char *presence_source = switch_event_get_header(event, "presence-source");
char *call_info_state = switch_event_get_header(event, "presence-call-info-state");
const char *uuid = switch_event_get_header(event, "unique-id");
switch_console_callback_match_t *matches;
struct presence_helper helper = { 0 };
int hup = 0;
if (!mod_sofia_globals.running) {
return;
@@ -877,6 +902,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
if (status && switch_stristr("CS_HANGUP", status)) {
status = "Available";
hup = 1;
}
if (rpid) {
@@ -884,89 +910,95 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
if (event->event_id == SWITCH_EVENT_ROSTER) {
struct presence_helper helper = { 0 };
if (!mod_sofia_globals.profile_hash) {
return;
}
if (from) {
sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
"sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
mod_sofia_globals.hostname, profile->name, from);
if (mod_sofia_globals.debug_presence > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
"sip_subscriptions.accept,sip_subscriptions.profile_name,sip_subscriptions.network_ip"
",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'','','','','sip',"
" sip_subscriptions.full_to,sip_subscriptions.network_ip,sip_subscriptions.network_port "
"from sip_subscriptions left join sip_presence on "
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
"sip_subscriptions.profile_name=sip_presence.profile_name and sip_presence.profile_name=sip_subscriptions.profile_name) "
"where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
"sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
switch_str_nil(status), switch_str_nil(rpid), mod_sofia_globals.hostname, profile->name, from);
} else {
sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
"sip_subscriptions.event='presence'", mod_sofia_globals.hostname, profile->name);
if (mod_sofia_globals.debug_presence > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
"sip_subscriptions.accept,sip_subscriptions.profile_name,sip_subscriptions.network_ip"
",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'','','','','sip',"
"sip_subscriptions.full_to,sip_subscriptions.network_ip,sip_subscriptions.network_port "
"from sip_subscriptions left join sip_presence on "
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
"sip_subscriptions.profile_name=sip_presence.profile_name and sip_subscriptions.hostname = sip_presence.hostname) "
"where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
"sip_subscriptions.event='presence'", switch_str_nil(status),
switch_str_nil(rpid), mod_sofia_globals.hostname, profile->name);
}
switch_assert(sql != NULL);
if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
switch_console_callback_match_node_t *m;
for (m = matches->head; m; m = m->next) {
if ((profile = sofia_glue_find_profile(m->val))) {
if (profile->pres_type != PRES_TYPE_FULL) {
if (!mod_sofia_globals.profile_hash) {
return;
}
if (from) {
sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
"sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
mod_sofia_globals.hostname, profile->name, from);
if (mod_sofia_globals.debug_presence > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
"sip_subscriptions.accept,sip_subscriptions.profile_name,sip_subscriptions.network_ip"
",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'','','','','sip',"
" sip_subscriptions.full_to,sip_subscriptions.network_ip,sip_subscriptions.network_port "
"from sip_subscriptions left join sip_presence on "
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and "
"sip_subscriptions.sub_to_host=sip_presence.sip_host and "
"sip_subscriptions.profile_name=sip_presence.profile_name and "
"sip_presence.profile_name=sip_subscriptions.profile_name) "
"where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
"sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
switch_str_nil(status), switch_str_nil(rpid), mod_sofia_globals.hostname, profile->name, from);
} else {
sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
"sip_subscriptions.event='presence'", mod_sofia_globals.hostname, profile->name);
if (mod_sofia_globals.debug_presence > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
"sip_subscriptions.accept,sip_subscriptions.profile_name,sip_subscriptions.network_ip"
",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'','','','','sip',"
"sip_subscriptions.full_to,sip_subscriptions.network_ip,sip_subscriptions.network_port "
"from sip_subscriptions left join sip_presence on "
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and "
"sip_subscriptions.sub_to_host=sip_presence.sip_host and "
"sip_subscriptions.profile_name=sip_presence.profile_name and "
"sip_subscriptions.hostname = sip_presence.hostname) "
"where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
"sip_subscriptions.event='presence'", switch_str_nil(status),
switch_str_nil(rpid), mod_sofia_globals.hostname, profile->name);
}
switch_assert(sql != NULL);
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is passive, skipping\n", (char *) profile->name);
}
sofia_glue_release_profile(profile);
continue;
}
memset(&helper, 0, sizeof(helper));
helper.profile = profile;
helper.event = NULL;
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper);
switch_safe_free(sql);
sofia_glue_release_profile(profile);
}
}
switch_console_free_matches(&matches);
}
free(sql);
switch_safe_free(sql);
return;
}
@@ -1040,9 +1072,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
continue;
}
if (call_info) {
const char *uuid = switch_event_get_header(event, "unique-id");
if (call_info) {
#if 0
if (mod_sofia_globals.debug_sla > 1) {
@@ -1078,19 +1108,65 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
if (!strcmp(proto, "dp")) {
sql = switch_mprintf("update sip_presence set rpid='%q',status='%q' where hostname='%q' nad profile_name='%q' and "
sql = switch_mprintf("update sip_presence set rpid='%q',status='%q' where hostname='%q' and profile_name='%q' and "
"sip_user='%q' and sip_host='%q'",
rpid, status, mod_sofia_globals.hostname, profile->name, euser, host);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs "
"where hostname='%q' and profile_name='%q' and "
"((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
mod_sofia_globals.hostname, profile->name, euser, host, euser, host);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh);
switch_safe_free(sql);
if (zstr(uuid)) {
sql = switch_mprintf("select state,status,rpid,presence_id from sip_dialogs "
"where call_info_state != 'seized' and hostname='%q' and profile_name='%q' and "
"((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
mod_sofia_globals.hostname, profile->name, euser, host, euser, host);
} else {
sql = switch_mprintf("select state,status,rpid,presence_id from sip_dialogs "
"where uuid != '%q' and call_info_state != 'seized' and hostname='%q' and profile_name='%q' and "
"((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
uuid, mod_sofia_globals.hostname, profile->name, euser, host, euser, host);
}
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK SQL: %s@%s [%s]\nhits: %d\n", euser, host, sql, dh.hits);
}
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh);
switch_safe_free(sql);
#if 0
if (hup && dh.hits > 0) {
/* sigh, mangle this packet to simulate a call that is up instead of hungup */
event->flags |= EF_UNIQ_HEADERS;
if (!strcasecmp(dh.state, "early")) {
status = "CS_ROUTING";
if (rpid) {
rpid = sofia_presence_translate_rpid(rpid, status);
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "early");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", "EARLY");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "early");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "early");
} else {
status = "CS_EXECUTE";
if (rpid) {
rpid = sofia_presence_translate_rpid(rpid, status);
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "answered");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", "ACTIVE");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "confirmed");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed");
}
}
#endif
if (zstr(call_id) && (dh.hits && presence_source && (!strcasecmp(presence_source, "register") || switch_stristr("register", status)))) {
goto done;
@@ -1207,25 +1283,22 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
}
#if 0
if (event) {
const char *refresh = switch_event_get_header(event, "refresh");
if (switch_true(refresh)) {
switch_event_t *s_event;
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", euser, host);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", euser, host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_fire(&s_event);
}
if (hup) {
/* so many phones get confused when whe hangup we have to reprobe to get them all to reset to absolute states so the lights stay correct */
switch_event_t *s_event;
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", euser, host);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", euser, host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_fire(&s_event);
}
}
#endif
if (!zstr((char *) helper.stream.data)) {
char *this_sql = (char *) helper.stream.data;
char *next = NULL;
@@ -1506,7 +1579,7 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-id", call_id);
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "resub", "true");
//switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "resub", "true");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
@@ -1538,12 +1611,9 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
}
}
switch_event_fire(&event);
}
switch_safe_free(free_me);
@@ -1779,8 +1849,13 @@ static void _send_presence_notify(sofia_profile_t *profile,
sofia_destination_t *dst = NULL;
char *contact_str, *contact, *user_via = NULL;
char *route_uri = NULL, *o_contact_dup = NULL, *tmp;
char *route_uri = NULL, *o_contact_dup = NULL, *tmp, *to_uri, *dcs = NULL;
const char *tp;
if (zstr(full_to) || zstr(full_from) || zstr(o_contact)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "MISSING DATA TO SEND NOTIFY.\n");
return;
}
tmp = (char *)o_contact;
o_contact_dup = sofia_glue_get_url_from_contact(tmp, 1);
@@ -1826,6 +1901,27 @@ static void _send_presence_notify(sofia_profile_t *profile,
} else {
contact_str = our_contact;
}
if ((to_uri = sofia_glue_get_url_from_contact((char *)full_to, 1))) {
char *p;
if ((p = strstr(to_uri, "sip:"))) {
char *q;
p += 4;
if ((q = strchr(p, '@'))) {
*q++ = '\0';
if ((dcs = switch_string_replace(contact_str, "mod_sofia", p))) {
contact_str = dcs;
}
}
}
free(to_uri);
}
dst = sofia_glue_get_destination((char *) o_contact);
switch_assert(dst);
@@ -1840,7 +1936,7 @@ static void _send_presence_notify(sofia_profile_t *profile,
route_uri = sofia_glue_strip_uri(dst->route_uri);
} else {
if (remote_ip && remote_port) {
route_uri = switch_mprintf("sip:%s:%s;transport=%s", remote_ip, remote_port, tp);
route_uri = switch_mprintf("sip:user@%s:%s;transport=%s", remote_ip, remote_port, tp);
}
}
@@ -1854,15 +1950,13 @@ static void _send_presence_notify(sofia_profile_t *profile,
}
}
if (exptime <= 0) {
switch_snprintf(sstr, sizeof(sstr), "terminated;reason=noresource");
} else {
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", (unsigned) exptime);
}
if (mod_sofia_globals.debug_presence > 1) {
if (mod_sofia_globals.debug_presence > 1 || mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SEND PRES NOTIFY:\n"
"file[%s]\nfunc[%s]\nline[%d]\n"
"profile[%s]\nvia[%s]\nip[%s]\nport[%s]\nroute[%s]\ncontact[%s]\nto[%s]\nfrom[%s]\nurl[%s]\ncall_id[%s]\nexpires_str[%s]\n"
@@ -1903,7 +1997,8 @@ static void _send_presence_notify(sofia_profile_t *profile,
nua_notify(nh,
NUTAG_NEWSUB(1),
TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
@@ -1922,13 +2017,14 @@ static void _send_presence_notify(sofia_profile_t *profile,
TAG_END());
switch_safe_free(route_uri);
switch_safe_free(dcs);
switch_safe_free(contact);
sofia_glue_free_destination(dst);
switch_safe_free(user_via);
switch_safe_free(o_contact_dup);
switch_safe_free(our_contact_dup);
}
@@ -2183,7 +2279,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
char *open_closed = NULL;
char *dialog_status = NULL;
char *dialog_rpid = NULL;
char *default_dialog = "partial";
const char *ct = "no/idea";
char *to = NULL;
@@ -2329,15 +2425,19 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
const char *astate = switch_str_nil(switch_event_get_header(helper->event, "astate"));
const char *answer_state = switch_str_nil(switch_event_get_header(helper->event, "answer-state"));
const char *dft_state;
const char *from_id;
const char *from_id = NULL, *from_name = NULL;
const char *to_user = switch_str_nil(switch_event_get_header(helper->event, "variable_sip_to_user"));
const char *from_user = switch_str_nil(switch_event_get_header(helper->event, "variable_sip_from_user"));
char *clean_to_user = NULL;
char *clean_from_user = NULL;
int force_status = 0;
const char *call_state = switch_event_get_header(helper->event, "channel-state");
char *call_info_state = switch_event_get_header(helper->event, "presence-call-info-state");
if (user_agent && switch_stristr("snom", user_agent) && uuid) {
default_dialog = "full" ;
}
if (call_state && !strcasecmp(call_state, "cs_hangup")) {
astate = "hangup";
}
@@ -2356,9 +2456,21 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!strcasecmp(direction, "inbound")) {
from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Destination-Number"));
} else {
from_id = switch_str_nil(switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Number"));
from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Caller-ID-Number"));
from_name = switch_event_get_header(helper->event, "Caller-Caller-ID-Name");
if (zstr(from_id)) {
from_id = switch_str_nil(switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Number"));
}
if (zstr(from_name)) {
from_name = switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Name");
}
}
#if 0
char *buf;
switch_event_serialize(helper->event, &buf, SWITCH_FALSE);
@@ -2400,8 +2512,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
stream.write_function(&stream,
"<?xml version=\"1.0\"?>\n"
"<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" "
"version=\"%s\" state=\"partial\" entity=\"%s\">\n", version, clean_id);
"version=\"%s\" state=\"%s\" entity=\"%s\">\n", version, default_dialog, clean_id);
}
@@ -2421,11 +2532,8 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!strcasecmp(astate, "answered")) {
astate = "confirmed";
}
if (!strcasecmp(astate, "hangup")) {
astate = "terminated";
}
if (is_dialog) {
if (!strcasecmp(astate, "ringing")) {
@@ -2439,6 +2547,11 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (holding) {
astate = "early";
}
if (!strcasecmp(astate, "hangup")) {
astate = "terminated";
}
stream.write_function(&stream, "<dialog id=\"%s\" direction=\"%s\">\n", uuid, direction);
stream.write_function(&stream, "<state>%s</state>\n", astate);
@@ -2447,8 +2560,13 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
astate = "early";
}
}
if (sofia_test_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY) &&
(!zstr(call_info_state) && (!strcasecmp(call_info_state, "alterting") || !strcasecmp(call_info_state, "progressing")))) {
goto end;
}
if (!strcasecmp(astate, "early") || !strcasecmp(astate, "confirmed")) {
clean_to_user = switch_mprintf("%s", sub_to_user ? sub_to_user : to_user);
@@ -2464,11 +2582,13 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (switch_true(switch_event_get_header(helper->event, "Presence-Privacy"))) {
stream.write_function(&stream, "<remote>\n<identity display=\"Anonymous\">sip:anonymous@anonymous.invalid</identity>\n");
} else {
stream.write_function(&stream, "<remote>\n<identity display=\"%s\">sip:%s@%s</identity>\n", clean_from_user, clean_from_user,
stream.write_function(&stream, "<remote>\n<identity display=\"%s\">sip:%s@%s</identity>\n",
from_name ? from_name : clean_from_user, clean_from_user,
host);
}
stream.write_function(&stream, "<target uri=\"sip:**%s@%s\"/>\n", clean_to_user, host);
stream.write_function(&stream, "</remote>\n");
} else if (!strcasecmp(proto, "queue")) {
stream.write_function(&stream, "<local>\n<identity display=\"queue\">sip:%s@%s;proto=queue</identity>\n",
!zstr(clean_to_user) ? clean_to_user : "unknown", host);
@@ -2582,7 +2702,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
rpid = "on-the-phone";
force_status = 1;
} else if (!strcmp(astate, "terminated")) {
} else if (!strcmp(astate, "terminated") || !strcmp(astate, "hangup")) {
rpid = "online";
dialog_rpid = "";
force_event_status = "Available";
@@ -2666,6 +2786,9 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
send_presence_notify(profile, full_to, full_from, contact, expires, call_id, event, ip, port, ct, pl, NULL);
end:
switch_safe_free(free_me);
if (ext_profile) {
@@ -2918,6 +3041,85 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t
char *sql;
int total = 0;
if (clear) {
struct pres_sql_cb cb = {profile, 0};
if (call_id) {
sql = switch_mprintf("update sip_subscriptions set version=version+1,expires=%ld where "
"call_id='%q' "
"and event='line-seize'", (long) switch_epoch_time_now(NULL),
call_id);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
}
switch_safe_free(sql);
sql = switch_mprintf("select full_to, full_from, contact, -1, call_id, event, network_ip, network_port, "
"NULL as ct, NULL as pt "
" from sip_subscriptions where call_id='%q' "
"and event='line-seize'", call_id);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, &cb);
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
}
switch_safe_free(sql);
} else {
sql = switch_mprintf("update sip_subscriptions set version=version+1,expires=%ld where "
"hostname='%q' and profile_name='%q' "
"and sub_to_user='%q' and sub_to_host='%q' "
"and event='line-seize'", (long) switch_epoch_time_now(NULL),
mod_sofia_globals.hostname, profile->name, to_user, to_host
);
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sql = switch_mprintf("select full_to, full_from, contact, -1, call_id, event, network_ip, network_port, "
"NULL as ct, NULL as pt "
" from sip_subscriptions where "
"hostname='%q' and profile_name='%q' "
"and sub_to_user='%q' and sub_to_host='%q' "
"and event='line-seized'",
mod_sofia_globals.hostname, profile->name, to_user, to_host
);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, &cb);
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
}
switch_safe_free(sql);
}
sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and profile_name='%q' and "
"((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
"and call_info_state='seized'", mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host);
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
switch_safe_free(sql);
}
switch_core_new_memory_pool(&pool);
sh = switch_core_alloc(pool, sizeof(*sh));
sh->pool = pool;
@@ -2941,13 +3143,14 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t
if (unseize) {
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
"from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q')",
mod_sofia_globals.hostname, call_id, profile->name);
"from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q' "
"and (event='call-info' or event='line-seize')",
call_id, mod_sofia_globals.hostname, profile->name);
} else {
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
"from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q'",
mod_sofia_globals.hostname, call_id, profile->name);
"from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q' and event='call-info'",
call_id, mod_sofia_globals.hostname, profile->name);
}
} else {
@@ -2982,17 +3185,7 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t
if (clear) {
sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and profile_name='%q' and "
"((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
"and call_info_state='seized'", mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host);
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
return total;
@@ -3215,7 +3408,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
np.network_port, np.network_ip, orig_proto, full_to, to_tag);
switch_assert(sql != NULL);
if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n%s\n",
@@ -3352,6 +3545,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
SIPTAG_EVENT_STR("line-seize"), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info)), TAG_END());
sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and profile_name='%q' and "
@@ -3461,15 +3655,18 @@ void sofia_presence_handle_sip_i_subscribe(int status,
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sub-call-id", call_id);
switch_event_fire(&sevent);
}
} else {
if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
} else if (!strcasecmp(event, "presence")) {
if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "presence-source", "subscribe");
switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, to_host);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "rpid", "unknown");
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Registered");
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sub-call-id", call_id);
switch_event_fire(&sevent);
}
}
@@ -3584,10 +3781,6 @@ void sofia_presence_handle_sip_r_subscribe(int status,
}
}
struct pres_sql_cb {
sofia_profile_t *profile;
int ttl;
};
static int sofia_presence_send_sql(void *pArg, int argc, char **argv, char **columnNames)
{
@@ -3636,9 +3829,10 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
char expstr[30] = "";
long exp = 0, exp_delta = 3600;
char *pd_dup = NULL;
int count = 1, sub_count = 0;
int count = 1, sub_count = 1;
char *contact_str;
int open = 1;
sofia_nat_parse_t np = { { 0 } };
if (!sip) {
return;
@@ -3647,7 +3841,8 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
from = sip->sip_from;
payload = sip->sip_payload;
contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, NULL);
np.fs_path = 1;
contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, &np);
if (from) {
from_user = (char *) from->a_url->url_user;
@@ -3699,9 +3894,8 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
if (sofia_test_pflag(profile, PFLAG_MULTIREG) && !open) {
count = sofia_reg_reg_count(profile, from_user, from_host);
sub_count = sofia_presence_contact_count(profile, contact_str);
}
sub_count = sofia_presence_contact_count(profile, contact_str);
/* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */
@@ -3925,7 +4119,7 @@ void sofia_presence_handle_sip_i_message(int status,
end:
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
}
+11 -8
View File
@@ -460,20 +460,20 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
{
int sec;
if (gateway_ptr->failure_status == 503 || gateway_ptr->failure_status == 908) {
if (gateway_ptr->failure_status == 503 || gateway_ptr->failure_status == 908 || gateway_ptr->failures < 1) {
sec = gateway_ptr->retry_seconds;
} else {
sec = gateway_ptr->retry_seconds * (gateway_ptr->failures + 1);
sec = gateway_ptr->retry_seconds * gateway_ptr->failures;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s Failed Registration [%d], setting retry to %d seconds.\n",
gateway_ptr->name, gateway_ptr->failure_status, sec);
gateway_ptr->retry = switch_epoch_time_now(NULL) + sec;
gateway_ptr->status = SOFIA_GATEWAY_DOWN;
gateway_ptr->state = REG_STATE_FAIL_WAIT;
gateway_ptr->failure_status = 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s Failed Registration [%d], setting retry to %d seconds.\n",
gateway_ptr->name, gateway_ptr->failure_status, sec);
}
break;
case REG_STATE_FAIL_WAIT:
@@ -1651,7 +1651,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
if (switch_event_create(&s_mwi_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host);
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Pofile", profile->name);
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Call-ID", call_id);
}
}
@@ -2101,7 +2101,8 @@ void sofia_reg_handle_sip_r_challenge(int status,
} else if (gateway) {
switch_snprintf(authentication, sizeof(authentication), "%s:%s:%s:%s", scheme, realm, gateway->auth_username, gateway->register_password);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot locate any authentication credentials to complete an authentication request for realm '%s'\n", realm);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"Cannot locate any authentication credentials to complete an authentication request for realm '%s'\n", realm);
goto cancel;
}
@@ -2114,7 +2115,9 @@ void sofia_reg_handle_sip_r_challenge(int status,
tl_gets(tags, NUTAG_CALLSTATE_REF(ss_state), SIPTAG_WWW_AUTHENTICATE_REF(authenticate), TAG_END());
nua_authenticate(nh, SIPTAG_EXPIRES_STR(gateway ? gateway->expires_str : "3600"), NUTAG_AUTH(authentication), TAG_END());
nua_authenticate(nh,
TAG_IF(sofia_private && sofia_private->gateway, SIPTAG_EXPIRES_STR(gateway ? gateway->expires_str : "3600")),
NUTAG_AUTH(authentication), TAG_END());
goto end;