[asterisk-users] Questions on converting to ConfBridge

kenner at gnat.com kenner at gnat.com
Wed Oct 3 05:39:30 CDT 2012


> Why are you wanting to use CLI commands instead of AMI? The available 
> AMI actions for ConfBridge can do listing/locking/muting/kicking etc as 
> you want.

Because I can't easily manually do an AMI command, but instead have to
write code to do it.  It's important to me to be able to clean up things
from the command-line if something is stuck or broken.

> As for dialplan applications to do the various things - what are you 
> trying to achieve using them?

And IVR application that people can call into and manipulate people in
conference rooms.  Note that this depends on dialplan commands *and*
having a number index for them.  It's unclear how I'd do this with
confbridge.

Here's the dialplan I'm using.

exten => 210/_[12]XX,1,NoOp			; Valid if internal.
exten => 210,s,Gosub(Authenticate,s,1(0000))	; Else authenticate.
 same => n,Mset(C=conference&ha/room&digits/2&digits/0,E=adacore/not-exist)
 same => n,Mset(STATS_INC(conf_mgr)=1,__G=conf_op) ; Count the usage.
 same => n(r),Macro(Get-Speech,${G},${EFN}adacore/conf_mgr,2,10,100,w)
 same => n,GotoIf(${S_T}?${S_T},1:r)		; Retry or do action.

exten => _[lLK]20Z,1,GotoIf(${MEETME_INFO(parties,20${EXTEN:-1})}?:err)
exten => _L20Z,n,Mset(V=lock,T=locked,E=is&adacore/already-locked)
exten => _l20Z,s,Mset(V=unlock,T=unlocked,E=is&adacore/already-unlocked)
exten => _K20Z,s,Mset(V=terminate,T=terminated) ; To terminate.
exten => _[lLK]20Z,n,Set(CFN=adacore/you-want-to&adacore/${V}&${C}&digits/${EXTEN:-1}&)
exten => _[lLK]20Z,n,Gosub(Is-That-Correct,s,1) ; ... and see if correct.
exten => _[lLK]20Z,n,GotoIf($[${GOSUB_RETVAL}=2]?210,r) ; Retry it not.
exten => _L20Z,n,GotoIf(${MEETME_INFO(lock,20${EXTEN:-1})}?err) ; Bad status.
exten => _l20Z,s,GotoIf(${MEETME_INFO(lock,20${EXTEN:-1})}?:err) ; Likewise.
exten => _K20Z,s,NoOp			; No test needed for termination.
exten => _[lLK]20Z,n,MeetMeAdmin(${EXTEN:-3},${EXTEN:0:1}) ; Perform op.
exten => _[lLK]20Z,n,Set(EFN=${C}&digits/${EXTEN:-1}&is&now&adacore/${T}&)
exten => _[lLK]20Z,n,Goto(210,r)	; Ask for another operation.

exten => _[lLK]20Z,n(err),Set(EFN=im-sorry&${C}&digits/${EXTEN:-1}&${E}&)
exten => _[lLK]20Z,n,Goto(210,r)	; See if another operation is wanted.

