Hello! I have a problem when sending a response sl_send_reply("415", "The other party does not support video calling!"); in route[HTTP_REPLY]. When I make a request using http_async_query() to send a push notification to a mobile device, I need to process the response from the push server and respond with a SIP message to the client. Before sending the request I do $http_req(suspend) = 0; What am I doing wrong? Why are $fU and $ru equal to null ? #processing HTTP responses route[HTTP_REPLY] { if ($http_ok && $http_rs == 200) { xlog("L_INFO", "route[HTTP_REPLY]: status $http_rs\n"); xlog("L_INFO", "route[HTTP_REPLY]: body $http_rb\n"); } else if($http_rs == 415 || $http_rs == "415") { xlog("L_ERR", "route[HTTP_REPLY]: caller: $fU phone: $ru error: $http_err)\n"); send_reply("415", "The other party does not support video calling!"); } else { xlog("L_ALERT", "route[HTTP_REPLY]: error $http_err)\n"); } #exit; }
Hi, since you are not suspending the transaction ($http_req(suspend) = 0) you cannot reference the transaction itself in the http reply route. Nothing about the transaction has been stored, the transaction continued to be processed in the main route and might have already finished by the moment the http reply is received. If you want to send a reply to a transaction after an http reply you need to suspend it.
Cheers,
Federico
On Sat, Apr 27, 2024 at 12:10 PM Masud Muborakshohi via sr-users < sr-users@lists.kamailio.org> wrote:
Hello! I have a problem when sending a response sl_send_reply("415", "The other party does not support video calling!"); in route[HTTP_REPLY]. When I make a request using http_async_query() to send a push notification to a mobile device, I need to process the response from the push server and respond with a SIP message to the client. Before sending the request I do $http_req(suspend) = 0; What am I doing wrong? Why are $fU and $ru equal to null ? #processing HTTP responses route[HTTP_REPLY] { if ($http_ok && $http_rs == 200) { xlog("L_INFO", "route[HTTP_REPLY]: status $http_rs\n"); xlog("L_INFO", "route[HTTP_REPLY]: body $http_rb\n"); } else if($http_rs == 415 || $http_rs == "415") { xlog("L_ERR", "route[HTTP_REPLY]: caller: $fU phone: $ru error: $http_err)\n"); send_reply("415", "The other party does not support video calling!"); } else { xlog("L_ALERT", "route[HTTP_REPLY]: error $http_err)\n"); } #exit; } __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
Thank you for quick response! But when I leave suspending enabled ($http_req(suspend) = 1, default) the call logic does not work, when after receiving a register (with id_index and id_label) from party B, the call should continue. I built this functionality based on your presentation https://www.voztovoice.org/sites/default/files/KamilioWorld2015%20-Federico..... I’ll give you my routes so that the picture is complete: request_route { ... if (is_method("INVITE")) { #Push notification route(SUSPEND); } ... }
# Handle SIP registrations route[REGISTRAR] { if (!is_method("REGISTER")) return; ... if (!save("location")) { sl_reply_error(); } ... #Push notification if ( (is_method("REGISTER")) && (($hdr(Expires) != "0") || !(($hdr(Contact) =~ "expires=0"))) && ($hdr(id_index) != "" && $hdr(id_label) != "") ) { xlog("L_INFO", "New $rm ru=$ru tu=$tu \n"); route(JOIN); }
exit; }
#Push notification route[SUSPEND] { if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE"); send_reply("100", "Suspending"); if ( !t_suspend() ) { xlog("L_ERROR","[SUSPEND] failed suspending trasaction [$T(id_index):$T(id_label)]\n"); send_reply("501", "Suspending error"); exit; } xlog("L_INFO","[SUSPEND] suspended transaction [$T(id_index):$T(id_label)] $fU=> $rU\n"); $sht(vtp=>join::$rU) = "" + $T(id_index) + ":" + $T(id_label); route(SENDPUSH); exit;
}
route[SENDPUSH] { sl_send_reply("100", "Pushing"); $http_req(suspend) = 0; $http_req(body) = '{ "caller": "' + $fU + '", "phone": "' + $rU + '", "id_index": "' + $T(id_index) + '", "id_label": "' + $T(id_label)+ '", "call_type": "'+ $var(calltype) +'" }'; #for apple sandbox test. if (is_user_in("Request-URI", "test")) { http_async_query("http://127.0.0.1:9996/notification/", "HTTP_REPLY"); } http_async_query("http://127.0.0.1:9999/notification/", "HTTP_REPLY"); }
#Resuming transaction. route[JOIN] { xlog("L_INFO","[JOIN] from REGISTER key value [$hdr(id_index) -- $hdr(id_label)]\n"); $var(hjoin) = 0; lock("$tU"); $var(hjoin) = $sht(vtp=>join::$tU); $var(hstored) = $sht(vtp=>stored::$tU); $sht(vtp=>join::$tU) = $null; $var(id_index) = $(var(hjoin){s.select,0,:}{s.int}); $var(id_label) = $(var(hjoin){s.select,1,:}{s.int}); unlock("$tU"); if($var(id_index)!=$null){ if ($var(hjoin)==0) { xlog("L_INFO","do ts_append_to() for $tu and hstored = $var(hstored)\n"); if ($var(hstored)) { ts_append_to("$(hdr(id_index){s.int})", "$(hdr(id_label){s.int})", "location"); xlog("L_INFO","do ts_append_to() for $tu end \n"); } return; } xlog("L_INFO","resuming trasaction [$(hdr(id_index){s.int}):$(hdr(id_label){s.int})] $tU ($var(hjoin))\n"); if ( !t_continue("$(hdr(id_index){s.int})", "$(hdr(id_label){s.int})", "LOCATION") ){ send_reply("404", "CALL NOT FOUND"); } } }
#processing HTTP responses route[HTTP_REPLY] { if ($http_ok && $http_rs == 200) { xlog("L_INFO", "route[HTTP_REPLY]: status $http_rs\n"); xlog("L_INFO", "route[HTTP_REPLY]: body $http_rb\n"); } else if($http_rs == 415 || $http_rs == "415") { xlog("L_ERR", "route[HTTP_REPLY]: caller: $fU phone: $ru error: $http_err)\n"); sl_send_reply("415", "The other party does not support video calling!"); } else { xlog("L_ALERT", "route[HTTP_REPLY]: error $http_err)\n"); } #exit; }
Hi, the presentation is from before http_async_client module was written so the example configuration does not apply straight once you add the http async request.
if (is_method("INVITE")) { #Push notification route(SUSPEND); }
You don't have to suspend the transaction here, http_async_query will do it for you if you have to send the push. I would rather do if (is_method("INVITE")) { #Push notification route(SENDPUSH); }
In the SENDPUSH route suspend the transaction $http_req(suspend) = 1; Then in the HTTP_REPLY route process the return code and either suspend again the transaction or reply an error message:
route[HTTP_REPLY] { if ($http_ok && $http_rs == 200) { route(SUSPEND); } else if($http_rs == 415) { send_reply("415", "The other party does not support video calling!"); } else { xlog("L_ALERT", "route[HTTP_REPLY]: error $http_err)\n"); send_reply("500", "Server Error"); } }
Hope this helps.
Cheers,
Federico
On Sat, Apr 27, 2024 at 6:38 PM Masud Muborakshohi via sr-users < sr-users@lists.kamailio.org> wrote:
Thank you for quick response! But when I leave suspending enabled ($http_req(suspend) = 1, default) the call logic does not work, when after receiving a register (with id_index and id_label) from party B, the call should continue. I built this functionality based on your presentation https://www.voztovoice.org/sites/default/files/KamilioWorld2015%20-Federico.... . I’ll give you my routes so that the picture is complete: request_route { ... if (is_method("INVITE")) { #Push notification route(SUSPEND); } ... }
# Handle SIP registrations route[REGISTRAR] { if (!is_method("REGISTER")) return; ... if (!save("location")) { sl_reply_error(); } ... #Push notification if ( (is_method("REGISTER")) && (($hdr(Expires) != "0") || !(($hdr(Contact) =~ "expires=0"))) && ($hdr(id_index) != "" && $hdr(id_label) != "") ) { xlog("L_INFO", "New $rm ru=$ru tu=$tu \n"); route(JOIN); }
exit;
}
#Push notification route[SUSPEND] { if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE"); send_reply("100", "Suspending"); if ( !t_suspend() ) { xlog("L_ERROR","[SUSPEND] failed suspending trasaction [$T(id_index):$T(id_label)]\n"); send_reply("501", "Suspending error"); exit; } xlog("L_INFO","[SUSPEND] suspended transaction [$T(id_index):$T(id_label)] $fU=> $rU\n"); $sht(vtp=>join::$rU) = "" + $T(id_index) + ":" + $T(id_label); route(SENDPUSH); exit;
}
route[SENDPUSH] { sl_send_reply("100", "Pushing"); $http_req(suspend) = 0; $http_req(body) = '{ "caller": "' + $fU + '", "phone": "' + $rU + '", "id_index": "' + $T(id_index) + '", "id_label": "' + $T(id_label)+ '", "call_type": "'+ $var(calltype) +'" }'; #for apple sandbox test. if (is_user_in("Request-URI", "test")) { http_async_query("http://127.0.0.1:9996/notification/", "HTTP_REPLY"); } http_async_query("http://127.0.0.1:9999/notification/", "HTTP_REPLY"); }
#Resuming transaction. route[JOIN] { xlog("L_INFO","[JOIN] from REGISTER key value [$hdr(id_index) -- $hdr(id_label)]\n"); $var(hjoin) = 0; lock("$tU"); $var(hjoin) = $sht(vtp=>join::$tU); $var(hstored) = $sht(vtp=>stored::$tU); $sht(vtp=>join::$tU) = $null; $var(id_index) = $(var(hjoin){s.select,0,:}{s.int}); $var(id_label) = $(var(hjoin){s.select,1,:}{s.int}); unlock("$tU"); if($var(id_index)!=$null){ if ($var(hjoin)==0) { xlog("L_INFO","do ts_append_to() for $tu and hstored = $var(hstored)\n"); if ($var(hstored)) { ts_append_to("$(hdr(id_index){s.int})", "$(hdr(id_label){s.int})", "location"); xlog("L_INFO","do ts_append_to() for $tu end \n"); } return; } xlog("L_INFO","resuming trasaction [$(hdr(id_index){s.int }):$(hdr(id_label){s.int})] $tU ($var(hjoin))\n"); if ( !t_continue("$(hdr(id_index){s.int})", "$(hdr(id_label){s.int})", "LOCATION") ){ send_reply("404", "CALL NOT FOUND"); } } }
#processing HTTP responses route[HTTP_REPLY] { if ($http_ok && $http_rs == 200) { xlog("L_INFO", "route[HTTP_REPLY]: status $http_rs\n"); xlog("L_INFO", "route[HTTP_REPLY]: body $http_rb\n"); } else if($http_rs == 415 || $http_rs == "415") { xlog("L_ERR", "route[HTTP_REPLY]: caller: $fU phone: $ru error: $http_err)\n"); sl_send_reply("415", "The other party does not support video calling!"); } else { xlog("L_ALERT", "route[HTTP_REPLY]: error $http_err)\n"); } #exit; } __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
Hello Federico! thank you for your detailed answer! Yes, I was already able to configure it and everything works fine. The only thing that was not clear was why it is necessary to do t_newtran() before calling the http_async_query() method? otherwise t_suspend() would throw an error. -- Отправлено из Mail.ru для Android четверг, 02 мая 2024г., 11:08 +05:00 от Federico Cabiddu via sr-users sr-users@lists.kamailio.org :
Hi, the presentation is from before http_async_client module was written so the example configuration does not apply straight once you add the http async request.
if (is_method("INVITE")) { #Push notification route(SUSPEND); }
You don't have to suspend the transaction here, http_async_query will do it for you if you have to send the push. I would rather do if (is_method("INVITE")) { #Push notification route(SENDPUSH); }
In the SENDPUSH route suspend the transaction $http_req(suspend) = 1; Then in the HTTP_REPLY route process the return code and either suspend again the transaction or reply an error message:
route[HTTP_REPLY] { if ($http_ok && $http_rs == 200) { route(SUSPEND); } else if($http_rs == 415) { send_reply("415", "The other party does not support video calling!"); } else { xlog("L_ALERT", "route[HTTP_REPLY]: error $http_err)\n"); send_reply("500", "Server Error"); } }
Hope this helps.
Cheers,
Federico
On Sat, Apr 27, 2024 at 6:38PM Masud Muborakshohi via sr-users < sr-users@lists.kamailio.org> wrote:
Thank you for quick response! But when I leave suspending enabled ($http_req(suspend) = 1, default) the call logic does not work, when after receiving a register (with id_index and id_label) from party B, the call should continue. I built this functionality based on your presentation https://www.voztovoice.org/sites/default/files/KamilioWorld2015%20-Federico.... . I’ll give you my routes so that the picture is complete: request_route { ... if (is_method("INVITE")) { #Push notification route(SUSPEND); } ... }
# Handle SIP registrations route[REGISTRAR] { if (!is_method("REGISTER")) return; ... if (!save("location")) { sl_reply_error(); } ... #Push notification if ( (is_method("REGISTER")) && (($hdr(Expires) != "0") || !(($hdr(Contact) =~ "expires=0"))) && ($hdr(id_index) != "" && $hdr(id_label) != "") ) { xlog("L_INFO", "New $rm ru=$ru tu=$tu \n"); route(JOIN); }
exit; }
#Push notification route[SUSPEND] { if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE"); send_reply("100", "Suspending"); if ( !t_suspend() ) { xlog("L_ERROR","[SUSPEND] failed suspending trasaction [$T(id_index):$T(id_label)]\n"); send_reply("501", "Suspending error"); exit; } xlog("L_INFO","[SUSPEND] suspended transaction [$T(id_index):$T(id_label)] $fU=> $rU\n"); $sht(vtp=> join::$rU) = "" + $T(id_index) + ":" + $T(id_label); route(SENDPUSH); exit;
}
route[SENDPUSH] { sl_send_reply("100", "Pushing"); $http_req(suspend) = 0; $http_req(body) = '{ "caller": "' + $fU + '", "phone": "' + $rU + '", "id_index": "' + $T(id_index) + '", "id_label": "' + $T(id_label)+ '", "call_type": "'+ $var(calltype) +'" }'; #for apple sandbox test. if (is_user_in("Request-URI", "test")) { http_async_query(" http://127.0.0.1:9996/notification/ ", "HTTP_REPLY"); } http_async_query(" http://127.0.0.1:9999/notification/ ", "HTTP_REPLY"); }
#Resuming transaction. route[JOIN] { xlog("L_INFO","[JOIN] from REGISTER key value [$hdr(id_index) -- $hdr(id_label)]\n"); $var(hjoin) = 0; lock("$tU"); $var(hjoin) = $sht(vtp=> join::$tU); $var(hstored) = $sht(vtp=> stored::$tU); $sht(vtp=> join::$tU) = $null; $var(id_index) = $(var(hjoin){s.select,0,:}{ s.int }); $var(id_label) = $(var(hjoin){s.select,1,:}{ s.int }); unlock("$tU"); if($var(id_index)!=$null){ if ($var(hjoin)==0) { xlog("L_INFO","do ts_append_to() for $tu and hstored = $var(hstored)\n"); if ($var(hstored)) { ts_append_to("$(hdr(id_index){ s.int })", "$(hdr(id_label){ s.int })", "location"); xlog("L_INFO","do ts_append_to() for $tu end \n"); } return; } xlog("L_INFO","resuming trasaction [$(hdr(id_index){ s.int }):$(hdr(id_label){ s.int })] $tU ($var(hjoin))\n"); if ( !t_continue("$(hdr(id_index){ s.int })", "$(hdr(id_label){ s.int })", "LOCATION") ){ send_reply("404", "CALL NOT FOUND"); } } }
#processing HTTP responses route[HTTP_REPLY] { if ($http_ok && $http_rs == 200) { xlog("L_INFO", "route[HTTP_REPLY]: status $http_rs\n"); xlog("L_INFO", "route[HTTP_REPLY]: body $http_rb\n"); } else if($http_rs == 415 || $http_rs == "415") { xlog("L_ERR", "route[HTTP_REPLY]: caller: $fU phone: $ru error: $http_err)\n"); sl_send_reply("415", "The other party does not support video calling!"); } else { xlog("L_ALERT", "route[HTTP_REPLY]: error $http_err)\n"); } #exit; } __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
Hi Masoud, transactions in kamailio are either implicitly created when calling t_relay() or explicitly created in the routing script calling t_newtran(). http_async_query() won't create the transaction if it doesn't already exist.
Cheers,
Federico
On Thu, May 2, 2024 at 8:58 AM Muborakshohi Masoud masoud96@mail.ru wrote:
Hello Federico! thank you for your detailed answer! Yes, I was already able to configure it and everything works fine. The only thing that was not clear was why it is necessary to do t_newtran() before calling the http_async_query() method? otherwise t_suspend() would throw an error.
-- Отправлено из Mail.ru для Android четверг, 02 мая 2024г., 11:08 +05:00 от Federico Cabiddu via sr-users sr-users@lists.kamailio.org:
Hi, the presentation is from before http_async_client module was written so the example configuration does not apply straight once you add the http async request.
if (is_method("INVITE")) { #Push notification route(SUSPEND); }
You don't have to suspend the transaction here, http_async_query will do it for you if you have to send the push. I would rather do if (is_method("INVITE")) { #Push notification route(SENDPUSH); }
In the SENDPUSH route suspend the transaction $http_req(suspend) = 1; Then in the HTTP_REPLY route process the return code and either suspend again the transaction or reply an error message:
route[HTTP_REPLY] { if ($http_ok && $http_rs == 200) { route(SUSPEND); } else if($http_rs == 415) { send_reply("415", "The other party does not support video calling!"); } else { xlog("L_ALERT", "route[HTTP_REPLY]: error $http_err)\n"); send_reply("500", "Server Error"); } }
Hope this helps.
Cheers,
Federico
On Sat, Apr 27, 2024 at 6:38PM Masud Muborakshohi via sr-users < sr-users@lists.kamailio.org> wrote:
Thank you for quick response! But when I leave suspending enabled ($http_req(suspend) = 1, default) the call logic does not work, when after receiving a register (with id_index and id_label) from party B, the call should continue. I built this functionality based on your presentation https://www.voztovoice.org/sites/default/files/KamilioWorld2015%20-Federico.... . I’ll give you my routes so that the picture is complete: request_route { ... if (is_method("INVITE")) { #Push notification route(SUSPEND); } ... }
# Handle SIP registrations route[REGISTRAR] { if (!is_method("REGISTER")) return; ... if (!save("location")) { sl_reply_error(); } ... #Push notification if ( (is_method("REGISTER")) && (($hdr(Expires) != "0") || !(($hdr(Contact) =~ "expires=0"))) && ($hdr(id_index) != "" && $hdr(id_label) != "") ) { xlog("L_INFO", "New $rm ru=$ru tu=$tu \n"); route(JOIN); }
exit;
}
#Push notification route[SUSPEND] { if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE"); send_reply("100", "Suspending"); if ( !t_suspend() ) { xlog("L_ERROR","[SUSPEND] failed suspending trasaction [$T(id_index):$T(id_label)]\n"); send_reply("501", "Suspending error"); exit; } xlog("L_INFO","[SUSPEND] suspended transaction [$T(id_index):$T(id_label)] $fU=> $rU\n"); $sht(vtp=>join::$rU) = "" + $T(id_index) + ":" + $T(id_label); route(SENDPUSH); exit;
}
route[SENDPUSH] { sl_send_reply("100", "Pushing"); $http_req(suspend) = 0; $http_req(body) = '{ "caller": "' + $fU + '", "phone": "' + $rU + '", "id_index": "' + $T(id_index) + '", "id_label": "' + $T(id_label)+ '", "call_type": "'+ $var(calltype) +'" }'; #for apple sandbox test. if (is_user_in("Request-URI", "test")) { http_async_query("http://127.0.0.1:9996/notification/", "HTTP_REPLY"); } http_async_query("http://127.0.0.1:9999/notification/", "HTTP_REPLY"); }
#Resuming transaction. route[JOIN] { xlog("L_INFO","[JOIN] from REGISTER key value [$hdr(id_index) -- $hdr(id_label)]\n"); $var(hjoin) = 0; lock("$tU"); $var(hjoin) = $sht(vtp=>join::$tU); $var(hstored) = $sht(vtp=>stored::$tU); $sht(vtp=>join::$tU) = $null; $var(id_index) = $(var(hjoin){s.select,0,:}{s.int}); $var(id_label) = $(var(hjoin){s.select,1,:}{s.int}); unlock("$tU"); if($var(id_index)!=$null){ if ($var(hjoin)==0) { xlog("L_INFO","do ts_append_to() for $tu and hstored = $var(hstored)\n"); if ($var(hstored)) { ts_append_to("$(hdr(id_index){s.int})", "$(hdr(id_label){s.int})", "location"); xlog("L_INFO","do ts_append_to() for $tu end \n"); } return; } xlog("L_INFO","resuming trasaction [$(hdr(id_index){s.int }):$(hdr(id_label){s.int})] $tU ($var(hjoin))\n"); if ( !t_continue("$(hdr(id_index){s.int})", "$(hdr(id_label){s.int})", "LOCATION") ){ send_reply("404", "CALL NOT FOUND"); } } }
#processing HTTP responses route[HTTP_REPLY] { if ($http_ok && $http_rs == 200) { xlog("L_INFO", "route[HTTP_REPLY]: status $http_rs\n"); xlog("L_INFO", "route[HTTP_REPLY]: body $http_rb\n"); } else if($http_rs == 415 || $http_rs == "415") { xlog("L_ERR", "route[HTTP_REPLY]: caller: $fU phone: $ru error: $http_err)\n"); sl_send_reply("415", "The other party does not support video calling!"); } else { xlog("L_ALERT", "route[HTTP_REPLY]: error $http_err)\n"); } #exit; } __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe: