mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Renamed tutorials_test to tutorial_tests
This commit is contained in:
committed by
Dan Christian Bogos
parent
d3d9769034
commit
1ec879deab
15
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/README
Executable file
15
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/README
Executable file
@@ -0,0 +1,15 @@
|
||||
The included Asterisk configuration files are intended to be an example
|
||||
implementation for a fictitious company, Super Awesome Company.
|
||||
|
||||
It can serve as a handy reference for understanding a simple Asterisk
|
||||
configuration in an approximate real-world environment.
|
||||
|
||||
If you intend to use this configuration as a template for your own, then
|
||||
you will need to change many values in the various configuration files to
|
||||
match your own devices, network, SIP ITSP accounts and more.
|
||||
|
||||
For further documentation on this configuration see the Asterisk wiki:
|
||||
https://wiki.asterisk.org/wiki/display/AST/Reference+Use+Cases+for+Asterisk.
|
||||
|
||||
Please report bugs or errors in configuration on the Asterisk issue tracker:
|
||||
https://wiki.asterisk.org/wiki/display/AST/Asterisk+Issue+Guidelines
|
||||
8
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/ari.conf
Executable file
8
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/ari.conf
Executable file
@@ -0,0 +1,8 @@
|
||||
[general]
|
||||
enabled = yes
|
||||
allowed_origins = http://cgrates.org
|
||||
|
||||
[cgrates]
|
||||
type = user
|
||||
read_only = no
|
||||
password = CGRateS.org
|
||||
12
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/asterisk.conf
Executable file
12
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/asterisk.conf
Executable file
@@ -0,0 +1,12 @@
|
||||
[directories]
|
||||
astetcdir => /usr/share/cgrates/tutorial_tests/asterisk_ari/asterisk/etc/asterisk
|
||||
astspooldir => /tmp/cgr_asterisk_ari/asterisk/spool
|
||||
astlogdir => /tmp/cgr_asterisk_ari/asterisk/log
|
||||
astrundir => /tmp/cgr_asterisk_ari/asterisk/run
|
||||
astdbdir => /tmp/cgr_asterisk_ari/asterisk/lib
|
||||
|
||||
[options]
|
||||
runuser = asterisk ; The user to run as. The default is root.
|
||||
rungroup = asterisk ; The group to run as. The default is root
|
||||
|
||||
|
||||
7
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/cdr.conf
Executable file
7
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/cdr.conf
Executable file
@@ -0,0 +1,7 @@
|
||||
[general]
|
||||
enable=yes
|
||||
|
||||
[custom]
|
||||
; We log the unique ID as it can be useful for troubleshooting any issues
|
||||
; that arise.
|
||||
loguniqueid=yes
|
||||
4
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/cdr_custom.conf
Executable file
4
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/cdr_custom.conf
Executable file
@@ -0,0 +1,4 @@
|
||||
[mappings]
|
||||
; Our CDR log will be written to /var/log/asterisk/cdr-custom/Master.csv
|
||||
; with the following schema.
|
||||
Master.csv => ${CSV_QUOTE(${CDR(clid)})},${CSV_QUOTE(${CDR(src)})},${CSV_QUOTE(${CDR(dst)})},${CSV_QUOTE(${CDR(dcontext)})},${CSV_QUOTE(${CDR(channel)})},${CSV_QUOTE(${CDR(dstchannel)})},${CSV_QUOTE(${CDR(lastapp)})},${CSV_QUOTE(${CDR(lastdata)})},${CSV_QUOTE(${CDR(start)})},${CSV_QUOTE(${CDR(answer)})},${CSV_QUOTE(${CDR(end)})},${CSV_QUOTE(${CDR(duration)})},${CSV_QUOTE(${CDR(billsec)})},${CSV_QUOTE(${CDR(disposition)})},${CSV_QUOTE(${CDR(amaflags)})},${CSV_QUOTE(${CDR(accountcode)})},${CSV_QUOTE(${CDR(uniqueid)})},${CSV_QUOTE(${CDR(userfield)})},${CDR(sequence)}
|
||||
1
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/confbridge.conf
Executable file
1
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/confbridge.conf
Executable file
@@ -0,0 +1 @@
|
||||
; All conferences use default settings. This config must be present to load the confbridge application
|
||||
8
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/extensions.conf
Executable file
8
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/extensions.conf
Executable file
@@ -0,0 +1,8 @@
|
||||
[internal]
|
||||
exten => _1XXX,1,NoOp()
|
||||
same => n,Set(CGRMaxSessionTime=0); use it to disconnect automatically the call if CGRateS is not active
|
||||
same => n,DumpChan()
|
||||
same => n,Stasis(cgrates_auth,cgr_reqtype=*prepaid,cgr_supplier=supplier1,cgr_subsystems=*accounts*attributes*resources*stats*suppliers*thresholds)
|
||||
same => n,Dial(PJSIP/${EXTEN},30,L(${CGRMaxSessionTime}))
|
||||
same => n,Hangup()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
[general]
|
||||
enabled = yes
|
||||
bindaddr = 0.0.0.0
|
||||
bindport = 8088
|
||||
19
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/indications.conf
Executable file
19
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/indications.conf
Executable file
@@ -0,0 +1,19 @@
|
||||
[general]
|
||||
country = us ; We are in Waldo, Al, USA so the US is our default.
|
||||
|
||||
[us]
|
||||
description = United States / North America
|
||||
ringcadence = 2000,4000
|
||||
dial = 350+440
|
||||
busy = 480+620/500,0/500
|
||||
ring = 440+480/2000,0/4000
|
||||
congestion = 480+620/250,0/250
|
||||
callwaiting = 440/300,0/10000
|
||||
dialrecall = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
|
||||
record = 1400/500,0/15000
|
||||
info = !950/330,!1400/330,!1800/330,0
|
||||
stutter = !350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440
|
||||
|
||||
; Additional country configurations can be found in the Asterisk source
|
||||
; at /configs/samples/indications.conf.sample
|
||||
|
||||
9
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/logger.conf
Executable file
9
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/logger.conf
Executable file
@@ -0,0 +1,9 @@
|
||||
[general]
|
||||
|
||||
[logfiles]
|
||||
|
||||
console = verbose,notice,warning,error
|
||||
|
||||
;messages = notice,warning,error
|
||||
;full = verbose,notice,warning,error,debug
|
||||
;security = security
|
||||
155
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/manager.conf
Executable file
155
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/manager.conf
Executable file
@@ -0,0 +1,155 @@
|
||||
;
|
||||
; AMI - The Asterisk Manager Interface
|
||||
;
|
||||
; Third party application call management support and PBX event supervision
|
||||
;
|
||||
; Use the "manager show commands" at the CLI to list available manager commands
|
||||
; and their authorization levels.
|
||||
;
|
||||
; "manager show command <command>" will show a help text.
|
||||
;
|
||||
; ---------------------------- SECURITY NOTE -------------------------------
|
||||
; Note that you should not enable the AMI on a public IP address. If needed,
|
||||
; block this TCP port with iptables (or another FW software) and reach it
|
||||
; with IPsec, SSH, or SSL vpn tunnel. You can also make the manager
|
||||
; interface available over http/https if Asterisk's http server is enabled in
|
||||
; http.conf and if both "enabled" and "webenabled" are set to yes in
|
||||
; this file. Both default to no. httptimeout provides the maximum
|
||||
; timeout in seconds before a web based session is discarded. The
|
||||
; default is 60 seconds.
|
||||
;
|
||||
[general]
|
||||
enabled = yes
|
||||
;webenabled = yes
|
||||
|
||||
port = 5038
|
||||
bindaddr = 0.0.0.0
|
||||
|
||||
; Parameters that control AMI over TLS. ("enabled" must be set too).
|
||||
; You can open a connection to this socket with e.g.
|
||||
;
|
||||
; openssl s_client -connect my_host:5039
|
||||
;
|
||||
;tlsenable=no ; set to YES to enable it
|
||||
;tlsbindaddr=0.0.0.0:5039 ; address and port to bind to, default to bindaddr and port 5039
|
||||
;tlscertfile=/tmp/asterisk.pem ; path to the certificate.
|
||||
;tlsprivatekey=/tmp/private.pem ; path to the private key, if no private given,
|
||||
; if no tlsprivatekey is given, default is to search
|
||||
; tlscertfile for private key.
|
||||
;tlscipher=<cipher string> ; string specifying which SSL ciphers to use or not use
|
||||
;
|
||||
;allowmultiplelogin = yes ; IF set to no, rejects manager logins that are already in use.
|
||||
; ; The default is yes.
|
||||
;
|
||||
;displayconnects = yes
|
||||
;
|
||||
; Add a Unix epoch timestamp to events (not action responses)
|
||||
;
|
||||
;timestampevents = yes
|
||||
|
||||
;brokeneventsaction = yes ; Restore previous behavior that caused the events
|
||||
; action to not return a response in certain
|
||||
; circumstances. Defaults to 'no'.
|
||||
|
||||
;
|
||||
; Display certain channel variables every time a channel-oriented
|
||||
; event is emitted:
|
||||
;
|
||||
;channelvars = var1,var2,var3
|
||||
|
||||
; debug = on ; enable some debugging info in AMI messages (default off).
|
||||
; Also accessible through the "manager debug" CLI command.
|
||||
|
||||
; authtimeout specifies the maximum number of seconds a client has to
|
||||
; authenticate. If the client does not authenticate beofre this timeout
|
||||
; expires, the client will be disconnected. (default: 30 seconds)
|
||||
|
||||
;authtimeout = 30
|
||||
|
||||
; authlimit specifies the maximum number of unauthenticated sessions that will
|
||||
; be allowed to connect at any given time.
|
||||
|
||||
;authlimit = 50
|
||||
|
||||
;httptimeout = 60
|
||||
; a) httptimeout sets the Max-Age of the http cookie
|
||||
; b) httptimeout is the amount of time the webserver waits
|
||||
; on a action=waitevent request (actually its httptimeout-10)
|
||||
; c) httptimeout is also the amount of time the webserver keeps
|
||||
; a http session alive after completing a successful action
|
||||
|
||||
|
||||
;[mark]
|
||||
;secret = mysecret
|
||||
;deny=0.0.0.0/0.0.0.0
|
||||
;permit=209.16.236.73/255.255.255.0
|
||||
;acl=named_acl_example ; use a named ACL from acl.conf
|
||||
;
|
||||
;
|
||||
;setvar=PBXACCOUNT=edvina
|
||||
; The setvar option defines channel variables that will be set when this account
|
||||
; originates a call. You can define multiple setvar= commands for one manager
|
||||
; user.
|
||||
;
|
||||
;eventfilter=Event: Newchannel
|
||||
;eventfilter=Channel: (PJ)?SIP/(james|jim|john)-
|
||||
;eventfilter=!Channel: DAHDI/
|
||||
; The eventfilter option is used to whitelist or blacklist events per user.
|
||||
; A filter consists of an (unanchored) regular expression that is run on the
|
||||
; entire event data. If the first character of the filter is an exclamation
|
||||
; mark (!), the filter is appended to the blacklist instead of the whitelist.
|
||||
; After first checking the read access below, the regular expression filters
|
||||
; are processed as follows:
|
||||
; - If no filters are configured all events are reported as normal.
|
||||
; - If there are white filters only: implied black all filter processed first,
|
||||
; then white filters.
|
||||
; - If there are black filters only: implied white all filter processed first,
|
||||
; then black filters.
|
||||
; - If there are both white and black filters: implied black all filter processed
|
||||
; first, then white filters, and lastly black filters.
|
||||
|
||||
;
|
||||
; If the device connected via this user accepts input slowly,
|
||||
; the timeout for writes to it can be increased to keep it
|
||||
; from being disconnected (value is in milliseconds)
|
||||
;
|
||||
; writetimeout = 100
|
||||
;
|
||||
;displayconnects = yes ; Display on CLI user login/logoff
|
||||
;
|
||||
; Authorization for various classes
|
||||
;
|
||||
; Read authorization permits you to receive asynchronous events, in general.
|
||||
; Write authorization permits you to send commands and get back responses. The
|
||||
; following classes exist:
|
||||
;
|
||||
; all - All event classes below (including any we may have missed).
|
||||
; system - General information about the system and ability to run system
|
||||
; management commands, such as Shutdown, Restart, and Reload.
|
||||
; call - Information about channels and ability to set information in a
|
||||
; running channel.
|
||||
; log - Logging information. Read-only. (Defined but not yet used.)
|
||||
; verbose - Verbose information. Read-only. (Defined but not yet used.)
|
||||
; agent - Information about queues and agents and ability to add queue
|
||||
; members to a queue.
|
||||
; user - Permission to send and receive UserEvent.
|
||||
; config - Ability to read and write configuration files.
|
||||
; command - Permission to run CLI commands. Write-only.
|
||||
; dtmf - Receive DTMF events. Read-only.
|
||||
; reporting - Ability to get information about the system.
|
||||
; cdr - Output of cdr_manager, if loaded. Read-only.
|
||||
; dialplan - Receive NewExten and VarSet events. Read-only.
|
||||
; originate - Permission to originate new calls. Write-only.
|
||||
; agi - Output AGI commands executed. Input AGI command to execute.
|
||||
; cc - Call Completion events. Read-only.
|
||||
; aoc - Permission to send Advice Of Charge messages and receive Advice
|
||||
; - Of Charge events.
|
||||
; test - Ability to read TestEvent notifications sent to the Asterisk Test
|
||||
; Suite. Note that this is only enabled when the TEST_FRAMEWORK
|
||||
; compiler flag is defined.
|
||||
; security - Security Events. Read-only.
|
||||
; message - Permissions to send out of call messages. Write-only
|
||||
;
|
||||
;read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan
|
||||
;write = system,call,agent,user,config,command,reporting,originate,message
|
||||
|
||||
136
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/modules.conf
Executable file
136
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/modules.conf
Executable file
@@ -0,0 +1,136 @@
|
||||
[modules]
|
||||
autoload = no
|
||||
|
||||
; This is a minimal module load. We are loading only the modules required for
|
||||
; the Asterisk features used in the Super Awesome Company configuration.
|
||||
|
||||
; Applications
|
||||
|
||||
load = app_bridgewait.so
|
||||
load = app_dial.so
|
||||
load = app_playback.so
|
||||
load = app_stack.so
|
||||
load = app_verbose.so
|
||||
load = app_voicemail.so
|
||||
load = app_directory.so
|
||||
load = app_confbridge.so
|
||||
load = app_queue.so
|
||||
load = app_dumpchan.so
|
||||
|
||||
; Bridging
|
||||
|
||||
load = bridge_builtin_features.so
|
||||
load = bridge_builtin_interval_features.so
|
||||
load = bridge_holding.so
|
||||
load = bridge_native_rtp.so
|
||||
load = bridge_simple.so
|
||||
load = bridge_softmix.so
|
||||
|
||||
; Call Detail Records
|
||||
|
||||
load = cdr_custom.so
|
||||
|
||||
; Channel Drivers
|
||||
|
||||
load = chan_bridge_media.so
|
||||
load = chan_pjsip.so
|
||||
|
||||
; Codecs
|
||||
|
||||
load = codec_gsm.so
|
||||
load = codec_resample.so
|
||||
load = codec_ulaw.so
|
||||
load = codec_g722.so
|
||||
|
||||
; Formats
|
||||
|
||||
load = format_gsm.so
|
||||
load = format_pcm.so
|
||||
load = format_wav_gsm.so
|
||||
load = format_wav.so
|
||||
|
||||
; Functions
|
||||
|
||||
load = func_callerid.so
|
||||
load = func_cdr.so
|
||||
load = func_pjsip_endpoint.so
|
||||
load = func_sorcery.so
|
||||
load = func_devstate.so
|
||||
load = func_strings.so
|
||||
|
||||
; Core/PBX
|
||||
|
||||
load = pbx_config.so
|
||||
|
||||
; Resources
|
||||
|
||||
load = res_musiconhold.so
|
||||
load = res_pjproject.so
|
||||
load = res_pjsip_acl.so
|
||||
load = res_pjsip_authenticator_digest.so
|
||||
load = res_pjsip_caller_id.so
|
||||
load = res_pjsip_dialog_info_body_generator.so
|
||||
load = res_pjsip_diversion.so
|
||||
load = res_pjsip_dtmf_info.so
|
||||
load = res_pjsip_endpoint_identifier_anonymous.so
|
||||
load = res_pjsip_endpoint_identifier_ip.so
|
||||
load = res_pjsip_endpoint_identifier_user.so
|
||||
load = res_pjsip_exten_state.so
|
||||
load = res_pjsip_header_funcs.so
|
||||
load = res_pjsip_logger.so
|
||||
load = res_pjsip_messaging.so
|
||||
load = res_pjsip_multihomed.so
|
||||
load = res_pjsip_mwi_body_generator.so
|
||||
load = res_pjsip_mwi.so
|
||||
load = res_pjsip_nat.so
|
||||
load = res_pjsip_notify.so
|
||||
load = res_pjsip_one_touch_record_info.so
|
||||
load = res_pjsip_outbound_authenticator_digest.so
|
||||
load = res_pjsip_outbound_publish.so
|
||||
load = res_pjsip_outbound_registration.so
|
||||
load = res_pjsip_path.so
|
||||
load = res_pjsip_pidf_body_generator.so
|
||||
load = res_pjsip_pidf_digium_body_supplement.so
|
||||
load = res_pjsip_pidf_eyebeam_body_supplement.so
|
||||
load = res_pjsip_publish_asterisk.so
|
||||
load = res_pjsip_pubsub.so
|
||||
load = res_pjsip_refer.so
|
||||
load = res_pjsip_registrar_expire.so
|
||||
load = res_pjsip_registrar.so
|
||||
load = res_pjsip_rfc3326.so
|
||||
load = res_pjsip_sdp_rtp.so
|
||||
load = res_pjsip_send_to_voicemail.so
|
||||
load = res_pjsip_session.so
|
||||
load = res_pjsip.so
|
||||
load = res_pjsip_t38.so
|
||||
load = res_pjsip_transport_websocket.so
|
||||
load = res_pjsip_xpidf_body_generator.so
|
||||
load = res_rtp_asterisk.so
|
||||
load = res_sorcery_astdb.so
|
||||
load = res_sorcery_config.so
|
||||
load = res_sorcery_memory.so
|
||||
load = res_sorcery_realtime.so
|
||||
load = res_timing_timerfd.so
|
||||
|
||||
;ARI
|
||||
load => app_stasis.so
|
||||
load => res_http_websocket.so
|
||||
load => res_stasis.so
|
||||
load => res_stasis_answer.so
|
||||
load => res_stasis_device_state.so
|
||||
load => res_stasis_playback.so
|
||||
load => res_stasis_recording.so
|
||||
load => res_stasis_snoop.so
|
||||
load => res_ari.so
|
||||
load => res_ari_applications.so
|
||||
load => res_ari_asterisk.so
|
||||
load => res_ari_bridges.so
|
||||
load => res_ari_channels.so
|
||||
load => res_ari_device_states.so
|
||||
load => res_ari_endpoints.so
|
||||
load => res_ari_events.so
|
||||
load => res_ari_mailboxes.so
|
||||
load => res_ari_model.so
|
||||
load => res_ari_playbacks.so
|
||||
load => res_ari_recordings.so
|
||||
load => res_ari_sounds.so
|
||||
5
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/musiconhold.conf
Executable file
5
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/musiconhold.conf
Executable file
@@ -0,0 +1,5 @@
|
||||
[general]
|
||||
|
||||
[default]
|
||||
mode = files
|
||||
directory = moh
|
||||
147
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/pjsip.conf
Executable file
147
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/pjsip.conf
Executable file
@@ -0,0 +1,147 @@
|
||||
[testcalls]
|
||||
type=transport
|
||||
protocol=udp
|
||||
bind=0.0.0.0:5080
|
||||
|
||||
[1001]
|
||||
type = endpoint
|
||||
transport = testcalls
|
||||
context = internal
|
||||
disallow = all
|
||||
allow = ulaw
|
||||
allow = alaw
|
||||
aors = 1001
|
||||
auth = 1001
|
||||
|
||||
[1001]
|
||||
type = aor
|
||||
max_contacts = 5
|
||||
|
||||
[1001]
|
||||
type=auth
|
||||
auth_type=userpass
|
||||
username=1001
|
||||
password=CGRateS.org
|
||||
|
||||
[1002]
|
||||
type = endpoint
|
||||
transport = testcalls
|
||||
context = internal
|
||||
disallow = all
|
||||
allow = ulaw
|
||||
allow = alaw
|
||||
aors = 1002
|
||||
auth = 1002
|
||||
|
||||
[1002]
|
||||
type = aor
|
||||
max_contacts = 5
|
||||
qualify_frequency = 0
|
||||
|
||||
[1002]
|
||||
type=auth
|
||||
auth_type=userpass
|
||||
username=1002
|
||||
password=CGRateS.org
|
||||
|
||||
[1003]
|
||||
type = endpoint
|
||||
transport = testcalls
|
||||
context = internal
|
||||
aors = 1003
|
||||
auth = 1003
|
||||
disallow = all
|
||||
allow = ulaw
|
||||
allow = alaw
|
||||
|
||||
[1003]
|
||||
type = aor
|
||||
max_contacts = 5
|
||||
|
||||
[1003]
|
||||
type=auth
|
||||
auth_type=userpass
|
||||
username=1003
|
||||
password=CGRateS.org
|
||||
|
||||
[1004]
|
||||
type = endpoint
|
||||
transport = testcalls
|
||||
context = internal
|
||||
aors = 1004
|
||||
auth = 1004
|
||||
disallow = all
|
||||
allow = ulaw
|
||||
allow = alaw
|
||||
|
||||
[1004]
|
||||
type = aor
|
||||
max_contacts = 5
|
||||
|
||||
[1004]
|
||||
type=auth
|
||||
auth_type=userpass
|
||||
username=1004
|
||||
password=CGRateS.org
|
||||
|
||||
[1005]
|
||||
type = endpoint
|
||||
transport = testcalls
|
||||
context = internal
|
||||
aors = 1005
|
||||
auth = 1005
|
||||
disallow = all
|
||||
allow = ulaw
|
||||
allow = alaw
|
||||
|
||||
[1005]
|
||||
type = aor
|
||||
max_contacts = 5
|
||||
|
||||
[1005]
|
||||
type=auth
|
||||
auth_type=userpass
|
||||
username=1005
|
||||
password=CGRateS.org
|
||||
|
||||
[1006]
|
||||
type = endpoint
|
||||
transport = testcalls
|
||||
context = internal
|
||||
aors = 1006
|
||||
auth = 1006
|
||||
disallow = all
|
||||
allow = ulaw
|
||||
allow = alaw
|
||||
|
||||
[1006]
|
||||
type = aor
|
||||
max_contacts = 5
|
||||
|
||||
[1006]
|
||||
type=auth
|
||||
auth_type=userpass
|
||||
username=1006
|
||||
password=CGRateS.org
|
||||
|
||||
|
||||
[1007]
|
||||
type = endpoint
|
||||
transport = testcalls
|
||||
context = internal
|
||||
aors = 1007
|
||||
auth = 1007
|
||||
disallow = all
|
||||
allow = ulaw
|
||||
allow = alaw
|
||||
|
||||
[1007]
|
||||
type = aor
|
||||
max_contacts = 5
|
||||
|
||||
[1007]
|
||||
type=auth
|
||||
auth_type=userpass
|
||||
username=1007
|
||||
password=CGRateS.org
|
||||
|
||||
19
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/queues.conf
Executable file
19
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/queues.conf
Executable file
@@ -0,0 +1,19 @@
|
||||
[general]
|
||||
monitor-type = MixMonitor
|
||||
|
||||
;========================Sales Queue ==
|
||||
; Calls all sales persons in a ring-all fashion
|
||||
[sales]
|
||||
strategy=ringall
|
||||
member => PJSIP/1109 ; Terry Jules - Director of Sales
|
||||
member => PJSIP/1105 ; Garnet Claude - Sales Associate
|
||||
member => PJSIP/1112 ; Franny Ocean - Sales Associate
|
||||
|
||||
;===================== Customer Advocate Queue ==
|
||||
; Calls all customer advocates in a ring-all fashion
|
||||
[customer_advocate]
|
||||
strategy=ringall
|
||||
member => PJSIP/1101 ; Maria Berny - Director of Customer Experience
|
||||
member => PJSIP/1115 ; Dusty Williams - Customer Advocate
|
||||
member => PJSIP/1102 ; Tommy Briar - Customer Advocate
|
||||
|
||||
23
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/voicemail.conf
Executable file
23
data/tutorial_tests/asterisk_ari/asterisk/etc/asterisk/voicemail.conf
Executable file
@@ -0,0 +1,23 @@
|
||||
[general]
|
||||
format = wav49|gsm|wav
|
||||
|
||||
[default]
|
||||
|
||||
|
||||
[example]
|
||||
; Voicemail context for all internal users in the example.com domain.
|
||||
1101 = 0717,Maria Berny
|
||||
1102 = 7085,Tommie Briar
|
||||
1103 = 1809,Penelope Bronte
|
||||
1104 = 0039,Richard Casey
|
||||
1105 = 6618,Garnet Claude
|
||||
1106 = 9805,Aaron Courtney
|
||||
1107 = 7484,Lindsey Freddie
|
||||
1108 = 7788,Colby Hildred
|
||||
1109 = 5750,Terry Jules
|
||||
1110 = 3702,Hollis Justy
|
||||
1111 = 1878,Temple Morgan
|
||||
1112 = 5497,Franny Ocean
|
||||
1113 = 1637,Laverne Roberts
|
||||
1114 = 3717,Sal Smith
|
||||
1115 = 3088,Dusty Williams
|
||||
175
data/tutorial_tests/asterisk_ari/asterisk/etc/init.d/asterisk
Executable file
175
data/tutorial_tests/asterisk_ari/asterisk/etc/init.d/asterisk
Executable file
@@ -0,0 +1,175 @@
|
||||
#! /bin/sh
|
||||
# $Id$
|
||||
#
|
||||
# Mon Jun 04 2007 Iñaki Baz Castillo <ibc@in.ilimit.es>
|
||||
# - Eliminated SAFE_ASTERISK since it doesn't work as LSB script (it could require a independent "safe_asterisk" init script).
|
||||
# - Load and use the standar "/lib/lsb/init-functions".
|
||||
# - Added "--oknodo" to "start-stop-daemon" for compatibility with LSB:
|
||||
# http://www.linux-foundation.org/spec/refspecs/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
|
||||
#
|
||||
# Thu Nov 17 2005 Gregory Boehnlein <damin@nacs.net>
|
||||
# - Reversed behavior of LD_ASSUME_KERNEL=2.4.1
|
||||
# - Added detailed failure messages
|
||||
#
|
||||
# Sun Jul 18 2004 Gregory Boehnlein <damin@nacs.net>
|
||||
# - Added test for safe_asterisk
|
||||
# - Changed "stop gracefully" to "stop now"
|
||||
# - Added support for -U and -G command line options
|
||||
# - Modified "reload" to call asterisk -rx 'reload'
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
NAME=asterisk
|
||||
DESC="Asterisk PBX"
|
||||
TUTDIR=/usr/share/cgrates/tutorial_tests/asterisk_ari/asterisk
|
||||
TMP_DIR=/tmp/cgr_asterisk_ari/asterisk
|
||||
# Full path to asterisk binary
|
||||
DAEMON=/usr/sbin/asterisk
|
||||
ASTVARRUNDIR=$TMP_DIR/run
|
||||
LOGDIR=$TMP_DIR/log
|
||||
DBDIR=$TMP_DIR/lib
|
||||
CDRDIR=$LOGDIR/cdr-custom
|
||||
SPOOLDIR=$TMP_DIR/spool
|
||||
ALTCONF=$TUTDIR/etc/asterisk/asterisk.conf
|
||||
TRUE=/bin/true
|
||||
AST_USER="asterisk"
|
||||
AST_GROUP="asterisk"
|
||||
VERBOSITY=1
|
||||
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: asterisk
|
||||
# Required-Start: $network $syslog $named $local_fs $remote_fs
|
||||
# Required-Stop: $network $syslog $named $local_fs $remote_fs
|
||||
# Should-Start: dahdi misdn lcr wanrouter mysql postgresql
|
||||
# Should-Stop: dahdi misdn lcr wanrouter mysql postgresql
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Asterisk PBX
|
||||
# Description: the Asterisk Open Source PBX
|
||||
### END INIT INFO
|
||||
|
||||
set -e
|
||||
|
||||
if ! [ -x $DAEMON ] ; then
|
||||
echo "ERROR: $DAEMON not found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! [ -d $ASTETCDIR ] ; then
|
||||
echo "ERROR: $ASTETCDIR directory not found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -d $LOGDIR ]; then
|
||||
mkdir -p $LOGDIR
|
||||
chown -R $AST_USER:$AST_GROUP $LOGDIR
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d $CDRDIR ]; then
|
||||
mkdir -p $CDRDIR
|
||||
chown -R $AST_USER:$AST_GROUP $CDRDIR
|
||||
fi
|
||||
|
||||
if [ ! -d $SPOOLDIR ]; then
|
||||
mkdir -p $SPOOLDIR
|
||||
chown -R $AST_USER:$AST_GROUP $SPOOLDIR
|
||||
fi
|
||||
|
||||
if [ ! -d $DBDIR ]; then
|
||||
mkdir -p $DBDIR
|
||||
chown -R $AST_USER:$AST_GROUP $DBDIR
|
||||
fi
|
||||
|
||||
# Use the LSB standard functions for services management
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
# Allow configuration overrides in /etc/default/asterisk
|
||||
CONFIG0=`readlink $0 || :` # readlink returns 1 when something isn't a symlink
|
||||
if [ "$CONFIG0" = "" ]; then
|
||||
CONFIGFILE=/etc/default/`basename $0`
|
||||
else
|
||||
CONFIGFILE=/etc/default/`basename $CONFIG0`
|
||||
fi
|
||||
[ -r $CONFIGFILE ] && . $CONFIGFILE
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
# Check if Asterisk is already running. If it is, then bug out, because
|
||||
# starting up Asterisk when Asterisk is already running is very bad.
|
||||
VERSION=`${DAEMON} -rx 'core show version' 2>/dev/null || ${TRUE}`
|
||||
if [ "`echo $VERSION | cut -c 1-8`" = "Asterisk" ]; then
|
||||
echo "Asterisk is already running. $0 will exit now."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log_begin_msg "Starting $DESC: $NAME"
|
||||
if [ ! -d $ASTVARRUNDIR ]; then
|
||||
mkdir -p $ASTVARRUNDIR
|
||||
fi
|
||||
if [ $AST_USER ] ; then
|
||||
ASTARGS="$ASTARGS -U $AST_USER"
|
||||
chown $AST_USER $ASTVARRUNDIR
|
||||
fi
|
||||
if [ $AST_GROUP ] ; then
|
||||
ASTARGS="$ASTARGS -G $AST_GROUP"
|
||||
chgrp $AST_GROUP $ASTVARRUNDIR
|
||||
fi
|
||||
if [ $ALTCONF ]; then
|
||||
ASTARGS="$ASTARGS -C $ALTCONF"
|
||||
fi
|
||||
if [ "x$COREDUMP" = "xyes" ]; then
|
||||
ASTARGS="$ASTARGS -g"
|
||||
fi
|
||||
if [ "0$MAXLOAD" -gt "0" ]; then
|
||||
ASTARGS="$ASTARGS -L $MAXLOAD"
|
||||
fi
|
||||
if [ "0$MAXCALLS" -gt "0" ]; then
|
||||
ASTARGS="$ASTARGS -M $MAXCALLS"
|
||||
fi
|
||||
if [ "0$VERBOSITY" -gt "0" ]; then
|
||||
for i in `seq 1 $VERBOSITY`; do
|
||||
ASTARGS="$ASTARGS -v"
|
||||
done
|
||||
# -v implies -f, so we override that implicit specification here
|
||||
ASTARGS="$ASTARGS -F"
|
||||
fi
|
||||
if [ "x$INTERNALTIMING" = "xyes" ]; then
|
||||
ASTARGS="$ASTARGS -I"
|
||||
fi
|
||||
if [ "x$TEMPRECORDINGLOCATION" = "xyes" -o "x$TMPRECORDINGLOCATION" = "xyes" ]; then
|
||||
ASTARGS="$ASTARGS -t"
|
||||
fi
|
||||
if test "x$COLOR" = "xno" ; then
|
||||
ASTARGS="$ASTARGS -n"
|
||||
fi
|
||||
# "start-stop-daemon --oknodo" returns 0 even if Asterisk was already running (as LSB expects):
|
||||
echo "$DAEMON -- $ASTARGS"
|
||||
start-stop-daemon --start --oknodo --exec $DAEMON -- $ASTARGS
|
||||
log_end_msg $?
|
||||
;;
|
||||
stop)
|
||||
log_begin_msg "Stopping $DESC: $NAME"
|
||||
# "start-stop-daemon --oknodo" returns 0 even if Asterisk was already stopped (as LSB expects):
|
||||
start-stop-daemon --stop --oknodo --exec $DAEMON
|
||||
log_end_msg $?
|
||||
;;
|
||||
reload)
|
||||
echo "Reloading $DESC configuration files."
|
||||
$DAEMON -rx 'module reload' > /dev/null 2> /dev/null
|
||||
;;
|
||||
restart|force-reload)
|
||||
$0 stop
|
||||
sleep 2 # It needs some time to really be stopped.
|
||||
$0 start
|
||||
# "restart|force-reload" starts Asterisk and returns 0 even if Asterisk was stopped (as LSB expects).
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
*)
|
||||
N=/etc/init.d/$NAME
|
||||
echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,145 @@
|
||||
{
|
||||
|
||||
// Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
// Copyright (C) ITsysCOM GmbH
|
||||
|
||||
"general": {
|
||||
"log_level": 7,
|
||||
"node_id":"CGRAsterisk",
|
||||
"reply_timeout": "5s",
|
||||
},
|
||||
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080",
|
||||
},
|
||||
|
||||
|
||||
"stor_db": {
|
||||
"db_password": "CGRateS.org",
|
||||
},
|
||||
|
||||
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"cdrs": {
|
||||
"enabled": true,
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"chargers_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"sessions_cost_retries": 5,
|
||||
},
|
||||
|
||||
|
||||
"chargers": {
|
||||
"enabled": true,
|
||||
"attributes_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"sessions": {
|
||||
"enabled": true,
|
||||
"rals_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"cdrs_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"suppliers_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"chargers_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"store_session_costs": true,
|
||||
"debit_interval": "5s",
|
||||
"channel_sync_interval":"7s",
|
||||
},
|
||||
|
||||
|
||||
"asterisk_agent": {
|
||||
"enabled": true,
|
||||
"asterisk_conns":[
|
||||
{"address": "127.0.0.1:8088", "user": "cgrates",
|
||||
"password": "CGRateS.org", "connect_attempts": 3,"reconnects": 10}
|
||||
],
|
||||
"sessions_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"create_cdr": true,
|
||||
},
|
||||
|
||||
|
||||
"attributes": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"resources": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"stats": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account","RunID","Destination"],
|
||||
},
|
||||
|
||||
|
||||
"thresholds": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"suppliers": {
|
||||
"enabled": true,
|
||||
"rals_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
184
data/tutorial_tests/asterisk_ari/cgrates/etc/init.d/cgrates
Executable file
184
data/tutorial_tests/asterisk_ari/cgrates/etc/init.d/cgrates
Executable file
@@ -0,0 +1,184 @@
|
||||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: cgrates
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: CGRateS real-time charging system
|
||||
# Description: Control CGRateS - carrier grade real-time charging system
|
||||
### END INIT INFO
|
||||
|
||||
# Author: DanB <danb@cgrates.org>
|
||||
#
|
||||
# Do NOT "set -e"
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="CGRateS real-time online/offline Charging System"
|
||||
NAME=cgrates
|
||||
DAEMON=/usr/bin/cgr-engine
|
||||
USER=cgrates
|
||||
GROUP=cgrates
|
||||
DAEMON_OPTS=""
|
||||
TUTFOLDER=/usr/share/cgrates/tutorial_tests/asterisk_ari/cgrates
|
||||
TMP_DIR=/tmp/cgr_astevents/cgrates
|
||||
SCRIPTNAME=$TUTFOLDER/etc/init.d/$NAME
|
||||
RUNDIR=$TMP_DIR/run
|
||||
PIDFILE=$RUNDIR/cgr-engine.pid
|
||||
STACKTRACE=$RUNDIR/$NAME.strace
|
||||
ENABLE=true
|
||||
DAEMON_OPTS="-config_path=$TUTFOLDER/etc/cgrates"
|
||||
CDREDIR=$TMP_DIR/cdre
|
||||
CDRCINDIR=$TMP_DIR/cdrc/in
|
||||
CDRCOUTDIR=$TMP_DIR/cdrc/out
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
if [ "$ENABLE" != "true" ]; then
|
||||
echo "$DESC not yet configured. Edit $DEFAULTS first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Install the run folder
|
||||
if [ ! -d $RUNDIR ]; then
|
||||
mkdir -p $RUNDIR
|
||||
touch $STACKTRACE
|
||||
chown -R $USER:$GROUP $RUNDIR
|
||||
fi
|
||||
# Install the cdrc folder
|
||||
if [ ! -d $CDRCINDIR ]; then
|
||||
mkdir -p $CDRCINDIR
|
||||
chown $USER:$GROUP $CDRCINDIR
|
||||
mkdir -p $CDRCOUTDIR
|
||||
chown $USER:$GROUP $CDRCOUTDIR
|
||||
fi
|
||||
# Install the cdre folder
|
||||
if [ ! -d $CDREDIR ]; then
|
||||
mkdir -p $CDREDIR
|
||||
chown $USER:$GROUP $CDREDIR
|
||||
fi
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
echo "\n### Started at:" `date`>>$STACKTRACE
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test\
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --background\
|
||||
--startas /bin/bash -- -c "exec $DAEMON $DAEMON_OPTS >> $STACKTRACE 2>&1" \
|
||||
|| return 2
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
||||
17
data/tutorial_tests/fs_evsock/README.md
Normal file
17
data/tutorial_tests/fs_evsock/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
Tutorial FS_JSON
|
||||
================
|
||||
|
||||
Scenario:
|
||||
---------
|
||||
|
||||
- FreeSWITCH with minimal custom configuration.
|
||||
|
||||
- Added following users (with configs in *etc/freeswitch/directory/default*): 1001-prepaid, 1002-postpaid, 1003-pseudoprepaid, 1004-rated, 1006-prepaid, 1007-prepaid.
|
||||
- Have added inside default dialplan CGR own extensions just before routing towards users (*etc/freeswitch/dialplan/default.xml*).
|
||||
|
||||
- **CGRateS** with following components:
|
||||
|
||||
- CGR-SM started as prepaid controller, with debits taking place at 5s intervals.
|
||||
- CGR-Mediator component attaching costs to the raw CDRs from FreeSWITCH_ inside CGR StorDB.
|
||||
- CGR-CDRE exporting mediated CDRs from CGR StorDB (export path: */tmp*).
|
||||
- CGR-CDRStats component building up stats in 5 different queues.
|
||||
142
data/tutorial_tests/fs_evsock/cgrates/etc/cgrates/cgrates.json
Normal file
142
data/tutorial_tests/fs_evsock/cgrates/etc/cgrates/cgrates.json
Normal file
@@ -0,0 +1,142 @@
|
||||
{
|
||||
|
||||
// Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
// Copyright (C) ITsysCOM GmbH
|
||||
|
||||
"general": {
|
||||
"log_level": 7,
|
||||
"node_id":"CGRFreeswitch",
|
||||
},
|
||||
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080",
|
||||
},
|
||||
|
||||
|
||||
"stor_db": {
|
||||
"db_password": "CGRateS.org",
|
||||
},
|
||||
|
||||
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"cdrs": {
|
||||
"enabled": true,
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"chargers_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"sessions_cost_retries": 5,
|
||||
},
|
||||
|
||||
|
||||
"chargers": {
|
||||
"enabled": true,
|
||||
"attributes_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"sessions": {
|
||||
"enabled": true,
|
||||
"rals_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"cdrs_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"suppliers_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"chargers_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"store_session_costs": true,
|
||||
"debit_interval": "5s",
|
||||
"channel_sync_interval":"7s",
|
||||
},
|
||||
|
||||
|
||||
"freeswitch_agent": {
|
||||
"enabled": true,
|
||||
"event_socket_conns":[
|
||||
{"address": "127.0.0.1:8021", "password": "ClueCon", "reconnects": -1,"alias":""}
|
||||
],
|
||||
"sessions_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"attributes": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"resources": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"stats": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account","RunID","Destination"],
|
||||
},
|
||||
|
||||
|
||||
"thresholds": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"suppliers": {
|
||||
"enabled": true,
|
||||
"rals_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
184
data/tutorial_tests/fs_evsock/cgrates/etc/init.d/cgrates
Executable file
184
data/tutorial_tests/fs_evsock/cgrates/etc/init.d/cgrates
Executable file
@@ -0,0 +1,184 @@
|
||||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: cgrates
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: CGRateS real-time charging system
|
||||
# Description: Control CGRateS - carrier grade real-time charging system
|
||||
### END INIT INFO
|
||||
|
||||
# Author: DanB <danb@cgrates.org>
|
||||
#
|
||||
# Do NOT "set -e"
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="CGRateS real-time charging system"
|
||||
NAME=cgrates
|
||||
DAEMON=/usr/bin/cgr-engine
|
||||
USER=cgrates
|
||||
GROUP=cgrates
|
||||
DAEMON_OPTS=""
|
||||
TUTFOLDER=/usr/share/cgrates/tutorial_tests/fs_evsock/cgrates
|
||||
TMP_DIR=/tmp/cgr_fsevsock/cgrates
|
||||
SCRIPTNAME=$TUTFOLDER/etc/init.d/$NAME
|
||||
RUNDIR=$TMP_DIR/run
|
||||
PIDFILE=$RUNDIR/cgr-engine.pid
|
||||
STACKTRACE=$RUNDIR/$NAME.strace
|
||||
ENABLE=true
|
||||
DAEMON_OPTS="-config_path=$TUTFOLDER/etc/cgrates"
|
||||
CDREDIR=$TMP_DIR/cdre
|
||||
CDRCINDIR=$TMP_DIR/cdrc/in
|
||||
CDRCOUTDIR=$TMP_DIR/cdrc/out
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
if [ "$ENABLE" != "true" ]; then
|
||||
echo "$DESC not yet configured. Edit $DEFAULTS first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Install the run folder
|
||||
if [ ! -d $RUNDIR ]; then
|
||||
mkdir -p $RUNDIR
|
||||
touch $STACKTRACE
|
||||
chown -R $USER:$GROUP $RUNDIR
|
||||
fi
|
||||
# Install the cdrc folder
|
||||
if [ ! -d $CDRCINDIR ]; then
|
||||
mkdir -p $CDRCINDIR
|
||||
chown $USER:$GROUP $CDRCINDIR
|
||||
mkdir -p $CDRCOUTDIR
|
||||
chown $USER:$GROUP $CDRCOUTDIR
|
||||
fi
|
||||
# Install the cdre folder
|
||||
if [ ! -d $CDREDIR ]; then
|
||||
mkdir -p $CDREDIR
|
||||
chown $USER:$GROUP $CDREDIR
|
||||
fi
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
echo "\n### Started at:" `date`>>$STACKTRACE
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test\
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --background\
|
||||
--startas /bin/bash -- -c "exec $DAEMON $DAEMON_OPTS >> $STACKTRACE 2>&1" \
|
||||
|| return 2
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
||||
Binary file not shown.
145
data/tutorial_tests/fs_evsock/freeswitch/etc/init.d/freeswitch
Executable file
145
data/tutorial_tests/fs_evsock/freeswitch/etc/init.d/freeswitch
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/bin/sh
|
||||
### -*- mode:shell-script; indent-tabs-mode:nil; sh-basic-offset:2 -*-
|
||||
### BEGIN INIT INFO
|
||||
# Provides: freeswitch
|
||||
# Required-Start: $network $remote_fs $local_fs
|
||||
# Required-Stop: $network $remote_fs $local_fs
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: FreeSWITCH Softswitch
|
||||
# Description: FreeSWITCH Softswitch
|
||||
### END INIT INFO
|
||||
|
||||
# Author: Travis Cross <tc@traviscross.com>
|
||||
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC=freeswitch
|
||||
NAME=freeswitch
|
||||
DAEMON=/usr/bin/freeswitch
|
||||
USER=freeswitch
|
||||
GROUP=freeswitch
|
||||
TUTDIR=/usr/share/cgrates/tutorial_tests/fs_evsock/freeswitch
|
||||
SCRIPTNAME=$TUTDIR/etc/init.d/$NAME
|
||||
TMP_DIR=/tmp/cgr_fsevsock/freeswitch
|
||||
CONFDIR=$TUTDIR/etc/$NAME
|
||||
RUNDIR=$TMP_DIR/run
|
||||
LOGDIR=$TMP_DIR/log
|
||||
PIDFILE=$RUNDIR/$NAME.pid
|
||||
WORKDIR=$TMP_DIR/lib
|
||||
DBDIR=$WORKDIR/db/
|
||||
DAEMON_ARGS="-rp -conf $CONFDIR -db $DBDIR -log $LOGDIR -u $USER -g $GROUP -nonat -nc"
|
||||
|
||||
|
||||
[ -x $DAEMON ] || exit 0
|
||||
. /lib/init/vars.sh
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
if [ ! -d $RUNDIR ]; then
|
||||
mkdir -p $RUNDIR
|
||||
chown -R $USER:$GROUP $RUNDIR
|
||||
chmod -R ug=rwX,o= $RUNDIR
|
||||
fi
|
||||
|
||||
if [ ! -d $LOGDIR ]; then
|
||||
mkdir -p $LOGDIR
|
||||
chown -R $USER:$GROUP $LOGDIR
|
||||
fi
|
||||
|
||||
if [ ! -d $DBDIR ]; then
|
||||
mkdir -p $DBDIR
|
||||
chown -R $USER:$GROUP $DBDIR
|
||||
fi
|
||||
|
||||
do_start() {
|
||||
if ! [ -f $CONFDIR/freeswitch.xml ]; then
|
||||
echo "$NAME is not configured so not starting.">&2
|
||||
echo "Please review /usr/share/doc/$NAME/README.Debian">&2
|
||||
return 3
|
||||
fi
|
||||
echo $DAEMON_ARGS
|
||||
start-stop-daemon --start --quiet \
|
||||
--pidfile $PIDFILE --exec $DAEMON --name $NAME --user $USER \
|
||||
--test > /dev/null \
|
||||
|| return 1
|
||||
ulimit -s 240
|
||||
start-stop-daemon --start --quiet \
|
||||
--pidfile $PIDFILE --exec $DAEMON --name $NAME --user $USER \
|
||||
--chdir $WORKDIR -- $DAEMON_ARGS $DAEMON_OPTS \
|
||||
|| return 2
|
||||
return 0
|
||||
}
|
||||
|
||||
stop_fs() {
|
||||
start-stop-daemon --stop --quiet \
|
||||
--pidfile $PIDFILE --name $NAME --user $USER \
|
||||
--retry=TERM/30/KILL/5
|
||||
}
|
||||
|
||||
stop_fs_children() {
|
||||
start-stop-daemon --stop --quiet \
|
||||
--exec $DAEMON \
|
||||
--oknodo --retry=0/30/KILL/5
|
||||
}
|
||||
|
||||
do_stop() {
|
||||
stop_fs
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" -eq 2 ] && return 2
|
||||
stop_fs_children
|
||||
[ "$?" -eq 2 ] && return 2
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
do_reload() {
|
||||
start-stop-daemon --stop --quiet \
|
||||
--pidfile $PIDFILE --name $NAME --user $USER \
|
||||
--signal HUP
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
reload|force-reload)
|
||||
log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
do_reload
|
||||
log_end_msg $?
|
||||
;;
|
||||
restart)
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1|*) log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
*) log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
141
data/tutorial_tests/kamevapi/cgrates/etc/cgrates/cgrates.json
Normal file
141
data/tutorial_tests/kamevapi/cgrates/etc/cgrates/cgrates.json
Normal file
@@ -0,0 +1,141 @@
|
||||
{
|
||||
|
||||
// Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
// Copyright (C) ITsysCOM GmbH
|
||||
|
||||
"general": {
|
||||
"log_level": 7,
|
||||
"node_id":"CGRKamailio",
|
||||
"reply_timeout": "5s",
|
||||
},
|
||||
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080",
|
||||
},
|
||||
|
||||
|
||||
"stor_db": {
|
||||
"db_password": "CGRateS.org",
|
||||
},
|
||||
|
||||
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"cdrs": {
|
||||
"enabled": true,
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"sessions_cost_retries": 5,
|
||||
},
|
||||
|
||||
|
||||
"chargers": {
|
||||
"enabled": true,
|
||||
"attributes_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"sessions": {
|
||||
"enabled": true,
|
||||
"rals_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"cdrs_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"suppliers_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"chargers_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"},
|
||||
],
|
||||
"store_session_costs": true,
|
||||
"debit_interval": "5s",
|
||||
"channel_sync_interval":"7s",
|
||||
},
|
||||
|
||||
|
||||
"kamailio_agent": {
|
||||
"enabled": true,
|
||||
"evapi_conns":[
|
||||
{"address": "127.0.0.1:8448", "reconnects": 5}
|
||||
],
|
||||
"sessions_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"create_cdr": true,
|
||||
},
|
||||
|
||||
|
||||
"attributes": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"resources": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"stats": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account","RunID","Destination"],
|
||||
},
|
||||
|
||||
|
||||
"thresholds": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"suppliers": {
|
||||
"enabled": true,
|
||||
"rals_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
175
data/tutorial_tests/kamevapi/cgrates/etc/init.d/cgrates
Executable file
175
data/tutorial_tests/kamevapi/cgrates/etc/init.d/cgrates
Executable file
@@ -0,0 +1,175 @@
|
||||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: cgrates
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: CGRateS real-time charging system
|
||||
# Description: Control CGRateS - carrier grade real-time charging system
|
||||
### END INIT INFO
|
||||
|
||||
# Author: DanB <danb@cgrates.org>
|
||||
#
|
||||
# Do NOT "set -e"
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="CGRateS real-time charging system"
|
||||
NAME=cgrates
|
||||
DAEMON=/usr/bin/cgr-engine
|
||||
USER=cgrates
|
||||
GROUP=cgrates
|
||||
DAEMON_OPTS=""
|
||||
TUTFOLDER=/usr/share/cgrates/tutorial_tests/kamevapi/cgrates
|
||||
TMP_DIR=/tmp/cgr_kamevapi/cgrates
|
||||
SCRIPTNAME=$TUTFOLDER/etc/init.d/$NAME
|
||||
RUNDIR=$TMP_DIR/run
|
||||
PIDFILE=$RUNDIR/cgr-engine.pid
|
||||
STACKTRACE=$RUNDIR/$NAME.strace
|
||||
ENABLE=true
|
||||
DAEMON_OPTS="-config_path=$TUTFOLDER/etc/cgrates"
|
||||
CDREDIR=$TMP_DIR/cdre
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
if [ "$ENABLE" != "true" ]; then
|
||||
echo "$DESC not yet configured. Edit $DEFAULTS first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Install the run folder
|
||||
if [ ! -d $RUNDIR ]; then
|
||||
mkdir -p $RUNDIR
|
||||
touch $STACKTRACE
|
||||
chown -R $USER:$GROUP $RUNDIR
|
||||
fi
|
||||
# Install the cdre folder
|
||||
if [ ! -d $CDREDIR ]; then
|
||||
mkdir -p $CDREDIR
|
||||
chown -R $USER:$GROUP $CDREDIR
|
||||
fi
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
echo "\n### Started at:" `date`>>$STACKTRACE
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test\
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --background\
|
||||
--startas /bin/bash -- -c "exec $DAEMON $DAEMON_OPTS >> $STACKTRACE 2>&1" \
|
||||
|| return 2
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
||||
166
data/tutorial_tests/kamevapi/kamailio/etc/init.d/kamailio
Executable file
166
data/tutorial_tests/kamevapi/kamailio/etc/init.d/kamailio
Executable file
@@ -0,0 +1,166 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: kamailio
|
||||
# Required-Start: $syslog $network $local_fs $remote_fs $time
|
||||
# Should-Start: $named slapd mysql postgresql snmpd radiusd
|
||||
# Should-Stop: $named slapd mysql postgresql snmpd radiusd
|
||||
# Required-Stop: $syslog $network $local_fs $remote_fs
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start the Kamailio SIP proxy server
|
||||
# Description: Start the Kamailio SIP proxy server
|
||||
### END INIT INFO
|
||||
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
DAEMON=/usr/sbin/kamailio
|
||||
NAME=kamailio
|
||||
DESC="Kamailio SIP Server"
|
||||
TUTDIR=/usr/share/cgrates/tutorial_tests/kamevapi/
|
||||
TMP_DIR=/tmp/cgr_kamevapi/kamailio
|
||||
HOMEDIR=$TMP_DIR/run/
|
||||
PIDFILE=$HOMEDIR/$NAME.pid
|
||||
CFGFILE=$TUTDIR/kamailio/etc/kamailio/kamailio.cfg
|
||||
USER=kamailio
|
||||
GROUP=kamailio
|
||||
# Amount of shared and private memory to allocate
|
||||
# for the running Kamailio server (in Mb)
|
||||
SHM_MEMORY=64
|
||||
PKG_MEMORY=8
|
||||
DUMP_CORE=no
|
||||
|
||||
if [ ! -d $HOMEDIR ]; then
|
||||
mkdir -p $HOMEDIR
|
||||
chown -R $USER:$GROUP $HOMEDIR
|
||||
chmod -R ug=rwX,o= $HOMEDIR
|
||||
fi
|
||||
|
||||
if [ ! -d $LOGDIR ]; then
|
||||
mkdir -p $LOGDIR
|
||||
chown -R $USER:$GROUP $LOGDIR
|
||||
fi
|
||||
|
||||
# Do not start kamailio if fork=no is set in the config file
|
||||
# otherwise the boot process will just stop
|
||||
check_fork ()
|
||||
{
|
||||
if grep -q "^[[:space:]]*fork[[:space:]]*=[[:space:]]*no.*" $CFGFILE; then
|
||||
log_failure_msg "Not starting $DESC: fork=no specified in config file; run /etc/init.d/kamailio debug instead"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
check_kamailio_config ()
|
||||
{
|
||||
# Check if kamailio configuration is valid before starting the server
|
||||
set +e
|
||||
out=$($DAEMON -f $CFGFILE -M $PKG_MEMORY -c 2>&1 > /dev/null)
|
||||
retcode=$?
|
||||
set -e
|
||||
if [ "$retcode" != '0' ]; then
|
||||
log_failure_msg "Not starting $DESC: invalid configuration file!"
|
||||
log_failure_msg
|
||||
log_failure_msg "$out"
|
||||
log_failure_msg
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
create_radius_seqfile ()
|
||||
{
|
||||
# Create a radius sequence file to be used by the radius client if
|
||||
# radius accounting is enabled. This is needed to avoid any issue
|
||||
# with the file not being writable if kamailio first starts as user
|
||||
# root because DUMP_CORE is enabled and creates this file as user
|
||||
# root and then later it switches back to user kamailio and cannot
|
||||
# write to the file. If the file exists before kamailio starts, it
|
||||
# won't change it's ownership and will be writable for both root
|
||||
# and kamailio, no matter what options are chosen at install time
|
||||
RADIUS_SEQ_FILE=/var/run/kamailio/kamailio_radius.seq
|
||||
if [ -d /var/run/kamailio ]; then
|
||||
chown ${USER}:${GROUP} /var/run/kamailio
|
||||
|
||||
if [ ! -f $RADIUS_SEQ_FILE ]; then
|
||||
touch $RADIUS_SEQ_FILE
|
||||
fi
|
||||
|
||||
chown ${USER}:${GROUP} $RADIUS_SEQ_FILE
|
||||
chmod 660 $RADIUS_SEQ_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
test -f $DAEMON || exit 0
|
||||
|
||||
# Load startup options if available
|
||||
|
||||
|
||||
set -e
|
||||
|
||||
SHM_MEMORY=$((`echo $SHM_MEMORY | sed -e 's/[^0-9]//g'`))
|
||||
PKG_MEMORY=$((`echo $PKG_MEMORY | sed -e 's/[^0-9]//g'`))
|
||||
[ -z "$USER" ] && USER=kamailio
|
||||
[ -z "$GROUP" ] && GROUP=kamailio
|
||||
[ $SHM_MEMORY -le 0 ] && SHM_MEMORY=64
|
||||
[ $PKG_MEMORY -le 0 ] && PKG_MEMORY=4
|
||||
|
||||
if test "$DUMP_CORE" = "yes" ; then
|
||||
# set proper ulimit
|
||||
ulimit -c unlimited
|
||||
|
||||
# directory for the core dump files
|
||||
# COREDIR=/home/corefiles
|
||||
# [ -d $COREDIR ] || mkdir $COREDIR
|
||||
# chmod 777 $COREDIR
|
||||
# echo "$COREDIR/core.%e.sig%s.%p" > /proc/sys/kernel/core_pattern
|
||||
fi
|
||||
|
||||
# /var/run can be a tmpfs
|
||||
if [ ! -d $HOMEDIR ]; then
|
||||
mkdir -p $HOMEDIR
|
||||
fi
|
||||
|
||||
OPTIONS="-f $CFGFILE -P $PIDFILE -m $SHM_MEMORY -M $PKG_MEMORY -u $USER -g $GROUP"
|
||||
|
||||
case "$1" in
|
||||
start|debug)
|
||||
check_kamailio_config
|
||||
create_radius_seqfile
|
||||
|
||||
if [ "$1" != "debug" ]; then
|
||||
check_fork
|
||||
fi
|
||||
|
||||
log_daemon_msg "Starting $DESC: $NAME"
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE \
|
||||
--exec $DAEMON -- $OPTIONS || log_failure_msg " already running"
|
||||
log_end_msg 0
|
||||
;;
|
||||
stop)
|
||||
log_daemon_msg "Stopping $DESC: $NAME"
|
||||
start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE \
|
||||
--exec $DAEMON
|
||||
log_end_msg 0
|
||||
;;
|
||||
restart|force-reload)
|
||||
check_kamailio_config
|
||||
create_radius_seqfile
|
||||
|
||||
$0 stop
|
||||
sleep 1
|
||||
$0 start
|
||||
;;
|
||||
status)
|
||||
log_daemon_msg "Status of $DESC: "
|
||||
|
||||
status_of_proc -p"$PIDFILE" $NAME $NAME
|
||||
;;
|
||||
*)
|
||||
N=/etc/init.d/$NAME
|
||||
echo "Usage: $N {start|stop|restart|force-reload|status|debug}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,192 @@
|
||||
# Kamailio-CGRateS related route blocks
|
||||
|
||||
|
||||
# Called on new connection over evapi, should normally be the case of CGRateS engine
|
||||
event_route[evapi:connection-new] {
|
||||
$sht(cgrconn=>cgr) = $evapi(srcaddr) + ":" + $evapi(srcport); # Detect presence of at least one connection
|
||||
}
|
||||
|
||||
|
||||
# Called when the connection with CGRateS closes
|
||||
event_route[evapi:connection-closed] {
|
||||
$var(connClosed) = $evapi(srcaddr) + ":" + $evapi(srcport);
|
||||
if $sht(cgrconn=>cgr) == $var(connClosed) {
|
||||
$sht(cgrconn=>cgr) = $null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Message received from CGRateS, dispatch it to own route
|
||||
event_route[evapi:message-received] {
|
||||
json_get_field("$evapi(msg)", "Event", "$var(Event)");
|
||||
route($(var(Event){s.rm,"})); # String characters are kept by json_get_field, remove them here
|
||||
}
|
||||
|
||||
|
||||
# Called by Kamailio on new dialog
|
||||
event_route[dialog:start] {
|
||||
route(CGR_CALL_START);
|
||||
}
|
||||
|
||||
|
||||
# Called by Kamailio on dialog end
|
||||
event_route[dialog:end] {
|
||||
route(CGR_CALL_END);
|
||||
}
|
||||
|
||||
# Parse the CGRateS attributes from encoded variable into pseudovariables
|
||||
route[PARSE_CGRATES_ATTRIBUTES] {
|
||||
# convert encoded attributes into individual Kamailio pseudovariables
|
||||
$var(idx) = 0;
|
||||
while !strempty($(var(cgrAttributes){s.select,$var(idx),,})) {
|
||||
$avp($(var(cgrAttributes){s.select,$var(idx),,}{s.select,0,:}))
|
||||
= $(var(cgrAttributes){s.select,$var(idx),,}{s.select,1,:});
|
||||
$var(idx) = $var(idx) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# CGRateS request for session disconnect
|
||||
route[CGR_SESSION_DISCONNECT] {
|
||||
json_get_field("$evapi(msg)", "HashEntry", "$var(HashEntry)");
|
||||
json_get_field("$evapi(msg)", "HashId", "$var(HashId)");
|
||||
json_get_field("$evapi(msg)", "Reason", "$var(Reason)");
|
||||
jsonrpc_exec('{"jsonrpc":"2.0","id":1, "method":"dlg.end_dlg","params":[$(var(HashEntry){s.rm,"}),$(var(HashId){s.rm,"})]}');
|
||||
}
|
||||
|
||||
route[CGR_DLG_LIST] {
|
||||
if $sht(cgrconn=>cgr) == $null {
|
||||
sl_send_reply("503","Charging controller unreachable");
|
||||
exit;
|
||||
}
|
||||
jsonrpc_exec('{"jsonrpc":"2.0","id":1, "method":"dlg.list","params":[]}');
|
||||
evapi_relay("{\"event\":\"CGR_DLG_LIST_REPLY\",
|
||||
\"jsonrpl_body\":$jsonrpl(body)}");
|
||||
}
|
||||
|
||||
|
||||
# Route to mainly query account password from CGRateS
|
||||
route[CGRATES_SIMPLEAUTH_REQUEST] {
|
||||
if $sht(cgrconn=>cgr) == $null {
|
||||
sl_send_reply("503","Charging controller unreachable");
|
||||
exit;
|
||||
}
|
||||
evapi_async_relay("{\"event\":\"CGR_AUTH_REQUEST\",
|
||||
\"tr_index\":\"$T(id_index)\",
|
||||
\"tr_label\":\"$T(id_label)\",
|
||||
\"cgr_subsystems\":\"*attributes\",
|
||||
\"cgr_context\":\"simpleauth\",
|
||||
\"reply_route\":\"CGR_SIMPLEAUTH_REPLY\",
|
||||
\"Account\":\"$fU\"}");
|
||||
}
|
||||
|
||||
|
||||
# Route receiving simpleauth replies, sanitizes them and dispatch back into Kamailio inside CGRATES_SIMPLEAUTH_REPLY
|
||||
route[CGR_SIMPLEAUTH_REPLY] {
|
||||
|
||||
json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)");
|
||||
$var(TransactionIndex) = $(var(TransactionIndex){s.rm,"});
|
||||
$var(id_index) = $(var(TransactionIndex){s.int});
|
||||
|
||||
json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)");
|
||||
$var(TransactionLabel) = $(var(TransactionLabel){s.rm,"});
|
||||
$var(id_label) = $(var(TransactionLabel){s.int});
|
||||
|
||||
json_get_field("$evapi(msg)", "Attributes", "$var(cgrAttributes)");
|
||||
$var(cgrAttributes) = $(var(cgrAttributes){s.rm,"});
|
||||
|
||||
json_get_field("$evapi(msg)", "Error", "$var(cgrError)");
|
||||
$var(cgrError) = $(var(cgrError){s.rm,"});
|
||||
|
||||
t_continue("$var(id_index)", "$var(id_label)", "CGRATES_SIMPLEAUTH_REPLY"); # Unpark the transaction
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Request session auth information from CGRateS
|
||||
route[CGRATES_SESSIONAUTH_REQUEST] {
|
||||
# Auth INVITEs with CGRateS
|
||||
if $sht(cgrconn=>cgr) == $null {
|
||||
sl_send_reply("503","Charging controller unreachable");
|
||||
exit;
|
||||
}
|
||||
evapi_async_relay("{\"event\":\"CGR_AUTH_REQUEST\",
|
||||
\"tr_index\":\"$T(id_index)\",
|
||||
\"tr_label\":\"$T(id_label)\",
|
||||
\"cgr_subsystems\":\"*attributes;*accounts;*suppliers;*resources;*thresholds\",
|
||||
\"reply_route\":\"CGR_SESSIONAUTH_REPLY\",
|
||||
\"Account\":\"$fU\",
|
||||
\"Destination\":\"$rU\",
|
||||
\"SetupTime\":\"$TS\"}");
|
||||
}
|
||||
|
||||
|
||||
# Process SESSIONAUTH_reply from CGRateS
|
||||
route[CGR_SESSIONAUTH_REPLY] {
|
||||
json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)");
|
||||
$var(TransactionIndex) = $(var(TransactionIndex){s.rm,"});
|
||||
$var(id_index) = $(var(TransactionIndex){s.int});
|
||||
|
||||
json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)");
|
||||
$var(TransactionLabel) = $(var(TransactionLabel){s.rm,"});
|
||||
$var(id_label) = $(var(TransactionLabel){s.int});
|
||||
|
||||
json_get_field("$evapi(msg)", "Attributes", "$var(cgrAttributes)");
|
||||
$var(cgrAttributes) = $(var(cgrAttributes){s.rm,"});
|
||||
|
||||
json_get_field("$evapi(msg)", "ResourceAllocation", "$var(cgrResourceAllocation)");
|
||||
$var($var(cgrResourceAllocation)) = $(var(cgrResourceAllocation){s.rm,"});
|
||||
|
||||
json_get_field("$evapi(msg)", "MaxUsage", "$var(MaxUsage)");
|
||||
$var(cgrMaxUsage) = $(var(MaxUsage){s.int});
|
||||
|
||||
json_get_field("$evapi(msg)", "Suppliers", "$var(cgrSuppliers)");
|
||||
$var($var(cgrSuppliers)) = $(var(cgrSuppliers){s.rm,"});
|
||||
|
||||
json_get_field("$evapi(msg)", "Error", "$var(cgrError)");
|
||||
$var(cgrError) = $(var(cgrError){s.rm,"});
|
||||
|
||||
t_continue("$var(id_index)", "$var(id_label)", "CGRATES_SESSIONAUTH_REPLY"); # Unpark the transaction
|
||||
}
|
||||
|
||||
|
||||
# Inform CGRateS about CALL_START (start prepaid sessions loops)
|
||||
route[CGR_CALL_START] {
|
||||
if $sht(cgrconn=>cgr) == $null {
|
||||
xlog("Charging controller unreachable");
|
||||
exit;
|
||||
}
|
||||
evapi_relay("{\"event\":\"CGR_CALL_START\",
|
||||
\"h_entry\":\"$dlg(h_entry)\",
|
||||
\"h_id\":\"$dlg(h_id)\",
|
||||
\"cgr_subsystems\":\"*attributes;*accounts;*resources;*thresholds\",
|
||||
\"OriginID\":\"$dlg_var(cgrOriginID)\",
|
||||
\"RequestType\":\"$dlg_var(cgrReqType)\",
|
||||
\"Tenant\":\"$dlg_var(cgrTenant)\",
|
||||
\"Account\":\"$dlg_var(cgrAccount)\",
|
||||
\"Destination\":\"$dlg_var(cgrDestination)\",
|
||||
\"SetupTime\":\"$dlg_var(SetupTime)\",
|
||||
\"AnswerTime\":\"$TS\"}");
|
||||
}
|
||||
|
||||
|
||||
# Inform CGRateS about CALL_END (stop debit loops, perform accounting if desired in this way)
|
||||
route[CGR_CALL_END] {
|
||||
if $sht(cgrconn=>cgr) == $null {
|
||||
xlog("Charging controller unreachable");
|
||||
exit;
|
||||
}
|
||||
$var(callDur) = $TS - $dlg(start_ts);
|
||||
evapi_relay("{\"event\":\"CGR_CALL_END\",
|
||||
\"cgr_subsystems\":\"*accounts;*resources\",
|
||||
\"OriginID\":\"$dlg_var(cgrOriginID)\",
|
||||
\"RequestType\":\"$dlg_var(cgrReqType)\",
|
||||
\"Tenant\":\"$dlg_var(cgrTenant)\",
|
||||
\"Account\":\"$dlg_var(cgrAccount)\",
|
||||
\"Destination\":\"$dlg_var(cgrDestination)\",
|
||||
\"AnswerTime\":\"$dlg(start_ts)\",
|
||||
\"PaypalAccount\":\"$dlg_var(paypalAccount)\",
|
||||
\"SetupTime\":\"$dlg_var(SetupTime)\",
|
||||
\"Usage\":\"$var(callDur)\"}");
|
||||
}
|
||||
|
||||
439
data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio.cfg
Normal file
439
data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio.cfg
Normal file
@@ -0,0 +1,439 @@
|
||||
#!KAMAILIO
|
||||
|
||||
# Sample demo config for Kamailio-CGRateS communication
|
||||
# tested against Kamailio 5.1
|
||||
|
||||
####### Defined Values #########
|
||||
|
||||
#!define FLT_DIALOG 4
|
||||
#!define FLT_NATS 5
|
||||
#!define FLB_NATB 6
|
||||
#!define FLB_NATSIPPING 7
|
||||
|
||||
####### Global Parameters #########
|
||||
|
||||
debug=2
|
||||
log_stderror=no
|
||||
|
||||
listen=udp:enp0s3:5060
|
||||
listen=udp:127.0.0.1:5080
|
||||
listen=udp:127.0.0.1:5060
|
||||
listen=udp:enp0s3:5080
|
||||
|
||||
memdbg=5
|
||||
memlog=5
|
||||
log_facility=LOG_LOCAL0
|
||||
fork=yes
|
||||
children=4
|
||||
tcp_connection_lifetime=3605
|
||||
use_dns_cache=no
|
||||
dns_try_ipv6=no
|
||||
dns_retr_time=1
|
||||
dns_retr_no=1
|
||||
dns_servers_no=1
|
||||
dns_use_search_list=no
|
||||
|
||||
####### Modules Section ########
|
||||
|
||||
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
|
||||
|
||||
loadmodule "kex.so"
|
||||
loadmodule "corex.so"
|
||||
loadmodule "tm.so"
|
||||
loadmodule "tmx.so"
|
||||
loadmodule "sl.so"
|
||||
loadmodule "rr.so"
|
||||
loadmodule "pv.so"
|
||||
loadmodule "maxfwd.so"
|
||||
loadmodule "usrloc.so"
|
||||
loadmodule "registrar.so"
|
||||
loadmodule "textops.so"
|
||||
loadmodule "siputils.so"
|
||||
loadmodule "xlog.so"
|
||||
loadmodule "sanity.so"
|
||||
loadmodule "nathelper.so"
|
||||
loadmodule "htable.so"
|
||||
loadmodule "auth.so"
|
||||
loadmodule "evapi.so"
|
||||
loadmodule "json.so"
|
||||
loadmodule "dialog.so"
|
||||
loadmodule "jsonrpcs.so"
|
||||
|
||||
|
||||
|
||||
# ----------------- setting module-specific parameters ---------------
|
||||
|
||||
modparam("evapi", "bind_addr", "127.0.0.1:8448")
|
||||
|
||||
# ----- tm params -----
|
||||
modparam("tm", "failure_reply_mode", 3)
|
||||
modparam("tm", "fr_timer", 30000)
|
||||
modparam("tm", "fr_inv_timer", 120000)
|
||||
|
||||
# ----- rr params -----
|
||||
modparam("rr", "enable_full_lr", 0)
|
||||
modparam("rr", "append_fromtag", 0)
|
||||
|
||||
# ----- registrar params -----
|
||||
modparam("registrar", "method_filtering", 1)
|
||||
modparam("registrar", "max_expires", 3600)
|
||||
|
||||
# ----- dialog params -----
|
||||
modparam("dialog", "dlg_flag", FLT_DIALOG)
|
||||
modparam("dialog", "send_bye", 1)
|
||||
modparam("dialog", "timeout_noreset", 1)
|
||||
|
||||
# ----- nathelper params -----
|
||||
modparam("nathelper", "natping_interval", 30)
|
||||
modparam("nathelper", "ping_nated_only", 1)
|
||||
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
|
||||
modparam("nathelper", "sipping_from", "sip:pinger@kamailio.org")
|
||||
|
||||
# params needed for NAT traversal in other modules
|
||||
modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
|
||||
modparam("usrloc", "nat_bflag", FLB_NATB)
|
||||
|
||||
# ----- htable params -----
|
||||
modparam("htable", "htable", "cgrconn=>size=1;")
|
||||
|
||||
####### Routing Logic ########
|
||||
|
||||
include_file "kamailio-cgrates.cfg"
|
||||
|
||||
|
||||
# Main SIP request routing logic
|
||||
request_route {
|
||||
|
||||
# per request initial checks
|
||||
route(REQINIT);
|
||||
|
||||
# NAT detection
|
||||
route(NATDETECT);
|
||||
|
||||
# CANCEL processing
|
||||
if (is_method("CANCEL")) {
|
||||
if (t_check_trans()) {
|
||||
route(RELAY);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
# handle requests within SIP dialogs
|
||||
route(WITHINDLG);
|
||||
|
||||
### only initial requests (no To tag)
|
||||
|
||||
# handle retransmissions
|
||||
if(t_precheck_trans()) {
|
||||
t_check_trans();
|
||||
exit;
|
||||
}
|
||||
t_check_trans();
|
||||
|
||||
# record routing for dialog forming requests (in case they are routed)
|
||||
# - remove preloaded route headers
|
||||
remove_hf("Route");
|
||||
if (is_method("INVITE|SUBSCRIBE"))
|
||||
record_route();
|
||||
|
||||
# Not handling requests towards external domains
|
||||
if uri != myself {
|
||||
sl_send_reply("604", "Only local destinations accepted");
|
||||
exit;
|
||||
}
|
||||
|
||||
### requests for my local domains
|
||||
|
||||
# SIMPLE AUTH methods
|
||||
if is_method("REGISTER|SUBSCRIBE|PUBLISH") {
|
||||
route(CGRATES_SIMPLEAUTH_REQUEST);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($rU==$null) {
|
||||
# request with no Username in RURI
|
||||
sl_send_reply("484","Address Incomplete");
|
||||
exit;
|
||||
}
|
||||
|
||||
if !is_method("INVITE") {
|
||||
sl_send_reply("503", "Unsupported method");
|
||||
exit;
|
||||
}
|
||||
|
||||
route(CGRATES_SESSIONAUTH_REQUEST);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
# Here will land requests after processing them with CGRateS.
|
||||
route[CGRATES_SIMPLEAUTH_REPLY] {
|
||||
if $var(cgrError) != "" {
|
||||
xlog("CGR_PROFILE_ERROR: $var(cgrError)");
|
||||
sl_send_reply("503","CGR_ERROR");
|
||||
exit;
|
||||
}
|
||||
|
||||
# parse the CGRateS attributes
|
||||
route(PARSE_CGRATES_ATTRIBUTES);
|
||||
|
||||
# password based auth
|
||||
route(AUTH);
|
||||
|
||||
if is_method("REGISTER") {
|
||||
route(REGISTRAR);
|
||||
exit;
|
||||
}
|
||||
|
||||
# other methods going over location
|
||||
route(LOCATION);
|
||||
route(RELAY);
|
||||
}
|
||||
|
||||
|
||||
# Here will land requests after processing them with CGRateS. Call RELAY or other routes following this route
|
||||
route[CGRATES_SESSIONAUTH_REPLY] {
|
||||
|
||||
if $var(cgrError) != "" {
|
||||
xlog("CGR_AUTH_ERROR: $var(cgrError)");
|
||||
sl_send_reply("503","CGR_ERROR");
|
||||
exit;
|
||||
}
|
||||
|
||||
# parse the CGRateS attributes
|
||||
route(PARSE_CGRATES_ATTRIBUTES);
|
||||
|
||||
# password based auth
|
||||
route(AUTH);
|
||||
|
||||
# track the dialog so we can set it's timeout and channel variables to store in CDRs
|
||||
# cannot initialize the dialog sooner due to AUTH
|
||||
dlg_manage();
|
||||
$dlg_var(SetupTime) = $TS;
|
||||
$dlg_var(cgrOriginID) = $dlg(callid) + ";" + $dlg(from_tag);
|
||||
$dlg_var(cgrTenant) = "cgrates.org";
|
||||
$dlg_var(cgrReqType) = $avp(RequestType);
|
||||
$dlg_var(cgrAccount) = $fU;
|
||||
$dlg_var(cgrDestination) = $rU;
|
||||
$dlg_var(paypalAccount) = $avp(PaypalAccount);
|
||||
|
||||
if $var(cgrMaxUsage) != -1 {
|
||||
if $var(cgrMaxUsage) == 0 { // Not enough balance, do not allow the call to go through
|
||||
sl_send_reply("403","Insufficient credit");
|
||||
exit;
|
||||
} else if !dlg_set_timeout("$var(cgrMaxUsage)") {
|
||||
sl_send_reply("503","CGR_MAX_USAGE_ERROR");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if $var(cgrSuppliers) != "" { # Enforce the supplier variable to the first one received from CGRateS, here more for demo purposes
|
||||
$dlg_var(cgrSupplier) = $(var(cgrSuppliers){s.select,0,,});
|
||||
}
|
||||
|
||||
# user location service
|
||||
route(LOCATION);
|
||||
|
||||
# send out
|
||||
route(RELAY);
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Wrapper for relaying requests
|
||||
route[RELAY] {
|
||||
# enable additional event routes for forwarded requests
|
||||
# - serial forking, RTP relaying handling, a.s.o.
|
||||
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
|
||||
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
|
||||
}
|
||||
if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
|
||||
if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
|
||||
}
|
||||
if (is_method("INVITE")) {
|
||||
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
|
||||
}
|
||||
|
||||
if (!t_relay()) {
|
||||
sl_reply_error();
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
# Per SIP request initial checks
|
||||
route[REQINIT] {
|
||||
if (!mf_process_maxfwd_header("10")) {
|
||||
sl_send_reply("483","Too Many Hops");
|
||||
exit;
|
||||
}
|
||||
|
||||
if(is_method("OPTIONS") && uri==myself && $rU==$null) {
|
||||
sl_send_reply("200","Keepalive");
|
||||
exit;
|
||||
}
|
||||
|
||||
if(!sanity_check("1511", "7")) {
|
||||
xlog("Malformed SIP message from $si:$sp\n");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
# Handle requests within SIP dialogs
|
||||
route[WITHINDLG] {
|
||||
if (!has_totag()) return;
|
||||
|
||||
# sequential request withing a dialog should
|
||||
# take the path determined by record-routing
|
||||
if (loose_route()) {
|
||||
route(DLGURI);
|
||||
if ( is_method("ACK") ) {
|
||||
# ACK is forwarded statelessy
|
||||
route(NATMANAGE);
|
||||
}
|
||||
else if ( is_method("NOTIFY") ) {
|
||||
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
|
||||
record_route();
|
||||
}
|
||||
route(RELAY);
|
||||
exit;
|
||||
}
|
||||
if ( is_method("ACK") ) {
|
||||
if ( t_check_trans() ) {
|
||||
# no loose-route, but stateful ACK;
|
||||
# must be an ACK after a 487
|
||||
# or e.g. 404 from upstream server
|
||||
route(RELAY);
|
||||
exit;
|
||||
} else {
|
||||
# ACK without matching transaction ... ignore and discard
|
||||
exit;
|
||||
}
|
||||
}
|
||||
sl_send_reply("404","Not here");
|
||||
exit;
|
||||
}
|
||||
|
||||
# Handle SIP registrations
|
||||
route[REGISTRAR] {
|
||||
if(isflagset(FLT_NATS)) {
|
||||
setbflag(FLB_NATB);
|
||||
}
|
||||
if (!save("location"))
|
||||
sl_reply_error();
|
||||
exit;
|
||||
}
|
||||
|
||||
# User location service
|
||||
route[LOCATION] {
|
||||
$avp(oexten) = $rU;
|
||||
if (!lookup("location")) {
|
||||
$var(rc) = $rc;
|
||||
t_newtran();
|
||||
switch ($var(rc)) {
|
||||
case -1:
|
||||
case -3:
|
||||
send_reply("404", "Not Found");
|
||||
exit;
|
||||
case -2:
|
||||
send_reply("405", "Method Not Allowed");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# user uthentication
|
||||
route[AUTH] {
|
||||
if (is_method("REGISTER")) {
|
||||
if ( strempty($au) || !pv_www_authenticate("$td", "$avp(Password)", "0") ) {
|
||||
www_challenge("$td", "0");
|
||||
exit;
|
||||
}
|
||||
} else { # All other methods here
|
||||
if ( strempty($au) || !pv_proxy_authenticate("$td", "$avp(Password)", "0") ) {
|
||||
proxy_challenge("$td", "0");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
consume_credentials();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# Caller NAT detection
|
||||
route[NATDETECT] {
|
||||
force_rport();
|
||||
if (nat_uac_test("19")) {
|
||||
if (is_method("REGISTER")) {
|
||||
fix_nated_register();
|
||||
} else {
|
||||
if(is_first_hop())
|
||||
set_contact_alias();
|
||||
}
|
||||
setflag(FLT_NATS);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# RTPProxy control and singaling updates for NAT traversal
|
||||
route[NATMANAGE] {
|
||||
if (is_request()) {
|
||||
if(has_totag()) {
|
||||
if(check_route_param("nat=yes")) {
|
||||
setbflag(FLB_NATB);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB)))
|
||||
return;
|
||||
|
||||
if (is_request()) {
|
||||
if (!has_totag()) {
|
||||
if(t_is_branch_route()) {
|
||||
add_rr_param(";nat=yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_reply()) {
|
||||
if(isbflagset(FLB_NATB)) {
|
||||
if(is_first_hop())
|
||||
set_contact_alias();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# URI update for dialog requests
|
||||
route[DLGURI] {
|
||||
if(!isdsturiset()) {
|
||||
handle_ruri_alias();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# Manage outgoing branches
|
||||
branch_route[MANAGE_BRANCH] {
|
||||
route(NATMANAGE);
|
||||
}
|
||||
|
||||
# Manage incoming replies
|
||||
onreply_route[MANAGE_REPLY] {
|
||||
if(status=~"[12][0-9][0-9]")
|
||||
route(NATMANAGE);
|
||||
}
|
||||
|
||||
# Manage failure routing cases
|
||||
failure_route[MANAGE_FAILURE] {
|
||||
route(NATMANAGE);
|
||||
|
||||
if (t_is_canceled()) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (t_check_status("3[0-9][0-9]")) {
|
||||
t_reply("404","Not found");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
139
data/tutorial_tests/osips/cgrates/etc/cgrates/cgrates.json
Normal file
139
data/tutorial_tests/osips/cgrates/etc/cgrates/cgrates.json
Normal file
@@ -0,0 +1,139 @@
|
||||
{
|
||||
|
||||
// Real-time Charging System for Telecom & ISP environments
|
||||
// Copyright (C) ITsysCOM GmbH
|
||||
//
|
||||
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080",
|
||||
},
|
||||
|
||||
|
||||
"stor_db": {
|
||||
"db_password": "CGRateS.org",
|
||||
},
|
||||
|
||||
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"cdrs": {
|
||||
"enabled": true,
|
||||
"stats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"chargers_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"sessions_cost_retries": 5,
|
||||
},
|
||||
|
||||
|
||||
"chargers": {
|
||||
"enabled": true,
|
||||
"attributes_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"sessions": {
|
||||
"enabled": true,
|
||||
"listen_bijson": "127.0.0.1:2014", // address where to listen for bidirectional JSON-RPC requests
|
||||
"chargers_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"rals_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"cdrs_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"suppliers_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"thresholds_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"debit_interval": "5s",
|
||||
"channel_sync_interval":"7s",
|
||||
},
|
||||
|
||||
|
||||
|
||||
"attributes": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"resources": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"string_indexed_fields": ["Account"],
|
||||
"prefix_indexed_fields": ["Destination"],
|
||||
},
|
||||
|
||||
|
||||
"stats": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"thresholds": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"],
|
||||
},
|
||||
|
||||
|
||||
"suppliers": {
|
||||
"enabled": true,
|
||||
"rals_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"string_indexed_fields": ["Account"],
|
||||
"prefix_indexed_fields": ["Destination"],
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
175
data/tutorial_tests/osips/cgrates/etc/init.d/cgrates
Executable file
175
data/tutorial_tests/osips/cgrates/etc/init.d/cgrates
Executable file
@@ -0,0 +1,175 @@
|
||||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: cgrates
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: CGRateS real-time charging system
|
||||
# Description: Control CGRateS - carrier grade real-time charging system
|
||||
### END INIT INFO
|
||||
|
||||
# Author: DanB <danb@cgrates.org>
|
||||
#
|
||||
# Do NOT "set -e"
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="CGRateS Online Charging System"
|
||||
NAME=cgrates
|
||||
DAEMON=/usr/bin/cgr-engine
|
||||
USER=cgrates
|
||||
GROUP=cgrates
|
||||
DAEMON_OPTS=""
|
||||
TUTFOLDER=/usr/share/cgrates/tutorial_tests/osips/$NAME
|
||||
TMP_DIR=/tmp/cgr_osipsnative/$NAME
|
||||
SCRIPTNAME=$TUTFOLDER/etc/init.d/$NAME
|
||||
RUNDIR=$TMP_DIR/run
|
||||
PIDFILE=$RUNDIR/cgr-engine.pid
|
||||
STACKTRACE=$RUNDIR/$NAME.strace
|
||||
ENABLE=true
|
||||
DAEMON_OPTS="-config_path=$TUTFOLDER/etc/cgrates"
|
||||
CDREDIR=$TMP_DIR/cdre
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
if [ "$ENABLE" != "true" ]; then
|
||||
echo "$DESC not yet configured. Edit $DEFAULTS first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Install the run folder
|
||||
if [ ! -d $RUNDIR ]; then
|
||||
mkdir -p $RUNDIR
|
||||
touch $STACKTRACE
|
||||
chown -R $USER:$GROUP $RUNDIR
|
||||
fi
|
||||
# Install the cdre folder
|
||||
if [ ! -d $CDREDIR ]; then
|
||||
mkdir -p $CDREDIR
|
||||
chown $USER:$GROUP $CDREDIR
|
||||
fi
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
echo "\n### Started at:" `date`>>$STACKTRACE
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test\
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --background\
|
||||
--startas /bin/bash -- -c "exec $DAEMON $DAEMON_OPTS >> $STACKTRACE 2>&1" \
|
||||
|| return 2
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
||||
27
data/tutorial_tests/osips/opensips/etc/default/opensips
Executable file
27
data/tutorial_tests/osips/opensips/etc/default/opensips
Executable file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# OpenSIPS startup options
|
||||
#
|
||||
|
||||
# Set to yes to enable opensips, once configured properly.
|
||||
RUN_OPENSIPS=yes
|
||||
|
||||
# User to run as
|
||||
USER=opensips
|
||||
|
||||
# Group to run as
|
||||
GROUP=opensips
|
||||
|
||||
# Amount of shared memory to allocate for the running OpenSIPS server (in Mb)
|
||||
S_MEMORY=64
|
||||
|
||||
# Amount of pkg memory to allocate for the running OpenSIPS server (in Mb)
|
||||
P_MEMORY=4
|
||||
|
||||
# Enable the server to leave a core file when it crashes.
|
||||
# Set this to 'yes' to enable OpenSIPS to leave a core file when it crashes
|
||||
# or 'no' to disable this feature. This option is case sensitive and only
|
||||
# accepts 'yes' and 'no' and only in lowercase letters.
|
||||
# On some systems (e.g. Ubuntu 6.10, Debian 4.0) it is necessary to specify
|
||||
# a directory for the core files to get a dump. Look into the opensips
|
||||
# init file for an example configuration.
|
||||
DUMP_CORE=no
|
||||
199
data/tutorial_tests/osips/opensips/etc/init.d/opensips
Executable file
199
data/tutorial_tests/osips/opensips/etc/init.d/opensips
Executable file
@@ -0,0 +1,199 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: opensips
|
||||
# Required-Start: $syslog $network $local_fs $time
|
||||
# Required-Stop: $syslog $network $local_fs
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start the OpenSIPS SIP server
|
||||
# Description: Start the OpenSIPS SIP server
|
||||
### END INIT INFO
|
||||
#
|
||||
# TODO:
|
||||
# The following fields should be added (and completed):
|
||||
# Should-Start: postgresql mysql radius
|
||||
# Should-Stop: postgresql mysql radius
|
||||
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
DAEMON=/usr/sbin/opensips
|
||||
NAME=opensips
|
||||
DESC=opensips
|
||||
TUTDIR=/usr/share/cgrates/tutorial_tests/osips/$NAME
|
||||
SCRIPTNAME=$TUTDIR/etc/init.d/$NAME
|
||||
TMP_DIR=/tmp/cgr_osipsnative/$NAME
|
||||
CFGFILE=$TUTDIR/etc/$NAME/opensips.cfg
|
||||
M4CFGFILE=/etc/opensips/opensips.m4
|
||||
M4ARCHIVEDIR=/etc/opensips/archive
|
||||
HOMEDIR=$TMP_DIR/run/opensips
|
||||
PIDFILE=$HOMEDIR/$NAME.pid
|
||||
DEFAULTS=$TUTDIR/etc/default/opensips
|
||||
RUN_OPENSIPS=no
|
||||
|
||||
if [ ! -d $HOMEDIR ]; then
|
||||
mkdir -p $HOMEDIR
|
||||
chown -R $USER:$GROUP $HOMEDIR
|
||||
fi
|
||||
|
||||
# Do not start opensips if fork=no is set in the config file
|
||||
# otherwise the boot process will just stop
|
||||
check_fork ()
|
||||
{
|
||||
if grep -q "^[[:space:]]*fork[[:space:]]*=[[:space:]]*no.*" $CFGFILE; then
|
||||
echo "Not starting $DESC: fork=no specified in config file; run /etc/init.d/opensips debug instead"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_opensips_config ()
|
||||
{
|
||||
# Check if opensips configuration is valid before starting the server
|
||||
set +e
|
||||
out=$($DAEMON -c 2>&1 > /dev/null)
|
||||
retcode=$?
|
||||
set -e
|
||||
if [ "$retcode" != '0' ]; then
|
||||
echo "Not starting $DESC: invalid configuration file!"
|
||||
echo -e "\n$out\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
create_radius_seqfile ()
|
||||
{
|
||||
# Create a radius sequence file to be used by the radius client if
|
||||
# radius accounting is enabled. This is needed to avoid any issue
|
||||
# with the file not being writable if opensips first starts as user
|
||||
# root because DUMP_CORE is enabled and creates this file as user
|
||||
# root and then later it switches back to user opensips and cannot
|
||||
# write to the file. If the file exists before opensips starts, it
|
||||
# won't change it's ownership and will be writable for both root
|
||||
# and opensips, no matter what options are chosen at install time
|
||||
RADIUS_SEQ_FILE=/var/run/opensips/opensips_radius.seq
|
||||
if [ -d /var/run/opensips ]; then
|
||||
chown ${USER}:${GROUP} /var/run/opensips
|
||||
|
||||
if [ ! -f $RADIUS_SEQ_FILE ]; then
|
||||
touch $RADIUS_SEQ_FILE
|
||||
fi
|
||||
|
||||
chown ${USER}:${GROUP} $RADIUS_SEQ_FILE
|
||||
chmod 660 $RADIUS_SEQ_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
test -f $DAEMON || exit 0
|
||||
|
||||
# Load startup options if available
|
||||
if [ -f $DEFAULTS ]; then
|
||||
. $DEFAULTS || true
|
||||
fi
|
||||
|
||||
if [ "$RUN_OPENSIPS" != "yes" ]; then
|
||||
echo "OpenSIPS not yet configured. Edit /etc/default/opensips first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
S_MEMORY=$((`echo $S_MEMORY | sed -e 's/[^0-9]//g'`))
|
||||
P_MEMORY=$((`echo $P_MEMORY | sed -e 's/[^0-9]//g'`))
|
||||
[ -z "$USER" ] && USER=opensips
|
||||
[ -z "$GROUP" ] && GROUP=opensips
|
||||
[ $S_MEMORY -le 0 ] && S_MEMORY=32
|
||||
[ $P_MEMORY -le 0 ] && P_MEMORY=32
|
||||
|
||||
if test "$DUMP_CORE" = "yes" ; then
|
||||
# set proper ulimit
|
||||
ulimit -c unlimited
|
||||
|
||||
# directory for the core dump files
|
||||
# COREDIR=/home/corefiles
|
||||
# [ -d $COREDIR ] || mkdir $COREDIR
|
||||
# chmod 777 $COREDIR
|
||||
# echo "$COREDIR/core.%e.sig%s.%p" > /proc/sys/kernel/core_pattern
|
||||
fi
|
||||
|
||||
OPTIONS="-f $CFGFILE -P $PIDFILE -m $S_MEMORY -M $P_MEMORY -u $USER -g $GROUP -w $HOMEDIR"
|
||||
|
||||
case "$1" in
|
||||
start|debug)
|
||||
check_opensips_config
|
||||
create_radius_seqfile
|
||||
|
||||
if [ "$1" != "debug" ]; then
|
||||
check_fork
|
||||
fi
|
||||
|
||||
# dirs under /var/run can go away on reboots.
|
||||
mkdir -p "$HOMEDIR"
|
||||
chmod 775 "$HOMEDIR"
|
||||
chown "$USER:$GROUP" "$HOMEDIR" >/dev/null 2>&1 || true
|
||||
|
||||
# Generate config from M4
|
||||
if [ -f $M4CFGFILE ]; then
|
||||
m4 -Q $M4CFGFILE >$CFGFILE.tmp
|
||||
if [ $? != 0 ]; then
|
||||
echo "Cannot process m4 macro"
|
||||
rm "$CFGFILE.tmp"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -e $CFGFILE ] || touch $CFGFILE
|
||||
|
||||
# compare configs
|
||||
if [ `md5sum $CFGFILE|awk '{print $1}'` != `md5sum $CFGFILE.tmp|awk '{print $1}'` ]; then
|
||||
mkdir -p "$M4ARCHIVEDIR"
|
||||
mv "$CFGFILE" "$M4ARCHIVEDIR/$NAME.cfg-`date +%Y%m%d_%H%M%S`"
|
||||
fi
|
||||
|
||||
mv "$CFGFILE.tmp" "$CFGFILE"
|
||||
chown $USER:$GROUP $CFGFILE
|
||||
chmod 640 $CFGFILE
|
||||
fi
|
||||
|
||||
echo -n "Starting $DESC: $NAME"
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE \
|
||||
--exec $DAEMON -- $OPTIONS || echo -n " already running"
|
||||
echo "."
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping $DESC: $NAME"
|
||||
start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE \
|
||||
--exec $DAEMON
|
||||
echo "."
|
||||
;;
|
||||
restart|force-reload)
|
||||
check_opensips_config
|
||||
create_radius_seqfile
|
||||
|
||||
echo -n "Restarting $DESC: $NAME"
|
||||
start-stop-daemon --oknodo --stop --quiet --pidfile \
|
||||
$PIDFILE --exec $DAEMON
|
||||
sleep 1
|
||||
start-stop-daemon --start --quiet --pidfile \
|
||||
$PIDFILE --exec $DAEMON -- $OPTIONS
|
||||
echo "."
|
||||
;;
|
||||
status)
|
||||
echo -n "Status of $DESC: "
|
||||
if [ ! -r "$PIDFILE" ]; then
|
||||
echo "$NAME is not running."
|
||||
exit 3
|
||||
fi
|
||||
if read pid < "$PIDFILE" && ps -p "$pid" > /dev/null 2>&1; then
|
||||
echo "$NAME is running."
|
||||
exit 0
|
||||
else
|
||||
echo "$NAME is not running but $PIDFILE exists."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
N=/etc/init.d/$NAME
|
||||
echo "Usage: $N {start|stop|restart|force-reload|debug|status}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
269
data/tutorial_tests/osips/opensips/etc/opensips/opensips.cfg
Normal file
269
data/tutorial_tests/osips/opensips/etc/opensips/opensips.cfg
Normal file
@@ -0,0 +1,269 @@
|
||||
#
|
||||
# OpenSIPS residential configuration script
|
||||
# by OpenSIPS Solutions <team@opensips-solutions.com>
|
||||
#
|
||||
# This script was generated via "make menuconfig", from
|
||||
# the "Residential" scenario.
|
||||
# You can enable / disable more features / functionalities by
|
||||
# re-generating the scenario with different options.#
|
||||
#
|
||||
# Please refer to the Core CookBook at:
|
||||
# http://www.opensips.org/Resources/DocsCookbooks
|
||||
# for a explanation of possible statements, functions and parameters.
|
||||
#
|
||||
|
||||
|
||||
####### Global Parameters #########
|
||||
|
||||
log_level=3
|
||||
log_stderror=no
|
||||
log_facility=LOG_LOCAL0
|
||||
|
||||
udp_workers=4
|
||||
|
||||
auto_aliases=no
|
||||
|
||||
listen=udp:enp0s3:5060
|
||||
listen=udp:127.0.0.1:5080
|
||||
listen=udp:127.0.0.1:5060
|
||||
listen=udp:enp0s3:5080
|
||||
|
||||
|
||||
|
||||
####### 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"
|
||||
|
||||
#### FIFO Management Interface
|
||||
loadmodule "mi_fifo.so"
|
||||
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
|
||||
modparam("mi_fifo", "fifo_mode", 0666)
|
||||
|
||||
#### USeR LOCation module
|
||||
loadmodule "usrloc.so"
|
||||
modparam("usrloc", "nat_bflag", "NAT")
|
||||
modparam("usrloc", "db_mode", 0)
|
||||
|
||||
#### REGISTRAR module
|
||||
loadmodule "registrar.so"
|
||||
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
|
||||
|
||||
#### ACCounting module
|
||||
loadmodule "acc.so"
|
||||
modparam("acc", "early_media", 0)
|
||||
modparam("acc", "report_cancels", 0)
|
||||
modparam("acc", "detect_direction", 0)
|
||||
|
||||
loadmodule "proto_udp.so"
|
||||
|
||||
|
||||
#### CGRateS module
|
||||
loadmodule "dialog.so"
|
||||
loadmodule "cgrates.so"
|
||||
modparam("cgrates", "cgrates_engine", "127.0.0.1:2014")
|
||||
|
||||
|
||||
####### Routing Logic ########
|
||||
|
||||
# main request routing logic
|
||||
|
||||
route{
|
||||
|
||||
if (!mf_process_maxfwd_header(10)) {
|
||||
send_reply(483,"Too Many Hops");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (has_totag()) {
|
||||
|
||||
# handle hop-by-hop ACK (no routing required)
|
||||
if ( is_method("ACK") && t_check_trans() ) {
|
||||
t_relay();
|
||||
exit;
|
||||
}
|
||||
|
||||
# sequential request within a dialog should
|
||||
# take the path determined by record-routing
|
||||
if ( !loose_route() ) {
|
||||
# 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;
|
||||
}
|
||||
|
||||
if (is_method("BYE")) {
|
||||
# do accounting even if the transaction fails
|
||||
do_accounting("log","failed");
|
||||
}
|
||||
|
||||
# route it out to whatever destination was set by loose_route()
|
||||
# in $du (destination URI).
|
||||
route(relay);
|
||||
exit;
|
||||
}
|
||||
|
||||
# CANCEL processing
|
||||
if (is_method("CANCEL")) {
|
||||
if (t_check_trans())
|
||||
t_relay();
|
||||
exit;
|
||||
}
|
||||
|
||||
# absorb retransmissions, but do not create transaction
|
||||
t_check_trans();
|
||||
|
||||
if ( !(is_method("REGISTER") ) ) {
|
||||
|
||||
if (is_myself("$fd")) {
|
||||
|
||||
} else {
|
||||
# if caller is not local, then called number must be local
|
||||
|
||||
if (!is_myself("$rd")) {
|
||||
send_reply(403,"Relay Forbidden");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# 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();
|
||||
|
||||
if (!is_myself("$rd")) {
|
||||
append_hf("P-hint: outbound\r\n");
|
||||
|
||||
route(relay);
|
||||
}
|
||||
|
||||
# requests for my domain
|
||||
|
||||
if (is_method("PUBLISH|SUBSCRIBE")) {
|
||||
send_reply(503, "Service Unavailable");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (is_method("REGISTER")) {
|
||||
|
||||
if (!save("location"))
|
||||
sl_reply_error();
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($rU==NULL) {
|
||||
# request with no Username in RURI
|
||||
send_reply(484,"Address Incomplete");
|
||||
exit;
|
||||
}
|
||||
|
||||
# do lookup with method filtering
|
||||
if (!lookup("location","m")) {
|
||||
t_reply(404, "Not Found");
|
||||
exit;
|
||||
}
|
||||
|
||||
# check auth with CGRateS
|
||||
$cgr_opt(GetMaxUsage) = 1; # also retrieve the max usage
|
||||
$cgr_opt(GetAttributes) = 1;
|
||||
$cgr_opt(GetSuppliers) = 1;
|
||||
$cgr_opt(AuthorizeResources) = 1;
|
||||
$cgr_opt(AllocateResources) = 1;
|
||||
$cgr_opt(ReleaseResources) = 1;
|
||||
$cgr_opt(ProcessThresholds) = 1;
|
||||
$cgr_opt(ProcessStatQueues) = 1;
|
||||
$cgr(RequestType) = "*prepaid";
|
||||
$cgr(OriginHost) = "127.0.0.1";
|
||||
$cgr(Source) = "OpenSIPS";
|
||||
|
||||
if (!async(cgrates_auth("$fU", "$rU"), resume_cgr_auth)) {
|
||||
sl_send_reply(503, "Service Unavailable");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
route [resume_cgr_auth] {
|
||||
if ($rc != 1) {
|
||||
xlog("Call not authorized: code=$cgrret!\n");
|
||||
send_reply(403, "Forbidden");
|
||||
exit;
|
||||
}
|
||||
$var(idx) = 0;
|
||||
while ($(cgr_ret(AttributesDigest){s.select,$var(idx),,}) != NULL) {
|
||||
$avp($(cgr_ret(AttributesDigest){s.select,$var(idx),,}{s.select,0,:}))
|
||||
= $(cgr_ret(AttributesDigest){s.select,$var(idx),,}{s.select,1,:});
|
||||
$var(idx) = $var(idx) + 1;
|
||||
}
|
||||
cgrates_acc("cdr|missed", "$fU", "$rU");
|
||||
xlog("### Have authorized the call and it should go through");
|
||||
route(relay);
|
||||
}
|
||||
|
||||
|
||||
route[relay] {
|
||||
# for INVITEs enable some additional helper routes
|
||||
if (is_method("INVITE")) {
|
||||
t_on_branch("per_branch_ops");
|
||||
t_on_reply("handle_nat");
|
||||
t_on_failure("missed_call");
|
||||
}
|
||||
|
||||
if (!t_relay()) {
|
||||
send_reply(500,"Internal Error");
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
branch_route[per_branch_ops] {
|
||||
xlog("new branch at $ru\n");
|
||||
}
|
||||
|
||||
|
||||
onreply_route[handle_nat] {
|
||||
xlog("incoming reply\n");
|
||||
}
|
||||
|
||||
|
||||
failure_route[missed_call] {
|
||||
if (t_was_cancelled()) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user