####### Global Parameters ######### log_level=3 log_stderror=no log_facility=LOG_LOCAL0 children=4 open_files_limit=4096 tcp_connection_lifetime=360 /* uncomment the following lines to enable debugging */ #debug_mode=yes /* uncomment the next line to enable the auto temporary blacklisting of not available destinations (default disabled) */ #disable_dns_blacklist=no /* uncomment the next line to enable IPv6 lookup after IPv4 dns lookup failures (default disabled) */ #dns_try_ipv6=yes /* comment the next line to enable the auto discovery of local aliases based on reverse DNS on IPs */ auto_aliases=no /* Server&UA */ server_header="Server: Webitel" user_agent_header="User-Agent: Webitel" ####### Connectivity ######## listen=udp:*:5060 listen=tcp:*:5060 #listen=tls:eth0:5061 listen=ws:*:5070 #listen=wss:eth0:5443 ####### Modules Section ######## #set module path mpath="/usr/lib/x86_64-linux-gnu/opensips/modules/" #### SIGNALING module loadmodule "signaling.so" #### StateLess module loadmodule "sl.so" #### Transaction Module loadmodule "tm.so" modparam("tm", "fr_timeout", 5) modparam("tm", "fr_inv_timeout", 30) modparam("tm", "restart_fr_on_each_reply", 0) modparam("tm", "onreply_avp_mode", 1) #### Record Route Module loadmodule "rr.so" /* do not append from tag to the RR (no need for this script) */ modparam("rr", "append_fromtag", 0) #### MAX ForWarD module loadmodule "maxfwd.so" #### SIP MSG OPerationS module loadmodule "sipmsgops.so" #### HTTPD/Event modules loadmodule "httpd.so" modparam("httpd", "ip", "10.9.8.111") modparam("httpd", "port", 8000) loadmodule "mi_http.so" loadmodule "event_jsonrpc.so" loadmodule "event_route.so" loadmodule "event_rabbitmq.so" modparam("event_rabbitmq", "heartbeat", 10) # seconds #### PostgreSQL module loadmodule "db_postgres.so" #### FreeSWITCH module #loadmodule "freeswitch.so" #### AVPOPS module loadmodule "avpops.so" modparam("avpops", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") #### USeR LOCation module loadmodule "usrloc.so" modparam("usrloc", "working_mode_preset", "single-instance-sql-write-through") modparam("usrloc", "nat_bflag", "NAT") modparam("usrloc", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") modparam("usrloc", "attr_column", "device_id") #### REGISTRAR module loadmodule "registrar.so" modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT") modparam("registrar", "attr_avp", "$avp(attr)") modparam("registrar", "received_avp", "$avp(received)") /* ?? */ /* uncomment the next line not to allow more than 10 contacts per AOR */ #modparam("registrar", "max_contacts", 10) #### Auth module #### AUTHentication modules loadmodule "auth.so" loadmodule "auth_db.so" modparam("auth_db", "uri_uriuser_column", "user_id") modparam("auth_db", "domain_column", "realm") modparam("auth_db", "uri_domain_column", "realm") modparam("auth_db", "uri_user_column", "auth_id") modparam("auth_db", "user_column", "auth_id") modparam("auth_db", "password_column", "digest_ha1") modparam("auth_db", "calculate_ha1", 0) modparam("auth_db", "load_credentials", "") modparam("auth_db", "skip_version_check", 1) modparam("auth_db", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") #### UAC modules loadmodule "uac_auth.so" loadmodule "uac_registrant.so" modparam("uac_registrant", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") modparam("uac_registrant", "table_name", "wbt_registrant") modparam("uac_registrant", "hash_size", 4) modparam("uac_registrant", "timer_interval", 32) #### DOMAIN module loadmodule "domain.so" modparam("domain", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") modparam("domain", "db_mode", 0) /* 1 for cache */ modparam("domain", "domain_table", "directory.wbt_domain") modparam("domain", "domain_col", "name") modparam("domain", "attrs_col", "attrs") modparam("auth_db|usrloc|uri", "use_domain", 1) #### Permissions module loadmodule "permissions.so" modparam("permissions", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") modparam("permissions", "address_table", "directory.sip_address_allow") #### DIALOG module loadmodule "dialog.so" modparam("dialog", "dlg_match_mode", 1) modparam("dialog", "default_timeout", 21600) # 6 hours timeout modparam("dialog", "db_mode", 1) modparam("dialog", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") #### PRESENCE modules loadmodule "xcap.so" # deps::database|libxml-dev modparam("xcap", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") modparam("xcap", "xcap_table", "xcap") # default(xcap) modparam("xcap", "integrated_xcap_server", 0) # If integrated ones, like OpenXCAP from AG Projects, the parameter should be set to a positive value. loadmodule "xcap_client.so" # deps::xcap|libxml-dev|libcurl-dev # modparam("xcap_client", "periodical_query", 0) # because NOT using integrated_xcap_server, - internal one # default(1) # modparam("xcap_client", "query_period", 50) loadmodule "presence.so" # deps::database|signaling[|clusterer]|libxml-dev modparam("presence", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") modparam("presence", "fallback2db", 0) # enable when clustering # modparam("presence", "cluster_id", 2) # modparam("presence", "cluster_federation_mode", 1) # modparam("presence", "cluster_pres_events" ,"presence, dialog;sla, message-summary") # modparam("presence", "expires_offset", 10) # The extra time to store a subscription/publication. modparam("presence", "max_expires_subscribe", 3600) # The the maximum admissible expires value for SUBSCRIBE messages. modparam("presence", "max_expires_publish", 3600) # The the maximum admissible expires value for PUBLISH messages. modparam("presence", "server_address", "sip:sa@10.9.8.111:5060") # modparam("presence", "enable_sphere_check", 0) modparam("presence", "waiting_subs_daysno", 3) # The number of days to keep the record of a subscription in server database if the subscription is in pending or waiting state modparam("presence", "mix_dialog_presence", 1) # !!!!! Generating presence information from dialogs state. You will need to load the dialoginfo modules, presence_dialoginfo, pua_dialoginfo, dialog and pua. # modparam("presence", "bla_presentity_spec", "$var(bla_pres)") # modparam("presence", "bla_fix_remote_target", 1) modparam("presence", "notify_offline_body", 0) # 1 modparam("presence", "end_sub_on_timeout", 0) modparam("presence", "clean_period", 100) modparam("presence", "db_update_period", 100) modparam("presence", "presentity_table", "presentity") modparam("presence", "active_watchers_table", "active_watchers") modparam("presence", "watchers_table", "watchers") modparam("presence", "subs_htable_size", 11) modparam("presence", "pres_htable_size", 11) loadmodule "presence_xml.so" # deps::database|presence|signaling|xcap|xcap_client(if 'integrated_xcap_server' parameter is not set) modparam("presence_xml", "force_active", 1) # default(0) # should be set to 1 if not using an xcap server modparam("presence_xml", "pidf_manipulation", 1) # default(0) # The address of the xcap servers used for storage. This parameter is compulsory # if the integrated_xcap_server parameter is not set. It can be set more that once, # to construct an address list of trusted XCAP servers. # modparam("presence_xml", "xcap_server", "xcap_server.example.org") # modparam("presence_xml", "xcap_server", "xcap_server.ag.org") modparam("presence_xml", "xcap_server", "10.9.8.111") # modparam("presence_xml", "pres_rules_auid", "org.openmobilealliance.pres-rules") # modparam("presence_xml", "pres_rules_filename", "pres-rules") modparam("presence_xml", "generate_offline_body", 1) # The module requires 1 table in OpenSIPS database: xcap. loadmodule "presence_dialoginfo.so" # deps::presence # signaling,libxml-dev presence_dialoginfo, pua_dialoginfo, dialog and pua modparam("presence_dialoginfo", "force_single_dialog", 0) # default(0) loadmodule "presence_callinfo.so" # deps::presence|dialog modparam("presence_callinfo", "call_info_timeout_notification", 0) # Enables or disables call_info event timeout notifications. # default(1) enabled modparam("presence_callinfo", "line_seize_timeout_notification", 0) # Enables or disables line_seize event timeout notifications. # default(0) disabled modparam("presence_callinfo", "disable_dialog_support_for_sca", 0) # Disables the internal publishing of the "call-info" events (generated by the dialog module). # default(0) enabled modparam("presence_callinfo", "line_hash_size", 64) # The value must be a power of 2. You may consider increasing the value if using a large set of lines (>1000). # default(64) loadmodule "pua.so" # deps::database|tm|libxml modparam("pua", "hash_size", 11) modparam("pua", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") modparam("pua", "db_table", "pua") modparam("pua", "min_expires", 0) modparam("pua", "default_expires", 3600) modparam("pua", "update_period", 100) loadmodule "pua_usrloc.so" # deps::usrloc|pua|libxml modparam("pua_usrloc", "entity_prefix", "pres") # [pres]ence modparam("pua_usrloc", "default_domain", "10.9.8.111") modparam("pua_usrloc", "presence_server", "sip:sa@10.9.8.111:5060") # If set, it will be used as outbound proxy when sending PUBLISH requests. loadmodule "pua_bla.so" modparam("pua_bla", "default_domain", "sip.webitel.com") modparam("pua_bla", "header_name", "Sender") # The name of the header to be added to PUBLISH requests. modparam("pua_bla", "outbound_proxy", "sip:sa@10.9.8.111:5060") # The outbound_proxy uri to be used when sending SUBSCRIBE requests. modparam("pua_bla", "server_address", "sip:sa@10.9.8.111:5060") # The IP address of the server. modparam("pua_bla", "presence_server", "sip:sa@10.9.8.111:5060") # The address of the presence server - will be used as an outbound proxy when sending PUBLISH requests. It is optional. loadmodule "pua_dialoginfo.so" # deps::dialog|pua|libxml modparam("pua_dialoginfo", "include_callid", 1) # default(1) modparam("pua_dialoginfo", "include_tags", 1) # default(1) modparam("pua_dialoginfo", "include_localremote", 1) # default(1) modparam("pua_dialoginfo", "caller_confirmed", 1) # default(0) # To avoid blinking LEDs for the caller, you can enable this parameter. modparam("pua_dialoginfo", "publish_on_trying", 1) # default(0) # modparam("pua_dialoginfo", "nopublish_flag", "no_publish") modparam("pua_dialoginfo", "presence_server", "sip:sa@10.9.8.111:5060") # modparam("pua_dialoginfo", "caller_spec_param", "$avp(10)") # modparam("pua_dialoginfo", "callee_spec_param", "$avp(11)") modparam("pua_dialoginfo", "osips_ps", 1) # disable internal - use external #### SIP Session Timer module loadmodule "sst.so" modparam("sst", "sst_flag", "SST_FLAG") modparam("sst", "min_se", 120) #### DISPATCHER module loadmodule "dispatcher.so" modparam("dispatcher", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") modparam("dispatcher", "ds_ping_method", "OPTIONS") modparam("dispatcher", "ds_probing_mode", 0) modparam("dispatcher", "ds_ping_interval", 30) #### NAT modules loadmodule "nathelper.so" modparam("nathelper", "natping_interval", 10) modparam("nathelper", "ping_nated_only", 1) modparam("nathelper", "sipping_bflag", "SIP_PING_FLAG") modparam("nathelper", "sipping_from", "sip:pinger@10.9.8.111") modparam("nathelper", "remove_on_timeout_bflag", "KILL_ZOMBIES") modparam("nathelper", "max_pings_lost", 10) modparam("registrar|nathelper", "received_avp", "$avp(received)") #### RTPengine protocol loadmodule "rtpengine.so" modparam("rtpengine", "db_url", "postgres://opensips:webitel@postgres:5432/webitel") loadmodule "topology_hiding.so" #### Protocols loadmodule "proto_udp.so" loadmodule "proto_tcp.so" #loadmodule "proto_tls.so" loadmodule "proto_ws.so" #loadmodule "proto_wss.so" #modparam("proto_wss", "wss_max_msg_chunks", 16) #loadmodule "tls_mgm.so" #modparam("tls_mgm", "server_domain", "dev") #modparam("tls_mgm","verify_cert", "[dev]0") #modparam("tls_mgm","require_cert", "[dev]0") #modparam("tls_mgm", "match_ip_address", "[dev]*") #modparam("tls_mgm", "match_sip_domain", "[dev]*") #modparam("tls_mgm","certificate", "[dev]/config/keys/letsencrypt/fullchain.pem") #modparam("tls_mgm","private_key", "[dev]/config/keys/letsencrypt/privkey.pem") ####### Routing Logic ######## startup_route { # https://opensips.org/docs/modules/3.0.x/usrloc.html#exported_events if (!subscribe_event("E_UL_AOR_REGISTER", "rabbitmq:webitel:webitel@rabbit/opensips?sip.register")) xlog("L_ERR","cannot the RabbitMQ server subscribe to the E_UL_AOR_INSERT event\n"); if (!subscribe_event("E_UL_AOR_UNREGISTER", "rabbitmq:webitel:webitel@rabbit/opensips?sip.register")) xlog("L_ERR","cannot the RabbitMQ server subscribe to the E_UL_AOR_DELETE event\n"); # if (!subscribe_event("E_CONTACT_INSERT", "rabbitmq:webitel:webitel@rabbit/opensips?contacts")) # xlog("L_ERR","cannot the RabbitMQ server to the E_CONTACT_INSERT event\n"); # if (!subscribe_event("E_CONTACT_DELETE", "rabbitmq:webitel:webitel@rabbit/opensips?contacts")) # xlog("L_ERR","cannot the RabbitMQ server to the E_CONTACT_DELETE event\n"); # if (!subscribe_event("E_WEBITEL_SIP", "rabbitmq:webitel:webitel@rabbit/opensips?sip")) # xlog("L_ERR","cannot the RabbitMQ server to the E_WEBITEL_SIP event\n"); # if (!subscribe_event("E_WEBITEL_DIALOG_STATE", "rabbitmq:webitel:webitel@rabbit/opensips?dialogs")) # xlog("L_ERR","cannot the RabbitMQ server to the E_DLG_STATE_CHANGED event\n"); # if (!subscribe_event("E_WEBITEL_PRESENCE_PUBLISH", "rabbitmq:webitel:webitel@rabbit/opensips?presence")) # xlog("L_ERR","cannot the RabbitMQ server to the E_WEBITEL_PRESENCE_PUBLISH event\n"); } # main request routing logic route{ # initial NAT handling; detect if the request comes from behind a NAT # and apply contact fixing force_rport(); if (nat_uac_test(23)) { if (is_method("REGISTER")) { fix_nated_register(); setbflag(NAT); } else { fix_nated_contact(); setflag(NAT); } } if (!mf_process_maxfwd_header(10)) { send_reply(483,"Too Many Hops"); exit; } if (has_totag()) { if (is_method("BYE")) { # do accounting even if the transaction fails # do_accounting("db","failed"); rtpengine_delete(); } if (topology_hiding_match()) { xlog("Succesfully matched this request to a topology hiding dialog. \n"); xlog("Calller side callid is $ci \n"); xlog("Callee side callid is $TH_callee_callid \n"); if (check_route_param("nat=yes")) setflag(NAT); route(relay); exit; } else { # handle hop-by-hop ACK (no routing required) if ( is_method("ACK") ) { if ( t_check_trans() ) t_relay(); exit; } # sequential request within a dialog should # take the path determined by record-routing if ( !loose_route() ) { if (is_method("SUBSCRIBE") && is_myself("$rd")) { # in-dialog subscribe requests route(handle_presence); exit; } # we do record-routing for all our traffic, so we should not # receive any sequential requests without Route hdr. send_reply(404,"Not here"); exit; } } # validate the sequential request against dialog if ( $DLG_status!=NULL && !validate_dialog() ) { xlog("In-Dialog $rm from $si (callid=$ci) is not valid according to dialog\n"); ## exit; } } # CANCEL processing if (is_method("CANCEL")) { rtpengine_delete(); if (t_check_trans()) t_relay(); exit; } # OPTIONS processing if( is_method("OPTIONS")) route(handle_options); # absorb retransmissions, but do not create transaction t_check_trans(); if( is_method("PUBLISH|SUBSCRIBE")) { route(handle_presence); exit; } # handle BLA Notifications if (is_method("NOTIFY") && $hdr(event)=="dialog;sla") { bla_handle_notify(); send_reply(200, "OK"); } if (!(is_method("REGISTER")) ) { if ( ds_is_in_list("$si", $sp, 1) ) { # From mediaserver setflag(fs); } else if (is_from_local()) { # authenticate if from local subscriber # authenticate all initial non-REGISTER request that pretend to be # generated by local subscriber (domain from FROM URI is local) if (!proxy_authorize("", "wbt_subscriber")) { proxy_challenge("", 0); exit; } if (!db_is_from_authorized("wbt_subscriber")) { send_reply(403,"Forbidden auth ID"); exit; } consume_credentials(); # caller authenticated xlog("L_INFO", "Caller is authenticated\n"); avp_db_query("SELECT uid, dc FROM wbt_subscriber WHERE user_id='$fU'", "$avp(uid);$avp(dc)"); if ($avp(uid) >0) { setflag(dev); append_hf("X-Webitel-Uuid: $ci\r\n"); append_hf("X-Webitel-User-Id: $avp(uid)\r\n"); append_hf("X-Webitel-Domain-Id: $avp(dc)\r\n"); append_hf("X-Webitel-Direction: outbound\r\n"); append_hf("X-Webitel-Origin: user\r\n"); } else { send_reply(403,"Forbidden hotdesk"); exit; } } else { avp_db_query("select sa.id, sa.name, sa.dc from directory.sip_registrant as sa where sa.binding_uri = '$ru' and sa.state = 3 order by sa.id limit 1;", "$avp(id);$avp(name);$avp(dc)"); if ( $avp(id) > 0 ) { # From PSTN xlog("From registrant '$ru'\n"); setflag(pstn); append_hf("X-Webitel-Domain-Id: $avp(dc)\r\n"); append_hf("X-Webitel-Gateway-Id: $avp(id)\r\n"); append_hf("X-Webitel-Gateway: $avp(name)\r\n"); append_hf("X-Webitel-Direction: inbound\r\n"); append_hf("X-Webitel-Origin: gateway\r\n"); } else if (check_address(1,"$si",$sp,"$pr")) { avp_db_query("select sa.id, sa.name, sa.dc from directory.sip_address_allow as sa where sa.host = ('$td'||':'||'$Rp') and ('$si')::inet <<= sa.cidr and coalesce(nullif(port, 0), $sp) = $sp and coalesce(nullif(proto, 'any'), '$pr') = '$pr' order by sa.id limit 1;", "$avp(id);$avp(name);$avp(dc)"); if ( $avp(id) > 0 ) { # From PSTN xlog("From SIP trunk to '$td'\n"); setflag(pstn); append_hf("X-Webitel-Domain-Id: $avp(dc)\r\n"); append_hf("X-Webitel-Gateway-Id: $avp(id)\r\n"); append_hf("X-Webitel-Gateway: $avp(name)\r\n"); append_hf("X-Webitel-Direction: inbound\r\n"); append_hf("X-Webitel-Origin: gateway\r\n"); } else { send_reply(403,"Forbidden auth host"); exit; } } else { if (is_method("PUBLISH|SUBSCRIBE")) { route(handle_presence); } else { send_reply(403,"Relay Forbidden"); } exit; } } } # script_trace( 1, "$rm from $si, ruri=$ru", "WBT"); # script_trace( 1, "$rm $ru from $si, dest=$ds", "WBT"); # preloaded route checking if (loose_route()) { xlog("L_ERR", "Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]"); if (!is_method("ACK")) send_reply(403,"Preload Route denied"); exit; } # record routing if (!is_method("REGISTER|MESSAGE")) record_route(); # raise MESSAGE event #if (is_method("MESSAGE")) { # $avp(attrs) = "user"; # $avp(vals) = $rU; # $avp(attrs) = "msg"; # $avp(vals) = $rb; # if (!raise_event("E_SIP_MESSAGE", $avp(attrs), $avp(vals))) # xlog("L_ERR", "cannot raise E_SIP_MESSAGE event\n"); #} if (is_method("INVITE")) { setflag(SST_FLAG); # Set the sst flag # create dialog with timeout if ( !create_dialog("B") ) { send_reply(500,"Internal Server Error"); exit; } dialoginfo_set("AB"); } # if( is_method("PUBLISH|SUBSCRIBE")) # route(handle_presence); if ($pr == "ws" || $pr == "wss") setflag(SRC_WS); # consider the client is behind NAT - always fix the contact if ($pr == "ws" || $pr == "wss") fix_nated_contact(); if (is_method("REGISTER")) { # authenticate the REGISTER requests if (!www_authorize("", "wbt_subscriber")) { www_challenge("", 0); exit; } if (!db_is_to_authorized("wbt_subscriber")) { xlog("Webitel user $tu is not authorized to authenticate with $au credential\n"); send_reply(403,"Forbidden auth ID"); exit; } if ($pr == "ws" || $pr == "wss") { setbflag(DST_WS); fix_nated_register(); } if ($pr == "tcp" || $pr == "tls") setflag(TCP_PERSISTENT); if (isflagset(NAT)) setbflag(SIP_PING_FLAG); setbflag(KILL_ZOMBIES); /* for cluster: disable on the secondary: nh_enable_ping */ # $avp(attr) = $au; xlog("[REGISTER] domain($td); userid($tU); device($au)\n"); avp_db_query("SELECT dc, oid::text, uid FROM wbt_subscriber WHERE realm = '$td' AND user_id = '$tU' AND auth_id = '$au'", "$avp(pdc);$avp(cid);$avp(uid)"); $avp(attr) = $avp(cid); xlog("[REGISTER] domain($avp(pdc)::$td); user($avp(uid)::$tU); device($avp(cid)::$au); attr($avp(attr))\n"); bla_set_flag(); # https://opensips.org/docs/modules/3.0.x/pua_bla.html#func_bla_set_flag pua_set_publish(); # https://opensips.org/docs/modules/3.0.x/pua_usrloc.html#func_pua_set_publish #if (is_avp_set("$avp(cid)")) { # $avp(device_id) = $avp(i:cid); #} if (!save("location")) sl_reply_error(); exit; } if ($rU==NULL) { # request with no Username in RURI send_reply(484,"Address Incomplete"); exit; } if (isflagset(pstn)) { if ( !ds_select_dst(1,4) ) { send_reply(500,"No Destination available"); exit; } t_on_failure("gw_failover"); } else if ($(hdr(X-Webitel-Direction)[0]) == "outbound") { xlog("Webitel outbound\n"); } else if ($(hdr(X-Webitel-Direction)[0]) == "internal") { # do lookup with method filtering xlog("Webitel internal\n"); if (is_present_hf("X-Webitel-Uuid")) remove_hf("X-Webitel-Uuid"); append_hf("X-Webitel-Uuid: $ci\r\n"); if (!lookup("location","m")) { if (!db_does_uri_exist("$ru","wbt_subscriber")) send_reply(480,"Subscriber absent"); exit; } # redirect to a different VM system ## $du = "sip:127.0.0.2:5060"; # CUSTOMIZE ME } else { if (!ds_select_dst(1,4) ) { send_reply(500,"No Destination available"); exit; } t_on_failure("gw_failover"); } if (isbflagset(NAT)) setflag(NAT); route(relay); } route[relay] { # for INVITEs enable some additional helper routes if (is_method("INVITE")) { topology_hiding("UC"); if (!has_totag()) { sca_set_called_line(""); sca_set_calling_line(""); } t_on_branch("per_branch_ops"); t_on_reply("handle_nat"); t_on_failure("missed_call"); } if (isflagset(NAT)) { add_rr_param(";nat=yes"); } if (!t_relay()) { send_reply(500,"Internal Error"); } exit; } route[rtpengine_offer] { if (isflagset(SRC_WS) && isbflagset(DST_WS)) # - Web to web $var(reflags) = "trust-addres sreplace-origin replace-session-connection SDES-off ICE=force"; else if (isflagset(SRC_WS)) # - Web to SIP $var(reflags) = "trust-addres replace-origin replace-session-connection rtcp-mux-demux ICE=remove RTP/AVP"; else if (isbflagset(DST_WS)) # - SIP to web $var(reflags) = "trust-addres replace-origin replace-session-connection rtcp-mux-offer ICE=force transcode-opus transcode-G722 transcode-PCMU SDES-off UDP/TLS/RTP/SAVP"; else # - SIP to SIP $var(reflags) = "trust-addres replace-origin replace-session-connection rtcp-mux-demux ICE=remove RTP/AVP"; rtpengine_use_set(1); rtpengine_offer("$var(reflags)"); # rtpengine_start_recording(); } route[rtpengine_answer] { if (isflagset(SRC_WS) && isbflagset(DST_WS)) $var(reflags) = "trust-addres replace-origin replace-session-connection SDES-off ICE=force"; else if (isflagset(SRC_WS)) $var(reflags) = "trust-addres replace-origin replace-session-connection rtcp-mux-require ICE=force RTP/SAVPF"; else $var(reflags) = "trust-addres replace-origin replace-session-connection rtcp-mux-demux ICE=remove RTP/AVP"; rtpengine_use_set(1); rtpengine_answer("$var(reflags)"); } # Presence route route[handle_presence] { if (!t_newtran()) { sl_reply_error(); exit; } if (is_method("PUBLISH")) { if ($hdr(Sender)!= NULL) { handle_publish($hdr(Sender)); } else { handle_publish(); } } else if (is_method("SUBSCRIBE")) { handle_subscribe(); } exit; } branch_route[per_branch_ops] { xlog("[BRANCH] request $ru contact(s) $ct\n"); # align the published info with the RURI of the branch dialoginfo_set_branch_callee("sip:$tU@$td"); # https://opensips.org/docs/modules/3.0.x/pua_dialoginfo.html#func_dialoginfo_set_branch_callee # route(handle_sip); if (has_body("application/sdp")) route(rtpengine_offer); } onreply_route[handle_nat] { xlog("incoming reply\n"); if ($pr == "ws" || $pr == "wss") fix_nated_contact(); if (nat_uac_test(1)) fix_nated_contact(); if (has_body("application/sdp")) route(rtpengine_answer); } route[handle_options] { send_reply(200, "I See You"); exit; } # route[handle_sip] # { # $avp(attrs) = "method"; # $avp(vals) = $rm; # $avp(attrs) = "to"; # $avp(vals) = $tu; # $avp(attrs) = "from"; # $avp(vals) = $fu; # $avp(attrs) = "contact"; # $avp(vals) = $ct; # if (!raise_event("E_WEBITEL_SIP", $avp(attrs), $avp(vals))) # xlog("L_ERR", "cannot raise E_WEBITEL_SIP event\n"); # } failure_route[gw_failover] { if (t_was_cancelled()) { rtpengine_delete(); exit; } # failure detection with redirect to next available trunk if (t_check_status("(408)|([56][0-9][0-9])")) { xlog("Webitel failed trunk $rd/$du detected \n"); t_on_failure("gw_failover"); t_relay(); exit; } rtpengine_delete(); send_reply(500,"All GW are down"); } failure_route[missed_call] { if (t_was_cancelled()) { rtpengine_delete(); exit; } # uncomment the following lines if you want to block client # redirect based on 3xx replies. ##if (t_check_status("3[0-9][0-9]")) { ##t_reply("404","Not found"); ## exit; ##} } # [USRLOC] This event is raised when a new AOR is inserted in the USRLOC memory cache. event_route[E_UL_AOR_INSERT] { $avp(attrs) = "aor"; $avp(vals) = $param(aor); # The AOR of the inserted record. # $avp(attrs) = "tsec"; # $avp(vals) = $Ts; ## get_timestamp($avp(sec), $avp(usec)); $avp(attrs) = "tsec"; $avp(attrs) = "usec"; # guess this will push two sequential $avp(vals) values get_timestamp($avp(vals), $avp(vals)); if (!raise_event("E_UL_AOR_REGISTER", $avp(attrs), $avp(vals))) xlog("L_ERR", "failed to raise E_UL_AOR_INSERT event\n"); exit; } # [USRLOC] this event is raised when a new AOR is deleted from the USRLOC memory cache. event_route[E_UL_AOR_DELETE] { $avp(attrs) = "aor"; $avp(vals) = $param(aor); # The AOR of the inserted record. # $avp(attrs) = "tsec"; # $avp(vals) = $Ts; ## get_timestamp($avp(sec), $avp(usec)); $avp(attrs) = "tsec"; $avp(attrs) = "usec"; # guess this will push two sequential $avp(vals) values get_timestamp($avp(vals), $avp(vals)); if (!raise_event("E_UL_AOR_UNREGISTER", $avp(attrs), $avp(vals))) xlog("L_ERR", "failed to raise E_UL_AOR_DELETE event\n"); exit; } # event_route[E_UL_CONTACT_INSERT] { # $avp(attrs) = "callid"; # $avp(vals) = $param(callid); # $avp(attrs) = "aor"; # $avp(vals) = $param(aor); # $avp(attrs) = "uri"; # $avp(vals) = $param(uri); # $avp(attrs) = "cseq"; # $avp(vals) = $param(cseq); # $avp(attrs) = "expires"; # $avp(vals) = $param(expires); # $avp(attrs) = "device_id"; # $avp(vals) = $param(attr); # $avp(attrs) = "timestamp"; # $avp(vals) = $Ts; # if (!raise_event("E_CONTACT_INSERT", $avp(attrs), $avp(vals))) # xlog("L_ERR", "cannot raise E_CONTACT_INSERT event\n"); # exit; # } # event_route[E_UL_CONTACT_DELETE] { # $avp(attrs) = "callid"; # $avp(vals) = $param(callid); # $avp(attrs) = "aor"; # $avp(vals) = $param(aor); # $avp(attrs) = "uri"; # $avp(vals) = $param(uri); # $avp(attrs) = "cseq"; # $avp(vals) = $param(cseq); # $avp(attrs) = "expires"; # $avp(vals) = $param(expires); # $avp(attrs) = "device_id"; # $avp(vals) = $param(attr); # $avp(attrs) = "timestamp"; # $avp(vals) = $Ts; # if (!raise_event("E_CONTACT_DELETE", $avp(attrs), $avp(vals))) # xlog("L_ERR", "cannot raise E_CONTACT_DELETE event\n"); # exit; # } # event_route[E_DLG_STATE_CHANGED] { # $avp(attrs) = "hash_entry"; # $avp(vals) = $param(hash_entry); # $avp(attrs) = "hash_id"; # $avp(vals) = $param(hash_id); # $avp(attrs) = "callid"; # $avp(vals) = $param(callid); # $avp(attrs) = "from_tag"; # $avp(vals) = $param(from_tag); # $avp(attrs) = "to_tag"; # $avp(vals) = $param(to_tag); # $avp(attrs) = "old_state"; # $avp(vals) = $param(old_state); # $avp(attrs) = "new_state"; # $avp(vals) = $param(new_state); # if (!raise_event("E_WEBITEL_DIALOG_STATE", $avp(attrs), $avp(vals))) # xlog("L_ERR", "cannot raise E_WEBITEL_DIALOG_STATE event\n"); # exit; # } # event_route[E_PRESENCE_PUBLISH] { # $avp(attrs) = "user"; # $avp(vals) = $param(user); # $avp(attrs) = "domain"; # $avp(vals) = $param(domain); # $avp(attrs) = "event"; # $avp(vals) = $param(event); # $avp(attrs) = "expires"; # $avp(vals) = $param(expires); # $avp(attrs) = "etag"; # $avp(vals) = $param(etag); # $avp(attrs) = "body"; # $avp(vals) = $param(body); # if (!raise_event("E_WEBITEL_PRESENCE_PUBLISH", $avp(attrs), $avp(vals))) # xlog("L_ERR", "cannot raise E_WEBITEL_PRESENCE_PUBLISH event\n"); # exit; # } local_route { # route(handle_sip); if (is_method("BYE") && $DLG_dir=="UPSTREAM") { rtpengine_delete(); #acc_db_request("200 Dialog Timeout", "acc"); } }