Merge branch 'netborder'

This commit is contained in:
David Yat Sin 2010-11-22 15:16:10 -05:00
commit 8e142ff22a
25 changed files with 862 additions and 1314 deletions

View File

@ -13,7 +13,6 @@
<param name="time-base-score" value="system"/>
<param name="max-wait-time" value="0"/>
<param name="max-wait-time-with-no-agent" value="0"/>
<param name="max-wait-time-with-no-agent-time-reached" value="5"/>
<param name="tier-rules-apply" value="false"/>
<param name="tier-rule-wait-second" value="300"/>
<param name="tier-rule-wait-multiply-level" value="true"/>

View File

@ -2,16 +2,7 @@
<settings>
<param name="listen-ip" value="0.0.0.0"/>
<param name="listen-port" value="8031"/>
<!-- Specify the first part of the node name
(the host part after the @ will be autodetected)
OR pass a complete nodename to avoid autodetection
eg. freeswitch@example or freeswitch@example.com.
If you pass a complete node name, the 'shortname' parameter has no effect. -->
<param name="nodename" value="freeswitch"/>
<!-- Specify this OR 'cookie-file' or $HOME/.erlang.cookie will be read -->
<param name="cookie" value="ClueCon"/>
<!-- Read a cookie from an arbitary erlang cookie file instead -->
<!--<param name="cookie-file" value="/tmp/erlang.cookie"/>-->
<param name="shortname" value="true"/>
<!-- in additon to cookie, optionally restrict by ACL -->
<!--<param name="apply-inbound-acl" value="lan"/>-->

View File

