c - Connecting to Bluetooth Device using bluetooth_client_connect_service() - gnome-bluetooth 3.8.2.1 -
i glad if can pointed in right direction community concerning above topic.
i interested in connecting bluetooth devices using gnome-bluetooth
api in ubuntu 14.04 using bluetooth_client_connect_service()
function.
i have tried searching not find results on how use decided read gnome-bluetooth
's source code due insufficient commenting unable understand.
below have done far not errors when try running application yet when double-click on device nothing.
#define agent_path "/org/bluez/agent/wizard" #include <stdio.h> #include <errno.h> #include <ctype.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <getopt.h> #include <sys/param.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <signal.h> #include <math.h> #include <glib.h> //#include <dbus/dbus.h> #include <glib/gi18n.h> #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> #include <bluetooth-chooser.h> #include <bluetooth-client.h> #include <bluetooth-utils.h> #include <bluetooth/bluetooth.h> #include <bluetooth/hci.h> #include <bluetooth/hci_lib.h> #define connect_timeout 3.0 #define agent_path "/org/bluez/agent/wizard" typedef struct { char *path; gtimer *timer; } connectdata; bluetoothclient *client; gtkwidget *selector; gtkwidget *vboxmainlayout; gvalue value = { 0, }; int find_conn(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; int i; if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { perror("can't allocate memory"); exit(1); } cl->dev_id = dev_id; cl->conn_num = 10; ci = cl->conn_info; if (ioctl(s, hcigetconnlist, (void *) cl)) { perror("can't connection list"); exit(1); } (i = 0; < cl->conn_num; i++, ci++) if (!bacmp((bdaddr_t *) arg, &ci->bdaddr)) { free(cl); return 1; } free(cl); return 0; } void cmd_rssi(const char *bt_address) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; int8_t rssi; int dd, dev_id; str2ba(bt_address, &bdaddr); dev_id = hci_for_each_dev(hci_up, find_conn, (long) &bdaddr); if (dev_id < 0) { g_print("\tnot connected.\n"); return; } dd = hci_open_dev(dev_id); if (dd < 0) { perror("hci device open failed"); exit(1); } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("can't allocate memory"); exit(1); } bacpy(&cr->bdaddr, &bdaddr); cr->type = acl_link; if (ioctl(dd, hcigetconninfo, (unsigned long) cr) < 0) { perror("get connection info failed"); exit(1); } if (hci_read_rssi(dd, htobs(cr->conn_info->handle), &rssi, 1000) < 0) { perror("read rssi failed"); exit(1); } g_print("\trssi return value: %d\n", rssi); free(cr); hci_close_dev(dd); } void connect_callback (gobject *source_object, gasyncresult *res, gpointer user_data) { connectdata *data = (connectdata *) user_data; gboolean success; success = bluetooth_client_connect_service_finish (client, res, null); if (success == false && g_timer_elapsed (data->timer, null) < connect_timeout) { bluetooth_client_connect_service (client, data->path, true, null, connect_callback, data); return; } if (success == false) g_print ("\tfailed connect device %s", data->path); else g_print("\n\tconnection successfully.. ha.. i'm tired\n"); g_timer_destroy (data->timer); g_free (data->path); g_free (data); } void create_callback (bluetoothclient *_client, const char *path, const gerror *error, gpointer user_data) { connectdata *data; //compiler throws "implicit declaration" warning here //bluetooth_client_set_trusted(client, path, true); data = g_new0 (connectdata, 1); data->path = g_strdup (path); data->timer = g_timer_new (); bluetooth_client_connect_service (client, path, true, null, connect_callback, data); } void get_device_info(bluetoothchooser *self) { const gchar* result; g_print ("info dumped:\n"); if (bluetooth_chooser_get_selected_device_info (self, "name", &value)) { g_print ("\tname: '%s'\n", g_value_get_string (&value)); g_value_unset (&value); } if (bluetooth_chooser_get_selected_device_info (self, "address", &value)) { g_print ("\taddress: '%s'\n", g_value_get_string (&value)); g_value_unset (&value); } if (bluetooth_chooser_get_selected_device_info (self, "paired", &value)) { result = g_value_get_boolean (&value)? "paired":"unpaired"; g_print ("\tpaired: '%s'\n", result); g_value_unset (&value); } guint type = bluetooth_chooser_get_selected_device_type (self); const gchar *device_type = bluetooth_type_to_string(type); if(type) { g_print("\ttype: '%s'\n", device_type); } if (bluetooth_chooser_get_selected_device_info (self, "connected", &value)) { result = g_value_get_boolean (&value)? "connected":"not connected"; g_print ("\tconnected: '%s'\n", result); g_value_unset (&value); } } /* problem lies here.. how connect detected device * no error message displayed when device double-clicked */ void connect_button_clicked(gtkwidget *widget, gpointer user_data) { const char *path = agent_path; connectdata *data = (connectdata *) user_data; gvalue value = { 0, }; bluetooth_chooser_get_selected_device_info (widget, "address", &value); bluetooth_client_connect_service (client, path, true, null, connect_callback, data); //function rssi value of remote device cmd_rssi(g_value_get_string (&value)); } void create_interface(gtkapplication *app, gpointer user_data) { gtkwidget *frmtopwindow; frmtopwindow = gtk_application_window_new(app); gtk_window_set_title(gtk_window(frmtopwindow), "test"); gtk_window_set_position(gtk_window(frmtopwindow),gtk_win_pos_center); gtk_window_set_default_size(gtk_window(frmtopwindow),200,400); selector = bluetooth_chooser_new(); g_object_set(selector, "show-searching", true, "show-device-type", false, "show-pairing" , true, "show-device-category", false, null); client = bluetooth_client_new(); vboxmainlayout = gtk_box_new(gtk_orientation_vertical, 3); g_object_set(vboxmainlayout, "width-request", 190, "height-request", 300, null); gtk_container_add(gtk_container(frmtopwindow),selector); /*events , signals*/ /*------------------*/ // when user double-clicks on detected device, try , connect device // , display it's rssi g_signal_connect(g_object(selector),"notify::selected-device-activated",g_callback(connect_button_clicked),client); //when user clicks on detected device, display information device in // standard output g_signal_connect(g_object(selector),"notify::device-selected",g_callback(get_device_info),vboxmainlayout); gtk_widget_show_all(frmtopwindow); } int main(int argc, char** argv) { gtkapplication *app; int status; app = gtk_application_new ("rucst.project.test", g_application_flags_none); g_signal_connect (app, "activate", g_callback (create_interface), null); status = g_application_run (g_application (app), argc, argv); g_object_unref (app); return status; }
in implementation code, have g_signal_connect
function calls shown below:
g_signal_connect(g_object(selector),"notify::selected-device-activated",g_callback(connect_button_clicked),client);
this code expect connect selected detected device when receives double-click signal @ moment nothing happens when double-click on it.
i grateful receive guidance experts.
thank in advance
g_signal_connect(g_object(selector),"notify::selected-device-activated", g_callback(connect_button_clicked),client);
this signal signature used if there property "selected-device-activated" , wanted know when property value changes. in case "selected-device-activated" actual signal should do:
g_signal_connect(g_object(selector),"selected-device-activated", g_callback(callback), client);
the single click version happens work because you've found property want, connecting "notify::device-selected" works (i'd still connect "selected-device-changed" signal consistency instead).
after in connect_button_clicked() connect call uses seems unrelated path device object path... might work instead (although i'm not 100% sure "proxy" field name, i've not used api myself):
gvalue value = { 0, }; if (bluetooth_chooser_get_selected_device_info (bluetooth_chooser (widget), "proxy", &value)) { gdbusproxy *proxy = g_value_get_object (&value); g_print ("connecting %s\n", g_dbus_proxy_get_object_path(proxy)); bluetooth_client_connect_service (client, g_dbus_proxy_get_object_path(proxy), true, null, connect_callback, data); }
note userdata pointers give callbacks wrong: e.g. connect_button_clicked() expects connectdata*
gets bluetoothclient*
.
Comments
Post a Comment