Re: [Ekiga-devel-list] Blacklisting



Jan Schampera a écrit :
I just saw a (IMHO) good idea:
Filtering incoming calls by a SIP-address blacklist.

Comments?

I have thought about this.

The idea I had was the following : if we make the core of ekiga work with signals, how do we handle answering a call?

Here are some ways to handle an incoming call :
(1) user prompt with current dialog ;
(2) user prompt through other channel (say the user has a hardware phone to unhook, or uses something through DBUS to handle calls) ;
(3) ekiga mode (auto-answer or dnd) ;
(4) whitelists ;
(5) blacklists ;
(6) greylists ;
(7) custom logic ;
(8) ring (this is different from the dialog).

Let's say we try to handle this with the same system as the DBUS component : a signal is emitted with each state change of a call token, which means that by watching it :
- you know there's a new call ;
- you know when it has been answered ;
- you know when it ended.

So for example, we could adapt the dialog code to :
- show the dialog when an incoming call happens ;
- hide the dialog when the call changes state (established or rejected).

This would work quite well at first sight : the dialog will be hidden even if it wasn't used to answer, magically.

On second sight however, this sucks. Ekiga will trigger the ringing on incoming call, and decide it is in dnd and reject simultaneously. So the user will still hear probably one ringing tone before the decision is made. Bad, bad, bad.

So signals aren't a good way to handle a call answer decision.

The better is certainly to use the "chain of responsibility" design pattern. As usual, the name hurts more than the concept itself.

The idea is that we have a stack of handlers for a message. Each handler is called after the other (so we get the ordering of things we were lacking with signals -- which were the observer pattern of the model-view-controller design [don't point PVH to this mail : it's full of words he gets wet on ;-) ]), and makes or not a decision.

Basically, each handler answers either "Ok, I handled, stop there" or "Go down the list".

Let's put those handlers in the list and run a call through them:
(1) the ekiga mode handler ;
(2) the ringer handler ;
(3) the dialog handler.

The first to decide is the ekiga mode handler. If we are in DND, it will do two things :
- tell the endpoint to reject the call ;
- return "Ok, I handled, stop here".
In this case, no ring, no dialog, everything is ok. Likewise, if we're in autoanswer, we answered without bothering the user. If we're in normal mode, it will just return "Go down the list". Let's assume it's the case.

Now the ringer handler is called. It makes the ringing sound, and will stop it automatically when something happens to the call token using the signal. It will just return "Go down the list" anyway.

So the dialog handler gets called. It shows the dialog, and will hide automatically when something happens to the call token using the signal. It will just return "Go down the list" anyway.

We get a saner behaviour, and we can stick quite a few other handlers in there to handle wilder things.

Notice that this pattern is also one which is often used to handle XMPP messages, so having a good implementation of such a chain system would be nice for future things :-)

The api of the object would be something like :
void chain_of_responsibility_add_handler (chain, handler, priority);
chain_result chain_of_responsibility_handle (chain, message);

Where the priority would be something like "first" and "last", and would either : * put the handler at the end of the first list or second list if we have two lists of handlers ; * put the handler at the beginning or the end of the list if we only have one.

And where the chain_result would be HANDLED_OK or HANDLED_FURTHER.

And where message would be I don't know what.

And where a handler would be a function :
chain_result handle (handler, message);

Notice how I made chain_of_responsibility_handle look very much like a handler itself, which would allow chaining chains, should the need arise.

Probably glib or gobject already has something looking like this we could reuse. If not, it shouldn't be hard to implement.

Hope it makes sense.

Snark



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]