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
_______________________________________________
Ekiga-devel-list mailing list
Ekiga-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/ekiga-devel-list

Reply via email to