diff --git a/attrib/client.c b/attrib/client.c
index 29cb34a..7f0dac4 100644
--- a/attrib/client.c
+++ b/attrib/client.c
char *path;
GSList *chars;
GSList *watchers;
- gboolean listen;
};
struct characteristic {
}
}
-static void attrib_destroy(gpointer user_data)
-{
- struct gatt_service *gatt = user_data;
-
- gatt->attrib = NULL;
-}
-
-static void attrib_disconnect(gpointer user_data)
-{
- struct gatt_service *gatt = user_data;
-
- /* Remote initiated disconnection only */
- g_attrib_unref(gatt->attrib);
-}
-
-static void connect_cb(GIOChannel *chan, GError *gerr, gpointer user_data)
-{
- struct gatt_service *gatt = user_data;
-
- if (gerr) {
- error("%s", gerr->message);
- goto fail;
- }
-
- if (gatt->attrib == NULL)
- return;
-
- /* Listen mode: used for notification and indication */
- if (gatt->listen == TRUE) {
- g_attrib_register(gatt->attrib,
- ATT_OP_HANDLE_NOTIFY,
- events_handler, gatt, NULL);
- g_attrib_register(gatt->attrib,
- ATT_OP_HANDLE_IND,
- events_handler, gatt, NULL);
- return;
- }
-
- return;
-fail:
- g_attrib_unref(gatt->attrib);
-}
-
-static int l2cap_connect(struct gatt_service *gatt, GError **gerr,
- gboolean listen)
-{
- bdaddr_t sba, dba;
- GIOChannel *io;
-
- if (gatt->attrib != NULL) {
- gatt->attrib = g_attrib_ref(gatt->attrib);
- gatt->listen = listen;
- return 0;
- }
-
- /*
- * FIXME: If the service doesn't support Client Characteristic
- * Configuration it is necessary to poll the server from time
- * to time checking for modifications.
- */
- gatt_get_address(gatt, &sba, &dba);
- if (gatt->psm < 0)
- io = bt_io_connect(BT_IO_L2CAP, connect_cb, gatt, NULL, gerr,
- BT_IO_OPT_SOURCE_BDADDR, &sba,
- BT_IO_OPT_DEST_BDADDR, &dba,
- BT_IO_OPT_CID, ATT_CID,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
- BT_IO_OPT_INVALID);
- else
- io = bt_io_connect(BT_IO_L2CAP, connect_cb, gatt, NULL, gerr,
- BT_IO_OPT_SOURCE_BDADDR, &sba,
- BT_IO_OPT_DEST_BDADDR, &dba,
- BT_IO_OPT_PSM, gatt->psm,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
- BT_IO_OPT_INVALID);
- if (!io)
- return -1;
-
- gatt->attrib = g_attrib_new(io);
- g_io_channel_unref(io);
- gatt->listen = listen;
-
- g_attrib_set_destroy_function(gatt->attrib, attrib_destroy, gatt);
- g_attrib_set_disconnect_function(gatt->attrib, attrib_disconnect,
- gatt);
-
- return 0;
-}
-
static DBusMessage *register_watcher(DBusConnection *conn,
DBusMessage *msg, void *data)
{
const char *sender = dbus_message_get_sender(msg);
struct gatt_service *gatt = data;
struct watcher *watcher;
- GError *gerr = NULL;
char *path;
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
return btd_error_invalid_args(msg);
- if (l2cap_connect(gatt, &gerr, TRUE) < 0) {
- DBusMessage *reply = btd_error_failed(msg, gerr->message);
- g_error_free(gerr);
- return reply;
- }
-
watcher = g_new0(struct watcher, 1);
watcher->name = g_strdup(sender);
watcher->gatt = gatt;
{
struct gatt_service *gatt = chr->gatt;
DBusMessageIter sub;
- GError *gerr = NULL;
uint8_t *value;
int len;
+ if (gatt->attrib == NULL)
+ return btd_error_not_connected(msg);
+
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
dbus_message_iter_get_element_type(iter) != DBUS_TYPE_BYTE)
return btd_error_invalid_args(msg);
dbus_message_iter_get_fixed_array(&sub, &value, &len);
- if (l2cap_connect(gatt, &gerr, FALSE) < 0) {
- DBusMessage *reply = btd_error_failed(msg, gerr->message);
- g_error_free(gerr);
- return reply;
- }
-
gatt_write_cmd(gatt->attrib, chr->handle, value, len, NULL, NULL);
characteristic_set_value(chr, value, len);
struct gatt_service *gatt = data;
struct att_primary *prim = gatt->prim;
struct query_data *qchr;
- GError *gerr = NULL;
- if (l2cap_connect(gatt, &gerr, FALSE) < 0) {
- DBusMessage *reply = btd_error_failed(msg, gerr->message);
- g_error_free(gerr);
- return reply;
- }
+ if (gatt->attrib == NULL)
+ return btd_error_not_connected(msg);
qchr = g_new0(struct query_data, 1);
qchr->gatt = gatt;
struct gatt_service *gatt = user_data;
gatt->attrib = attrib;
+
+ g_attrib_register(gatt->attrib, ATT_OP_HANDLE_NOTIFY,
+ events_handler, gatt, NULL);
+ g_attrib_register(gatt->attrib, ATT_OP_HANDLE_IND,
+ events_handler, gatt, NULL);
}
static void attio_disconnected(gpointer user_data)
gatt->dev = btd_device_ref(device);
gatt->prim = prim;
gatt->psm = psm;
- gatt->listen = FALSE;
gatt->conn = dbus_connection_ref(conn);
gatt->path = g_strdup_printf("%s/service%04x", device_path,
prim->start);