return BT_SUCCESS;
}
+
+int bt_gatt_foreach_primary_services(const char *remote_address,
+ bt_gatt_primary_service_cb callback,
+ void *user_data)
+{
+ bluez_device_t *device;
+ GList *primary_services, *list, *next;
+ char *service_path;
+
+ DBG("");
+
+ if (initialized == false)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (default_adapter == NULL)
+ return BT_ERROR_ADAPTER_NOT_FOUND;
+
+ if (remote_address == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ device = bluez_adapter_get_device_by_address(default_adapter,
+ remote_address);
+ if (device == NULL)
+ return BT_ERROR_OPERATION_FAILED;
+
+ primary_services = bluez_device_get_primary_services(device);
+
+ if (primary_services == NULL)
+ return BT_ERROR_OPERATION_FAILED;
+
+ for (list = g_list_first(primary_services); list; list = next) {
+ service_path = list->data;
+
+ next = g_list_next(list);
+
+ if (!callback((bt_gatt_attribute_h)service_path, user_data))
+ break;
+ }
+
+ g_list_free(primary_services);
+
+ return BT_SUCCESS;
+}
+
+int bt_gatt_get_service_uuid(bt_gatt_attribute_h service, char **uuid)
+{
+ bluez_gatt_service_t *gatt_service;
+ const char *service_path = service;
+
+ DBG("");
+
+ if (initialized == false)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (default_adapter == NULL)
+ return BT_ERROR_ADAPTER_NOT_FOUND;
+
+ if (service_path == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ gatt_service = bluez_gatt_get_service_by_path(service_path);
+
+ if (gatt_service == NULL)
+ return BT_ERROR_OPERATION_FAILED;
+
+ *uuid = bluez_gatt_service_get_property_uuid(gatt_service);
+
+ return BT_SUCCESS;
+}
+
+int bt_gatt_foreach_included_services(bt_gatt_attribute_h service,
+ bt_gatt_included_service_cb callback,
+ void *user_data)
+{
+ bluez_gatt_service_t *gatt_service;
+ guint length, index;
+ const char *service_path = service;
+ char **includes;
+
+ DBG("");
+
+ if (initialized == false)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (default_adapter == NULL)
+ return BT_ERROR_ADAPTER_NOT_FOUND;
+
+ if (service_path == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ gatt_service = bluez_gatt_get_service_by_path(service_path);
+
+ if (gatt_service == NULL)
+ return BT_ERROR_OPERATION_FAILED;
+
+ includes = bluez_gatt_service_get_property_includes(gatt_service);
+
+ if (includes == NULL) {
+ DBG("No include services found in service handle");
+ return BT_SUCCESS;
+ }
+
+ length = g_strv_length(includes);
+
+ for (index = 0; index < length; index++) {
+ if (!callback((bt_gatt_attribute_h)includes[index], user_data))
+ break;
+ }
+
+ return BT_SUCCESS;
+}
+
+int bt_gatt_clone_attribute_handle(bt_gatt_attribute_h *clone,
+ bt_gatt_attribute_h origin)
+{
+ DBG("");
+
+ if (initialized == false)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (default_adapter == NULL)
+ return BT_ERROR_ADAPTER_NOT_FOUND;
+
+ if (origin == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ *clone = g_strdup((char *)origin);
+
+ return BT_SUCCESS;
+}
+
+int bt_gatt_destroy_attribute_handle(bt_gatt_attribute_h handle)
+{
+ DBG("");
+
+ if (initialized == false)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (default_adapter == NULL)
+ return BT_ERROR_ADAPTER_NOT_FOUND;
+
+ if (handle == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ g_free(handle);
+
+ return BT_SUCCESS;
+}
struct _bluez_device;
typedef struct _bluez_device bluez_device_t;
+struct _bluez_gatt_service;
+typedef struct _bluez_gatt_service bluez_gatt_service_t;
+
+struct _bluez_gatt_char;
+typedef struct _bluez_gatt_char bluez_gatt_char_t;
+
+struct _bluez_gatt_desc;
+typedef struct _bluez_gatt_desc bluez_gatt_desc_t;
+
struct _bluez_agent;
typedef struct _bluez_agent bluez_agent_t;
char **bluez_adapter_get_property_uuids(
struct _bluez_adapter *adapter);
+char *bluez_gatt_service_get_property_uuid(
+ struct _bluez_gatt_service *service);
+
+struct _bluez_gatt_service *bluez_gatt_get_service_by_path(
+ const char *service_path);
+
+GList *bluez_device_get_primary_services(
+ struct _bluez_device *device);
+
+char **bluez_gatt_service_get_property_includes(
+ struct _bluez_gatt_service *service);
+
/* Returned Glist should not be freed and modified */
const GList *bluez_adapter_get_devices_path(
struct _bluez_adapter *adapter);
const char *interface_name,
const char *property);
+char **property_get_object_list(GDBusProxy *proxy,
+ const char *interface_name,
+ const char *property);
+
void property_set_string(GDBusProxy *proxy,
const char *interface_name,
const char *property,
GATT_SERVICE_IFACE, "Device");
}
+int bluez_gatt_service_get_property_primary(
+ struct _bluez_gatt_service *service,
+ gboolean *primary)
+{
+ return property_get_boolean(service->property_proxy,
+ GATT_SERVICE_IFACE,
+ "Primary", primary);
+}
+
+char **bluez_gatt_service_get_property_includes(
+ struct _bluez_gatt_service *service)
+{
+ return property_get_object_list(service->property_proxy,
+ GATT_SERVICE_IFACE, "Includes");
+}
+
+char *bluez_gatt_service_get_property_uuid(
+ struct _bluez_gatt_service *service)
+{
+ return property_get_string(service->property_proxy,
+ GATT_SERVICE_IFACE, "UUID");
+}
+
char *bluez_gatt_char_property_get_service(
struct _bluez_gatt_char *characteristic)
{
GATT_DESCRIPTOR_IFACE, "Characteristic");
}
+struct _bluez_gatt_service *bluez_gatt_get_service_by_path(
+ const char *service_path)
+{
+ struct _gatt_service_head *head = NULL;
+ struct _bluez_gatt_service *service = NULL;
+ GList *list, *next;
+
+ for (list = g_list_first(gatt_service_head_list); list; list = next) {
+ head = list->data;
+
+ next = g_list_next(list);
+
+ service = g_hash_table_lookup(head->gatt_service_hash,
+ (gconstpointer) service_path);
+
+ if (service != NULL)
+ break;
+ }
+
+ return service;
+}
+
+
static void destruct_bluez_device(gpointer data)
{
struct _bluez_device *device = data;
return 0;
}
+GList *bluez_device_get_primary_services(struct _bluez_device *device)
+{
+ struct _gatt_service_head *service_head = device->service_head;
+ struct _bluez_gatt_service *service;
+ GList *primary_services = NULL;
+ GList *services, *list, *next;
+ int primary;
+
+ services = g_hash_table_get_values(service_head->gatt_service_hash);
+
+ for (list = g_list_first(services); list; list = next) {
+ service = list->data;
+
+ next = g_list_next(list);
+
+ bluez_gatt_service_get_property_primary(service, &primary);
+ if (primary)
+ primary_services = g_list_append(primary_services,
+ service->object_path);
+ }
+
+ return primary_services;
+}
+
void bluez_device_network_set_connected_changed_cb(
struct _bluez_device *device,
bluez_device_network_connected_cb_t cb,
return strv;
}
+char **property_get_object_list(GDBusProxy *proxy,
+ const char *interface_name,
+ const char *property)
+{
+ GVariant *objv_v, *objv_vv;
+ char **objv;
+ GError *error = NULL;
+
+ objv_vv = g_dbus_proxy_call_sync(
+ proxy, "Get",
+ g_variant_new("(ss)", interface_name, property),
+ 0, -1, NULL, &error);
+
+ if (objv_vv == NULL) {
+ WARN("no cached property %s", property);
+ return NULL;
+ }
+
+ g_variant_get(objv_vv, "(v)", &objv_v);
+
+ objv = g_variant_dup_objv(objv_v, NULL);
+
+ return objv;
+}
+
void property_set_string(GDBusProxy *proxy,
const char *interface_name,
const char *property,
return 0;
}
+static bool gatt_primary_service_callback(bt_gatt_attribute_h service,
+ void *user_data)
+{
+ const char *service_handle = service;
+
+ DBG("Primary service found %s", service_handle);
+
+ return TRUE;
+}
+
+
+static int gatt_foreach_primary_services(const char *p1, const char *p2)
+{
+ int ret;
+
+ if (p1 == NULL) {
+ ERROR("gatt primary service must give the device address");
+ return 0;
+ }
+
+ ret = bt_gatt_foreach_primary_services(p1,
+ gatt_primary_service_callback, NULL);
+
+ DBG("ret = %d", ret);
+
+ return 0;
+}
+
+static int gatt_get_service_uuid(const char *p1, const char *p2)
+{
+ int ret;
+ char *uuid;
+
+ if (p1 == NULL) {
+ ERROR("gatt service uuid must give the service handle");
+ return 0;
+ }
+
+ ret = bt_gatt_get_service_uuid((bt_gatt_attribute_h)p1, &uuid);
+
+ DBG("ret = %d", ret);
+
+ DBG("uuid = %s", uuid);
+
+ return 0;
+}
+
+static bool gatt_include_service_callback(bt_gatt_attribute_h service,
+ void *user_data)
+{
+ const char *service_handle = service;
+
+ DBG("Include service found %s", service_handle);
+
+ return TRUE;
+}
+
+static int gatt_foreach_included_services(const char *p1, const char *p2)
+{
+ int ret;
+
+ if (p1 == NULL) {
+ ERROR("gatt service includes must give the service handle");
+ return 0;
+ }
+
+ ret = bt_gatt_foreach_included_services((bt_gatt_attribute_h)p1,
+ gatt_include_service_callback, NULL);
+
+ DBG("ret = %d", ret);
+
+ return 0;
+}
+
+static int gatt_clone_and_destroy_attribute_handle(const char *p1, const char *p2)
+{
+ int ret;
+ bt_gatt_attribute_h clone;
+
+ if (p1 == NULL) {
+ ERROR("gatt clone must give the attribue handle");
+ return 0;
+ }
+
+ ret = bt_gatt_clone_attribute_handle(&clone, (bt_gatt_attribute_h)p1);
+
+ DBG("Clone handle %s", (char *)clone);
+
+ ret = bt_gatt_destroy_attribute_handle(clone);
+
+ DBG("destroy handle ret = %d", ret);
+
+ return 0;
+}
+
struct {
const char *command;
int (*function)(const char *p1, const char *p2);
"Usage: hdp_set_data_rec_cb\n\tset hdp data rec cb"},
{"hdo_unset_connect_cb", hdp_unset_connection_state_changed_cb,
- "Usage: hdp_set_connect_cb\n\tset hdp conn cb"},
+ "Usage: hdp_unset_connect_cb\n\tunset hdp conn cb"},
{"hdp_unset_data_rec_cb", hdp_unset_data_received_cb,
- "Usage: hdp_set_data_rec_cb\n\tset hdp data rec cb"},
+ "Usage: hdp_unset_data_rec_cb\n\tunset hdp data rec cb"},
+
+ {"gatt_foreach_primary_services", gatt_foreach_primary_services,
+ "Usage: gatt_foreach_primary_services\n\tgatt foreach primary services"},
+
+ {"gatt_get_service_uuid", gatt_get_service_uuid,
+ "Usage: gatt_get_service_uuid\n\tgatt get service uuid"},
+
+ {"gatt_foreach_included_services", gatt_foreach_included_services,
+ "Usage: gatt_foreach_included_services\n\tgatt foreach included services"},
+
+ {"gatt_clone_and_destroy_attribute_handle", gatt_clone_and_destroy_attribute_handle,
+ "Usage: gatt_clone_and_destroy_attribute_handle\n\tgatt clone and destroy attribute handle"},
{"q", quit,
"Usage: q\n\tQuit"},