]> www.infradead.org Git - pidgin-chime.git/commitdiff
Import tincan protobuf definitions
authorDavid Woodhouse <dwmw@amazon.co.uk>
Mon, 11 Sep 2017 21:12:20 +0000 (14:12 -0700)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Mon, 11 Sep 2017 21:19:42 +0000 (14:19 -0700)
We will probably end up doing this differently — partly because we might
be able to use a GLib-based protobuf encoder/decoder which fits more
neatly, and partly because we don't *want* to be lifting things from
internal code even if it's just the protocol definitions in a standard
form. But this is the easy option for now....

protobuf/auth_message.proto [new file with mode: 0644]
protobuf/data_message.proto [new file with mode: 0644]
protobuf/rt_message.proto [new file with mode: 0644]

diff --git a/protobuf/auth_message.proto b/protobuf/auth_message.proto
new file mode 100644 (file)
index 0000000..abac29e
--- /dev/null
@@ -0,0 +1,178 @@
+//  AUTH PROTOCOL 
+//
+//  The client drives the auth sequence until the RT packet flow is started.
+//  The server responds to client messages based on the sequence of messages
+//  received and the state of the authorization.  To be resilient to an
+//  unreliable transport, the client resends each message until a response is
+//  received or too many tries have been made.
+//
+//  FULL DUPLEX AUTH SEQUENCE
+//
+//     Client                  Server
+//
+//  1. REQUEST  ------>  
+//
+//              <------  2. RESPONSE
+//                            authorized=true
+//
+//  3. mic      <=====>  3. spk
+//     packets              packets
+//
+//  The client repeatedly sends a Request message until a Response is received.
+//  When it receives a Response message with authorized=true, it leaves auth
+//  mode and begins sending and receiving RT packets.
+//
+//  The server responds to each Request with a Response.  If authorization
+//  fails, it closes the connection immediately after sending the response.  If
+//  authorization succeeds, it continues to respond to authorization requests
+//  so long as the details of the request do not change; this accomodates lost
+//  response packets.  If too many requests are received, the server hangs up.
+//  If an RT packet is received after successful authorization for a duplex
+//  stream, the server leaves auth mode and begins sending and receiving RT
+//  packets.
+//
+//
+//  DEPRECATED MIC AND SPK STREAM AUTH SEQUENCES
+//
+//  In these deprecated sequences, the flow of RT packets is unidirectional and
+//  opposite for microphone and speaker streams, and so we use slightly
+//  different sequences.
+//
+//  MIC SEQUENCE (DEPRECATED)
+//
+//     Client                  Server
+//
+//  1. REQUEST  ------>  
+//
+//              <------  2. RESPONSE
+//                            authorized=true
+//  3. mic      ======>
+//     packets
+//
+//  The client repeatedly sends a Request message until a Response is received.
+//  When it receives a Response message with authorized=true, it leaves auth
+//  mode and begins sending mic packets.
+//
+//  The server responds to each Request with a Response.  If authorization
+//  fails, it closes the connection immediately after sending the response.  If
+//  authorization succeeds, it continues to respond to authorization requests
+//  so long as the details of the request do not change; this accomodates lost
+//  response packets.  If too many requests are received, the server hangs up.
+//  If an audio packet is received after successful authorization for a mic
+//  stream, the server leaves auth mode and services the mic stream.
+//
+//
+//  SPEAKER SEQUENCE (DEPRECATED)
+//
+//     Client                  Server
+//
+//  1. REQUEST  ------>  
+//
+//              <------  2. RESPONSE
+//                            authorized=true
+//  3. FINISH   ------>
+//
+//              <======  4. speaker packets
+//
+//  The client repeatedly sends a Request message until a Response is received.
+//  When it receives a Response message with authorized=true, it repeatedly
+//  sends a Finish message until a speaker packet is received.
+//  
+//  The server responds to each Request with a Response.  If authorization
+//  fails, it closes the connection immediately after sending the response.  If
+//  authorization succeeds, it continues to respond to authorization requests
+//  so long as the details of the request do not change; this accomodates lost
+//  response packets.  If too many requests are received, the server hangs up.
+//  If a Finish packet is received after successful authorization for a speaker
+//  stream, the server leaves auth mode and begins sending speaker packets.
+//
+//
+//  HANGUP SEQUENCE
+//
+//  The client may initiate the hangup sequence at any time after successful
+//  authorization.  The client sends a HANGUP message and waits for a FINISH
+//  message from the server.  It resends the HANGUP message on a timeout
+//  repeatedly until the FINISH is received or too many tries have been made.
+//
+//  The server checks for a HANGUP message when reading, and when received,
+//  sends a FINISH message and closes the connection.  Note that the server
+//  only responds to a single HANGUP message, and thus if the FINISH message is
+//  lost over unreliable transport, the client will fruitlessly retransmit
+//  HANGUP until it gives up.
+//
+//
+//  SERVER HANGUP SEQUENCE
+//
+//  If a client reports on its initial authorization packet that it supports
+//  being hung up on by the server by enabling the FLAG_HAS_SERVER_HANGUP flag,
+//  then the server server may initiate the hangup sequence at any time after
+//  successful authorization.  The server sends a HANGUP message to the client.
+//  The client should respond with a FINISH message, thus allowing both ends to
+//  terminate the connection.
+//
+
+message AuthMessage {
+    optional AuthMessageType message_type  = 1;
+    optional          uint32 call_id       = 2;  // relay only
+    optional     ServiceType service_type  = 3;
+    optional          string session_token = 4;
+    optional            bool authorized    = 5;
+    optional          string call_uuid     = 6;  // CCP only
+    optional          string profile_uuid  = 7;  // for display only, CCP clients
+    optional          uint32 profile_id    = 16; // for display only, relay clients
+    
+    // at one point we had the idea that codec would be dynamically
+    // settable in each rt packet. however, tincan internals currently
+    // require this to be specified. setting this once in the auth message
+    // avoid wasting space on sending the codec id in each subsequent media
+    // packet
+    optional          uint32 codec         = 17;
+
+    optional          uint32 flags         = 18;
+    optional     PolyContext poly_context  = 19;
+    optional          uint32 status        = 21;
+    optional          uint32 origin        = 22 [default=1];
+    optional          uint32 server_flags  = 23;
+}
+
+message PolyContext {
+    optional string call_token      = 1;
+    repeated string local_addresses = 2;
+}
+
+enum AuthMessageType {
+    REQUEST  = 1;
+    RESPONSE = 2;
+    FINISH   = 3;
+    HANGUP   = 4;
+}
+
+enum ServiceType { // note: match xtl_connection_type_t
+     SPEAKER     = 1;
+     MICROPHONE  = 2;
+     FULL_DUPLEX = 3;
+}
+
+// client status/capabilities
+enum Flags {
+    FLAG_MUTE                 = 1;
+    FLAG_HAS_MIC_GAP_FIX      = 2;
+    FLAG_HAS_SERVER_HANGUP    = 4;
+    FLAG_HAS_POLY_BRAIN       = 8;
+    FLAG_HAS_POLY_CLIENT      = 16;
+    FLAG_HAS_PROFILE_TABLE    = 32;
+    FLAG_HAS_DISCONNECT_AUDIO = 64;
+    FLAG_HAS_CLIENT_STATUS    = 128;
+    FLAG_HAS_RX_MUTE_DTX      = 256;
+}
+
+// sent by server to client
+enum ServerFlags {
+    SERVER_FLAG_HAS_RX_MUTE_DTX = 1;
+}
+
+enum Origin {
+    ORIGIN_NATIVE   = 1;
+    ORIGIN_H323     = 2;
+}
+
diff --git a/protobuf/data_message.proto b/protobuf/data_message.proto
new file mode 100644 (file)
index 0000000..32347a2
--- /dev/null
@@ -0,0 +1,45 @@
+// XRPDataMessage
+// is used to implement a simple reliable message protocol.
+// Messages can be broken into segments which are conveyed
+// by DataMessage packets.
+//
+// seq is monotonically increasing (mod 2^32) for each packet
+// msg_id is monotonically increasing (mod 2^32) for each logical message
+// Messages are delivered in order according to msg_id.
+//
+// A single logical message can be split across multiple
+// DataMessage packets, each having the same msg_id and different
+// seq.
+//
+// msg_len is the total length of the logical message
+// and must be sent in every segment.
+//
+// offset indicates the offset in bytes of this segment within
+// the logical message.
+//
+// data carries the bytes to be reassembled into the larger message.
+//
+// ack is carries the sequence number to be acknowledged. It
+// can be piggybacked with other data, or sent alone. To ack
+// multiple packets or to selectively acknowledge, use the optional
+// ack_mask bitfield. Acks are not cumulative, so every packet
+// must be acked.
+//
+message DataMessage {
+  optional uint32  seq      = 1;
+  optional uint32  msg_id   = 2;
+  optional uint32  msg_len  = 3;
+  optional uint32  offset   = 4;
+  optional bytes   data     = 5;
+  optional uint32  ack      = 6;
+  optional uint64  ack_mask = 7;
+}
+
+message StreamIdInfo {
+  optional uint32  stream_id  = 1;
+  optional string  profile_id = 2;
+}
+
+message StreamMessage {
+  repeated StreamIdInfo streams = 1;
+}
diff --git a/protobuf/rt_message.proto b/protobuf/rt_message.proto
new file mode 100644 (file)
index 0000000..63c3b10
--- /dev/null
@@ -0,0 +1,95 @@
+
+// xxx call_id will be removed
+
+message RTMessage {
+  optional uint32               call_id         = 1; // deprecated
+  optional uint32               locale_id       = 2; // for future use
+  optional AudioMessage         audio           = 3;
+  repeated ProfileMessage       profiles        = 4;
+  repeated ClientStatsMessage   client_stats    = 16;
+  repeated QualityMessage       qualities       = 17; // deprecated
+  optional PolyMessage          poly_info       = 18;
+  optional ClientStatusMessage  client_status   = 19;
+}
+
+message AudioMessage {
+  optional uint32  seq               = 1; // randomized uint16 carried in a uint32.
+  optional fixed32 sample_time       = 2; // randomized uint32.
+  optional uint32  codec             = 3; // deprecated
+  optional bytes   audio             = 4;
+  optional uint32  total_frames_lost = 5; // frames lost in the *opposite* direction
+  optional uint32  flags             = 6;
+  optional fixed64 server_time       = 16;
+  optional fixed64 echo_time         = 17;
+  optional uint32  pong              = 18; // sequence number
+  optional fixed64 client_time       = 19; // client system time
+  optional fixed64 playout_delay     = 20;
+  optional uint32  pong_time_offset  = 21; // time offset of pong in microseconds
+  optional fixed64 ntp_time          = 22; // ntp_time capture time  
+}
+
+message ProfileMessage {
+  // Previously stream_id was called profile_id.
+  // When we migrated to strings for profile ids we did
+  // not want to send strings in these messages because they
+  // are sent frequently and can consume a lot of bandwidth.
+  // For legacy clients using a uint32 for profile id,
+  // stream_id == profile id. For new clients, there will
+  // be a mapping from stream_id to string profile id.
+  optional uint32  stream_id       = 1;
+  optional uint32  volume          = 2;  // either volume or muted should be set, not both
+  optional bool    muted           = 3;
+  optional uint32  signal_strength = 4;
+  optional fixed64 ntp_timestamp   = 5;
+}
+
+message ClientStatsMessage {
+  optional uint64  time        = 1; // only send once in a single message list
+  optional string  key         = 2; // deprecated
+  optional float   value       = 3;
+  optional uint32  tag         = 4;
+}
+
+// deprecated
+message QualityMessage {
+  optional uint32 profile_id = 1;
+  // signal strength one of three states 0=none, 1=weak, 2=good
+  optional uint32 signal_strength = 2;
+}
+
+enum RTFlags {
+    FLAG_PING          = 1;
+    FLAG_NON_PRESENTER = 2;
+}
+
+message PolyMessage {
+    repeated PolyEndpoint candidates = 1;
+}
+
+message PolyEndpoint {
+    optional string address = 1;
+    optional string token   = 2;
+    optional uint32 port    = 3;
+}
+
+//
+// The remote_mute and remote_mute_ack flags are used as follows:
+//
+//   1. relay tells tincan to remote mute a caller
+//   2. tincan will start sending ClientStatusMessages to the given
+//      client with remote_muted=true
+//   3. the client, seeing remote_muted=true, will mute itself and then
+//      send ClientStatusMessages back to tincan with remote_mute_ack=true
+//   4. when tincan sees remote_mute_ack=true, it will clear the
+//      remote_muted field back to false
+//   5. when the client then sees remote_muted=false, it will clear its
+//      remote_mute_ack field back to false
+//
+// This "fire" and then "ack" style allows us to treat remote muting as the
+// event that it is, rather than a "state" of the call in tincan.
+//
+message ClientStatusMessage {
+    optional bool   remote_muted    = 1;
+    optional bool   is_recording    = 2;
+    optional bool   remote_mute_ack = 3;
+}