Add CAPI: 50/25050/1
authorGu Chaojie <chao.jie.gu@intel.com>
Mon, 28 Jul 2014 07:30:37 +0000 (15:30 +0800)
committerGu Chaojie <chao.jie.gu@intel.com>
Mon, 28 Jul 2014 07:30:37 +0000 (15:30 +0800)
Gatt get primary services
Gatt get service uuid/includes
Gatt clone/destroy attribute handle

Change-Id: Ib214e605313ad2777104cedf50b9627d334e9887
Signed-off-by: Gu Chaojie <chao.jie.gu@intel.com>
capi/bluetooth.c
include/bluez.h
include/common.h
lib/bluez.c
lib/common.c
test/bluez-capi-test.c

index e351659..732f2e8 100644 (file)
@@ -5323,3 +5323,151 @@ int bt_device_foreach_connected_profiles(
 
        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;
+}
index a5829a1..0a88a3b 100644 (file)
@@ -41,6 +41,15 @@ typedef struct _bluez_adapter bluez_adapter_t;
 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;
 
@@ -236,6 +245,18 @@ int bluez_adapter_get_property_discovering(
 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);
index e038c83..c68e5bb 100644 (file)
@@ -99,6 +99,10 @@ char **property_get_string_list(GDBusProxy *proxy,
                                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,
index f9c6aba..b0b8661 100644 (file)
@@ -1175,6 +1175,29 @@ char *bluez_gatt_service_property_get_device(
                                        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)
 {
@@ -1189,6 +1212,29 @@ char *bluez_gatt_desc_property_get_char(
                                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;
@@ -2933,6 +2979,30 @@ int bluez_device_network_disconnect(struct _bluez_device *device)
        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,
index 7e688dc..58e96a1 100644 (file)
@@ -216,6 +216,31 @@ char **property_get_string_list(GDBusProxy *proxy,
        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,
index 101715b..909fb2a 100644 (file)
@@ -2214,6 +2214,101 @@ static int hdp_unset_data_received_cb(const char *p1, const char *p2)
        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);
@@ -2527,10 +2622,22 @@ struct {
                "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"},