@ -1,113 +1,17 @@
<configuration name="modules.conf" description="Modules">
<modules>
<!-- Loggers (I'd load these first) -->
<load module="mod_console"/>
<load module="mod_logfile"/>
<!-- <load module="mod_syslog"/> -->
<!--<load module="mod_yaml"/>-->
<!-- Multi-Faceted -->
<!-- mod_enum is a dialplan interface, an application interface and an api command interface -->
<load module="mod_enum"/>
<!-- XML Interfaces -->
<!-- <load module="mod_xml_rpc"/> -->
<!-- <load module="mod_xml_curl"/> -->
<!-- <load module="mod_xml_cdr"/> -->
<!-- Event Handlers -->
<load module="mod_cdr_csv"/>
<!-- <load module="mod_event_multicast"/> -->
<load module="mod_event_socket"/>
<!-- <load module="mod_zeroconf"/> -->
<!-- <load module="mod_erlang_event"/> -->
<!-- Directory Interfaces -->
<!-- <load module="mod_ldap"/> -->
<!-- Endpoints -->
<!-- <load module="mod_dingaling"/> -->
<!-- <load module="mod_portaudio"/> -->
<!-- <load module="mod_alsa"/> -->
<load module="mod_sofia"/>
<load module="mod_loopback"/>
<!-- <load module="mod_woomera"/> -->
<!-- <load module="mod_freetdm"/> -->
<!-- <load module="mod_openzap"/> -->
<!-- <load module="mod_unicall"/> -->
<!-- <load module="mod_skinny"/> -->
<!-- Applications -->
<load module="mod_commands"/>
<load module="mod_conference"/>
<load module="mod_db"/>
<load module="mod_dptools"/>
<load module="mod_expr"/>
<load module="mod_fifo"/>
<load module="mod_hash"/>
<load module="mod_voicemail"/>
<!--<load module="mod_directory"/>-->
<!--<load module="mod_lcr"/>-->
<load module="mod_esf"/>
<load module="mod_fsv"/>
<load module="mod_cluechoo"/>
<load module="mod_valet_parking"/>
<!--<load module="mod_spy"/>-->
<!-- SNOM Module -->
<!--<load module="mod_snom"/>-->
<!-- Dialplan Interfaces -->
<!-- <load module="mod_dialplan_directory"/> -->
<load module="mod_dialplan_xml"/>
<load module="mod_dialplan_asterisk"/>
<!-- Codec Interfaces -->
<load module="mod_spandsp"/>
<load module="mod_g723_1"/>
<load module="mod_g729"/>
<load module="mod_amr"/>
<load module="mod_ilbc"/>
<load module="mod_speex"/>
<load module="mod_h26x"/>
<load module="mod_siren"/>
<!--<load module="mod_celt"/>-->
<!-- File Format Interfaces -->
<load module="mod_sndfile"/>
<load module="mod_native_file"/>
<!--For icecast/mp3 streams/files-->
<!--<load module="mod_shout"/>-->
<!--For local streams (play all the files in a directory)-->
<load module="mod_local_stream"/>
<load module="mod_tone_stream"/>
<load module="mod_file_string"/>
<!-- Timers -->
<!-- Languages -->
<load module="mod_spidermonkey"/>
<!-- <load module="mod_perl"/> -->
<!-- <load module="mod_python"/> -->
<!-- <load module="mod_java"/> -->
<load module="mod_lua"/>
<!-- ASR /TTS -->
<!-- <load module="mod_flite"/> -->
<!-- <load module="mod_pocketsphinx"/> -->
<!-- <load module="mod_cepstral"/> -->
<!-- <load module="mod_tts_commandline"/> -->
<!-- <load module="mod_rss"/> -->
<!-- Say -->
<load module="mod_say_en"/>
<load module="mod_say_ru"/>
<!-- <load module="mod_say_zh"/> -->
<!-- Third party modules -->
<!--<load module="mod_nibblebill"/>-->
</modules>
</configuration>

View File

@ -15,11 +15,6 @@
<key name="12" value="version"/>
</cli-keybindings>
<default-ptimes>
<!-- set this to overide the 20ms assumption of various codecs in the sdp with no ptime defined -->
<!--<codec name="G729" ptime="40"/>-->
</default-ptimes>
<settings>
<!--Colorize the Console -->
<param name="colorize-console" value="true"/>
@ -86,7 +81,6 @@
<!-- <param name="core-db-dsn" value="dsn:username:password" /> -->
<!-- The system will create all the db schemas automatically, set this to false to avoid this behaviour-->
<!--<param name="auto-create-schemas" value="true"/>-->
<!-- <param name="core-dbtype" value="MSSQL"/> -->
</settings>
</configuration>

View File

@ -33,10 +33,9 @@
<param name="ff-key" value="6"/>
<param name="rew-key" value="4"/>
<param name="skip-greet-key" value="#"/>
<param name="previous-message-key" value="1"/>-->
<param name="next-message-key" value="3"/>
<param name="skip-info-key" value="*"/>
<param name="repeat-message-key" value="0"/>
<!--<param name="previous-message-key" value=""/>-->
<!--<param name="next-message-key" value=""/>-->
<!--<param name="skip-info-key" value=""/>-->
<param name="record-silence-threshold" value="200"/>
<param name="record-silence-hits" value="2"/>
<param name="web-template-file" value="web-vm.tpl"/>

View File

@ -1,763 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
NOTICE:
This context is usually accessed via authenticated callers on the sip profile on port 5060
or transfered callers from the public context which arrived via the sip profile on port 5080.
Authenticated users will use the user_context variable on the user to determine what context
they can access. You can also add a user in the directory with the cidr= attribute acl.conf.xml
will build the domains ACL using this value.
-->
<!-- http://wiki.freeswitch.org/wiki/Dialplan_XML -->
<include>
<context name="default">
<extension name="unloop">
<condition field="${unroll_loops}" expression="^true$"/>
<condition field="${sip_looped_call}" expression="^true$">
<action application="deflect" data="${destination_number}"/>
</condition>
</extension>
<!-- Example of doing things based on time of day.
year = 4 digit year. Example year="2009"
yday = 1-365
mon = 1-12
mday = 1-31
week = 1-52
mweek= 1-6
wday = 1-7
hour = 0-23
minute = 0-59
minute-of-day = 1-1440
Example:
<condition minute-of-day="540-1080"> (9am to 6pm EVERY day)
do something ...
</condition>
-->
<extension name="tod_example" continue="true">
<condition wday="2-6" hour="9-18">
<action application="set" data="open=true"/>
</condition>
</extension>
<!-- Example of routing based on holidays
This example covers all US Federal holidays except for inauguration day.
-->
<extension name="holiday_example" continue="true">
<condition mday="1" mon="1">
<!-- new year's day -->
<action application="set" data="open=false"/>
</condition>
<condition wday="2" mweek="3" mon="1">
<!-- martin luther king day is the 3rd monday in january -->
<action application="set" data="open=false"/>
</condition>
<condition wday="2" mweek="3" mon="2">
<!-- president's day is the 3rd monday in february -->
<action application="set" data="open=false"/>
</condition>
<condition wday="2" mon="5" mday="25-31">
<!-- memorial day is the last monday in may (the only monday between the 25th and the 31st) -->
<action application="set" data="open=false"/>
</condition>
<condition mday="4" mon="7">
<!-- independence day -->
<action application="set" data="open=false"/>
</condition>
<condition wday="2" mweek="1" mon="9">
<!-- labor day is the 1st monday in september -->
<action application="set" data="open=false"/>
</condition>
<condition wday="2" mweek="2" mon="10">
<!-- columbus day is the 2nd monday in october -->
<action application="set" data="open=false"/>
</condition>
<condition mday="11" mon="11">
<!-- veteran's day -->
<action application="set" data="open=false"/>
</condition>
<condition wday="5-6" mweek="4" mon="11">
<!-- thanksgiving is the 4th thursday in november and usually there's an extension for black friday -->
<action application="set" data="open=false"/>
</condition>
<condition mday="25" mon="12">
<!-- Christmas -->
<action application="set" data="open=false"/>
</condition>
</extension>
<extension name="global-intercept">
<condition field="destination_number" expression="^886$">
<action application="answer"/>
<action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/global)}"/>
<action application="sleep" data="2000"/>
</condition>
</extension>
<extension name="group-intercept">
<condition field="destination_number" expression="^\*8$">
<action application="answer"/>
<action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/${callgroup})}"/>
<action application="sleep" data="2000"/>
</condition>
</extension>
<extension name="intercept-ext">
<condition field="destination_number" expression="^\*\*(\d+)$">
<action application="answer"/>
<action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/$1)}"/>
<action application="sleep" data="2000"/>
</condition>
</extension>
<extension name="redial">
<condition field="destination_number" expression="^(redial|870)$">
<action application="transfer" data="${hash(select/${domain_name}-last_dial/${caller_id_number})}"/>
</condition>
</extension>
<extension name="global" continue="true">
<condition field="${call_debug}" expression="^true$" break="never">
<action application="info"/>
</condition>
<!--
This is an example of how to auto detect if telephone-event is missing and activate inband detection
-->
<!--
<condition field="${switch_r_sdp}" expression="a=rtpmap:(\d+)\stelephone-event/8000" break="never">
<action application="set" data="rtp_payload_number=$1"/>
<anti-action application="start_dtmf"/>
</condition>
-->
<condition field="${sip_has_crypto}" expression="^(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)$" break="never">
<action application="set" data="sip_secure_media=true"/>
<!-- Offer SRTP on outbound legs if we have it on inbound. -->
<!-- <action application="export" data="sip_secure_media=true"/> -->
</condition>
<condition>
<action application="hash" data="insert/${domain_name}-spymap/${caller_id_number}/${uuid}"/>
<action application="hash" data="insert/${domain_name}-last_dial/${caller_id_number}/${destination_number}"/>
<action application="hash" data="insert/${domain_name}-last_dial/global/${uuid}"/>
<action application="set" data="RFC2822_DATE=${strftime(%a, %d %b %Y %T %z)}"/>
</condition>
</extension>
<!-- If sip_req_host is not a local domain then this has to be an external sip uri -->
<!--
<extension name="external_sip_uri" continue="true">
<condition field="source" expression="mod_sofia"/>
<condition field="${outside_call}" expression="^$"/>
<condition field="${domain_exists(${sip_req_host})}" expression="true">
<anti-action application="bridge" data="sofia/${use_profile}/${sip_to_uri}"/>
</condition>
</extension>
-->
<!--
Snom button demo, call 9000 to make button 2 mapped to transfer the current call to a conference
-->
<extension name="snom-demo-2">
<condition field="destination_number" expression="^9001$">
<action application="eval" data="${snom_bind_key(2 off DND ${sip_from_user} ${sip_from_host} ${sofia_profile_name} message notused)}"/>
<action application="transfer" data="3000"/>
</condition>
</extension>
<extension name="snom-demo-1">
<condition field="destination_number" expression="^9000$">
<!--<key> <light> <label> <user> <host> <profile> <action_name> <action>-->
<action application="eval" data="${snom_bind_key(2 on DND ${sip_from_user} ${sip_from_host} ${sofia_profile_name} message api+uuid_transfer ${uuid} 9001)}"/>
<action application="playback" data="$${hold_music}"/>
</condition>
</extension>
<extension name="eavesdrop">
<condition field="destination_number" expression="^88(\d{4})$|^\*0(.*)$">
<action application="answer"/>
<action application="eavesdrop" data="${hash(select/${domain_name}-spymap/$1)}"/>
</condition>
</extension>
<extension name="eavesdrop">
<condition field="destination_number" expression="^779$">
<action application="answer"/>
<action application="set" data="eavesdrop_indicate_failed=tone_stream://%(500, 0, 320)"/>
<action application="set" data="eavesdrop_indicate_new=tone_stream://%(500, 0, 620)"/>
<action application="set" data="eavesdrop_indicate_idle=tone_stream://%(250, 0, 920)"/>
<action application="eavesdrop" data="all"/>
</condition>
</extension>
<extension name="call_return">
<condition field="destination_number" expression="^\*69$|^869$|^lcr$">
<action application="transfer" data="${hash(select/${domain_name}-call_return/${caller_id_number})}"/>
</condition>
</extension>
<extension name="del-group">
<condition field="destination_number" expression="^80(\d{2})$">
<action application="answer"/>
<action application="group" data="delete:$1@${domain_name}:${sofia_contact(${sip_from_user}@${domain_name})}"/>
<action application="gentones" data="%(1000, 0, 320)"/>
</condition>
</extension>
<extension name="add-group">
<condition field="destination_number" expression="^81(\d{2})$">
<action application="answer"/>
<action application="group" data="insert:$1@${domain_name}:${sofia_contact(${sip_from_user}@${domain_name})}"/>
<action application="gentones" data="%(1000, 0, 640)"/>
</condition>
</extension>
<extension name="call-group-simo">
<condition field="destination_number" expression="^82(\d{2})$">
<action application="bridge" data="{leg_timeout=15,ignore_early_media=true}${group(call:$1@${domain_name})}"/>
</condition>
</extension>
<extension name="call-group-order">
<condition field="destination_number" expression="^83(\d{2})$">
<action application="bridge" data="{leg_timeout=15,ignore_early_media=true}${group(call:$1@${domain_name}:order)}"/>
</condition>
</extension>
<extension name="extension-intercom">
<condition field="destination_number" expression="^8(10[01][0-9])$">
<action application="set" data="dialed_extension=$1"/>
<action application="export" data="sip_auto_answer=true"/>
<action application="bridge" data="user/${dialed_extension}@${domain_name}"/>
</condition>
</extension>
<!--
dial the extension (1000-1019) for 30 seconds and go to voicemail if the
call fails (continue_on_fail=true), otherwise hang up after a successful
bridge (hangup_after_bridge=true)
-->
<extension name="Local_Extension">
<condition field="destination_number" expression="^(10[01][0-9])$">
<action application="set" data="dialed_extension=$1"/>
<action application="export" data="dialed_extension=$1"/>
<!-- bind_meta_app can have these args <key> [a|b|ab] [a|b|o|s] <app> -->
<action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>
<action application="bind_meta_app" data="2 b s record_session::$${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
<action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
<action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/>
<action application="set" data="ringback=${us-ring}"/>
<action application="set" data="transfer_ringback=$${hold_music}"/>
<action application="set" data="call_timeout=30"/>
<!-- <action application="set" data="sip_exclude_contact=${network_addr}"/> -->
<action application="set" data="hangup_after_bridge=true"/>
<!--<action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,USER_BUSY,NO_ANSWER,TIMEOUT,NO_ROUTE_DESTINATION"/> -->
<action application="set" data="continue_on_fail=true"/>
<action application="hash" data="insert/${domain_name}-call_return/${dialed_extension}/${caller_id_number}"/>
<action application="hash" data="insert/${domain_name}-last_dial_ext/${dialed_extension}/${uuid}"/>
<action application="hash" data="insert/${domain_name}-last_dial_ext/${called_party_callgroup}/${uuid}"/>
<action application="hash" data="insert/${domain_name}-last_dial_ext/global/${uuid}"/>
<action application="set" data="called_party_callgroup=${user_data(${dialed_extension}@${domain_name} var callgroup)}"/>
<!--<action application="export" data="nolocal:sip_secure_media=${user_data(${dialed_extension}@${domain_name} var sip_secure_media)}"/>-->
<action application="hash" data="insert/${domain_name}-last_dial/${called_party_callgroup}/${uuid}"/>
<action application="bridge" data="{sip_invite_domain=$${domain}}user/${dialed_extension}@${domain_name}"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>
</condition>
</extension>
<extension name="Local_Extension_Skinny">
<condition field="destination_number" expression="^(11[01][0-9])$">
<action application="bridge" data="skinny/internal/${destination_number}"/>
</condition>
</extension>
<extension name="group_dial_sales">
<condition field="destination_number" expression="^2000$">
<action application="bridge" data="${group_call(sales@${domain_name})}"/>
</condition>
</extension>
<extension name="group_dial_support">
<condition field="destination_number" expression="^2001$">
<action application="bridge" data="group/support@${domain_name}"/>
</condition>
</extension>
<extension name="group_dial_billing">
<condition field="destination_number" expression="^2002$">
<action application="bridge" data="group/billing@${domain_name}"/>
</condition>
</extension>
<!-- voicemail operator extension -->
<extension name="operator">
<condition field="destination_number" expression="^(operator|0)$">
<action application="set" data="transfer_ringback=$${hold_music}"/>
<action application="transfer" data="1000 XML features"/>
</condition>
</extension>
<!-- voicemail main extension -->
<extension name="vmain">
<condition field="destination_number" expression="^vmain$|^4000$|^\*98$">
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="voicemail" data="check default ${domain_name}"/>
</condition>
</extension>
<!--
This extension is used by mod_portaudio so you can pa call sip:someone@example.com
mod_portaudio will pass the entire string to the dialplan for routing.
-->
<extension name="sip_uri">
<condition field="destination_number" expression="^sip:(.*)$">
<action application="bridge" data="sofia/${use_profile}/$1"/>
</condition>
</extension>
<!--
start a dynamic conference with the settings of the "default" conference profile in conference.conf.xml
-->
<extension name="nb_conferences">
<condition field="destination_number" expression="^(30\d{2})$">
<action application="answer"/>
<action application="conference" data="$1-${domain_name}@default"/>
</condition>
</extension>
<extension name="wb_conferences">
<condition field="destination_number" expression="^(31\d{2})$">
<action application="answer"/>
<action application="conference" data="$1-${domain_name}@wideband"/>
</condition>
</extension>
<extension name="uwb_conferences">
<condition field="destination_number" expression="^(32\d{2})$">
<action application="answer"/>
<action application="conference" data="$1-${domain_name}@ultrawideband"/>
</condition>
</extension>
<!-- MONO 48kHz conferences -->
<extension name="cdquality_conferences">
<condition field="destination_number" expression="^(33\d{2})$">
<action application="answer"/>
<action application="conference" data="$1-${domain_name}@cdquality"/>
</condition>
</extension>
<!-- dial the FreeSWITCH conference via SIP-->
<extension name="freeswitch_public_conf_via_sip">
<condition field="destination_number" expression="^9(888|8888|1616|3232)$">
<action application="export" data="hold_music=silence"/>
<!--
This will take the SAS from the b-leg and send it to the display on the a-leg phone.
Known working with Polycom and Snom maybe others.
-->
<!--
<action application="set" data="exec_after_bridge_app=${sched_api(+4 zrtp expand uuid_display ${uuid} \${uuid_getvar(\${uuid_getvar(${uuid} signal_bond)} zrtp_sas1_string )} \${uuid_getvar(\${uuid_getvar(${uuid} signal_bond)} zrtp_sas2_string )} )}"/>
<action application="export" data="nolocal:zrtp_secure_media=true"/>
-->
<action application="bridge" data="sofia/${use_profile}/$1@conference.freeswitch.org"/>
</condition>
</extension>
<!--
This extension will start a conference and invite a group.
At anytime the participant can dial *2 to bridge directly to the boss.
All other callers are then hung up on.
-->
<extension name="mad_boss_intercom">
<condition field="destination_number" expression="^0911$">
<action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss1"/>
<action application="set" data="conference_auto_outcall_caller_id_number=0911"/>
<action application="set" data="conference_auto_outcall_timeout=60"/>
<action application="set" data="conference_auto_outcall_flags=mute"/>
<action application="set" data="conference_auto_outcall_prefix={sip_auto_answer=true,execute_on_answer='bind_meta_app 2 a s1 transfer::intercept:${uuid} inline'}"/>
<action application="set" data="sip_exclude_contact=${network_addr}"/>
<action application="conference_set_auto_outcall" data="${group_call(sales)}"/>
<action application="conference" data="madboss_intercom1@default+flags{endconf|deaf}"/>
</condition>
</extension>
<!--
This extension will start a conference and invite a few of people.
At anytime the participant can dial *2 to bridge directly to the boss.
All other callers are then hung up on.
-->
<extension name="mad_boss_intercom">
<condition field="destination_number" expression="^0912$">
<action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss2"/>
<action application="set" data="conference_auto_outcall_caller_id_number=0912"/>
<action application="set" data="conference_auto_outcall_timeout=60"/>
<action application="set" data="conference_auto_outcall_flags=mute"/>
<action application="set" data="conference_auto_outcall_prefix={sip_auto_answer=true,execute_on_answer='bind_meta_app 2 a s1 transfer::intercept:${uuid} inline'}"/>
<action application="set" data="sip_exclude_contact=${network_addr}"/>
<action application="conference_set_auto_outcall" data="loopback/9664"/>
<action application="conference" data="madboss_intercom2@default+flags{endconf|deaf}"/>
</condition>
</extension>
<!--This extension will start a conference and invite several people upon entering -->
<extension name="mad_boss">
<condition field="destination_number" expression="^0913$">
<!--These params effect the outcalls made once you join-->
<action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss"/>
<action application="set" data="conference_auto_outcall_caller_id_number=0911"/>
<action application="set" data="conference_auto_outcall_timeout=60"/>
<action application="set" data="conference_auto_outcall_flags=none"/>
<!--<action application="set" data="conference_auto_outcall_announce=say:You have been called into an emergency conference"/>-->
<!--Add as many of these as you need, These are the people you are going to call-->
<action application="conference_set_auto_outcall" data="loopback/9664"/>
<action application="conference" data="madboss3@default"/>
</condition>
</extension>
<!-- a sample IVR -->
<extension name="ivr_demo">
<condition field="destination_number" expression="^5000$">
<action application="answer"/>
<action application="sleep" data="2000"/>
<action application="ivr" data="demo_ivr"/>
</condition>
</extension>
<!-- Create a conference on the fly and pull someone in at the same time. -->
<extension name="dynamic_conference">
<condition field="destination_number" expression="^5001$">
<action application="conference" data="bridge:mydynaconf:sofia/${use_profile}/1234@conference.freeswitch.org"/>
</condition>
</extension>
<extension name="rtp_multicast_page">
<condition field="destination_number" expression="^pagegroup$|^7243$">
<action application="answer"/>
<action application="esf_page_group"/>
</condition>
</extension>
<!--
Parking extensions... transferring calls to 5900 will park them in a queue.
-->
<extension name="park">
<condition field="destination_number" expression="^5900$">
<action application="set" data="fifo_music=$${hold_music}"/>
<action application="fifo" data="5900@${domain_name} in"/>
</condition>
</extension>
<!--
Parking pickup extension. Calling 5901 will pickup the call.
-->
<extension name="unpark">
<condition field="destination_number" expression="^5901$">
<action application="answer"/>
<action application="fifo" data="5900@${domain_name} out nowait"/>
</condition>
</extension>
<!--
Valet park retrieval, works with valet_park extension below.
Retrieve a valet parked call by dialing 6000 + park number + #
-->
<extension name="valet_park">
<condition field="destination_number" expression="^(6000)$">
<action application="answer"/>
<action application="valet_park" data="valet_parking_lot ask 1 11 10000 ivr/ivr-enter_ext_pound.wav"/>
</condition>
</extension>
<!--
Valet park 6001-6099. Blind x-fer to 6001, 6002, etc. to valet park the call.
Dial 6001, 6002, etc. to retrieve a call that is already valet parked.
After call is retrieved, park extension is free for another call.
-->
<extension name="valet_park">
<condition field="destination_number" expression="^(60\d[1-9])$">
<action application="answer"/>
<action application="valet_park" data="valet_parking_lot $1"/>
</condition>
</extension>
<!--
This extension is used with Snom phones.
Set a function key to park+lot (lot being a number or name.)
Set type to Park+Orbit. You can then park and pickup using
the softkey on the phone. Should work with other phones.
-->
<extension name="park">
<condition field="source" expression="mod_sofia"/>
<condition field="destination_number" expression="park\+(\d+)">
<action application="fifo" data="$1@${domain_name} in undef $${hold_music}"/>
</condition>
</extension>
<!--
The extension is parking pickup with a to param of the fifo we are calling
Some phones send things like orbit= and you can extract that info.
-->
<extension name="unpark">
<condition field="source" expression="mod_sofia"/>
<condition field="destination_number" expression="^parking$"/>
<condition field="${sip_to_params}" expression="fifo\=(\d+)">
<action application="answer"/>
<action application="fifo" data="$1@${domain_name} out nowait"/>
</condition>
</extension>
<!--
This extension is used with Linksys phones.
Set a Phone tab option Call Park Serv to yes. You can park and
pickup using soft keys "park" and "unpark" found during
active call when moving navigation button. The other option
is to use phone's star codes (defaults to *38 and *39).
-->
<extension name="park">
<condition field="source" expression="mod_sofia"/>
<condition field="destination_number" expression="callpark"/>
<condition field="${sip_refer_to}">
<expression><![CDATA[<sip:callpark@${domain_name};orbit=(\d+)>]]></expression>
<action application="fifo" data="$1@${domain_name} in undef $${hold_music}"/>
</condition>
</extension>
<!--
This extension is used with Linksys phones.
The extension is parking pickup with a to param of the fifo
we are calling. Linksys sends orbit=<parkingslotnumber>
and we extract that info.
-->
<extension name="unpark">
<condition field="source" expression="mod_sofia"/>
<condition field="destination_number" expression="pickup"/>
<condition field="${sip_to_params}" expression="orbit\=(\d+)">
<action application="answer"/>
<action application="fifo" data="$1@${domain_name} out nowait"/>
</condition>
</extension>
<!--
Here are some examples of how to override the ringback heard by the
far end. You have two variables that you can use to override this.
ringback - used when a call isn't answered. (early media)
transfer_ringback - used when the call is already answered. (post answer)
-->
<!-- Demonstration of how to override the ringback in various situations -->
<extension name="wait">
<condition field="destination_number" expression="^wait$">
<action application="pre_answer"/>
<action application="sleep" data="20000"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="playback" data="voicemail/vm-goodbye.wav"/>
<action application="hangup"/>
</condition>
</extension>
<extension name="fax_receive">
<condition field="destination_number" expression="^9178$">
<action application="answer" />
<action application="playback" data="silence_stream://2000"/>
<action application="rxfax" data="/tmp/rxfax.tif"/>
<action application="hangup"/>
</condition>
</extension>
<extension name="fax_transmit">
<condition field="destination_number" expression="^9179$">
<action application="txfax" data="/tmp/txfax.tif"/>
<action application="hangup"/>
</condition>
</extension>
<!-- Send a 180 and let the far end generate ringback. -->
<extension name="ringback_180">
<condition field="destination_number" expression="^9180$">
<action application="ring_ready"/>
<action application="sleep" data="20000"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="playback" data="voicemail/vm-goodbye.wav"/>
<action application="hangup"/>
</condition>
</extension>
<!-- Send a 183 and send uk-ring as the ringtone. (early media) -->
<extension name="ringback_183_uk_ring">
<condition field="destination_number" expression="^9181$">
<action application="set" data="ringback=$${uk-ring}"/>
<action application="bridge" data="{ignore_early_media=true}loopback/wait"/>
</condition>
</extension>
<!-- Send a 183 and use music as the ringtone. (early media) -->
<extension name="ringback_183_music_ring">
<condition field="destination_number" expression="^9182$">
<action application="set" data="ringback=$${hold_music}"/>
<action application="bridge" data="{ignore_early_media=true}loopback/wait"/>
</condition>
</extension>
<!-- Answer the call and use music as the ringtone. (post answer) -->
<extension name="ringback_post_answer_uk_ring">
<condition field="destination_number" expression="^9183$">
<action application="set" data="transfer_ringback=$${uk-ring}"/>
<action application="answer"/>
<action application="bridge" data="{ignore_early_media=true}loopback/wait"/>
</condition>
</extension>
<!-- Answer the call and use music as the ringtone. (post answer) -->
<extension name="ringback_post_answer_music">
<condition field="destination_number" expression="^9184$">
<action application="set" data="transfer_ringback=$${hold_music}"/>
<action application="answer"/>
<action application="bridge" data="{ignore_early_media=true}loopback/wait"/>
</condition>
</extension>
<extension name="ClueCon">
<condition field="destination_number" expression="^9191$">
<action application="set" data="effective_caller_id_name=ClueCon IVR"/>
<action application="bridge" data="sofia/$${domain}/2000@bkw.org"/>
</condition>
</extension>
<extension name="show_info">
<condition field="destination_number" expression="^9192$">
<action application="answer"/>
<action application="info"/>
<action application="sleep" data="250"/>
<action application="hangup"/>
</condition>
</extension>
<extension name="video_record">
<condition field="destination_number" expression="^9193$">
<action application="answer"/>
<action application="record_fsv" data="/tmp/testrecord.fsv"/>
</condition>
</extension>
<extension name="video_playback">
<condition field="destination_number" expression="^9194$">
<action application="answer"/>
<action application="play_fsv" data="/tmp/testrecord.fsv"/>
</condition>
</extension>
<extension name="delay_echo">
<condition field="destination_number" expression="^9195$">
<action application="answer"/>
<action application="delay_echo" data="5000"/>
</condition>
</extension>
<extension name="echo">
<condition field="destination_number" expression="^9196$">
<action application="answer"/>
<action application="echo"/>
</condition>
</extension>
<extension name="milliwatt">
<condition field="destination_number" expression="^9197$">
<action application="answer"/>
<action application="playback" data="tone_stream://%(251,0,1004);loops=-1"/>
</condition>
</extension>
<extension name="tone_stream">
<condition field="destination_number" expression="^9198$">
<action application="answer"/>
<action application="playback" data="tone_stream://path=${base_dir}/conf/tetris.ttml;loops=10"/>
</condition>
</extension>
<!-- install zrtp_agent.lua into scripts (ZRTP == 9787) -->
<extension name="zrtp_enrollement">
<condition field="destination_number" expression="^9787$">
<action application="lua" data="zrtp_agent.lua"/>
</condition>
</extension>
<!--
You will no longer hear the bong tone. The wav file is playing stating the call is secure.
The file will not play unless you have both TLS and SRTP active.
-->
<extension name="hold_music">
<condition field="destination_number" expression="^9664$"/>
<condition field="${sip_has_crypto}" expression="^(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)$">
<action application="answer"/>
<action application="execute_extension" data="is_secure XML features"/>
<action application="playback" data="$${hold_music}"/>
<anti-action application="set" data="zrtp_secure_media=true"/>
<anti-action application="answer"/>
<anti-action application="playback" data="silence_stream://2000"/>
<anti-action application="execute_extension" data="is_zrtp_secure XML features"/>
<anti-action application="playback" data="$${hold_music}"/>
</condition>
</extension>
<!--
You can place files in the default directory to get included.
-->
<X-PRE-PROCESS cmd="include" data="default/*.xml"/>
<!--
<extension name="refer">
<condition field="${sip_refer_to}">
<expression><![CDATA[<sip:${destination_number}@${domain_name}>]]></expression>
</condition>
<condition field="${sip_refer_to}">
<expression><![CDATA[<sip:(.*)@(.*)>]]></expression>
<action application="set" data="refer_user=$1"/>
<action application="set" data="refer_domain=$2"/>
<action application="info"/>
<action application="bridge" data="sofia/${use_profile}/${refer_user}@${refer_domain}"/>
</condition>
</extension>
-->
<!--
This is an example of how to override the RURI on an outgoing invite to a registered contact.
-->
<!--
<extension name="ruri">
<condition field="destination_number" expression="^ruri$">
<action application="bridge" data="sofia/${ruri_profile}/${ruri_user}${regex(${sofia_contact(${ruri_contact})}|^[^\@]+(.*)|%1)}"/>
</condition>
</extension>
<extension name="7004">
<condition field="destination_number" expression="^7004$">
<action application="set" data="ruri_profile=default"/>
<action application="set" data="ruri_user=2000"/>
<action application="set" data="ruri_contact=1001@${domain_name}"/>
<action application="execute_extension" data="ruri"/>
</condition>
</extension>
-->
<extension name="enum">
<condition field="${module_exists(mod_enum)}" expression="true"/>
<condition field="destination_number" expression="^(.*)$">
<action application="transfer" data="$1 enum"/>
</condition>
</extension>
</context>
<context name="public">
<extension name="outbound-service">
<condition field="destination_number" expression="^service$">
</condition>
</extension>
<extension name="outbound132">
<condition field="destination_number" expression="^132$">
<action application="set" data="origination_caller_id_name=sipp"/>
<action application="set" data="origination_caller_id_number=987654321"/>
<action application="set" data="call_timeout=80"/>
<action application="bridge" data="freetdm/grp1/a/132"/>
</condition>
</extension>
service <extension name="outbound">
<condition field="destination_number" expression="(.*)">
<action application="set" data="dialed_number=$1"/>
<!-- <action application="answer"/> -->
<action application="set" data="caller_id_name=sipp"/>
<action application="set" data="effective_caller_id_number=987654321"/>
<action application="set_profile_var" data="caller_ton=1"/>
<action application="set_profile_var" data="caller_numplan=0"/>
<action application="set_profile_var" data="destination_number_ton=1"/>
<action application="set_profile_var" data="destination_number_numplan=0"/>
<action application="bridge" data="freetdm/grp1/a/${dialed_number}"/>
</condition>
</extension>
</context>
<context name="default">
<extension name="fast-hangup">
<condition field="destination_number" expression="123">
<!-- <action application="sleep" data="1000"/> -->
<!-- <action application="answer"/> -->
<action application="answer"/>
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="playback" data="/usr/local/freeswitch/sounds/demo-congrats.gsm" />
<action application="hangup" />
</condition>
</extension>
<extension name="slow-hangup">
<condition field="destination_number" expression="124">
<action application="answer"/>
<action application="playback" data="c:\cygwin\home\davidy\smg_freeswitch.netborder\Debug\sounds\tt-monkeys.gsm" />
<action application="hangup" />
</condition>
</extension>
<extension name="answer-then-bridge">
<condition field="destination_number" expression="125">
<action application="answer"/>
<action application="bridge" data="sofia/$${domain}/123@192.168.1.144:5062"/>
<action application="hangup" />
</condition>
</extension>
<extension name="just-bridge">
<condition field="destination_number" expression="126">
<!-- <action application="sleep" data="20000" /> -->
<!-- <action application="answer"/> -->
<!-- <action application="info" /> -->
<action application="log" data="DESTINATION_NUMBER [${destination_number}]" />
<action application="log" data="CALLER_TON [${caller_ton}]" />
<action application="log" data="CALLER_NPI [${caller_numplan}]" />
<action application="log" data="DEST_TON [${destination_number_ton}]" />
<action application="log" data="DEST_NPI [${destination_number_numplan}]" />
<action application="bridge" data="sofia/$${domain}/123@192.168.1.145:5062"/>
<action application="hangup" />
</condition>
</extension>
<extension name="other">
<condition field="destination_number" expression="(.*)">
<action application="log" data="CID_NAME [${caller_id_name}]" />
<action application="bridge" data="sofia/$${domain}/123@192.168.1.145:5062"/>
<action application="hangup"/>
</condition>
</extension>
</context>
</include>

