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); } }
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); } } }
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); }
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); } }