The name is not activable on g_dbus_proxy_call_sync - c

On a GNOME Xorg session, to get the return value of method GetIdletime exposed on DBus, you can either use
$ dbus-send --print-reply --dest=org.gnome.Mutter.IdleMonitor /org/gnome/Mutter/IdleMonitor/Core org.gnome.Mutter.IdleMonitor.GetIdletime
or
$ gdbus call --session --dest org.gnome.Mutter.IdleMonitor --object-path /org/gnome/Mutter/IdleMonitor/Core --method org.gnome.Mutter.IdleMonitor.GetIdletime
I need to retrieve this value by using GDBus API, so I wrote the following code
/*
* Compile with:
* gcc -Wall print_user_idle_time-gnome.c -o print_user_idle_time-gnome `pkg-config --libs gio-2.0 --cflags`
*/
#include <gio/gio.h>
static void
print_user_idle_time (GDBusProxy *proxy)
{
guint64 user_idle_time;
gchar *method = "GetIdletime";
GError *error = NULL;
GVariant *ret = NULL;
ret = g_dbus_proxy_call_sync(proxy,
method,
NULL,
G_DBUS_CALL_FLAGS_NONE, -1,
NULL, &error);
if (!ret) {
g_dbus_error_strip_remote_error (error);
g_print ("GetIdletime failed: %s\n", error->message);
g_error_free (error);
return;
}
user_idle_time = g_variant_get_uint64 (ret);
g_print("%lu\n", user_idle_time);
g_variant_unref (ret);
}
int
main (int argc, char *argv[])
{
GDBusProxy *proxy = NULL;
gchar *name = "org.gnome.Mutter.IdleMonitor";
gchar *object_path = "/org/gnome/Mutter/IdleMonitor/Core";
gchar *interface_name = "org.gnome.Mutter.IdleMonitor";
/* Create a D-Bus proxy */
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
name,
object_path,
interface_name,
NULL, NULL);
g_assert (proxy != NULL);
print_user_idle_time (proxy);
g_object_unref (proxy);
return 0;
}
But when I run it I get error GetIdletime failed: The name is not activable. What is wrong? Thank you

org.gnome.Mutter.IdleMonitor is on the session bus, not the system bus; so you need to use G_BUS_TYPE_SESSION.

Related

c++ gdbus - how to fetch the property of interface using gdbus library?

