aboutsummaryrefslogtreecommitdiffstats
path: root/attrib/client.c
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2011-07-12 17:28:37 -0300
committerJohan Hedberg <johan.hedberg@intel.com>2011-07-27 10:31:15 +0300
commite4a3edb1110ecd1bca644c39a5968e9f6a6cfa49 (patch)
tree65dc7cfee1305a395b0da2810e431da4c92e47ed /attrib/client.c
parent95bf1f076a607fa84a52d6e48db8f2ac6036fa70 (diff)
downloadbluez-e4a3edb1110ecd1bca644c39a5968e9f6a6cfa49.tar.gz
bluez-e4a3edb1110ecd1bca644c39a5968e9f6a6cfa49.tar.xz
bluez-e4a3edb1110ecd1bca644c39a5968e9f6a6cfa49.zip
Remove implicit connection from generic API
Generic attribute API should not actively manage L2CAP connections. GAttrib instance is notified through registered callbacks. SetProperty or DiscoverCharacteristic now returns NotConnected error if the link is down.
Diffstat (limited to 'attrib/client.c')
-rw-r--r--attrib/client.c121
1 files changed, 10 insertions, 111 deletions
diff --git a/attrib/client.c b/attrib/client.c
index 29cb34ab..7f0dac46 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -72,7 +72,6 @@ struct gatt_service {
char *path;
GSList *chars;
GSList *watchers;
- gboolean listen;
};
struct characteristic {
@@ -289,114 +288,18 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
}
}
-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;
@@ -443,10 +346,12 @@ static DBusMessage *set_value(DBusConnection *conn, DBusMessage *msg,
{
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);
@@ -455,12 +360,6 @@ static DBusMessage *set_value(DBusConnection *conn, DBusMessage *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);
@@ -907,13 +806,9 @@ static DBusMessage *discover_char(DBusConnection *conn, DBusMessage *msg,
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;
@@ -983,6 +878,11 @@ static void attio_connected(GAttrib *attrib, gpointer user_data)
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)
@@ -1006,7 +906,6 @@ static struct gatt_service *primary_register(DBusConnection *conn,
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);