diff --git a/attrib/client.c b/attrib/client.c
index bb6adf8..906d345 100644
--- a/attrib/client.c
+++ b/attrib/client.c
#include <errno.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <glib.h>
#include <bluetooth/bluetooth.h>
diff --git a/audio/avctp.c b/audio/avctp.c
index 2970986..03f3e7f 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
#include <stdlib.h>
#include <stdint.h>
+#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
diff --git a/audio/avdtp.c b/audio/avdtp.c
index eafafc0..d44c504 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
+#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
diff --git a/audio/avrcp.c b/audio/avrcp.c
index d925365..0688ffa 100644
--- a/audio/avrcp.c
+++ b/audio/avrcp.c
#include <stdlib.h>
#include <stdint.h>
+#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
diff --git a/audio/control.c b/audio/control.c
index 187f838..5477c2d 100644
--- a/audio/control.c
+++ b/audio/control.c
#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
#include <glib.h>
#include <dbus/dbus.h>
static unsigned int avctp_id = 0;
struct control {
- struct audio_device *dev;
struct avctp *session;
-
gboolean target;
};
AUDIO_CONTROL_INTERFACE);
}
-void control_update(struct control *control, uint16_t uuid16)
+void control_update(struct control *control, GSList *uuids)
{
- if (uuid16 == AV_REMOTE_TARGET_SVCLASS_ID)
+ if (g_slist_find_custom(uuids, AVRCP_TARGET_UUID, bt_uuid_strcmp))
control->target = TRUE;
}
-struct control *control_init(struct audio_device *dev, uint16_t uuid16)
+struct control *control_init(struct audio_device *dev, GSList *uuids)
{
struct control *control;
AUDIO_CONTROL_INTERFACE, dev->path);
control = g_new0(struct control, 1);
- control->dev = dev;
- control_update(control, uuid16);
+ control_update(control, uuids);
if (!avctp_id)
avctp_id = avctp_add_state_cb(state_changed, NULL);
diff --git a/audio/control.h b/audio/control.h
index 2219e5f..5f4f728 100644
--- a/audio/control.h
+++ b/audio/control.h
#define AUDIO_CONTROL_INTERFACE "org.bluez.Control"
-struct control *control_init(struct audio_device *dev, uint16_t uuid16);
-void control_update(struct control *control, uint16_t uuid16);
+struct control *control_init(struct audio_device *dev, GSList *uuids);
+void control_update(struct control *control, GSList *uuids);
void control_unregister(struct audio_device *dev);
gboolean control_is_active(struct audio_device *dev);
diff --git a/audio/device.c b/audio/device.c
index 9507eac..4952b57 100644
--- a/audio/device.c
+++ b/audio/device.c
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
+#include <stdbool.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <netinet/in.h>
diff --git a/audio/gateway.h b/audio/gateway.h
index 77f5787..6fde445 100644
--- a/audio/gateway.h
+++ b/audio/gateway.h
void gateway_set_state(struct audio_device *dev, gateway_state_t new_state);
void gateway_unregister(struct audio_device *dev);
-struct gateway *gateway_init(struct audio_device *device);
+struct gateway *gateway_init(struct audio_device *dev);
gboolean gateway_is_active(struct audio_device *dev);
gboolean gateway_is_connected(struct audio_device *dev);
int gateway_connect_rfcomm(struct audio_device *dev, GIOChannel *io);
diff --git a/audio/headset.c b/audio/headset.c
index 0ddd134..1ef6c49 100644
--- a/audio/headset.c
+++ b/audio/headset.c
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <signal.h>
#include <string.h>
#include <getopt.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
#include <glib.h>
#include <dbus/dbus.h>
{ }
};
-void headset_update(struct audio_device *dev, uint16_t svc,
- const char *uuidstr)
+void headset_update(struct audio_device *dev, struct headset *headset,
+ GSList *uuids)
{
- struct headset *headset = dev->headset;
const sdp_record_t *record;
- record = btd_device_get_record(dev->btd_dev, uuidstr);
- if (!record)
- return;
-
- switch (svc) {
- case HANDSFREE_SVCLASS_ID:
- if (headset->hfp_handle &&
- (headset->hfp_handle != record->handle)) {
- error("More than one HFP record found on device");
- return;
- }
-
- headset->hfp_handle = record->handle;
- break;
-
- case HEADSET_SVCLASS_ID:
- if (headset->hsp_handle &&
- (headset->hsp_handle != record->handle)) {
- error("More than one HSP record found on device");
- return;
- }
-
- headset->hsp_handle = record->handle;
-
- /* Ignore this record if we already have access to HFP */
- if (headset->hfp_handle)
- return;
-
- break;
+ if (g_slist_find_custom(uuids, HFP_HS_UUID, bt_uuid_strcmp) &&
+ headset->hfp_handle == 0) {
+ record = btd_device_get_record(dev->btd_dev, HFP_HS_UUID);
+ if (record)
+ headset->hfp_handle = record->handle;
+ }
- default:
- DBG("Invalid record passed to headset_update");
- return;
+ if (g_slist_find_custom(uuids, HSP_HS_UUID, bt_uuid_strcmp) &&
+ headset->hsp_handle == 0) {
+ record = btd_device_get_record(dev->btd_dev, HSP_HS_UUID);
+ if (record)
+ headset->hsp_handle = record->handle;
}
}
AUDIO_HEADSET_INTERFACE);
}
-struct headset *headset_init(struct audio_device *dev, uint16_t svc,
- const char *uuidstr)
+struct headset *headset_init(struct audio_device *dev, GSList *uuids,
+ gboolean hfp_enabled)
{
struct headset *hs;
- const sdp_record_t *record;
hs = g_new0(struct headset, 1);
hs->rfcomm_ch = -1;
- hs->search_hfp = server_is_enabled(&dev->src, HANDSFREE_SVCLASS_ID);
-
- record = btd_device_get_record(dev->btd_dev, uuidstr);
- if (!record)
- goto register_iface;
+ hs->search_hfp = hfp_enabled;
- switch (svc) {
- case HANDSFREE_SVCLASS_ID:
- hs->hfp_handle = record->handle;
- break;
-
- case HEADSET_SVCLASS_ID:
- hs->hsp_handle = record->handle;
- break;
+ headset_update(dev, hs, uuids);
- default:
- DBG("Invalid record passed to headset_init");
- g_free(hs);
- return NULL;
- }
-
-register_iface:
if (!g_dbus_register_interface(dev->conn, dev->path,
AUDIO_HEADSET_INTERFACE,
headset_methods, headset_signals, NULL,
return NULL;
}
- DBG("Registered interface %s on path %s",
- AUDIO_HEADSET_INTERFACE, dev->path);
+ DBG("Registered interface %s on path %s", AUDIO_HEADSET_INTERFACE,
+ dev->path);
return hs;
}
diff --git a/audio/headset.h b/audio/headset.h
index 465c2d6..736e4fe 100644
--- a/audio/headset.h
+++ b/audio/headset.h
GIOChannel *headset_get_rfcomm(struct audio_device *dev);
-struct headset *headset_init(struct audio_device *dev, uint16_t svc,
- const char *uuidstr);
+struct headset *headset_init(struct audio_device *dev, GSList *uuids,
+ gboolean hfp_enabled);
void headset_unregister(struct audio_device *dev);
uint32_t headset_config_init(GKeyFile *config);
-void headset_update(struct audio_device *dev, uint16_t svc,
- const char *uuidstr);
+void headset_update(struct audio_device *dev, struct headset *headset,
+ GSList *uuids);
unsigned int headset_config_stream(struct audio_device *dev,
gboolean auto_dc,
diff --git a/audio/manager.c b/audio/manager.c
index 7406a1f..5b34f9b 100644
--- a/audio/manager.c
+++ b/audio/manager.c
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
+#include <stdbool.h>
#include <sys/stat.h>
#include <dirent.h>
#include <ctype.h>
return NULL;
}
-gboolean server_is_enabled(bdaddr_t *src, uint16_t svc)
-{
- switch (svc) {
- case HEADSET_SVCLASS_ID:
- return enabled.headset;
- case HEADSET_AGW_SVCLASS_ID:
- return FALSE;
- case HANDSFREE_SVCLASS_ID:
- return enabled.headset && enabled.hfp;
- case HANDSFREE_AGW_SVCLASS_ID:
- return enabled.gateway;
- case AUDIO_SINK_SVCLASS_ID:
- return enabled.sink;
- case AUDIO_SOURCE_SVCLASS_ID:
- return enabled.source;
- case AV_REMOTE_TARGET_SVCLASS_ID:
- case AV_REMOTE_SVCLASS_ID:
- return enabled.control;
- default:
- return FALSE;
- }
-}
-
-static void handle_uuid(const char *uuidstr, struct audio_device *device)
-{
- uuid_t uuid;
- uint16_t uuid16;
-
- if (bt_string2uuid(&uuid, uuidstr) < 0) {
- error("%s not detected as an UUID-128", uuidstr);
- return;
- }
-
- if (!sdp_uuid128_to_uuid(&uuid) && uuid.type != SDP_UUID16) {
- error("Could not convert %s to a UUID-16", uuidstr);
- return;
- }
-
- uuid16 = uuid.value.uuid16;
-
- if (!server_is_enabled(&device->src, uuid16)) {
- DBG("server not enabled for %s (0x%04x)", uuidstr, uuid16);
- return;
- }
-
- switch (uuid16) {
- case HEADSET_SVCLASS_ID:
- DBG("Found Headset record");
- if (device->headset)
- headset_update(device, uuid16, uuidstr);
- else
- device->headset = headset_init(device, uuid16,
- uuidstr);
- break;
- case HEADSET_AGW_SVCLASS_ID:
- DBG("Found Headset AG record");
- break;
- case HANDSFREE_SVCLASS_ID:
- DBG("Found Handsfree record");
- if (device->headset)
- headset_update(device, uuid16, uuidstr);
- else
- device->headset = headset_init(device, uuid16,
- uuidstr);
- break;
- case HANDSFREE_AGW_SVCLASS_ID:
- DBG("Found Handsfree AG record");
- if (enabled.gateway && (device->gateway == NULL))
- device->gateway = gateway_init(device);
- break;
- case AUDIO_SINK_SVCLASS_ID:
- DBG("Found Audio Sink");
- if (device->sink == NULL)
- device->sink = sink_init(device);
- break;
- case AUDIO_SOURCE_SVCLASS_ID:
- DBG("Found Audio Source");
- if (device->source == NULL)
- device->source = source_init(device);
- break;
- case AV_REMOTE_SVCLASS_ID:
- case AV_REMOTE_TARGET_SVCLASS_ID:
- DBG("Found AV %s", uuid16 == AV_REMOTE_SVCLASS_ID ?
- "Remote" : "Target");
- if (device->control)
- control_update(device->control, uuid16);
- else
- device->control = control_init(device, uuid16);
-
- if (device->sink && sink_is_active(device))
- avrcp_connect(device);
- break;
- default:
- DBG("Unrecognized UUID: 0x%04X", uuid16);
- break;
- }
-}
-
static sdp_record_t *hsp_ag_record(uint8_t ch)
{
sdp_list_t *svclass_id, *pfseq, *apseq, *root;
return -1;
}
-static int audio_probe(struct btd_device *device, GSList *uuids)
+static struct audio_device *get_audio_dev(struct btd_device *device)
{
struct btd_adapter *adapter = device_get_adapter(device);
bdaddr_t src, dst;
- struct audio_device *audio_dev;
adapter_get_address(adapter, &src);
device_get_address(device, &dst, NULL);
- audio_dev = manager_get_device(&src, &dst, TRUE);
+ return manager_get_device(&src, &dst, TRUE);
+}
+
+static void audio_remove(struct btd_device *device)
+{
+ struct audio_device *dev;
+
+ dev = get_audio_dev(device);
+ if (!dev)
+ return;
+
+ devices = g_slist_remove(devices, dev);
+ audio_device_unregister(dev);
+}
+
+static int hs_probe(struct btd_device *device, GSList *uuids)
+{
+ struct audio_device *audio_dev;
+
+ audio_dev = get_audio_dev(device);
if (!audio_dev) {
DBG("unable to get a device object");
return -1;
}
- g_slist_foreach(uuids, (GFunc) handle_uuid, audio_dev);
+ if (audio_dev->headset)
+ headset_update(audio_dev, audio_dev->headset, uuids);
+ else
+ audio_dev->headset = headset_init(audio_dev, uuids,
+ enabled.hfp);
return 0;
}
-static void audio_remove(struct btd_device *device)
+static int ag_probe(struct btd_device *device, GSList *uuids)
{
- struct audio_device *dev;
- const char *path;
+ struct audio_device *audio_dev;
- path = device_get_path(device);
+ audio_dev = get_audio_dev(device);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
- dev = manager_find_device(path, NULL, NULL, NULL, FALSE);
- if (!dev)
- return;
+ if (!audio_dev->gateway)
+ return -EALREADY;
- devices = g_slist_remove(devices, dev);
+ audio_dev->gateway = gateway_init(audio_dev);
- audio_device_unregister(dev);
+ return 0;
+}
+
+static int a2dp_probe(struct btd_device *device, GSList *uuids)
+{
+ struct audio_device *audio_dev;
+
+ audio_dev = get_audio_dev(device);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+ if (g_slist_find_custom(uuids, A2DP_SINK_UUID, bt_uuid_strcmp) &&
+ audio_dev->sink == NULL)
+ audio_dev->sink = sink_init(audio_dev);
+
+ if (g_slist_find_custom(uuids, A2DP_SOURCE_UUID, bt_uuid_strcmp) &&
+ audio_dev->source == NULL)
+ audio_dev->source = source_init(audio_dev);
+
+ return 0;
+}
+
+static int avrcp_probe(struct btd_device *device, GSList *uuids)
+{
+ struct audio_device *audio_dev;
+
+ audio_dev = get_audio_dev(device);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+
+ if (audio_dev->control)
+ control_update(audio_dev->control, uuids);
+ else
+ audio_dev->control = control_init(audio_dev, uuids);
+
+ if (audio_dev->sink && sink_is_active(audio_dev))
+ avrcp_connect(audio_dev);
+
+ return 0;
}
static struct audio_adapter *audio_adapter_ref(struct audio_adapter *adp)
audio_adapter_unref(adp);
}
-static struct btd_device_driver audio_driver = {
- .name = "audio",
- .uuids = BTD_UUIDS(HSP_HS_UUID, HFP_HS_UUID, HSP_AG_UUID, HFP_AG_UUID,
- ADVANCED_AUDIO_UUID, A2DP_SOURCE_UUID, A2DP_SINK_UUID,
- AVRCP_TARGET_UUID, AVRCP_REMOTE_UUID),
- .probe = audio_probe,
- .remove = audio_remove,
-};
+static struct btd_profile headset_profile = {
+ .name = "audio-headset",
-static struct btd_adapter_driver headset_server_driver = {
- .name = "audio-headset",
- .probe = headset_server_probe,
- .remove = headset_server_remove,
+ .remote_uuids = BTD_UUIDS(HSP_HS_UUID, HFP_HS_UUID),
+ .device_probe = hs_probe,
+ .device_remove = audio_remove,
+
+ .adapter_probe = headset_server_probe,
+ .adapter_remove = headset_server_remove,
};
-static struct btd_adapter_driver gateway_server_driver = {
- .name = "audio-gateway",
- .probe = gateway_server_probe,
- .remove = gateway_server_remove,
+static struct btd_profile gateway_profile = {
+ .name = "audio-gateway",
+
+ .remote_uuids = BTD_UUIDS(HSP_AG_UUID, HFP_AG_UUID),
+ .device_probe = ag_probe,
+ .device_remove = audio_remove,
+
+ .adapter_probe = gateway_server_probe,
+ .adapter_remove = gateway_server_remove,
};
-static struct btd_adapter_driver a2dp_server_driver = {
- .name = "audio-a2dp",
- .probe = a2dp_server_probe,
- .remove = a2dp_server_remove,
+static struct btd_profile a2dp_profile = {
+ .name = "audio-a2dp",
+
+ .remote_uuids = BTD_UUIDS(A2DP_SOURCE_UUID, A2DP_SINK_UUID),
+ .device_probe = a2dp_probe,
+ .device_remove = audio_remove,
+
+ .adapter_probe = a2dp_server_probe,
+ .adapter_remove = a2dp_server_remove,
};
-static struct btd_adapter_driver avrcp_server_driver = {
- .name = "audio-control",
- .probe = avrcp_server_probe,
- .remove = avrcp_server_remove,
+static struct btd_profile avrcp_profile = {
+ .name = "audio-avrcp",
+
+ .remote_uuids = BTD_UUIDS(AVRCP_TARGET_UUID, AVRCP_REMOTE_UUID),
+ .device_probe = avrcp_probe,
+ .device_remove = audio_remove,
+
+ .adapter_probe = avrcp_server_probe,
+ .adapter_remove = avrcp_server_remove,
};
-static struct btd_adapter_driver media_server_driver = {
+static struct btd_adapter_driver media_driver = {
.name = "media",
.probe = media_server_probe,
.remove = media_server_remove,
max_connected_headsets = i;
proceed:
- if (enabled.control)
- btd_register_adapter_driver(&avrcp_server_driver);
-
- if (enabled.media)
- btd_register_adapter_driver(&media_server_driver);
-
if (enabled.headset)
- btd_register_adapter_driver(&headset_server_driver);
+ btd_profile_register(&headset_profile);
if (enabled.gateway)
- btd_register_adapter_driver(&gateway_server_driver);
+ btd_profile_register(&gateway_profile);
if (enabled.source || enabled.sink)
- btd_register_adapter_driver(&a2dp_server_driver);
+ btd_profile_register(&a2dp_profile);
- btd_register_device_driver(&audio_driver);
+ if (enabled.control)
+ btd_profile_register(&avrcp_profile);
+
+ if (enabled.media)
+ btd_register_adapter_driver(&media_driver);
*enable_sco = (enabled.gateway || enabled.headset);
config = NULL;
}
- if (enabled.media)
- btd_unregister_adapter_driver(&media_server_driver);
-
if (enabled.headset)
- btd_unregister_adapter_driver(&headset_server_driver);
+ btd_profile_unregister(&headset_profile);
if (enabled.gateway)
- btd_unregister_adapter_driver(&gateway_server_driver);
+ btd_profile_unregister(&gateway_profile);
if (enabled.source || enabled.sink)
- btd_unregister_adapter_driver(&a2dp_server_driver);
+ btd_profile_unregister(&a2dp_profile);
if (enabled.control)
- btd_unregister_adapter_driver(&avrcp_server_driver);
+ btd_profile_unregister(&avrcp_profile);
- btd_unregister_device_driver(&audio_driver);
+ if (enabled.media)
+ btd_unregister_adapter_driver(&media_driver);
}
GSList *manager_find_devices(const char *path,
diff --git a/audio/manager.h b/audio/manager.h
index f1d3021..1320c71 100644
--- a/audio/manager.h
+++ b/audio/manager.h
gboolean *enable_sco);
void audio_manager_exit(void);
-gboolean server_is_enabled(bdaddr_t *src, uint16_t svc);
-
struct audio_device *manager_find_device(const char *path,
const bdaddr_t *src,
const bdaddr_t *dst,
diff --git a/audio/sink.c b/audio/sink.c
index 64e38f4..53a0b80 100644
--- a/audio/sink.c
+++ b/audio/sink.c
#endif
#include <stdint.h>
+#include <stdbool.h>
#include <errno.h>
#include <bluetooth/bluetooth.h>
diff --git a/audio/source.c b/audio/source.c
index 6dabd1b..e4ba211 100644
--- a/audio/source.c
+++ b/audio/source.c
#endif
#include <stdint.h>
+#include <stdbool.h>
#include <errno.h>
#include <bluetooth/bluetooth.h>
diff --git a/plugins/adaptername.c b/plugins/adaptername.c
index d3341b5..c109b44 100644
--- a/plugins/adaptername.c
+++ b/plugins/adaptername.c
#endif
#include <stdlib.h>
+#include <stdbool.h>
#include <unistd.h>
#include <errno.h>
diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index ef2a7e7..a7259ba 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include <errno.h>
#include <gdbus.h>
diff --git a/plugins/wiimote.c b/plugins/wiimote.c
index 9c69c6d..337d408 100644
--- a/plugins/wiimote.c
+++ b/plugins/wiimote.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include <bluetooth/bluetooth.h>
#include <glib.h>
diff --git a/profiles/deviceinfo/deviceinfo.c b/profiles/deviceinfo/deviceinfo.c
index ca849ad..e7c442f 100644
--- a/profiles/deviceinfo/deviceinfo.c
+++ b/profiles/deviceinfo/deviceinfo.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include <glib.h>
#include <bluetooth/uuid.h>
diff --git a/profiles/deviceinfo/manager.c b/profiles/deviceinfo/manager.c
index 1d59918..914ec40 100644
--- a/profiles/deviceinfo/manager.c
+++ b/profiles/deviceinfo/manager.c
#include <glib.h>
#include <errno.h>
+#include <stdbool.h>
#include <bluetooth/uuid.h>
#include "adapter.h"
deviceinfo_unregister(device);
}
-static struct btd_device_driver deviceinfo_device_driver = {
- .name = "deviceinfo-driver",
- .uuids = BTD_UUIDS(DEVICE_INFORMATION_UUID),
- .probe = deviceinfo_driver_probe,
- .remove = deviceinfo_driver_remove
+static struct btd_profile deviceinfo_profile = {
+ .name = "deviceinfo",
+ .remote_uuids = BTD_UUIDS(DEVICE_INFORMATION_UUID),
+ .device_probe = deviceinfo_driver_probe,
+ .device_remove = deviceinfo_driver_remove
};
int deviceinfo_manager_init(void)
{
- return btd_register_device_driver(&deviceinfo_device_driver);
+ return btd_profile_register(&deviceinfo_profile);
}
void deviceinfo_manager_exit(void)
{
- btd_unregister_device_driver(&deviceinfo_device_driver);
+ btd_profile_unregister(&deviceinfo_profile);
}
diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 67cc5ae..ddd4e70 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include <glib.h>
#include <bluetooth/uuid.h>
diff --git a/profiles/gatt/manager.c b/profiles/gatt/manager.c
index 0702d26..9c5ea14 100644
--- a/profiles/gatt/manager.c
+++ b/profiles/gatt/manager.c
#include <glib.h>
#include <errno.h>
+#include <stdbool.h>
#include <bluetooth/uuid.h>
#include "adapter.h"
gas_unregister(device);
}
-static struct btd_device_driver gatt_device_driver = {
- .name = "gap-gatt-driver",
- .uuids = BTD_UUIDS(GAP_UUID, GATT_UUID),
- .probe = gatt_driver_probe,
- .remove = gatt_driver_remove
+static struct btd_profile gatt_profile = {
+ .name = "gap-gatt-profile",
+ .remote_uuids = BTD_UUIDS(GAP_UUID, GATT_UUID),
+ .device_probe = gatt_driver_probe,
+ .device_remove = gatt_driver_remove
};
int gatt_manager_init(void)
{
- return btd_register_device_driver(&gatt_device_driver);
+ return btd_profile_register(&gatt_profile);
}
void gatt_manager_exit(void)
{
- btd_unregister_device_driver(&gatt_device_driver);
+ btd_profile_unregister(&gatt_profile);
}
diff --git a/profiles/health/hdp.c b/profiles/health/hdp.c
index b54733b..5d62d35 100644
--- a/profiles/health/hdp.c
+++ b/profiles/health/hdp.c
#include <stdlib.h>
#include <stdint.h>
+#include <stdbool.h>
#include <sdpd.h>
#include <unistd.h>
diff --git a/profiles/health/hdp_manager.c b/profiles/health/hdp_manager.c
index ffaed5d..416286e 100644
--- a/profiles/health/hdp_manager.c
+++ b/profiles/health/hdp_manager.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
#include <bluetooth/uuid.h>
hdp_adapter_unregister(adapter);
}
-static struct btd_adapter_driver hdp_adapter_driver = {
- .name = "hdp-adapter-driver",
- .probe = hdp_adapter_probe,
- .remove = hdp_adapter_remove,
-};
-
static int hdp_driver_probe(struct btd_device *device, GSList *uuids)
{
return hdp_device_register(connection, device);
hdp_device_unregister(device);
}
-static struct btd_device_driver hdp_device_driver = {
- .name = "hdp-device-driver",
- .uuids = BTD_UUIDS(HDP_UUID, HDP_SOURCE_UUID, HDP_SINK_UUID),
- .probe = hdp_driver_probe,
- .remove = hdp_driver_remove
+static struct btd_profile hdp_profile = {
+ .name = "hdp-profile",
+ .remote_uuids = BTD_UUIDS(HDP_UUID, HDP_SOURCE_UUID, HDP_SINK_UUID),
+
+ .device_probe = hdp_driver_probe,
+ .device_remove = hdp_driver_remove,
+
+ .adapter_probe = hdp_adapter_probe,
+ .adapter_remove = hdp_adapter_remove,
};
int hdp_manager_init(DBusConnection *conn)
return -1;
connection = dbus_connection_ref(conn);
- btd_register_adapter_driver(&hdp_adapter_driver);
- btd_register_device_driver(&hdp_device_driver);
+
+ btd_profile_register(&hdp_profile);
return 0;
}
void hdp_manager_exit(void)
{
- btd_unregister_device_driver(&hdp_device_driver);
- btd_unregister_adapter_driver(&hdp_adapter_driver);
+ btd_profile_unregister(&hdp_profile);
+
hdp_manager_stop();
dbus_connection_unref(connection);
diff --git a/profiles/health/hdp_util.c b/profiles/health/hdp_util.c
index 744e390..761e07d 100644
--- a/profiles/health/hdp_util.c
+++ b/profiles/health/hdp_util.c
#endif
#include <stdint.h>
+#include <stdbool.h>
#include <glib.h>
diff --git a/profiles/input/device.c b/profiles/input/device.c
index e3f9dac..f1e1af0 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
#endif
#include <stdlib.h>
+#include <stdbool.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
diff --git a/profiles/input/fakehid.c b/profiles/input/fakehid.c
index 3be1489..d9af2dd 100644
--- a/profiles/input/fakehid.c
+++ b/profiles/input/fakehid.c
#include <config.h>
#endif
+#include <stdbool.h>
#include <fcntl.h>
#include <unistd.h>
diff --git a/profiles/input/hog_device.c b/profiles/input/hog_device.c
index 000f173..664c52b 100644
--- a/profiles/input/hog_device.c
+++ b/profiles/input/hog_device.c
#endif
#include <stdlib.h>
+#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
diff --git a/profiles/input/hog_manager.c b/profiles/input/hog_manager.c
index c544e79..6d971fa 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
#endif
#include <errno.h>
+#include <stdbool.h>
#include "log.h"
#include "../src/adapter.h"
hog_device_unregister(path);
}
-static struct btd_device_driver hog_driver = {
- .name = "input-hog",
- .uuids = BTD_UUIDS(HOG_UUID),
- .probe = hog_device_probe,
- .remove = hog_device_remove,
+static struct btd_profile hog_profile = {
+ .name = "input-hog",
+ .remote_uuids = BTD_UUIDS(HOG_UUID),
+ .device_probe = hog_device_probe,
+ .device_remove = hog_device_remove,
};
static int hog_manager_init(void)
{
- return btd_register_device_driver(&hog_driver);
+ return btd_profile_register(&hog_profile);
}
static void hog_manager_exit(void)
{
- btd_unregister_device_driver(&hog_driver);
+ btd_profile_register(&hog_profile);
}
static int hog_init(void)
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index add9789..2f9e087 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
#endif
#include <errno.h>
+#include <stdbool.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
btd_adapter_unref(adapter);
}
-static struct btd_device_driver input_hid_driver = {
- .name = "input-hid",
- .uuids = BTD_UUIDS(HID_UUID),
- .probe = hid_device_probe,
- .remove = hid_device_remove,
-};
+static struct btd_profile input_profile = {
+ .name = "input-hid",
+ .remote_uuids = BTD_UUIDS(HID_UUID),
+
+ .device_probe = hid_device_probe,
+ .device_remove = hid_device_remove,
-static struct btd_device_driver input_headset_driver = {
- .name = "input-headset",
- .uuids = BTD_UUIDS(HSP_HS_UUID),
- .probe = headset_probe,
- .remove = headset_remove,
+ .adapter_probe = hid_server_probe,
+ .adapter_remove = hid_server_remove,
};
-static struct btd_adapter_driver input_server_driver = {
- .name = "input-server",
- .probe = hid_server_probe,
- .remove = hid_server_remove,
+static struct btd_profile input_headset_profile = {
+ .name = "input-headset",
+ .remote_uuids = BTD_UUIDS(HSP_HS_UUID),
+
+ .device_probe = headset_probe,
+ .device_remove = headset_remove,
};
int input_manager_init(DBusConnection *conn, GKeyFile *config)
connection = dbus_connection_ref(conn);
- btd_register_adapter_driver(&input_server_driver);
-
- btd_register_device_driver(&input_hid_driver);
- btd_register_device_driver(&input_headset_driver);
+ btd_profile_register(&input_profile);
+ btd_profile_register(&input_headset_profile);
return 0;
}
void input_manager_exit(void)
{
- btd_unregister_device_driver(&input_hid_driver);
- btd_unregister_device_driver(&input_headset_driver);
-
- btd_unregister_adapter_driver(&input_server_driver);
+ btd_profile_unregister(&input_profile);
+ btd_profile_unregister(&input_headset_profile);
dbus_connection_unref(connection);
-
connection = NULL;
}
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 40b360f..dba448e 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
#endif
#include <stdio.h>
+#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>
{ }
};
-void connection_unregister(const char *path, uint16_t id)
+void connection_unregister(const char *path)
{
struct network_peer *peer;
- struct network_conn *nc;
peer = find_peer(peers, path);
if (!peer)
return;
- nc = find_connection(peer->connections, id);
- if (!nc)
- return;
-
- peer->connections = g_slist_remove(peer->connections, nc);
- connection_free(nc);
- if (peer->connections)
- return;
+ g_slist_free_full(peer->connections, connection_free);
+ peer->connections = NULL;
g_dbus_unregister_interface(connection, path, NETWORK_PEER_INTERFACE);
}
diff --git a/profiles/network/connection.h b/profiles/network/connection.h
index 5ea4147..a5e0e61 100644
--- a/profiles/network/connection.h
+++ b/profiles/network/connection.h
void connection_exit(void);
int connection_register(struct btd_device *device, const char *path,
bdaddr_t *src, bdaddr_t *dst, uint16_t id);
-void connection_unregister(const char *path, uint16_t id);
+void connection_unregister(const char *path);
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 7fcd8f0..ac36406 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include <bluetooth/bluetooth.h>
#include <bluetooth/bnep.h>
#include <bluetooth/sdp.h>
conf_security ? "true" : "false");
}
-static int network_probe(struct btd_device *device, GSList *uuids, uint16_t id)
+static int network_probe(struct btd_device *device, GSList *uuids)
{
struct btd_adapter *adapter = device_get_adapter(device);
const gchar *path = device_get_path(device);
adapter_get_address(adapter, &src);
device_get_address(device, &dst, NULL);
- return connection_register(device, path, &src, &dst, id);
+ if (g_slist_find_custom(uuids, PANU_UUID, bt_uuid_strcmp))
+ connection_register(device, path, &src, &dst, BNEP_SVC_PANU);
+ if (g_slist_find_custom(uuids, GN_UUID, bt_uuid_strcmp))
+ connection_register(device, path, &src, &dst, BNEP_SVC_GN);
+ if (g_slist_find_custom(uuids, NAP_UUID, bt_uuid_strcmp))
+ connection_register(device, path, &src, &dst, BNEP_SVC_NAP);
+
+ return 0;
}
-static void network_remove(struct btd_device *device, uint16_t id)
+static void network_remove(struct btd_device *device)
{
const gchar *path = device_get_path(device);
DBG("path %s", path);
- connection_unregister(path, id);
-}
-
-static int panu_probe(struct btd_device *device, GSList *uuids)
-{
- return network_probe(device, uuids, BNEP_SVC_PANU);
-}
-
-static void panu_remove(struct btd_device *device)
-{
- network_remove(device, BNEP_SVC_PANU);
-}
-
-static int gn_probe(struct btd_device *device, GSList *uuids)
-{
- return network_probe(device, uuids, BNEP_SVC_GN);
-}
-
-static void gn_remove(struct btd_device *device)
-{
- network_remove(device, BNEP_SVC_GN);
-}
-
-static int nap_probe(struct btd_device *device, GSList *uuids)
-{
- return network_probe(device, uuids, BNEP_SVC_NAP);
-}
-
-static void nap_remove(struct btd_device *device)
-{
- network_remove(device, BNEP_SVC_NAP);
+ connection_unregister(path);
}
static int network_server_probe(struct btd_adapter *adapter)
server_unregister(adapter);
}
-static struct btd_device_driver network_panu_driver = {
- .name = "network-panu",
- .uuids = BTD_UUIDS(PANU_UUID),
- .probe = panu_probe,
- .remove = panu_remove,
-};
-
-static struct btd_device_driver network_gn_driver = {
- .name = "network-gn",
- .uuids = BTD_UUIDS(GN_UUID),
- .probe = gn_probe,
- .remove = gn_remove,
-};
+static struct btd_profile network_profile = {
+ .name = "network",
+ .remote_uuids = BTD_UUIDS(PANU_UUID, GN_UUID, NAP_UUID),
+ .device_probe = network_probe,
+ .device_remove = network_remove,
-static struct btd_device_driver network_nap_driver = {
- .name = "network-nap",
- .uuids = BTD_UUIDS(NAP_UUID),
- .probe = nap_probe,
- .remove = nap_remove,
-};
-
-static struct btd_adapter_driver network_server_driver = {
- .name = "network-server",
- .probe = network_server_probe,
- .remove = network_server_remove,
+ .adapter_probe = network_server_probe,
+ .adapter_remove = network_server_remove,
};
int network_manager_init(DBusConnection *conn)
if (server_init(conn, conf_security) < 0)
return -1;
- /* Register network server if it doesn't exist */
- btd_register_adapter_driver(&network_server_driver);
+ btd_profile_register(&network_profile);
if (connection_init(conn) < 0)
return -1;
- btd_register_device_driver(&network_panu_driver);
- btd_register_device_driver(&network_gn_driver);
- btd_register_device_driver(&network_nap_driver);
-
connection = dbus_connection_ref(conn);
return 0;
{
server_exit();
- btd_unregister_device_driver(&network_panu_driver);
- btd_unregister_device_driver(&network_gn_driver);
- btd_unregister_device_driver(&network_nap_driver);
-
connection_exit();
- btd_unregister_adapter_driver(&network_server_driver);
+ btd_profile_unregister(&network_profile);
dbus_connection_unref(connection);
connection = NULL;
diff --git a/profiles/proximity/immalert.c b/profiles/proximity/immalert.c
index 1540b61..cc7c26a 100644
--- a/profiles/proximity/immalert.c
+++ b/profiles/proximity/immalert.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include <glib.h>
#include <bluetooth/uuid.h>
#include <adapter.h>
diff --git a/profiles/proximity/linkloss.c b/profiles/proximity/linkloss.c
index 14403cb..7be5223 100644
--- a/profiles/proximity/linkloss.c
+++ b/profiles/proximity/linkloss.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include <glib.h>
#include <bluetooth/uuid.h>
#include <adapter.h>
diff --git a/profiles/proximity/manager.c b/profiles/proximity/manager.c
index f2e49a6..6368221 100644
--- a/profiles/proximity/manager.c
+++ b/profiles/proximity/manager.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include <glib.h>
#include <gdbus.h>
#include <bluetooth/uuid.h>
struct gatt_primary *linkloss, *txpower, *immediate;
GSList *l, *primaries;
+ reporter_device_probe(device);
+
primaries = btd_device_get_primaries(device);
l = g_slist_find_custom(primaries, IMMEDIATE_ALERT_UUID,
static void attio_device_remove(struct btd_device *device)
{
monitor_unregister(connection, device);
+ reporter_device_remove(device);
}
-static struct btd_device_driver monitor_driver = {
- .name = "Proximity GATT Monitor Driver",
- .uuids = BTD_UUIDS(IMMEDIATE_ALERT_UUID, LINK_LOSS_UUID, TX_POWER_UUID),
- .probe = attio_device_probe,
- .remove = attio_device_remove,
-};
+static struct btd_profile pxp_profile = {
+ .name = "Proximity GATT Driver",
+ .remote_uuids = BTD_UUIDS(GATT_UUID, IMMEDIATE_ALERT_UUID,
+ LINK_LOSS_UUID, TX_POWER_UUID),
+ .device_probe = attio_device_probe,
+ .device_remove = attio_device_remove,
-static struct btd_adapter_driver reporter_server_driver = {
- .name = "Proximity GATT Reporter Driver",
- .probe = reporter_init,
- .remove = reporter_exit,
+ .adapter_probe = reporter_init,
+ .adapter_remove = reporter_exit,
};
static void load_config_file(GKeyFile *config)
load_config_file(config);
- connection = dbus_connection_ref(conn);
-
- ret = btd_register_device_driver(&monitor_driver);
+ ret = btd_profile_register(&pxp_profile);
if (ret < 0)
- goto fail_monitor;
+ return ret;
- ret = btd_register_adapter_driver(&reporter_server_driver);
- if (ret < 0)
- goto fail_reporter;
+ connection = dbus_connection_ref(conn);
return 0;
-
-fail_reporter:
- btd_unregister_device_driver(&monitor_driver);
-
-fail_monitor:
- dbus_connection_unref(connection);
- return ret;
}
void proximity_manager_exit(void)
{
- btd_unregister_device_driver(&monitor_driver);
- btd_unregister_adapter_driver(&reporter_server_driver);
+ btd_profile_unregister(&pxp_profile);
dbus_connection_unref(connection);
}
diff --git a/profiles/proximity/monitor.c b/profiles/proximity/monitor.c
index f22d6f4..a5f265e 100644
--- a/profiles/proximity/monitor.c
+++ b/profiles/proximity/monitor.c
#include <fcntl.h>
#include <gdbus.h>
#include <stdint.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
diff --git a/profiles/proximity/reporter.c b/profiles/proximity/reporter.c
index 607de2b..d2eb194 100644
--- a/profiles/proximity/reporter.c
+++ b/profiles/proximity/reporter.c
#include <config.h>
#endif
+#include <stdbool.h>
+#include <errno.h>
+
#include <glib.h>
#include <bluetooth/uuid.h>
#include <adapter.h>
-#include <errno.h>
#include <dbus/dbus.h>
#include <gdbus.h>
radapter->devices = g_slist_prepend(radapter->devices, device);
}
-static int reporter_device_probe(struct btd_device *device, GSList *uuids)
+int reporter_device_probe(struct btd_device *device)
{
struct reporter_adapter *radapter;
struct btd_adapter *adapter = device_get_adapter(device);
return -1;
register_reporter_device(device, radapter);
+
return 0;
}
-static void reporter_device_remove(struct btd_device *device)
+void reporter_device_remove(struct btd_device *device)
{
struct reporter_adapter *radapter;
struct btd_adapter *adapter = device_get_adapter(device);
unregister_reporter_device(device, radapter);
}
-/* device driver for tracking remote GATT client devices */
-static struct btd_device_driver reporter_device_driver = {
- .name = "Proximity GATT Reporter Device Tracker Driver",
- .uuids = BTD_UUIDS(GATT_UUID),
- .probe = reporter_device_probe,
- .remove = reporter_device_remove,
-};
-
int reporter_init(struct btd_adapter *adapter)
{
struct reporter_adapter *radapter;
register_tx_power(adapter);
imm_alert_register(adapter, radapter->conn);
- btd_register_device_driver(&reporter_device_driver);
-
reporter_adapters = g_slist_prepend(reporter_adapters, radapter);
DBG("Proximity Reporter for adapter %p", adapter);
if (!radapter)
return;
- btd_unregister_device_driver(&reporter_device_driver);
-
g_slist_foreach(radapter->devices, unregister_reporter_device,
radapter);
diff --git a/profiles/proximity/reporter.h b/profiles/proximity/reporter.h
index 5ae0eb2..4f3bee2 100644
--- a/profiles/proximity/reporter.h
+++ b/profiles/proximity/reporter.h
HIGH_ALERT = 0x02,
};
+void reporter_device_remove(struct btd_device *device);
+int reporter_device_probe(struct btd_device *device);
+
int reporter_init(struct btd_adapter *adapter);
void reporter_exit(struct btd_adapter *adapter);
diff --git a/profiles/sap/manager.c b/profiles/sap/manager.c
index 9fa9c56..b563d7b 100644
--- a/profiles/sap/manager.c
+++ b/profiles/sap/manager.c
#include <config.h>
#endif
+#include <stdbool.h>
+
#include "log.h"
#include "adapter.h"
+#include "device.h"
#include "manager.h"
#include "server.h"
sap_server_unregister(path);
}
-static struct btd_adapter_driver sap_server_driver = {
- .name = "sap-server",
- .probe = sap_server_probe,
- .remove = sap_server_remove,
+static struct btd_profile sap_profile = {
+ .name = "sap-server",
+ .adapter_probe = sap_server_probe,
+ .adapter_remove = sap_server_remove,
};
int sap_manager_init(DBusConnection *conn)
return -1;
}
- btd_register_adapter_driver(&sap_server_driver);
+ btd_profile_register(&sap_profile);
return 0;
}
void sap_manager_exit(void)
{
- btd_unregister_adapter_driver(&sap_server_driver);
+ btd_profile_unregister(&sap_profile);
dbus_connection_unref(connection);
connection = NULL;
diff --git a/profiles/thermometer/manager.c b/profiles/thermometer/manager.c
index 3d5452b..9e909a3 100644
--- a/profiles/thermometer/manager.c
+++ b/profiles/thermometer/manager.c
#include <gdbus.h>
#include <errno.h>
+#include <stdbool.h>
#include <bluetooth/uuid.h>
#include "adapter.h"
thermometer_unregister(device);
}
-static struct btd_device_driver thermometer_device_driver = {
- .name = "thermometer-device-driver",
- .uuids = BTD_UUIDS(HEALTH_THERMOMETER_UUID),
- .probe = thermometer_driver_probe,
- .remove = thermometer_driver_remove
+static struct btd_profile thermometer_profile = {
+ .name = "thermometer-device-driver",
+ .remote_uuids = BTD_UUIDS(HEALTH_THERMOMETER_UUID),
+ .device_probe = thermometer_driver_probe,
+ .device_remove = thermometer_driver_remove
};
int thermometer_manager_init(DBusConnection *conn)
{
int ret;
- ret = btd_register_device_driver(&thermometer_device_driver);
+ ret = btd_profile_register(&thermometer_profile);
if (ret < 0)
return ret;
void thermometer_manager_exit(void)
{
- btd_unregister_device_driver(&thermometer_device_driver);
+ btd_profile_unregister(&thermometer_profile);
dbus_connection_unref(connection);
connection = NULL;
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 6652a41..f58e558 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
#include <config.h>
#endif
-#include <gdbus.h>
+#include <stdbool.h>
#include <errno.h>
+
#include <bluetooth/uuid.h>
+#include <gdbus.h>
+
#include "dbus-common.h"
#include "adapter.h"
#include "device.h"
diff --git a/profiles/time/manager.c b/profiles/time/manager.c
index 285c7b1..c29951c 100644
--- a/profiles/time/manager.c
+++ b/profiles/time/manager.c
#include <config.h>
#endif
-#include "adapter.h"
+#include <stdbool.h>
+
#include "manager.h"
+#include "adapter.h"
+#include "device.h"
#include "server.h"
-struct btd_adapter_driver time_server_driver = {
- .name = "gatt-time-server",
- .probe = time_server_init,
- .remove = time_server_exit,
+struct btd_profile time_profile = {
+ .name = "gatt-time-server",
+ .adapter_probe = time_server_init,
+ .adapter_remove = time_server_exit,
};
int time_manager_init(void)
{
- btd_register_adapter_driver(&time_server_driver);
+ btd_profile_register(&time_profile);
return 0;
}
void time_manager_exit(void)
{
- btd_unregister_adapter_driver(&time_server_driver);
+ btd_profile_unregister(&time_profile);
}
diff --git a/src/adapter.c b/src/adapter.c
index 50779fd..31fa87d 100644
--- a/src/adapter.c
+++ b/src/adapter.c
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <sys/ioctl.h>
#include <bluetooth/bluetooth.h>
GSList *powered_callbacks;
GSList *pin_callbacks;
- GSList *loaded_drivers;
+ GSList *drivers;
+ GSList *profiles;
};
static void dev_info_free(void *data)
if (list)
device_register_services(connection, device, list, ATT_PSM);
- device_probe_drivers(device, uuids);
+ device_probe_profiles(device, uuids);
g_slist_free_full(uuids, g_free);
}
device_register_services(connection, device, services, -1);
- device_probe_drivers(device, uuids);
+ device_probe_profiles(device, uuids);
g_slist_free(uuids);
}
return;
}
- adapter->loaded_drivers = g_slist_prepend(adapter->loaded_drivers,
- driver);
+ adapter->drivers = g_slist_prepend(adapter->drivers, driver);
}
static void load_drivers(struct btd_adapter *adapter)
probe_driver(adapter, l->data);
}
+static void probe_profile(struct btd_profile *profile, void *data)
+{
+ struct btd_adapter *adapter = data;
+ int err;
+
+ if (profile->adapter_probe == NULL)
+ return;
+
+ err = profile->adapter_probe(adapter);
+ if (err < 0) {
+ error("%s: %s (%d)", profile->name, strerror(-err), -err);
+ return;
+ }
+
+ adapter->profiles = g_slist_prepend(adapter->profiles, profile);
+}
+
static void load_connections(struct btd_adapter *adapter)
{
GSList *l, *conns;
driver->remove(adapter);
}
+static void remove_profile(gpointer data, gpointer user_data)
+{
+ struct btd_profile *profile = data;
+ struct btd_adapter *adapter = user_data;
+
+ if (profile->adapter_remove)
+ profile->adapter_remove(adapter);
+}
+
static void unload_drivers(struct btd_adapter *adapter)
{
- g_slist_foreach(adapter->loaded_drivers, remove_driver, adapter);
- g_slist_free(adapter->loaded_drivers);
- adapter->loaded_drivers = NULL;
+ g_slist_foreach(adapter->drivers, remove_driver, adapter);
+ g_slist_free(adapter->drivers);
+ adapter->drivers = NULL;
+
+ g_slist_foreach(adapter->profiles, remove_profile, adapter);
+ g_slist_free(adapter->profiles);
+ adapter->profiles = NULL;
}
static void set_mode_complete(struct btd_adapter *adapter)
btd_adapter_gatt_server_start(adapter);
load_drivers(adapter);
+ btd_profile_foreach(probe_profile, adapter);
clear_blocked(adapter);
load_devices(adapter);
static void unload_driver(struct btd_adapter *adapter, gpointer data)
{
- adapter->loaded_drivers = g_slist_remove(adapter->loaded_drivers, data);
+ adapter->drivers = g_slist_remove(adapter->drivers, data);
}
void btd_unregister_adapter_driver(struct btd_adapter_driver *driver)
diff --git a/src/agent.c b/src/agent.c
index e542425..b6ddd82 100644
--- a/src/agent.c
+++ b/src/agent.c
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 5cb1383..9b03e54 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
#include <errno.h>
#include <stdint.h>
+#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>
diff --git a/src/device.c b/src/device.c
index 3b44d9b..8cb0876 100644
--- a/src/device.c
+++ b/src/device.c
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <errno.h>
GSList *uuids;
GSList *services; /* Primary services path */
GSList *primaries; /* List of primary services */
- GSList *drivers; /* List of device drivers */
+ GSList *profiles; /* Probed profiles */
+ GSList *conns; /* Connected profiles */
GSList *watches; /* List of disconnect_data */
gboolean temporary;
struct agent *agent;
guint cleanup_id;
};
+static GSList *profiles = NULL;
+
static uint16_t uuid_list[] = {
L2CAP_UUID,
PNP_INFO_SVCLASS_ID,
0
};
-static GSList *device_drivers = NULL;
-
static void browse_request_free(struct browse_req *req)
{
if (req->listener_id)
return dbus_message_new_method_return(msg);
}
-static void driver_remove(struct btd_device_driver *driver,
+static void profile_remove(struct btd_profile *profile,
struct btd_device *device)
{
- driver->remove(device);
+ profile->device_remove(device);
- device->drivers = g_slist_remove(device->drivers, driver);
+ device->profiles = g_slist_remove(device->profiles, profile);
}
static gboolean do_disconnect(gpointer user_data)
if (device->connected)
do_disconnect(device);
- g_slist_foreach(device->drivers, (GFunc) driver_remove, device);
+ g_slist_foreach(device->profiles, (GFunc) profile_remove, device);
if (!update_only)
err = btd_adapter_block_address(device->adapter,
emit_property_changed(conn, device->path,
DEVICE_INTERFACE, "Blocked",
DBUS_TYPE_BOOLEAN, &device->blocked);
- device_probe_drivers(device, device->uuids);
+ device_probe_profiles(device, device->uuids);
}
return 0;
if (remove_stored)
device_remove_stored(device);
- g_slist_foreach(device->drivers, (GFunc) driver_remove, device);
- g_slist_free(device->drivers);
- device->drivers = NULL;
+ g_slist_foreach(device->profiles, (GFunc) profile_remove, device);
+ g_slist_free(device->profiles);
+ device->profiles = NULL;
attrib_client_unregister(device->services);
static GSList *device_match_pattern(struct btd_device *device,
const char *match_uuid,
- GSList *profiles)
+ GSList *uuids)
{
- GSList *l, *uuids = NULL;
+ GSList *l, *match_uuids = NULL;
- for (l = profiles; l; l = l->next) {
- char *profile_uuid = l->data;
+ for (l = uuids; l; l = l->next) {
+ char *uuid = l->data;
const sdp_record_t *rec;
- rec = btd_device_get_record(device, profile_uuid);
+ rec = btd_device_get_record(device, uuid);
if (!rec)
continue;
if (record_has_uuid(rec, match_uuid))
- uuids = g_slist_append(uuids, profile_uuid);
+ match_uuids = g_slist_append(match_uuids, uuid);
}
- return uuids;
+ return match_uuids;
}
-static GSList *device_match_driver(struct btd_device *device,
- struct btd_device_driver *driver,
- GSList *profiles)
+static GSList *device_match_profile(struct btd_device *device,
+ struct btd_profile *profile,
+ GSList *uuids)
{
const char **uuid;
- GSList *uuids = NULL;
+ GSList *match_uuids = NULL;
- for (uuid = driver->uuids; *uuid; uuid++) {
+ for (uuid = profile->remote_uuids; *uuid; uuid++) {
GSList *match;
/* skip duplicated uuids */
- if (g_slist_find_custom(uuids, *uuid,
+ if (g_slist_find_custom(match_uuids, *uuid,
(GCompareFunc) strcasecmp))
continue;
- /* match profile driver */
- match = g_slist_find_custom(profiles, *uuid,
+ /* match profile uuid */
+ match = g_slist_find_custom(uuids, *uuid,
(GCompareFunc) strcasecmp);
if (match) {
- uuids = g_slist_append(uuids, match->data);
+ match_uuids = g_slist_append(match_uuids, match->data);
continue;
}
/* match pattern driver */
- match = device_match_pattern(device, *uuid, profiles);
- uuids = g_slist_concat(uuids, match);
+ match = device_match_pattern(device, *uuid, uuids);
+ match_uuids = g_slist_concat(match_uuids, match);
}
- return uuids;
+ return match_uuids;
}
-void device_probe_drivers(struct btd_device *device, GSList *profiles)
+void device_probe_profiles(struct btd_device *device, GSList *uuids)
{
- GSList *list;
char addr[18];
- int err;
+ GSList *l;
ba2str(&device->bdaddr, addr);
if (device->blocked) {
- DBG("Skipping drivers for blocked device %s", addr);
+ DBG("Skipping profiles for blocked device %s", addr);
goto add_uuids;
}
- DBG("Probing drivers for %s", addr);
+ DBG("Probing profiles for device %s", addr);
- for (list = device_drivers; list; list = list->next) {
- struct btd_device_driver *driver = list->data;
+ for (l = profiles; l != NULL; l = g_slist_next(l)) {
+ struct btd_profile *profile = l->data;
GSList *probe_uuids;
+ int err;
- probe_uuids = device_match_driver(device, driver, profiles);
+ if (profile->device_probe == NULL)
+ continue;
+ probe_uuids = device_match_profile(device, profile, uuids);
if (!probe_uuids)
continue;
- err = driver->probe(device, probe_uuids);
+ err = profile->device_probe(device, probe_uuids);
if (err < 0) {
- error("%s driver probe failed for device %s",
- driver->name, addr);
+ error("%s profile probe failed for device %s",
+ profile->name, addr);
g_slist_free(probe_uuids);
continue;
}
- device->drivers = g_slist_append(device->drivers, driver);
+ device->profiles = g_slist_append(device->profiles, profile);
g_slist_free(probe_uuids);
}
add_uuids:
- for (list = profiles; list; list = list->next) {
- GSList *l = g_slist_find_custom(device->uuids, list->data,
+ for (l = uuids; l != NULL; l = g_slist_next(l)) {
+ GSList *match = g_slist_find_custom(device->uuids, l->data,
(GCompareFunc) strcasecmp);
- if (l)
+ if (match)
continue;
device->uuids = g_slist_insert_sorted(device->uuids,
- g_strdup(list->data),
+ g_strdup(l->data),
(GCompareFunc) strcasecmp);
}
}
-static void device_remove_drivers(struct btd_device *device, GSList *uuids)
+static void device_remove_profiles(struct btd_device *device, GSList *uuids)
{
struct btd_adapter *adapter = device_get_adapter(device);
- GSList *list, *next;
char srcaddr[18], dstaddr[18];
bdaddr_t src;
sdp_list_t *records;
+ GSList *l;
adapter_get_address(adapter, &src);
ba2str(&src, srcaddr);
records = read_records(&src, &device->bdaddr);
- DBG("Removing drivers for %s", dstaddr);
+ DBG("Removing profiles for %s", dstaddr);
- for (list = device->drivers; list; list = next) {
- struct btd_device_driver *driver = list->data;
+ for (l = profiles; l != NULL; l = g_slist_next(l)) {
+ struct btd_profile *profile = l->data;
const char **uuid;
- next = list->next;
-
- for (uuid = driver->uuids; *uuid; uuid++) {
+ for (uuid = profile->remote_uuids; *uuid; uuid++) {
if (!g_slist_find_custom(uuids, *uuid,
(GCompareFunc) strcasecmp))
continue;
- DBG("UUID %s was removed from device %s",
- *uuid, dstaddr);
+ DBG("UUID %s was removed from device %s", *uuid, dstaddr);
- driver->remove(device);
- device->drivers = g_slist_remove(device->drivers,
- driver);
+ profile->device_remove(device);
+ device->profiles = g_slist_remove(device->profiles,
+ profile);
break;
}
}
- for (list = uuids; list; list = list->next) {
+ for (l = uuids; l != NULL; l = g_slist_next(l)) {
sdp_record_t *rec;
- device->uuids = g_slist_remove(device->uuids, list->data);
+ device->uuids = g_slist_remove(device->uuids, l->data);
- rec = find_record_in_list(records, list->data);
+ rec = find_record_in_list(records, l->data);
if (!rec)
continue;
records = sdp_list_remove(records, rec);
sdp_record_free(rec);
-
}
if (records)
goto send_reply;
}
- /* Probe matching drivers for services added */
+ /* Probe matching profiles for services added */
if (req->profiles_added) {
GSList *list;
device_register_services(req->conn, device, list,
ATT_PSM);
- device_probe_drivers(device, req->profiles_added);
+ device_probe_profiles(device, req->profiles_added);
}
- /* Remove drivers for services removed */
+ /* Remove profiles for services removed */
if (req->profiles_removed)
- device_remove_drivers(device, req->profiles_removed);
+ device_remove_profiles(device, req->profiles_removed);
/* Propagate services changes */
uuids_changed(req->device);
device_register_services(req->conn, device, g_slist_copy(services), -1);
if (req->profiles_removed)
- device_remove_drivers(device, req->profiles_removed);
+ device_remove_profiles(device, req->profiles_removed);
- device_probe_drivers(device, req->profiles_added);
+ device_probe_profiles(device, req->profiles_added);
if (device->attios == NULL && device->attios_offline == NULL)
attio_cleanup(device);
new_uuid = g_strdup(uuid);
uuid_list = g_slist_append(NULL, new_uuid);
- device_probe_drivers(device, uuid_list);
+ device_probe_profiles(device, uuid_list);
g_free(new_uuid);
g_slist_free(uuid_list);
return find_record_in_list(device->tmp_records, uuid);
}
-int btd_register_device_driver(struct btd_device_driver *driver)
-{
- device_drivers = g_slist_append(device_drivers, driver);
-
- return 0;
-}
-
-void btd_unregister_device_driver(struct btd_device_driver *driver)
-{
- device_drivers = g_slist_remove(device_drivers, driver);
-}
-
struct btd_device *btd_device_ref(struct btd_device *device)
{
device->ref++;
device_set_product(device, product_id);
device_set_version(device, product_ver);
}
+
+void btd_profile_foreach(void (*func)(struct btd_profile *p, void *data),
+ void *data)
+{
+ GSList *l, *next;
+
+ for (l = profiles; l != NULL; l = next) {
+ struct btd_profile *profile = l->data;
+
+ next = g_slist_next(l);
+
+ func(profile, data);
+ }
+}
+
+int btd_profile_register(struct btd_profile *profile)
+{
+ profiles = g_slist_append(profiles, profile);
+ return 0;
+}
+
+void btd_profile_unregister(struct btd_profile *profile)
+{
+ profiles = g_slist_remove(profiles, profile);
+}
+
+void btd_profile_connected(struct btd_profile *profile,
+ struct btd_device *device, int err)
+{
+ if (err == 0)
+ device->conns = g_slist_append(device->conns, profile);
+}
+
+void btd_profile_disconnected(struct btd_profile *profile,
+ struct btd_device *device)
+{
+ device->conns = g_slist_remove(device->conns, profile);
+}
diff --git a/src/device.h b/src/device.h
index a65de26..ccb15fc 100644
--- a/src/device.h
+++ b/src/device.h
AUTH_TYPE_NOTIFY_PINCODE,
} auth_type_t;
+#define BTD_UUIDS(args...) ((const char *[]) { args, NULL } )
+
+struct btd_profile {
+ const char *name;
+
+ const char *local_uuid;
+ const char **remote_uuids;
+
+ bool auto_connect;
+
+ int (*device_probe) (struct btd_device *device, GSList *uuids);
+ void (*device_remove) (struct btd_device *device);
+
+ void (*connect) (struct btd_device *device);
+ void (*disconnect) (struct btd_device *device);
+
+ int (*adapter_probe) (struct btd_adapter *adapter);
+ void (*adapter_remove) (struct btd_adapter *adapter);
+};
+
+void btd_profile_foreach(void (*func)(struct btd_profile *p, void *data),
+ void *data);
+
+int btd_profile_register(struct btd_profile *profile);
+void btd_profile_unregister(struct btd_profile *profile);
+
+void btd_profile_connected(struct btd_profile *profile,
+ struct btd_device *device, int err);
+void btd_profile_disconnected(struct btd_profile *profile,
+ struct btd_device *device);
+
struct btd_device *device_create(DBusConnection *conn,
struct btd_adapter *adapter,
const char *address, uint8_t bdaddr_type);
+
void device_set_name(struct btd_device *device, const char *name);
void device_get_name(struct btd_device *device, char *name, size_t len);
uint16_t btd_device_get_vendor(struct btd_device *device);
DBusMessage *msg, gboolean secure);
int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
DBusMessage *msg, uuid_t *search, gboolean reverse);
-void device_probe_drivers(struct btd_device *device, GSList *profiles);
+void device_probe_profiles(struct btd_device *device, GSList *profiles);
const sdp_record_t *btd_device_get_record(struct btd_device *device,
const char *uuid);
GSList *btd_device_get_primaries(struct btd_device *device);
int device_get_appearance(struct btd_device *device, uint16_t *value);
void device_set_appearance(struct btd_device *device, uint16_t value);
-#define BTD_UUIDS(args...) ((const char *[]) { args, NULL } )
-
-struct btd_device_driver {
- const char *name;
- const char **uuids;
- int (*probe) (struct btd_device *device, GSList *uuids);
- void (*remove) (struct btd_device *device);
-};
-
-int btd_register_device_driver(struct btd_device_driver *driver);
-void btd_unregister_device_driver(struct btd_device_driver *driver);
-
struct btd_device *btd_device_ref(struct btd_device *device);
void btd_device_unref(struct btd_device *device);
diff --git a/src/event.c b/src/event.c
index 1586293..42d05b6 100644
--- a/src/event.c
+++ b/src/event.c
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <bluetooth/bluetooth.h>
diff --git a/src/mgmt.c b/src/mgmt.c
index 58aab2d..45a5c90 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>