View File

@ -42,26 +42,6 @@
<!-- 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"/>
<!--
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 shut
down 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.
-->
<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="true"/>
<param name="forward-unsolicited-mwi-notify" value="false"/>

View File

@ -16,7 +16,7 @@
<soft-key-set-sets>
<soft-key-set-set name="default">
<soft-key-set name="KeySetOnHook" value="SoftkeyNewcall,SoftkeyRedial"/>
<soft-key-set name="KeySetOffHook" value=",SoftkeyRedial,SoftkeyEndcall"/>
<soft-key-set name="KeySetOffHook" value=",SoftkeyNewcall,SoftkeyEndcall"/>
<soft-key-set name="KeySetDigitsAfterDialingFirstDigit" value="SoftkeyBackspace,,SoftkeyEndcall"/>
<soft-key-set name="KeySetConnected" value="SoftkeyEndcall,SoftkeyHold,SoftkeyNewcall,SoftkeyTransfer"/>
<soft-key-set name="KeySetRingIn" value="SoftkeyAnswer,SoftkeyEndcall,SoftkeyNewcall"/>

View File

@ -195,7 +195,7 @@
<!-- various debug and defaults -->
<X-PRE-PROCESS cmd="set" data="call_debug=false"/>
<X-PRE-PROCESS cmd="set" data="console_loglevel=info"/>
<X-PRE-PROCESS cmd="set" data="console_loglevel=debug"/>
<X-PRE-PROCESS cmd="set" data="default_areacode=918"/>
<X-PRE-PROCESS cmd="set" data="default_country=US"/>