exten => _s20Z,1,Goto(s20${EXTEN:-1}${MEETME_INFO(parties,${EXTEN:-3})},1)
exten => _s20Z.,1,Playback(${C}&digits/${EXTEN:3:1}) ; Say that conference ...
exten => _s20Z0,n,Playback(adacore/not-exist)   ; ... doesn't exist,
exten => _s20Z1,s,Swift(has one participant)	; ... or has one person,
exten => _s20Z.,s,Swift(has ${EXTEN:4} participants) ; ... or more.
exten => _s20Z.,n,ExecIf(${MEETME_INFO(lock,${EXTEN:1})}?Swift(and is locked)
exten => _s20Z.,n,Set(M=$[CEIL(MEETME_INFO(activity,${EXTEN:1:3})/60)])
exten => _s20Z[1-9]!,n,Swift(and has been active for ${M} minutes)
exten => _s20Z.,s,NoOp			; In other cases, do nothing.
exten => _s20Z.,n,Goto(210,r)		; Go back for another operation.

exten => _j20Z,1,Set(CFN=you-wish-to-join&${C}&digits/${EXTEN:-1}&)
 same => n,Gosub(Is-That-Correct,s,1) ; See if correct.
 same => n,GotoIf($[${GOSUB_RETVAL}=2]?210,r) ; Retry it not.
 same => n,SpeechDestroy		; Else free speech channel.
 same => n,Goto(${EXTEN:-3},1)		; And go there.

exten => _[pP]20Z,1,GotoIf($[MEETME_INFO(parties,${EXTEN:1})=0]?s20${EXTEN:-1}0,1)
 same => n,Swift(participants in)	; Say the header and ...
 same => n,Playback(${C}&digits/${EXTEN:3:1})	; ... conference number.
 same => n,ExecIf($[x${G:0:3}=xtmp]?System(rm -f ${GRAMS}/${G}.gram))
 same => n,Set(__G=tmp/r${RAND(10000,99999)})	; Grammar filename part.
 same => n,AGI(conflist.php,${EXTEN:1},${GRAMS}/${G}.gram,${EXTEN:0:1})
 same => n,Goto(210,r)				; And go back.

exten => _m20ZXX.,1,Mset(Q=adacore/unmute,OP=adacore/unmuted)
exten => _M20ZXX.,s,Mset(Q=adacore/mute,OP=adacore/muted)
exten => _k20ZXX.,s,Mset(Q=adacore/remove,OP=removed)
exten => _[Mmk]20ZXX.,n,Playback(adacore/you-want-to&${Q}) ; Start question.
 same => n,Swift(${EXTEN:6})			; Say who ...
 same => n,Gosub(Is-That-Correct,s,1)		; ... and see if correct.
 same => n,GotoIf($[${GOSUB_RETVAL}=2]?210,r)	; Retry it not.
 same => n,Set(U=${IF($[${EXTEN:4:1}=0]?${EXTEN:5:1}:${EXTEN:4:2})})
 same => n,MeetMeAdmin(${EXTEN:1:3},${EXTEN:0:1},${U}) ; Do operation.
 same => n,Swift(${EXTEN:6})			; Say name ...
 same => n,Playback(${OP})			; ... and what we did.
 same => n,Goto(210,r)				; Go back for another try.

exten => What,1,Set(EFN=adacore/confop_what&) ; Say what options are available.
 same => n,Goto(210,r)			; And go back and prompt again.
exten => Done,1,Playback(vm-goodbye)	; Here to hangup.

Here's the grammar:

#ABNF 1.0 UTF-8;
language en-US;
mode voice;
tag-format <semantics/1.0.2006>;
root $conf_op;

$Operation = lock {out = "L";}
	| unlock {out = "l";}
	| (end | kill | terminate) {out = "K";}
	| join { out = "j";}
	| [(say | get)] status [of] { out = "s";}
	| [(list | say)] (participants | callers) [(to | in | of)]
		{ out = "p"; }
	| (full | detailed) [(list | say)] [of] (participants | callers)
		[(to | in | of)] { out = "P"; }
        ;

$Room = [conference] [room] $<digits.gram#ConfRoom>;

$conf_op = (what can i do | what options do i have | help) { out = "What"; }
	| (done | hangup) { out = "Done"; }
	| $Operation $Room {out = rules.Operation + rules.Room;}
	| $Operation [conference] [room] { out = rules.Operation + "201"; }
  ;

And here's the AGI:

#!/usr/bin/php -q
<?php

require_once 'agi-util.php';
include '/var/www/phpagi/phpagi-asmanager.php';

agi_init ();

$as = new AGI_AsteriskManager ();
$res = $as->connect ();
$res = $as->Command ("meetme list $argv[1] concise");

$gram = "#ABNF 1.0 UTF-8;\nlanguage en-US;\nmode voice;\n";
$gram .= "tag-format <semantics/1.0.2006>;\nroot \$caller_conf_op;\n";

if (isset ($res['data']))
  $lines = explode ("\n", $res['data']);
 else
   $lines = array ();

$all_names = array ();

foreach ($lines as $line)
{
  $linevalue = explode ('!', $line);
  if (count ($linevalue) > 2)
    {
      $index = $linevalue[0];
      $number = $linevalue[1];
      $name = $linevalue[2];
      $comma = strpos ($name, ',');
      $paren = strpos ($name, '(');
      if ($comma)
	$name = substr ($name, 0, $comma - 1) . ' '
	  . substr ($name, $comma + 1);

      if ($paren)
	$name = substr ($name, 0, $paren - 1);

      if (strlen ($name) > 2)
	say_text ($name);

      if ($argv[3] == 'P')
	{
	  if (strlen ($number) < 5)
	    say_text ('extension');

	  if (is_numeric ($number))
	    say_digits ($number);
	}

      if (strlen ($index) == 1)
	$index = "0$index";
      $index .= $name;

      $name = preg_replace ('/[^a-z\s]/', '', strtolower ($name));
      $all_names[$name] = $index;
      $names = explode (' ', $name);
      if (count ($names) == 2)
	for ($i = 0; $i < 2; $i++)
	  $all_names[$names[$i]] = isset ($all_names[$names[$i]])
	    ? 'dup' : $index;
    }
}

$header = '$names = ';
foreach ($all_names as $name => $idx)
  if ($idx != 'dup')
    {
      $gram .= $header . $name . " { out = \"$idx\"; }\n";
      $header = '       | ';
    }

$gram .= "       ;\n\$user_op = /1/ mute { out = \"M\"; }"
  . " | /100/ unmute { out = \"m\"; }\n"
  . "         | /1/ (kick [out] | terminate | remove) "
  . "{ out = \"k\"; }\n         ;\n";
$gram .= '$cop = $user_op $names'
  . ' { out = rules.user_op + "' . $argv[1]  . '" + rules.names; };';
$gram .= "\n";
$gram .= '$caller_conf_op = $<../conf_op.gram> | $cop;' . "\n";

$f = fopen ($argv[2], 'w');
fwrite ($f, $gram);
fclose ($f);

$as->disconnect ();
?>



More information about the asterisk-users mailing list