Hello Everyone,
I am trying to implement music on hold with Asterisk. I know that this has been asked before, but I have searched through the archives and I think I am doing something a bit different...
Here is the situation:
Components: Phone (registered to OpenSER)
Cisco GW (connects to PSTN)
OpenSER (in the middle of this mess)
Diagram Outgoing Call:
Phone -> OpenSER (Authentication, LCR, record route, NAT traversal, yada yada) -> Cisco GW
Incoming:
Cisco GW -> OpenSER (locations lookup, record route, NAT traversal, yada yada) -> Phone
OpenSER catches any INVITE from the phone and routes it as necessary. The above config works perfectly except for hold/music on hold.
As I understand it, music on hold is implemented with a re-INVITE (from the phone) with a 0.0.0.0 address in the SDP (c=IN IP4 0.0.0.0). I think that if I had a way to check for this I could route the re-INVITE for hold to an Asterisk server to run music on hold instead of routing it to the Cisco GW (which is what happens now). A few questions:
1) Is there a better way to differentiate a re-INVITE for hold/moh vs. just a regular INVITE? 2) Is there a way to do this in OpenSER (either using some kind of matching based on SDPs or some other method)? 3) Is there any reason this wouldn't work?
I'm thinking that the Asterisk side would be fairly simple, with a context like this for the incoming INVITEs to play music on hold:
exten => _NXX.,1,Answer ; (can't hurt) exten => _NXX.,n,MusicOnHold(default) exten => _NXX.,n,Hangup
... or something to that effect.
What do you think? Any and all comments welcome.
Thanks!
Hi!
You cant do MOH in openser. MOH is an endpoint feature. Some phones allow to configure a MOH URI (SNOM) which I guess is used for reINVITEs.
Maybe you can implement it with sems - catch the on-hold reINVITE and "tell" sems to stream RTP to the other party - ask the sems guys.
regards klaus
Kristian Kielhofner wrote:
Hello Everyone,
I am trying to implement music on hold with Asterisk. I know that this has been asked before, but I have searched through the archives and I think I am doing something a bit different...
Here is the situation:
Components: Phone (registered to OpenSER)
Cisco GW (connects to PSTN)
OpenSER (in the middle of this mess)
Diagram Outgoing Call:
Phone -> OpenSER (Authentication, LCR, record route, NAT traversal, yada yada) -> Cisco GW
Incoming:
Cisco GW -> OpenSER (locations lookup, record route, NAT traversal, yada yada) -> Phone
OpenSER catches any INVITE from the phone and routes it as necessary. The above config works perfectly except for hold/music on hold.
As I understand it, music on hold is implemented with a re-INVITE (from the phone) with a 0.0.0.0 address in the SDP (c=IN IP4 0.0.0.0). I think that if I had a way to check for this I could route the re-INVITE for hold to an Asterisk server to run music on hold instead of routing it to the Cisco GW (which is what happens now). A few questions:
- Is there a better way to differentiate a re-INVITE for hold/moh
vs. just a regular INVITE? 2) Is there a way to do this in OpenSER (either using some kind of matching based on SDPs or some other method)? 3) Is there any reason this wouldn't work?
I'm thinking that the Asterisk side would be fairly simple, with a context like this for the incoming INVITEs to play music on hold:
exten => _NXX.,1,Answer ; (can't hurt) exten => _NXX.,n,MusicOnHold(default) exten => _NXX.,n,Hangup
... or something to that effect.
What do you think? Any and all comments welcome.
Thanks!
On 5/10/07, Klaus Darilion klaus.mailinglists@pernau.at wrote:
Hi!
You cant do MOH in openser. MOH is an endpoint feature. Some phones allow to configure a MOH URI (SNOM) which I guess is used for reINVITEs.
Maybe you can implement it with sems - catch the on-hold reINVITE and "tell" sems to stream RTP to the other party - ask the sems guys.
regards klaus
klaus,
Thanks for the reply. I'm not looking to do anything too special in openser. If anything, all I need to do is add a check for the address in the SDP for an INVITE.
Some phones do allow you to configure a MOH URL but not all do. I'd like to come up with something that will work for me and other people in the community on any phone. Plain 'ol generic SIP is probably the only way (this is how Asterisk does it so seamlessly).
If I implement this with SEMS I will have the same problem. As you said, I still need to "catch" the on-hold re-INVITE from the phone and send it to SEMS. I already have Asterisk servers (and I'm much more familiar with Asterisk than SEMS), I might as well try to send the intercepted (for lack of a better term) re-INVITE to Asterisk (and have Asterisk process it as a normal call) - not to SEMS (although it would probably also work for SEMS in place of Asterisk).
It looks like textops might be able to do this in a hack-ish sort of way... I'll try it and see what happens but I would certainly like something cleaner.
What would need to be added to OpenSER to support checking for this? Even exposing a few of the values (perhaps as pseudo-variables) from the SDP on an INVITE would be a great start. I'm sure that this is more of a dev list question but I thought that I would ask here first...
Thanks again for the reply!
Kristian,
Just a quick note : if you need to differentiate an initial INVITE from a re-INVITE, I would say the most RFC-compliant way would be to check for a to: tag. If there is one, then this is a re-INVITE. If not, then it's an initial invite.
Based on that information, you can route either invites wherever you please, but keep in mind that after the first re-INVITE, the phone will send a second one to restore the initial media session, and that one needs to be handled carefully. The initial outbound gateway won't mind if there is a jump in CSeq between two transactions (that's in RFC3261), but still, depending on wether the phone keeps the same ports as in the initial media session or not, you might need to to more or less hacking in order to restor the initial session when MOH ends.
I've never used client-side MOH, and this seems pretty complicated in terms of handling.
Cheers, Jerome
On Thu, 2007-05-10 at 14:30 -0400, Kristian Kielhofner wrote:
On 5/10/07, Klaus Darilion klaus.mailinglists@pernau.at wrote:
Hi!
You cant do MOH in openser. MOH is an endpoint feature. Some phones allow to configure a MOH URI (SNOM) which I guess is used for reINVITEs.
Maybe you can implement it with sems - catch the on-hold reINVITE and "tell" sems to stream RTP to the other party - ask the sems guys.
regards klaus
klaus,
Thanks for the reply. I'm not looking to do anything too special in openser. If anything, all I need to do is add a check for the address in the SDP for an INVITE.
Some phones do allow you to configure a MOH URL but not all do. I'd like to come up with something that will work for me and other people in the community on any phone. Plain 'ol generic SIP is probably the only way (this is how Asterisk does it so seamlessly).
If I implement this with SEMS I will have the same problem. As you said, I still need to "catch" the on-hold re-INVITE from the phone and send it to SEMS. I already have Asterisk servers (and I'm much more familiar with Asterisk than SEMS), I might as well try to send the intercepted (for lack of a better term) re-INVITE to Asterisk (and have Asterisk process it as a normal call) - not to SEMS (although it would probably also work for SEMS in place of Asterisk).
It looks like textops might be able to do this in a hack-ish sort of way... I'll try it and see what happens but I would certainly like something cleaner.
What would need to be added to OpenSER to support checking for this? Even exposing a few of the values (perhaps as pseudo-variables) from the SDP on an INVITE would be a great start. I'm sure that this is more of a dev list question but I thought that I would ask here first...
Thanks again for the reply!
Hi Kristian!
It is easy to catch a on-hold reINVITE: has_totag() and search for 0.0.0.0 in the SDP. But the problem is the whole logic behind it.
Example A calls B. Then B put A on hold. What do you want to achive - music on hold for A or B? For B IMO it is not necessary as B probably does something else now. Usually you want MOH for A.
Thus, how to get MOH for A? if A has no built in support for MOH, you have to: 1. tell you MOH server to send RTP to A 2. make A to accept RTP from the MOH server.
For 1. you have to send an INVITE to the MOH server with the SDP of A - triggered by a reINVITE from B - quite difficult
For 2. (if A is behind NAT) you have to make A to send RTP to the MOH server to open the pinhole in the NAT. Thus send a reINVITE to A with the SDP of the MOH server.
I have no clue how this can be done with openser. For this you need a B2BUA - like asterisk and sems and the call must be routed from the beginning via the B2BUA.
regards klaus
Kristian Kielhofner wrote:
On 5/10/07, Klaus Darilion klaus.mailinglists@pernau.at wrote:
Hi!
You cant do MOH in openser. MOH is an endpoint feature. Some phones allow to configure a MOH URI (SNOM) which I guess is used for reINVITEs.
Maybe you can implement it with sems - catch the on-hold reINVITE and "tell" sems to stream RTP to the other party - ask the sems guys.
regards klaus
klaus,
Thanks for the reply. I'm not looking to do anything too special in openser. If anything, all I need to do is add a check for the address in the SDP for an INVITE.
Some phones do allow you to configure a MOH URL but not all do. I'd like to come up with something that will work for me and other people in the community on any phone. Plain 'ol generic SIP is probably the only way (this is how Asterisk does it so seamlessly).
If I implement this with SEMS I will have the same problem. As you said, I still need to "catch" the on-hold re-INVITE from the phone and send it to SEMS. I already have Asterisk servers (and I'm much more familiar with Asterisk than SEMS), I might as well try to send the intercepted (for lack of a better term) re-INVITE to Asterisk (and have Asterisk process it as a normal call) - not to SEMS (although it would probably also work for SEMS in place of Asterisk).
It looks like textops might be able to do this in a hack-ish sort of way... I'll try it and see what happens but I would certainly like something cleaner.
What would need to be added to OpenSER to support checking for this? Even exposing a few of the values (perhaps as pseudo-variables) from the SDP on an INVITE would be a great start. I'm sure that this is more of a dev list question but I thought that I would ask here first...
Thanks again for the reply!