I would like to know the approach/code snippet to fetch the property from a dbus interface using c++ code snippet.
I have tried the following approaches with error.
Approach#1 using g_dbus_proxy_get_cached_property but it is always returning null
ifproxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
flags,
NULL,
"org.freedesktop.NetworkManager",
"org/freedesktop/NetworkManager/Device/0",
"org.freedesktop.NetworkManager.Device",
NULL,
&error);
ret = g_dbus_proxy_get_cached_property(ifproxy, "State")
Approach#2 g_dbus_proxy_call_sync - this one says "org.freedesktop.networkmanager" isn't exported (or may not exist), can't access property "Interface"
ifproxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
"org.freedesktop.NetworkManager",
"org/freedesktop/NetworkManager/Device/0",
"org.freedesktop.DBus.Properties",
NULL, NULL);
g_assert (ifproxy);
/* Get the object path of the Connection details */
ret = g_dbus_proxy_call_sync (ifproxy,
"Get",
g_variant_new ("(ss)",
"org/freedesktop/NetworkManager/Device/0",
"Interface"),
G_DBUS_CALL_FLAGS_NONE, -1,
NULL, &error);
if (!ret) {
g_dbus_error_strip_remote_error (error);
g_warning ("Failed to get property: %s\n",
error->message);
g_error_free (error);
return;
}
name = g_variant_get_string(ret, NULL);
//g_assert(ret != NULL);
g_variant_get (ret, "s", &name);
g_variant_unref (ret);
At least the first form should work (assuming you handle errors in your real code) but there are issues with your D-Bus object paths.
First, valid object paths start with a '/' so you probably wanted /org/freedesktop/NetworkManager/Device/0... except that doesn't seem to be a path NetworkManager uses.
Looking at their API reference, it seems you may really want /org/freedesktop/NetworkManager/Devices/N (note the plural "Devices") but note that you can't really be sure what the last part of the path (N) is going to be. In proper code you should get the devices object path from org.freedesktop.NetworkManager but for debugging you might just use a tool like d-feet to find which objects paths are available and use those.
Thanks a lot #jku.
I was able to solve the issue of encoding.
Sharing the working code below for others.
static void
list_connections (GDBusProxy *proxy)
{
int i;
GError *error = NULL;
GVariant *ret, *ret1;
char **paths;
gchar *name;
GDBusProxy *ifproxy;
GDBusProxyFlags flags;
/* Call ListConnections D-Bus method */
ret = g_dbus_proxy_call_sync (proxy,
"GetDevices",
NULL,
G_DBUS_CALL_FLAGS_NONE, -1,
NULL, &error);
if (!ret) {
g_dbus_error_strip_remote_error (error);
g_print ("ListConnections failed: %s\n", error->message);
g_error_free (error);
return;
}
g_variant_get (ret, "(^ao)", &paths);
g_variant_unref (ret);
flags = static_cast<GDBusProxyFlags> (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START);
for (i = 0; paths[i]; i++)
{
g_print ("%s\n", paths[i]);
/*ifproxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
flags,
NULL,
"org.freedesktop.NetworkManager",
paths[i],//"/org/freedesktop/NetworkManager/Devices/0"
"org.freedesktop.NetworkManager.Device",
NULL,
&error);
//name = g_dbus_proxy_get_interface_name(ifproxy);
ret = g_dbus_proxy_get_cached_property(ifproxy, "FirmwareVersion");*/
ifproxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
"org.freedesktop.NetworkManager",
"/org/freedesktop/NetworkManager/Devices/0",
"org.freedesktop.DBus.Properties",
NULL, NULL);
g_assert (ifproxy);
ret = g_dbus_proxy_call_sync (ifproxy,
"Get",
g_variant_new ("(ss)",
"org.freedesktop.NetworkManager.Device",
"Interface"),
G_DBUS_CALL_FLAGS_NONE, -1,
NULL, &error);
if (!ret) {
g_dbus_error_strip_remote_error (error);
g_warning ("Failed to get property: %s\n",
error->message);
g_error_free (error);
return;
}
g_print("\nType String of Variant:- %s\n", g_variant_get_type_string (ret));
g_variant_get (ret, "(v)", &ret1);
g_variant_unref (ret);
g_print("\nType String of Variant:- %s\n", g_variant_get_type_string (ret1));
g_variant_get (ret1, "s", &name);
g_variant_unref (ret1);
g_print ("Interface name:- %s\n", name);
}
g_strfreev (paths);
}
int
main (int argc, char *argv[])
{
GDBusProxy *proxy;
GDBusProxyFlags flags;
GError *error = NULL;
flags = static_cast<GDBusProxyFlags> (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START);
#if !GLIB_CHECK_VERSION (2, 35, 0)
/* Initialize GType system */
g_type_init ();
#endif
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
flags,
NULL, /* GDBusInterfaceInfo */
"org.freedesktop.NetworkManager",
"/org/freedesktop/NetworkManager",
"org.freedesktop.NetworkManager",
NULL, /* GCancellable */
&error);
g_assert (proxy != NULL);
/* List connections of system settings service */
list_connections (proxy);
g_object_unref (proxy);
return 0;
}

How does a method get called using C, after the dbus-send command is issued?

I'm learning how to use D-Bus on C with GLib. So far I've created a D-Bus service which calls my application, and I get a response after using the 'dbus-send' command. I have two files, one with the D-Bus code and one with the functions to call. The 'test_method_start' function lets us know that it has been called successfully, and creates a new thread. The second funtion tells us that we are stopping, and exits the thread.
I'm obviously missing something out, because I'm not seeing the result of the function calls. Can anyone tell me where I'm going wrong? I'm referring to the example here.
Here's the code snippets:
File1.c:
void test_method_start()
{
printf("Test method started\n")``;
//syslog(LOG_NOTICE, "Test method started\n");
if (!(pthread_create(&socketServerThread, NULL,
socketServerLoop, &socketServerParam)))
{
printf("Socket Server thread created successfully\n");
}
else
fprintf(stderr, "Error creating Socket Server thread\n");
pthread_exit(NULL);
}
void test_method_stop()
{
printf("Test method ended\n");
pthread_exit(NULL);
}
File2.c:
/*
* dbusClient
*/
/** Headers **/
#include "dbusClient.h"
#include <glib.h>
#include <gio/gio.h>
#include <gio/gioerror.h>
#include <gio/gdbuserror.h>
#include <stdlib.h>
#include <stdio.h>
/** Function Predeclarations **/
/** Globals **/
/** The service name on the bus. **/
static const gchar service[] = "org.test.DBusClient";
/** The object we publish on the bus. **/
static const gchar object_path[] = "/org/test/DBusObject";
/** Introspection data for the one object, in the internal form. **/
static GDBusNodeInfo *introspection_data = NULL;
/** Introspection data for the one object in XML form **/
static const gchar introspection_xml[] =
"<node>"
" <interface name='org.test.DBusClientInterface'>"
" <method name='test_method_start'>"
" <arg type='s' name='message' direction='in'/>"
" <arg type='s' name='response' direction='out'/>"
" </method>"
" <method name='test_method_stop'>"
" <arg type='s' name='message' direction='in'/>"
" <arg type='s' name='response' direction='out'/>"
" </method>"
" </interface>"
"</node>";
/** Object Callbacks **/
/* Handle a request for a property */
static GVariant *handle_get_property (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GError **error,
gpointer user_data)
{
printf("handle_get_property\n");
/* Print an optional log message */
#ifdef VERBOSE
fprintf (stderr, "[server 0] "
"handle_get_property (%p,\"%s\",\"%s\",\"%s\",\"%s\",(error),%p)\n",
connection, sender, object_path, interface_name, property_name,
user_data);
#endif
/* We currently don't have any properties,
so this should be an error. */
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"[server 0] Invalid property '%s'",
property_name);
// And we're done
return NULL;
} // handle_get_property
/* Handle a call to a method */
static void handle_method_call (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
printf("handle_method_call\n");
#ifdef VERBOSE
gchar *paramstr = g_variant_print (parameters, TRUE);
fprintf (stderr, "[server 0] "
"handle_method_call (%p,\"%s\",\"%s\",\"%s\",\"%s",
\"\",invocation),%p)\n",
connection, sender, object_path, interface_name, method_name,
paramstr, user_data);
g_free (paramstr);
#endif
/* Default: No such method */
if (g_strcmp0 (method_name, "test_method_start") == 0)
{
const gchar *greeting;
g_variant_get (parameters, "(&s)", &greeting);
if (g_strcmp0 (greeting, "Return Unregistered") == 0)
{
g_dbus_method_invocation_return_error (invocation,
G_IO_ERROR,
G_IO_ERROR_FAILED_HANDLED,
"As requested, here's a GError not registered
(G_IO_ERROR_FAILED_HANDLED)");
}
else if (g_strcmp0 (greeting, "Return Registered") == 0)
{
g_dbus_method_invocation_return_error (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_MATCH_RULE_NOT_FOUND,
"As requested, here's a GError that is
registered
(G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)");
}
else if (g_strcmp0 (greeting, "Return Raw") == 0)
{
g_dbus_method_invocation_return_dbus_error (invocation,
"org.gtk.GDBus.SomeErrorName",
"As requested, here's a raw D-Bus error");
}
else
{
gchar *response;
response = g_strdup_printf ("You greeted me with '%s'.
Thanks!", greeting);
g_dbus_method_invocation_return_value
(invocation,
g_variant_new ("(s)", response));
g_free (response);
}
}
else if (g_strcmp0 (method_name, "test_method_stop") == 0)
{
const gchar *greeting;
g_variant_get (parameters, "(&s)", &greeting);
if (g_strcmp0 (greeting, "Return Unregistered") == 0)
{
g_dbus_method_invocation_return_error (invocation,
G_IO_ERROR,
G_IO_ERROR_FAILED_HANDLED,
"As requested, here's a GError not registered
(G_IO_ERROR_FAILED_HANDLED)");
}
else if (g_strcmp0 (greeting, "Return Registered") == 0)
{
g_dbus_method_invocation_return_error (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_MATCH_RULE_NOT_FOUND,
"As requested, here's a GError that is registered
(G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)");
}
else if (g_strcmp0 (greeting, "Return Raw") == 0)
{
g_dbus_method_invocation_return_dbus_error (invocation,
"org.gtk.GDBus.SomeErrorName",
"As requested, here's a raw D-Bus error");
}
else
{
gchar *response;
response = g_strdup_printf ("You greeted me with
'%s'.Thanks!", greeting);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(s)", response));
g_free (response);
}
}
else
{
g_dbus_method_invocation_return_error (invocation,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
"[server 0] Invalid method: '%s'",
method_name);
}
} // handle_method_call
/* Handle a request to set a property. */
static gboolean handle_set_property (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GVariant *value,
GError **error,
gpointer user_data)
{
printf("handle_set_property\n");
/* Print an optional log message */
#ifdef VERBOSE
gchar *valstr = g_variant_print (value, TRUE);
fprintf (stderr, "[server 0] "
"handle_set_property (%p,\"%s\",\"%s\",\"%s\",\"%s\",
\"%s\",(error),%p)\n",
connection, sender, object_path,
interface_name, property_name,
valstr, user_data);
g_free (valstr);
#endif
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"[server 0] No such property: '%s'",
property_name);
return 0;
} // handle_set_property
/** Bus Callbacks **/
/* When the bus gets acquired... */
static void on_bus_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
printf("on_bus_acquired\n");
static GDBusInterfaceVTable interface_vtable =
{
handle_method_call,
handle_get_property,
handle_set_property
};
guint registration_id;
// GError *error = NULL;
// An optional notification
#ifdef VERBOSE
fprintf (stderr, "[server 0] on_bus_acquired (%p, \"%s\", %p)\n",
connection, name, user_data);
#endif
registration_id = g_dbus_connection_register_object (connection,
object_path,
introspection_data->interfaces[0],
&interface_vtable,
NULL, // Optional user data
NULL, // Func. for freeing user data
NULL); // GError
// Check to see whether or not the call succeeded.
printf("g_assert registration_id = %d\n", registration_id);
g_assert (registration_id > 0);
} // on_bus_acquired
static void on_name_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
// An optional notification
#ifdef VERBOSE
fprintf (stderr, "[server 0] on_name_acquired (%p, \"%s\", %p)\n",
connection, name, user_data);
#endif
} // on_name_acquired
static void on_name_lost (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
// An optional notification
#ifdef VERBOSE
fprintf (stderr, "[server 0] on_name_lost (%p, \"%s\", %p)\n",
connection, name, user_data);
#endif
// Things seem to have gone badly wrong, so give up
exit (1);
} // on_name_lost
/** Main **/
void *dbusLoop(void *dbusParam)
{
guint owner_id;
GMainLoop *loop;
printf("Reached dbusLoop\n");
// Build an internal representation of the interface
printf("Register the object\n");
introspection_data = g_dbus_node_info_new_for_xml
(introspection_xml, NULL);
g_assert (introspection_data != NULL);
// Request the name on the bus
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
service,
G_BUS_NAME_OWNER_FLAGS_NONE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
NULL,
NULL);
// Start the main loop
printf("Start the loop\n");
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
// Tell the bus that we're done with the name
printf("Release the owner_id\n");
g_bus_unown_name (owner_id);
// Clean up after ourselves
g_dbus_node_info_unref (introspection_data);
//Exit and join main thread
pthread_exit(NULL);
} // main
My command line statement is:
dbus-send --session --print-reply --type=method_call --dest=org.test.DBusClient /org/test/DBusObject org.test.DBusClientInterface.test_method_start string:"Hello"
and the response is:
method return sender=:1.364 -> dest=:1.376 reply_serial=2
string "You greeted me with 'Hello'. Thanks!"
What should I be doing now to get "test_method_start" to run?
Thanks for any help.
You should not be calling pthread_exit on a thread you didn't start. test_method_start is called by a thread created by someone else.
How do you expect test_method_start to be called when you never call it anywhere or take its address? There is no magic to DBUS; you have to call it from handle_method_call if you want it to be called. You seem to have the code to check if the method name is "test_method_start", so you would call it inside that if.

How can I compile my C program with the polkit library?

Today, I tried to use polkit - an application-level toolkit for defining and handling the policy that allows unprivileged processes to speak to privileged processes. In order to understand it better, I tried to download this code:
#include <polkit/polkit.h>
static gboolean
on_tensec_timeout (gpointer user_data)
{
GMainLoop *loop = user_data;
g_print ("Ten seconds has passed. Now exiting.\n");
g_main_loop_quit (loop);
return FALSE;
}
static void
check_authorization_cb (PolkitAuthority *authority,
GAsyncResult *res,
gpointer user_data)
{
GMainLoop *loop = user_data;
PolkitAuthorizationResult *result;
GError *error;
error = NULL;
result = polkit_authority_check_authorization_finish (authority, res, &error);
if (error != NULL)
{
g_print ("Error checking authorization: %s\n", error->message);
g_error_free (error);
}
else
{
const gchar *result_str;
if (polkit_authorization_result_get_is_authorized (result))
{
result_str = "authorized";
}
else if (polkit_authorization_result_get_is_challenge (result))
{
result_str = "challenge";
}
else
{
result_str = "not authorized";
}
g_print ("Authorization result: %s\n", result_str);
}
g_print ("Authorization check has been cancelled and the dialog should now be hidden.\n"
"This process will exit in ten seconds.\n");
g_timeout_add (10000, on_tensec_timeout, loop);
}
static gboolean
do_cancel (GCancellable *cancellable)
{
g_print ("Timer has expired; cancelling authorization check\n");
g_cancellable_cancel (cancellable);
return FALSE;
}
int
main (int argc, char *argv[])
{
pid_t parent_pid;
const gchar *action_id;
GMainLoop *loop;
PolkitSubject *subject;
PolkitAuthority *authority;
GCancellable *cancellable;
g_type_init ();
if (argc != 2)
{
g_printerr ("usage: %s <action_id>\n", argv[0]);
return 1;
}
action_id = argv[1];
loop = g_main_loop_new (NULL, FALSE);
authority = polkit_authority_get_sync (NULL, NULL);
/* Typically mechanisms will use a PolkitSystemBusName since most
* clients communicate with the mechanism via D-Bus. However for
* this simple example we use the process id of the calling process.
*
* Note that if the parent was reaped we have to be careful not to
* check if init(1) is authorized (it always is).
*/
parent_pid = getppid ();
if (parent_pid == 1)
{
g_printerr ("Parent process was reaped by init(1)\n");
return 1;
}
subject = polkit_unix_process_new (parent_pid);
cancellable = g_cancellable_new ();
g_print ("Will cancel authorization check in 10 seconds\n");
/* Set up a 10 second timer to cancel the check */
g_timeout_add (10 * 1000,
(GSourceFunc) do_cancel,
cancellable);
polkit_authority_check_authorization (authority,
subject,
action_id,
NULL, /* PolkitDetails */
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
cancellable,
(GAsyncReadyCallback) check_authorization_cb,
loop);
g_main_loop_run (loop);
g_object_unref (authority);
g_object_unref (subject);
g_object_unref (cancellable);
g_main_loop_unref (loop);
return 0;
}
But when I tried to compile it with gcc, I received this output:
ciao.c:35:27: fatal error: polkit/polkit.h: File o directory non esistente
compilation terminated.
The path polkit/polkit.h is not in the system include path. Make sure you've downloaded and installed PolKit so that the headers and libraries are available.
I solved my problem adding this
pkg-config --cflags glib-2.0 polkit-gobject-1
and this
pkg-config --libs glib-2.0 polkit-gobject-1
to gcc compilation's command in this way
gcc `pkg-config --cflags glib-2.0 polkit-gobject-1` -o polkit PolicyKit/example.c `pkg-config --libs glib-2.0`

