I'm using a C#/.NET library to implement the Asterisk RESTful Interface (ARI) to create conference call app.
So far the app works like this:
- User calls the number
- App answers
- App starts voice detection
- App asks for name and records the audio
- App adds the user to the conference
Requirement:
I need to add in the above process some kind of authorization, before the user is added into the conference. I need to implement the ask for a PIN number functionality, create a PIN number construct and if the caller enters the correct PIN add the caller to the correct conference call.
The Code:
Conference:
public Conference( AriClient c, Guid id, string name)
{
_client = c;
Id = id;
ConferenceName = name;
State = ConferenceState.Destroyed;
c.OnChannelDtmfReceivedEvent += c_OnChannelDtmfReceivedEvent; // ??
c.OnBridgeCreatedEvent += c_OnBridgeCreatedEvent;
c.OnChannelEnteredBridgeEvent += c_OnChannelEnteredBridgeEvent;
c.OnBridgeDestroyedEvent += c_OnBridgeDestroyedEvent;
c.OnChannelLeftBridgeEvent += c_OnChannelLeftBridgeEvent;
c.OnRecordingFinishedEvent += c_OnRecordingFinishedEvent;
// Added support for talk detection
c.OnChannelTalkingStartedEvent += c_OnChannelTalkingStartedEvent;
c.OnChannelTalkingFinishedEvent += c_OnChannelTalkingFinishedEvent;
Debug.Print("Added Conference {0}", ConferenceName);
}
OnChannelEnteredBridgeEvent:
private void c_OnChannelEnteredBridgeEvent(object sender, ChannelEnteredBridgeEvent e)
{
ConferenceUser confUser = ConferenceUsers.SingleOrDefault(x => x.Channel.Id == e.Channel.Id);
if (confUser == null) return;
confUser.State = ConferenceUserState.InConf;
if (ConferenceUsers.Count(x => x.State == ConferenceUserState.InConf) > 1) // are we the only ones here
{
// stop moh
_client.Bridges.StopMoh(Confbridge.Id);
// change state
State = ConferenceState.Ready;
// announce new user
_client.Bridges.Play(Confbridge.Id, "recording:" + confUser.CurrentRecodingId, "en", 0, 0, Guid.NewGuid().ToString());
_client.Bridges.Play(Confbridge.Id, "sound:conf-hasjoin", "en", 0, 0, Guid.NewGuid().ToString());
}
else
{
// only caller in conf
_client.Channels.Play(e.Channel.Id, "sound:conf-onlyperson", "en", 0, 0, Guid.NewGuid().ToString());
}
}
StartConference:
public bool StartConference()
{
// Create the conference bridge
Debug.Print("Requesting new bridge {0} for {1}", Id, ConferenceName);
Bridge bridge = _client.Bridges.Create("mixing", Id.ToString(), ConferenceName);
if (bridge == null)
{
return false;
}
Debug.Print("Subscribing to events on bridge {0} for {1}", Id, ConferenceName);
_client.Applications.Subscribe(AppConfig.AppName, "bridge:" + bridge.Id);
// Start MOH on conf bridge
_client.Bridges.StartMoh(bridge.Id, "default");
// Default state is ReadyWaiting until MOH is turned off
State = ConferenceState.ReadyWaiting;
Confbridge = bridge;
// Conference ready to accept calls
State = ConferenceState.Ready;
return true;
}
AddUser:
public bool AddUser(Channel c) //here check for pin and caller id
{
if (State == ConferenceState.Destroying)
return false;
if (State == ConferenceState.Destroyed)
{
// We should initiate a new conference bridge
if (!StartConference())
return false;
}
if (State < ConferenceState.Ready) return false;
// Answer channel
_client.Channels.Answer(c.Id);
// Turn on talk detection on this channel
_client.Channels.SetChannelVar(c.Id, "TALK_DETECT(set)", "");
// Add conference user to collection
ConferenceUsers.Add(new ConferenceUser(this, c, _client, ConferenceUserType.Normal));
return true;
}
Question:
How can I raise/invoke the "ask for pin number" event/channel within the app and grab the input DTMF digits into a variable?
Can this be done solely in my C# ARI application, or do I need to fiddle with the .conf files on the Asterisk server?
My preferred way of doing is is by implementing it in my C# ARI app, as this would give me more control over conferences.