View File

@ -5,8 +5,9 @@ fsdir=../..
set -x
cp Debug/mod/*.dll $fsdir/Debug/mod/
cp mod_freetdm/Debug/*.pdb $fsdir/Debug/mod/
cp Debug/*.dll $fsdir/Debug/
cp Debug/*.pdb $fsdir/Debug/
cp Debug/freetdm.dll $fsdir/Debug/
cp Debug/ftmod_*.dll $fsdir/Debug/mod/
cp Debug/*.pdb $fsdir/Debug/mod/
#cp Debug/testsangomaboost.exe $fsdir/Debug/
echo "FRIENDLY REMINDER: RECOMPILE ftmod_wanpipe WHENEVER YOU INSTALL NEW DRIVERS"
set +x

View File

@ -56,6 +56,9 @@
#define FTDM_READ_TRACE_INDEX 0
#define FTDM_WRITE_TRACE_INDEX 1
ftdm_time_t time_last_throttle_log = 0;
ftdm_time_t time_current_throttle_log = 0;
static int time_is_init = 0;
static void time_init(void)

View File

@ -1557,11 +1557,11 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
ftdm_set_string(event.calling_name, ftdmchan->caller_data.cid_name);
ftdm_set_string(event.rdnis.digits, ftdmchan->caller_data.rdnis.digits);
if (strlen(ftdmchan->caller_data.rdnis.digits)) {
event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1;
event.rdnis.ton = ftdmchan->caller_data.rdnis.type;
event.rdnis.npi = ftdmchan->caller_data.rdnis.plan;
event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1;
event.rdnis.ton = ftdmchan->caller_data.rdnis.type;
event.rdnis.npi = ftdmchan->caller_data.rdnis.plan;
}
event.calling.screening_ind = ftdmchan->caller_data.screen;
event.calling.presentation_ind = ftdmchan->caller_data.pres;

View File

@ -48,14 +48,16 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span);
ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
static void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftdmchan);
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span);
static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event);
static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan);
static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan);
static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *ftdmchan);
static ftdm_io_interface_t g_sngisdn_io_interface;
static sng_isdn_event_interface_t g_sngisdn_event_interface;
static ftdm_io_interface_t g_sngisdn_io_interface;
static sng_isdn_event_interface_t g_sngisdn_event_interface;
ftdm_sngisdn_data_t g_sngisdn_data;
ftdm_sngisdn_data_t g_sngisdn_data;
ftdm_state_map_t sangoma_isdn_state_map = {
{
@ -236,39 +238,51 @@ static __inline__ void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftd
}
}
static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
sngisdn_snd_event(signal_data->dchan, event);
switch (event) {
/* Check if the span woke up from power-saving mode */
case FTDM_OOB_ALARM_CLEAR:
if (FTDM_SPAN_IS_BRI(span)) {
ftdm_channel_t *ftdmchan;
sngisdn_chan_data_t *sngisdn_info;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data;
if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) {
ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
ftdm_sched_timer(signal_data->sched, "delayed_setup", 1000, sngisdn_delayed_setup, (void*) ftdmchan->call_data, NULL);
}
}
ftdm_iterator_free(chaniter);
}
break;
default:
/* Ignore other events for now */
break;
}
}
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
{
ftdm_status_t ret_status;
ftdm_channel_t *ftdmchan;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
ftdm_status_t ret_status;
ret_status = ftdm_span_poll_event(span, 0, NULL);
switch(ret_status) {
case FTDM_SUCCESS:
{
ftdm_event_t *event;
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
if (FTDM_SPAN_IS_BRI(span)) {
switch (event->enum_id) {
/* Check if the span woke up from power-saving mode */
case FTDM_OOB_ALARM_CLEAR:
{
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) {
ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
sngisdn_snd_setup((ftdm_channel_t*)ftdmchan);
}
}
ftdm_iterator_free(chaniter);
}
}
}
ftdm_sangoma_isdn_process_phy_events(span, event->enum_id);
}
}
break;
@ -280,6 +294,80 @@ static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
}
}
static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *dchan)
{
ftdm_status_t ret_status;
uint32_t queue_size;
queue_size = SNGISDN_DCHAN_QUEUE_LEN;
ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &queue_size);
ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Rx Queue size");
queue_size = SNGISDN_DCHAN_QUEUE_LEN;
ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &queue_size);
ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Tx Queue size");
RETVOID;
}
static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan)
{
ftdm_status_t ret_status;
ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED;
ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_LINK_STATUS, &status);
if (ret_status != FTDM_SUCCESS) {
ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to wake-up link\n");
}
return;
}
static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj)
{
uint8_t data[1000];
ftdm_status_t status = FTDM_SUCCESS;
ftdm_wait_flag_t wflags = FTDM_READ;
ftdm_span_t *span = (ftdm_span_t*) obj;
ftdm_channel_t *dchan = ((sngisdn_span_data_t*)span->signal_data)->dchan;
ftdm_size_t len = 0;
ftdm_channel_set_feature(dchan, FTDM_CHANNEL_FEATURE_IO_STATS);
ftdm_sangoma_isdn_dchan_set_queue_size(dchan);
ftdm_assert(dchan, "Span does not have a dchannel");
ftdm_channel_open_chan(dchan);
while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
wflags = FTDM_READ;
status = ftdm_channel_wait(dchan, &wflags, 10000);
switch(status) {
case FTDM_FAIL:
ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Failed to wait for d-channel\n");
break;
case FTDM_TIMEOUT:
break;
case FTDM_SUCCESS:
if ((wflags & FTDM_READ)) {
len = 1000;
status = ftdm_channel_read(dchan, data, &len);
if (status == FTDM_SUCCESS) {
sngisdn_snd_data(dchan, data, len);
} else {
ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to read from channel \n");
}
#ifndef WIN32 /* It is valid on WIN32 for poll to return without errors, but no flags set */
} else {
ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Failed to poll for d-channel\n");
#endif
}
break;
default:
ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Unhandled IO event\n");
}
}
ftdm_channel_close(&dchan);
return NULL;
}
static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
{
ftdm_interrupt_t *ftdm_sangoma_isdn_int[2];
@ -343,6 +431,7 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
/* Poll for events, e.g HW DTMF */
ftdm_sangoma_isdn_poll_events(span);
ftdm_span_trigger_signals(span);
if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) {
if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) {
@ -535,8 +624,8 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Line activation\n");
sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING);
sng_isdn_wake_up_phy(ftdmchan->span);
sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING);
ftdm_sangoma_isdn_wakeup_phy(ftdmchan);
ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL);
} else {
sngisdn_snd_setup(ftdmchan);
@ -633,7 +722,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
sngisdn_snd_release(ftdmchan, 0);
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
}
} else {
sngisdn_snd_disconnect(ftdmchan);
@ -788,7 +877,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status)
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
{
ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id);
if (sng_isdn_stack_start(span) != FTDM_SUCCESS) {
if (sngisdn_stack_start(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
return FTDM_FAIL;
}
@ -802,6 +891,12 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
return FTDM_FAIL;
}
/*start the dchan monitor thread*/
if (ftdm_thread_create_detached(ftdm_sangoma_isdn_dchan_run, span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT,"Failed to start Sangoma ISDN d-channel Monitor Thread!\n");
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG,"Finished starting span %s\n", span->name);
return FTDM_SUCCESS;
}
@ -823,7 +918,7 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
ftdm_sleep(10);
}
if (sng_isdn_stack_stop(span) != FTDM_SUCCESS) {
if (sngisdn_stack_stop(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s\n", span->name);
}
@ -875,7 +970,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
return FTDM_FAIL;
}
if (sng_isdn_stack_cfg(span) != FTDM_SUCCESS) {
if (sngisdn_stack_cfg(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Sangoma ISDN Stack configuration failed\n");
return FTDM_FAIL;
}
@ -898,7 +993,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
span->trunk_type == FTDM_TRUNK_BRI) {
sng_isdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
sngisdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
}
/* Initialize scheduling context */
@ -917,7 +1012,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
ftdm_log(FTDM_LOG_INFO, "Loading ftmod_sangoma_isdn...\n");
memset(&g_sngisdn_data, 0, sizeof(g_sngisdn_data));
memset(&g_sngisdn_event_interface, 0, sizeof(g_sngisdn_event_interface));
/* set callbacks */
g_sngisdn_event_interface.cc.sng_con_ind = sngisdn_rcv_con_ind;
g_sngisdn_event_interface.cc.sng_con_cfm = sngisdn_rcv_con_cfm;
@ -946,8 +1041,11 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
g_sngisdn_event_interface.sta.sng_q921_trc_ind = sngisdn_rcv_q921_trace;
g_sngisdn_event_interface.sta.sng_q931_sta_ind = sngisdn_rcv_q931_ind;
g_sngisdn_event_interface.sta.sng_q931_trc_ind = sngisdn_rcv_q931_trace;
g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind;
g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind;
g_sngisdn_event_interface.io.sng_l1_data_req = sngisdn_rcv_l1_data_req;
g_sngisdn_event_interface.io.sng_l1_cmd_req = sngisdn_rcv_l1_cmd_req;
for(i=1;i<=MAX_VARIANTS;i++) {
ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex);
}
@ -1008,11 +1106,11 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
goto done;
}
if (!strcasecmp(trace_opt, "q921")) {
sng_isdn_activate_trace(span, SNGISDN_TRACE_Q921);
sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
} else if (!strcasecmp(trace_opt, "q931")) {
sng_isdn_activate_trace(span, SNGISDN_TRACE_Q931);
sngisdn_activate_trace(span, SNGISDN_TRACE_Q931);
} else if (!strcasecmp(trace_opt, "disable")) {
sng_isdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
} else {
stream->write_function(stream, "-ERR invalid trace option <q921|q931> <span name>\n");
}

View File

@ -60,6 +60,7 @@
#define SNGISDN_EVENT_QUEUE_SIZE 100
#define SNGISDN_EVENT_POLL_RATE 100
#define SNGISDN_NUM_LOCAL_NUMBERS 8
#define SNGISDN_DCHAN_QUEUE_LEN 200
/* TODO: rename all *_cc_* to *_an_* */
@ -168,6 +169,7 @@ typedef struct sngisdn_chan_data {
/* Span specific data */
typedef struct sngisdn_span_data {
ftdm_span_t *ftdm_span;
ftdm_channel_t *dchan;
uint8_t link_id;
uint8_t switchtype;
uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */
@ -268,28 +270,20 @@ extern ftdm_sngisdn_data_t g_sngisdn_data;
ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
/* Support functions */
FT_DECLARE(uint32_t) get_unique_suInstId(int16_t cc_id);
FT_DECLARE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info);
FT_DECLARE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
uint32_t get_unique_suInstId(int16_t cc_id);
void clear_call_data(sngisdn_chan_data_t *sngisdn_info);
void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
void stack_hdr_init(Header *hdr);
void stack_pst_init(Pst *pst);
FT_DECLARE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
FT_DECLARE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
FT_DECLARE(ftdm_status_t) sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail);
FT_DECLARE(ftdm_status_t) cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
FT_DECLARE(ftdm_status_t) cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
FT_DECLARE(ftdm_status_t) cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
FT_DECLARE(ftdm_status_t) cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display);
FT_DECLARE(ftdm_status_t) cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
FT_DECLARE(ftdm_status_t) cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
FT_DECLARE(ftdm_status_t) cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm);
FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
/* Outbound Call Control functions */
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan);
@ -303,25 +297,30 @@ void sngisdn_snd_reset(ftdm_channel_t *ftdmchan);
void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event);
/* Inbound Call Control functions */
void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces);
void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces);
void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt);
void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt);
void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt);
void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
void sngisdn_rcv_sta_cfm ( int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
void sngisdn_rcv_srv_ind ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
void sngisdn_rcv_srv_cfm ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
void sngisdn_rcv_rst_cfm ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
void sngisdn_rcv_rst_ind ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
void sngisdn_rcv_con_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces);
void sngisdn_rcv_con_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces);
void sngisdn_rcv_cnst_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
void sngisdn_rcv_disc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt);
void sngisdn_rcv_rel_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt);
void sngisdn_rcv_dat_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt);
void sngisdn_rcv_sshl_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
void sngisdn_rcv_sshl_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
void sngisdn_rcv_rmrt_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
void sngisdn_rcv_rmrt_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
void sngisdn_rcv_flc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
void sngisdn_rcv_fac_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
void sngisdn_rcv_sta_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
void sngisdn_rcv_srv_ind(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
void sngisdn_rcv_srv_cfm(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
void sngisdn_rcv_rst_cfm(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
void sngisdn_rcv_rst_ind(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame);
int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd);
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event);
void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event);
@ -359,6 +358,15 @@ void sngisdn_rcv_cc_ind(CcMngmt *status);
void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...);
void sngisdn_rcv_sng_assert(char *message);
ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display);
ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm);
ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability);
uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot);
ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability);
@ -385,6 +393,7 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis
void handle_sng_log(uint8_t level, char *fmt,...);
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
void sngisdn_delayed_setup(void* p_sngisdn_info);
void sngisdn_delayed_release(void* p_sngisdn_info);
void sngisdn_delayed_connect(void* p_sngisdn_info);
void sngisdn_delayed_disconnect(void* p_sngisdn_info);
@ -392,10 +401,10 @@ void sngisdn_facility_timeout(void* p_sngisdn_info);
void sngisdn_t3_timeout(void* p_sngisdn_info);
/* Stack management functions */
ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
ftdm_status_t sng_isdn_wake_up_phy(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_start(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span);
ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span);
void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span);
void sngisdn_print_spans(ftdm_stream_handle_t *stream);

View File

@ -56,9 +56,11 @@ ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
{
unsigned i;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
sngisdn_dchan_data_t *dchan_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
switch(span->trunk_type) {
case FTDM_TRUNK_T1:
if (!strcasecmp(switch_name, "ni2") ||
@ -124,9 +126,9 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
/* add this span to its ent_cc */
signal_data->cc_id = i;
/* create a new dchan */ /* for NFAS - no-dchan on b-channels only links */
/* create a new dchan */ /* for NFAS - no-dchan on b-channels-only links */
g_sngisdn_data.num_dchan++;
signal_data->dchan_id = g_sngisdn_data.num_dchan;
signal_data->dchan_id = g_sngisdn_data.num_dchan;
dchan_data = &g_sngisdn_data.dchans[signal_data->dchan_id];
dchan_data->num_spans++;
@ -138,16 +140,23 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d dchan_id:%d span_id:%d\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id);
/* Add the channels to the span */
for (i=1;i<=span->chan_count;i++) {
unsigned chan_id;
ftdm_channel_t *ftdmchan = span->channels[i];
/* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */
chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id;
dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data;
dchan_data->num_chans++;
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
int32_t chan_id;
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
/* set the d-channel */
signal_data->dchan = ftdmchan;
} else {
/* Add the channels to the span */
/* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */
chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id;
dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data;
dchan_data->num_chans++;
}
}
ftdm_iterator_free(chaniter);
return FTDM_SUCCESS;
}

View File

