5

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:

  1. User calls the number
  2. App answers
  3. App starts voice detection
  4. App asks for name and records the audio
  5. 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.

alex
  • 1,300
  • 1
  • 29
  • 64

1 Answers1

-2

You should create some dialplan to support that and ask dialplan check you pin etc

Sure it can be done without dialplan support, but in that case task become guru level, have no real sense do like that.

For start i can recommend you "Asterisk the future of telephony" book.

You can use func_odbc, Read application, CHANNEL function(for ip)

arheops
  • 15,544
  • 1
  • 21
  • 27
  • Thanks. I want to start by doing this within my ARi app and hopefully I'll manage to do it, if not, then I'll use the dialplan. do you think this is a good resource: https://wiki.asterisk.org/wiki/display/AST/ARI+and+Channels%3A+Handling+DTMF ? – alex Feb 12 '16 at 09:09
  • I think the point of using ARI is to have complete control over conferences. – alex Feb 12 '16 at 09:17
  • Not think you can use statis(asyncagi) and conference. But you can try. However it will be MUCH simpler in dialplan – arheops Feb 12 '16 at 12:45
  • In dialplan dialplan do all for you, after that return you result. While in statis you have control every single action. – arheops Feb 12 '16 at 12:48