Author Topic: Blind transfer on Cisco phones fails  (Read 6053 times)

lewis

  • Newbie
  • *
  • Posts: 10
    • View Profile
Blind transfer on Cisco phones fails
« on: March 12, 2015, 07:40:51 AM »
Hi,

I've been trying Yate and FreeSentral as a possible replacement for our current Asterisk SIP server. Unfortunately I'm having trouble whilst testing compatibility with our Cisco SPA504G phones.

I use extension 1056 to call extension 1024. I answer the call and use the phone's blind transfer button to try transferring the call to extension 1052. When I select the blind xfer button on handset 1024, enter extension 1052 and press 'dial', it says the transfer failed and puts the call back on hold.

An extract from Yate's debug log show this:


------
20150312131235.896679 <sip:INFO> 'udp:0.0.0.0:5060' received 462 bytes SIP message from 192.168.16.62:5060 [0x80211d900]
------
REFER sip:1024@x.x.x.166:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.16.62:5060;branch=z9h0000-000034c
From: <sip:1056@192.168.16.62>;tag=e07bbfb000000ca1i0
To: "1024" <sip:1024@x.x.x.166>;tag=770492463
Referred-By: "1056" <sip:1056@x.x.x.166>
Call-ID: 641670369@x.x.x.166
CSeq: 102 REFER
Max-Forwards: 70
Contact: "1056" <sip:1056@192.168.16.62:5060>
Refer-To: <sip:1052@x.x.x.166>
User-Agent: Cisco/SPA504G-7.5.6a
Content-Length: 0

------
20150312131235.907558 <sip:INFO> 'udp:0.0.0.0:5060' sending code 100 0x8020db600 to 192.168.16.62:5060 [0x80211d900]
------
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.16.62:5060;branch=z9hG4bK-f39a34c;received=192.168.16.62
From: <sip:1056@192.168.16.62>;tag=e07bbfb0419d8ca1i0
To: "1024" <sip:1024@x.x.x.166>;tag=770492463
Call-ID: 641670369@x.x.x.166
CSeq: 102 REFER
Server: YATE/5.4.0
Content-Length: 0


20150312131235.907776 <sip/3:STUB> initTransfer. Possible incomplete NOTIFY party creation [0x80e0b9800]
20150312131235.913491 <sip:INFO> 'udp:0.0.0.0:5060' sending code 481 0x80e061700 to 192.168.16.62:5060 [0x80211d900]
------
SIP/2.0 481 Call/Transaction Does Not Exist
Via: SIP/2.0/UDP 192.168.16.62:5060;branch=z9hG000-f390000;received=192.168.16.62
From: <sip:1056@192.168.16.62>;tag=e07bbfb000000ca1i0
To: "1024" <sip:1024@x.x.x.166>;tag=770492463
Call-ID: 641670369@x.x.x.166
CSeq: 102 REFER
Server: YATE/5.4.0
Allow: ACK, INVITE, BYE, CANCEL, REGISTER, REFER, OPTIONS, INFO
Content-Length: 0



With kind assistance from a few people in the #yate IRC channel, I have tried all kinds of things to figure out why this isn't working all without success :(

I've made sure to set a *98 trigger in the [transfer] subsection (to match the phone) in pbxassist.conf. I've set transfer=enable in ysipchan.conf. I changed the phone to send $OPTIONS messages instead of $NOTIFY messages because Yate said NOTIFY messages were not allowed despite adding NOTIFY=no to [methods] in ysipchan.conf.

Help or advice from anyone here please would be very much appreciated. Thank you in advance for your time and consideration.

Kind regards,
Lewis

marian

  • Sr. Member
  • ****
  • Posts: 381
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #1 on: March 13, 2015, 01:50:46 AM »
Hi,
A possible failure reason may be call route failure.
Can you post a log with sniffer enabled?

lewis

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #2 on: March 13, 2015, 09:13:11 AM »
Hi,

Thanks for your help.