@ -38,52 +38,52 @@ extern ftdm_sngisdn_data_t g_sngisdn_data;
uint8_t sng_isdn_stack_switchtype(sngisdn_switchtype_t switchtype);
ftdm_status_t sng_isdn_cfg_phy(ftdm_span_t *span);
ftdm_status_t sng_isdn_cfg_q921(ftdm_span_t *span);
ftdm_status_t sng_isdn_cfg_q931(ftdm_span_t *span);
ftdm_status_t sng_isdn_cfg_cc(ftdm_span_t *span);
ftdm_status_t sngisdn_cfg_phy(ftdm_span_t *span);
ftdm_status_t sngisdn_cfg_q921(ftdm_span_t *span);
ftdm_status_t sngisdn_cfg_q931(ftdm_span_t *span);
ftdm_status_t sngisdn_cfg_cc(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_cfg_phy_gen(void);
ftdm_status_t sng_isdn_stack_cfg_q921_gen(void);
ftdm_status_t sng_isdn_stack_cfg_q931_gen(void);
ftdm_status_t sng_isdn_stack_cfg_cc_gen(void);
ftdm_status_t sngisdn_stack_cfg_phy_gen(void);
ftdm_status_t sngisdn_stack_cfg_q921_gen(void);
ftdm_status_t sngisdn_stack_cfg_q931_gen(void);
ftdm_status_t sngisdn_stack_cfg_cc_gen(void);
ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management);
ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management);
ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
if (!g_sngisdn_data.gen_config_done) {
g_sngisdn_data.gen_config_done = 1;
ftdm_log(FTDM_LOG_DEBUG, "Starting general stack configuration\n");
if(sng_isdn_stack_cfg_phy_gen()!= FTDM_SUCCESS) {
if(sngisdn_stack_cfg_phy_gen()!= FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed general physical configuration\n");
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "General stack physical done\n");
if(sng_isdn_stack_cfg_q921_gen()!= FTDM_SUCCESS) {
if(sngisdn_stack_cfg_q921_gen()!= FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n");
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "General stack q921 done\n");
if(sng_isdn_stack_cfg_q931_gen()!= FTDM_SUCCESS) {
if(sngisdn_stack_cfg_q931_gen()!= FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n");
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "General stack q931 done\n");
if(sng_isdn_stack_cfg_cc_gen()!= FTDM_SUCCESS) {
if(sngisdn_stack_cfg_cc_gen()!= FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed general CC configuration\n");
return FTDM_FAIL;
}
@ -92,26 +92,26 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
}
/* TODO: for NFAS, should only call these function for spans with d-chans */
if (sng_isdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) {
if (sngisdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:phy_psap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:phy_psap configuration done\n", span->name);
if (sng_isdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) {
if (sngisdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q921_msap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:q921_msap configuration done\n", span->name);
if (sng_isdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) {
if (sngisdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap configuration done\n", span->name);
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
if (sng_isdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) {
if (sngisdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap management configuration failed\n", span->name);
return FTDM_FAIL;
}
@ -119,13 +119,13 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
}
if (sng_isdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) {
if (sngisdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q931_dlsap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:q931_dlsap configuration done\n", span->name);
if (sng_isdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) {
if (sngisdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q931_lce configuration failed\n", span->name);
return FTDM_FAIL;
}
@ -134,13 +134,13 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
if (!g_sngisdn_data.ccs[signal_data->cc_id].config_done) {
g_sngisdn_data.ccs[signal_data->cc_id].config_done = 1;
/* if BRI, need to configure dlsap_mgmt */
if (sng_isdn_stack_cfg_q931_tsap(span) != FTDM_SUCCESS) {
if (sngisdn_stack_cfg_q931_tsap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q931_tsap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:q931_tsap configuration done\n", span->name);
if (sng_isdn_stack_cfg_cc_sap(span) != FTDM_SUCCESS) {
if (sngisdn_stack_cfg_cc_sap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:cc_sap configuration failed\n", span->name);
return FTDM_FAIL;
}
@ -153,37 +153,37 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
ftdm_status_t sng_isdn_stack_cfg_phy_gen(void)
ftdm_status_t sngisdn_stack_cfg_phy_gen(void)
{
/*local variables*/
L1Mngmt cfg; /*configuration structure*/
Pst pst; /*post structure*/
L1Mngmt cfg; /*configuration structure*/
Pst pst; /*post structure*/
/* initalize the post structure */
stack_pst_init(&pst);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTL1;
/* insert the destination Entity */
pst.dstEnt = ENTL1;
/*clear the configuration structure*/
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTL1;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STGEN;
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTL1;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STGEN;
stack_pst_init(&cfg.t.cfg.s.l1Gen.sm );
cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1;
cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM;
stack_pst_init(&cfg.t.cfg.s.l1Gen.sm );
cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1;
cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM;
cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS+1;
cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */
cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */
cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS;
cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */
cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */
if (sng_isdn_phy_config(&pst, &cfg)) {
return FTDM_FAIL;
@ -191,55 +191,40 @@ ftdm_status_t sng_isdn_stack_cfg_phy_gen(void)
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
{
ftdm_iterator_t *chaniter;
ftdm_iterator_t *curr;
L1Mngmt cfg;
Pst pst;
ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span)
{
L1Mngmt cfg;
Pst pst;
int32_t d_channel_fd = -1;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */
stack_pst_init(&pst);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTL1;
/* insert the destination Entity */
pst.dstEnt = ENTL1;
/*clear the configuration structure*/
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTL1;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STPSAP;
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTL1;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STPSAP;
cfg.hdr.elmId.elmntInst1 = signal_data->link_id;
/* Find the d-channel */
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
d_channel_fd = (int32_t)ftdmchan->sockfd;
break;
}
}
ftdm_iterator_free(chaniter);
if(d_channel_fd < 0) {
if (!signal_data->dchan) {
ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name);
return FTDM_FAIL;
}
cfg.t.cfg.s.l1PSAP.sockfd = d_channel_fd;
cfg.t.cfg.s.l1PSAP.sockfd = (int32_t)signal_data->dchan->sockfd;
switch(span->trunk_type) {
case FTDM_TRUNK_E1:
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI;
@ -255,8 +240,8 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
default:
ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunk type %d\n", span->name, span->trunk_type);
return FTDM_FAIL;
}
cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id;
}
cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id;
if (sng_isdn_phy_config(&pst, &cfg)) {
return FTDM_FAIL;
@ -265,28 +250,28 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
}
ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
ftdm_status_t sngisdn_stack_cfg_q921_gen(void)
{
BdMngmt cfg;
Pst pst;
Pst pst;
/* initalize the post structure */
stack_pst_init(&pst);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTLD;
pst.dstEnt = ENTLD;
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTLD;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STGEN;
/* fill in the Gen Conf structures internal pst struct */
stack_hdr_init(&cfg.hdr);
stack_pst_init(&cfg.t.cfg.s.bdGen.sm);
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTLD;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STGEN;
/* fill in the Gen Conf structures internal pst struct */
stack_pst_init(&cfg.t.cfg.s.bdGen.sm);
cfg.t.cfg.s.bdGen.sm.dstEnt = ENTSM; /* entity */
@ -299,8 +284,8 @@ ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
#ifdef LAPD_3_4
cfg.t.cfg.s.bdGen.timeRes = 100; /* timer resolution = 1 sec */
#endif
cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */
cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */
cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */
cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */
if (sng_isdn_q921_config(&pst, &cfg)) {
return FTDM_FAIL;
@ -308,30 +293,30 @@ ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span)
{
BdMngmt cfg;
Pst pst;
Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */
stack_pst_init(&pst);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTLD;
pst.dstEnt = ENTLD;
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
stack_hdr_init(&cfg.hdr);
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTLD;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STMSAP;
cfg.hdr.entId.ent = ENTLD;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STMSAP;
cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id;
cfg.t.cfg.s.bdMSAP.maxOutsFrms = 24; /* MAC window */
cfg.t.cfg.s.bdMSAP.tQUpperTrs = 32; /* Tx Queue Upper Threshold */
cfg.t.cfg.s.bdMSAP.tQLowerTrs = 24; /* Tx Queue Lower Threshold */
@ -343,7 +328,7 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
cfg.t.cfg.s.bdMSAP.route = RTESPEC; /* Route */
cfg.t.cfg.s.bdMSAP.dstProcId = SFndProcId(); /* destination proc id */
cfg.t.cfg.s.bdMSAP.dstEnt = ENTL1; /* entity */
cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */
cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */
cfg.t.cfg.s.bdMSAP.t201Tmr = 1; /* T201 - should be equal to t200Tmr */
cfg.t.cfg.s.bdMSAP.t202Tmr = 2; /* T202 */
cfg.t.cfg.s.bdMSAP.bndRetryCnt = 2; /* bind retry counter */
@ -392,7 +377,7 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
if (signal_data->setup_arb == SNGISDN_OPT_TRUE) {
cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE;
} else if (signal_data->setup_arb == SNGISDN_OPT_FALSE) {
cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE;
cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE;
}
if (sng_isdn_q921_config(&pst, &cfg)) {
@ -401,27 +386,27 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management)
ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management)
{
BdMngmt cfg;
Pst pst;
Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */
stack_pst_init(&pst);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTLD;
pst.dstEnt = ENTLD;
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
stack_hdr_init(&cfg.hdr);
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTLD;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STDLSAP;
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTLD;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STDLSAP;
cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->link_id;
@ -433,10 +418,10 @@ ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t managemen
} else {
cfg.t.cfg.s.bdDLSAP.k = 7; /* k */
}
cfg.t.cfg.s.bdDLSAP.n200 = 3; /* n200 */
cfg.t.cfg.s.bdDLSAP.congTmr = 300; /* congestion timer */
cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */
cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */
cfg.t.cfg.s.bdDLSAP.t203Tmr = 10; /* t3 changed from 50 */
cfg.t.cfg.s.bdDLSAP.mod = 128; /* modulo */
cfg.t.cfg.s.bdDLSAP.selector = 0; /* Selector 0 */
@ -483,31 +468,31 @@ ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t managemen
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_stack_cfg_q931_gen(void)
ftdm_status_t sngisdn_stack_cfg_q931_gen(void)
{
InMngmt cfg;
Pst pst;
Pst pst;
/* initalize the post structure */
stack_pst_init(&pst);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTIN;
/* insert the destination Entity */
pst.dstEnt = ENTIN;
/*clear the configuration structure*/
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STGEN;
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STGEN;
/* fill in the Gen Conf structures internal pst struct */
stack_pst_init(&cfg.t.cfg.s.inGen.sm);
/* fill in the Gen Conf structures internal pst struct */
stack_pst_init(&cfg.t.cfg.s.inGen.sm);
cfg.t.cfg.s.inGen.nmbSaps = MAX_VARIANTS+1; /* Total number of variants supported */
@ -538,29 +523,29 @@ ftdm_status_t sng_isdn_stack_cfg_q931_gen(void)
}
/* Link between CC and q931 */
ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span)
ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span)
{
InMngmt cfg;
Pst pst;
Pst pst;
unsigned i;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */
stack_pst_init(&pst);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTIN;
/* insert the destination Entity */
pst.dstEnt = ENTIN;
/*clear the configuration structure*/
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STTSAP;
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STTSAP;
cfg.t.cfg.s.inTSAP.sapId = signal_data->cc_id;
@ -601,34 +586,34 @@ ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span)
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
{
InMngmt cfg;
Pst pst;
Pst pst;
unsigned i;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */
stack_pst_init(&pst);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTIN;
/* insert the destination Entity */
pst.dstEnt = ENTIN;
/*clear the configuration structure*/
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STDLSAP;
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STDLSAP;
cfg.hdr.response.selector=0;
cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id;
cfg.t.cfg.s.inDLSAP.spId = signal_data->link_id;
cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype);
@ -674,7 +659,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
cfg.t.cfg.s.inDLSAP.ctldInt[1] = 1;
}
cfg.t.cfg.s.inDLSAP.numRstInd = 255;
cfg.t.cfg.s.inDLSAP.numRstInd = 255;
cfg.t.cfg.s.inDLSAP.relOpt = TRUE;
#ifdef ISDN_SRV
cfg.t.cfg.s.inDLSAP.bcas = FALSE;
@ -851,39 +836,39 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span)
{
InMngmt cfg;
Pst pst;
Pst pst;
uint8_t i;
uint8_t numCes=1;
uint8_t numCes=1;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP && signal_data->signalling == SNGISDN_SIGNALING_NET) {
numCes = 8;
}
/* initalize the post structure */
stack_pst_init(&pst);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTIN;
/* insert the destination Entity */
pst.dstEnt = ENTIN;
/*clear the configuration structure*/
/*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr);
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STDLC;
/*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STDLC;
cfg.hdr.response.selector=0;
cfg.t.cfg.s.inLCe.sapId = signal_data->link_id;
cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE;
cfg.t.cfg.s.inLCe.tCon.enb = TRUE;
@ -892,7 +877,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
cfg.t.cfg.s.inLCe.tDisc.val = 35;
cfg.t.cfg.s.inLCe.t314.enb = FALSE; /* if segmentation enabled, set to TRUE */
cfg.t.cfg.s.inLCe.t314.val = 35;
cfg.t.cfg.s.inLCe.t332i.enb = FALSE; /* set to TRUE for NFAS */
#ifdef NFAS
@ -912,7 +897,6 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
cfg.t.cfg.s.inLCe.tRstAck.enb = TRUE;
cfg.t.cfg.s.inLCe.tRstAck.val = 10;
cfg.t.cfg.s.inLCe.usid = 0;
cfg.t.cfg.s.inLCe.tid = 0;
@ -927,7 +911,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
}
ftdm_status_t sng_isdn_stack_cfg_cc_gen(void)
ftdm_status_t sngisdn_stack_cfg_cc_gen(void)
{
CcMngmt cfg;
Pst pst;
@ -966,7 +950,7 @@ ftdm_status_t sng_isdn_stack_cfg_cc_gen(void)
}
ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span)
ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span)
{
CcMngmt cfg;
Pst pst;
@ -998,11 +982,11 @@ ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span)
cfg.t.cfg.s.ccISAP.pst.dstInst = S_INST;
cfg.t.cfg.s.ccISAP.pst.dstProcId = SFndProcId();
cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0;
cfg.t.cfg.s.ccISAP.pst.route = RTESPEC;
cfg.t.cfg.s.ccISAP.pst.region = S_REG;
cfg.t.cfg.s.ccISAP.pst.pool = S_POOL;
cfg.t.cfg.s.ccISAP.pst.selector = 0;
cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0;
cfg.t.cfg.s.ccISAP.pst.route = RTESPEC;
cfg.t.cfg.s.ccISAP.pst.region = S_REG;
cfg.t.cfg.s.ccISAP.pst.pool = S_POOL;
cfg.t.cfg.s.ccISAP.pst.selector = 0;
cfg.t.cfg.s.ccISAP.suId = signal_data->cc_id;
cfg.t.cfg.s.ccISAP.spId = signal_data->cc_id;
@ -1020,19 +1004,19 @@ ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span)
void stack_pst_init(Pst *pst)
{
memset(pst, 0, sizeof(Pst));
/*fill in the post structure*/
pst->dstProcId = SFndProcId();
pst->dstInst = S_INST;
/*fill in the post structure*/
pst->dstProcId = SFndProcId();
pst->dstInst = S_INST;
pst->srcProcId = SFndProcId();
pst->srcEnt = ENTSM;
pst->srcInst = S_INST;
pst->srcProcId = SFndProcId();
pst->srcEnt = ENTSM;
pst->srcInst = S_INST;
pst->prior = PRIOR0;
pst->route = RTESPEC;
pst->region = S_REG;
pst->pool = S_POOL;
pst->selector = 0;
pst->prior = PRIOR0;
pst->route = RTESPEC;
pst->region = S_REG;
pst->pool = S_POOL;
pst->selector = 0;
return;
}
@ -1041,21 +1025,21 @@ void stack_pst_init(Pst *pst)
void stack_hdr_init(Header *hdr)
{
hdr->msgType = 0;
hdr->msgLen = 0;
hdr->entId.ent = 0;
hdr->entId.inst = 0;
hdr->elmId.elmnt = 0;
hdr->elmId.elmntInst1 = 0;
hdr->elmId.elmntInst2 = 0;
hdr->elmId.elmntInst3 = 0;
hdr->seqNmb = 0;
hdr->version = 0;
hdr->response.prior = PRIOR0;
hdr->response.route = RTESPEC;
hdr->response.mem.region = S_REG;
hdr->response.mem.pool = S_POOL;
hdr->transId = 0;
hdr->response.selector = 0;
hdr->msgLen = 0;
hdr->entId.ent = 0;
hdr->entId.inst = 0;
hdr->elmId.elmnt = 0;
hdr->elmId.elmntInst1 = 0;
hdr->elmId.elmntInst2 = 0;
hdr->elmId.elmntInst3 = 0;
hdr->seqNmb = 0;
hdr->version = 0;
hdr->response.prior = PRIOR0;
hdr->response.route = RTESPEC;
hdr->response.mem.region = S_REG;
hdr->response.mem.pool = S_POOL;
hdr->transId = 0;
hdr->response.selector = 0;
return;
}

View File

@ -37,27 +37,26 @@
void stack_resp_hdr_init(Header *hdr);
ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span);
ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span);
ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span);
ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span);
ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span);
ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span);
ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction);
ftdm_status_t sng_isdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction);
ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction);
ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction);
extern ftdm_sngisdn_data_t g_sngisdn_data;
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
ftdm_status_t sngisdn_stack_start(ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
if (sng_isdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) {
if (sngisdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name);
return FTDM_FAIL;
}
@ -72,7 +71,7 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name);
if (!g_sngisdn_data.ccs[signal_data->cc_id].activation_done) {
g_sngisdn_data.ccs[signal_data->cc_id].activation_done = 1;
if (sng_isdn_activate_cc(span) != FTDM_SUCCESS) {
if (sngisdn_activate_cc(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack CC\n", span->name);
return FTDM_FAIL;
}
@ -80,7 +79,7 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
}
if (sng_isdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) {
if (sngisdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q931\n", span->name);
return FTDM_FAIL;
}
@ -90,20 +89,20 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span)
{
/* Stop L1 first, so we do not receive any more frames */
if (sng_isdn_deactivate_phy(span) != FTDM_SUCCESS) {
if (sngisdn_deactivate_phy(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name);
return FTDM_FAIL;
}
if (sng_isdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
if (sngisdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q931\n", span->name);
return FTDM_FAIL;
}
if (sng_isdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
if (sngisdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q921\n", span->name);
return FTDM_FAIL;
}
@ -113,41 +112,7 @@ ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
}
ftdm_status_t sng_isdn_wake_up_phy(ftdm_span_t *span)
{
L1Mngmt cntrl;
Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTL1;
/* initalize the control structure */
memset(&cntrl, 0, sizeof(cntrl));
/* initalize the control header */
stack_hdr_init(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* configuration */
cntrl.hdr.entId.ent = ENTL1; /* entity */
cntrl.hdr.entId.inst = S_INST; /* instance */
cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
cntrl.t.cntrl.action = AENA;
cntrl.t.cntrl.subAction = SAELMNT;
cntrl.t.cntrl.sapId = signal_data->link_id;
if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
return FTDM_FAIL;
}
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span)
ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span)
{
/* There is no need to start phy, as it will Q921 will send a activate request to phy when it starts */
@ -155,7 +120,7 @@ ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span)
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span)
ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span)
{
L1Mngmt cntrl;
Pst pst;
@ -189,8 +154,41 @@ ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span)
return FTDM_SUCCESS;
}
ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span)
{
L1Mngmt cntrl;
Pst pst;
ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span)
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTL1;
/* initalize the control structure */
memset(&cntrl, 0, sizeof(cntrl));
/* initalize the control header */
stack_hdr_init(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* configuration */
cntrl.hdr.entId.ent = ENTL1; /* entity */
cntrl.hdr.entId.inst = S_INST; /* instance */
cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
cntrl.t.cntrl.action = AENA;
cntrl.t.cntrl.subAction = SAELMNT;
cntrl.t.cntrl.sapId = signal_data->link_id;
if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
return FTDM_FAIL;
}
return FTDM_SUCCESS;
}
ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span)
{
CcMngmt cntrl;
Pst pst;
@ -224,7 +222,7 @@ ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span)
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt)
ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
switch (trace_opt) {
@ -233,7 +231,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_log(FTDM_LOG_INFO, "s%d Disabling q921 trace\n", signal_data->link_id);
sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921);
if (sng_isdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
if (sngisdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q921 trace\n");
}
}
@ -241,7 +239,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_log(FTDM_LOG_INFO, "s%d Disabling q931 trace\n", signal_data->link_id);
sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q931);
if (sng_isdn_cntrl_q931(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
if (sngisdn_cntrl_q931(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q931 trace\n");
}
}
@ -251,7 +249,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_log(FTDM_LOG_INFO, "s%d Enabling q921 trace\n", signal_data->link_id);
sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q921);
if (sng_isdn_cntrl_q921(span, AENA, SATRC) != FTDM_SUCCESS) {
if (sngisdn_cntrl_q921(span, AENA, SATRC) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q921 trace\n");
}
}
@ -261,7 +259,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_log(FTDM_LOG_INFO, "s%d Enabling q931 trace\n", signal_data->link_id);
sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q931);
if (sng_isdn_cntrl_q931(span, AENA, SATRC) != FTDM_SUCCESS) {
if (sngisdn_cntrl_q931(span, AENA, SATRC) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q931 trace\n");
}
}
@ -271,7 +269,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
}
ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction)
ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction)
{
InMngmt cntrl;
Pst pst;
@ -310,7 +308,7 @@ ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t sub
}
ftdm_status_t sng_isdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction)
ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction)
{
BdMngmt cntrl;
Pst pst;

View File

@ -535,7 +535,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
case FTDM_CHANNEL_STATE_DIALING:
/* Remote side rejected our SETUP message on outbound call */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
}
/* fall-through */
case FTDM_CHANNEL_STATE_PROGRESS:

View File

@ -34,13 +34,6 @@
#include "ftmod_sangoma_isdn.h"
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan);
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
{
ConEvnt conEvnt;
@ -596,6 +589,73 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
return;
}
/* We received an incoming frame on the d-channel, send data to the stack */
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
{
sng_l1_frame_t l1_frame;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
memset(&l1_frame, 0, sizeof(l1_frame));
l1_frame.len = len;
memcpy(&l1_frame.data, data, len);
if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_CRC)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_CRC;
}
if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FRAME)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME;
}
if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_ABORT)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT;
}
if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FIFO)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO;
}
if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_DMA)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_DMA;
}
if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)) {
/* Should we trigger congestion here? */
l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES;
}
if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)) {
/* Should we trigger congestion here? */
l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL;
}
sng_isdn_data_ind(signal_data->link_id, &l1_frame);
}
void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event)
{
sng_l1_event_t l1_event;
sngisdn_span_data_t *signal_data = NULL;
memset(&l1_event, 0, sizeof(l1_event));
signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
switch(event) {
case FTDM_OOB_ALARM_CLEAR:
l1_event.type = SNG_L1EVENT_ALARM_OFF;
sng_isdn_event_ind(signal_data->link_id, &l1_event);
break;
case FTDM_OOB_ALARM_TRAP:
l1_event.type = SNG_L1EVENT_ALARM_ON;
sng_isdn_event_ind(signal_data->link_id, &l1_event);
break;
default:
/* We do not care about the other OOB events for now */
return;
}
return;
}
/* For Emacs:

View File

@ -732,7 +732,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
} else {
ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
status->t.usta.suId,
@ -741,7 +741,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN);
sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
}
}
break;
@ -862,6 +862,82 @@ end_of_trace:
return;
}
/* The stacks is wants to transmit a frame */
int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame)
{
ftdm_status_t status;
ftdm_wait_flag_t flags = FTDM_WRITE;
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId];
ftdm_size_t length = l1_frame->len;
ftdm_assert(signal_data, "Received Data request on unconfigured span\n");
do {
flags = FTDM_WRITE;
status = signal_data->dchan->fio->wait(signal_data->dchan, &flags, 1000);
if (status != FTDM_SUCCESS) {
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "transmit timed-out\n");
return -1;
}
if ((flags & FTDM_WRITE)) {
status = signal_data->dchan->fio->write(signal_data->dchan, l1_frame->data, (ftdm_size_t*)&length);
if (status != FTDM_SUCCESS) {
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_CRIT, "Failed to transmit frame\n");
return -1;
}
break;
/* On WIN32, it is possible for poll to return without FTDM_WRITE flag set, so we try to retransmit */
#ifndef WIN32
} else {
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "Failed to poll for d-channel\n");
return -1;
#endif
}
} while(1);
return 0;
}
int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd)
{
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId];
ftdm_assert(signal_data, "Received Data request on unconfigured span\n");
switch(l1_cmd->type) {
case SNG_L1CMD_SET_LINK_STATUS:
{
ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED;
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_SET_LINK_STATUS, &status);
}
break;
case SNG_L1CMD_GET_LINK_STATUS:
{
ftdm_channel_hw_link_status_t status = 0;
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_GET_LINK_STATUS, &status);
if (status == FTDM_HW_LINK_CONNECTED) {
l1_cmd->cmd.status = 1;
} else if (status == FTDM_HW_LINK_DISCONNECTED) {
l1_cmd->cmd.status = 0;
} else {
ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Invalid link status reported %d\n", status);
l1_cmd->cmd.status = 0;
}
}
break;
case SNG_L1CMD_FLUSH_STATS:
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_IOSTATS, NULL);
break;
case SNG_L1CMD_FLUSH_BUFFERS:
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_BUFFERS, NULL);
break;
default:
ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Unsupported channel command:%d\n", l1_cmd->type);
return -1;
}
return 0;
}
void sngisdn_rcv_sng_assert(char *message)
{
ftdm_assert(0, message);

View File

@ -39,7 +39,7 @@ ftdm_status_t sngisdn_check_free_ids(void);
extern ftdm_sngisdn_data_t g_sngisdn_data;
void get_memory_info(void);
FT_DECLARE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info)
void clear_call_data(sngisdn_chan_data_t *sngisdn_info)
{
uint32_t cc_id = ((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->cc_id;
@ -56,7 +56,7 @@ FT_DECLARE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info)
return;
}
FT_DECLARE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
{
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Clearing glare data (suId:%d suInstId:%u spInstId:%u actv-suInstId:%u actv-spInstId:%u)\n",
sngisdn_info->glare.suId,
@ -81,7 +81,7 @@ FT_DECLARE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
}
FT_DECLARE(uint32_t) get_unique_suInstId(int16_t cc_id)
uint32_t get_unique_suInstId(int16_t cc_id)
{
uint32_t suInstId;
ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
@ -103,7 +103,7 @@ FT_DECLARE(uint32_t) get_unique_suInstId(int16_t cc_id)
return 0;
}
FT_DECLARE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
{
ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
@ -115,7 +115,7 @@ FT_DECLARE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suIns
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
{
ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
@ -127,7 +127,7 @@ FT_DECLARE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spIns
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
{
if (span->trunk_type == FTDM_TRUNK_BRI ||
@ -147,7 +147,7 @@ ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb)
ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb)
{
if (cgPtyNmb->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
@ -174,7 +174,7 @@ FT_DECLARE(ftdm_status_t) cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, C
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb)
ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb)
{
if (cdPtyNmb->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
@ -196,7 +196,7 @@ FT_DECLARE(ftdm_status_t) cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, Cd
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb)
ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb)
{
if (redirNmb->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
@ -216,7 +216,7 @@ FT_DECLARE(ftdm_status_t) cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, Red
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display)
ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display)
{
if (display->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
@ -229,7 +229,7 @@ FT_DECLARE(ftdm_status_t) cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm,
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm)
ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm)
{
uint8_t len = strlen(ftdm->cid_num.digits);
if (!len) {
@ -257,7 +257,7 @@ FT_DECLARE(ftdm_status_t) cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_cal
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm)
ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm)
{
uint8_t len = strlen(ftdm->dnis.digits);
if (!len) {
@ -287,7 +287,7 @@ FT_DECLARE(ftdm_status_t) cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_call
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm)
ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm)
{
uint8_t len = strlen(ftdm->rdnis.digits);
if (!len) {
@ -319,7 +319,7 @@ FT_DECLARE(ftdm_status_t) cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_calle
}
FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan)
ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan)
{
uint8_t len;
ftdm_caller_data_t *ftdm = &ftdmchan->caller_data;
@ -394,6 +394,17 @@ void sngisdn_t3_timeout(void* p_sngisdn_info)
ftdm_mutex_unlock(ftdmchan->mutex);
}
void sngisdn_delayed_setup(void* p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
ftdm_mutex_lock(ftdmchan->mutex);
sngisdn_snd_setup(ftdmchan);
ftdm_mutex_unlock(ftdmchan->mutex);
return;
}
void sngisdn_delayed_release(void* p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;

View File

@ -115,7 +115,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
static __inline__ int tdmv_api_wait_socket(ftdm_channel_t *ftdmchan, int timeout, int *flags)
{
#ifdef LIBSANGOMA_VERSION
#ifdef LIBSANGOMA_VERSION
int err;
uint32_t inflags = *flags;
uint32_t outflags = 0;
@ -169,7 +169,7 @@ static __inline__ sng_fd_t tdmv_api_open_span_chan(int span, int chan)
static __inline__ sng_fd_t __tdmv_api_open_span_chan(int span, int chan)
{
return __sangoma_open_tdmapi_span_chan(span, chan);
}
}
#endif
static ftdm_io_interface_t wanpipe_interface;
@ -745,6 +745,28 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
}
}
break;
case FTDM_COMMAND_FLUSH_BUFFERS:
{
err = sangoma_flush_bufs(ftdmchan->sockfd, &tdm_api);
}
break;
case FTDM_COMMAND_FLUSH_IOSTATS:
{
err = sangoma_flush_stats(ftdmchan->sockfd, &tdm_api);
}
break;
case FTDM_COMMAND_SET_RX_QUEUE_SIZE:
{
uint32_t queue_size = FTDM_COMMAND_OBJ_INT;
err = sangoma_set_rx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
}
break;
case FTDM_COMMAND_SET_TX_QUEUE_SIZE:
{
uint32_t queue_size = FTDM_COMMAND_OBJ_INT;
err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
}
break;
default:
break;
};
@ -758,6 +780,46 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
return FTDM_SUCCESS;
}
static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx_stats)
{
ftdmchan->iostats.stats.rx.flags = 0;
ftdmchan->iostats.stats.rx.errors = rx_stats->wp_api_rx_hdr_errors;
ftdmchan->iostats.stats.rx.rx_queue_size = rx_stats->wp_api_rx_hdr_max_queue_length;
ftdmchan->iostats.stats.rx.rx_queue_len = rx_stats->wp_api_rx_hdr_number_of_frames_in_queue;
if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_ABORT_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_ABORT);
}
if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_DMA_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_DMA);
}
if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_FIFO_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FIFO);
}
if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_CRC_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_CRC);
}
if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_FRAME_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FRAME);
}
if (ftdmchan->iostats.stats.rx.rx_queue_len >= (0.8*ftdmchan->iostats.stats.rx.rx_queue_size)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Rx Queue length exceeded threshold (%d/%d)\n",
ftdmchan->iostats.stats.rx.rx_queue_len, ftdmchan->iostats.stats.rx.rx_queue_size);
ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
}
if (ftdmchan->iostats.stats.rx.rx_queue_len >= ftdmchan->iostats.stats.rx.rx_queue_size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Rx Queue Full (%d/%d)\n",
ftdmchan->iostats.stats.rx.rx_queue_len, ftdmchan->iostats.stats.rx.rx_queue_size);
ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
}
return;
}
/**
* \brief Reads data from a Wanpipe channel
* \param ftdmchan Channel to read from
@ -786,9 +848,11 @@ static FIO_READ_FUNCTION(wanpipe_read)
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len);
return FTDM_FAIL;
}
}
if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
wanpipe_read_stats(ftdmchan, &hdrframe);
}
return FTDM_SUCCESS;
}

View File

@ -430,12 +430,15 @@ typedef enum {
FTDM_COMMAND_FLUSH_TX_BUFFERS,
FTDM_COMMAND_FLUSH_RX_BUFFERS,
FTDM_COMMAND_FLUSH_BUFFERS,
FTDM_COMMAND_FLUSH_IOSTATS,
FTDM_COMMAND_SET_PRE_BUFFER_SIZE,
FTDM_COMMAND_SET_LINK_STATUS,
FTDM_COMMAND_GET_LINK_STATUS,
FTDM_COMMAND_ENABLE_LOOP,
FTDM_COMMAND_DISABLE_LOOP,
FTDM_COMMAND_COUNT
FTDM_COMMAND_COUNT,
FTDM_COMMAND_SET_RX_QUEUE_SIZE,
FTDM_COMMAND_SET_TX_QUEUE_SIZE,
} ftdm_command_t;
/*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */

