Beispiel #1
0
static void
snra_json_node_into_val (JsonNode *element_node, GValue *v)
{
  if (JSON_NODE_HOLDS_OBJECT (element_node)) {
    GstStructure *child = snra_json_to_gst_structure (element_node);
    g_value_init (v, GST_TYPE_STRUCTURE);
    gst_value_set_structure (v, child);
  } else if (JSON_NODE_HOLDS_ARRAY (element_node)) {
    JsonArray *arr = json_node_get_array (element_node);
    g_value_init (v, GST_TYPE_ARRAY);
    json_array_foreach_element (arr,
        (JsonArrayForeach) snra_json_array_add_to_val, v);
  } else {
    json_node_get_value (element_node, v);
  }
}
Beispiel #2
0
static void
handle_received_chunk (G_GNUC_UNUSED SoupMessage * msg, SoupBuffer * chunk,
    SnraClient * client)
{
  if (client->was_connected == FALSE) {
    g_print ("Successfully connected to server %s:%d\n",
        client->connected_server, client->connected_port);

    client->was_connected = TRUE;
  }
  /* Successful server connection, stop avahi discovery */
  if (client->avahi_client) {
    avahi_client_free (client->avahi_client);
    client->avahi_sb = NULL;
    client->avahi_client = NULL;
  }

  if (client->json == NULL)
    client->json = json_parser_new ();
#if 0
  {
    gchar *tmp = g_strndup (chunk->data, chunk->length);
    g_print ("%s\n", tmp);
    g_free (tmp);
  }
#endif
  if (json_parser_load_from_data (client->json, chunk->data, chunk->length,
          NULL)) {
    JsonNode *root = json_parser_get_root (client->json);
    GstStructure *s = snra_json_to_gst_structure (root);
    const char *msg_type;

    if (s == NULL)
      return;                   /* Invalid chunk */

    msg_type = gst_structure_get_string (s, "msg-type");
    if (msg_type == NULL || g_str_equal (msg_type, "ping")) {
      gst_structure_free (s);
      return;
    }

    if (g_str_equal (msg_type, "enrol"))
      handle_enrol_message (client, s);
    else if (g_str_equal (msg_type, "set-media"))
      handle_set_media_message (client, s);
    else if (g_str_equal (msg_type, "play"))
      handle_play_message (client, s);
    else if (g_str_equal (msg_type, "pause")) {
      client->paused = TRUE;
      if (client->enabled == FALSE)
        client->state = DISABLED_STATE;
      else
        client->state = GST_STATE_PAUSED;
      if (client->player)
        gst_element_set_state (GST_ELEMENT (client->player), client->state);
    } else if (g_str_equal (msg_type, "volume")) {
      handle_set_volume_message (client, s);
    } else if (g_str_equal (msg_type, "client-setting")) {
      handle_set_client_message (client, s);
    } else {
      g_print ("Unhandled event of type %s\n", msg_type);
    }
  }
}
Beispiel #3
0
static void
handle_received_chunk (SoupMessage * msg, SoupBuffer * chunk,
    SnraClient * client)
{
  const gchar *ptr;
  gsize length;
  SnraClientFlags flag = get_flag_from_msg (msg);

  if (client->was_connected & flag) {
    g_print ("Successfully connected %s to server %s:%d\n",
        flag == SNRA_CLIENT_PLAYER ? "player" : "controller",
        client->connected_server, client->connected_port);
    client->was_connected |= flag;
  }

  /* Successful server connection, stop avahi discovery */
  if (client->avahi_client) {
    avahi_client_free (client->avahi_client);
    client->avahi_sb = NULL;
    client->avahi_client = NULL;
  }

  if (client->json == NULL)
    client->json = json_parser_new ();
#if 0
  {
    gchar *tmp = g_strndup (chunk->data, chunk->length);
    g_print ("%s\n", tmp);
    g_free (tmp);
  }
#endif

  ptr = memchr (chunk->data, '\0', chunk->length);
  if (!ptr)
    return;

  /* Save remaining portion */
  ptr += 1;
  length =(chunk->length - (ptr - chunk->data));

  chunk = soup_message_body_flatten (msg->response_body);
  if (json_parser_load_from_data (client->json, chunk->data, chunk->length,
          NULL)) {
    JsonNode *root = json_parser_get_root (client->json);
    GstStructure *s = snra_json_to_gst_structure (root);

    if (s == NULL)
      goto end;                   /* Invalid chunk */

    if (flag == SNRA_CLIENT_PLAYER)
      handle_player_message (client, s);
    else
      handle_controller_message (client, s);

    gst_structure_free (s);
  }

end:
  soup_message_body_truncate (msg->response_body);
  /* Put back remaining part */
  if (length)
    soup_message_body_append (msg->response_body, SOUP_MEMORY_COPY, ptr, length);
}
Beispiel #4
0
static void
handle_player_info (G_GNUC_UNUSED SoupSession *session, SoupMessage *msg,
    SnraClient *client)
{
  SoupBuffer *buffer;

  if (msg->status_code < 200 || msg->status_code >= 300)
    return;

  buffer = soup_message_body_flatten (msg->response_body);
  if (json_parser_load_from_data (client->json, buffer->data, buffer->length,
          NULL)) {
    const GValue *v1;
    GArray *player_info = NULL;
    gsize i;
    JsonNode *root = json_parser_get_root (client->json);
    GstStructure *s1 = snra_json_to_gst_structure (root);

    if (s1 == NULL)
      return;                   /* Invalid chunk */

    v1 = gst_structure_get_value (s1, "player-clients");
    if (!GST_VALUE_HOLDS_ARRAY (v1))
      goto failed;

    player_info = g_array_sized_new (TRUE, TRUE,
          sizeof (SnraPlayerInfo), gst_value_array_get_size (v1));

    for (i = 0; i < gst_value_array_get_size (v1); i++) {
      SnraPlayerInfo info;
      const GValue *v2 = gst_value_array_get_value (v1, i);
      const GstStructure *s2;
      gint64 client_id;

      if (!GST_VALUE_HOLDS_STRUCTURE (v2))
        goto failed;

      s2 = gst_value_get_structure (v2);
      if (!snra_json_structure_get_int64 (s2, "client-id", &client_id))
        goto failed;
      info.id = client_id;

      if (!snra_json_structure_get_boolean (s2, "enabled", &info.enabled))
        goto failed;

      if (!snra_json_structure_get_double (s2, "volume", &info.volume))
        goto failed;

      if (!(info.host = g_strdup (gst_structure_get_string (s2, "host"))))
        goto failed;

      g_array_append_val (player_info, info);
    }

    free_player_info (client->player_info);
    client->player_info = player_info;
    player_info = NULL;

    g_signal_emit (client, signals[SIGNAL_PLAYER_INFO_CHANGED], 0);

failed:
    if (player_info)
      free_player_info (player_info);
    gst_structure_free (s1);
  }
}