Centurion_Dan helped with setting up the sniffer. Apparently the route fails because of a 'noauth' error. I'm not sure why that would happen though?


20150313112643.981270 <sip:INFO> 'udp:0.0.0.0:5060' received 464 bytes SIP message from 192.168.16.62:5060 [0x80210c900]
------
REFER sip:1024@x.x.x.166:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.16.62:5060;branch=z9hG4bK-c4b373f8
From: <sip:1056@192.168.16.62>;tag=c1e180a16e76fb2fi0
To: "1024" <sip:1024@x.x.x.166>;tag=679522944
Referred-By: "1056" <sip:1056@x.x.x.166>
Call-ID: 1117126792@x.x.x.166
CSeq: 102 REFER
Max-Forwards: 70
Contact: "1056" <sip:1056@192.168.16.62:5060>
Refer-To: <sip:1052@x.x.x.166>
User-Agent: Cisco/SPA504G-7.5.6a
Content-Length: 0

------
20150313112643.992061 <sip:INFO> 'udp:0.0.0.0:5060' sending code 100 0x80dc84980 to 192.168.16.62:5060 [0x80210c900]
------
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.16.62:5060;branch=z9hG4bK-c4b373f8;received=192.168.16.62
From: <sip:1056@192.168.16.62>;tag=c1e180a16e76fb2fi0
To: "1024" <sip:1024@x.x.x.166>;tag=679522944
Call-ID: 1117126792@x.x.x.166
CSeq: 102 REFER
Server: YATE/5.4.0
Content-Length: 0

------
20150313112643.992276 <sip/12:STUB> initTransfer. Possible incomplete NOTIFY party creation [0x80e108800]
Sniffed 'call.route' time=1426246003.992221
  thread=0x80e434020 'YSIP Transfer'
  data=0x0
  retval='(null)'
  param['id'] = 'sip/11'
  param['billid'] = '1426244789-8'
  param['caller'] = '1024'
  param['callername'] = '1024'
  param['called'] = '1052'
  param['calledname'] = ''
  param['diverter'] = '1056'
  param['divertername'] = '1056'
  param['reason'] = 'transfer'
  param['sip_referred-by'] = '"1056" <sip:1056@x.x.x.166>'
  param['sip_contact'] = '"1056" <sip:1056@192.168.16.62:5060>'
  param['sip_refer-to'] = '<sip:1052@x.x.x.166>'
  param['sip_user-agent'] = 'Cisco/SPA504G-7.5.6a'
Returned false 'call.route' delay=0.010829
  thread=0x80e434020 'YSIP Transfer'
  data=0x0
  retval='(null)'
  param['id'] = 'sip/11'
  param['billid'] = '1426244789-8'
  param['caller'] = '1024'
  param['callername'] = '1024'
  param['called'] = '1052'
  param['calledname'] = ''
  param['diverter'] = '1056'
  param['divertername'] = '1056'
  param['reason'] = 'transfer'
  param['sip_referred-by'] = '"1056" <sip:1056@x.x.x.166>'
  param['sip_contact'] = '"1056" <sip:1056@192.168.16.62:5060>'
  param['sip_refer-to'] = '<sip:1052@x.x.x.166>'
  param['sip_user-agent'] = 'Cisco/SPA504G-7.5.6a'
  param['handlers'] = 'javascript:15,cdrbuild:50,fileinfo:90,regexroute:95,iax:100,jingle:100,subscription:100,sip:100,sig:100,analog:100,regfile:100'
  param['copyparams'] = 'maxcall,call_type,already-auth,trusted-auth'
  param['pbxparams'] = 'maxcall,call_type,already-auth,trusted-auth,copyparams'
  param['error'] = 'noauth'