Gstreamer HLS pipeline creation error

I am trying to stream a HLS Stream using gstreamer 1.0. I have a filter which works
gst-launch-1.0 -v souphttpsrc location="http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8" ! hlsdemux ! tsdemux ! h264parse ! avdec_h264 ! autovideosink
But when I try to convert this into c code, it fails.
int main(int argc, char* argv[])
{
GMainLoop *loop;
GstElement *pipeline, *source, *demuxer, *tsdemux, *h264parse, *vdecoder, *vsink;
GstElement *aacparse, *adecoder, *aconvert, *asink;
GstBus *bus;
int bus_watch_id;
gst_debug_set_default_threshold(3);
gst_init(&argc, &argv);
loop = g_main_loop_new(NULL, FALSE);
if (argc != 2)
{
g_printerr("Usage: %s <http stream source>\n", argv[0]);
return -1;
}
pipeline = gst_pipeline_new("myApp");
source = gst_element_factory_make("souphttpsrc", "http-src");
demuxer = gst_element_factory_make("hlsdemux", "hls-demuxer");
tsdemux = gst_element_factory_make("tsdemux", "ts-demuxer");
h264parse = gst_element_factory_make("h264parse", "h264parse");
vdecoder = gst_element_factory_make("avdec_h264", "h264decoder");
vsink = gst_element_factory_make("autovideosink", "videosink");
/* set the input url to the source element */
g_object_set(G_OBJECT(source), "location", argv[1], NULL);
bus = gst_pipeline_get_bus(GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
gst_object_unref(bus);
/* add elements into the pipeline */ //next aacparse
gst_bin_add_many(GST_BIN (pipeline), source, demuxer, tsdemux, h264parse, vdecoder,vsink, NULL);
gst_element_link(source, demuxer);
// this was wrong
/*gst_element_link_many(tsdemux, h264parse, vdecoder, vsink, NULL);*/
/* connect demuxer and decoder on pad added */
/*g_signal_connect(demuxer, "pad-added", G_CALLBACK(on_pad_added), vdecoder);*/
// Correct Implementation
gst_element_link_many(h264parse, vdecoder, vsink, NULL);
g_signal_connect(demuxer, "pad-added", G_CALLBACK(on_pad_added), tsdemux);
g_signal_connect(tsdemux, "pad-added", G_CALLBACK(on_pad_added), h264parse);
g_signal_connect(demuxer, "pad-added", G_CALLBACK(on_pad_added), vdecoder);
// Correct Implementation
g_print ("Starting play: %s\n", argv[1]);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
g_print ("Running\n");
g_main_loop_run(loop);
/* Clean up after execution of main loop */
g_print ("Stopping Playback: %s\n", argv[1]);
gst_element_set_state(pipeline, GST_STATE_NULL);
g_print ("Quitting\n");
g_object_unref(G_OBJECT(pipeline));
g_source_remove(bus_watch_id);
g_main_loop_unref(loop);
return 0;
}
I compile the code using:
cc my_app.c -o my_app $(pkg-config --cflags --libs gstreamer-1.0)
And launch the application using:
./my_app http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8
I always get the following error:
hlsdemux gsthlsdemux.c:792:gst_hls_demux_stream_loop:<hls-demuxer> error: stream stopped, reason not-negotiated
Do I have to do anything differently?
// this was wrong
gst_element_link(source, demuxer);
// Correct Implementation
gst_element_link(source, demuxer,NULL);
where is your void
on_pad_added (GstElement *element,
GstPad *pad,
gpointer data); function?and take a look at here.
I was able to get it working. The problem was "tsdemux" and "demuxer" have to connect at run time in "on_pad_added" method.

Asynchronous GIO Server/Client

I would like to create an Asynchronous server and client application that communicate via sockets using GIO. As I am newbie to GIO, on browsing I got the below code - which is my client. I am unable to find any examples of the server. Please guide me in this regard.
GMainLoop *loop;
GMainContext *ctx;
struct conn
{
GSocketClient *client;
GSocketConnection *conn;
GInputStream *in;
GOutputStream *out;
gchar data[8192];
unsigned int count;
};
static void
read_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
printf("## %s\n", __FUNCTION__);
struct conn *c = (struct conn *)user_data;
gssize len = g_input_stream_read_finish(c->in, res, NULL);
g_input_stream_read_async(c->in, c->data, sizeof c->data / sizeof *c->data, G_PRIORITY_DEFAULT, NULL, read_done_cb, c);
if (c->count++ == 1) {
printf("End of life as I know it...\n");
g_main_loop_quit(loop);
}
}
static void
write_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
}
static void
connect_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
printf("## %s\n", __FUNCTION__);
struct conn *c = (struct conn *)user_data;
c->conn = g_socket_client_connect_to_host_finish(c->client, res, NULL);
printf("I'm\n");
c->in = g_io_stream_get_input_stream(G_IO_STREAM (c->conn));
c->out = g_io_stream_get_output_stream(G_IO_STREAM (c->conn));
char *data = "hello world!!!\n";
printf("I'm here\n");
g_output_stream_write_async(c->out, data, strlen(data), G_PRIORITY_DEFAULT, NULL, write_done_cb, c);
g_input_stream_read_async(c->in, c->data, sizeof c->data / sizeof *c->data, G_PRIORITY_DEFAULT, NULL, read_done_cb, c);
}
int
main(int argc, char **argv)
{
g_type_init();
struct conn *c = g_malloc0(sizeof *c);
ctx = g_main_context_new();
loop = g_main_loop_new(ctx, FALSE);
g_main_context_push_thread_default(ctx);
c->client = g_socket_client_new();
g_socket_client_connect_to_host_async(c->client, "localhost", 1500, NULL, connect_done_cb, c);
g_main_loop_run(loop);
g_io_stream_close(G_IO_STREAM(c->conn), NULL, NULL);
g_object_unref(c->client);
g_object_unref(c->conn);
g_main_context_pop_thread_default(ctx);
g_main_loop_unref(loop);
g_main_context_unref(ctx);
return 0;
}
Hope this would help you
#include <glib.h>
#include <gio/gio.h>
/* this function will get called everytime a client attempts to connect */
gboolean
incoming_callback (GSocketService *service,
GSocketConnection *connection,
GObject *source_object,
gpointer user_data)
{
g_print("Received Connection from client!\n");
GInputStream * istream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
gchar message[1024];
g_input_stream_read (istream,
message,
1024,
NULL,
NULL);
g_print("Message was: \"%s\"\n", message);
return FALSE;
}
int
main (int argc, char **argv)
{
/* initialize glib */
g_type_init();
GError * error = NULL;
/* create the new socketservice */
GSocketService * service = g_socket_service_new ();
/* connect to the port */
g_socket_listener_add_inet_port ((GSocketListener*)service,
1500, /* your port goes here */
NULL,
&error);
/* don't forget to check for errors */
if (error != NULL)
{
g_error (error->message);
}
/* listen to the 'incoming' signal */
g_signal_connect (service,
"incoming",
G_CALLBACK (incoming_callback),
NULL);
/* start the socket service */
g_socket_service_start (service);
/* enter mainloop */
g_print ("Waiting for client!\n");
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
return 0;
}

Resources