maemo.org - Talk

maemo.org - Talk (https://talk.maemo.org/index.php)
-   Development (https://talk.maemo.org/forumdisplay.php?f=13)
-   -   Help with creating daemon for n900 (https://talk.maemo.org/showthread.php?t=46786)

jaeezzy 2010-03-08 07:49

Help with creating daemon for n900
 
Hi,
I'm trying to create a simple daemon that switches the speaker on/off by sliding the keyboard while on the call. I'm getting the result but the thing is its switching all the time and continuously monitoring the devices which, of course, gonna shorten battery life. So I'm trying to create a daemon that gets triggered only when the user clicks the "Answer" button to answer a call and stops with the user ending the call. So, just wondering if this is possible.
In the mean time I'm going through the script from shortcutd that triggers the daemon and at the top it has "start on XSESSIONS_STARTING" followed by "stop on stopped hal" -: (ya I'm just learning to write one and most of the things in this script is kinda foreign language to me :D). Is it responsible for what I'm looking for and if so what are the other combinations I can choose? Any help/suggestions or links would be greatly appreciated. Thanks

krk969 2010-03-08 10:48

Re: Help with creating daemon for n900
 
not a 100% sure about this until I try it myself but you could register for the call state signal using dbus wrappers

MCE_CALL_STATE_SIG can have states like
MCE_CALL_STATE_NONE "none"
No ongoing call.
#define MCE_CALL_STATE_RINGING "ringing"
Call ringing.
#define MCE_CALL_STATE_ACTIVE "active"
Call on-going.

you can activate listening to the keyboard status when the call is active or ringing.

You could further listen to call status only when screen is on ( MCE_DISPLAY_STATUS_GET ), that would save battery as well.

btw, I like your idea, good luck ! :)

jaeezzy 2010-03-08 16:48

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by krk969 (Post 559671)
not a 100% sure about this until I try it myself but you could register for the call state signal using dbus wrappers

MCE_CALL_STATE_SIG can have states like
MCE_CALL_STATE_NONE "none"
No ongoing call.
#define MCE_CALL_STATE_RINGING "ringing"
Call ringing.
#define MCE_CALL_STATE_ACTIVE "active"
Call on-going.

you can activate listening to the keyboard status when the call is active or ringing.

You could further listen to call status only when screen is on ( MCE_DISPLAY_STATUS_GET ), that would save battery as well.

btw, I like your idea, good luck ! :)

Thanks for the the reply. The main idea I took from brainstorm as it will be bit of a practise as well ;) but I guess it's killing me coz I have been trying since to use the mce-dev but without any success. Googling didn't help either. I just couldn't figure out how I can make use of those constants. As you said that you have tried them yourself, it would be great if you could show me how you did. Thank you.

qwerty12 2010-03-08 16:54

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by jaeezzy (Post 560185)
I just couldn't figure out how I can make use of those constants.

In combination with the D-Bus method calls and signals it provides (http://maemo.org/api_refs/5.0/5.0-fi...5a46afdad43a94 and http://maemo.org/api_refs/5.0/5.0-fi...1a695659d394da in particular). What are you programming your daemon in? Are you using Qt or GLib/GTK?

jaeezzy 2010-03-08 17:06

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by qwerty12 (Post 560193)
In combination with the D-Bus method calls and signals it provides (http://maemo.org/api_refs/5.0/5.0-fi...5a46afdad43a94 and http://maemo.org/api_refs/5.0/5.0-fi...1a695659d394da in particular). What are you programming your daemon in? Are you using Qt or GLib/GTK?

Thanks. I'm using GLib/GTK.

EDIT: Just went through the links and ya thats what I'm been going through till now - 4am, without being able to figure out how to use 'em as it just says return gchar * ..

krk969 2010-03-08 17:10

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by jaeezzy (Post 560206)
Thanks. I'm using GLib/GTK.

I suggest you try using QT , if you are starting off, its much simpler to read and write ;)

jaeezzy 2010-03-08 17:13

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by krk969 (Post 560209)
I suggest you try using QT , if you are starting off, its much simpler to read and write ;)

