summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-07-21 09:33:59 +0200
committerWim Taymans <wtaymans@redhat.com>2014-07-21 09:33:59 +0200
commitfc7cc92a00d52be9de01c82566d07c66bee27fee (patch)
tree16ef2e1431e2e5c0760182f6caf4e144896397cb
first test
Registers new profile, negotiates SLC
-rwxr-xr-xcompile1
-rw-r--r--make-hsp-ag.c201
2 files changed, 202 insertions, 0 deletions
diff --git a/compile b/compile
new file mode 100755
index 0000000..4159fae
--- /dev/null
+++ b/compile
@@ -0,0 +1 @@
+gcc `pkg-config --cflags --libs gio-2.0` -o make-hsp-ag make-hsp-ag.c
diff --git a/make-hsp-ag.c b/make-hsp-ag.c
new file mode 100644
index 0000000..e4c5d01
--- /dev/null
+++ b/make-hsp-ag.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2014 Wim Taymans <wim.taymans@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gio/gio.h>
+
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GDBusNodeInfo *introspection_data = NULL;
+
+static GDBusProxy *manager;
+
+/* Introspection data for the service we are exporting */
+static const gchar introspection_xml[] =
+ "<node>"
+ " <interface name='org.bluez.Profile1'>"
+ " <method name='Release'>"
+ " </method>"
+ " <method name='Cancel'>"
+ " </method>"
+ " <method name='RequestDisconnection'>"
+ " <arg type='o' name='device' direction='in'/>"
+ " </method>"
+ " <method name='NewConnection'>"
+ " <arg type='o' name='device' direction='in'/>"
+ " <arg type='h' name='fd' direction='in'/>"
+ " <arg type='a{sv}' name='opts' direction='in'/>"
+ " </method>"
+ " </interface>"
+ "</node>";
+
+static gboolean
+my_io_cb (GIOChannel *source, GIOCondition condition, gpointer data)
+{
+ gchar buf[512];
+ GIOStatus st;
+
+ g_print ("condition %d\n", condition);
+
+ if (condition & G_IO_IN) {
+ gint fd = g_io_channel_unix_get_fd (source);
+ gsize length;
+
+ g_print ("we can read\n", condition);
+
+ g_io_channel_read_chars (source, buf, 512, &length, NULL);
+ buf[length] = 0;
+ g_print ("%d %s\n", length, buf);
+
+ if (g_str_has_prefix (buf, "AT+BRSF=")) {
+ write (fd, "+BRSF:254\r\n", 11);
+ write (fd, "OK\r\n", 3);
+ }
+ else if (g_str_has_prefix (buf, "AT+CIND=?")) {
+ write (fd, "+CIND:254\r\n", 11);
+ write (fd, "OK\r\n", 3);
+ }
+ else if (g_str_has_prefix (buf, "AT+CIND?")) {
+ write (fd, "+CIND:254\r\n", 11);
+ write (fd, "OK\r\n", 3);
+ }
+ else if (g_str_has_prefix (buf, "AT+CMER=")) {
+ write (fd, "OK\r\n", 3);
+ }
+ else {
+ write (fd, "OK\r\n", 3);
+ }
+ }
+ return TRUE;
+}
+
+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)
+{
+
+ if (g_strcmp0 (method_name, "Release") == 0) {
+ g_print ("Release\n");
+ } else if (g_strcmp0 (method_name, "Cancel") == 0) {
+ g_print ("Cancel\n");
+ } else if (g_strcmp0 (method_name, "RequestDisconnection") == 0) {
+ g_print ("RequestDisconnection\n");
+ } else if (g_strcmp0 (method_name, "NewConnection") == 0) {
+ gint fd;
+ gchar *obj;
+ GDBusMessage *message;
+ GUnixFDList * fdlist;
+ GIOChannel *channel;
+ gsize written;
+
+ g_variant_get (parameters, "(oha{sv})",
+ &obj, &fd, NULL);
+
+ message = g_dbus_method_invocation_get_message (invocation);
+ fdlist = g_dbus_message_get_unix_fd_list (message);
+ fd = g_unix_fd_list_get (fdlist, fd, NULL);
+
+ g_print ("NewConnection %s %d\n", obj, fd);
+
+ channel = g_io_channel_unix_new (fd);
+ g_io_add_watch (channel, G_IO_IN, my_io_cb, NULL);
+ } else
+ g_print ("%s\n", method_name);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+}
+
+/* for now */
+static const GDBusInterfaceVTable interface_vtable =
+{
+ handle_method_call,
+ NULL,
+ NULL
+};
+
+int
+main (int argc, char *argv[])
+{
+ GDBusConnection * connection;
+ GError *error = NULL;
+ guint owner_id;
+ GMainLoop *loop;
+ guint registration_id;
+
+ g_print ("connecting to system bus\n");
+ connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (error != NULL) {
+ g_printerr ("error getting bus: %s", error->message);
+ return -1;
+ }
+
+ g_print ("making proxy for ProfileManager1\n");
+ manager = g_dbus_proxy_new_sync (connection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL, "org.bluez", "/org/bluez", "org.bluez.ProfileManager1",
+ NULL, &error);
+ if (error != NULL) {
+ g_printerr ("error getting ProfileManager1: %s", error->message);
+ return -1;
+ }
+
+ introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+ g_assert (introspection_data != NULL);
+
+ registration_id = g_dbus_connection_register_object (connection,
+ "/org/myorg/MyObject",
+ introspection_data->interfaces[0],
+ &interface_vtable,
+ NULL,
+ NULL, /* user_data_free_func */
+ NULL); /* GError** */
+ g_assert (registration_id > 0);
+
+ g_print ("Register profile\n");
+ g_dbus_proxy_call_sync (manager,
+ "RegisterProfile",
+ g_variant_new ("(osa{sv})",
+ "/org/myorg/MyObject",
+ "0000111f-0000-1000-8000-00805f9b34fb", NULL),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (error) {
+ g_printerr ("error registering %s\n", error->message);
+ }
+ g_print ("Profile registered\n");
+
+ g_print ("going into mainloop\n");
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+ g_print ("exit mainloop\n");
+
+ g_bus_unown_name (owner_id);
+
+ g_dbus_node_info_unref (introspection_data);
+
+ return 0;
+}