4 * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU Lesser General Public License,
8 * version 2.1, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 * Mark Ryan <mark.d.ryan@intel.com>
31 #include <sys/signalfd.h>
33 #include <libdleyna/core/connector.h>
34 #include <libdleyna/core/control-point.h>
35 #include <libdleyna/core/error.h>
36 #include <libdleyna/core/log.h>
37 #include <libdleyna/core/task-processor.h>
40 #include "control-point-renderer.h"
42 #include "prop-defs.h"
47 #define DLR_PRG_NAME UA_PREFIX " dLeyna/" VERSION
49 #define DLR_PRG_NAME "dLeyna/" VERSION
52 #define DLR_INTERFACE_GET_VERSION "GetVersion"
53 #define DLR_INTERFACE_GET_SERVERS "GetServers"
54 #define DLR_INTERFACE_RELEASE "Release"
56 #define DLR_INTERFACE_FOUND_SERVER "FoundServer"
57 #define DLR_INTERFACE_LOST_SERVER "LostServer"
59 #define DLR_INTERFACE_HOST_FILE "HostFile"
60 #define DLR_INTERFACE_REMOVE_FILE "RemoveFile"
62 #define DLR_INTERFACE_VERSION "Version"
63 #define DLR_INTERFACE_SERVERS "Servers"
65 #define DLR_INTERFACE_PATH "Path"
66 #define DLR_INTERFACE_URI "Uri"
67 #define DLR_INTERFACE_ID "Id"
69 #define DLR_INTERFACE_CHANGED_PROPERTIES "changed_properties"
70 #define DLR_INTERFACE_INVALIDATED_PROPERTIES "invalidated_properties"
71 #define DLR_INTERFACE_GET "Get"
72 #define DLR_INTERFACE_GET_ALL "GetAll"
73 #define DLR_INTERFACE_SET "Set"
74 #define DLR_INTERFACE_INTERFACE_NAME "interface_name"
75 #define DLR_INTERFACE_PROPERTY_NAME "property_name"
76 #define DLR_INTERFACE_PROPERTIES_VALUE "properties"
77 #define DLR_INTERFACE_VALUE "value"
78 #define DLR_INTERFACE_OFFSET "offset"
79 #define DLR_INTERFACE_POSITION "position"
80 #define DLR_INTERFACE_TRACKID "trackid"
81 #define DLR_INTERFACE_TRACK_NUMBER "TrackNumber"
83 #define DLR_INTERFACE_RAISE "Raise"
84 #define DLR_INTERFACE_QUIT "Quit"
85 #define DLR_INTERFACE_PLAY "Play"
86 #define DLR_INTERFACE_PLAY_PAUSE "PlayPause"
87 #define DLR_INTERFACE_NEXT "Next"
88 #define DLR_INTERFACE_PREVIOUS "Previous"
89 #define DLR_INTERFACE_PAUSE "Pause"
90 #define DLR_INTERFACE_STOP "Stop"
91 #define DLR_INTERFACE_OPEN_URI "OpenUri"
92 #define DLR_INTERFACE_SEEK "Seek"
93 #define DLR_INTERFACE_SET_POSITION "SetPosition"
94 #define DLR_INTERFACE_GOTO_TRACK "GotoTrack"
96 #define DLR_INTERFACE_CANCEL "Cancel"
98 typedef struct dlr_context_t_ dlr_context_t;
99 struct dlr_context_t_ {
101 dleyna_connector_id_t connection;
103 dleyna_task_processor_t *processor;
104 const dleyna_connector_t *connector;
106 dleyna_settings_t *settings;
109 static dlr_context_t g_context;
111 static const gchar g_root_introspection[] =
113 " <interface name='"DLEYNA_SERVER_INTERFACE_MANAGER"'>"
114 " <method name='"DLR_INTERFACE_GET_VERSION"'>"
115 " <arg type='s' name='"DLR_INTERFACE_VERSION"'"
118 " <method name='"DLR_INTERFACE_RELEASE"'>"
120 " <method name='"DLR_INTERFACE_GET_SERVERS"'>"
121 " <arg type='as' name='"DLR_INTERFACE_SERVERS"'"
124 " <signal name='"DLR_INTERFACE_FOUND_SERVER"'>"
125 " <arg type='s' name='"DLR_INTERFACE_PATH"'/>"
127 " <signal name='"DLR_INTERFACE_LOST_SERVER"'>"
128 " <arg type='s' name='"DLR_INTERFACE_PATH"'/>"
133 static const gchar g_server_introspection[] =
135 " <interface name='"DLR_INTERFACE_PROPERTIES"'>"
136 " <method name='"DLR_INTERFACE_GET"'>"
137 " <arg type='s' name='"DLR_INTERFACE_INTERFACE_NAME"'"
139 " <arg type='s' name='"DLR_INTERFACE_PROPERTY_NAME"'"
141 " <arg type='v' name='"DLR_INTERFACE_VALUE"'"
144 " <method name='"DLR_INTERFACE_GET_ALL"'>"
145 " <arg type='s' name='"DLR_INTERFACE_INTERFACE_NAME"'"
147 " <arg type='a{sv}' name='"DLR_INTERFACE_PROPERTIES_VALUE"'"
150 " <method name='"DLR_INTERFACE_SET"'>"
151 " <arg type='s' name='"DLR_INTERFACE_INTERFACE_NAME"'"
153 " <arg type='s' name='"DLR_INTERFACE_PROPERTY_NAME"'"
155 " <arg type='v' name='"DLR_INTERFACE_VALUE"'"
158 " <signal name='"DLR_INTERFACE_PROPERTIES_CHANGED"'>"
159 " <arg type='s' name='"DLR_INTERFACE_INTERFACE_NAME"'/>"
160 " <arg type='a{sv}' name='"DLR_INTERFACE_CHANGED_PROPERTIES"'/>"
161 " <arg type='as' name='"DLR_INTERFACE_INVALIDATED_PROPERTIES"'/>"
164 " <interface name='"DLR_INTERFACE_SERVER"'>"
165 " <method name='"DLR_INTERFACE_RAISE"'>"
167 " <method name='"DLR_INTERFACE_QUIT"'>"
169 " <property type='b' name='"DLR_INTERFACE_PROP_CAN_QUIT"'"
171 " <property type='b' name='"DLR_INTERFACE_PROP_CAN_RAISE"'"
173 " <property type='b' name='"DLR_INTERFACE_PROP_CAN_SET_FULLSCREEN"'"
175 " <property type='b' name='"DLR_INTERFACE_PROP_HAS_TRACK_LIST"'"
177 " <property type='s' name='"DLR_INTERFACE_PROP_IDENTITY"'"
179 " <property type='as' name='"DLR_INTERFACE_PROP_SUPPORTED_URIS"'"
181 " <property type='as' name='"DLR_INTERFACE_PROP_SUPPORTED_MIME"'"
184 " <interface name='"DLR_INTERFACE_PLAYER"'>"
185 " <method name='"DLR_INTERFACE_PLAY"'>"
187 " <method name='"DLR_INTERFACE_PAUSE"'>"
189 " <method name='"DLR_INTERFACE_PLAY_PAUSE"'>"
191 " <method name='"DLR_INTERFACE_STOP"'>"
193 " <method name='"DLR_INTERFACE_NEXT"'>"
195 " <method name='"DLR_INTERFACE_PREVIOUS"'>"
197 " <method name='"DLR_INTERFACE_OPEN_URI"'>"
198 " <arg type='s' name='"DLR_INTERFACE_URI"'"
201 " <method name='"DLR_INTERFACE_SEEK"'>"
202 " <arg type='x' name='"DLR_INTERFACE_OFFSET"'"
205 " <method name='"DLR_INTERFACE_SET_POSITION"'>"
206 " <arg type='o' name='"DLR_INTERFACE_TRACKID"'"
208 " <arg type='x' name='"DLR_INTERFACE_POSITION"'"
211 " <method name='"DLR_INTERFACE_GOTO_TRACK"'>"
212 " <arg type='u' name='"DLR_INTERFACE_TRACK_NUMBER"'"
215 " <property type='s' name='"DLR_INTERFACE_PROP_PLAYBACK_STATUS"'"
217 " <property type='d' name='"DLR_INTERFACE_PROP_RATE"'"
218 " access='readwrite'/>"
219 " <property type='d' name='"DLR_INTERFACE_PROP_MINIMUM_RATE"'"
221 " <property type='d' name='"DLR_INTERFACE_PROP_MAXIMUM_RATE"'"
223 " <property type='ad'"
224 " name='"DLR_INTERFACE_PROP_TRANSPORT_PLAY_SPEEDS"'"
226 " <property type='d' name='"DLR_INTERFACE_PROP_VOLUME"'"
227 " access='readwrite'/>"
228 " <property type='b' name='"DLR_INTERFACE_PROP_CAN_PLAY"'"
230 " <property type='b' name='"DLR_INTERFACE_PROP_CAN_SEEK"'"
232 " <property type='b' name='"DLR_INTERFACE_PROP_CAN_CONTROL"'"
234 " <property type='b' name='"DLR_INTERFACE_PROP_CAN_PAUSE"'"
236 " <property type='b' name='"DLR_INTERFACE_PROP_CAN_NEXT"'"
238 " <property type='b' name='"DLR_INTERFACE_PROP_CAN_PREVIOUS"'"
240 " <property type='x' name='"DLR_INTERFACE_PROP_POSITION"'"
242 " <property type='a{sv}' name='"DLR_INTERFACE_PROP_METADATA"'"
244 " <property type='u' name='"DLR_INTERFACE_PROP_CURRENT_TRACK"'"
246 " <property type='u' name='"DLR_INTERFACE_PROP_NUMBER_OF_TRACKS"'"
249 " <interface name='"DLEYNA_INTERFACE_PUSH_HOST"'>"
250 " <method name='"DLR_INTERFACE_HOST_FILE"'>"
251 " <arg type='s' name='"DLR_INTERFACE_PATH"'"
253 " <arg type='s' name='"DLR_INTERFACE_URI"'"
256 " <method name='"DLR_INTERFACE_REMOVE_FILE"'>"
257 " <arg type='s' name='"DLR_INTERFACE_PATH"'"
261 " <interface name='"DLEYNA_SERVER_INTERFACE_RENDERER_DEVICE"'>"
262 " <method name='"DLR_INTERFACE_CANCEL"'>"
264 " <property type='s' name='"DLR_INTERFACE_PROP_DEVICE_TYPE"'"
266 " <property type='s' name='"DLR_INTERFACE_PROP_UDN"'"
268 " <property type='s' name='"DLR_INTERFACE_PROP_FRIENDLY_NAME"'"
270 " <property type='s' name='"DLR_INTERFACE_PROP_ICON_URL"'"
272 " <property type='s' name='"DLR_INTERFACE_PROP_MANUFACTURER"'"
274 " <property type='s' name='"DLR_INTERFACE_PROP_MANUFACTURER_URL"'"
276 " <property type='s' name='"DLR_INTERFACE_PROP_MODEL_DESCRIPTION"'"
278 " <property type='s' name='"DLR_INTERFACE_PROP_MODEL_NAME"'"
280 " <property type='s' name='"DLR_INTERFACE_PROP_MODEL_NUMBER"'"
282 " <property type='s' name='"DLR_INTERFACE_PROP_SERIAL_NUMBER"'"
284 " <property type='s' name='"DLR_INTERFACE_PROP_PRESENTATION_URL"'"
286 " <property type='s' name='"DLR_INTERFACE_PROP_PROTOCOL_INFO"'"
291 static void prv_process_task(dleyna_task_atom_t *task, gpointer user_data);
293 static void prv_dlr_method_call(dleyna_connector_id_t conn,
296 const gchar *interface,
298 GVariant *parameters,
299 dleyna_connector_msg_id_t invocation);
301 static void prv_dlr_device_method_call(dleyna_connector_id_t conn,
304 const gchar *interface,
306 GVariant *parameters,
307 dleyna_connector_msg_id_t invocation);
309 static void prv_props_method_call(dleyna_connector_id_t conn,
312 const gchar *interface,
314 GVariant *parameters,
315 dleyna_connector_msg_id_t invocation);
317 static void prv_dlr_player_method_call(dleyna_connector_id_t conn,
320 const gchar *interface,
322 GVariant *parameters,
323 dleyna_connector_msg_id_t invocation);
325 static void prv_dlr_push_host_method_call(dleyna_connector_id_t conn,
328 const gchar *interface,
330 GVariant *parameters,
331 dleyna_connector_msg_id_t invocation);
333 static void prv_renderer_device_method_call(
334 dleyna_connector_id_t conn,
337 const gchar *interface,
339 GVariant *parameters,
340 dleyna_connector_msg_id_t invocation);
342 static const dleyna_connector_dispatch_cb_t g_root_vtables[1] = {
346 static const dleyna_connector_dispatch_cb_t
347 g_server_vtables[DLR_INTERFACE_INFO_MAX] = {
348 /* MUST be in the exact same order as g_msu_server_introspection */
349 prv_props_method_call,
350 prv_dlr_device_method_call,
351 prv_dlr_player_method_call,
352 prv_dlr_push_host_method_call,
353 prv_renderer_device_method_call
356 const dleyna_connector_t *dlr_renderer_get_connector(void)
358 return g_context.connector;
361 dleyna_task_processor_t *dlr_renderer_service_get_task_processor(void)
363 return g_context.processor;
366 dlr_upnp_t *dlr_renderer_service_get_upnp(void)
368 return g_context.upnp;
371 static void prv_process_sync_task(dlr_task_t *task)
375 switch (task->type) {
376 case DLR_TASK_GET_VERSION:
377 dlr_task_complete(task);
378 dleyna_task_queue_task_completed(task->atom.queue_id);
380 case DLR_TASK_GET_SERVERS:
381 task->result = dlr_upnp_get_server_ids(g_context.upnp);
382 dlr_task_complete(task);
383 dleyna_task_queue_task_completed(task->atom.queue_id);
387 error = g_error_new(DLEYNA_SERVER_ERROR,
388 DLEYNA_ERROR_NOT_SUPPORTED,
389 "Command not supported.");
390 dlr_task_fail(task, error);
391 dleyna_task_queue_task_completed(task->atom.queue_id);
399 static void prv_async_task_complete(dlr_task_t *task, GError *error)
401 DLEYNA_LOG_DEBUG("Enter");
404 dlr_task_fail(task, error);
407 dlr_task_complete(task);
410 dleyna_task_queue_task_completed(task->atom.queue_id);
412 DLEYNA_LOG_DEBUG("Exit");
415 static void prv_process_async_task(dlr_task_t *task)
417 dlr_async_task_t *async_task = (dlr_async_task_t *)task;
419 DLEYNA_LOG_DEBUG("Enter");
421 async_task->cancellable = g_cancellable_new();
423 switch (task->type) {
424 case DLR_TASK_GET_PROP:
425 dlr_upnp_get_prop(g_context.upnp, task,
426 prv_async_task_complete);
428 case DLR_TASK_GET_ALL_PROPS:
429 dlr_upnp_get_all_props(g_context.upnp, task,
430 prv_async_task_complete);
432 case DLR_TASK_SET_PROP:
433 dlr_upnp_set_prop(g_context.upnp, task,
434 prv_async_task_complete);
437 dlr_upnp_play(g_context.upnp, task,
438 prv_async_task_complete);
441 dlr_upnp_pause(g_context.upnp, task,
442 prv_async_task_complete);
444 case DLR_TASK_PLAY_PAUSE:
445 dlr_upnp_play_pause(g_context.upnp, task,
446 prv_async_task_complete);
449 dlr_upnp_stop(g_context.upnp, task,
450 prv_async_task_complete);
453 dlr_upnp_next(g_context.upnp, task,
454 prv_async_task_complete);
456 case DLR_TASK_PREVIOUS:
457 dlr_upnp_previous(g_context.upnp, task,
458 prv_async_task_complete);
460 case DLR_TASK_OPEN_URI:
461 dlr_upnp_open_uri(g_context.upnp, task,
462 prv_async_task_complete);
465 dlr_upnp_seek(g_context.upnp, task,
466 prv_async_task_complete);
468 case DLR_TASK_SET_POSITION:
469 dlr_upnp_set_position(g_context.upnp, task,
470 prv_async_task_complete);
472 case DLR_TASK_GOTO_TRACK:
473 dlr_upnp_goto_track(g_context.upnp, task,
474 prv_async_task_complete);
476 case DLR_TASK_HOST_URI:
477 dlr_upnp_host_uri(g_context.upnp, task,
478 prv_async_task_complete);
480 case DLR_TASK_REMOVE_URI:
481 dlr_upnp_remove_uri(g_context.upnp, task,
482 prv_async_task_complete);
488 DLEYNA_LOG_DEBUG("Exit");
491 static void prv_process_task(dleyna_task_atom_t *task, gpointer user_data)
493 dlr_task_t *client_task = (dlr_task_t *)task;
495 if (client_task->synchronous)
496 prv_process_sync_task(client_task);
498 prv_process_async_task(client_task);
501 static void prv_cancel_task(dleyna_task_atom_t *task, gpointer user_data)
503 dlr_task_cancel((dlr_task_t *)task);
506 static void prv_delete_task(dleyna_task_atom_t *task, gpointer user_data)
508 dlr_task_delete((dlr_task_t *)task);
511 static void prv_remove_client(const gchar *name)
513 dleyna_task_processor_remove_queues_for_source(g_context.processor,
516 dlr_upnp_lost_client(g_context.upnp, name);
518 g_context.watchers--;
519 if (g_context.watchers == 0)
520 if (!dleyna_settings_is_never_quit(g_context.settings))
521 dleyna_task_processor_set_quitting(g_context.processor);
524 static void prv_lost_client(const gchar *name)
526 DLEYNA_LOG_INFO("Client %s lost", name);
527 prv_remove_client(name);
530 static void prv_control_point_initialize(const dleyna_connector_t *connector,
531 dleyna_task_processor_t *processor,
532 dleyna_settings_t *settings)
534 memset(&g_context, 0, sizeof(g_context));
536 g_context.processor = processor;
537 g_context.settings = settings;
538 g_context.connector = connector;
539 g_context.connector->set_client_lost_cb(prv_lost_client);
541 g_set_prgname(DLR_PRG_NAME);
544 static void prv_control_point_stop_service(void)
546 dlr_upnp_unsubscribe(g_context.upnp);
549 dlr_upnp_delete(g_context.upnp);
551 if (g_context.connection) {
552 if (g_context.dlr_id)
553 g_context.connector->unpublish_object(
554 g_context.connection,
559 static void prv_control_point_free(void)
563 static void prv_add_task(dlr_task_t *task, const gchar *source,
566 const dleyna_task_queue_key_t *queue_id;
568 if (g_context.connector->watch_client(source))
569 g_context.watchers++;
571 queue_id = dleyna_task_processor_lookup_queue(g_context.processor,
574 queue_id = dleyna_task_processor_add_queue(
578 DLEYNA_TASK_QUEUE_FLAG_AUTO_START,
583 dleyna_task_queue_add_task(queue_id, &task->atom);
586 static void prv_dlr_method_call(dleyna_connector_id_t conn,
587 const gchar *sender, const gchar *object,
588 const gchar *interface,
589 const gchar *method, GVariant *parameters,
590 dleyna_connector_msg_id_t invocation)
594 DLEYNA_LOG_INFO("Calling %s method", method);
596 if (!strcmp(method, DLR_INTERFACE_RELEASE)) {
597 g_context.connector->unwatch_client(sender);
598 prv_remove_client(sender);
599 g_context.connector->return_response(invocation, NULL);
601 if (!strcmp(method, DLR_INTERFACE_GET_VERSION))
602 task = dlr_task_get_version_new(invocation);
603 else if (!strcmp(method, DLR_INTERFACE_GET_SERVERS))
604 task = dlr_task_get_servers_new(invocation);
608 prv_add_task(task, sender, DLR_RENDERER_SINK);
616 static const gchar *prv_get_device_id(const gchar *object, GError **error)
618 dlr_device_t *device;
620 device = dlr_device_from_path(object,
621 dlr_upnp_get_server_udn_map(g_context.upnp));
625 DLEYNA_LOG_WARNING("Cannot locate device for %s", object);
627 *error = g_error_new(DLEYNA_SERVER_ERROR,
628 DLEYNA_ERROR_OBJECT_NOT_FOUND,
629 "Cannot locate device corresponding to the specified path");
640 static void prv_props_method_call(dleyna_connector_id_t conn,
643 const gchar *interface,
645 GVariant *parameters,
646 dleyna_connector_msg_id_t invocation)
649 const gchar *device_id;
650 GError *error = NULL;
652 device_id = prv_get_device_id(object, &error);
654 g_context.connector->return_error(invocation, error);
660 if (!strcmp(method, DLR_INTERFACE_GET_ALL))
661 task = dlr_task_get_props_new(invocation, object, parameters);
662 else if (!strcmp(method, DLR_INTERFACE_GET))
663 task = dlr_task_get_prop_new(invocation, object, parameters);
664 else if (!strcmp(method, DLR_INTERFACE_SET))
665 task = dlr_task_set_prop_new(invocation, object, parameters);
669 prv_add_task(task, sender, device_id);
676 static void prv_dlr_device_method_call(dleyna_connector_id_t conn,
679 const gchar *interface,
681 GVariant *parameters,
682 dleyna_connector_msg_id_t invocation)
685 const gchar *device_id;
686 GError *error = NULL;
688 device_id = prv_get_device_id(object, &error);
690 g_context.connector->return_error(invocation, error);
696 if (!strcmp(method, DLR_INTERFACE_RAISE))
697 task = dlr_task_raise_new(invocation);
698 else if (!strcmp(method, DLR_INTERFACE_QUIT))
699 task = dlr_task_quit_new(invocation);
703 prv_add_task(task, sender, device_id);
710 static void prv_dlr_player_method_call(dleyna_connector_id_t conn,
713 const gchar *interface,
715 GVariant *parameters,
716 dleyna_connector_msg_id_t invocation)
719 const gchar *device_id;
720 GError *error = NULL;
722 device_id = prv_get_device_id(object, &error);
724 g_context.connector->return_error(invocation, error);
730 if (!strcmp(method, DLR_INTERFACE_PLAY))
731 task = dlr_task_play_new(invocation, object);
732 else if (!strcmp(method, DLR_INTERFACE_PAUSE))
733 task = dlr_task_pause_new(invocation, object);
734 else if (!strcmp(method, DLR_INTERFACE_PLAY_PAUSE))
735 task = dlr_task_play_pause_new(invocation, object);
736 else if (!strcmp(method, DLR_INTERFACE_STOP))
737 task = dlr_task_stop_new(invocation, object);
738 else if (!strcmp(method, DLR_INTERFACE_NEXT))
739 task = dlr_task_next_new(invocation, object);
740 else if (!strcmp(method, DLR_INTERFACE_PREVIOUS))
741 task = dlr_task_previous_new(invocation, object);
742 else if (!strcmp(method, DLR_INTERFACE_OPEN_URI))
743 task = dlr_task_open_uri_new(invocation, object, parameters);
744 else if (!strcmp(method, DLR_INTERFACE_SEEK))
745 task = dlr_task_seek_new(invocation, object, parameters);
746 else if (!strcmp(method, DLR_INTERFACE_SET_POSITION))
747 task = dlr_task_set_position_new(invocation, object,
749 else if (!strcmp(method, DLR_INTERFACE_GOTO_TRACK))
750 task = dlr_task_goto_track_new(invocation, object, parameters);
754 prv_add_task(task, sender, device_id);
761 static void prv_dlr_push_host_method_call(dleyna_connector_id_t conn,
764 const gchar *interface,
766 GVariant *parameters,
767 dleyna_connector_msg_id_t invocation)
770 const gchar *device_id;
771 GError *error = NULL;
773 device_id = prv_get_device_id(object, &error);
775 g_context.connector->return_error(invocation, error);
781 if (!strcmp(method, DLR_INTERFACE_HOST_FILE))
782 task = dlr_task_host_uri_new(invocation, object, sender,
784 else if (!strcmp(method, DLR_INTERFACE_REMOVE_FILE))
785 task = dlr_task_remove_uri_new(invocation, object, sender,
790 prv_add_task(task, sender, device_id);
797 static void prv_renderer_device_method_call(
798 dleyna_connector_id_t conn,
801 const gchar *interface,
803 GVariant *parameters,
804 dleyna_connector_msg_id_t invocation)
806 const gchar *device_id = NULL;
807 GError *error = NULL;
808 const dleyna_task_queue_key_t *queue_id;
810 device_id = prv_get_device_id(object, &error);
812 g_context.connector->return_error(invocation, error);
818 if (!strcmp(method, DLR_INTERFACE_CANCEL)) {
819 queue_id = dleyna_task_processor_lookup_queue(
823 dleyna_task_processor_cancel_queue(queue_id);
825 g_context.connector->return_response(invocation, NULL);
833 static void prv_found_media_server(const gchar *path)
835 DLEYNA_LOG_INFO("New media server %s", path);
837 (void) g_context.connector->notify(g_context.connection,
838 DLEYNA_SERVER_OBJECT,
839 DLEYNA_SERVER_INTERFACE_MANAGER,
840 DLR_INTERFACE_FOUND_SERVER,
841 g_variant_new("(s)", path),
845 static void prv_lost_media_server(const gchar *path)
847 DLEYNA_LOG_INFO("Lost %s", path);
849 (void) g_context.connector->notify(g_context.connection,
850 DLEYNA_SERVER_OBJECT,
851 DLEYNA_SERVER_INTERFACE_MANAGER,
852 DLR_INTERFACE_LOST_SERVER,
853 g_variant_new("(s)", path),
856 dleyna_task_processor_remove_queues_for_sink(g_context.processor, path);
859 static gboolean prv_control_point_start_service(
860 dleyna_connector_id_t connection)
862 gboolean retval = TRUE;
864 g_context.connection = connection;
866 g_context.dlr_id = g_context.connector->publish_object(
868 DLEYNA_SERVER_OBJECT,
873 if (!g_context.dlr_id) {
877 g_context.upnp = dlr_upnp_new(connection,
879 prv_found_media_server,
880 prv_lost_media_server);
888 static const gchar *prv_control_point_server_name(void)
890 return DLEYNA_SERVER_NAME;
893 static const gchar *prv_control_point_server_introspection(void)
895 return g_server_introspection;
898 static const gchar *prv_control_point_root_introspection(void)
900 return g_root_introspection;
903 static const dleyna_control_point_t g_control_point = {
904 prv_control_point_initialize,
905 prv_control_point_free,
906 prv_control_point_server_name,
907 prv_control_point_server_introspection,
908 prv_control_point_root_introspection,
909 prv_control_point_start_service,
910 prv_control_point_stop_service
913 const dleyna_control_point_t *dleyna_control_point_get_renderer(void)
915 return &g_control_point;