|
|
| (28 intermediate revisions by the same user not shown) |
| Line 1: |
Line 1: |
| {{DISPLAYTITLE:Routing Script tutorial: A Mini Development Guide}} | | {{DISPLAYTITLE:Routing Script Tutorial: Development Guide}} |
| | |
| | |
|
| |
|
| ==Introduction== | | ==Introduction== |
| This Routing Script Tutorial provides you with essential information in managing the routing of your calls. Consult the sections below to learn more. | | This Routing Script Tutorial provides you with essential information in managing the routing of your calls. Consult the sections below to learn more. |
| | |
| | {| class="wikitable" |
| | |
| | |[[File:NoteIcon.png|100px]]|| An alternate version of this guide for routing scripts is available. [[Routing script tutorial|Consult it to enhance your learning.]] |
| | |} |
|
| |
|
| ==Accessing Routing Script Parameters == | | ==Accessing Routing Script Parameters == |
| Line 28: |
Line 35: |
| [[Routing Script Tutorial: Recording|Learn how to use routing scripts to record incoming and/or outgoing call legs.]] | | [[Routing Script Tutorial: Recording|Learn how to use routing scripts to record incoming and/or outgoing call legs.]] |
|
| |
|
| | ==User-to-User Information== |
| | [[Routing Script Tutorial: User-to-User Information|Learn how to use User-to-User Information (UUI) in routing scripts.]] |
|
| |
|
| | ==Radius Autorization== |
| | [[Routing Script Tutorial: Radius Authorization|Learn how to send RADIUS authorization requests in routing scripts.]] |
|
| |
|
| | | ==ENUM Query== |
| | | [[Routing Script Tutorial: ENUM Query|Learn how to send ENUM Query requests to DNS servers in routing scripts.]] |
| | |
| | |
| | |
| == Controlling UUI relay ==
| |
| UUI (user-to-user information) can be present in different messages received by either call leg during a call. For example, information can be carried during the initial invite, other information can be carried when the call is alerted, answered, or terminated.
| |
| | |
| Routing scripts can control if the UUI received from one leg through the call will be forwarded to the other call leg:
| |
| *uui_forward_enabled
| |
| | |
| Routing scripts can also read and modify the UUI received with the incoming call leg, before it gets forwarded upon creation of the outgoing call leg:
| |
| *uui
| |
| | |
| === UUI (user-to-user indication) values ===
| |
| | |
| Byte array represented as ruby String. Use ''bridge=params[:bridge]'', then ''bridge[:uui]'' to access the data.
| |
| | |
| To access the bytes in Ruby, use ruby String operator []. For example: bridge[:uui][0] will return the binary value of the first UUI byte.
| |
| | |
| Function each_byte can also be useful to iterate through all bytes of the UUI.
| |
| | |
| === uui_forward_enabled values ===
| |
| | |
| Controls forwarding or discarding of UUI to outgoing call leg.
| |
| | |
| Values for this parameter are "0", "1", "false" or "true.
| |
| * 0/false: UUI is not forwarded between call legs
| |
| * 1/true: UUI is forwarded between call legs
| |
| | |
| The value for this parameter at input of routing script depends on the "Forward UUI" parameter in the "Advanced" section of the Gateway configuration page of the Web Portal. The script may change this value to override the Gateway configuration.
| |
| | |
| == Authorization ==
| |
| Starting with release 2.7, it is possible to issue RADIUS authorization requests from routing scripts. To do so, the params[:authorization] object must be filled with the required RADIUS attributes and [[#Refuse|an exception must be raised]] with reason :authorization_required.
| |
| | |
| When the authorization is completed, the routing script is called again with the result. The params[:authorization] object will be filled with the RADIUS attributes from the response. The params[:authorization][:result] field will also contain a string indicating the result of the authorization:
| |
| | |
| * ''accept'': The authorization was successful.
| |
| * ''reject'': The authorization was refused.
| |
| * ''challenge'': The authorization was challenged.
| |
| * ''timeout'': The authorization was not answered.
| |
| | |
| == ENUM Query == | |
| Starting with release 3.1, it is possible to issue ENUM Query requests to DNS servers from routing scripts. To do so, the params[:enum_query] object must be filled with the required ENUM Query attributes params[:enum_query][:fqdn] and [[#Refuse|an exception must be raised]] with reason :enum_query_required.
| |
| | |
| When ENUM Query completes, the routing script is called again with the result. The params[:enum_query] object will be filled with the ENUM Query attributes from the response. The params[:enum_query][:result] field will also contain a string indicating the result of the ENUM Query:
| |
| | |
| * ''ok'': The ENUM Query was successful.
| |
| * ''timeout'': The ENUM Query was not answered.
| |
| | |
| The params[:enum_query][:responses_list] field will contain a list of hash responses for each NAPTR records.
| |
| | |
| NAPTR records contain:
| |
| * '':uri''
| |
| * '':order''
| |
| * '':preference''
| |
| Example:
| |
| <code>
| |
| params[:enum_query][:responses_list]
| |
| [{:order=>"200", :preference=>"10", :uri=>"!^03111.*$!sip:123456782@example-2.com!"},
| |
| {:order=>"100", :preference=>"1", :uri=>"!^03222.*$!sip:123456782@example-3.com!"},
| |
| {:order=>"200", :preference=>"1", :uri=>"!^03111.*$!sip:123456782@example-1.com!"}]
| |
| </code>
| |
| | |
| Using enum_called_remap.rb before filter script allows handling of ENUM query requests/responses. The match and replace regular expression from ENUM query responses are applied to params[:call][:called] to get "new called". This script allows update of the call parameters according to "new called" value. Refer to enum_called_remap.rb before filter script to get instructions on how to integrate this script into the main routing script (i.e. simple_routing_sbc.rb):
| |
| | |
| <code>
| |
| ...
| |
| require 'enum_called_remap' unless defined?(EnumCalledRemap)
| |
| ...
| |
| include EnumCalledRemap
| |
| ...
| |
| before_filter :method => :enum_called_remap
| |
| ...
| |
| </code>
| |
| | |
| === Resolve ENUM Query down to type A records ===
| |
| | |
| The ENUM query could also resolve uri from responses and get matching outgoing NAP, NAP proxy IP and port through a sequence of DNS queries (i.e. NAPTR, SRV down to type A records). This behavior could be requested using "dns_query" parameter:
| |
| | |
| <code>
| |
| params[:enum_query][:dns_query] = true
| |
| </code>
| |
| | |
| When ENUM and DNS Queries complete, the routing script is called again with the results. The params[:enum_query] and params[:dns_query] objects will be filled with the ENUM Query and the DNS Query attributes from the responses. The DNS query responses are available through params[:dns_query][:responses_list] call parameters:
| |
| | |
| <code>
| |
| params[:dns_query][:responses_list]
| |
| [{:nap=>"NAP_UDP", :nap_proxy_ip=>"10.3.14.191", :nap_proxy_port=>"8080", :transport=>"UDP", :order=>"100",
| |
| :preference=>"1", :priority=>"0", :weight=>"5"},
| |
| {:nap=>"NAP_TCP", :nap_proxy_ip=>"10.3.14.192", :nap_proxy_port=>"8081", :transport=>"TCP", :order=>"100",
| |
| :preference=>"2", :priority=>"1", :weight=>"10"}]
| |
| </code>
| |
| | |
| === Add dynamic routes ===
| |
| | |
| The ENUM query could also add dynamic routes base on DNS query responses. This could be requested using the "add_dynamic_routes" call parameter:
| |
| | |
| <code>
| |
| params[:enum_query][:dns_query] = true
| |
| params[:enum_query][:add_dynamic_routes] = true
| |
| </code>
| |
| | |
| Note that it is mandatary to send DNS query to add dynamic routes.
| |
| | |
| The "base_routing.rb" script version should be greater then 1.37 in order to allow dynamic routes creation base on DNS query responses.
| |
| | |
| When requesting to add_dynamic_routes, the dns_query responses are used to create routes. Make sure that your configuration includes a route with remapped_nap = "Registered or DNS users". A route will be created for each DNS query responses. The routes "remapped_nap" takes NAP value from DNS query responses.
| |
| | |
| It is required to modify main routing script (i.e. simple_routing_sbc.rb) to forward IP/port values from params[:routes] to params[:call] like we are doing for NAP. See following example:
| |
| | |
| <code>
| |
| ...
| |
| # This will select the outgoing NAP for this call according to the "remapped_nap" route parameter
| |
| route_remap :call_field_name => :nap, :route_field_name => :remapped_nap
| |
|
| |
| # This will select the outgoing NAP proxy ip address for this call according to the "remapped_nap_proxy_ip" route parameter
| |
| route_remap :call_field_name => :nap_proxy_ip, :route_field_name => :remapped_nap_proxy_ip
| |
|
| |
| # This will select the outgoing NAP proxy port for this call according to the "remapped_nap_proxy_port" route parameter
| |
| route_remap :call_field_name => :nap_proxy_port, :route_field_name => :remapped_nap_proxy_port
| |
| ...
| |
| </code>
| |
|
| |
|
| == DNS Query == | | == DNS Query == |
| Similarly to ENUM query, starting with release 3.1, it is possible to issue DNS Query requests to DNS servers from routing scripts. This could be used to skip the ENUM Query part when the called uri is already known but still need to get the matching outgoing NAP, NAP proxy IP and port. To do so, the params[:dns_query] object must be filled with the required DNS Query attributes params[:dns_query][:fqdn] and [[#Refuse|an exception must be raised]] with reason :dns_query_required.
| | [[Routing Script Tutorial: DNS Query|Learn how to send DNS Query requests to DNS servers in routing scripts.]] |
|
| |
|
| When DNS Query completes, the routing script is called again with the result. The params[:dns_query] object will be filled with the DNS Query attributes from the responses. The DNS query responses are available through params[:dns_query][:responses_list] call parameters:
| | == Call Diversion Options == |
| | [[Routing Script Tutorial: Call Diversion Options|Learn how control a call flow with diversion options.]] |
|
| |
|
| <code>
| | == Call Transfer Requests == |
| params[:dns_query][:responses_list]
| | [[Routing Script Tutorial: Call Transfer Requests|Learn how to route call transfer requests.]] |
| [{:nap=>"NAP_UDP", :nap_proxy_ip=>"10.3.14.191", :nap_proxy_port=>"8080", :transport=>"UDP", :order=>"100",
| |
| :preference=>"1", :priority=>"0", :weight=>"5"},
| |
| {:nap=>"NAP_TCP", :nap_proxy_ip=>"10.3.14.192", :nap_proxy_port=>"8081", :transport=>"TCP", :order=>"100",
| |
| :preference=>"2", :priority=>"1", :weight=>"10"}]
| |
| </code>
| |
| | |
| === Add dynamic routes ===
| |
| | |
| Similarly to ENUM Query, the DNS query could also create dynamic routes base on DNS query responses. This could be requested using the "add_dynamic_routes" call parameter:
| |
| | |
| <code>
| |
| params[:dns_query][:add_dynamic_routes] = true
| |
| </code>
| |
| | |
| The "base_routing.rb" script version should be greater then 1.37 in order to allow dynamic routes creation base on DNS query responses.
| |
| | |
| When requesting to add_dynamic_routes, the dns_query responses are used to create routes. Make sure that your configuration include a route with remapped_nap = "Registered or DNS users". A route will be created for each DNS query responses. The routes "remapped_nap" takes NAP value from DNS query responses.
| |
| | |
| It is required to modify main routing script (i.e. simple_routing_sbc.rb) to forward IP/port values from params[:routes] to params[:call] like we are doing for NAP. See following example:
| |
| | |
| <code>
| |
| ...
| |
| # This will select the outgoing NAP for this call according to the "remapped_nap" route parameter
| |
| route_remap :call_field_name => :nap, :route_field_name => :remapped_nap
| |
|
| |
| # This will select the outgoing NAP proxy ip address for this call according to the "remapped_nap_proxy_ip" route parameter
| |
| route_remap :call_field_name => :nap_proxy_ip, :route_field_name => :remapped_nap_proxy_ip
| |
|
| |
| # This will select the outgoing NAP proxy port for this call according to the "remapped_nap_proxy_port" route parameter
| |
| route_remap :call_field_name => :nap_proxy_port, :route_field_name => :remapped_nap_proxy_port
| |
| ...
| |
| </code>
| |
| | |
| == Call diversion options ==
| |
| It's possible to control the call flow when a call diversion information is received in the alerting state.
| |
| | |
| Two fields are available: bridge[ :diversion ] and bridge[ :diversion_reason ]
| |
| | |
| The internal release cause TOOLPACK_DIVERT_NOT_ALLOWED is used by gateway application to terminate both legs.
| |
| | |
| bridge[ :diversion ] = :allowed
| |
| The alert message will not be analyzed and the call will be progressed. Default behavior.
| |
| bridge[ :diversion ] = :not_allowed
| |
| If the alert message indicates that the call is diverted, the call will be released no matter the In-band information to allow
| |
| early media.
| |
| bridge[ :diversion ] = :not_allowed_w_early_media
| |
| The call will be released If the alert message indicates that the call is diverted with in-band information to allow early media.
| |
| bridge[ :diversion_reason ] = "*"
| |
| If the diversion is not allowed, the gateway will drop the call for any redirecting reason.
| |
| bridge[ :diversion_reason ] = "0,1,2"
| |
| or
| |
| bridge[ :diversion_reason ] = "unknown,busy,no_reply"
| |
| If the diversion is not allowed, the redirecting reason will be analyzed and the call will only be dropped for the configured cases.
| |
| | |
| See section [[Routing_script_tutorial:Mini_Development_Guide#Redirecting_number,_Original_Called_Number_and_Diversion_Reason|Redirecting number reason values]].
| |
| | |
| == Call transfer requests ==
| |
| Toolpack allows that [[Call transfer]] requests are relayed from one leg to the other, or to process them locally (making another outgoing call to replace the call that requested the call transfer).
| |
| | |
| If the chosen [[Call transfer]] mode is to process requests locally, upon reception of a call transfer request (SIP REFER or ISDN Facility), routing script will be called once again, to select the routes for the new outgoing call (call transfer target).
| |
| | |
| === How to route call transfer request ===
| |
| Routing of a call transfer request is done exactly like routing of a normal incoming call.
| |
| The routing script generally does not need any modification to support that.
| |
| | |
| In some cases, the routing script may want to use information related to the transfer request to perform routing, or to insert information in the outgoing call leg.
| |
| Additional information is provided to the routing script, allowing routing decisions using information from the call transfer request (SIP REFER or ISDN Facility).
| |
| See below...
| |
| | |
| === params[ :call ] content during transfer request ===
| |
| When processing a call transfer request, the params[ :call ] hash contains the information from the inbound call (same as was passed to the routing script upon arrival of the inbound call)
| |
| call = params[ :call ] -> Information from original inbound call, with exception of call[ :called ]
| |
| | |
| One exception (convenient because it allows a unmodified routing script to process call transfer request the same way as any other routing request):
| |
| call[ :called ] -> Replaced by the called number from the call transfer request (also called "redirection number")
| |
| Complementary information:
| |
| call[ :original_called_number ] -> Contains the called number that was initially received from the incoming call, prior to call transfer request
| |
| call[ :redirecting_number ] -> Number of the call from which the call transfer request was received (generally equals to original_called_number)
| |
| | |
| These fields will also be included in the outgoing call made after routing:
| |
| * original called number and redirecting number are existing fields on SS7 and ISDN calls
| |
| * SIP "diversion" header is used for SIP calls
| |
| | |
| === params[ :transfer ] content ===
| |
| (this if valid only for release 2.7.102 and above)<br>
| |
| When processing a call transfer request, information from the call transfer request message (SIP REFER, ISDN Facility) is provided in params[ :transfer ]:
| |
| transfer = params[ :transfer ]
| |
| The following field is always present:
| |
| transfer[ :original_nap ] -> Contains the NAP of the first call from which a call transfer request was received
| |
| transfer[ :redirecting_nap ] -> Contains the NAP of the call from which the current call transfer request was received
| |
| (same as :original_nap for the first call transfer, different for subsequent transfers)
| |
| Examples of other fields that may be present, when appropriate:
| |
| transfer[ :uui ] -> The UUI (user-to-user information) found in the call transfer request
| |
| transfer[ :sip_header ] -> Contains custom SIP headers from the call transfer request
| |
| transfer[ :request_uri ] -> Contains the SIP Request URI
| |
| | |
| These fields are 'read-only'. They will not be included in the outgoing call, as they represent the contents of the call transfer request, and not the outgoing call to be made.
| |
| | |
| To insert/modify attributes of the outgoing call, the parameters from params[ :call ] must be edited instead.
| |
|
| |
|
| == Redirection == | | == Redirection == |
| In release 2.8 and above, redirection contacts are obtained from the routing engine in the following format:
| | [[Routing Script Tutorial: Redirection|Learn how to get redirection contacts.]] |
| | |
| contacts = params[ :contacts ]
| |
| contacts = {
| |
| :index=>"3",
| |
| :list=>[
| |
| {:called_number=>"6660", :priority=>"1000", :is_number_ported=>"0", :sip_uri=>"", :raw_data=>"", :expiration=>"3600"},
| |
| {:called_number=>"6661", :priority=>"1000", :is_number_ported=>"0", :sip_uri=>"sip:6661@192.168.215.127", :raw_data=>"<sip:6661@192.168.215.127>", :expiration=>"3600"}
| |
| {:called_number=>"6662", :priority=>"1000", :is_number_ported=>"0", :sip_uri=>"sip:6662@192.168.215.128", :raw_data=>"<sip:6662@192.168.215.128>", :expiration=>"3600"},
| |
| {:called_number=>"6663", :priority=>"1000", :is_number_ported=>"0", :sip_uri=>"sip:6663@192.168.215.129", :raw_data=>"<sip:6663@192.168.215.129>", :expiration=>"3600"},
| |
| {:called_number=>"6664", :priority=>"1000", :is_number_ported=>"0", :sip_uri=>"sip:6664@192.168.215.150", :raw_data=>"<sip:6664@192.168.215.150>", :expiration=>"3600"}
| |
| ],
| |
| :source_indexes=>"nil,0,0,0,2"
| |
| }
| |
|
| |
|
| * <code>params[:contacts][:list]</code> contains the contact log. Each contact within the list has the following fields:
| | == Connected Number == |
| ** <code>:called_number</code> - the called number
| | [[Routing Script Tutorial: Connected Number|Connected Number]] |
| ** <code>:is_number_ported</code> - if the called number has been ported (for SIP: if the npdi parameter is present)
| |
| ** <code>:ported_number</code> - the called number that was ported (for SIP: the rn parameter value, if available)
| |
| ** <code>:sip_uri</code> - the SIP URI of the contact, without the contact-params section (without the expires and q contact parameters)
| |
| ** <code>:raw_data</code> - the raw data representing the contact in the signaling protocol. For SIP, this is the full SIP URI (including the expires and q contact parameters).
| |
| ** <code>:priority</code> - the priority of the contact [0-1000]
| |
| ** <code>:expiration</code> - the expiration time in seconds of the contact
| |
| * <code>params[:contacts][:index]</code> contains the index of the contact that is currently being routed.
| |
| * <code>params[:contacts][:source_indexes]</code> contains a comma-separated list of indexes from <code>params[:contacts][:list]</code>. Each index represents the contact from which the contact in the list was obtained from.
| |
|
| |
|
| | | == Terminating Calls == |
| To get more information, see:
| | [[Routing Script Tutorial: Terminating Calls|Learn how to terminate calls with routing scripts.]] |
| *[[Routing_script_tutorial:SIP_Redirection_Contacts|SIP Redirection Contacts Parameters in a Call Flow]]
| |
| | |
| | |
| == Connected number == | |
| Insert a connected number in the answer message of the call flow.
| |
| | |
| Routing script example:
| |
| bridge = params[ :bridge ]
| |
| bridge [ :connected_number ] = "3335577"
| |
| bridge [ :connected_number_noa ] = :national_number
| |
| bridge [ :connected_number_npi ] = :private
| |
| bridge [ :connected_number_presentation ] = :allowed
| |
| bridge [ :connected_number_screening ] = :pass
| |
| | |
| == Terminating calls ==
| |
| In release 2.8, it is now possible to terminate a call through the routing scripts. The [[#Reason values|reason code]] must be specified in <code>params[:bridge][:reason]</code>. The <code>:terminate</code> hash must be created and copied into <code>params</code>:
| |
| terminate = {}
| |
| params[:terminate] = terminate
| |
| The following fields can then be set in <code>:terminate</code>:
| |
| * <code>:sip_header</code>
| |
| * <code>:contacts</code> # list of contacts as described in the [[#Redirection|redirection]] section
| |
| * <code>:isup_raw</code>
| |
| * <code>:isup_raw_variant</code>
| |
| * <code>:redirecting_number</code>
| |
| * <code>:redirecting_number_noa</code>
| |
| * <code>:redirecting_number_npi</code>
| |
| * <code>:redirecting_number_presentation</code>
| |
| * <code>:redirecting_number_reason</code>
| |
| * <code>:redirecting_number_counter</code>
| |
| * <code>:redirecting_number_indicator</code>
| |
| * <code>:original_called_number</code>
| |
| * <code>:original_called_number_noa</code>
| |
| * <code>:original_called_number_npi</code>
| |
| * <code>:original_called_number_presentation</code>
| |
| * <code>:original_called_number_reason</code>
| |
| * <code>:original_called_number_counter</code>
| |
| | |
| == Reason values ==
| |
| | |
| Check here for Termination Reason Cause codes:<br>
| |
| | |
| [[Termination_cause_codes|Termination Reason Cause codes]]
| |
| <br>
| |
| | |
| Example to refuse an incoming call leg.
| |
| raise RoutingException, :no_route
| |
| | |
| Reason cause strings available inside routing scripts:
| |
| | |
| List of Q.850 reason causes:
| |
| :unallocated_number
| |
| :no_route_to_network
| |
| :no_route_to_destination
| |
| :send_special_tone
| |
| :misdialled_trunk_prefix
| |
| :channel_unacceptable
| |
| :call_awarded_in_established_channel
| |
| :preemption
| |
| :reattempt
| |
| :qor_ported_number
| |
| :normal_call_clearing
| |
| :user_busy
| |
| :no_user_responding
| |
| :no_answer_from_user
| |
| :subscriber_absent
| |
| :call_rejected
| |
| :number_changed
| |
| :redirection
| |
| :exchange_routing_error
| |
| :non_selected_user_clearing
| |
| :destination_out_of_order
| |
| :address_incomplete
| |
| :facility_rejected
| |
| :response_to_status_enquiry
| |
| :normal_unspecified
| |
| :no_circuit_available
| |
| :network_out_of_order
| |
| :frame_mode_out_of_service
| |
| :frame_mode_connection_operational
| |
| :temporary_failure
| |
| :switching_equipment_congestion
| |
| :access_information_discarded
| |
| :requested_circuit_not_available
| |
| :precedence_call_blocked
| |
| :resource_unavailable
| |
| :quality_of_service_not_available
| |
| :requested_facility_not_subscribed
| |
| :outgoing_calls_barred
| |
| :outgoing_calls_barred_within_cug
| |
| :incoming_calls_barred
| |
| :incoming_calls_barred_within_cug
| |
| :bearer_cap_not_authorized
| |
| :bearer_cap_not_available
| |
| :inconsistency_access_info
| |
| :service_not_available
| |
| :bearer_cap_not_implemented
| |
| :channel_type_not_implemented
| |
| :requested_facility_not_implemented
| |
| :only_restricted_digital_info
| |
| :service_not_implemented
| |
| :invalid_call_reference
| |
| :channel_does_not_exist
| |
| :call_identity_does_not_exist
| |
| :call_identity_in_use
| |
| :no_call_suspended
| |
| :call_has_been_cleared
| |
| :user_not_member_of_cug
| |
| :incompatible_destination
| |
| :non_existant_cug
| |
| :invalid_transit_network
| |
| :invalid_message_unspecified
| |
| :mandatory_ie_missing
| |
| :message_type_non_existent
| |
| :message_not_compatible_with_call_state
| |
| :ie_non_existent
| |
| :invalid_ie_content
| |
| :msg_not_compatible_with_call_state
| |
| :recovery_on_timer_expiry
| |
| :parameter_non_existent_passed_on
| |
| :message_with_non_recognized_parameters_discarded
| |
| :protocol_error
| |
| :interworking_unspecified
| |
| | |
| List of toolpack reason causes:
| |
| | |
| :toolpack_normal or :normal
| |
| :toolpack_resource_error or :resource_error
| |
| :toolpack_timeout or :timeout
| |
| :toolpack_no_route or :no_route
| |
| :toolpack_call_collision or :call_collision
| |
| :toolpack_sync_drop or :sync_drop
| |
| :toolpack_signaling_error or :signaling_error
| |
| :toolpack_locally_rejected or :locally_rejected
| |
| :toolpack_interface_not_available or :interface_not_available
| |
| :toolpack_reset_in_progress or :reset_in_progress
| |
| :toolpack_adapter_reject or :adapter_reject
| |
| :toolpack_missing_or_invalid_ie or :missing_or_invalid_ie
| |
| :toolpack_incoming_only or :incoming_only
| |
| :toolpack_system_configuration_changed or :system_configuration_changed
| |
| :toolpack_resource_no_more_available or :resource_no_more_available
| |
| :toolpack_incompatible_media or :incompatible_media
| |
| :toolpack_resource_allocation_failed or :resource_allocation_failed
| |
| :toolpack_data_path_not_available or :data_path_not_available
| |
| :toolpack_local_congestion or :local_congestion
| |
| :toolpack_authorization_required or :authorization_required
| |
| :toolpack_call_divert_is_not_allowed or :call_divert_is_not_allowed
| |
| | |
| List of SIP reason causes:<br/>
| |
| Reason causes starting with a digit must use the following syntax (can't use : as prefix).
| |
| | |
| '300_multiple_choices'
| |
| '301_moved_permanently'
| |
| '302_moved_temporarily'
| |
| '305_use_proxy'
| |
| '380_alternative_service'
| |
| '400_bad_request'
| |
| '401_unauthorized'
| |
| '402_payment_required'
| |
| '403_forbidden'
| |
| '404_not_found'
| |
| '405_method_not_allowed'
| |
| '406_not_acceptable'
| |
| '407_proxy_authentication_required'
| |
| '408_request_timeout'
| |
| '409_conflict'
| |
| '410_gone'
| |
| '413_request_entity_too_large'
| |
| '414_request_URI_too_long'
| |
| '415_unsupported_media'
| |
| '416_unsupported_URI_scheme'
| |
| '420_bad_extension'
| |
| '421_extension_required'
| |
| '422_session_timer_too_small'
| |
| '423_interval_too_brief'
| |
| '429_referrer_identity_error'
| |
| '480_temporary_unavailable'
| |
| '481_call_or_transaction_does_not_exist'
| |
| '482_loop_detected'
| |
| '483_too_many_hops'
| |
| '484_address_incomplete'
| |
| '485_ambiguous'
| |
| '486_busy_here'
| |
| '487_request_terminated'
| |
| '488_not_acceptable_here'
| |
| '489_bad_event'
| |
| '491_retry_after'
| |
| '500_server_internal_error'
| |
| '501_not_implemented'
| |
| '502_bad_gateway'
| |
| '503_service_unavailable'
| |
| '504_server_timeout'
| |
| '505_version_unsupported'
| |
| '513_message_too_large'
| |
| '600_busy_everywhere'
| |
| '603_decline'
| |
| '604_not_exist_anywhere'
| |
| '606_not_acceptable'
| |
|
| |
|
| == NAP status and other NAP information == | | == NAP status and other NAP information == |
| | [[Routing Script Tutorial: NAP Status and other NAP Information|Learn how to use NAP status field in routing scripts.]] |
|
| |
|
| All the status fields of the NAPs are provided for use by the routing scripts.
| | == Telephony Services (CNAM Request over SS7)== |
| ''<br> For developpers: see the nap status provider for more details on which fields are available in the CEngineStatTransNap.hpp file.''
| | [[Routing Script Tutorial: CNAM Request|Learn how to manage CNAM requests over SS7.]] |
|
| |
|
| '''Notice:''' These values may change between major release.
| | == Custom User Context == |
| | | [[Routing Script Tutorial: Custom User Context|Custom User Context]] |
| Routing script call attribute name Description
| |
| --------------------------------------------------------------------------------------------
| |
| "name" NAP name.
| |
| "signaling_type" Signaling type (SS7, ISDN, CASR2, SIP)
| |
| "profile" Profile name.
| |
| "sip_destination_ip" Destination IP address.
| |
| "sip_destination_port" Destination IP port.
| |
| "sip_transport_type" SIP transport type (:udp, :tcp, or :tls) (Toolpack 3.1 and more)
| |
| "inst_incoming_call_cnt" Instantaneous Count of incoming calls.
| |
| "inst_outgoing_call_cnt" Instantaneous Count of outgoing calls.
| |
| "available_cnt" Number of available circuits or channels.
| |
| "unavailable_cnt" Number of unavailable circuits or channels.
| |
| "availability_percent" Percentage of available circuits or channels.
| |
| "usage_percent" Percentage of used circuits or channels.
| |
| "unused_shared_percent" Percentage of used circuits or channels of this NAP available to make new calls with (taking into account shared with other NAPs)
| |
| "total_incoming_call_cnt" Total Count of incoming calls.
| |
| "global_asr_percent" Global calculated ASR percentage.
| |
| "total_outgoing_call_cnt" Total Count of outgoing calls.
| |
| "last_24h_asr_percent" Last 24 hours calculated ASR percentage.
| |
| "last_24h_outgoing_call_cnt" Last 24 hours outgoing calls.
| |
| "current_hour_asr_percent" Current hour calculated ASR percentage.
| |
| "current_hour_outgoing_call_cnt" Current hour outgoing calls.
| |
| "last_hour_asr_percent" Last hour calculated ASR percentage.
| |
| "last_hour_outgoing_call_cnt" Last hour outgoing calls.
| |
| "poll_remote_proxy" Remote proxy polling enabled
| |
| "is_available" Remote proxy actually available or not
| |
| "time_since_polling" Time since the last availibility polling
| |
| "time_available_seconds" Number of seconds since the NAP is available
| |
| "time_unavailable_seconds" Number of seconds since the NAP is unavailable
| |
| "register_to_proxy" Register to proxy enabled
| |
| "registered" Actually registered or not
| |
| "time_since_refresh" Time since the last refresh
| |
| "time_registered_seconds" Number of seconds since the NAP is registered
| |
| "time_not_registered_seconds" Number of seconds since the NAP is not registered
| |
| "asr_stats_incoming_struct" Detailed Answer-Seizure Rate incoming statistics.
| |
| {
| |
| "global_asr_percent" Global calculated ASR percentage.
| |
| "total_call_cnt" Total count of calls.
| |
| "total_accepted_call_cnt" Total count of accepted calls (not dropped due to congestion or rate-limiting).
| |
| "total_answered_call_cnt" Total count of answered calls.
| |
| "last_24h_asr_percent" Last 24 hours calculated ASR percentage.
| |
| "last_24h_call_cnt" Last 24 hours count of calls.
| |
| "current_hour_asr_percent" Current hour calculated ASR percentage.
| |
| "current_hour_call_cnt" Current hour count of calls.
| |
| "last_hour_asr_percent" Last hour calculated ASR percentage.
| |
| "last_hour_call_cnt" Last hour count of calls.
| |
| }
| |
| "asr_stats_outgoing_struct" Detailed Answer-Seizure Rate outgoing statistics.
| |
| {
| |
| "global_asr_percent" Global calculated ASR percentage.
| |
| "total_call_cnt" Total count of calls.
| |
| "total_accepted_call_cnt" Total count of accepted calls (not dropped due to congestion or rate-limiting).
| |
| "total_answered_call_cnt" Total count of answered calls.
| |
| "last_24h_asr_percent" Last 24 hours calculated ASR percentage.
| |
| "last_24h_call_cnt" Last 24 hours count of calls.
| |
| "current_hour_asr_percent" Current hour calculated ASR percentage.
| |
| "current_hour_call_cnt" Current hour count of calls.
| |
| "last_hour_asr_percent" Last hour calculated ASR percentage.
| |
| "last_hour_call_cnt" Last hour count of calls.
| |
| }
| |
| "mos_struct" Detailed Mean Opinion Score statistics.
| |
| {
| |
| "last_24h_ingress" Last 24 hours calculated MOS for incoming RTP packets.
| |
| "last_24h_egress" Last 24 hours calculated MOS for outgoing RTP packets.
| |
| "current_hour_ingress" Current hour calculated MOS for incoming RTP packets.
| |
| "current_hour_egress" Current hour calculated MOS for outgoing RTP packets.
| |
| "last_hour_ingress" Last hour calculated MOS for incoming RTP packets.
| |
| "last_hour_egress" Last hour calculated MOS for outgoing RTP packets.
| |
| }
| |
| "network_quality_struct" Detailed network quality statistics.
| |
| {
| |
| "last_24h_ingress" Last 24 hours network quality percentage for incoming RTP packets.
| |
| "last_24h_egress" Last 24 hours network quality percentage for outgoing RTP packets.
| |
| "current_hour_ingress" Current hour network quality percentage for incoming RTP packets.
| |
| "current_hour_egress" Current hour network quality percentage for outgoing RTP packets.
| |
| "last_hour_ingress" Last hour network quality percentage for incoming RTP packets.
| |
| "last_hour_egress" Last hour network quality percentage for outgoing RTP packets.
| |
| }
| |
|
| |
| <br> The nap status is part of a substructure and will be a hash containing all subfield elements.
| |
| | |
| === Example to access NAP information and NAP status of the current call === | |
| <br> To find the incoming nap in a routing script, we can do this in before_filter or after_filter and use these lines to create a symbol:
| |
| incoming_nap = params[:call][:nap].to_sym
| |
| log_trace 1, "incoming_nap = " + incoming_nap.inspect
| |
| | |
| <br> To get the configured NAP list, you can do this:
| |
| nap_lists = params[:naps]
| |
| log_trace 1, "nap_lists = " + nap_lists.inspect
| |
| | |
| <br> From the list above, you can find how many calls you have on this NAP:
| |
| log_trace 1,"Incoming NAP call count=" + nap_lists[incoming_nap][:asr_stats_incoming_struct][:total_call_cnt].inspect
| |
| <br> Or which network the call is coming from:
| |
| log_trace 1,"Incoming NAP signaling type=" + nap_lists[incoming_nap][:signaling_type].inspect
| |
| | |
| <br> If you are using a "NAP Columns" custom parameter (Create New NAP Column), you can get the information (since incoming_nap is a symbol):
| |
| network_type = nap_lists[incoming_nap][:network_type]
| |
| log_trace 1, "For incoming_nap = " + incoming_nap.inspect + " network_type is: " + network_type.inspect
| |
| | |
| <br> If you want to modify something according to nap information, you may need to do a loop like this:
| |
| nap_lists.each do |nap_list,nap_info|
| |
| log_trace 1, "NAP: " + nap_info[:name].inspect + " network_type: " + nap_info[:network_type].inspect
| |
| end
| |
| | |
| == Telephony Services ==
| |
| In release 2.10 and the above, telephony services (CNAM Request) can be manage from the routing engine in the following format:
| |
| | |
| params[:telephony_services].each do |service| -> Array of telephony services
| |
| service[:name] -> Customer telephony service name
| |
| service[:type] -> For now only "CNAM Request"
| |
| service[:enabled] -> Indicate if the service is enabled (true) or not (false)
| |
| (Only the telephony service define in the profile associated to the NAP is enabled)
| |
| (The others telephony services define in others profiles are disabled)
| |
| (If we are in the case where we return in the routing script with a response, it is important to set :enabled to false in order to avoid repeating the same query)
| |
| serviceParams = service[:params]
| |
| serviceParams[:return_to_script] -> Indicates to Gateway if we must return to the routing script after receiving the CNAM response
| |
| (It is important to set back to false this field to avoid an infinite loop)
| |
| serviceQuery = service[:query]
| |
| serviceQuery[:phone] -> 10 digits of calling number from the incoming call to send to the CNAM server
| |
| serviceQuery[:timeout] -> Timeout in millisecond to wait a CNAM response from CNAM server
| |
| (Default value from profile configuration)
| |
| serviceResponse = service[:response]
| |
| serviceResponse[:success] -> Indicates if we received a good CNAM response from the CNAM Server (Only present if :return_to_script is set to true)
| |
| serviceResponse[:caller_name] -> The caller name received in the CNAM response from the CNAM Server (Only present if :return_to_script is set to true)
| |
| | |
| == Custom user context ==
| |
| The routing script may '''save per-call information within the call context''', that will be available if routing is called again later during the call flow.
| |
| | |
| Cases where routing is called multiple times for the same call are:
| |
| - Call transfer requests
| |
| - SIP redirect requests
| |
| - Radius Authorization result
| |
| - Announcement server with digit collection
| |
| | |
| The routing script can save a recursive hash of attributes here:
| |
| params[:user_context]
| |
| | |
| For example
| |
| params[:user_context] = { "SomeKey" => "Some value I want to retrieve upon next routing for this call", "OtherVal" => { "subkey" => "subval" } }
| |
| | |
| Upon first call to routing script, params[:user_context] will be nil.
| |
| Upon subsequent calls to routing script, it will contain whatever the script had stored upon previous call (or nil if it was not set)
| |
| | |
| Note: This feature is available starting from release 2.9.85, 2.10.31 and 3.0.15 (in respective branches 2.9, 2.10 or 3.0)
| |
|
| |
|
| == Routing Script Tests == | | == Routing Script Tests == |
| The Web portal features a tool for Testing Scripts. The user must enter parameters to simulate the incoming call and after pressing the Test button, will output selected routes and numbers. You do not need to activate the new routes, or the new scripts to use this test tool: It can be used to test the routing scripts and routing table before activating it.
| | [[Routing Script Tutorial: Routing Script Tests|Learn how to use the Web Portal to test your routing scripts.]] |
| This is available in the Routing Scripts section of the Web portal.
| |
| | |
| === Test parameters ===
| |
| ==== @call_params ====
| |
| | |
| That variable should contain a hash of call parameters that will be passed to the routing script. This is equivalent to the incoming call parameters.
| |
| | |
| <br>
| |
| | |
| ==== @nap_list ====
| |
| | |
| A list of the hash containing the nap statuses. This is equivalent to the nap statuses at the time the call is to be routed.
| |
| | |
| '''The nap list is hashed by the nap names in UPPERCASE.''' It is important to consider this when creating new dynamic route or nap attributes that may nap names that will be used to fetch a status.
| |
| | |
| <br>
| |
| | |
| ==== @params ====
| |
| | |
| A hash of hashes containing parameters. This hash contains bridge parameters and other kind of parameter groups may be added in the future.
| |
| | |
| @params = {
| |
| :bridge => {:announcement_tone, "announcement.wav"},
| |
| :contacts => {
| |
| :index=>"1",
| |
| :list=>[
| |
| {:called_number=>"6660", :priority=>"1000", :is_number_ported=>"0", :sip_uri=>"",
| |
| :raw_data=>"", :expiration=>"3600"},
| |
| {:called_number=>"6661", :priority=>"1000", :is_number_ported=>"0", :sip_uri=>"sip:6661@192.168.215.127",
| |
| :raw_data=>"<sip:6661@192.168.215.127>", :expiration=>"3600"}
| |
| ],
| |
| :source_indexes=>"nil,0"
| |
| }
| |
| }
| |
| | |
| <br>
| |
| | |
| ----
| |
| | |
| <br> Back to [[Routing script tutorial|Routing Script Tutorial]].
| |
| | |
| [[category:FAQ]]
| |