[gnome-network-displays/cc-tmp: 2/80] cc: wip connect and other messages don't seem to work




commit ab065f8aaee8ddbdb07b45e7a6edbe06b4bf01f9
Author: Anupam Kumar <kyteinsky gmail com>
Date:   Mon Jul 11 18:51:31 2022 +0530

    cc: wip connect and other messages don't seem to work

 src/cc/cast_channel.pb-c.c | 603 +++++++++++++++++++++++++++++++++++++++++++++
 src/cc/cast_channel.pb-c.h | 274 ++++++++++++++++++++
 src/cc/cast_channel.proto  |  79 ++++++
 src/cc/cc-client.c         |   6 +-
 src/cc/meson.build         |  24 ++
 src/meson.build            |   4 +-
 src/nd-cc-provider.c       |   2 +
 src/nd-cc-sink.c           | 279 ++++++++++++++++-----
 src/nd-cc-sink.h           |   7 +
 9 files changed, 1207 insertions(+), 71 deletions(-)
---
diff --git a/src/cc/cast_channel.pb-c.c b/src/cc/cast_channel.pb-c.c
new file mode 100644
index 0000000..097bfaf
--- /dev/null
+++ b/src/cc/cast_channel.pb-c.c
@@ -0,0 +1,603 @@
+/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
+/* Generated from: cast_channel.proto */
+
+/* Do not generate deprecated warnings for self */
+#ifndef PROTOBUF_C__NO_DEPRECATED
+#define PROTOBUF_C__NO_DEPRECATED
+#endif
+
+#include "cast_channel.pb-c.h"
+void   castchannel__cast_message__init
+                     (Castchannel__CastMessage         *message)
+{
+  static const Castchannel__CastMessage init_value = CASTCHANNEL__CAST_MESSAGE__INIT;
+  *message = init_value;
+}
+size_t castchannel__cast_message__get_packed_size
+                     (const Castchannel__CastMessage *message)
+{
+  assert(message->base.descriptor == &castchannel__cast_message__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t castchannel__cast_message__pack
+                     (const Castchannel__CastMessage *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &castchannel__cast_message__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t castchannel__cast_message__pack_to_buffer
+                     (const Castchannel__CastMessage *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &castchannel__cast_message__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+Castchannel__CastMessage *
+       castchannel__cast_message__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (Castchannel__CastMessage *)
+     protobuf_c_message_unpack (&castchannel__cast_message__descriptor,
+                                allocator, len, data);
+}
+void   castchannel__cast_message__free_unpacked
+                     (Castchannel__CastMessage *message,
+                      ProtobufCAllocator *allocator)
+{
+  if(!message)
+    return;
+  assert(message->base.descriptor == &castchannel__cast_message__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void   castchannel__auth_challenge__init
+                     (Castchannel__AuthChallenge         *message)
+{
+  static const Castchannel__AuthChallenge init_value = CASTCHANNEL__AUTH_CHALLENGE__INIT;
+  *message = init_value;
+}
+size_t castchannel__auth_challenge__get_packed_size
+                     (const Castchannel__AuthChallenge *message)
+{
+  assert(message->base.descriptor == &castchannel__auth_challenge__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t castchannel__auth_challenge__pack
+                     (const Castchannel__AuthChallenge *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &castchannel__auth_challenge__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t castchannel__auth_challenge__pack_to_buffer
+                     (const Castchannel__AuthChallenge *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &castchannel__auth_challenge__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+Castchannel__AuthChallenge *
+       castchannel__auth_challenge__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (Castchannel__AuthChallenge *)
+     protobuf_c_message_unpack (&castchannel__auth_challenge__descriptor,
+                                allocator, len, data);
+}
+void   castchannel__auth_challenge__free_unpacked
+                     (Castchannel__AuthChallenge *message,
+                      ProtobufCAllocator *allocator)
+{
+  if(!message)
+    return;
+  assert(message->base.descriptor == &castchannel__auth_challenge__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void   castchannel__auth_response__init
+                     (Castchannel__AuthResponse         *message)
+{
+  static const Castchannel__AuthResponse init_value = CASTCHANNEL__AUTH_RESPONSE__INIT;
+  *message = init_value;
+}
+size_t castchannel__auth_response__get_packed_size
+                     (const Castchannel__AuthResponse *message)
+{
+  assert(message->base.descriptor == &castchannel__auth_response__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t castchannel__auth_response__pack
+                     (const Castchannel__AuthResponse *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &castchannel__auth_response__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t castchannel__auth_response__pack_to_buffer
+                     (const Castchannel__AuthResponse *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &castchannel__auth_response__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+Castchannel__AuthResponse *
+       castchannel__auth_response__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (Castchannel__AuthResponse *)
+     protobuf_c_message_unpack (&castchannel__auth_response__descriptor,
+                                allocator, len, data);
+}
+void   castchannel__auth_response__free_unpacked
+                     (Castchannel__AuthResponse *message,
+                      ProtobufCAllocator *allocator)
+{
+  if(!message)
+    return;
+  assert(message->base.descriptor == &castchannel__auth_response__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void   castchannel__auth_error__init
+                     (Castchannel__AuthError         *message)
+{
+  static const Castchannel__AuthError init_value = CASTCHANNEL__AUTH_ERROR__INIT;
+  *message = init_value;
+}
+size_t castchannel__auth_error__get_packed_size
+                     (const Castchannel__AuthError *message)
+{
+  assert(message->base.descriptor == &castchannel__auth_error__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t castchannel__auth_error__pack
+                     (const Castchannel__AuthError *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &castchannel__auth_error__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t castchannel__auth_error__pack_to_buffer
+                     (const Castchannel__AuthError *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &castchannel__auth_error__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+Castchannel__AuthError *
+       castchannel__auth_error__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (Castchannel__AuthError *)
+     protobuf_c_message_unpack (&castchannel__auth_error__descriptor,
+                                allocator, len, data);
+}
+void   castchannel__auth_error__free_unpacked
+                     (Castchannel__AuthError *message,
+                      ProtobufCAllocator *allocator)
+{
+  if(!message)
+    return;
+  assert(message->base.descriptor == &castchannel__auth_error__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void   castchannel__device_auth_message__init
+                     (Castchannel__DeviceAuthMessage         *message)
+{
+  static const Castchannel__DeviceAuthMessage init_value = CASTCHANNEL__DEVICE_AUTH_MESSAGE__INIT;
+  *message = init_value;
+}
+size_t castchannel__device_auth_message__get_packed_size
+                     (const Castchannel__DeviceAuthMessage *message)
+{
+  assert(message->base.descriptor == &castchannel__device_auth_message__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t castchannel__device_auth_message__pack
+                     (const Castchannel__DeviceAuthMessage *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &castchannel__device_auth_message__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t castchannel__device_auth_message__pack_to_buffer
+                     (const Castchannel__DeviceAuthMessage *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &castchannel__device_auth_message__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+Castchannel__DeviceAuthMessage *
+       castchannel__device_auth_message__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (Castchannel__DeviceAuthMessage *)
+     protobuf_c_message_unpack (&castchannel__device_auth_message__descriptor,
+                                allocator, len, data);
+}
+void   castchannel__device_auth_message__free_unpacked
+                     (Castchannel__DeviceAuthMessage *message,
+                      ProtobufCAllocator *allocator)
+{
+  if(!message)
+    return;
+  assert(message->base.descriptor == &castchannel__device_auth_message__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+static const ProtobufCEnumValue castchannel__cast_message__protocol_version__enum_values_by_number[1] =
+{
+  { "CASTV2_1_0", "CASTCHANNEL__CAST_MESSAGE__PROTOCOL_VERSION__CASTV2_1_0", 0 },
+};
+static const ProtobufCIntRange castchannel__cast_message__protocol_version__value_ranges[] = {
+{0, 0},{0, 1}
+};
+static const ProtobufCEnumValueIndex castchannel__cast_message__protocol_version__enum_values_by_name[1] =
+{
+  { "CASTV2_1_0", 0 },
+};
+const ProtobufCEnumDescriptor castchannel__cast_message__protocol_version__descriptor =
+{
+  PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
+  "castchannel.CastMessage.ProtocolVersion",
+  "ProtocolVersion",
+  "Castchannel__CastMessage__ProtocolVersion",
+  "castchannel",
+  1,
+  castchannel__cast_message__protocol_version__enum_values_by_number,
+  1,
+  castchannel__cast_message__protocol_version__enum_values_by_name,
+  1,
+  castchannel__cast_message__protocol_version__value_ranges,
+  NULL,NULL,NULL,NULL   /* reserved[1234] */
+};
+static const ProtobufCEnumValue castchannel__cast_message__payload_type__enum_values_by_number[2] =
+{
+  { "STRING", "CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__STRING", 0 },
+  { "BINARY", "CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__BINARY", 1 },
+};
+static const ProtobufCIntRange castchannel__cast_message__payload_type__value_ranges[] = {
+{0, 0},{0, 2}
+};
+static const ProtobufCEnumValueIndex castchannel__cast_message__payload_type__enum_values_by_name[2] =
+{
+  { "BINARY", 1 },
+  { "STRING", 0 },
+};
+const ProtobufCEnumDescriptor castchannel__cast_message__payload_type__descriptor =
+{
+  PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
+  "castchannel.CastMessage.PayloadType",
+  "PayloadType",
+  "Castchannel__CastMessage__PayloadType",
+  "castchannel",
+  2,
+  castchannel__cast_message__payload_type__enum_values_by_number,
+  2,
+  castchannel__cast_message__payload_type__enum_values_by_name,
+  1,
+  castchannel__cast_message__payload_type__value_ranges,
+  NULL,NULL,NULL,NULL   /* reserved[1234] */
+};
+static const ProtobufCFieldDescriptor castchannel__cast_message__field_descriptors[7] =
+{
+  {
+    "protocol_version",
+    1,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_ENUM,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__CastMessage, protocol_version),
+    &castchannel__cast_message__protocol_version__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "source_id",
+    2,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_STRING,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__CastMessage, source_id),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "destination_id",
+    3,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_STRING,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__CastMessage, destination_id),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "namespace",
+    4,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_STRING,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__CastMessage, namespace_),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "payload_type",
+    5,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_ENUM,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__CastMessage, payload_type),
+    &castchannel__cast_message__payload_type__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "payload_utf8",
+    6,
+    PROTOBUF_C_LABEL_OPTIONAL,
+    PROTOBUF_C_TYPE_STRING,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__CastMessage, payload_utf8),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "payload_binary",
+    7,
+    PROTOBUF_C_LABEL_OPTIONAL,
+    PROTOBUF_C_TYPE_BYTES,
+    offsetof(Castchannel__CastMessage, has_payload_binary),
+    offsetof(Castchannel__CastMessage, payload_binary),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+};
+static const unsigned castchannel__cast_message__field_indices_by_name[] = {
+  2,   /* field[2] = destination_id */
+  3,   /* field[3] = namespace */
+  6,   /* field[6] = payload_binary */
+  4,   /* field[4] = payload_type */
+  5,   /* field[5] = payload_utf8 */
+  0,   /* field[0] = protocol_version */
+  1,   /* field[1] = source_id */
+};
+static const ProtobufCIntRange castchannel__cast_message__number_ranges[1 + 1] =
+{
+  { 1, 0 },
+  { 0, 7 }
+};
+const ProtobufCMessageDescriptor castchannel__cast_message__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "castchannel.CastMessage",
+  "CastMessage",
+  "Castchannel__CastMessage",
+  "castchannel",
+  sizeof(Castchannel__CastMessage),
+  7,
+  castchannel__cast_message__field_descriptors,
+  castchannel__cast_message__field_indices_by_name,
+  1,  castchannel__cast_message__number_ranges,
+  (ProtobufCMessageInit) castchannel__cast_message__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
+#define castchannel__auth_challenge__field_descriptors NULL
+#define castchannel__auth_challenge__field_indices_by_name NULL
+#define castchannel__auth_challenge__number_ranges NULL
+const ProtobufCMessageDescriptor castchannel__auth_challenge__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "castchannel.AuthChallenge",
+  "AuthChallenge",
+  "Castchannel__AuthChallenge",
+  "castchannel",
+  sizeof(Castchannel__AuthChallenge),
+  0,
+  castchannel__auth_challenge__field_descriptors,
+  castchannel__auth_challenge__field_indices_by_name,
+  0,  castchannel__auth_challenge__number_ranges,
+  (ProtobufCMessageInit) castchannel__auth_challenge__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
+static const ProtobufCFieldDescriptor castchannel__auth_response__field_descriptors[2] =
+{
+  {
+    "signature",
+    1,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_BYTES,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__AuthResponse, signature),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "client_auth_certificate",
+    2,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_BYTES,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__AuthResponse, client_auth_certificate),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+};
+static const unsigned castchannel__auth_response__field_indices_by_name[] = {
+  1,   /* field[1] = client_auth_certificate */
+  0,   /* field[0] = signature */
+};
+static const ProtobufCIntRange castchannel__auth_response__number_ranges[1 + 1] =
+{
+  { 1, 0 },
+  { 0, 2 }
+};
+const ProtobufCMessageDescriptor castchannel__auth_response__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "castchannel.AuthResponse",
+  "AuthResponse",
+  "Castchannel__AuthResponse",
+  "castchannel",
+  sizeof(Castchannel__AuthResponse),
+  2,
+  castchannel__auth_response__field_descriptors,
+  castchannel__auth_response__field_indices_by_name,
+  1,  castchannel__auth_response__number_ranges,
+  (ProtobufCMessageInit) castchannel__auth_response__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
+static const ProtobufCEnumValue castchannel__auth_error__error_type__enum_values_by_number[2] =
+{
+  { "INTERNAL_ERROR", "CASTCHANNEL__AUTH_ERROR__ERROR_TYPE__INTERNAL_ERROR", 0 },
+  { "NO_TLS", "CASTCHANNEL__AUTH_ERROR__ERROR_TYPE__NO_TLS", 1 },
+};
+static const ProtobufCIntRange castchannel__auth_error__error_type__value_ranges[] = {
+{0, 0},{0, 2}
+};
+static const ProtobufCEnumValueIndex castchannel__auth_error__error_type__enum_values_by_name[2] =
+{
+  { "INTERNAL_ERROR", 0 },
+  { "NO_TLS", 1 },
+};
+const ProtobufCEnumDescriptor castchannel__auth_error__error_type__descriptor =
+{
+  PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
+  "castchannel.AuthError.ErrorType",
+  "ErrorType",
+  "Castchannel__AuthError__ErrorType",
+  "castchannel",
+  2,
+  castchannel__auth_error__error_type__enum_values_by_number,
+  2,
+  castchannel__auth_error__error_type__enum_values_by_name,
+  1,
+  castchannel__auth_error__error_type__value_ranges,
+  NULL,NULL,NULL,NULL   /* reserved[1234] */
+};
+static const ProtobufCFieldDescriptor castchannel__auth_error__field_descriptors[1] =
+{
+  {
+    "error_type",
+    1,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_ENUM,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__AuthError, error_type),
+    &castchannel__auth_error__error_type__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+};
+static const unsigned castchannel__auth_error__field_indices_by_name[] = {
+  0,   /* field[0] = error_type */
+};
+static const ProtobufCIntRange castchannel__auth_error__number_ranges[1 + 1] =
+{
+  { 1, 0 },
+  { 0, 1 }
+};
+const ProtobufCMessageDescriptor castchannel__auth_error__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "castchannel.AuthError",
+  "AuthError",
+  "Castchannel__AuthError",
+  "castchannel",
+  sizeof(Castchannel__AuthError),
+  1,
+  castchannel__auth_error__field_descriptors,
+  castchannel__auth_error__field_indices_by_name,
+  1,  castchannel__auth_error__number_ranges,
+  (ProtobufCMessageInit) castchannel__auth_error__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
+static const ProtobufCFieldDescriptor castchannel__device_auth_message__field_descriptors[3] =
+{
+  {
+    "challenge",
+    1,
+    PROTOBUF_C_LABEL_OPTIONAL,
+    PROTOBUF_C_TYPE_MESSAGE,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__DeviceAuthMessage, challenge),
+    &castchannel__auth_challenge__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "response",
+    2,
+    PROTOBUF_C_LABEL_OPTIONAL,
+    PROTOBUF_C_TYPE_MESSAGE,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__DeviceAuthMessage, response),
+    &castchannel__auth_response__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "error",
+    3,
+    PROTOBUF_C_LABEL_OPTIONAL,
+    PROTOBUF_C_TYPE_MESSAGE,
+    0,   /* quantifier_offset */
+    offsetof(Castchannel__DeviceAuthMessage, error),
+    &castchannel__auth_error__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+};
+static const unsigned castchannel__device_auth_message__field_indices_by_name[] = {
+  0,   /* field[0] = challenge */
+  2,   /* field[2] = error */
+  1,   /* field[1] = response */
+};
+static const ProtobufCIntRange castchannel__device_auth_message__number_ranges[1 + 1] =
+{
+  { 1, 0 },
+  { 0, 3 }
+};
+const ProtobufCMessageDescriptor castchannel__device_auth_message__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "castchannel.DeviceAuthMessage",
+  "DeviceAuthMessage",
+  "Castchannel__DeviceAuthMessage",
+  "castchannel",
+  sizeof(Castchannel__DeviceAuthMessage),
+  3,
+  castchannel__device_auth_message__field_descriptors,
+  castchannel__device_auth_message__field_indices_by_name,
+  1,  castchannel__device_auth_message__number_ranges,
+  (ProtobufCMessageInit) castchannel__device_auth_message__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
diff --git a/src/cc/cast_channel.pb-c.h b/src/cc/cast_channel.pb-c.h
new file mode 100644
index 0000000..c925886
--- /dev/null
+++ b/src/cc/cast_channel.pb-c.h
@@ -0,0 +1,274 @@
+/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
+/* Generated from: cast_channel.proto */
+
+#ifndef PROTOBUF_C_cast_5fchannel_2eproto__INCLUDED
+#define PROTOBUF_C_cast_5fchannel_2eproto__INCLUDED
+
+#include <protobuf-c/protobuf-c.h>
+
+PROTOBUF_C__BEGIN_DECLS
+
+#if PROTOBUF_C_VERSION_NUMBER < 1000000
+# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c 
headers. Please update your headers.
+#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION
+# error This file was generated by an older version of protoc-c which is incompatible with your 
libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
+#endif
+
+
+typedef struct Castchannel__CastMessage Castchannel__CastMessage;
+typedef struct Castchannel__AuthChallenge Castchannel__AuthChallenge;
+typedef struct Castchannel__AuthResponse Castchannel__AuthResponse;
+typedef struct Castchannel__AuthError Castchannel__AuthError;
+typedef struct Castchannel__DeviceAuthMessage Castchannel__DeviceAuthMessage;
+
+
+/* --- enums --- */
+
+/*
+ * Always pass a version of the protocol for future compatibility
+ * requirements.
+ */
+typedef enum _Castchannel__CastMessage__ProtocolVersion {
+  CASTCHANNEL__CAST_MESSAGE__PROTOCOL_VERSION__CASTV2_1_0 = 0
+    PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(CASTCHANNEL__CAST_MESSAGE__PROTOCOL_VERSION)
+} Castchannel__CastMessage__ProtocolVersion;
+/*
+ * What type of data do we have in this message.
+ */
+typedef enum _Castchannel__CastMessage__PayloadType {
+  CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__STRING = 0,
+  CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__BINARY = 1
+    PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE)
+} Castchannel__CastMessage__PayloadType;
+typedef enum _Castchannel__AuthError__ErrorType {
+  CASTCHANNEL__AUTH_ERROR__ERROR_TYPE__INTERNAL_ERROR = 0,
+  /*
+   * The underlying connection is not TLS
+   */
+  CASTCHANNEL__AUTH_ERROR__ERROR_TYPE__NO_TLS = 1
+    PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(CASTCHANNEL__AUTH_ERROR__ERROR_TYPE)
+} Castchannel__AuthError__ErrorType;
+
+/* --- messages --- */
+
+struct  Castchannel__CastMessage
+{
+  ProtobufCMessage base;
+  Castchannel__CastMessage__ProtocolVersion protocol_version;
+  /*
+   * source and destination ids identify the origin and destination of the
+   * message.  They are used to route messages between endpoints that share a
+   * device-to-device channel.
+   * For messages between applications:
+   *   - The sender application id is a unique identifier generated on behalf of
+   *     the sender application.
+   *   - The receiver id is always the the session id for the application.
+   * For messages to or from the sender or receiver platform, the special ids
+   * 'sender-0' and 'receiver-0' can be used.
+   * For messages intended for all endpoints using a given channel, the
+   * wildcard destination_id '*' can be used.
+   */
+  char *source_id;
+  char *destination_id;
+  /*
+   * This is the core multiplexing key.  All messages are sent on a namespace
+   * and endpoints sharing a channel listen on one or more namespaces.  The
+   * namespace defines the protocol and semantics of the message.
+   */
+  char *namespace_;
+  Castchannel__CastMessage__PayloadType payload_type;
+  /*
+   * Depending on payload_type, exactly one of the following optional fields
+   * will always be set.
+   */
+  char *payload_utf8;
+  protobuf_c_boolean has_payload_binary;
+  ProtobufCBinaryData payload_binary;
+};
+#define CASTCHANNEL__CAST_MESSAGE__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&castchannel__cast_message__descriptor) \
+    , CASTCHANNEL__CAST_MESSAGE__PROTOCOL_VERSION__CASTV2_1_0, NULL, NULL, NULL, 
CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__STRING, NULL, 0, {0,NULL} }
+
+
+/*
+ * Messages for authentication protocol between a sender and a receiver.
+ */
+struct  Castchannel__AuthChallenge
+{
+  ProtobufCMessage base;
+};
+#define CASTCHANNEL__AUTH_CHALLENGE__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&castchannel__auth_challenge__descriptor) \
+     }
+
+
+struct  Castchannel__AuthResponse
+{
+  ProtobufCMessage base;
+  ProtobufCBinaryData signature;
+  ProtobufCBinaryData client_auth_certificate;
+};
+#define CASTCHANNEL__AUTH_RESPONSE__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&castchannel__auth_response__descriptor) \
+    , {0,NULL}, {0,NULL} }
+
+
+struct  Castchannel__AuthError
+{
+  ProtobufCMessage base;
+  Castchannel__AuthError__ErrorType error_type;
+};
+#define CASTCHANNEL__AUTH_ERROR__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&castchannel__auth_error__descriptor) \
+    , CASTCHANNEL__AUTH_ERROR__ERROR_TYPE__INTERNAL_ERROR }
+
+
+struct  Castchannel__DeviceAuthMessage
+{
+  ProtobufCMessage base;
+  /*
+   * Request fields
+   */
+  Castchannel__AuthChallenge *challenge;
+  /*
+   * Response fields
+   */
+  Castchannel__AuthResponse *response;
+  Castchannel__AuthError *error;
+};
+#define CASTCHANNEL__DEVICE_AUTH_MESSAGE__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&castchannel__device_auth_message__descriptor) \
+    , NULL, NULL, NULL }
+
+
+/* Castchannel__CastMessage methods */
+void   castchannel__cast_message__init
+                     (Castchannel__CastMessage         *message);
+size_t castchannel__cast_message__get_packed_size
+                     (const Castchannel__CastMessage   *message);
+size_t castchannel__cast_message__pack
+                     (const Castchannel__CastMessage   *message,
+                      uint8_t             *out);
+size_t castchannel__cast_message__pack_to_buffer
+                     (const Castchannel__CastMessage   *message,
+                      ProtobufCBuffer     *buffer);
+Castchannel__CastMessage *
+       castchannel__cast_message__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   castchannel__cast_message__free_unpacked
+                     (Castchannel__CastMessage *message,
+                      ProtobufCAllocator *allocator);
+/* Castchannel__AuthChallenge methods */
+void   castchannel__auth_challenge__init
+                     (Castchannel__AuthChallenge         *message);
+size_t castchannel__auth_challenge__get_packed_size
+                     (const Castchannel__AuthChallenge   *message);
+size_t castchannel__auth_challenge__pack
+                     (const Castchannel__AuthChallenge   *message,
+                      uint8_t             *out);
+size_t castchannel__auth_challenge__pack_to_buffer
+                     (const Castchannel__AuthChallenge   *message,
+                      ProtobufCBuffer     *buffer);
+Castchannel__AuthChallenge *
+       castchannel__auth_challenge__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   castchannel__auth_challenge__free_unpacked
+                     (Castchannel__AuthChallenge *message,
+                      ProtobufCAllocator *allocator);
+/* Castchannel__AuthResponse methods */
+void   castchannel__auth_response__init
+                     (Castchannel__AuthResponse         *message);
+size_t castchannel__auth_response__get_packed_size
+                     (const Castchannel__AuthResponse   *message);
+size_t castchannel__auth_response__pack
+                     (const Castchannel__AuthResponse   *message,
+                      uint8_t             *out);
+size_t castchannel__auth_response__pack_to_buffer
+                     (const Castchannel__AuthResponse   *message,
+                      ProtobufCBuffer     *buffer);
+Castchannel__AuthResponse *
+       castchannel__auth_response__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   castchannel__auth_response__free_unpacked
+                     (Castchannel__AuthResponse *message,
+                      ProtobufCAllocator *allocator);
+/* Castchannel__AuthError methods */
+void   castchannel__auth_error__init
+                     (Castchannel__AuthError         *message);
+size_t castchannel__auth_error__get_packed_size
+                     (const Castchannel__AuthError   *message);
+size_t castchannel__auth_error__pack
+                     (const Castchannel__AuthError   *message,
+                      uint8_t             *out);
+size_t castchannel__auth_error__pack_to_buffer
+                     (const Castchannel__AuthError   *message,
+                      ProtobufCBuffer     *buffer);
+Castchannel__AuthError *
+       castchannel__auth_error__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   castchannel__auth_error__free_unpacked
+                     (Castchannel__AuthError *message,
+                      ProtobufCAllocator *allocator);
+/* Castchannel__DeviceAuthMessage methods */
+void   castchannel__device_auth_message__init
+                     (Castchannel__DeviceAuthMessage         *message);
+size_t castchannel__device_auth_message__get_packed_size
+                     (const Castchannel__DeviceAuthMessage   *message);
+size_t castchannel__device_auth_message__pack
+                     (const Castchannel__DeviceAuthMessage   *message,
+                      uint8_t             *out);
+size_t castchannel__device_auth_message__pack_to_buffer
+                     (const Castchannel__DeviceAuthMessage   *message,
+                      ProtobufCBuffer     *buffer);
+Castchannel__DeviceAuthMessage *
+       castchannel__device_auth_message__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   castchannel__device_auth_message__free_unpacked
+                     (Castchannel__DeviceAuthMessage *message,
+                      ProtobufCAllocator *allocator);
+/* --- per-message closures --- */
+
+typedef void (*Castchannel__CastMessage_Closure)
+                 (const Castchannel__CastMessage *message,
+                  void *closure_data);
+typedef void (*Castchannel__AuthChallenge_Closure)
+                 (const Castchannel__AuthChallenge *message,
+                  void *closure_data);
+typedef void (*Castchannel__AuthResponse_Closure)
+                 (const Castchannel__AuthResponse *message,
+                  void *closure_data);
+typedef void (*Castchannel__AuthError_Closure)
+                 (const Castchannel__AuthError *message,
+                  void *closure_data);
+typedef void (*Castchannel__DeviceAuthMessage_Closure)
+                 (const Castchannel__DeviceAuthMessage *message,
+                  void *closure_data);
+
+/* --- services --- */
+
+
+/* --- descriptors --- */
+
+extern const ProtobufCMessageDescriptor castchannel__cast_message__descriptor;
+extern const ProtobufCEnumDescriptor    castchannel__cast_message__protocol_version__descriptor;
+extern const ProtobufCEnumDescriptor    castchannel__cast_message__payload_type__descriptor;
+extern const ProtobufCMessageDescriptor castchannel__auth_challenge__descriptor;
+extern const ProtobufCMessageDescriptor castchannel__auth_response__descriptor;
+extern const ProtobufCMessageDescriptor castchannel__auth_error__descriptor;
+extern const ProtobufCEnumDescriptor    castchannel__auth_error__error_type__descriptor;
+extern const ProtobufCMessageDescriptor castchannel__device_auth_message__descriptor;
+
+PROTOBUF_C__END_DECLS
+
+
+#endif  /* PROTOBUF_C_cast_5fchannel_2eproto__INCLUDED */
diff --git a/src/cc/cast_channel.proto b/src/cc/cast_channel.proto
new file mode 100644
index 0000000..d940baa
--- /dev/null
+++ b/src/cc/cast_channel.proto
@@ -0,0 +1,79 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package castchannel;
+
+message CastMessage {
+  // Always pass a version of the protocol for future compatibility
+  // requirements.
+  enum ProtocolVersion {
+    CASTV2_1_0 = 0;
+  }
+  required ProtocolVersion protocol_version = 1;
+
+  // source and destination ids identify the origin and destination of the
+  // message.  They are used to route messages between endpoints that share a
+  // device-to-device channel.
+  //
+  // For messages between applications:
+  //   - The sender application id is a unique identifier generated on behalf of
+  //     the sender application.
+  //   - The receiver id is always the the session id for the application.
+  //
+  // For messages to or from the sender or receiver platform, the special ids
+  // 'sender-0' and 'receiver-0' can be used.
+  //
+  // For messages intended for all endpoints using a given channel, the
+  // wildcard destination_id '*' can be used.
+  required string source_id = 2;
+  required string destination_id = 3;
+
+  // This is the core multiplexing key.  All messages are sent on a namespace
+  // and endpoints sharing a channel listen on one or more namespaces.  The
+  // namespace defines the protocol and semantics of the message.
+  required string namespace = 4;
+
+  // Encoding and payload info follows.
+
+  // What type of data do we have in this message.
+  enum PayloadType {
+    STRING = 0;
+    BINARY = 1;
+  }
+  required PayloadType payload_type = 5;
+
+  // Depending on payload_type, exactly one of the following optional fields
+  // will always be set.
+  optional string payload_utf8 = 6;
+  optional bytes payload_binary = 7;
+}
+
+// Messages for authentication protocol between a sender and a receiver.
+message AuthChallenge {
+}
+
+message AuthResponse {
+  required bytes signature = 1;
+  required bytes client_auth_certificate = 2;
+}
+
+message AuthError {
+  enum ErrorType {
+    INTERNAL_ERROR = 0;
+    NO_TLS = 1;  // The underlying connection is not TLS
+  }
+  required ErrorType error_type = 1;
+}
+
+message DeviceAuthMessage {
+  // Request fields
+  optional AuthChallenge challenge = 1;
+  // Response fields
+  optional AuthResponse response = 2;
+  optional AuthError error = 3;
+}
diff --git a/src/cc/cc-client.c b/src/cc/cc-client.c
index e990cdd..c01075f 100644
--- a/src/cc/cc-client.c
+++ b/src/cc/cc-client.c
@@ -2,9 +2,9 @@
 #include <gst/rtsp/gstrtspmessage.h>
 #include <gst/video/video.h>
 #include "cc-client.h"
-#include "wfd-media-factory.h"
-#include "wfd-media.h"
-#include "wfd-params.h"
+#include "../wfd/wfd-media-factory.h"
+#include "../wfd/wfd-media.h"
+#include "../wfd/wfd-params.h"
 
 typedef enum {
   INIT_STATE_M0_INVALID = 0,
diff --git a/src/cc/meson.build b/src/cc/meson.build
new file mode 100644
index 0000000..bdff983
--- /dev/null
+++ b/src/cc/meson.build
@@ -0,0 +1,24 @@
+
+cc_sources = [
+  'cc-client.c',
+  'cast_channel.pb-c.c',
+]
+
+#enum_headers = files()
+#
+#gnome_nd_sources += gnome.mkenums_simple(
+#  'nd-enum-types',
+#  sources: enum_headers,
+#)
+
+cc_deps = [
+  dependency('gstreamer-video-1.0', version: '>= 1.14'),
+  dependency('gstreamer-rtsp-1.0', version: '>= 1.14'),
+  dependency('libprotobuf-c', version: '>= 1.0.0'),
+]
+
+cc_cast_channel = static_library(
+  'cc-cast-channel',
+  cc_sources,
+  dependencies: cc_deps,
+)
diff --git a/src/meson.build b/src/meson.build
index 13ddba5..d92f0a5 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,5 +1,6 @@
 
 subdir('wfd')
+subdir('cc')
 
 gnome_nd_sources = [
   'main.c',
@@ -46,6 +47,7 @@ gnome_nd_deps = [
 ]
 
 gnome_nd_deps += wfd_server_deps
+gnome_nd_deps += cc_deps
 
 gnome_nd_sources += gnome.compile_resources('gnome-nd-resources',
   'gnome-network-displays.gresource.xml',
@@ -56,5 +58,5 @@ executable('gnome-network-displays',
   gnome_nd_sources,
   dependencies: gnome_nd_deps,
   install: true,
-  link_with: wfd_server,
+  link_with: [wfd_server, cc_cast_channel],
 )
diff --git a/src/nd-cc-provider.c b/src/nd-cc-provider.c
index 3e4de08..ad34118 100644
--- a/src/nd-cc-provider.c
+++ b/src/nd-cc-provider.c
@@ -315,6 +315,8 @@ nd_cc_provider_init(NdCCProvider *provider)
   //   return;
   // }
 
+  // g_debug("NdCCProvider: Started signalling server on port 8009, listening for clients");
+
   // g_signal_connect(server,
   //                  "incoming",
   //                  G_CALLBACK(signalling_incoming_cb),
diff --git a/src/nd-cc-sink.c b/src/nd-cc-sink.c
index f768ca1..e301dcd 100644
--- a/src/nd-cc-sink.c
+++ b/src/nd-cc-sink.c
@@ -21,6 +21,9 @@
 #include "cc/cc-client.h"
 #include "wfd/wfd-media-factory.h"
 #include "wfd/wfd-server.h"
+#include "cc/cast_channel.pb-c.h"
+
+#define MAX_MSG_SIZE 4096
 
 struct _NdCCSink
 {
@@ -74,28 +77,6 @@ G_DEFINE_TYPE_EXTENDED (NdCCSink, nd_cc_sink, G_TYPE_OBJECT, 0,
 
 static GParamSpec * props[PROP_LAST] = { NULL, };
 
-// TODO: this should be the protobuf msg
-// msg sent after connection
-static gchar msg_source_ready[] = {
-  0x00, 0x29, /* Length (41 bytes) */
-  0x01, /* MICE Protocol Version */
-  0x01, /* Command SOURCE_READY */
-
-  0x00, /* Friendly Name TLV */
-  0x00, 0x0A, /* Length (10 bytes) */
-  /* GNOME (UTF-16-encoded) */
-  0x47, 0x00, 0x4E, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x45, 0x00,
-
-  0x02, /* RTSP Port TLV */
-  0x00, 0x02, /* Length (2 bytes) */
-  0x1C, 0x44, /* Port 7236 */
-
-  0x03, /* Source ID TLV */
-  0x00, 0x10, /* Length (16 bits) */
-  /* Source ID GnomeMICEDisplay (ascii) */
-  0x47, 0x6E, 0x6F, 0x6D, 0x65, 0x4D, 0x49, 0x43, 0x45, 0x44, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79
-};
-
 static gchar msg_stop_projection[] = {
   0x00, 0x24, /* Length (36 bytes) */
   0x01, /* MICE Protocol Version */
@@ -291,6 +272,23 @@ play_request_cb (NdCCSink *sink, GstRTSPContext *ctx, CCClient *client)
   g_object_notify (G_OBJECT (sink), "state");
 }
 
+void
+parse_received_data(uint8_t * input_buffer, gssize input_size)
+{
+  Castchannel__CastMessage *message;
+
+  message = castchannel__cast_message__unpack(NULL, input_size-4, input_buffer+4);
+  if (message == NULL)
+  {
+    g_warning ("NdCCSink: Failed to unpack received data");
+    return;
+  }
+
+  g_debug("NdCCSink: Received data: %s", message->payload_utf8);
+
+  castchannel__cast_message__free_unpacked(message, NULL);
+}
+
 gboolean
 comm_client_send (NdCCSink      * self,
                   GSocketClient * client,
@@ -301,6 +299,9 @@ comm_client_send (NdCCSink      * self,
                   GError        * error)
 {
   GOutputStream * ostream;
+  GInputStream *  istream;
+  gssize input_size;
+  uint8_t * input_buffer = malloc(MAX_MSG_SIZE);
 
   if (self->comm_client_conn == NULL)
     self->comm_client_conn = g_socket_client_connect_to_host (client,
@@ -311,42 +312,67 @@ comm_client_send (NdCCSink      * self,
                                                               &error);
 
   if (!self->comm_client_conn || error != NULL)
-    {
-      if (error != NULL)
-        g_warning ("NdCCSink: Failed to write to communication stream: %s", error->message);
-
-      return FALSE;
-
-    }
+  {
+    if (error != NULL)
+      g_warning ("NdCCSink: Failed to write to communication stream: %s", error->message);
+    return FALSE;
+  }
 
   g_assert (G_IO_STREAM (self->comm_client_conn));
-
   g_debug ("NdCCSink: Client connection established");
 
   ostream = g_io_stream_get_output_stream (G_IO_STREAM (self->comm_client_conn));
   if (!ostream)
-    {
-      g_warning ("NdCCSink: Could not signal to sink");
-
-      return FALSE;
-    }
+  {
+    g_warning ("NdCCSink: Could not signal to sink");
+    return FALSE;
+  }
 
   size = g_output_stream_write (ostream, message, size, cancellable, &error);
   if (error != NULL)
+  {
+    if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
     {
-      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
-        {
-          g_warning ("NdCCSink: Communication client socket send would block");
-          return FALSE;
-        }
-      else
-        {
-          g_warning ("NdCCSink: Error writing to client socket output: %s", error->message);
-          return FALSE;
-        }
+      g_warning ("NdCCSink: Communication client socket send would block");
+      return FALSE;
+    }
+    else
+    {
+      g_warning ("NdCCSink: Error writing to client socket output: %s", error->message);
+      return FALSE;
     }
+  }
 
   g_debug ("NdCCSink: Sent %" G_GSSIZE_FORMAT " bytes of data", size);
+  
+  g_debug ("NdCCSink: Waiting for response from sink");
+
+  // get input stream from the connection
+  istream = g_io_stream_get_input_stream (G_IO_STREAM (self->comm_client_conn));
+  if (!istream)
+  {
+    g_warning ("NdCCSink: Could not get input stream from client connection");
+    return FALSE;
+  }
+
+  // read the response from the sink
+  input_size = g_input_stream_read (istream, input_buffer, MAX_MSG_SIZE, NULL, &error);
+  if (error != NULL)
+  {
+    g_warning ("NdCCSink: Error reading from client socket input: %s", error->message);
+    // return FALSE;
+  }
+
+  g_debug("NdCCSink: Received %" G_GSSIZE_FORMAT " bytes of data", input_size);
+  // for (int i = 0; i < input_size; i++)
+  // {
+  //   g_debug ("NdCCSink: Received byte %", input_buffer[i]);
+  // }
+
+  g_debug("NdCCSink: Received Message: %s", input_buffer);
+  parse_received_data(input_buffer, input_size);
+
+  free(input_buffer);
 
   return TRUE;
 }
@@ -423,12 +449,135 @@ server_create_audio_source_cb (NdCCSink *sink, WfdServer *server)
   return res;
 }
 
-static NdSink *
-nd_cc_sink_sink_start_stream (NdSink *sink)
+// builds message based on available types
+Castchannel__CastMessage
+build_message (
+  gchar *namespace_,
+  Castchannel__CastMessage__PayloadType payload_type,
+  ProtobufCBinaryData * binary_payload,
+  gchar *utf8_payload)
+{
+  Castchannel__CastMessage message;
+  castchannel__cast_message__init(&message);
+
+  message.protocol_version = CASTCHANNEL__CAST_MESSAGE__PROTOCOL_VERSION__CASTV2_1_0;
+  message.source_id = "gnd-0";
+  message.destination_id = "destination-0";
+  message.namespace_ = namespace_;
+  message.payload_type = payload_type;
+
+  switch (payload_type)
+  {
+  case CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__BINARY:
+    message.payload_binary = *binary_payload;
+    message.has_payload_binary = 1;
+    break;
+  case CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__STRING:
+  default:
+    message.payload_utf8 = utf8_payload;
+    message.has_payload_binary = 0;
+    break;
+  }
+
+  return message;
+}
+
+void
+send_request (NdCCSink *sink, enum MessageType message_type, char * utf8_payload)
 {
   NdCCSink *self = ND_CC_SINK (sink);
   g_autoptr(GError) error = NULL;
   gboolean send_ok;
+  Castchannel__CastMessage message;
+  // ProtobufCBinaryData binary_payload;
+  // binary_payload.data = NULL;
+  // binary_payload.len = 0;
+  guint32 packed_size = 0;
+
+  // TODO: how to do this again?
+  // g_autoptr(uint8_t) *sock_buffer = NULL;
+  uint8_t *sock_buffer = NULL;
+
+  g_debug("Send request: %d", message_type);
+
+  switch (message_type)
+  {
+  case MESSAGE_TYPE_CONNECT:
+    message = build_message(
+      "urn:x-cast:com.google.cast.tp.connection",
+      CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__STRING,
+      NULL,
+      "{ \"type\": \"CONNECT\" }");
+    break;
+
+  case MESSAGE_TYPE_DISCONNECT:
+    message = build_message(
+      "urn:x-cast:com.google.cast.tp.connection",
+      CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__STRING,
+      NULL,
+      "{ \"type\": \"CLOSE\" }");
+    break;
+
+  case MESSAGE_TYPE_PING:
+    message = build_message(
+      "urn:x-cast:com.google.cast.tp.heartbeat",
+      CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__STRING,
+      NULL,
+      "{ \"type\": \"PING\" }");
+    break;
+
+  case MESSAGE_TYPE_RECEIVER:
+    message = build_message(
+      "urn:x-cast:com.google.cast.receiver",
+      CASTCHANNEL__CAST_MESSAGE__PAYLOAD_TYPE__STRING,
+      NULL,
+      utf8_payload);
+    break;
+
+  default:
+    break;
+  }
+
+  packed_size = castchannel__cast_message__get_packed_size(&message);
+  sock_buffer = malloc(4 + packed_size);
+
+  // TODO: look for gobject way of doing this: like with g_autoptr
+
+  guint32 packed_size_be = GUINT32_TO_BE(packed_size);
+  memcpy(sock_buffer, &packed_size_be, 4);
+  castchannel__cast_message__pack(&message, 4 + sock_buffer);
+
+  g_debug("Sending message to %s:%s", self->remote_address, self->remote_name);
+  send_ok = comm_client_send (self,
+                              self->comm_client,
+                              self->remote_address,
+                              sock_buffer,
+                              packed_size+4,
+                              NULL,
+                              error);
+
+  // g_debug("Waiting for response");
+  // g_io_add_watch(self->comm_client_conn, G_IO_IN | G_IO_HUP, msg_received_cb, self);
+
+  if (!send_ok || error != NULL)
+    {
+      if (error != NULL)
+        g_warning ("NdCCSink: Failed to connect to Chromecast: %s", error->message);
+      else
+        g_warning ("NdCCSink: Failed to connect to Chromecast");
+
+      self->state = ND_SINK_STATE_ERROR;
+      g_object_notify (G_OBJECT (self), "state");
+      g_clear_object (&self->server);
+    }
+
+  free(sock_buffer);
+}
+
+static NdSink *
+nd_cc_sink_sink_start_stream (NdSink *sink)
+{
+  NdCCSink *self = ND_CC_SINK (sink);
 
   g_return_val_if_fail (self->state == ND_SINK_STATE_DISCONNECTED, NULL);
 
@@ -439,7 +588,18 @@ nd_cc_sink_sink_start_stream (NdSink *sink)
 
   g_debug ("NdCCSink: Attempting connection to Chromecast: %s", self->remote_name);
 
-  // not using server for now
+  // send connection request to client
+  send_request(self, MESSAGE_TYPE_CONNECT, NULL);
+
+  // send ping to client
+  send_request(self, MESSAGE_TYPE_PING, NULL);
+
+  // send req to get status
+  send_request(self, MESSAGE_TYPE_RECEIVER, "{\"type\": \"GET_STATUS\"}");
+
+  // send req to open youtube
+  send_request(self, MESSAGE_TYPE_RECEIVER, "{ \"type\": \"LAUNCH\", \"appId\": \"YouTube\", \"requestId\": 
1 }");
+
   self->server = wfd_server_new ();
   self->server_source_id = gst_rtsp_server_attach (GST_RTSP_SERVER (self->server), NULL);
 
@@ -449,7 +609,7 @@ nd_cc_sink_sink_start_stream (NdSink *sink)
       g_object_notify (G_OBJECT (self), "state");
       g_clear_object (&self->server);
 
-      return;
+      return NULL;
     }
 
   g_signal_connect_object (self->server,
@@ -473,24 +633,9 @@ nd_cc_sink_sink_start_stream (NdSink *sink)
   self->state = ND_SINK_STATE_WAIT_SOCKET;
   g_object_notify (G_OBJECT (self), "state");
 
-  send_ok = comm_client_send (self,
-                              self->comm_client,
-                              self->remote_address,
-                              msg_source_ready,
-                              sizeof (msg_source_ready),
-                              NULL,
-                              error);
-  if (!send_ok || error != NULL)
-    {
-      if (error != NULL)
-        g_warning ("NdCCSink: Failed to connect to Chromecast: %s", error->message);
-      else
-        g_warning ("NdCCSink: Failed to connect to Chromecast");
-
-      self->state = ND_SINK_STATE_ERROR;
-      g_object_notify (G_OBJECT (self), "state");
-      g_clear_object (&self->server);
-    }
+  // these were originally here
+  // 1. send connect request
+  // 2. send ping
 
   return g_object_ref (sink);
 }
diff --git a/src/nd-cc-sink.h b/src/nd-cc-sink.h
index 5f3a0fd..f40d911 100644
--- a/src/nd-cc-sink.h
+++ b/src/nd-cc-sink.h
@@ -33,4 +33,11 @@ NdCCSink * nd_cc_sink_new (GSocketClient *client,
 
 NdSinkState nd_cc_sink_get_state (NdCCSink *sink);
 
+enum MessageType {
+    MESSAGE_TYPE_CONNECT,
+    MESSAGE_TYPE_DISCONNECT,
+    MESSAGE_TYPE_PING,
+    MESSAGE_TYPE_RECEIVER,
+};
+
 G_END_DECLS


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