--- /dev/null
+// 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;
+}
+
--- /dev/null
+// 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;
+}
--- /dev/null
+
+// 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;
+}