Re: send_reply not accepting values
Henning Westerholt via sr-users <[email protected]>
| Newsgroups | gmane.comp.voip.ser |
|---|---|
| Message-ID | <AS8PR07MB8103B1DA1C6881DCC0ADFD85BF09A@AS8PR07MB8103.eurprd07.prod.outlook.com> |
Thanks for reporting back, great that its solved. Cheers, Henning From: Sergio Charrua <[email protected]> Sent: Thursday, September 11, 2025 3:24 PM To: Henning Westerholt <[email protected]> Cc: Kamailio (SER) - Users Mailing List <[email protected]> Subject: Re: [SR-Users] send_reply not accepting values Found the issue! for future reference, after every evapi_{async}_relay() call, there should be an exit(). In the route[NOTIFY_CALL_REJECT] block, after the evapi_async_relay call, I added an exit(); and it worked ! Solved both issues I was getting! Atenciosamente / Kind Regards / Cordialement / Un saludo, Sérgio Charrua On Thu, Sep 11, 2025 at 1:00 PM Sergio Charrua <[email protected]<mailto:[email protected]>> wrote: Hi Henning, Below is part of the Kamailio script that i'm developing. I've run with debug level 3, but there is nothing helpful found on log. There are 2 issues which i cannot get a solution, so far: 1 - after a 1st call to EVAPI script where the list of routes are returned (RTJson object), the transaction continues fine. When the INVITE cannot be relayed to the egress endpoint (because it is off-line) there is the obvious 408 Session Timeout error, the route[NOTIFY_CALL_REJECT] is executed calling EVAPI script and when event_route[evapi:message-received] is executed apparently the t_continue() fails because there is no transaction available! I have tested multiple ways, with t_new_trans + evapi_relay(), just evapi_realy() or evapi_async_relay but in the NOTIFY_CALL_REJECT block, but always get the same error 2 - that nasty 503 - Service Unavailable error which, IMHO, doesn't make sense. Greatly appreciate the help. These are parts of the logs that are generated, with debug level 3: Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587920.971352 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: EVAPIRESPONSE - Resumed with JSON: {"action": "ROUTE", "call_id": "my_call_id", "error_code": 0, "error_text": "", "retry_on_failure": "0", "rtjson": {"routes": [{"branch_flags": 8, "default_timeout": 10, "dst_uri": "sip:10.20.0.6:5060<http://10.20.0.6:5060>", "headers": {"extra": "X-Hdr-A: abc\r\n", "from": {"display": "Alice", "uri": "sip:[email protected]@10.20.0.5<http://10.20.0.5>"}, "to": {"display": "Bob", "uri": "sip:[email protected]<mailto:sip%[email protected]>"}}, "route_id": "123", "socket": "udp:10.20.0.4:5060<http://10.20.0.4:5060>", "uri": "sip:[email protected]@10.20.0.5<http://10.20.0.5>"}, {"branch_flags": 8, "default_timeout": 10, "dst_uri": "sip:10.20.0.7:5060<http://10.20.0.7:5060>", "headers": {"extra": "P-Asserted-Identity: sip:+12122478000;[email protected]:5060<http://[email protected]:5060>\r\nIdentity: eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly9wcm9kMDAxLXByb2QwMTEtY3IucmJibmlkaHViLmNvbS9DbWJ5aVlISWd6L3Rlc3RucHJvZHB1YmxpYyJ9.eyJhdHRlc3QiOiJDIiwiZGVzdCI6eyJ0biI6WyIxMjAyMzI0MzAwMCJdfSwiaWF0IjoxNzEwMzk1NjAwLCJvcmlnIjp7InRuIjoiMTIxMjM0NzgwMzQifSwib3JpZ2lkIjoiYmFkYTM4OWYtOWM3MS00NWE2LThlNzgtODRjNDgwZjJlNjk5In0.xCMtauutY5K1kyS5htnXohjRSYluEFs_YIjURmTxhzifGaLDfF5pYgL_vt6jIiwvghBbL3V0Cw2UcPb-YMl8Tg;info=<https://prod001-prod011-cr.rbbnidhub.com/CmbyiYHIgz/testnprodpublic>;alg=ES256;ppt=shaken\r\n", "from": {"display": "Mary", "uri": "sip:[email protected]@10.20.0.5<http://10.20.0.5>"}, "to": {"display": "Dave", "uri": "sip:[email protected]<mailto:sip%[email protected]>"}}, "path": "", "route_id": "456", "socket": "udp:10.20.0.4:5060<http://10.20.0.4:5060>", "uri": ""}], "routing": "serial", "success": "True", "version": "1.0"}} Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587920.971782 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: EVAPIRESPONSE - retry_on_failure = 0 Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587920.971860 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: RTJSON_PROCESS - Initializing RTJSON routes Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587920.972103 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: RELAY - Modifying SIP headers from INVITE Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: ERROR: {1757587920.972120 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} app_jsdt [app_jsdt_mod.c:332]: w_app_jsdt_run(): p1 too long 1319 Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: ERROR: {1757587920.972210 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} pv [pv_core.c:261]: pv_get_ruri(): failed to parse the R-URI Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587920.972651 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: MANAGE_BRANCH - {"routes":[{"branch_flags":8,"default_timeout":10,"dst_uri":"sip:10.20.0.6:5060<http://10.20.0.6:5060>","headers":{"extra":"X-Hdr-A: abc\r\n","from":{"display":"Alice","uri" Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587920.972697 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: MANAGE_BRANCH - using new route index 0 Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: ERROR: {1757587920.972835 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} pv [pv_core.c:261]: pv_get_ruri(): failed to parse the R-URI Sep 11 12:52:00 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587920.972835 567385 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: MANAGE_BRANCH - New branch [1] to <null> - route ID 123 Sep 11 12:52:03 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587923.201293 567378 1 1 OPTIONS 123} <script>: Destination down: OPTIONS sip:10.20.0.7:5060<http://10.20.0.7:5060> (<null>) Sep 11 12:52:03 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587923.201722 567378 1 1 OPTIONS 123} <script>: NOTIFY_ENDPOINT_STATUS - notifying XPhere with SBC_STATUS:{"type":"SBC_STATUS","endpoint":"sip:10.20.0.7:5060<http://10.20.0.7:5060>","sip_code":0,"reason":"DOWN","timestamp":"1757587923.201674"} Sep 11 12:52:03 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587923.201827 567378 1 1 OPTIONS 123} <script>: Destination down: OPTIONS sip:10.20.0.6:5060<http://10.20.0.6:5060> (<null>) Sep 11 12:52:03 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587923.202010 567378 1 1 OPTIONS 123} <script>: NOTIFY_ENDPOINT_STATUS - notifying XPhere with SBC_STATUS:{"type":"SBC_STATUS","endpoint":"sip:10.20.0.6:5060<http://10.20.0.6:5060>","sip_code":0,"reason":"DOWN","timestamp":"1757587923.201975"} Sep 11 12:52:05 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587925.951168 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: SPOOL_CALL_STATUS - spooling CALL_STATUS SBC_STATUS:{"type":"SBC_STATUS","endpoint":"sip:10.20.0.6:5060<http://10.20.0.6:5060>","sip_code":0,"reason":"DOWN","timestamp":"1757587923.201975"} Sep 11 12:52:05 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587925.951877 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: MANAGE_FAILURE - next RTJson route selected - relaying call - retry_on_failure = 0 route_index=1 Sep 11 12:52:05 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587925.951944 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: RELAY - Modifying SIP headers from INVITE Sep 11 12:52:05 ire-lab-kamailio1 kamailio[567378]: ERROR: {1757587925.951951 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} app_jsdt [app_jsdt_mod.c:332]: w_app_jsdt_run(): p1 too long 1319 Sep 11 12:52:05 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587925.952251 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: MANAGE_BRANCH - {"routes":[{"branch_flags":8,"default_timeout":10,"dst_uri":"sip:10.20.0.6:5060<http://10.20.0.6:5060>","headers":{"extra":"X-Hdr-A: abc\r\n","from":{"display":"Alice","uri" Sep 11 12:52:05 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587925.952311 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: MANAGE_BRANCH - using new route index 1 Sep 11 12:52:05 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587925.952425 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: MANAGE_BRANCH - New branch [2] to sip:[email protected]<mailto:sip%[email protected]> - route ID 456 Sep 11 12:52:10 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587930.951206 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: SPOOL_CALL_STATUS - spooling CALL_STATUS SBC_STATUS:{"type":"SBC_STATUS","endpoint":"sip:10.20.0.6:5060<http://10.20.0.6:5060>","sip_code":0,"reason":"DOWN","timestamp":"1757587923.201975"} Sep 11 12:52:10 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587930.951665 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: MANAGE_FAILURE - retry_on_failure = 0 Sep 11 12:52:10 ire-lab-kamailio1 kamailio[567378]: ERROR: {1757587930.951721 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: MANAGE_FAILURE - no more routes available for RTJson Sep 11 12:52:10 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587930.952238 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: NOTIFY_CALL_REJECT - notifying XPhere with CALL_REJECT:54929:139397316:{"type":"CALL_REJECT","remote_ip_port":"10.20.0.5:5060<http://10.20.0.5:5060>","local_ip_port":"10.20.0.4:5060<http://10.20.0.4:5060>","protocol":"udp","sip_error":{"error_code":"408","error_text":"Request Timeout","from":"\"Anonymous\" <sip:[email protected]>;tag=as54ab6b37","to":"<sip:[email protected]<mailto:sip%[email protected]>>","call_id":"[email protected]:5060<http://[email protected]:5060>"},"crankback_history":[{"route_id":"123","error_code":408,"reason":"Request Timeout"},{"route_id":"456","error_code":408,"reason":"Request Timeout"}],"timestamp":"1757587930.952136"} Sep 11 12:52:10 ire-lab-kamailio1 kamailio[567378]: NOTICE: {1757587930.952260 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} tm [tm.c:1735]: w_t_newtran(): transaction already in process 0x7f4622dccf30 Sep 11 12:52:10 ire-lab-kamailio1 kamailio[567378]: INFO: {1757587930.952368 567378 1 102 INVITE [email protected]:5060<http://[email protected]:5060>} <script>: NOTIFY_CALL_REJECT - CALL_REJECT:54929:139397316:{"type":"CALL_REJECT","remote_ip_port":"10.20.0.5:5060<http://10.20.0.5:5060>","local_ip_port":"10.20.0.4:5060<http://10.20.0.4:5060>","protocol":"udp","sip_error":{"error_code":"408","error_text":"Request Timeout","from":"\"Anonymous\" <sip:[email protected]>;tag=as54ab6b37","to":"<sip:[email protected]<mailto:sip%[email protected]>>","call_id":"[email protected]:5060<http://[email protected]:5060>"},"crankback_history":[{"route_id":"123","error_code":408,"reason":"Request Timeout"},{"route_id":"456","error_code":408,"reason":"Request Timeout"}],"timestamp":"1757587930.952136"} Sep 11 12:52:11 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587931.484662 567385 1 1 OPTIONS 123} <script>: evapi:message-received - Received EVAPI message: RESPONSE:54929:139397316:{"action": "CALL_REJECT", "call_id": "[email protected]:5060<http://[email protected]:5060>", "reject": {"error_code": 480, "error_text": "some text"}} Sep 11 12:52:11 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587931.484727 567385 1 1 OPTIONS 123} <script>: Part 0: 'RESPONSE' Sep 11 12:52:11 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587931.484733 567385 1 1 OPTIONS 123} <script>: Part 1: '54929' Sep 11 12:52:11 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587931.484739 567385 1 1 OPTIONS 123} <script>: Part 2: '139397316' Sep 11 12:52:11 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587931.484743 567385 1 1 OPTIONS 123} <script>: Part 3: '{"action": "CALL_REJECT", "call_id": "[email protected]:5060<http://[email protected]:5060>", "reject": {"error_code": 480, "error_text": "some text"}}' Sep 11 12:52:11 ire-lab-kamailio1 kamailio[567385]: INFO: {1757587931.484768 567385 1 1 OPTIONS 123} <script>: evapi:message-received - t_continue for 54929/139397316 Sep 11 12:52:11 ire-lab-kamailio1 kamailio[567385]: WARNING: {1757587931.484775 567385 1 1 OPTIONS 123} tm [t_suspend.c:197]: t_continue_helper(): active transaction not found Sep 11 12:52:11 ire-lab-kamailio1 kamailio[567385]: WARNING: {1757587931.484775 567385 1 1 OPTIONS 123} tmx [tmx_mod.c:818]: w_t_continue(): resuming the processing of transaction [54929:139397316] failed Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: tm [timer.c:642]: wait_handler(): finished transaction: 0x7f4622dc3da0 (p:0x7f4622bc7700/n:0x7f4622bc7700) Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: tm [h_table.c:133]: free_cell_helper(): freeing transaction 0x7f4622dc3da0 from timer.c:651 Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: tm [timer.c:642]: wait_handler(): finished transaction: 0x7f4622dc61e0 (p:0x7f4622bc76a0/n:0x7f4622bc76a0) Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: tm [h_table.c:133]: free_cell_helper(): freeing transaction 0x7f4622dc61e0 from timer.c:651 Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: dialog [dlg_cseq.c:116]: dlg_cseq_prepare_new_msg(): prepare new msg for cseq update operations Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: <core> [core/parser/parse_fline.c:247]: parse_first_line(): first line type 1 (request) flags 1 Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: <core> [core/parser/msg_parser.c:721]: parse_msg(): SIP Request: Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: <core> [core/parser/msg_parser.c:722]: parse_msg(): method: <OPTIONS> Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: <core> [core/parser/msg_parser.c:724]: parse_msg(): uri: <sip:10.20.0.7:5060<http://10.20.0.7:5060>> Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: <core> [core/parser/msg_parser.c:726]: parse_msg(): version: <SIP/2.0> Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: <core> [core/parser/parse_hname2.c:314]: parse_sip_header_name(): parsed header name [Via] type 1 Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: <core> [core/parser/parse_via.c:1309]: parse_via_param(): Found param type 232, <branch> = <z9hG4bK379b.1343f1a4000000000000000000000000.0>; state=16 Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: <core> [core/parser/parse_via.c:2663]: parse_via(): end of header reached, state=5 Sep 11 12:52:17 ire-lab-kamailio1 kamailio[567379]: DEBUG: <core> [core/parser/msg_parser.c:591]: parse_headers(): Via found, flags=2 And the Kamailio script: #!KAMAILIO #!define FLT_ACC 1 #!define FLT_ACCMISSED 2 #!define FLT_ACCFAILED 3 #!define WITH_ACL #!define WITH_MONITORING ##!define WITH_DMQ # uncomment if DMQ is needed ####### Global Parameters ######### debug=3 log_stderror=no memdbg=5 memlog=5 log_facility=LOG_LOCAL0 fork=yes children=2 log_prefix_mode = 1 log_prefix="{$TV(Sn) $pp $mt $hdr(CSeq) $ci} " disable_sctp = yes force_rport = yes rundir="/tmp" pv_buffer_size=65536 ####### Modules Section ######## mpath="/usr/local/lib64/kamailio/modules/" loadmodule "jsonrpcs.so" loadmodule "db_mysql.so" loadmodule "db_cluster.so" 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 "ctl.so" loadmodule "cfg_rpc.so" loadmodule "acc.so" loadmodule "evapi.so" loadmodule "jansson.so" loadmodule "rtjson.so" loadmodule "dispatcher.so" loadmodule "dialog.so" loadmodule "permissions" loadmodule "app_jsdt.so" #!ifdef WITH_DMQ loadmodule "dmq.so" #!endif loadmodule "htable.so" include_file "listen.cfg" include_file "db_conn.cfg" ####### Setting module-specific parameters ####### # ----- Permissions params ----- modparam("permissions", "db_url", "cluster://k1") modparam("permissions", "db_mode", 1) modparam("permissions", "reload_delta", 10) # ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_ire1_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_ire1_rpc.sock") # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ire1_ctl") # ----- ctl params ----- /* set the path to RPC unix socket control file */ modparam("ctl", "binrpc", "unix:/tmp/kamailio_ire1_ctl") # ----- tm params ----- modparam("tm", "auto_inv_100", 1) # automatically send a 100 reply to INVITEs (0 is off). modparam("tm", "max_inv_lifetime", 180000) # Maximum time an INVITE transaction is allowed to be active (in milliseconds). modparam("tm", "failure_reply_mode", 3) # all previous branches are discarded if there is a new serial forking leg. This is the default behaviour modparam("tm", "fr_timer", 5000) # Timer which hits if no final reply for a request or ACK for a negative INVITE reply arrives (in milliseconds). #modparam("tm", "fr_inv_timer", 30000) # Timer which hits if no final reply for an INVITE arrives after a provisional message was received (in milliseconds). #modparam("tm", "restart_fr_on_each_reply", 1) # if 1, fr_inv_timer for an INVITE transaction will be restarted for each provisional reply received (rfc3261 mandated behaviour). # if 0, he fr_inv_timer will be restarted only for the first provisional replies and for increasing replies greater or equal 180 modparam("tm", "retr_timer1", 1000) # Initial modparam("tm", "cancel_b_method", 2) # used when attempting to CANCEL an unreplied transaction branch (a branch where no response was received). The possible values are 0, 1, and 2. # ----- rr params ----- modparam("rr", "enable_full_lr", 1) modparam("rr", "append_fromtag", 1) modparam("rr", "enable_double_rr", 0) # ----- evapi params ----- modparam("evapi", "workers", 4) modparam("evapi", "bind_addr", "10.20.0.4:8448<http://10.20.0.4:8448>") modparam("evapi", "netstring_format", 1) # ----- dmq params ----- #!ifdef WITH_DMQ modparam("dmq", "server_address", DMQ_SERVER_ADDRESS ) modparam("dmq", "notification_address", DMQ_NOTIFICATION_ADDRESS_1 ) # repeat previous line according to number of notification addresses of your environment modparam("dmq", "multi_notify", 0) modparam("dmq", "num_workers", 6) modparam("dmq", "ping_interval", 60) #modparam("dmq_usrloc", "enable", 1) #!endif # ----- dialog params ----- # Optimized for high CPS modparam("dialog", "db_mode", 1) modparam("dialog", "db_url", "cluster://k1") modparam("dialog", "dlg_flag", 4) modparam("dialog", "track_cseq_updates", 1) modparam("dialog", "dlg_match_mode", 1) modparam("dialog", "default_timeout", 43200) // 12hours call duration limit by default modparam("dialog", "profiles_with_value", "concurrent") modparam("dialog", "profiles_no_value", "total") modparam("dialog", "hash_size", 16384) # Increased for 4000+ CPS #!ifdef WITH_DMQ modparam("dialog", "enable_dmq", 1) #!endif # ----- dispatcher params ----- #!ifdef WITH_MONITORING modparam("dispatcher", "db_url", "cluster://k1") # Use DBURL variable for database parameters modparam("dispatcher", "ds_ping_interval", 3) # How often to ping destinations to check status modparam("dispatcher", "ds_ping_method", "OPTIONS") # Send SIP Options ping modparam("dispatcher", "ds_ping_from", "sip:[email protected]") modparam("dispatcher", "ds_probing_threshold", 3) # How many failed pings in a row do we need before we consider it down modparam("dispatcher", "ds_inactive_threshold", 2) # How many sucessful pings in a row do we need before considering it up modparam("dispatcher", "ds_ping_latency_stats", 1) # Enables stats on latency modparam("dispatcher", "ds_probing_mode", 1) # Keeps pinging gateways when state is known (to detect change in state) modparam("dispatcher", "ds_ping_latency_stats", 1) # for algorithm 13 - Latency check modparam("dispatcher", "ds_latency_estimator_alpha", 200) # configure latency estimator modparam("dispatcher", "reload_delta", 5) # number of seconds to wait before a new reload of dispatcher records is executed. default is 5 modparam("dispatcher", "flags", 2) # Enable database storage of flags #!endif # ----- app_jsdt params ----- modparam("app_jsdt", "load", "/etc/kamailio/functions.js") # ----- rtjson params ----- modparam("rtjson", "xavp_cfg", "rtjson") # ----- htable definition for evapi_event message response processing modparam("htable", "db_url", "cluster://k1") modparam("htable", "htable", "evcache=>size=64;autoexpire=120;dbmode=1;") ####### Routing Logic ######## # Main SIP request routing logic request_route { $avp(START_TIME)=$utimef(%Y-%m-%d %H:%M:%S); $var(send_sock) = $null; #!ifdef WITH_ACL $avp(GROUPID) = allow_address_group($si, $sp); if ( $avp(GROUPID) == 100 || !allow_address_group($si, $sp) ) { xlog("L_INFO", "INIT - $si:$sp is not in the allowed ACL Group ID !\n"); # uncoment below to return SIP 401 error to non-allowed clients #sl_reply("401", "Address not allowed"); exit; } if (is_method("OPTIONS")){ sl_send_reply("200","OK"); exit; } #!endif #!ifdef WITH_DMQ route(HANDLE_DMQ); #!endif # per request initial checks route(REQINIT); # CANCEL processing if (is_method("CANCEL")) { if (t_check_trans()) { xlog("L_INFO","INIT - CANCEL detected\n"); route(SEND_CALL_STATUS); t_relay(); } exit; } # handle retransmissions if (!is_method("ACK")) { if(t_precheck_trans()) { t_check_trans(); exit; } t_check_trans(); } # handle requests within SIP dialogs route(WITHINDLG); # record routing for dialog forming requests (in case they are routed) # - remove preloaded route headers remove_hf("Route"); if (is_method("INVITE")) record_route(); # record routing for dialog forming requests if (is_method("INVITE")) { $var(json_headers) = $null; $var(route_index) = 0; $var(retry) = 0; setflag(1); # Using the same flag as dlg_flag from dialog module $dlg_var(routeid) = $null; $dlg_var(branch_stats) = '[]'; # empty JSON array for keeping track of route status (failures) dlg_manage(); route(HANDLE_INVITE); exit; } route(RELAY); exit; } # Handle INVITE requests route[HANDLE_INVITE] { # Send INVITE details to Python script # Convert headers to JSON //if ($var(s:json_headers) == $null) route(HEADERS_TO_JSON); # Send to Python via EVAPI xlog("L_INFO", "HANDLE_INVITE - suspended transaction for INVITE. Index: $T(id_index) - Label: $T(id_label) \n" ); $var(evmsg) = "INVITE:" + $T(id_index) + ":" + $T(id_label) + ":" + $var(json_headers); evapi_async_relay("INVITE:$T(id_index):$T(id_label):$var(json_headers)"); exit; } # Handle responses from Python script event_route[evapi:message-received] { # Parse the message format: RESPONSE:index:label:data $var(msg) = $evapi(msg); #$var(logmsg) = $(var(msg){s.substr,0,100}); xlog("L_INFO", "evapi:message-received - Received EVAPI message: $var(msg) ...\n"); $var(type) = $(var(msg){s.select,0,:}); $var(tindex) = $(var(msg){s.select,1,:}{s.int<http://s.int>}); $var(tlabel) = $(var(msg){s.select,2,:}{s.int<http://s.int>}); $var(response) = $(var(msg){re.subst,/^[^:]*:[^:]*:[^:]*://}); xlog("L_INFO", "Part 0: '$var(type)'\n"); xlog("L_INFO", "Part 1: '$var(tindex)'\n"); xlog("L_INFO", "Part 2: '$var(tlabel)'\n"); xlog("L_INFO", "Part 3: '$var(response)'\n"); if ( $var(type) == "RESPONSE" && $var(tindex) =~ "^[0-9]+$" && $var(tlabel) =~ "^[0-9]+$" ) { xlog("L_INFO", "evapi:message-received - t_continue for $var(tindex)/$var(tlabel)\n"); t_continue("$var(tindex)", "$var(tlabel)", "EVAPIRESPONSE"); } else { xlog("L_INFO", "evapi:message-received - invalid message received from EVAPI. Cancelling the call \n"); t_reply("500", "Internal Server Error"); exit; } } # Resume processing after Python response route[EVAPIRESPONSE] { xlog("L_INFO", "EVAPIRESPONSE - Resuming Call processing with index $var(tindex) label $var(tlabel)\n"); xlog("L_INFO", "EVAPIRESPONSE - JSON : $var(response) \n"); # Test each condition individually if ($var(response) == "FALSE" or $var(response) == "NO_ROUTES") { # Check if response is FALSE (drop the call) xlog("L_ERR", "EVAPIRESPONSE - Python script returned FALSE or NO ROUTES, dropping call\n"); //t_reply("500", "Internal Server Error"); $var(code) = 500; $var(text) = "Internal Server Error"; route(REPLY_SAFE); exit; } if (jansson_get("action", $var(response), "$var(action)")){ if ($var(action) == "DROP") { jansson_get("error_code", $var(response), "$var(error_code)"); jansson_get("error_text", $var(response), "$var(error_text)"); xlog("L_INFO", "EVAPIRESPONSE - dropping call with returned error $var(error_code) - $var(error_text) \n"); $var(code) = $var(error_code); $var(text) = $var(error_text); route(REPLY_SAFE); exit; }else if ($var(action) == "CALL_REJECT") { jansson_get("reject", $var(response), "$var(sip_error)"); if ( "$var(sip_error)" == "" ) { xlog("L_INFO", "EVAPIRESPONSE - CALL_REJECT with no specific error code; return the received error\n"); return; } else { jansson_get("error_code", $var(sip_error), "$var(error_code)"); jansson_get("error_text", $var(sip_error), "$var(error_text)"); xlog("L_INFO", "EVAPIRESPONSE - CALL_REJECT with $var(error_code) - $var(error_text)\n"); $var(code) = $var(error_code); $var(text) = $var(error_text); route(REPLY_SAFE); exit; } } } # Process RTJSON routing if (jansson_get("rtjson", $var(response), "$var(rtjson_str)")) { jansson_get("retry_on_failure", $var(response), "$dlg_var(retry_on_failure)"); xlog("L_INFO", "EVAPIRESPONSE - retry_on_failure = $dlg_var(retry_on_failure) \n"); $dlg_var(rtjson_str) = $var(rtjson_str); # Process routes from RTJSON route(RTJSON_PROCESS); } else { xlog("L_INFO", "EVAPIRESPONSE - Invalid response format from Python\n"); //t_reply("500", "Internal Server Error"); $var(code) = 500; $var(text) = "Internal Server Error"; route(REPLY_SAFE); exit; } } route[NOTIFY_CALL_REJECT] { # Send route failure notification to Python $var(failure_data) = $null; jansson_set("string" , "type" , "CALL_REJECT" , "$var(failure_data)" ); jansson_set("string" , "remote_ip_port" , "$si:$sp" , "$var(failure_data)" ); jansson_set("string" , "local_ip_port" , "$RAi:$RAp" , "$var(failure_data)" ); jansson_set("string" , "protocol" , "$pr" , "$var(failure_data)" ); jansson_set("string", "error_code" , "$T(reply_code)" , "$var(sip_error_code_obj)"); jansson_set("string", "error_text" , "$T(reply_reason)" , "$var(sip_error_code_obj)"); jansson_set("string", "from" , "$hdr(From)" , "$var(sip_error_code_obj)"); jansson_set("string", "to" , "$hdr(To)" , "$var(sip_error_code_obj)"); jansson_set("string", "call_id" , "$ci" , "$var(sip_error_code_obj)" ); jansson_set("obj" , "sip_error" , "$var(sip_error_code_obj)", "$var(failure_data)"); jansson_set("array" ,"crankback_history", "$dlg_var(branch_stats)" , "$var(failure_data)"); jansson_set("string", "timestamp" , "$TV(Sn)" , "$var(failure_data)" ); $var(evmsg) = "CALL_REJECT:" + $T(id_index) + ":" + $T(id_label) + ":" + $var(failure_data); xlog("L_INFO","NOTIFY_CALL_REJECT - notifying XPhere with $var(evmsg) \n"); evapi_relay("CALL_REJECT:$T(id_index):$T(id_label):$var(failure_data)"); } # Tiny helper to reply correctly inside/outside TM route[REPLY_SAFE] { # validate code (default to 480 if bad/empty) if (!($var(code) =~ "^[1-6][0-9][0-9]$")) $var(code) = 480; if ($var(text) == "") $var(text) = "Temporarily Unavailable"; # remove CR/LF that can break the reason phrase $var(text) = $(var(text){re.subst,/[\r\n]/ /g}); if (t_check_trans()) { xlog("L_INFO", "REPLY_SAFE - replying with t_reply\n"); t_reply("$var(code)", "$var(text)"); } else { xlog("L_INFO", "REPLY_SAFE - replying with send_reply\n"); sl_send_reply("$var(code)", "$var(text)"); } xlog("L_INFO", "REPLY_SAFE - replied $var(code) - $var(text)\n"); exit; } # Failure route failure_route[MANAGE_FAILURE] { if (t_is_canceled()) { exit; } route(SPOOL_CALL_STATUS); route(PIN_SOCKET); # Try next route if available if (rtjson_next_route()) { # increase the route index $var(route_index) = $var(route_index) + 1; # Try next route from RTJson if available xlog("L_INFO","MANAGE_FAILURE - next RTJson route selected - relaying call - retry_on_failure = $dlg_var(retry_on_failure) route_index=$var(route_index)\n"); route(RELAY); } else { xlog("L_INFO","MANAGE_FAILURE - retry_on_failure = $dlg_var(retry_on_failure)\n"); if ($dlg_var(retry_on_failure) == 1) { // if the routes received have property retry_on_failure = 1 then // request a new list of routes and retry $var(retry) = 1; $var(route_index) = 0; xlog("L_INFO","MANAGE_FAILURE - all routes failed. requesting new RTJson\n"); route(HANDLE_INVITE); // send a new request for new routes }else{ # No more routes available xlog("L_ERROR","MANAGE_FAILURE - no more routes available for RTJson\n"); #### FIX ME - implement CALL_REJECT route(NOTIFY_CALL_REJECT); t_reply("503", "Service Unavailable!"); exit; } } exit; } # Relay route route[RELAY] { if (is_method("INVITE|UPDATE|BYE")) # |BYE { xlog("L_INFO","RELAY - Modifying SIP headers from INVITE\n"); jsdt_run("modify_invite_headers", "$dlg_var(rtjson_str)", "$var(route_index)" ); if (!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH"); } if (is_method("INVITE|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"); } route(PIN_SOCKET); if (!t_relay()) { xlog("L_INFO","RELAY - Returned from event"); sl_reply_error(); } exit; } route[PIN_SOCKET] { # routing block that sets the socket IP:PORT to SIP messages # sent to the egress side if (is_method("INVITE") && !has_totag()) { dlg_manage(); $var(proto) = $pr; # "udp" / "tcp" xlog("L_DEBUG", "PIN_SOCKET - stored dlg_sock=< $pr:$Ri:$Rp > \n"); $dlg_var(send_sock) = "$pr:$Ri:$Rp"; # e.g. udp:10.20.0.4:5061<http://10.20.0.4:5061> } # choose the socket we’ll force if ($dlg_var(send_sock) != $null) { $var(sock) = $dlg_var(send_sock); } else { $var(proto) = $pr; xlog("L_DEBUG", "PIN_SOCKET - setting $pr:$Ri:$Rp \n"); $var(sock) = "$pr:$Ri:$Rp"; # requests without dialog } xlog("L_DEBUG", "PIN_SOCKET - forcing <$var(sock)> (recv $pr:$Ri:$Rp)\n"); set_send_socket($var(sock)); xlog("L_DEBUG", "PIN_SOCKET - $$var(sock) = $var(sock) - $$dlg_var(send_sock) = $dlg_var(send_sock) \n"); } Atenciosamente / Kind Regards / Cordialement / Un saludo, Sérgio Charrua On Tue, Sep 9, 2025 at 2:39 PM Henning Westerholt <[email protected]<mailto:[email protected]>> wrote: Hello, did not looked to the whole script, but the usual action would be enabling the debug log and see where the 503 is actually generated from. Cheers, Henning From: Sergio Charrua via sr-users <[email protected]<mailto:[email protected]>> Sent: Freitag, 5. September 2025 19:34 To: Kamailio (SER) - Users Mailing List <[email protected]<mailto:[email protected]>> Cc: Sergio Charrua <[email protected]<mailto:[email protected]>> Subject: [SR-Users] send_reply not accepting values Hi all! I'm using EVAPI module. Upon INVITE, Kamailio gets a list of routes from a script using evapi_async_relay() . The EVAPI script (Python) then returns a RTJson structure. The Kamailio logic is set to iterate through each route and if at the end all routes have failed (ex.: if all egress endpoints are unavailable), then sends a EVAPI request using evapi_relay() to the script. Note that this request is not asynchronous (using evapi_async_relay() would fail with error stating that there is no transaction available....). This is my evapi:message-received: event_route[evapi:message-received] { # Parse the message format: RESPONSE:index:label:data $var(msg) = $evapi(msg); #$var(logmsg) = $(var(msg){s.substr,0,100}); xlog("L_INFO", "evapi:message-received - Received EVAPI message: $var(msg) ...\n"); $var(type) = $(var(msg){s.select,0,:}); $var(tindex) = $(var(msg){s.select,1,:}{s.int<http://s.int>}); $var(tlabel) = $(var(msg){s.select,2,:}{s.int<http://s.int>}); $var(response) = $(var(msg){re.subst,/^[^:]*:[^:]*:[^:]*://}); xlog("L_INFO", "Part 0: '$var(type)'\n"); xlog("L_INFO", "Part 1: '$var(tindex)'\n"); xlog("L_INFO", "Part 2: '$var(tlabel)'\n"); xlog("L_INFO", "Part 3: '$var(response)'\n"); if ( $var(type) == "RESPONSE" && $var(tindex) =~ "^[0-9]+$" && $var(tlabel) =~ "^[0-9]+$" ) { xlog("L_INFO", "evapi:message-received - RESPONSE index $var(tindex) label $var(tlabel) \n"); xlog("L_INFO", "evapi:message-received - Continue Call processing\n"); if (jansson_get("action", $var(response), "$var(action)")){ if ($var(action) == "CALL_REJECT"){ route(EVAPIRESPONSE); } } # Resume transaction t_continue("$var(tindex)", "$var(tlabel)", "EVAPIRESPONSE"); } else { xlog("L_INFO", "evapi:message-received - invalid message received from EVAPI. Cancelling the call \n"); t_reply("500", "Internal Server Error"); exit; } } CALL_REJECT action is received after the evapi_relay() request to the EVAPI script (python) that is launched after a route_failure. For example, Kamailio requests for error mappings when a call has been tried and no egress endpoint was reachable. My EVAPIRESPONSE route block is: route[EVAPIRESPONSE] { xlog("L_INFO", "EVAPIRESPONSE - Resuming INVITE processing with index $var(tindex) label $var(tlabel)\n"); xlog("L_INFO", "EVAPIRESPONSE - JSON : $var(response) \n"); # Test each condition individually if ($var(response) == "FALSE" or $var(response) == "NO_ROUTES") { # Check if response is FALSE (drop the call) xlog("L_ERR", "EVAPIRESPONSE - Python script returned FALSE or NO ROUTES, dropping call\n"); $var(code) = 500; $var(text) = "Internal Server Error"; route(REPLY_SAFE); exit; } if (jansson_get("action", $var(response), "$var(action)")){ if ($var(action) == "DROP") { jansson_get("error_code", $var(response), "$var(error_code)"); jansson_get("error_text", $var(response), "$var(error_text)"); xlog("L_INFO", "EVAPIRESPONSE - dropping call with returned error $var(error_code) - $var(error_text) \n"); $var(code) = $var(error_code); $var(text) = $var(error_text); route(REPLY_SAFE); }else if ($var(action) == "CALL_REJECT") { jansson_get("reject", $var(response), "$var(sip_error)"); if ( "$var(sip_error)" == "" ) { xlog("L_INFO", "EVAPIRESPONSE - CALL_REJECT with no specific error code; return the received error\n"); return; } else { jansson_get("error_code", $var(sip_error), "$var(error_code)"); jansson_get("error_text", $var(sip_error), "$var(error_text)"); xlog("L_INFO", "EVAPIRESPONSE - CALL_REJECT with $var(error_code) - $var(error_text)\n"); $var(code) = $var(error_code); $var(text) = $var(error_text); route(REPLY_SAFE); } } } # Process RTJSON routing if (jansson_get("rtjson", $var(response), "$var(rtjson_str)")) { jansson_get("retry_on_failure", $var(response), "$dlg_var(retry_on_failure)"); xlog("L_DEBUG", "EVAPIRESPONSE - retry_on_failure = $dlg_var(retry_on_failure) \n"); $dlg_var(rtjson_str) = $var(rtjson_str); # Process routes from RTJSON route(RTJSON_PROCESS); } else { xlog("L_ERR", "EVAPIRESPONSE - Invalid response format from Python\n"); $var(code) = 500; $var(text) = "Internal Server Error"; route(REPLY_SAFE); exit; } } # Tiny helper to reply correctly inside/outside TM route[REPLY_SAFE] { # validate code (default to 480 if bad/empty) if (!($var(code) =~ "^[1-6][0-9][0-9]$")) $var(code) = 480; if ($var(text) == "") $var(text) = "Temporarily Unavailable"; # remove CR/LF that can break the reason phrase $var(text) = $(var(text){re.subst,/[\r\n]/ /g}); if (t_check_trans()) { xlog("L_INFO", "REPLY_SAFE - replying with t_reply\n"); t_reply("$var(code)", "$var(text)"); } else { xlog("L_INFO", "REPLY_SAFE - replying with send_reply\n"); send_reply("$var(code)", "$var(text)"); } exit; } I have tried with t_reply, sl_send_reply, send_reply but the SIP trace only shows SIP 503 Service Unavailable being sent from Kamailio to the ingress endpoint. Setting log to DEBUG level doesn't show anything neither: Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169257 457395 1 1 OPTIONS 123} <script>: evapi:message-received - Received EVAPI message: RESPONSE:2825:1816929401:{"action": "CALL_REJECT", "call_id": "[email protected]:5060<http://[email protected]:5060>", "reject": {"error_code": 480, "error_text": "some text"}} ... Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169485 457395 1 1 OPTIONS 123} <script>: Part 0: 'RESPONSE' Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169497 457395 1 1 OPTIONS 123} <script>: Part 1: '2825' Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169506 457395 1 1 OPTIONS 123} <script>: Part 2: '1816929401' Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169514 457395 1 1 OPTIONS 123} <script>: Part 3: '{"action": "CALL_REJECT", "call_id": "[email protected]:5060<http://[email protected]:5060>", "reject": {"error_code": 480, "error_text": "some text"}}' Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169639 457395 1 1 OPTIONS 123} <script>: evapi:message-received - RESPONSE index 2825 label 1816929401 Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169654 457395 1 1 OPTIONS 123} <script>: evapi:message-received - Continue Call processing Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169816 457395 1 1 OPTIONS 123} <script>: EVAPIRESPONSE - Resuming INVITE processing with index 2825 label 1816929401 Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169829 457395 1 1 OPTIONS 123} <script>: EVAPIRESPONSE - JSON : {"action": "CALL_REJECT", "call_id": "[email protected]:5060<http://[email protected]:5060>", "reject": {"error_code": 480, "error_text": "some text"}} Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.169998 457395 1 1 OPTIONS 123} <script>: EVAPIRESPONSE - CALL_REJECT with 480 - some text Sep 5 19:16:48 ire-lab-kamailio1 kamailio[457395]: INFO: {1757092608.170253 457395 1 1 OPTIONS 123} <script>: REPLY_SAFE - replying with send_reply And nothing helps is found in logs. The goal is to send a custom SIP error and message depending if the error_code and error_text is specified. If not, then the message received from egress endpoint should be forwarded to the ingress endpoint. I just can't understand why the response is always SIP 503. Here is a SIP trace: [cid:[email protected]] Any suggestions? Thanks in advance. Atenciosamente / Kind Regards / Cordialement / Un saludo, Sérgio Charrua __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- [email protected] To unsubscribe send an email to [email protected] Important: keep the mailing list in the recipients, do not reply only to the sender!
image001.png
(image/png, 29.4 KB) - not displayed