View File

@ -222,8 +222,7 @@ extern "C" {
#define ftdm_is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119)
#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
/*!
\brief Copy flags from one arbitrary object to another
\command dest the object to copy the flags to
@ -358,6 +357,7 @@ typedef struct {
} ftdm_dtmf_debug_t;
#endif
typedef struct {
const char *file;
const char *func;
@ -367,6 +367,33 @@ typedef struct {
ftdm_time_t time;
} ftdm_channel_history_entry_t;
typedef enum {
FTDM_IOSTATS_ERROR_CRC = (1<<0),
FTDM_IOSTATS_ERROR_FRAME = (1<<1),
FTDM_IOSTATS_ERROR_ABORT = (1<<2),
FTDM_IOSTATS_ERROR_FIFO = (1<<3),
FTDM_IOSTATS_ERROR_DMA = (1<<4),
FTDM_IOSTATS_ERROR_QUEUE_THRES = (1<<5), /* Queue reached high threshold */
FTDM_IOSTATS_ERROR_QUEUE_FULL = (1<<6), /* Queue is full */
} ftdm_iostats_error_type_t;
typedef struct {
union {
struct {
uint32_t errors;
uint16_t flags;
uint8_t rx_queue_size; /* max queue size configured */
uint8_t rx_queue_len; /* Current number of elements in queue */
} rx;
struct {
uint32_t errors;
uint16_t flags;
uint8_t tx_queue_size; /* max queue size configured */
uint8_t tx_queue_len; /* Current number of elements in queue */
} tx;
} stats;
} ftdm_channel_iostats_t;
/* 2^8 table size, one for each byte (sample) value */
#define FTDM_GAINS_TABLE_SIZE 256
struct ftdm_channel {
@ -441,6 +468,7 @@ struct ftdm_channel {
int availability_rate;
void *user_private;
ftdm_timer_id_t hangup_timer;
ftdm_channel_iostats_t iostats;
#ifdef FTDM_DEBUG_DTMF
ftdm_dtmf_debug_t dtmfdbg;
#endif
@ -637,10 +665,21 @@ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan);
#define ftdm_channel_lock(chan) ftdm_mutex_lock(chan->mutex)
#define ftdm_channel_unlock(chan) ftdm_mutex_unlock(chan->mutex)
#define ftdm_log_throttle(level, ...) \
time_current_throttle_log = ftdm_current_time_in_ms(); \
if (time_current_throttle_log - time_last_throttle_log > FTDM_THROTTLE_LOG_INTERVAL) {\
ftdm_log(level, __VA_ARGS__); \
time_last_throttle_log = time_current_throttle_log; \
}
#define ftdm_log_chan_ex(fchan, file, func, line, level, format, ...) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id)
#define ftdm_log_chan_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_log_chan_msg_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex)
#define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex)

View File

@ -194,6 +194,7 @@ typedef enum {
FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */
FTDM_CHANNEL_FEATURE_HWEC = (1<<7), /*!< Channel has a hardware echo canceller */
FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE = (1<<8), /*!< hardware echo canceller is disabled when there are no calls on this channel */
FTDM_CHANNEL_FEATURE_IO_STATS = (1<<9), /*!< Channel supports IO statistics (HDLC channels only) */
} ftdm_channel_feature_t;
typedef enum {