ya I'm thinking but as I'm bit familier with C, I started with C/GTK.

qwerty12 2010-03-08 17:23

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by krk969 (Post 560209)
if you are starting off, its much simpler to read and write ;)

**** no! :p

@jaeezzy

Here's an example, using the lovely DBus-GLib bindings, that gets the current state and prints it out: http://slexy.org/view/s287btiNxS

As you can see, I'm not in the habit of commenting my code. I'll try and explain anything asked, but I'm no expert on D-Bus.

When I've finished it, I'll post again with another sample that automatically prints out the state when it changes.

jaeezzy 2010-03-08 17:51

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by qwerty12 (Post 560222)
**** no! :p

@jaeezzy

Here's an example, using the lovely DBus-GLib bindings, that gets the current state and prints it out: http://slexy.org/view/s287btiNxS

As you can see, I'm not in the habit of commenting my code. I'll try and explain anything asked, but I'm no expert on D-Bus.

When I've finished it, I'll post again with another sample that automatically prints out the state when it changes.

Thanks. BTW, it seems I was doing exactly same thing which I got from the web but just didn't work so thought it wasn't how it should be done any way here it is. I would be glad if any one can point out where I did wrong. Thanks.

Code:

#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <glib.h>
#include <stdio.h>
#include <string.h>

#include <mce/dbus-names.h>
#include <mce/mode-names.h>

#include <stdlib.h>

typedef struct{
        DBusGProxy *proxy;
        gchar *call_state;
        gchar *call_e_state;       
} PSSwitcherD;
       
static void mce_call_state_changed(DBusGProxy*, const gchar*, const gchar*, gpointer);
static void private_free(gpointer);
static GStaticPrivate private_key = G_STATIC_PRIVATE_INIT;

int main(int argc, char *argv[]){
        DBusGConnection *dbus;
        GError *dbus_err = NULL;
       
        PSSwitcherD *switcher;
        switcher = g_new0(PSSwitcherD, 1);
        g_static_private_set(&private_key, switcher, private_free);
       
        dbus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &dbus_err);
       
        if (!dbus){
                g_print("D-BUS Connection FAILED!!!\n");
                g_clear_error(&dbus_err);
                return 1;
        }
       
        switcher->proxy = dbus_g_proxy_new_for_name(dbus, MCE_SERVICE, MCE_SIGNAL_PATH, MCE_SIGNAL_IF);
        dbus_g_proxy_add_signal(switcher->proxy, MCE_CALL_STATE_SIG, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
        dbus_g_proxy_connect_signal(switcher->proxy, MCE_CALL_STATE_SIG, G_CALLBACK(mce_call_state_changed), NULL, NULL);
       
        g_print("Requesting current call state...\n");
       
        dbus_g_proxy_call(switcher->proxy, MCE_CALL_STATE_GET, &dbus_err, G_TYPE_INVALID, G_TYPE_STRING,
                                          &switcher->call_state, G_TYPE_STRING, &switcher->call_e_state, G_TYPE_INVALID);
                                         
        if (dbus_err){
                g_print("couldn't request current call state.\n");
                g_clear_error(&dbus_err);
        }else{
                g_print("Current state is %s.\n", switcher->call_state);
        }
       
        return 0;
}

static void mce_call_state_changed(DBusGProxy *proxy, const gchar *call_state, const gchar *call_e_state,
                                                        gpointer user_data){
        PSSwitcherD *switcher;
        switcher = g_static_private_get(&private_key);
        g_return_if_fail(switcher != NULL);
        g_print("Call state changed to %s\n", call_state);
       
        g_free(switcher->call_state);
        switcher->call_state = g_strdup(call_state);
       
        g_free(switcher->call_e_state);
        switcher->call_e_state = g_strdup(call_e_state);
       
        if (g_strcmp0(call_state, MCE_CALL_STATE_NONE))
                g_print("DOING NOTHING\n");
        else if (g_strcmp0(call_state, MCE_CALL_STATE_RINGING))
                g_print("BLOODY RINGING\n");
}