20150313112644.003786 <sip:INFO> 'udp:0.0.0.0:5060' sending code 481 0x80e065c40 to 192.168.16.62:5060 [0x80210c900]
------
SIP/2.0 481 Call/Transaction Does Not Exist
Via: SIP/2.0/UDP 192.168.16.62:5060;branch=z9hG4bK-c4b373f8;received=192.168.16.62
From: <sip:1056@192.168.16.62>;tag=c1e180a16e76fb2fi0
To: "1024" <sip:1024@x.x.x.166>;tag=679522944
Call-ID: 1117126792@x.x.x.166
CSeq: 102 REFER
Server: YATE/5.4.0
Allow: ACK, INVITE, BYE, CANCEL, REGISTER, REFER, OPTIONS, INFO, NOTIFY
Content-Length: 0

marian

  • Sr. Member
  • ****
  • Posts: 381
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #3 on: March 16, 2015, 02:04:14 AM »
You have somewhere a rule setting error='noauth'.
Check it.

lewis

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #4 on: March 16, 2015, 07:44:46 AM »
Oh right! I don't think I've created any rules yet though, everything should be using the default configuration for Yate / FreeSentral. Do you have any pointers for where I might find what is causing the 'noauth' problem please?

marian

  • Sr. Member
  • ****
  • Posts: 381
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #5 on: March 16, 2015, 09:31:55 AM »
Look at the 'handlers' parameter when the message returns.
Except for javascript and regexroute the other modules listed there don't set the error parameter.
I assume these 2 modules are the suspects.
javascript means some script: try to start yate without loading it.
regexroute: add some output to debug it: you may use the echo function.

lewis

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #6 on: March 16, 2015, 09:43:34 AM »
Thank you for your help!

I've checked javascript.conf, it only loads the default Eliza chat bot.

I've not made any changes to regexroute.conf, it has these defaults I think:

${address}^127\.0\.0\.=goto localhost
${username}.=goto localhost

[localhost]
; The following are for testing purposes
^99991001$=tone/dial
^99991002$=tone/busy
^99991003$=tone/ring
^99991004$=tone/specdial
^99991005$=tone/congestion
^99991006$=tone/outoforder
^99991007$=tone/milliwatt
^99991008$=tone/info

lewis

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #7 on: March 16, 2015, 09:47:19 AM »
According to http://www.ietf.org/rfc/rfc3515.txt the REFER message needs NOTIFY / subscription support in order to work. I believe by default this isn't available in Yate without a custom script or module to make it work. I'm beginning to wonder if fixing the 'noauth' error may not make a difference :s

marian

  • Sr. Member
  • ****
  • Posts: 381
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #8 on: March 16, 2015, 09:59:09 AM »
Hi,
Can you post the entire regexroute.conf?
Unload the javascript module.

lewis

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #9 on: March 17, 2015, 07:33:07 AM »
Yup!

; Minimalistic basic regular expressions information
;  ^ matches start of string
;  $ matches end of string
;  . matches any character
    matches one character in the list
    ;  [^list] matches one character not in list
    ;    Lists can be individual characters or ranges char-char. You can insert ]
    ;    by making it the first character in list and ^ by making it not the first
    ;    character
    ;  * matches preceeding expression any number of times (including zero)
    ;  \+ matches preceeding expression at least one time
    ;  \? matches preceeding expression zero or one time
    ;  \{N\} matches preceeding expression exactly N times
    ;  \{N,\} matches preceeding expression N or more times
    ;  \{N,M\} matches preceeding expression between N and M times
    ;  \| matches either the preceeding or following expression
    ;  \( \) captures the contained subexpression
    ; Remember matches are greedy, they will match as much as possible
    ; You must escape ^ $ . * [ and \ with \ whenever you want them to be normal
    ;  characters except in lists
    ; Please see the manual pages for grep and sed for more information

    ; Functions callable in the right-hand side:
    ;  $() = a ; character
    ;  $($) = a $ character
    ;  $(++N) = N+1
    ;  $(--N) = N-1
    ;  $(length,STRING) = length of STRING
    ;  $(upper,STRING) = STRING converted to upper case
    ;  $(lower,STRING) = STRING converted to lower case
    ;  $(chr,N) = character with numeric code N
    ;  $(hex,N[,LEN[,SEP]]) = little endian hexadecimal value of N with space or SEP between octets
    ;  $(add,VAL1,VAL2[,LEN]) = VAL1+VAL2 left filled to LEN or length of VAL1
    ;  $(sub,VAL1,VAL2[,LEN]) = VAL1-VAL2 left filled to LEN or length of VAL1
    ;  $(mul,VAL1,VAL2[,LEN]) = VAL1*VAL2 left filled to LEN or length of VAL1
    ;  $(div,VAL1,VAL2[,LEN]) = VAL1/VAL2 left filled to LEN or length of VAL1
    ;  $(mod,VAL1,VAL2[,LEN]) = VAL1%VAL2 left filled to LEN or length of VAL1
    ;  $(eq,VAL1,VAL2) = "true" if VAL1 = VAL2 (numerically), "false" otherwise
    ;  $(ne,VAL1,VAL2) = "true" if VAL1 != VAL2 (numerically), "false" otherwise
    ;  $(lt,VAL1,VAL2) = "true" if VAL1 < VAL2, "false" otherwise
    ;  $(gt,VAL1,VAL2) = "true" if VAL1 > VAL2, "false" otherwise
    ;  $(le,VAL1,VAL2) = "true" if VAL1 <= VAL2, "false" otherwise
    ;  $(ge,VAL1,VAL2) = "true" if VAL1 >= VAL2, "false" otherwise
    ;  $(streq,VAL1,VAL2) = "true" if VAL1 = VAL2 (string), "false" otherwise
    ;  $(strne,VAL1,VAL2) = "true" if VAL1 != VAL2 (string), "false" otherwise
    ;  $(strpos,VAL1,VAL2) = 0-based position of VAL1 in VAL2, -1 if not found
    ;  $(random,STRING) = STRING with each ? character replaced with a random digit
    ;  $(index,N,ITEM1,ITEM2,...) = N-th (modulo length of list) item in list
    ;  $(rotate,N,ITEM1,ITEM2,...) = list rotated N (modulo length of list) times
    ;  $(config,SECTION,KEY) = value of KEY= in
[SECTION] of main config file (yate.conf, yate-qt4.conf)
;  $(engine,NAME) = value of Engine's runtime parameter NAME
;  $(runid) = the current Engine run identifier
;  $(nodename) = the node name the Engine runs as, may be empty
;  $(threadname) = name of the thread that dispatched the message, may be empty
;  $(dispatching) = the reentry depth, 0 if the message is not generated locally
;  $(message,name) = name of the message handled
;  $(message,time) = time of the message handled, seconds since UNIX Epoch
;  $(message,broadcast) = true if the message is a broadcast, false otherwise
;  $(message,count) = parameter count of the message handled
;  $(message,parameters) = parameter list of the message handled, comma separated
;  $(message,parameters,sep) = parameter list of the message handled, explicit separator
;  $(variables,count) = current count of the global variables
;  $(variables,list) = comma separated list of the global variables names
;  $(variables,list,sep) = list of the global variables names with explicit separator
;  $(variables,NAME) = "true" if global variable NAME exists, "false" otherwise
;  $(transcode,FLAGS,FORMAT1,FORMAT2,...) = list of formats the input can be transcoded into
;       e - exclude initial formats form generated list
;       r - allow rate conversion (for use with wideband)
;       c - allow changing channels number
; Note that functions ++, --, index and rotate will automatically update N
;  if it is a variable in the $varname format.


[priorities]
; Set the priorities for the insertion of the regular expression module in the
;  handler chain; a priority of 0 disables the handler entirely

; preroute: int: Priority of the prerouting message handler
;preroute=100
; route: int: Priority of the routing message handler
; Route here before register.php which is at priority 100
route=95

; status: int: Priority of the status and line completion handlers
;status=110

; extended: bool: Use extended regular expressions
;extended=no

; insensitive: bool: Make the regular expressions case insensitive
;insensitive=no

; defaultrule: regexp: Default expression to use in matches if not specified
; Works only for ${param} or $(expression) matches
; Default matches any string that is not empty or explicitely false or zero
;defaultrule=^\(false\|no\|off\|disable\|f\|0*\)$^

; prerouteall: bool: Preroute even calls having a context or with empty caller
;prerouteall=no

; maxdepth: int: Maximum number of jumps or recursive includes
; Values are clamped to interval 5-100
;maxdepth=5

; trackparam: bool: Add the module to the handler tracking parameter
; Set it to false to disable defaults and do all tracking in user rules
;trackparam=true


[$once]
; First-time only global variables initialization.
; It is executed during first initialization before the [$init] section
; Each line must be of the form:
;  varname=value


[$init]
; Reload time global variables initialization
; Each line must be of the form:
;  varname=value

[extra]
; This section allows installing handlers for any message name.
; Each line must be of the form:
;  message.name=priority[,[paramname][,context]]
; For each handler create a corresponding [context] or [message.name] section
;  in which implement handling for that specific message. If paramname is not
;  set you will need to match parameters explicitely or set a new match string.
; Examples:
;  engine.command=90
;  call.execute=120,callto
;  call.route=200,called,reroute


[contexts]
; This section is used by the prerouting handler to classify calls by the
;  caller name; each call is assigned an input context (only if none exists
;  already) that is used later in the routing stage
; Expressions are scanned from top to bottom; the first match returns the value
; Each line must be of the form:
;   regexp=context_name
; To match a message parameter you can use the format:
;   ${paramname}regexp=context_name
; Strings captured with the regular expression construct \(...\) can be
;  inserted in the context name using \1, \2, \3, ... while \0 holds the entire
;  matched regexp even if no capture was used
; Message parameters can be inserted in the context name using ${paramname}
;
; Example:
;^$=empty
;^00=international
;^0=longdistance
;.*=default


[default]
; Sections like this one are used by the routing handler to find the target
;  of calls by the called name
; The [default] context is special, it is used when no context has been set
;  otherwise you have to place the entries in a section with the same name
;  as the context
; Expressions are scanned from top to bottom; the first match returns the value
; Each line must be of the form:
;   regexp=target
; To match a message parameter you can use the format:
;   ${paramname}regexp=target
; To match a function possibly containing parameters you can use the format:
;   $(function,param...)regexp=target
; To act on non-matching expressions add a ^ at end of the regexp. In this
;  case the \0 ... \9 replacements will always be empty
;   regexp^=target
; Strings captured with the regular expression construct \(...\) can be
;  inserted in the target using \1, \2, \3, ...
; Message parameters can be inserted in the target using ${paramname}
; Functions can be inserted using $(function,param,param)
;
; First word of a matched target has a special meaning:
; if, and - make a new match using the rest of the line up to the = character
; or - alternative match using the rest of the line up to the = character
; return - returns immediately from the context without routing
; include, call - calls another context, returns at the next entry if the other
;   context did not return successfully
; jump, goto - jumps to another context, does not return to this context
; match - modify the matched string instead of specifying a target
; rename - changes the name of the message
; enqueue - puts a new message in the engine, parameters are taken from the
;   old message but placed in the new one
; dispatch - dispatches a new message in the engine waiting for it to return,
;   parameters are taken from the old message but placed in the new one
; echo - displays that line after making substitutions
; { - starts a block that ends on another line with }
; The @jump, @goto, @include and @call forms suppress warning if missing target
;
; It is possible to set message parameters by appending them as name=value
;  while separating them with semicolons (;)
; Placing just the parameter name without the =  sign will clear the parameter
; Using $name=value will instead change the global variable with that name.
; Similarily specifying just $name will clear the global variable
;
; Please note that the match string is not changed together with the message
;  parameter from which it was copied; for example in routing stage using
;  "match 123" and ";called=123" have different effects
;
; Example:
;   route the emergency 112 and 911 numbers to POTS, any channel on an E1,
;   force specific data format too
;^112$=zap/1-31; format=alaw
;^911$=zap/1-31; format=mulaw
;   route international calls over SIP, replace caller name
;^00\(.*\)$=sip/sip:\1@international.gateway ; callername = International call
;   route value added services over IAX, trailing part is sent as IAX extension
;^09\(.*\)$=iax/vap@gateway.for.vap/\1
;   route green calls over IAX with 2 digits used to form an user name,
;   remaining digits are sent as extension
;^08\(..\)\(.*\)$=iax/green-\1@gateway.for.green/\2
;   everything else starting with 0 is routed over H.323
;^0\(.*\)$=h323/\1@long.distance.gateway
;   route short 3digit numbers to SIP using a DNS scheme 123 -> 3.2.1.domain
;^\(.\)\(.\)\(.\)$=sip/sip:\0@\3.\2.\1.domain
;   route only calls from SIP starting with 123 to a H.323 gateway
;${id}^sip/=if ^123.*$=h323/\0@provider.gw
;   is there anything else left? they go on E1 but only 15 channels can be used
;   we also make sure the number is at least 4 characters long
;   and we set a national caller dialplan
;.....*=zap/1-15 ; callerplan = national
;   leftovers... should not happen but let's handle them. we may not route the
;   call at all and let the caller receive a "no route" error
;.*=wave/play/sounds/invalid_number.gsm
${address}^127\.0\.0\.=goto localhost
${username}.=goto localhost

[localhost]
; The following are for testing purposes
^99991001$=tone/dial
^99991002$=tone/busy
^99991003$=tone/ring
^99991004$=tone/specdial
^99991005$=tone/congestion
^99991006$=tone/outoforder
^99991007$=tone/milliwatt
^99991008$=tone/info

; Example of handling call authorization by caller authentication or ip address
; If the user is not authenticated call the subsection check_addr_auth
;${username}^$=call check_addr_auth
; Optionally, force caller id to authenticated username (if any)
;${username}.=;caller=${username}
;
;[check_addr_auth]
; Here we check for trusted gateways or networks by the "address" parameter
;  that for VoIP protocols is in the format: ip.ad.dr.ess:port
;
; allow trusted gateway 10.0.1.2
;${address}^10\.0\.1\.2:=return
; also trust callers from network 192.168.0.*
;${address}^192\.168\.0\.=return
; all others should be challenged (SIP,IAX) or rejected (other protocols)
;.*=-;error=noauth[/list]

marian

  • Sr. Member
  • ****
  • Posts: 381
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #10 on: March 17, 2015, 09:13:04 AM »
I can't find the parameter values set in call.route (like 'pbxparams') anywhere in yate code.
Can you tell me what version are you using?

lewis

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #11 on: March 17, 2015, 09:31:44 AM »
Thank you again for your help. The package system for the box I'm testing on installed version 5.4.0

marian

  • Sr. Member
  • ****
  • Posts: 381
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #12 on: March 17, 2015, 09:55:45 AM »
I don't know what to say!
Try not to load modules listed in handlers parameters of call.route (except for sip) and see what happens.

marian

  • Sr. Member
  • ****
  • Posts: 381
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #13 on: March 18, 2015, 01:37:00 AM »
To not load the modules set in yate.conf:

[modules]
regexroute.yate=no
javascript.yate=no
cdrbuild.yate=no
fileinfo.yate=no
subscription.yate=no

Make a transfer. Check it.
If it works load the modules one by one and retry.

lewis

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Blind transfer on Cisco phones fails
« Reply #14 on: March 18, 2015, 04:27:37 AM »
I deactivated all those modules and restarted Yate.

I tested a normal blind transfer by pressing *98, the destination extension, and then * again. This worked fine.

I tried to do it using the phone's blind transfer service button. This failed as it usually does.

Thanks again!