Dear ALL:
I use Paul's ser.cfg for 0.9.0 post last year and wanna implement a call busy forward. I think Paul is busy on testing 'Best Practice', so he doesn't answer too much mail.
I try to make a call from UA1 to UA2, and UA2 is busy. So the call will forward to another Trunk 3. Ex: UA1 ==> UA2(busy) ==(failure_route[1])==> Trunk 3
PS: UA1 and UA2 behind different NATs.
But when I watch the log, I find that miss the following log (diff with call from UA1 to UA2 and directly forward to Trunk 3 Ex: UA1 ==> UA2(callfwd) ==> Trunk 3
When I make a callfwd call, the call will run route[3] but not failure_route[1]. UA1==>UA2(callfwd)==>route[2]==>Trunk 3
route[2] ====> SIP to SIP call route[3] ====> SIP to PSTN call failure_route[1] ====> NoAnswer or Busy Forward logic
And I make a fwdbusy call, the call will run route[2] then go to failure_route[1], and return to route[3]. UA1==>UA2(fwdbusy)==>failure_route[1]==>route[3] =XXX=> Trunk 3 ????
Why does the method be failed? Do I must "end_media_session()" before start a busy call? How can I modify it?
My snippet ser.cfg : -------------------------------------------------------------------------------------------------------------- route[3] { log(1, "SER: International Call Off-Net section route(3)\n");
# All Domestic Calls Go To CISCO if (method=="INVITE") { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; # enable caller id blocking for PSTN calls if (isflagset(25)) { append_rpid_hf(); }; }; # SIP->PSTN calls get 45 seconds to timeout log(1, "SER: Connecting to PSTN.....\n"); avp_write("i:45", "inv_timeout");
rewritehost("xxx.xxx.190.243"); #### A Trunking Gateway
if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; if (isflagset(31)) { # is voice mail? t_on_failure("1"); }; t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; } failure_route[1] { log(1, "SER: Failure Route section failure_route(1)\n");
# if caller hung up then don't sent to voicemail if (t_check_status("487")) { break; }; if (isflagset(26) && t_check_status("486")) { # forward busy is flag 26
if (avp_pushto("$ruri", "s:fwdbusy")) { log(1, "SER: fork to fwdbusy\n"); avp_delete("s:fwdbusy"); append_branch(); resetflag(26);
# test for domestic PSTN gateway if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_busy_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: Busy Failure and Jump to route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_busy_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: Busy Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: Busy Failure and Jump to route(2)\n"); route(2); }; break; }; };
# here we can have either voicemail __OR__ forward no answer if (isflagset(27) && t_check_status("408")) { # forward no answer is flag 27
if (avp_db_load("$ruri/username", "s:fwdnoanswer")) { avp_pushto("$ruri", "s:fwdnoanswer"); log(1, "SER: fork to fwdnoanswer\n"); avp_delete("s:fwdnoanswer"); append_branch(); resetflag(27);
if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_no_answer_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: No Answer Failure and Jump to route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_no_answer_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: No Answer Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: No Answer Failure and Jump to route(2)\n"); route(2); }; break; }; } else if (isflagset(31) && avp_pushto("$ruri", "$voicemail")) { avp_delete("$voicemail"); log(1, "SER: No Answer Failure and Jump to route(4)\n"); route(4); break; }; }
In SysLog: ------------------------------------------------------------------------------------------------------ proxydispatcher[13265]: command request 06DC9503-1938-4D9D-8628-E648F112BEC5@192.168.11.7 192.168.11.7:8000:audio 61.217.225.225 ser.xxx.net.tw local xxx.xxx.190.243 remote X-PRO=20build=201082 info=from:1011@ser.xxx.net.tw,to:9012@ser.xxx.net.tw,fromtag:2069977709,totag: Feb 24 00:59:21 ser proxydispatcher[13265]: domain ser.xxx.net.tw doesn't define any mediaproxy. Feb 24 00:59:21 ser proxydispatcher[13265]: will use default mediaproxy for this call. Feb 24 00:59:21 ser mediaproxy[1087]: command request 06DC9503-1938-4D9D-8628-E648F112BEC5@192.168.11.7 192.168.11.7:8000:audio 61.217.225.225 ser.xxx.net.tw local xxx.xxx.190.243 remote X-PRO=20build=201082 info=from:1011@ser.xxx.net.tw,to:9012@ser.xxx.net.tw,fromtag:2069977709,totag:,dispatcher Feb 24 00:59:21 ser mediaproxy[1087]: command execution time: 0.35 ms Feb 24 00:59:21 ser proxydispatcher[13265]: forwarding to mediaproxy on /var/run/mediaproxy.sock: got: 'xxx.xxx.190.248 35030' Feb 24 00:59:21 ser proxydispatcher[13265]: command execution time: 311.69 ms
Without following all your logic below, a quick question: You wrap the setting of t_on_failure based on flag 31. Is that the only situation where you want failure route to be called?
if (isflagset(31)) { # is voice mail? t_on_failure("1"); };
g-)
Charles Wang wrote:
Dear ALL:
I use Paul's ser.cfg for 0.9.0 post last year and wanna implement a call busy forward. I think Paul is busy on testing 'Best Practice', so he doesn't answer too much mail.
I try to make a call from UA1 to UA2, and UA2 is busy. So the call will forward to another Trunk 3. Ex: UA1 ==> UA2(busy) ==(failure_route[1])==> Trunk 3
PS: UA1 and UA2 behind different NATs.
But when I watch the log, I find that miss the following log (diff with call from UA1 to UA2 and directly forward to Trunk 3 Ex: UA1 ==> UA2(callfwd) ==> Trunk 3
When I make a callfwd call, the call will run route[3] but not failure_route[1]. UA1==>UA2(callfwd)==>route[2]==>Trunk 3
route[2] ====> SIP to SIP call route[3] ====> SIP to PSTN call failure_route[1] ====> NoAnswer or Busy Forward logic
And I make a fwdbusy call, the call will run route[2] then go to failure_route[1], and return to route[3]. UA1==>UA2(fwdbusy)==>failure_route[1]==>route[3] =XXX=> Trunk 3 ????
Why does the method be failed? Do I must "end_media_session()" before start a busy call? How can I modify it?
My snippet ser.cfg :
route[3] { log(1, "SER: International Call Off-Net section route(3)\n");
# All Domestic Calls Go To CISCO if (method=="INVITE") { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; # enable caller id blocking for PSTN calls if (isflagset(25)) { append_rpid_hf(); }; }; # SIP->PSTN calls get 45 seconds to timeout log(1, "SER: Connecting to PSTN.....\n"); avp_write("i:45", "inv_timeout");
rewritehost("xxx.xxx.190.243"); #### A Trunking Gateway
if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; if (isflagset(31)) { # is voice mail? t_on_failure("1"); }; t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; } failure_route[1] { log(1, "SER: Failure Route section failure_route(1)\n");
# if caller hung up then don't sent to voicemail if (t_check_status("487")) { break; }; if (isflagset(26) && t_check_status("486")) { # forward busy is flag 26 if (avp_pushto("$ruri", "s:fwdbusy")) { log(1, "SER: fork to fwdbusy\n"); avp_delete("s:fwdbusy"); append_branch(); resetflag(26); # test for domestic PSTN gateway if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_busy_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: Busy Failure and Jump to
route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_busy_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: Busy Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: Busy Failure and Jump to route(2)\n"); route(2); }; break; }; };
# here we can have either voicemail __OR__ forward no answer if (isflagset(27) && t_check_status("408")) { # forward no answer is flag 27 if (avp_db_load("$ruri/username", "s:fwdnoanswer")) { avp_pushto("$ruri", "s:fwdnoanswer"); log(1, "SER: fork to fwdnoanswer\n"); avp_delete("s:fwdnoanswer"); append_branch(); resetflag(27); if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_no_answer_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: No Answer Failure
and Jump to route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_no_answer_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: No Answer Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: No Answer Failure and Jump to route(2)\n"); route(2); }; break; }; } else if (isflagset(31) && avp_pushto("$ruri", "$voicemail")) { avp_delete("$voicemail"); log(1, "SER: No Answer Failure and Jump to route(4)\n"); route(4); break; }; }
In SysLog:
proxydispatcher[13265]: command request 06DC9503-1938-4D9D-8628-E648F112BEC5@192.168.11.7 192.168.11.7:8000:audio 61.217.225.225 ser.xxx.net.tw local xxx.xxx.190.243 remote X-PRO=20build=201082 info=from:1011@ser.xxx.net.tw,to:9012@ser.xxx.net.tw,fromtag:2069977709,totag: Feb 24 00:59:21 ser proxydispatcher[13265]: domain ser.xxx.net.tw doesn't define any mediaproxy. Feb 24 00:59:21 ser proxydispatcher[13265]: will use default mediaproxy for this call. Feb 24 00:59:21 ser mediaproxy[1087]: command request 06DC9503-1938-4D9D-8628-E648F112BEC5@192.168.11.7 192.168.11.7:8000:audio 61.217.225.225 ser.xxx.net.tw local xxx.xxx.190.243 remote X-PRO=20build=201082 info=from:1011@ser.xxx.net.tw,to:9012@ser.xxx.net.tw,fromtag:2069977709,totag:,dispatcher Feb 24 00:59:21 ser mediaproxy[1087]: command execution time: 0.35 ms Feb 24 00:59:21 ser proxydispatcher[13265]: forwarding to mediaproxy on /var/run/mediaproxy.sock: got: 'xxx.xxx.190.248 35030' Feb 24 00:59:21 ser proxydispatcher[13265]: command execution time: 311.69 ms
Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Dear Greger:
I have no voicemail service in my scenario. So I keep the voicemail flag and I setting it as "n" in usr_preferences table.
And where to add these code of your support? Please show me a example. Thank you very much.
Best Regard Charles.
On Thu, 24 Feb 2005 07:53:06 +0100, Greger V. Teigre greger@teigre.com wrote:
Without following all your logic below, a quick question: You wrap the setting of t_on_failure based on flag 31. Is that the only situation where you want failure route to be called?
if (isflagset(31)) { # is voice mail? t_on_failure("1"); };
g-)
Charles Wang wrote:
Dear ALL:
I use Paul's ser.cfg for 0.9.0 post last year and wanna implement a call busy forward. I think Paul is busy on testing 'Best Practice', so he doesn't answer too much mail.
I try to make a call from UA1 to UA2, and UA2 is busy. So the call will forward to another Trunk 3. Ex: UA1 ==> UA2(busy) ==(failure_route[1])==> Trunk 3
PS: UA1 and UA2 behind different NATs.
But when I watch the log, I find that miss the following log (diff with call from UA1 to UA2 and directly forward to Trunk 3 Ex: UA1 ==> UA2(callfwd) ==> Trunk 3
When I make a callfwd call, the call will run route[3] but not failure_route[1]. UA1==>UA2(callfwd)==>route[2]==>Trunk 3
route[2] ====> SIP to SIP call route[3] ====> SIP to PSTN call failure_route[1] ====> NoAnswer or Busy Forward logic
And I make a fwdbusy call, the call will run route[2] then go to failure_route[1], and return to route[3]. UA1==>UA2(fwdbusy)==>failure_route[1]==>route[3] =XXX=> Trunk 3 ????
Why does the method be failed? Do I must "end_media_session()" before start a busy call? How can I modify it?
My snippet ser.cfg :
route[3] { log(1, "SER: International Call Off-Net section route(3)\n");
# All Domestic Calls Go To CISCO if (method=="INVITE") { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; # enable caller id blocking for PSTN calls if (isflagset(25)) { append_rpid_hf(); }; }; # SIP->PSTN calls get 45 seconds to timeout log(1, "SER: Connecting to PSTN.....\n"); avp_write("i:45", "inv_timeout");
rewritehost("xxx.xxx.190.243"); #### A Trunking Gateway
if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; if (isflagset(31)) { # is voice mail? t_on_failure("1"); }; t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; } failure_route[1] { log(1, "SER: Failure Route section failure_route(1)\n");
# if caller hung up then don't sent to voicemail if (t_check_status("487")) { break; }; if (isflagset(26) && t_check_status("486")) { # forward busy is flag 26 if (avp_pushto("$ruri", "s:fwdbusy")) { log(1, "SER: fork to fwdbusy\n"); avp_delete("s:fwdbusy"); append_branch(); resetflag(26); # test for domestic PSTN gateway if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_busy_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: Busy Failure and Jump to
route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_busy_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: Busy Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: Busy Failure and Jump to route(2)\n"); route(2); }; break; }; };
# here we can have either voicemail __OR__ forward no answer if (isflagset(27) && t_check_status("408")) { # forward no answer is flag 27 if (avp_db_load("$ruri/username", "s:fwdnoanswer")) { avp_pushto("$ruri", "s:fwdnoanswer"); log(1, "SER: fork to fwdnoanswer\n"); avp_delete("s:fwdnoanswer"); append_branch(); resetflag(27); if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_no_answer_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: No Answer Failure
and Jump to route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_no_answer_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: No Answer Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: No Answer Failure and Jump to route(2)\n"); route(2); }; break; }; } else if (isflagset(31) && avp_pushto("$ruri", "$voicemail")) { avp_delete("$voicemail"); log(1, "SER: No Answer Failure and Jump to route(4)\n"); route(4); break; }; }
In SysLog:
proxydispatcher[13265]: command request 06DC9503-1938-4D9D-8628-E648F112BEC5@192.168.11.7 192.168.11.7:8000:audio 61.217.225.225 ser.xxx.net.tw local xxx.xxx.190.243 remote X-PRO=20build=201082 info=from:1011@ser.xxx.net.tw,to:9012@ser.xxx.net.tw,fromtag:2069977709,totag: Feb 24 00:59:21 ser proxydispatcher[13265]: domain ser.xxx.net.tw doesn't define any mediaproxy. Feb 24 00:59:21 ser proxydispatcher[13265]: will use default mediaproxy for this call. Feb 24 00:59:21 ser mediaproxy[1087]: command request 06DC9503-1938-4D9D-8628-E648F112BEC5@192.168.11.7 192.168.11.7:8000:audio 61.217.225.225 ser.xxx.net.tw local xxx.xxx.190.243 remote X-PRO=20build=201082 info=from:1011@ser.xxx.net.tw,to:9012@ser.xxx.net.tw,fromtag:2069977709,totag:,dispatcher Feb 24 00:59:21 ser mediaproxy[1087]: command execution time: 0.35 ms Feb 24 00:59:21 ser proxydispatcher[13265]: forwarding to mediaproxy on /var/run/mediaproxy.sock: got: 'xxx.xxx.190.248 35030' Feb 24 00:59:21 ser proxydispatcher[13265]: command execution time: 311.69 ms
Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Charles, IMHO, you should call t_on_failure for all failures and then do matching on status codes there. So, remove the if(isflagset(31)) . Remember that the flag can only be set in ser.cfg using setflag(31); If you want to map a usr_preferences setting like "n" to setting a flag or not, you need to avp_db_load() the avp (here:voicemail) and then do an if(avp_check(="y")) then setflag(31). This is like I showed in a previous email. g-)
Charles Wang wrote:
Dear Greger:
I have no voicemail service in my scenario. So I keep the voicemail flag and I setting it as "n" in usr_preferences table.
And where to add these code of your support? Please show me a example. Thank you very much.
Best Regard Charles.
On Thu, 24 Feb 2005 07:53:06 +0100, Greger V. Teigre greger@teigre.com wrote:
Without following all your logic below, a quick question: You wrap the setting of t_on_failure based on flag 31. Is that the only situation where you want failure route to be called?
if (isflagset(31)) { # is voice mail? t_on_failure("1"); };
g-)
Charles Wang wrote:
Dear ALL:
I use Paul's ser.cfg for 0.9.0 post last year and wanna implement a call busy forward. I think Paul is busy on testing 'Best Practice', so he doesn't answer too much mail.
I try to make a call from UA1 to UA2, and UA2 is busy. So the call will forward to another Trunk 3. Ex: UA1 ==> UA2(busy) ==(failure_route[1])==> Trunk 3
PS: UA1 and UA2 behind different NATs.
But when I watch the log, I find that miss the following log (diff with call from UA1 to UA2 and directly forward to Trunk 3 Ex: UA1 ==> UA2(callfwd) ==> Trunk 3
When I make a callfwd call, the call will run route[3] but not failure_route[1]. UA1==>UA2(callfwd)==>route[2]==>Trunk 3
route[2] ====> SIP to SIP call route[3] ====> SIP to PSTN call failure_route[1] ====> NoAnswer or Busy Forward logic
And I make a fwdbusy call, the call will run route[2] then go to failure_route[1], and return to route[3]. UA1==>UA2(fwdbusy)==>failure_route[1]==>route[3] =XXX=> Trunk 3 ????
Why does the method be failed? Do I must "end_media_session()" before start a busy call? How can I modify it?
My snippet ser.cfg :
route[3] { log(1, "SER: International Call Off-Net section route(3)\n");
# All Domestic Calls Go To CISCO if (method=="INVITE") { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; # enable caller id blocking for PSTN calls if (isflagset(25)) { append_rpid_hf(); }; }; # SIP->PSTN calls get 45 seconds to timeout log(1, "SER: Connecting to PSTN.....\n"); avp_write("i:45", "inv_timeout");
rewritehost("xxx.xxx.190.243"); #### A Trunking Gateway
if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; if (isflagset(31)) { # is voice mail? t_on_failure("1"); }; t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; } failure_route[1] { log(1, "SER: Failure Route section failure_route(1)\n");
# if caller hung up then don't sent to voicemail if (t_check_status("487")) { break; }; if (isflagset(26) && t_check_status("486")) { # forward busy is flag 26 if (avp_pushto("$ruri", "s:fwdbusy")) { log(1, "SER: fork to fwdbusy\n"); avp_delete("s:fwdbusy"); append_branch(); resetflag(26); # test for domestic PSTN gateway if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_busy_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: Busy Failure and Jump to
route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_busy_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: Busy Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: Busy Failure and Jump to route(2)\n"); route(2); }; break; }; };
# here we can have either voicemail __OR__ forward no answer if (isflagset(27) && t_check_status("408")) { # forward no answer is flag 27 if (avp_db_load("$ruri/username", "s:fwdnoanswer")) { avp_pushto("$ruri", "s:fwdnoanswer"); log(1, "SER: fork to fwdnoanswer\n"); avp_delete("s:fwdnoanswer"); append_branch(); resetflag(27); if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_no_answer_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: No Answer Failure
and Jump to route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_no_answer_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: No Answer Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: No Answer Failure and Jump to route(2)\n"); route(2); }; break; }; } else if (isflagset(31) && avp_pushto("$ruri", "$voicemail")) { avp_delete("$voicemail"); log(1, "SER: No Answer Failure and Jump to route(4)\n"); route(4); break; }; }
In SysLog:
proxydispatcher[13265]: command request 06DC9503-1938-4D9D-8628-E648F112BEC5@192.168.11.7 192.168.11.7:8000:audio 61.217.225.225 ser.xxx.net.tw local xxx.xxx.190.243 remote X-PRO=20build=201082 info=from:1011@ser.xxx.net.tw,to:9012@ser.xxx.net.tw,fromtag:2069977709,totag: Feb 24 00:59:21 ser proxydispatcher[13265]: domain ser.xxx.net.tw doesn't define any mediaproxy. Feb 24 00:59:21 ser proxydispatcher[13265]: will use default mediaproxy for this call. Feb 24 00:59:21 ser mediaproxy[1087]: command request 06DC9503-1938-4D9D-8628-E648F112BEC5@192.168.11.7 192.168.11.7:8000:audio 61.217.225.225 ser.xxx.net.tw local xxx.xxx.190.243 remote X-PRO=20build=201082 info=from:1011@ser.xxx.net.tw,to:9012@ser.xxx.net.tw,fromtag:2069977709,totag:,dispatcher Feb 24 00:59:21 ser mediaproxy[1087]: command execution time: 0.35 ms Feb 24 00:59:21 ser proxydispatcher[13265]: forwarding to mediaproxy on /var/run/mediaproxy.sock: got: 'xxx.xxx.190.248 35030' Feb 24 00:59:21 ser proxydispatcher[13265]: command execution time: 311.69 ms
Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Dear Greger:
I call t_on_failure("1"); on my route[2] (this is SIP to SIP route). If I make a SIP to SIP call failed, it should go to another route. For example: UA 1011 call 1022, and 1022 setting busy forward to PSTN(0939749xxx).
So, first route is route[2] (I setting t_on_failure("1") here), then if busy condiction, it will go to route[3](for PSTN).
I still can not understand where to add what you post before. So I add my complete ser.cfg in this post.
Thank you for your kind.
Best Regard Charles
ser.cfg: --------------------------------------------------------------------------------------------------------- # # $Id: ser.cfg,v 1.25 2004/11/30 16:28:24 andrei Exp $ # # simple quick-start config script #
# ----------- global configuration parameters ------------------------
debug=10 # debug level (cmd line: -dddddddddd) fork=yes log_stderror=no # (cmd line: -E)
/* Uncomment these lines to enter debugging mode fork=no log_stderror=yes */
listen=xxx.xxx.190.248
alias=ser.xxx.net.tw alias=ser alias=xxx.xxx.190.248
check_via=no # (cmd. line: -v) dns=no # (cmd. line: -r) rev_dns=no # (cmd. line: -R) port=5060 children=4 fifo_mode=0666 fifo="/tmp/ser_fifo" fifo_db_url="mysql://ser:heslo@localhost/ser"
# mhomed -- enable calculation of outbound interface. # useful on multihomed servers. mhomed=0
# ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database loadmodule "/usr/local/lib/ser/modules/mysql.so" loadmodule "/usr/local/lib/ser/modules/sl.so" loadmodule "/usr/local/lib/ser/modules/tm.so" loadmodule "/usr/local/lib/ser/modules/rr.so" loadmodule "/usr/local/lib/ser/modules/maxfwd.so" loadmodule "/usr/local/lib/ser/modules/usrloc.so" loadmodule "/usr/local/lib/ser/modules/registrar.so" loadmodule "/usr/local/lib/ser/modules/textops.so" loadmodule "/usr/local/lib/ser/modules/auth.so" loadmodule "/usr/local/lib/ser/modules/auth_db.so" loadmodule "/usr/local/lib/ser/modules/exec.so" loadmodule "/usr/local/lib/ser/modules/avpops.so" loadmodule "/usr/local/lib/ser/modules/domain.so" loadmodule "/usr/local/lib/ser/modules/group.so" loadmodule "/usr/local/lib/ser/modules/uri.so" loadmodule "/usr/local/lib/ser/modules/uri_db.so" loadmodule "/usr/local/lib/ser/modules/permissions.so" loadmodule "/usr/local/lib/ser/modules/speeddial.so" loadmodule "/usr/local/lib/ser/modules/acc.so" loadmodule "/usr/local/lib/ser/modules/pdt.so" loadmodule "/usr/local/lib/ser/modules/options.so" loadmodule "/usr/local/lib/ser/modules/mediaproxy.so" loadmodule "/usr/local/lib/ser/modules/xlog.so"
# ----------------- setting module-specific parameters ---------------
# -- mediaproxy params -- modparam("mediaproxy", "natping_interval", 30) modparam("mediaproxy", "sip_asymmetrics", "/usr/local/etc/ser/sip-asymmetric-clients") modparam("mediaproxy", "rtp_asymmetrics", "/usr/local/etc/ser/rtp-asymmetric-clients")
# -- usrloc params -- # # 0 = disable # 1 = write-through # 2 = write-back # modparam("usrloc", "db_mode", 1) modparam("usrloc", "timer_interval", 60) modparam("usrloc", "desc_time_order", 1)
# -- auth params -- modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password")
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# -- db_url params -- modparam("acc|auth_db|domain|group|permissions|speeddial|uri_db|usrloc|pdt", "db_url", "mysql://ser:heslo@localhost/ser")
# -- use_domain params -- modparam("auth_db|group|registrar|speeddial|uri_db|usrloc", "use_domain", 0)
# -- permissions params -- modparam("permissions", "db_mode", 1) modparam("permissions", "trusted_table", "trusted")
# -- accounting params -- modparam("acc", "db_flag", 1) modparam("acc", "db_missed_flag", 1) modparam("acc", "log_fmt", "cdfimorstup") modparam("acc", "log_level", 1) modparam("acc", "failed_transactions", 1) modparam("acc", "report_cancels", 1) modparam("acc", "report_ack", 0)
# -- domain params -- modparam("domain", "db_mode", 1)
# ------------- exec parameters modparam("exec", "setvars", 1) modparam("exec", "time_to_kill", 10)
# -- registration params -- modparam("registrar", "nat_flag", 2) modparam("registrar", "min_expires", 60) modparam("registrar", "max_expires", 86400) modparam("registrar", "default_expires", 3600) modparam("registrar", "append_branches", 1)
# -- avp params -- modparam("avpops", "avp_url", "mysql://ser:heslo@localhost/ser") modparam("avpops", "avp_table", "usr_preferences") #modparam("avpops", "use_domain", "1") modparam("avpops", "uuid_column", "uuid") modparam("avpops", "username_column", "username") modparam("avpops", "domain_column", "domain") modparam("avpops", "attribute_column", "attribute") modparam("avpops", "value_column", "value") modparam("avpops", "type_column", "type") modparam("avpops", "avp_aliases", "voicemail=i:500;calltype=i:700;fwd_no_answer_type=i:701;fwd_busy_type=i:702") # To use more than one tables example #modparam("avpops", "db_scheme", "scheme1:table=subscriber;uuid_column=uuid;value_column=first_name")
# -- tm params -- modparam("tm", "fr_timer", 15) modparam("tm", "fr_inv_timer", 22) modparam("tm", "wt_timer", 5) modparam("tm", "fr_inv_timer_avp", "inv_timeout")
# -- pdt params -- modparam("pdt", "db_table", "prefix_domain") modparam("pdt", "prefix", "") modparam("pdt", "hsize_2pow", 2) modparam("pdt", "sync_time", 300) modparam("pdt", "clean_time", 600)
# -- logging params modparam("xlog", "buf_size", 8192)
# -- group params -- modparam("group", "table", "grp") modparam("group", "user_column", "username") modparam("group", "domain_column", "domain") modparam("group", "group_column", "grp")
# -- speeddial params -- modparam("speeddial", "user_column", "username") modparam("speeddial", "domain_column", "domain") modparam("speeddial", "sd_user_column", "username_from_req_uri") modparam("speeddial", "sd_domain_column", "domain_from_req_uri") modparam("speeddial", "new_uri_column", "new_request_uri") modparam("speeddial", "domain_prefix", "tel")
#modparam("auth", "rpid_prefix", "Antek SIP <sip:") #modparam("auth", "rpid_suffix", "@ser.xxx.net.tw;user=phone>;party=calling;screen=no;privacy=on")
# ------------------------- request routing logic -------------------
# main routing logic
route {
# ------------------------------------------------------------------------ # Sanity Check Section # ------------------------------------------------------------------------ if (!mf_process_maxfwd_header("10")) { sl_send_reply("483", "Too Many Hops"); break; };
if (msg:len > max_len) { sl_send_reply("513", "Message Overflow"); break; };
# ------------------------------------------------------------------------ # NOTIFY Keep-Alive Section # ------------------------------------------------------------------------ if ((method=="NOTIFY") && search("^Event: keep-alive")) { sl_send_reply("200", "OK"); break; };
#if ((method=="NOTIFY") && (uri=~"^sip:700@")) { # sl_send_reply("200", "OK"); # break; #};
# ------------------------------------------------------------------------ # NOTIFY Message-Summary Section # # Event: Message-Summary is used to control the message waiting indicator # ------------------------------------------------------------------------ #if ((method=="NOTIFY") && (src_ip=="99.99.99.100") && search("^Event: message-summary")) { # if (lookup("location")) { # t_relay(); # }; # break; #};
# ------------------------------------------------------------------------ # OPTIONS Section # ------------------------------------------------------------------------ if (method=="OPTIONS") { options_reply(); break; };
# ------------------------------------------------------------------------ # NAT Test Section #1 # ------------------------------------------------------------------------ if (method=="REGISTER" && client_nat_test("3")) { fix_contact(); force_rport(); setflag(2); };
# ------------------------------------------------------------------------ # Click2Dial Section # 14 # ------------------------------------------------------------------------ #if (src_ip=="99.99.99.99" && (search("^From: <sip:700@") || search("^To: <sip:700@"))) { # setflag(14); #};
# ------------------------------------------------------------------------ # Registration Section # ------------------------------------------------------------------------ if (method=="REGISTER") {
# allow all requests from user 700 - the Click2Dial controller if (!isflagset(14)) { if (!is_from_local()) { sl_send_reply("403", "Unknown Domain"); break; }; if (!www_authorize("", "subscriber")) { www_challenge("", "0"); break; }; if (!check_to()) { sl_send_reply("401", "Unauthorized"); break; }; # To - Use To username and (optionally) domain to check if (is_user_in("To", "demo-disabled")) { sl_send_reply("403", "Your evaluation period has expired"); break; }; # To - Use To username and (optionally) domain to check if (is_user_in("To", "disabled")) { sl_send_reply("403", "Your account has been disabled"); break; }; };
# snom sip phones use this header to start their # keep-alive mechanism for NAT bindings append_to_reply("P-NAT-Refresh: 15\r\n");
if (!save("location")) { sl_reply_error(); }; break; };
# ------------------------------------------------------------------------ # Accounting Section # 1 # # NOTE: We test for flag 14 because we do not want to record Click2Dial # entries # ------------------------------------------------------------------------ if ((method=="INVITE" || method=="BYE") && !isflagset(14)) { setflag(1); };
# ------------------------------------------------------------------------ # NAT Tear-Down Section # ------------------------------------------------------------------------ if ((method == "BYE" || method == "CANCEL")) { end_media_session(); };
# ------------------------------------------------------------------------ # Record Route Section # # we record-route all messages -- to make sure that subsequent messages # will go through our proxy; that's particularly good if upstream and # downstream entities use different transport protocol # ------------------------------------------------------------------------ if (!method=="REGISTER") { record_route(); };
# ------------------------------------------------------------------------ # Loose Route Section # # Grant route routing if route headers present # ------------------------------------------------------------------------ if (loose_route()) { route(2); break; };
# ------------------------------------------------------------------------ # Prefix To Domain Section # # Convert the prefix defined on grp table to its own domain name # ------------------------------------------------------------------------ prefix2domain();
# ------------------------------------------------------------------------ # Message Waiting Indicator SUBSCRIBE Section # # Make sure all SUBSCRIBE messages with header "Event: message-summary" # are sent to the voicemail server # ------------------------------------------------------------------------ if ((method=="SUBSCRIBE") && search("^Event: message-summary")) { rewritehostport("xxx.xxx.190.243:5060"); t_relay(); break; };
# ------------------------------------------------------------------------ # NAT Test Section #1 # ------------------------------------------------------------------------ if (client_nat_test("3") && !search("^Record-Route:")) { force_rport(); fix_contact(); };
# ------------------------------------------------------------------------ # Enhanced Voicemail Applications Section # # Access additional Asterisk applications at extension 701 and 702 # ------------------------------------------------------------------------ #if (uri=~"^sip:70[1|2]@") { # route(5); # break; #};
# ------------------------------------------------------------------------ # PSTN Section # ------------------------------------------------------------------------ # # This is an example of US phone call. # #if (method=="INVITE") { # if (uri=~"^sip:1[0-9]{10}@") { # strip(1); # }; # if ((uri=~"^sip:911@.*") || (uri=~"^sip:900[0-9]{7}@") || (uri=~"^sip:976[0-9]{7}@")) { # sl_send_reply("503", "Service Unavailable"); # break; # }; #}; if (method=="INVITE") { ## Deny PSTN to 0204 and 095 on Tawan if ((uri=~"^sip:0204[0-9]*@") || (uri=~"^sip:095[0-9]*@")) { sl_send_reply("503", "Service Unavailable"); break; }; };
# ------------------------------------------------------------------------ # Alias Routing Section # ------------------------------------------------------------------------ lookup("aliases"); if (!uri==myself) { route(2); break; };
# ------------------------------------------------------------------------ # Load ACL Section # ------------------------------------------------------------------------ if (method=="INVITE" && !isflagset(14)) { xlog("L_ERR", "Time:[%Tf] Method:<%rm> r-uri:<%ru>\n"); xlog("L_ERR", "IP:<%is> From:<%fu> To:<%tu> %ct\n"); #if (is_user_in("Request-URI", "voicemail")) { # setflag(31); #}; if (is_from_local() || is_uri_host_local()) { #if (is_user_in("From", "411")) { # setflag(30); ## some call from directory service #}; # Check user from grp table if (is_user_in("From", "int")) { log(1, "SER: a INT user\n"); setflag(29); }; if (is_user_in("From", "free-pstn")) { log(1, "SER: a FREE-PSTN user\n"); setflag(28); }; if (avp_db_load("$from/username", "s:callidblock")) { if (avp_check("s:callidblock", "eq/y/i")) { setflag(25); }; }; }; if (avp_db_load("$ruri/username", "s:anoncallrej")) { if (avp_check("s:anoncallrej", "eq/y/i")) { log(1, "SER: a ANON-CALL-REJ user\n"); setflag(24); }; }; };
# ------------------------------------------------------------------------ # Anonymous Call Rejection Section # 24 # ------------------------------------------------------------------------ if (isflagset(24) && (method=="INVITE") && search("^(f|F)rom:.*(a|A)nonymous")) { route(8); break; };
# ------------------------------------------------------------------------ # 411 Directory Assistance Section # 30 # ------------------------------------------------------------------------ #if (method=="INVITE" && uri=~"^sip:411@.*") { # if (isflagset(30)) { # avp_write("$from", "i:34"); # avp_pushto("$ruri", "i:34"); # strip_tail(7); # subst_uri('/^sip:([0-9]+)@(.*)$/sip:\15551212@\2/i'); # avp_delete("i:34"); # route(3); # break; # }; # sl_send_reply("503", "Service Unavailable"); # break; #};
# ------------------------------------------------------------------------ # Speed Dialing Section # ------------------------------------------------------------------------ if ((method=="INVITE") && (uri=~"^sip:[0-9]{2}@.*")) { sd_lookup("speed_dial"); };
# ------------------------------------------------------------------------ # 011 International Call Section # 29 # ------------------------------------------------------------------------ #if (method=="INVITE" && uri=~"^sip:011[0-9]*@") { # if (isflagset(29)) { # route(6); # } else { # sl_send_reply("503", "Service Unavailable"); # }; # break; #};
# ------------------------------------------------------------------------ # 002 International Call Section # 29 # ------------------------------------------------------------------------ if (method=="INVITE" && uri=~"^sip:002[0-9]*@") { if (isflagset(29)) { log(1, "SER: an International Call route(6)\n"); route(6); } else { sl_send_reply("503", "Service Unavailable"); }; break; };
# ------------------------------------------------------------------------ # 0XXXXXXXXX Domestic Call Section # 29 # ------------------------------------------------------------------------ if (method=="INVITE" && uri=~"^sip:0[0-9]{9}@") { if (isflagset(29)) { log(1, "SER: a Domestic Call route(6)\n"); route(6); } else { sl_send_reply("503", "Service Unavailable"); }; break; };
# ------------------------------------------------------------------------ # URI Compare Section # # Here we compare the "from" and "to" to see if the caller is dialing # their own extension. If so then we route to voicemail(31) if needed # ------------------------------------------------------------------------ if (method=="INVITE") { avp_write("$from", "i:34"); if (avp_check("i:34", "eq/$ruri/i")) { if (isflagset(31)) { route(5); break; } else { sl_send_reply("486", "Busy"); break; }; }; };
# ------------------------------------------------------------------------ # Call Block Section # ------------------------------------------------------------------------ #if (is_caller_blocked()) { # route(7); # break; #};
# ------------------------------------------------------------------------ # Do Not Disturb Section # ------------------------------------------------------------------------ if (avp_db_load("$ruri/username", "s:donotdisturb")) { if (avp_check("s:donotdisturb", "eq/y/i")) { route(5); break; }; };
# ------------------------------------------------------------------------ # Blind Call Forwarding Section # ------------------------------------------------------------------------ if (method=="INVITE") { log(1, "SER: BLIND CALL FORWARDING\n"); # here we must store the current (aka original) R-URI because if # we set call forwarding and the forwarded number is busy then we # need to use this original R-URI to determine which voicemail # box we should go to if (isflagset(31)) { avp_write("$ruri", "$voicemail"); }; if (avp_db_load("$ruri/username", "s:callfwd")) { avp_pushto("$ruri", "s:callfwd"); # lookup the call fowarding number to see if it is a served # sip number or a PSTN number # check forwarding number rules log(1, "SER: Check Forwarding Number Rules\n"); route(1); #if (avp_check("$calltype", "eq/-/i")) { # log(1, "SER: 503 Service Unavailable 1\n"); # sl_send_reply("503", "Service Unavailable"); # break; #}; # test for domestic PSTN gateway if (uri=~"^sip:0[1-9]{9}@") { #if (avp_check("$calltype", "eq/dom/i")) { log(1, "SER: Start a domestic PSTN call route(3)\n"); route(3); break; }; # test for international PSTN gateway if (uri=~"^sip:002[1-9]*@") { # if (avp_check("$calltype", "eq/int/i")) { log(1, "SER: Start an international PSTN call route(6)\n"); route(6); break; }; }; };
# ------------------------------------------------------------------------ # Call Routing Section # ------------------------------------------------------------------------ if (!lookup("location")) { # if flag 31 (ie voicemail) is set and we made it here this means # the user's phone is not registered anywhere. We'll forward to # voicemail after this block because we need to check the call # forward settings first if (isflagset(31)) { # flag 19 means the user has voicemail but is not online # so we need to remember to send to voicemail if call # forwarding is not enabled setflag(19); }; if (method=="INVITE") { if (does_uri_exist()) { # subscriber record found, but they're offline log(1, "SER: Temporarily Unavailable\n"); sl_send_reply("480", "Temporarily Unavailable"); break; }; if (uri=~"^sip:0[0-9]{9}@") { # Send to PSTN Gateway if (isflagset(28) || (is_user_in("From", "int")) || (is_user_in("From", "free-pstn"))) { log(1, "SER: Start a PSTN call\n"); route(3); } else { log(1, "SER: 503 Service Unavailable 2\n"); sl_send_reply("503", "Service Unavailable"); }; break; }; sl_send_reply("404", "User Not Found"); break; }; };
# ------------------------------------------------------------------------ # Call Forwarding Section # ------------------------------------------------------------------------ if (method=="INVITE") { # save R-URI in a temp AVP for later use avp_write("$ruri", "i:99"); # only load the forward no answer option if voice mail is not enabled if (!isflagset(31)) { if (avp_db_load("$ruri/username", "s:fwdnoanswer")) { route(1); #if (!avp_check("$calltype", "eq/-/i")) { # if (avp_check("$calltype", "eq/dom/i")) { # avp_write("dom", "$fwd_no_answer_type"); # } else if (avp_check("$calltype", "eq/int/i")) { # avp_write("int", "$fwd_no_answer_type"); # } else { # avp_write("sip", "$fwd_no_answer_type"); # } setflag(27); #}; }; }; if (avp_db_load("$ruri/username", "s:fwdbusy")) { route(1); #if (!avp_check("$calltype", "eq/-/i")) { # if (avp_check("$calltype", "eq/dom/i")) { # avp_write("dom", "$fwd_busy_type"); # } else if (avp_check("$calltype", "eq/int/i")) { # avp_write("int", "$fwd_busy_type"); # } else { # avp_write("sip", "$fwd_busy_type"); # } setflag(26); #}; }; avp_pushto("$ruri", "i:99"); }; if (isflagset(19)) { # send to voicemail route(5); } else { route(2); }; }
route[1] {
# Here we have route checks for all the call forwarding stuff. # The return values are passed as AVP $calltype as follows: # # "-" = R-URI is not allowed # "dom" = R-RURI is a domestic call # "int" = R-RURI is an international call # "sip" = R-RURI is a sip call
avp_write("sip", "$calltype");
# US international call #if (uri=~"^sip:1[0-9]{10}@") { # strip(1); #};
# Call rejected #if ((uri=~"^sip:70[1|2]@") || (uri=~"^sip:411@.*") || # (uri=~"^sip:911@.*") || (uri=~"^sip:900[0-9]{7}@") || # (uri=~"^sip:976[0-9]{7}@")) { # break; #}; if ((uri=~"^sip:0204[0-9]*@") || (uri=~"^sip:095[0-9]*@") || (uri=~"^sip:[0-9]{3}@")) { break; }; log(1, "SER: Look aliases\n"); lookup("aliases"); log(1, "SER: Look location\n"); if (!lookup("location")) { if (uri=~"^sip:0[0-9]{9}@") { # test for domestic PSTN number if (isflagset(28)) { log(1, "SER isflagset 28 (domestic)\n"); avp_write("dom", "$calltype"); }; } else if (uri=~"^sip:002[0-9]*@") { # test for international PSTN number if (isflagset(29)) { log(1, "SER isflagset 29 (int)\n"); avp_write("int", "$calltype"); }; }; break; }; log(1, "SER isflagset (sip)\n"); avp_write("sip", "$calltype"); }
route[2] { log(1, "SER: SIP Call On-Net section route(2)\n"); if ((method=="INVITE") && !allow_trusted()) { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; }; if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (isflagset(25)) { replace("^From:(.*)>" , "From: "Anonymous" sip:someone@anonymous.invalid"); }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; t_on_failure("1"); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); };
}
route[3] { log(1, "SER: International Call Off-Net section route(3)\n");
# All Domestic Calls Go To CISCO 5300 if (method=="INVITE") { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; # enable caller id blocking for PSTN calls if (isflagset(25)) { append_rpid_hf(); }; }; # SIP->PSTN calls get 45 seconds to timeout log(1, "SER: Connecting to PSTN.....\n"); avp_write("i:45", "inv_timeout"); rewritehost("xxx.xxx.190.243"); #rewritehostport("xxx.xxx.190.248:5065"); if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; if (isflagset(31)) { # is voice mail? t_on_failure("1"); }; t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[4] { log(1, "SER: Voice Mail section route(4)\n");
# voicemail route #1 # # this path this executed during these conditions: # # cond 1) the called number is in the location table # but the callee did not answer the phone # (ie, failover to voicemail)
if (isflagset(25)) { replace("^From:(.*)>" , "From: "Anonymous" sip:someone@anonymous.invalid"); }; rewritehostport("99.99.99.100:5060"); append_branch(); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[5] { log(1, "SER: Voice Mail section route(5)\n");
# voicemail route #2 # # this path this executed during these conditions: # # cond 1) the called number is not in the location table # cond 2) the from_uri == to_uri (ie, caller==callee)
if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; rewritehostport("99.999.100:5060"); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[6] { log(1, "SER: Domestic Call Off-Net section route(6)\n"); # All International Calls Go To CISCO 5300 if (method=="INVITE") { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; # enable caller id blocking for PSTN calls if (isflagset(25)) { append_rpid_hf(); }; }; # SIP->PSTN calls get 45 seconds to timeout avp_write("i:45", "inv_timeout"); rewritehost("xxx.xxx.190.243"); #rewritehostport("xxx.xxx.190.248:5065"); if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[7] { log(1, "SER: Caller Blocked section route(7)\n");
# caller blocked announcment # # this path this executed if a caller has been blocked if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; rewriteuri("sip:699@99.99.99.100:5060"); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[8] { log(1, "SER: Anonymous Call Rejection section route(8)\n"); # anonymous call rejection announcment # # this path this executed for anonymous callers
if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; rewriteuri("sip:698@99.99.99.100:5060"); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
onreply_route[1] { # Not all 2xx messages have a content body so here we # make sure our Content-Length > 0 to avoid a parse error if (status=~"(180)|(183)|2[0-9][0-9]") { if (!search("^Content-Length:\ 0")) { use_media_proxy(); }; }; if (client_nat_test("1")) { fix_contact(); }; }
failure_route[1] { log(1, "SER: Failure Route section failure_route(1)\n");
# if caller hung up then don't sent to voicemail if (t_check_status("487")) { break; }; if (isflagset(26) && t_check_status("486")) { # forward busy is flag 26 if (avp_pushto("$ruri", "s:fwdbusy")) { log(1, "SER: fork to fwdbusy\n"); avp_delete("s:fwdbusy"); append_branch(); resetflag(26); # test for domestic PSTN gateway if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_busy_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: Busy Failure and Jump to route(6)\n"); route(6); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_busy_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: Busy Failure and Jump to route(3)\n"); route(3); } else { # default to sip call log(1, "SER: Busy Failure and Jump to route(2)\n"); route(2); }; break; }; };
# here we can have either voicemail __OR__ forward no answer if (isflagset(27) && t_check_status("408")) { # forward no answer is flag 27 if (avp_db_load("$ruri/username", "s:fwdnoanswer")) { avp_pushto("$ruri", "s:fwdnoanswer"); log(1, "SER: fork to fwdnoanswer\n"); avp_delete("s:fwdnoanswer"); append_branch(); resetflag(27); if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_no_answer_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: No Answer Failure and Jump to route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_no_answer_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: No Answer Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: No Answer Failure and Jump to route(2)\n"); route(2); }; break; }; } else if (isflagset(31) && avp_pushto("$ruri", "$voicemail")) { avp_delete("$voicemail"); log(1, "SER: No Answer Failure and Jump to route(4)\n"); route(4); break; }; }
Sorry, Charles, but your ser.cfg is too unwieldy (and with no indentation) to successfully be able to trace the routing logic. However, trying to go through the logic in my head, it seems that there is something wrong with your basic logic. Remember: every single message will start at the top route{} and then go through your logic until reaching a t_relay (or similar), sl_send_reply or break. If you don't call t_relay, the route[x] will return to the place where it was called and then continue processing. Your use of flags to control the routing makes ser.cfg very hard to read. My suggestion is that you strip away everything you don't need just to test what you are trying to achieve. When posting something, include your simplified ser.cfg, as well as an ngrep trace, it is a lot easier to help you. g-)
Charles Wang wrote:
Dear Greger:
I call t_on_failure("1"); on my route[2] (this is SIP to SIP route). If I make a SIP to SIP call failed, it should go to another route. For example: UA 1011 call 1022, and 1022 setting busy forward to PSTN(0939749xxx).
So, first route is route[2] (I setting t_on_failure("1") here), then if busy condiction, it will go to route[3](for PSTN).
I still can not understand where to add what you post before. So I add my complete ser.cfg in this post.
Thank you for your kind.
Best Regard Charles
ser.cfg:
# # $Id: ser.cfg,v 1.25 2004/11/30 16:28:24 andrei Exp $ # # simple quick-start config script #
# ----------- global configuration parameters ------------------------
debug=10 # debug level (cmd line: -dddddddddd) fork=yes log_stderror=no # (cmd line: -E)
/* Uncomment these lines to enter debugging mode fork=no log_stderror=yes */
listen=xxx.xxx.190.248
alias=ser.xxx.net.tw alias=ser alias=xxx.xxx.190.248
check_via=no # (cmd. line: -v) dns=no # (cmd. line: -r) rev_dns=no # (cmd. line: -R) port=5060 children=4 fifo_mode=0666 fifo="/tmp/ser_fifo" fifo_db_url="mysql://ser:heslo@localhost/ser"
# mhomed -- enable calculation of outbound interface. # useful on multihomed servers. mhomed=0
# ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database loadmodule "/usr/local/lib/ser/modules/mysql.so" loadmodule "/usr/local/lib/ser/modules/sl.so" loadmodule "/usr/local/lib/ser/modules/tm.so" loadmodule "/usr/local/lib/ser/modules/rr.so" loadmodule "/usr/local/lib/ser/modules/maxfwd.so" loadmodule "/usr/local/lib/ser/modules/usrloc.so" loadmodule "/usr/local/lib/ser/modules/registrar.so" loadmodule "/usr/local/lib/ser/modules/textops.so" loadmodule "/usr/local/lib/ser/modules/auth.so" loadmodule "/usr/local/lib/ser/modules/auth_db.so" loadmodule "/usr/local/lib/ser/modules/exec.so" loadmodule "/usr/local/lib/ser/modules/avpops.so" loadmodule "/usr/local/lib/ser/modules/domain.so" loadmodule "/usr/local/lib/ser/modules/group.so" loadmodule "/usr/local/lib/ser/modules/uri.so" loadmodule "/usr/local/lib/ser/modules/uri_db.so" loadmodule "/usr/local/lib/ser/modules/permissions.so" loadmodule "/usr/local/lib/ser/modules/speeddial.so" loadmodule "/usr/local/lib/ser/modules/acc.so" loadmodule "/usr/local/lib/ser/modules/pdt.so" loadmodule "/usr/local/lib/ser/modules/options.so" loadmodule "/usr/local/lib/ser/modules/mediaproxy.so" loadmodule "/usr/local/lib/ser/modules/xlog.so"
# ----------------- setting module-specific parameters ---------------
# -- mediaproxy params -- modparam("mediaproxy", "natping_interval", 30) modparam("mediaproxy", "sip_asymmetrics", "/usr/local/etc/ser/sip-asymmetric-clients") modparam("mediaproxy", "rtp_asymmetrics", "/usr/local/etc/ser/rtp-asymmetric-clients")
# -- usrloc params -- # # 0 = disable # 1 = write-through # 2 = write-back # modparam("usrloc", "db_mode", 1) modparam("usrloc", "timer_interval", 60) modparam("usrloc", "desc_time_order", 1)
# -- auth params -- modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password")
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# -- db_url params -- modparam("acc|auth_db|domain|group|permissions|speeddial|uri_db|usrloc|pdt", "db_url", "mysql://ser:heslo@localhost/ser")
# -- use_domain params -- modparam("auth_db|group|registrar|speeddial|uri_db|usrloc", "use_domain", 0)
# -- permissions params -- modparam("permissions", "db_mode", 1) modparam("permissions", "trusted_table", "trusted")
# -- accounting params -- modparam("acc", "db_flag", 1) modparam("acc", "db_missed_flag", 1) modparam("acc", "log_fmt", "cdfimorstup") modparam("acc", "log_level", 1) modparam("acc", "failed_transactions", 1) modparam("acc", "report_cancels", 1) modparam("acc", "report_ack", 0)
# -- domain params -- modparam("domain", "db_mode", 1)
# ------------- exec parameters modparam("exec", "setvars", 1) modparam("exec", "time_to_kill", 10)
# -- registration params -- modparam("registrar", "nat_flag", 2) modparam("registrar", "min_expires", 60) modparam("registrar", "max_expires", 86400) modparam("registrar", "default_expires", 3600) modparam("registrar", "append_branches", 1)
# -- avp params -- modparam("avpops", "avp_url", "mysql://ser:heslo@localhost/ser") modparam("avpops", "avp_table", "usr_preferences") #modparam("avpops", "use_domain", "1") modparam("avpops", "uuid_column", "uuid") modparam("avpops", "username_column", "username") modparam("avpops", "domain_column", "domain") modparam("avpops", "attribute_column", "attribute") modparam("avpops", "value_column", "value") modparam("avpops", "type_column", "type") modparam("avpops", "avp_aliases", "voicemail=i:500;calltype=i:700;fwd_no_answer_type=i:701;fwd_busy_type=i:702") # To use more than one tables example #modparam("avpops", "db_scheme", "scheme1:table=subscriber;uuid_column=uuid;value_column=first_name")
# -- tm params -- modparam("tm", "fr_timer", 15) modparam("tm", "fr_inv_timer", 22) modparam("tm", "wt_timer", 5) modparam("tm", "fr_inv_timer_avp", "inv_timeout")
# -- pdt params -- modparam("pdt", "db_table", "prefix_domain") modparam("pdt", "prefix", "") modparam("pdt", "hsize_2pow", 2) modparam("pdt", "sync_time", 300) modparam("pdt", "clean_time", 600)
# -- logging params modparam("xlog", "buf_size", 8192)
# -- group params -- modparam("group", "table", "grp") modparam("group", "user_column", "username") modparam("group", "domain_column", "domain") modparam("group", "group_column", "grp")
# -- speeddial params -- modparam("speeddial", "user_column", "username") modparam("speeddial", "domain_column", "domain") modparam("speeddial", "sd_user_column", "username_from_req_uri") modparam("speeddial", "sd_domain_column", "domain_from_req_uri") modparam("speeddial", "new_uri_column", "new_request_uri") modparam("speeddial", "domain_prefix", "tel")
#modparam("auth", "rpid_prefix", "Antek SIP <sip:") #modparam("auth", "rpid_suffix", "@ser.xxx.net.tw;user=phone>;party=calling;screen=no;privacy=on")
# ------------------------- request routing logic -------------------
# main routing logic
route {
#
# Sanity Check Section #
if (!mf_process_maxfwd_header("10")) { sl_send_reply("483", "Too Many Hops"); break; };
if (msg:len > max_len) { sl_send_reply("513", "Message Overflow"); break; };
#
# NOTIFY Keep-Alive Section #
if ((method=="NOTIFY") && search("^Event: keep-alive")) { sl_send_reply("200", "OK"); break; };
#if ((method=="NOTIFY") && (uri=~"^sip:700@")) { # sl_send_reply("200", "OK"); # break; #};
#
# NOTIFY Message-Summary Section # # Event: Message-Summary is used to control the message waiting indicator #
#if ((method=="NOTIFY") && (src_ip=="99.99.99.100") && search("^Event: message-summary")) { # if (lookup("location")) { # t_relay(); # }; # break; #};
#
# OPTIONS Section #
if (method=="OPTIONS") { options_reply(); break; };
#
# NAT Test Section #1 #
if (method=="REGISTER" && client_nat_test("3")) { fix_contact(); force_rport(); setflag(2); };
#
# Click2Dial Section # 14 #
#if (src_ip=="99.99.99.99" && (search("^From: <sip:700@") || search("^To: <sip:700@"))) { # setflag(14); #};
#
# Registration Section #
if (method=="REGISTER") {
# allow all requests from user 700 - the Click2Dial controller if (!isflagset(14)) { if (!is_from_local()) { sl_send_reply("403", "Unknown Domain"); break; }; if (!www_authorize("", "subscriber")) { www_challenge("", "0"); break; }; if (!check_to()) { sl_send_reply("401", "Unauthorized"); break; };
# To - Use To username and (optionally) domain to check if (is_user_in("To", "demo-disabled")) { sl_send_reply("403", "Your evaluation period has expired"); break; };
# To - Use To username and (optionally) domain to check if (is_user_in("To", "disabled")) { sl_send_reply("403", "Your account has been disabled"); break; }; };
# snom sip phones use this header to start their # keep-alive mechanism for NAT bindings append_to_reply("P-NAT-Refresh: 15\r\n");
if (!save("location")) { sl_reply_error(); }; break; };
#
# Accounting Section # 1 # # NOTE: We test for flag 14 because we do not want to record Click2Dial # entries
#
if ((method=="INVITE" || method=="BYE") && !isflagset(14)) { setflag(1); };
#
# NAT Tear-Down Section #
if ((method == "BYE" || method == "CANCEL")) { end_media_session(); };
#
# Record Route Section # # we record-route all messages -- to make sure that subsequent messages # will go through our proxy; that's particularly good if upstream and # downstream entities use different transport protocol
#
if (!method=="REGISTER") { record_route(); };
#
# Loose Route Section # # Grant route routing if route headers present
#
if (loose_route()) { route(2); break; };
#
# Prefix To Domain Section # # Convert the prefix defined on grp table to its own domain name
#
prefix2domain();
#
# Message Waiting Indicator SUBSCRIBE Section # # Make sure all SUBSCRIBE messages with header "Event: message-summary" # are sent to the voicemail server
#
if ((method=="SUBSCRIBE") && search("^Event: message-summary")) { rewritehostport("xxx.xxx.190.243:5060"); t_relay(); break; };
#
# NAT Test Section #1 #
if (client_nat_test("3") && !search("^Record-Route:")) { force_rport(); fix_contact(); };
#
# Enhanced Voicemail Applications Section # # Access additional Asterisk applications at extension 701 and 702
#
#if (uri=~"^sip:70[1|2]@") { # route(5); # break; #};
#
# PSTN Section #
# # This is an example of US phone call. # #if (method=="INVITE") { # if (uri=~"^sip:1[0-9]{10}@") { # strip(1); # }; # if ((uri=~"^sip:911@.*") || (uri=~"^sip:900[0-9]{7}@") || (uri=~"^sip:976[0-9]{7}@")) { # sl_send_reply("503", "Service Unavailable"); # break; # }; #}; if (method=="INVITE") { ## Deny PSTN to 0204 and 095 on Tawan if ((uri=~"^sip:0204[0-9]*@") || (uri=~"^sip:095[0-9]*@")) { sl_send_reply("503", "Service Unavailable"); break; }; };
#
# Alias Routing Section #
lookup("aliases"); if (!uri==myself) { route(2); break; };
#
# Load ACL Section #
if (method=="INVITE" && !isflagset(14)) { xlog("L_ERR", "Time:[%Tf] Method:<%rm> r-uri:<%ru>\n"); xlog("L_ERR", "IP:<%is> From:<%fu> To:<%tu> %ct\n"); #if (is_user_in("Request-URI", "voicemail")) { # setflag(31); #}; if (is_from_local() || is_uri_host_local()) { #if (is_user_in("From", "411")) { # setflag(30); ## some call from directory service #};
# Check user from grp table if (is_user_in("From", "int")) { log(1, "SER: a INT user\n"); setflag(29); }; if (is_user_in("From", "free-pstn")) { log(1, "SER: a FREE-PSTN user\n"); setflag(28); }; if (avp_db_load("$from/username", "s:callidblock")) { if (avp_check("s:callidblock", "eq/y/i")) { setflag(25); }; }; }; if (avp_db_load("$ruri/username", "s:anoncallrej")) { if (avp_check("s:anoncallrej", "eq/y/i")) { log(1, "SER: a ANON-CALL-REJ user\n"); setflag(24); }; }; };
#
# Anonymous Call Rejection Section # 24 #
if (isflagset(24) && (method=="INVITE") && search("^(f|F)rom:.*(a|A)nonymous")) { route(8); break; };
#
# 411 Directory Assistance Section # 30 #
#if (method=="INVITE" && uri=~"^sip:411@.*") { # if (isflagset(30)) { # avp_write("$from", "i:34"); # avp_pushto("$ruri", "i:34"); # strip_tail(7); # subst_uri('/^sip:([0-9]+)@(.*)$/sip:\15551212@\2/i'); # avp_delete("i:34"); # route(3); # break; # }; # sl_send_reply("503", "Service Unavailable"); # break; #};
#
# Speed Dialing Section #
if ((method=="INVITE") && (uri=~"^sip:[0-9]{2}@.*")) { sd_lookup("speed_dial"); };
#
# 011 International Call Section # 29 #
#if (method=="INVITE" && uri=~"^sip:011[0-9]*@") { # if (isflagset(29)) { # route(6); # } else { # sl_send_reply("503", "Service Unavailable"); # }; # break; #};
#
# 002 International Call Section # 29 #
if (method=="INVITE" && uri=~"^sip:002[0-9]*@") { if (isflagset(29)) { log(1, "SER: an International Call route(6)\n"); route(6); } else { sl_send_reply("503", "Service Unavailable"); }; break; };
#
# 0XXXXXXXXX Domestic Call Section # 29 #
if (method=="INVITE" && uri=~"^sip:0[0-9]{9}@") { if (isflagset(29)) { log(1, "SER: a Domestic Call route(6)\n"); route(6); } else { sl_send_reply("503", "Service Unavailable"); }; break; };
#
# URI Compare Section # # Here we compare the "from" and "to" to see if the caller is dialing # their own extension. If so then we route to voicemail(31) if needed
#
if (method=="INVITE") { avp_write("$from", "i:34"); if (avp_check("i:34", "eq/$ruri/i")) { if (isflagset(31)) { route(5); break; } else { sl_send_reply("486", "Busy"); break; }; }; };
#
# Call Block Section #
#if (is_caller_blocked()) { # route(7); # break; #};
#
# Do Not Disturb Section #
if (avp_db_load("$ruri/username", "s:donotdisturb")) { if (avp_check("s:donotdisturb", "eq/y/i")) { route(5); break; }; };
#
# Blind Call Forwarding Section #
if (method=="INVITE") { log(1, "SER: BLIND CALL FORWARDING\n"); # here we must store the current (aka original) R-URI because if # we set call forwarding and the forwarded number is busy then we # need to use this original R-URI to determine which voicemail # box we should go to if (isflagset(31)) { avp_write("$ruri", "$voicemail"); }; if (avp_db_load("$ruri/username", "s:callfwd")) { avp_pushto("$ruri", "s:callfwd");
# lookup the call fowarding number to see if it is a served # sip number or a PSTN number
# check forwarding number rules log(1, "SER: Check Forwarding Number Rules\n"); route(1);
#if (avp_check("$calltype", "eq/-/i")) { # log(1, "SER: 503 Service Unavailable 1\n"); # sl_send_reply("503", "Service Unavailable"); # break; #};
# test for domestic PSTN gateway if (uri=~"^sip:0[1-9]{9}@") { #if (avp_check("$calltype", "eq/dom/i")) { log(1, "SER: Start a domestic PSTN call route(3)\n"); route(3); break; };
# test for international PSTN gateway if (uri=~"^sip:002[1-9]*@") { # if (avp_check("$calltype", "eq/int/i")) { log(1, "SER: Start an international PSTN call route(6)\n"); route(6); break; }; }; };
#
# Call Routing Section #
if (!lookup("location")) {
# if flag 31 (ie voicemail) is set and we made it here this means # the user's phone is not registered anywhere. We'll forward to # voicemail after this block because we need to check the call # forward settings first if (isflagset(31)) { # flag 19 means the user has voicemail but is not online # so we need to remember to send to voicemail if call # forwarding is not enabled setflag(19); };
if (method=="INVITE") { if (does_uri_exist()) { # subscriber record found, but they're offline log(1, "SER: Temporarily Unavailable\n"); sl_send_reply("480", "Temporarily Unavailable"); break; };
if (uri=~"^sip:0[0-9]{9}@") { # Send to PSTN Gateway if (isflagset(28) || (is_user_in("From", "int")) || (is_user_in("From", "free-pstn"))) { log(1, "SER: Start a PSTN call\n"); route(3); } else { log(1, "SER: 503 Service Unavailable 2\n"); sl_send_reply("503", "Service Unavailable"); }; break; }; sl_send_reply("404", "User Not Found"); break; }; };
#
# Call Forwarding Section #
if (method=="INVITE") {
# save R-URI in a temp AVP for later use avp_write("$ruri", "i:99");
# only load the forward no answer option if voice mail is not enabled if (!isflagset(31)) { if (avp_db_load("$ruri/username", "s:fwdnoanswer")) { route(1); #if (!avp_check("$calltype", "eq/-/i")) { # if (avp_check("$calltype", "eq/dom/i")) { # avp_write("dom", "$fwd_no_answer_type"); # } else if (avp_check("$calltype", "eq/int/i")) { # avp_write("int", "$fwd_no_answer_type"); # } else { # avp_write("sip", "$fwd_no_answer_type"); # } setflag(27); #}; }; }; if (avp_db_load("$ruri/username", "s:fwdbusy")) { route(1); #if (!avp_check("$calltype", "eq/-/i")) { # if (avp_check("$calltype", "eq/dom/i")) { # avp_write("dom", "$fwd_busy_type"); # } else if (avp_check("$calltype", "eq/int/i")) { # avp_write("int", "$fwd_busy_type"); # } else { # avp_write("sip", "$fwd_busy_type"); # } setflag(26); #}; }; avp_pushto("$ruri", "i:99"); }; if (isflagset(19)) { # send to voicemail route(5); } else { route(2); }; }
route[1] {
# Here we have route checks for all the call forwarding stuff. # The return values are passed as AVP $calltype as follows: # # "-" = R-URI is not allowed # "dom" = R-RURI is a domestic call # "int" = R-RURI is an international call # "sip" = R-RURI is a sip call
avp_write("sip", "$calltype");
# US international call #if (uri=~"^sip:1[0-9]{10}@") { # strip(1); #};
# Call rejected #if ((uri=~"^sip:70[1|2]@") || (uri=~"^sip:411@.*") || # (uri=~"^sip:911@.*") || (uri=~"^sip:900[0-9]{7}@") || # (uri=~"^sip:976[0-9]{7}@")) { # break; #}; if ((uri=~"^sip:0204[0-9]*@") || (uri=~"^sip:095[0-9]*@") || (uri=~"^sip:[0-9]{3}@")) { break; }; log(1, "SER: Look aliases\n"); lookup("aliases");
log(1, "SER: Look location\n"); if (!lookup("location")) { if (uri=~"^sip:0[0-9]{9}@") { # test for domestic PSTN number if (isflagset(28)) { log(1, "SER isflagset 28 (domestic)\n"); avp_write("dom", "$calltype"); }; } else if (uri=~"^sip:002[0-9]*@") { # test for international PSTN number if (isflagset(29)) { log(1, "SER isflagset 29 (int)\n"); avp_write("int", "$calltype"); }; }; break; }; log(1, "SER isflagset (sip)\n"); avp_write("sip", "$calltype"); }
route[2] { log(1, "SER: SIP Call On-Net section route(2)\n"); if ((method=="INVITE") && !allow_trusted()) { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; }; if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (isflagset(25)) { replace("^From:(.*)>" , "From: "Anonymous" sip:someone@anonymous.invalid"); }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; t_on_failure("1"); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); };
}
route[3] { log(1, "SER: International Call Off-Net section route(3)\n");
# All Domestic Calls Go To CISCO 5300 if (method=="INVITE") { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; # enable caller id blocking for PSTN calls if (isflagset(25)) { append_rpid_hf(); }; }; # SIP->PSTN calls get 45 seconds to timeout log(1, "SER: Connecting to PSTN.....\n"); avp_write("i:45", "inv_timeout"); rewritehost("xxx.xxx.190.243"); #rewritehostport("xxx.xxx.190.248:5065"); if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; if (isflagset(31)) { # is voice mail? t_on_failure("1"); }; t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[4] { log(1, "SER: Voice Mail section route(4)\n");
# voicemail route #1 # # this path this executed during these conditions: # # cond 1) the called number is in the location table # but the callee did not answer the phone # (ie, failover to voicemail)
if (isflagset(25)) { replace("^From:(.*)>" , "From: "Anonymous" sip:someone@anonymous.invalid"); }; rewritehostport("99.99.99.100:5060"); append_branch(); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[5] { log(1, "SER: Voice Mail section route(5)\n");
# voicemail route #2 # # this path this executed during these conditions: # # cond 1) the called number is not in the location table # cond 2) the from_uri == to_uri (ie, caller==callee)
if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; rewritehostport("99.999.100:5060"); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[6] { log(1, "SER: Domestic Call Off-Net section route(6)\n");
# All International Calls Go To CISCO 5300 if (method=="INVITE") { if (!proxy_authorize("", "subscriber")) { proxy_challenge("", "0"); break; } else if (!check_from()) { log(1, "Spoofed SIP call attempt"); sl_send_reply("403", "Use From=ID"); break; } else if (!(is_from_local() || is_uri_host_local())) { sl_send_reply("403", "Please register to use our service"); break; }; # enable caller id blocking for PSTN calls if (isflagset(25)) { append_rpid_hf(); }; }; # SIP->PSTN calls get 45 seconds to timeout avp_write("i:45", "inv_timeout"); rewritehost("xxx.xxx.190.243"); #rewritehostport("xxx.xxx.190.248:5065"); if (uri=~"[@:](192.168.|10.|172.(1[6-9]|2[0-9]|3[0-1]).)" && !search("^Route:")){ sl_send_reply("479", "We don't forward to private IP addresses"); break; }; if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[7] { log(1, "SER: Caller Blocked section route(7)\n");
# caller blocked announcment # # this path this executed if a caller has been blocked
if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; rewriteuri("sip:699@99.99.99.100:5060"); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
route[8] { log(1, "SER: Anonymous Call Rejection section route(8)\n");
# anonymous call rejection announcment # # this path this executed for anonymous callers
if (method=="INVITE" || method=="ACK") { use_media_proxy(); }; rewriteuri("sip:698@99.99.99.100:5060"); t_on_reply("1"); if (!t_relay()) { if (method=="INVITE" || method=="ACK") { end_media_session(); }; sl_reply_error(); }; }
onreply_route[1] { # Not all 2xx messages have a content body so here we # make sure our Content-Length > 0 to avoid a parse error if (status=~"(180)|(183)|2[0-9][0-9]") { if (!search("^Content-Length:\ 0")) { use_media_proxy(); }; }; if (client_nat_test("1")) { fix_contact(); }; }
failure_route[1] { log(1, "SER: Failure Route section failure_route(1)\n");
# if caller hung up then don't sent to voicemail if (t_check_status("487")) { break; }; if (isflagset(26) && t_check_status("486")) { # forward busy is flag 26
if (avp_pushto("$ruri", "s:fwdbusy")) { log(1, "SER: fork to fwdbusy\n"); avp_delete("s:fwdbusy"); append_branch(); resetflag(26);
# test for domestic PSTN gateway if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_busy_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: Busy Failure and Jump to route(6)\n"); route(6); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_busy_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: Busy Failure and Jump to route(3)\n"); route(3); } else { # default to sip call log(1, "SER: Busy Failure and Jump to route(2)\n"); route(2); }; break; }; };
# here we can have either voicemail __OR__ forward no answer if (isflagset(27) && t_check_status("408")) { # forward no answer is flag 27
if (avp_db_load("$ruri/username", "s:fwdnoanswer")) { avp_pushto("$ruri", "s:fwdnoanswer"); log(1, "SER: fork to fwdnoanswer\n"); avp_delete("s:fwdnoanswer"); append_branch(); resetflag(27);
if (uri=~"^sip:0[0-9]{9}@") { # if (avp_check("$fwd_no_answer_type", "eq/dom/i")) { # test for domestic PSTN gateway log(1, "SER: No Answer Failure and Jump to route(3)\n"); route(3); } else if (uri=~"^sip:002[1-9][0-9]*@") { # } else if (avp_check("$fwd_no_answer_type", "eq/int/i")) { # test for international PSTN gateway log(1, "SER: No Answer Failure and Jump to route(6)\n"); route(6); } else { # default to sip call log(1, "SER: No Answer Failure and Jump to route(2)\n"); route(2); }; break; }; } else if (isflagset(31) && avp_pushto("$ruri", "$voicemail")) { avp_delete("$voicemail"); log(1, "SER: No Answer Failure and Jump to route(4)\n"); route(4); break; }; }