static void private_free(gpointer data){
        PSSwitcherD *switcher;
        switcher = data;
        g_free(switcher->call_state);
        g_free(switcher->call_e_state);
        if (switcher->proxy)
                g_object_unref(switcher->proxy);
        g_free(switcher);
}


qwerty12 2010-03-08 17:53

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by qwerty12 (Post 560222)
When I've finished it, I'll post again with another sample that automatically prints out the state when it changes.

As promised: http://qwerty12.qole.org/pimp2.tar

Make it, and run it on the N900. Whenever the call state changes, you will see a message. Use the code to implement something similar in your code (like !strcmp in the callback for MCE_CALL_STATE_ACTIVE etc. to know if you're in a call, and if you're using gtk_main, ignore the GMainloop stuff in the example.).

I see you've been posting as I've been posting my sample. Take a look at the code I've given first, please. :)

Merging my "on demand" code in #8 with this shouldn't be hard.

jaeezzy 2010-03-08 18:07

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by qwerty12 (Post 560256)
As promised: http://qwerty12.qole.org/pimp2.tar

Make it, and run it on the N900. Whenever the call state changes, you will see a message. Use the code to implement something similar in your code (like !strcmp in the callback for MCE_CALL_STATE_ACTIVE etc. to know if you're in a call, and if you're using gtk_main, ignore the GMainloop stuff in the example.).

I see you've been posting as I've been posting my sample. Take a look at the code I've given first, please. :)

Merging my "on demand" code in #8 with this shouldn't be hard.

Thanks tons. I'll definitely. Well it worth the stay till this long '5am'. Off I go now and will certainly return with new questions :D

jaeezzy 2010-03-09 05:09

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by qwerty12 (Post 560256)
As promised: http://qwerty12.qole.org/pimp2.tar

Make it, and run it on the N900. Whenever the call state changes, you will see a message. Use the code to implement something similar in your code (like !strcmp in the callback for MCE_CALL_STATE_ACTIVE etc. to know if you're in a call, and if you're using gtk_main, ignore the GMainloop stuff in the example.).

I see you've been posting as I've been posting my sample. Take a look at the code I've given first, please. :)

Merging my "on demand" code in #8 with this shouldn't be hard.

As I said, I'm back with ;) The thing is I didn't get why there are so many marshal* things needed.

qwerty12 2010-03-09 07:38

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by jaeezzy (Post 560799)
As I said, I'm back with ;) The thing is I didn't get why there are so many marshal* things needed.

As you will have noticed, D-Bus signals are handled like "normal, GObject-type" signals in DBus-GLib (think of dbus_g_proxy_connect_signal () as the D-Bus version of g_signal_connect ()).
g_signal_new requires a marshaller to be able to send whatever it receives (in this case, the two gchars* from MCE) to the callback function (see http://gnomejournal.org/article/36/w...d-gtk28-part-2 for an example on how it's used there).

So, according to http://maemo.org/api_refs/5.0/5.0-fi...5a46afdad43a94 , we receive two gchars*.
So our callback function signature is to look like "static void call_state_changed_cb (DBusGProxy *object G_GNUC_UNUSED, const gchar *call_state, const gchar *emergency_call_state G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)".

(G_GNUC_UNUSED is only there because I'm [generally] pedantic/anal about GCC warnings...)

But if we look at http://maemo.org/api_refs/5.0/5.0-fi...-Closures.html , we see GLib only comes with a marshaller (g_cclosure_marshal_VOID__STRING) that would only handle "static void call_state_changed_cb (DBusGProxy *object G_GNUC_UNUSED, const gchar *call_state, gpointer user_data G_GNUC_UNUSED)" (i.e. a DBus signal that only sends back one gchar*).

That is not what we want and, in any case, it wouldn't work - the callback function would never be called.

So we use glib-genmarshal to create a marshaller that understands VOID__STRING_STRING, matching the signature of the first callback function and we then use dbus_g_object_register_marshaller () to register it with DBus-GLib.

jaeezzy 2010-03-09 09:48

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by qwerty12 (Post 560860)
As you will have noticed, D-Bus signals are handled like "normal, GObject-type" signals in DBus-GLib (think of dbus_g_proxy_connect_signal () as the D-Bus version of g_signal_connect ()).
g_signal_new requires a marshaller to be able to send whatever it receives (in this case, the two gchars* from MCE) to the callback function (see http://gnomejournal.org/article/36/w...d-gtk28-part-2 for an example on how it's used there).

So, according to http://maemo.org/api_refs/5.0/5.0-fi...5a46afdad43a94 , we receive two gchars*.
So our callback function signature is to look like "static void call_state_changed_cb (DBusGProxy *object G_GNUC_UNUSED, const gchar *call_state, const gchar *emergency_call_state G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)".

(G_GNUC_UNUSED is only there because I'm [generally] pedantic/anal about GCC warnings...)

But if we look at http://maemo.org/api_refs/5.0/5.0-fi...-Closures.html , we see GLib only comes with a marshaller (g_cclosure_marshal_VOID__STRING) that would only handle "static void call_state_changed_cb (DBusGProxy *object G_GNUC_UNUSED, const gchar *call_state, gpointer user_data G_GNUC_UNUSED)" (i.e. a DBus signal that only sends back one gchar*).

That is not what we want and, in any case, it wouldn't work - the callback function would never be called.

So we use glib-genmarshal to create a marshaller that understands VOID__STRING_STRING, matching the signature of the first callback function and we then use dbus_g_object_register_marshaller () to register it with DBus-GLib.

Thanks for your time to explain. I'll have to go through it more coz I'm not quite familier with dbus let alone dbus-glib. However, I came across another problem coz as I'm using libhal to listen to hardware property changes and it uses dbus I couldn't think of how I could link dbus-glib and hal so I just made the whole thing which gets the current call state into one method with all the dbus-glib thing and flushes this connection after it gets what it wants while the main loop which uses plain dbus is there. So, I was wondering if there's better way to do it.

Anyway, I've got it to work and quickly created a .deb file and does what it is suppose to do. I guess I'll start a new thread for it and let this one continue coz I have more to implement ;)

qwerty12 2010-03-09 11:15

Re: Help with creating daemon for n900
 
Quote:

Originally Posted by jaeezzy (Post 560947)
Thanks for your time to explain. I'll have to go through it more coz I'm not quite familier with dbus let alone dbus-glib. However, I came across another problem coz as I'm using libhal to listen to hardware property changes and it uses dbus I couldn't think of how I could link dbus-glib and hal so I just made the whole thing which gets the current call state into one method with all the dbus-glib thing and flushes this connection after it gets what it wants while the main loop which uses plain dbus is there. So, I was wondering if there's better way to do it.

Anyway, I've got it to work and quickly created a .deb file and does what it is suppose to do. I guess I'll start a new thread for it and let this one continue coz I have more to implement ;)

If you run dbus-monitor, you'll notice that events are broadcast by HAL on the System bus, anyway, so you can just connect to those signals as you would any other.

But if you wish to use libhal; I haven't looked too deep into libhal because of the libdbus requirement, but I believe it requires a DBusConnection rather than a DBusGConnection. You can get a DBusConnection from your DBusGConnection by calling dbus_g_connection_get_connection (). The DBusConnection will automatically be integrated into the mainloop because dbus_connection_setup_with_g_main was called when you did dbus_g_dbus_get.

However, you will have to look into the libhal API reference to see how you check for events and the like - I can't help there, sorry.

P.S. If you're just checking to see if the keyboard is slid open, you can get the value of the GConf key /system/osso/af/slide-open. GConfClient is rather easy to use and you can get notifications of the key being changed.


All times are GMT. The time now is 22:24.

vBulletin® Version 3.8.8