Joined: 16 Jun 2009 Posts: 3 Location: Wokingham, uk
Posted: Tue Dec 15, 2009 10:04 am Post subject: SIP Flash Hook
Not sure where to put this, but as i had so much trouble trying to get this sorted, i felt i needed to post to help anyone else struggling!
The problem : Asterisk 1.6.1 - r231301M, Grandstream GXW4108 and 8 BT Feature Lines (system X based).
When a call comes in on a BT line (ech one has seperate DDI), the GS passes it to asterisk - great, we have the call and of course asterisk can transfer the call to any of the other extensions - wrong!! - by doing this, the incoming line is still in use, so that person is unable to dial out (even though they have transferred the call). Because of the DDI arrangement, people have their own lines, so a round robin approach was out of the question.
To fix this, you have to tell the BT feature line to transfer the call, rather than asterisk - this requires a Flash Hook on the line (aka Recall). The GS supports this, through RFC 2833 (event 16), but asterisk kinda does and doesn't!.
Their is some code in chan_sip.c which recognises the DTMF 'X' character as flash hook (as opposed to the normal 0-9, A-D, *# DTMF characters). The problem is that RTP needs to be involved, and their was no code there!!
So, a couple of changes to rtp.c are reuqired :
/*! \brief Send begin frames for DTMF */
int ast_rtp_senddigit_begin(struct ast_rtp *rtp, char digit)
{
unsigned int *rtpheader;
int hdrlen = 12, res = 0, i = 0, payload = 0;
char data[256];
/*! \brief Send end packets for DTMF */
int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit)
{
unsigned int *rtpheader;
int hdrlen = 12, res = 0, i = 0;
char data[256];
/* If no address, then bail out */
if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
return 0;
Using the 'F'/'f' character to indicate flash hook, RFC 2833 event 16.
A second issue, is that the Flash Hook event needs to occur during transfer, and not in the dial plan as you are in and ongoing call, so as they say on the telly, we need an App for that.
Rather than write a new app, which i'm sure is the proper way, but i really wanted to test this, I changed the asterisk inbuilt attended transfer function : builtin_atxfer()
/* this is specific of atxfer */
res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
finishup(transferee);
return res;
}
if (res == 0) {
// Craig Special - If valid digits but extension not found Send Flash Hook to BT, followed by digits and exit back to call
if (strlen(xferto)>1) {
ast_log(LOG_WARNING, "Using BT Feature Line - Sending Flash Hook\n");
ast_senddigit(transferee,'F',100);
ast_log(LOG_WARNING, "Now Sending Digits [%s]\n",xferto);
for ( l=0; l<strlen(xferto); ++l) {
ast_senddigit(transferee,xferto[l],100);
}
return AST_FEATURE_RETURN_SUCCESS;
}
// End Of Craig Special
ast_log(LOG_WARNING, "Did not read data.\n");
finishup(transferee);
if (ast_stream_and_wait(transferer, "beeperr", ""))
return -1;
return AST_FEATURE_RETURN_SUCCESS;
}
// Craig Special - If xfer to outside line Send Flash Hook to BT, followed by digits and exit back to call
if (xferto[0]=='9') {
ast_log(LOG_WARNING, "Using BT Feature Line - Sending Flash Hook\n");
ast_senddigit(transferee,'F',100);
ast_safe_sleep(transferee, 1000); //need to wait to allow Flash
ast_log(LOG_WARNING, "Now Sending Digits [%s]\n",xferto);
for ( l=0; l<strlen(xferto); ++l) {
ast_senddigit(transferee,xferto[l],100);
ast_safe_sleep(transferee, 100);
}
finishup(transferee);
return AST_FEATURE_RETURN_SUCCESS;
}
// End Of Craig Special
This is a little specific to me, but it shows how to handle the flash hook. What I am doing is to detect a transfer to an extension that is not in the dialplan, because i want to use the BT feature line in order to avoid a line being held - that is the first peice of code.
Secondly, if the call is to an outside line (i.e. through BT), callers must dial a 9 - so i detect this, and once again, use the transfer flash hook, followed by the digits to make the call. Note the use of ast_safe_sleep, this is because the GS has an RTP buffer overrun if you fire the digits at it too quickly.
hope this helps. When i get time, i'll try and make this a more generic 'app'
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum