2006/3/28, Jari Tenhunen <[EMAIL PROTECTED]>:
> On Tue, Mar 28, 2006 at 04:45:05PM +0200, koos vriezen wrote:
> > > 2006/3/27, Jari Tenhunen <[EMAIL PROTECTED]>:
> > >
> > > > I don't really follow, what are you trying to say here?
> > > >
> > > > We will release the BT plugin soon and Tapio will probably release an
> > > > updated GpsDrive package that will work with it.
> > >
> > > That is great. I got the impression that there wasn't any work being
> > > done for this. The version at ApplicationCatalogWip is from nov'05.
> > > Is there a public CVS repository or snapshots available. (my problem
> > > is that I need it ASAP, will be on the road a lot the coming weeks).
> > > Would be great if I can test your newly BT plugin and see if it's any
> > > better than what I have now (eg. could be my el-cheapo GPS receiver as
> > > well).
> >
> > Can you answer this please, I really want to get this going real soon.
>
> Currently there is no CVS or SVN repository for the project but we hope
> to get one real soon. The updated GpsDrive might available already
> tonight, I'll send you an email once it's there.
>
> If you're *really* in a hurry and can't wait for the official release
> (should happen some time this week) I can send you a binary pre-release
> of the BT plugin (the configuration tool I mentioned) that works with
> the updated GpsDrive.
>
> Patience, my friend ... =)

Ok, this week sound fast enough ;-)

> > Maybe you can help solving the PIN issue. If I connect, I get the
> > 'pin_req' signal, but where should I send the pin to? I did register
> > an object path with 'com.nokia.btpin.request.register' (and I did do
> > 'dbus_bus_acquire_service' and 'dbus_connection_register_object_path'
> > for it), but the callback is never called.
> > How does that work?
> > What now happens is a pin popup, which also works for setting up this
> > connection.
>
> My code is based on Tomas Junnonen's btkeyboard-plugin,
> http://770.fs-security.com/keyboards.html, you may find some help there.
> I can get back on this issue later when I'm not so busy...

Darn I made a mistake, shouldn't have added the 'request' path on
btpin. Anyhow, my version works for me. Attached the source for anyone
that may need some extra references on dbus-0.23 (I didn't find
anything useful for this version, only at
https://stage.maemo.org/viewcvs.cgi/maemo/projects/haf/branches/libosso/0.9-branch/src/
).
This is really a quick & dirty tool to get it working, run as
 LD_LIBRARY_PATH=/var/lib/install/usr/lib bt-gps <BT-Address> <PIN>
(library path is for launching gpsd)

I also noted that once gpsdrive reports a timeout on the GPS, gpsd
hangs and isn't killable w/ INT or TERM. Only KILL will do then, so
this little app also does that :-)

Koos
//#include <config.h>
// gcc -o bt-gps bt-gps.cpp `pkg-config --cflags dbus-glib-1 --libs` -s
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <bt-dbus.h>

static GMainLoop * g_event_loop;
static DBusConnection * sys_conn;
static DBusPendingCall * pending;
static bool interupted;
static const char * object_path = "/com/nokia/bt-gps";
static const char * service = "com.nokia.bt-gps";
static char * bt_address;
static char * bt_rfcomm;
static char * bt_pin;

void bt_connected () {
    printf ("bt_connected\n");
}

void bt_disconnected () {
    printf ("bt_disconnected\n");
}

void rf_connected () {
    printf ("rf_connected\n");
}

void rf_disconnected () {
    printf ("rf_disconnected\n");
    g_main_loop_quit (g_event_loop);
}

static DBusHandlerResult filter_func (DBusConnection * connection,
        DBusMessage *message, void * user_data) {
    const char *sender = dbus_message_get_sender (message);
    int message_type = dbus_message_get_type (message);
    bool handled = false;
    if (message_type == DBUS_MESSAGE_TYPE_SIGNAL &&
            !strcmp (dbus_message_get_interface (message),
                BTCOND_SIG_INTERFACE)) {
        do {
            DBusMessageIter iter;
            dbus_message_iter_init (message, &iter);
            int type = dbus_message_iter_get_arg_type (&iter);
            const char * method = dbus_message_get_member (message);
            handled = true;
            if (!strcmp (method, BTCOND_CONNECTION_STATUS_SIG)) {
                printf ("sig connection status\n");
                if (type != DBUS_TYPE_STRING)
                    break;
                const char * bt = dbus_message_iter_get_string (&iter);
                if (!dbus_message_iter_next (&iter))
                    break;
                type = dbus_message_iter_get_arg_type (&iter);
                if (type != DBUS_TYPE_STRING)
                    break;
                const char * state = dbus_message_iter_get_string (&iter);
                if (!strcmp (state, "disconnected"))
                    bt_disconnected ();
                else if (!strcmp (state, "connected"))
                    bt_connected ();
                else
                    fprintf (stderr, "unknown %s\n", state);
            } else if (!strcmp (method, BTCOND_RFCOMM_STATUS_SIG)) {
                printf ("sig rfcomm status\n");
                if (type != DBUS_TYPE_STRING)
                    break;
                const char * bt = dbus_message_iter_get_string (&iter);
                if (!dbus_message_iter_next (&iter))
                    break;
                type = dbus_message_iter_get_arg_type (&iter);
                const char * service = dbus_message_iter_get_string (&iter);
                if (!dbus_message_iter_next (&iter))
                    break;
                type = dbus_message_iter_get_arg_type (&iter);
                if (type != DBUS_TYPE_STRING)
                    break;
                const char * state = dbus_message_iter_get_string (&iter);
                if (!strcmp (state, "disconnected"))
                    rf_disconnected ();
                else if (!strcmp (state, "connected"))
                    rf_connected ();
                else
                    fprintf (stderr, "unknown %s\n", state);
            } else if (!strcmp (method, BTCOND_CONNECT_FAILED_SIG)) {
                printf ("sig connect failed\n");
                if (type != DBUS_TYPE_STRING)
                    break;
                const char * bt = dbus_message_iter_get_string (&iter);
            } else
                printf ("unhandled %s from %s\n", method, sender ? sender :"");
        } while (false);
    } else if (message_type == DBUS_MESSAGE_TYPE_SIGNAL &&
            !strcmp (dbus_message_get_interface (message),
                BTSEARCH_SIG_INTERFACE)) {
        do {
            DBusMessageIter iter;
            dbus_message_iter_init (message, &iter);
            int type = dbus_message_iter_get_arg_type (&iter);
            const char * method = dbus_message_get_member (message);
            handled = true;
            if (!strcmp (method, BTSEARCH_DEV_FOUND_SIG)) {
                printf ("sig dev found\n");
                if (type != DBUS_TYPE_STRING)
                    break;
                const char * bt = dbus_message_iter_get_string (&iter);
                if (!dbus_message_iter_next (&iter))
                    break;
                type = dbus_message_iter_get_arg_type (&iter);
                if (type != DBUS_TYPE_STRING)
                    break;
                const char * name = dbus_message_iter_get_string (&iter);
                if (!dbus_message_iter_next (&iter))
                    break;
                printf ("sig dev %s name %s\n", bt, name);
                //type = dbus_message_iter_get_arg_type (&iter);
                /*bool b = dbus_type_is_fixed (&iter);
                printf ("sig dev %s name %s type %d\n", bt, name, b);
                if (b) {
                    char buf [12];
                    dbus_message_iter_get_fixed_array (&iter, buf, 3);
                    buf [4] = 0;
                    printf ("sig dev %s name %s service %s\n", bt, name, buf);
                }*/
            } else if (!strcmp (method, BTSEARCH_SEARCH_COMPLETE_SIG)) {
                printf ("sig search done\n");
            }
        } while (false);
    } else if (message_type == DBUS_MESSAGE_TYPE_METHOD_CALL) {
        const char * method = dbus_message_get_member (message);
        printf ("filter_func method call %s\n", method);
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    } else if (message_type == DBUS_MESSAGE_TYPE_SIGNAL) {
        DBusMessageIter iter;
        dbus_message_iter_init (message, &iter);
        int type = dbus_message_iter_get_arg_type (&iter);
        const char * method = dbus_message_get_member (message);
        const char * arg = "";
        if (type == DBUS_TYPE_STRING)
            arg = dbus_message_iter_get_string (&iter);
        printf ("filter_func signal %s (%s)\n", method, arg);
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    } else if (message_type == DBUS_MESSAGE_TYPE_ERROR) {
        const char * method = dbus_message_get_error_name (message);
        const char * sender = dbus_message_get_sender (message);
        printf ("filter_func error %s %s \n", method, sender ? sender : "anon");
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    } else if (message_type == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
        const char * method = dbus_message_get_error_name (message);
        DBusMessageIter iter;
        dbus_message_iter_init(message, &iter);
        int type = dbus_message_iter_get_arg_type (&iter);
        const char * arg = "";
        if (type == DBUS_TYPE_STRING) {
            arg = dbus_message_iter_get_string (&iter);
            bt_rfcomm = g_strdup (arg);
            system ("/var/lib/install/usr/bin/gpsd -p /dev/rfcomm0");
        }
        printf ("filter_func message return %s (%s)\n", method, arg);
    } else {
        printf ("filter_func not handled %d\n", message_type);
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

    //print_message (message);

    if (dbus_message_is_signal (message,
                DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
                "Disconnected"))
        ;//exit (0);

    /* Conceptually we want this to be
     * DBUS_HANDLER_RESULT_NOT_YET_HANDLED, but this raises
     * some problems.  See bug 1719.
     */
    return DBUS_HANDLER_RESULT_HANDLED;
}

static void async_return_handler (DBusPendingCall *pending, void *) {
    DBusMessage *msg = dbus_pending_call_steal_reply(pending);
    if (!msg)
        return;
    int type = dbus_message_get_type(msg);
    if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
        DBusMessageIter iter;
        dbus_message_iter_init(msg, &iter);
        type = dbus_message_iter_get_arg_type (&iter);
        if (type == DBUS_TYPE_STRING) {
            char *str = dbus_message_iter_get_string (&iter);
            printf ("mgs return %s\n", str);
            bt_rfcomm = g_strdup (str);
            system ("/var/lib/install/usr/bin/gpsd -p /dev/rfcomm0");
        }
    } else if(type == DBUS_MESSAGE_TYPE_ERROR) {
        DBusError err;
        dbus_error_init(&err);
        dbus_set_error_from_message(&err, msg);
        printf ("mgs error %s\n", err.message);
        dbus_error_free(&err);
        if (!bt_rfcomm || !*bt_rfcomm)
            g_main_loop_quit (g_event_loop);
    }
}
/*
void cb_unregister_function (DBusConnection *conn, void *) {
    printf ("cb_unregister_function\n");
    if (conn)
        dbus_connection_unregister_object_path (conn, "/com/nokia/bt-gps");
}*/

DBusHandlerResult cb_message_function (DBusConnection *conn, DBusMessage *msg, void *) {
    int message_type = dbus_message_get_type (msg);
    if (message_type == DBUS_MESSAGE_TYPE_METHOD_CALL) {
        const char * method = dbus_message_get_member (msg);
        printf ("method call %s\n", method);
        if (!strcmp (method, "PinRequest") && bt_pin && *bt_pin) {
            dbus_uint32_t serial;
            DBusMessage *reply = dbus_message_new_method_return (msg);
            dbus_message_append_args(reply, DBUS_TYPE_STRING, bt_pin, DBUS_TYPE_INVALID);
            dbus_connection_send (sys_conn, reply, &serial);
            dbus_connection_flush (sys_conn);
            dbus_message_unref(reply);
            return DBUS_HANDLER_RESULT_HANDLED;
        }
    } else
        printf ("method call unknown type %d\n", message_type);
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

gboolean cb_connect (void *) {
    DBusMessage *msg = dbus_message_new_method_call ("com.nokia.btpin", "/com/nokia/btpin", "com.nokia.btpin", "register");
    dbus_message_append_args (msg, DBUS_TYPE_STRING, object_path, DBUS_TYPE_STRING, bt_address, DBUS_TYPE_INVALID);
    dbus_message_set_auto_activation (msg, true);
    dbus_message_set_no_reply (msg, TRUE);
    dbus_connection_send (sys_conn, msg, NULL);
    dbus_message_unref (msg);
    printf ("connect %s\n", bt_address);

    msg = dbus_message_new_method_call ("com.nokia.btcond", "/com/nokia/btcond/request", "com.nokia.btcond.request", "rfcomm_connect");
    dbus_message_append_args (msg, DBUS_TYPE_STRING, bt_address, DBUS_TYPE_STRING, "SPP", DBUS_TYPE_BOOLEAN, true, DBUS_TYPE_INVALID);
    dbus_message_set_auto_activation (msg, true);
    if (dbus_connection_send_with_reply (sys_conn, msg, &pending, INT_MAX))
        dbus_pending_call_set_notify (pending, async_return_handler, 0L, 0L);
    dbus_message_unref (msg);
    return false;
}

gboolean cb_scan (void *) {
    DBusMessage *msg = dbus_message_new_method_call ("com.nokia.btsearch", "/com/nokia/btsearch/request", "com.nokia.btsearch.request", "start_search");
    dbus_message_append_args (msg, DBUS_TYPE_INVALID);
    dbus_message_set_auto_activation (msg, true);
    dbus_message_set_no_reply (msg, TRUE);
    dbus_connection_send (sys_conn, msg, NULL);
    dbus_message_unref (msg);
    return false;
}

void signal_int (int) {
    interupted = true;
}

gboolean cb_checkInteruptTimer (void *) {
    if (!interupted)
        return true;
    if (bt_rfcomm) {
        system ("killall gpsd");
        usleep (200000);
        system ("killall -9 gpsd");
        DBusMessage *msg = dbus_message_new_method_call ("com.nokia.btcond", "/com/nokia/btcond/request", "com.nokia.btcond.request", "rfcomm_disconnect");
        dbus_message_append_args (msg, DBUS_TYPE_STRING, bt_address, DBUS_TYPE_STRING, "SPP", DBUS_TYPE_INVALID);
        dbus_message_set_no_reply (msg, TRUE);
        dbus_connection_send (sys_conn, msg, NULL);
        dbus_connection_flush (sys_conn);
        dbus_message_unref (msg);
    } else
        g_main_loop_quit (g_event_loop);
    return false;
}

int main (int argc, char ** argv) {
    DBusError error;
    DBusObjectPathVTable vtable;
    g_event_loop = g_main_loop_new (0L, false);
    dbus_error_init (&error);
    sys_conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
    if (!sys_conn) {
        g_printerr ("Failed to open connection to bus: %s\n", error.message);
        dbus_error_init (&error);
        exit (1);
    }
    dbus_connection_setup_with_g_main (sys_conn, 0L);
    int ret = dbus_bus_acquire_service (sys_conn, service, 0, &error);
    printf ("dbus_bus_acquire_service %d %s\n", ret, error.message);
    dbus_error_free(&error);
    vtable.unregister_function = 0L; //cb_unregister_function;
    vtable.message_function = cb_message_function;
    dbus_connection_register_object_path (sys_conn, object_path, &vtable, 0L);
    dbus_connection_set_exit_on_disconnect (sys_conn, false);
    dbus_connection_add_filter (sys_conn, filter_func, 0L /*data*/, NULL);

    DBusMessage *msg = dbus_message_new_method_call (
            DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, 
            DBUS_PATH_ORG_FREEDESKTOP_DBUS, 
            DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 
            "AddMatch");
    dbus_message_append_args (msg, DBUS_TYPE_STRING, "type='signal'",DBUS_TYPE_INVALID);
    dbus_message_set_no_reply (msg, TRUE);
    dbus_connection_send (sys_conn, msg, NULL);
    dbus_connection_flush (sys_conn);
    dbus_message_unref (msg);

    signal (SIGINT, signal_int);
    g_timeout_add (500, cb_checkInteruptTimer, 0L);
    if (argc > 1) {
        bt_address = g_strdup (argv[1]);
        g_timeout_add (0, cb_connect, 0L);
        if (argc > 2)
            bt_pin = g_strdup (argv[2]);
    } else
        g_timeout_add (0, cb_scan, 0L);
    g_main_loop_run (g_event_loop);
    msg = dbus_message_new_method_call (
            DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
            DBUS_PATH_ORG_FREEDESKTOP_DBUS,
            DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
            "RemoveMatch");
    dbus_message_append_args (msg, DBUS_TYPE_STRING, "type='signal'", DBUS_TYPE_INVALID);
    dbus_message_set_no_reply (msg, TRUE);
    dbus_connection_send (sys_conn, msg, NULL);
    dbus_message_unref (msg);
    dbus_connection_remove_filter (sys_conn, filter_func, 0L /*data*/);
    dbus_connection_unregister_object_path(sys_conn, object_path);
    dbus_connection_disconnect (sys_conn);
    return 0;
}

_______________________________________________
maemo-developers mailing list
[email protected]
https://maemo.org/mailman/listinfo/maemo-developers

Reply via email to