I've recently been working on an example StreamedMedia connection manager, in which simulated contacts can be called (having a simulated contact who calls you whenever you go from Away to Available isn't far down the list of things to do).
In the process, I've run into a problem with stream directionality: we don't always know the direction of streams! When StreamAdded is emitted, it doesn't tell the client about the stream direction (although when RequestStreams returns, it does). Introduction ============ Incoming calls have one or more streams. Each stream has a (current) direction, which can be None, Receive, Send or Bidirectional. These are an enum for historical reasons, but should be treated as a set of flags: neither, either or both of Receive and Send. Each stream also has a set of pending send flags, which can be neither, either or both of Pending_Local_Send and Pending_Remote_Send. For streaming from us to the remote contact, the possible states are nothing (we are not sending and the remote contact is content with this), Pending_Local_Send (we are not sending but the remote contact would like us to), and Send (we are sending media). Send and Pending_Local_Send do not make sense together. Similarly, for streaming from the remote contact to us, the possible states are nothing (the remote contact is not sending and we are content with this), Pending_Remote_Send (they are not sending but we would like them to do so), and Receive (we are receiving media). Receive and Pending_Remote_Send do not make sense together. How Gabble implements it ======================== Streams created by the remote contact are created with a direction set by the Jingle content, except that if they asked for us to send, we transform that into Pending_Local_Send so the user can approve it. If a call to RequestStreamDirection enables sending, we'll accept a pending local send if there is one; otherwise, we'll alter the "senders" attribute on the Jingle content to inform the peer that we would like to send them media. When we move our own handle from local-pending to member state (= accept the call), all currently pending local sends are automatically accepted (i.e. we start sending if we were asked to). Streams created by us are set to Bidirectional immediately; the remote contact might refuse this by changing the direction at their end. If a call to RequestStreamDirection enables receiving, we tell the remote contact to send us media, and blindly assume that they will do so (the StreamDirectionChanged signal immediately indicates that we expect to receive). If they refuse our request, they'll do so by removing the Receive direction later. This appears to be because the protocol has no concept of an intermediate/requested state. Conceptually, the stream is bidirectional as soon as we say it is, and the contact's only recourse is to change it back to (from their point of view) receive-only if they don't actually want to send us media. This doesn't really seem right, though - surely they send back *some* sort of affirmative response if they'll be sending us media? How telepathy-sofiasip implements it ==================================== Streams created by the remote contact are receiving and pending local send, which seems right. If the call is on hold locally, streams created by the remote contact are directionless and pending local send, which also seems right. Streams created by the local contact are receiving and pending remote send, which seems to me to be clearly wrong. Surely they should be sending and pending remote send? If the call is on hold locally, streams created by the local contact are directionless and pending remote send, which seems OK (but why would we want to request a stream if we've placed the call on hold, and why aren't they directionless and not pending anything?) When we request a stream direction, the code is a twisty maze of bitfields that doesn't make sense to me right now - perhaps some vodka would help. It doesn't look right to me at the moment, though... What StreamAdded should imply ============================= Possible solutions seem to be: * Arbitrarily pick one of the possible directions (which one?) and declare it to be the default. In all other cases, emit StreamDirectionChanged immediately after StreamAdded. * Require clients to call ListStreams after every StreamAdded to find out what's *really* going on. _______________________________________________ telepathy mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/telepathy
