D-bus Learning (5): small example of signal sending and receiving

Source: Internet
Author: User

From: http://blog.csdn.net/flowingflying/article/details/5449995

We continue to learn about D-bus, refer to the http://dbus.freedesktop.org/doc/dbus/libdbus-tutorial.html, from the bottom layer, that is, how to send signal, and how to listen to signal. Signal is broadcasted in the daemon of D-bus. To improve efficiency, it is only sent to the object that registers the singal to the daemon.

 

I have drawn this image for a long time. I hope to illustrate the relationships between various concepts in D-bus. For programs, the first step is to establish a connection between the application and the D-bus background, that is, to establish a connection with System D-bus daemon or Session D-bus daemon. Once a connection is established, daemon assigns a name to the connection. The name is unique in the lifecycle of the system or session, that is, the unique connection name, you can allocate a well-known name for this connection. For the signal method, assigning this name is not necessary (it is required in method_call, we will talk about it in the next study ), because the Interface Name and signal name are given in order in the signal listening, in the following example, the relevant code can be blocked without affecting the operation, but we usually process it like this, especially in complex programs. In our example, we define this bus name as test. Singal. Source. Of course, a good name should be used, such as com. mycompany. myfunction, to avoid repeated applications. While the interface name is usually the same as the bus name of the connection.

Sender's Applet

# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <alias/dbus-glib.h>
# Include <alias/example. h>
# Include <unistd. h>

Int send_a_signal (char * sigvalue)
{
Dbuserror err;
Dbusconnection * connection;
Dbusmessage * MSG;
Dbusmessageiter ARG;
Dbus_uint32_t serial = 0;
Int ret;

// Step 1: establish a connection with the D-bus background
/* Initialise the Erroes */
Dbus_error_init (& ERR ); 
/* Connect to bus */
Connection =Dbus_bus_get (Dbus_bus_session,& Err); 
If (dbus_error_is_set (& ERR )){
Fprintf (stderr, "connection err: % s/n", Err. Message );
Dbus_error_free (& ERR );
}
If (connection = NULL)
Return-1;

// Step 2: assign a well-known name to the connection name as the bus name. This step is not required. You can use if 0 to comment out a piece of code, we can use this name to check whether another process of the application has been enabled.
# If 1 
Ret =Dbus_bus_request_name (Connection, "test. Singal. Source", dbus_name_flag_replace_existing, & err); 
If (dbus_error_is_set (& ERR )){
Fprintf (stderr, "Name err: % s/n", Err. Message );
Dbus_error_free (& ERR );
}
If (Ret! = Dbus_request_name_reply_primary_owner)
Return-1;
# Endif 

// Step 3: send a signal
// Based on the figure, we provide the signal path (which can point to the object), interface, and signal name, and create a message
If (MSG =Dbus_message_new_signal("/Test/signal/object", "test. Signal. Type", "test") = NULL ){
Fprintf (stderr, "message null/N ");
Return-1;
}
// Specify the message content.
Dbus_message_iter_init_append(MSG, & Arg );
If (!Dbus_message_iter_append_basic(& Arg, dbus_type_string, & sigvalue )){
Fprintf (stderr, "out of memory! /N ");
Return-1;
}

// Step 4: Send the signal from the connection
If (!Dbus_connection_send(Connection, MSG, & serial )){
Fprintf (stderr, "out of memory! /N ");
Return-1;
}
Dbus_connection_flush(Connection );
Printf ("signal send/N ");

// Step 5: Release the allocated memory.
Dbus_message_unref (MSG); 
Return 0;
}

Int main (INT argc, char ** argv ){
Send_a_signal ("Hello, world! ");
Return 0;
}

Example of a small program that wants to receive the signal

# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <alias/dbus-glib.h>
# Include <alias/example. h>
# Include <unistd. h>

Void listen_signal ()
{
Dbusmessage * MSG;
Dbusmessageiter ARG;
Dbusconnection * connection;
Dbuserror err;
Int ret;
Char * sigvalue;

// Step 1: establish a connection with the D-bus background
Dbus_error_init (& ERR );
Connection = dbus_bus_get (dbus_bus_session, & ERR );
If (dbus_error_is_set (& ERR )){
Fprintf (stderr, "connection error % s/n", Err. Message );
Dbus_error_free (& ERR );
}
If (connection = NULL)
Return;

// Step 2: assign a memorable name test. Singal. DEST to the connection name as the bus name. This step is not required, but we recommend that you do this.
Ret = dbus_bus_request_name (connection, "test. Singal. DEST", dbus_name_flag_replace_existing, & ERR );
If (dbus_error_is_set (& ERR )){
Fprintf (stderr, "Name error % s/n", Err. Message );
Dbus_error_free (& ERR );
}
If (Ret! = Dbus_request_name_reply_primary_owner)
Return;

// Step 3: Notify D-bus daemon. You want to listen to the signal of the test. Signal. type interface.
Dbus_bus_add_match (connection, "type = 'signal ', interface = 'test. Signal. type'", & ERR ); 
// Actually, you need to send something to daemon to notify the content you want to listen to, so you need to flush
Dbus_connection_flush (connection ); 
If (dbus_error_is_set (& ERR )){
Fprintf (stderr, "Match error % s/n", Err. Message );
Dbus_error_free (& ERR );
}

// Step 4: listen in the loop, and try to obtain this signal in your connection every second after being separated. The following shows how to obtain any message in the connection. After obtaining the message, check whether the message is expected and obtain the content. We can also use this method to obtain the method call message.
While (1 ){
Dbus_connection_read_write (connection, 0 ); 
MSG =Dbus_connection_pop_message(Connection );
If (MSG = NULL ){
Sleep (1 );
Continue;
}

If (Dbus_message_is_signal (MSG, "test. Signal. Type", "test ")){
 If (!Dbus_message_iter_init (MSG, & Arg))
Fprintf (stderr, "message has no Param ");
Else IF (dbus_message_iter_get_arg_type (& Arg )! = Dbus_type_string) 
G_printerr ("Param is not string ");
Else
Dbus_message_iter_get_basic (& Arg, & sigvalue ); 
Printf ("got singal with value: % s/n", sigvalue );
}
Dbus_message_unref (MSG );
} // End of while

}

Int main (INT argc, char ** argv ){
Listen_signal ();
Return 0;
}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.