From: Seungyoun Ju Date: Wed, 26 Dec 2018 09:11:17 +0000 (+0900) Subject: gatt-service : Fix some minor bugs X-Git-Tag: accepted/tizen/unified/20190103.061728~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git;a=commitdiff_plain;h=d49130038cecaa0c9d7317de3b6a093375190626 gatt-service : Fix some minor bugs [Problem] init -> register service -> deinit -> init -> register service -> start server : service is not added. There are some warning about reference to invalid GOBJECT. [Cause & Measure] Remove pending count. Unref GOBJECT after check of validation. Change-Id: I4829505ebac3e3c0668aa2a386de3085163d0b8d --- diff --git a/bt-api/bt-gatt-service.c b/bt-api/bt-gatt-service.c index f56447b..1d30065 100644 --- a/bt-api/bt-gatt-service.c +++ b/bt-api/bt-gatt-service.c @@ -161,7 +161,6 @@ guint manager_id; static gboolean new_service = FALSE; static gboolean new_char = FALSE; static int serv_id = 1; -static int register_pending_cnt = 0; static bool is_server_started = false; GCancellable *register_cancel; @@ -271,7 +270,6 @@ struct gatt_service_info { guint serv_id; gchar *service_uuid; guint manager_id; - guint prop_id; GSList *char_data; gboolean is_svc_registered; gboolean is_svc_primary; @@ -343,6 +341,7 @@ static struct gatt_desc_info *__bt_gatt_find_gatt_desc_info( const char *desc_path); static struct gatt_req_info *__bt_gatt_find_request_info(guint request_id); +static int __bt_gatt_unregister_service(struct gatt_service_info *svc_info); @@ -596,97 +595,60 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, GDBusMethodInvocation *invocation, gpointer user_data) { - GSList *l1 = NULL; - int len = 0; - int i = 0; - if (g_strcmp0(method_name, "GetManagedObjects") == 0) { BT_DBG("Getting values for service, chars and descriptors"); - GVariantBuilder *builder; + int svc_index = 0; + GVariantBuilder *builder = NULL; GVariantBuilder *inner_builder1 = NULL; GVariant *svc_char = NULL; - GSList *l4; - /*Main Builder */ - builder = g_variant_builder_new( - G_VARIANT_TYPE("a{oa{sa{sv}}}")); - - /* Prepare inner builder for GattService1 interface */ + GSList *char_list = NULL; + GSList *desc_list = NULL; - len = g_slist_length(gatt_services); + /* Main Builder */ + builder = g_variant_builder_new(G_VARIANT_TYPE("a{oa{sa{sv}}}")); - for (i = 0; i <= len; i++) { + /* Prepare inner builder for GattService1 interface */ + svc_index = g_slist_length(gatt_services) - 1; + for (; svc_index >= 0; svc_index--) { GVariantBuilder *svc_builder = NULL; GVariantBuilder *inner_builder = NULL; + struct gatt_service_info *serv_info = NULL; - if (register_pending_cnt > 1) - l1 = g_slist_nth(gatt_services, len - register_pending_cnt); - else - l1 = g_slist_last(gatt_services); - - register_pending_cnt--; - - if (l1 == NULL) { - BT_ERR("gatt service list is NULL"); - g_dbus_method_invocation_return_value(invocation, NULL); - g_variant_builder_unref(builder); - return; - } - - struct gatt_service_info *serv_info = l1->data; + serv_info = g_slist_nth_data(gatt_services, svc_index); if (serv_info == NULL) { - BT_ERR("service info value is NULL"); - g_dbus_method_invocation_return_value(invocation, NULL); - g_variant_builder_unref(builder); - return; + BT_ERR("serv_info is NULL"); + continue; } /* Prepare inner builder for GattService1 interface */ - BT_DBG("Creating builder for service"); - svc_builder = g_variant_builder_new( - G_VARIANT_TYPE("a{sa{sv}}")); + BT_DBG("Creating builder for service : %s", serv_info->service_uuid); + svc_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}")); inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); g_variant_builder_add(inner_builder, "{sv}", "UUID", g_variant_new_string(serv_info->service_uuid)); - g_variant_builder_add(inner_builder, "{sv}", "Primary", g_variant_new_boolean(serv_info->is_svc_primary)); - /*Characteristics*/ + /* Characteristics */ inner_builder1 = g_variant_builder_new(G_VARIANT_TYPE("ao")); + BT_DBG("Adding Charatarisitcs list"); - for (l4 = serv_info->char_data; l4 != NULL; l4 = l4->next) { - struct gatt_char_info *char_info = l4->data; - g_variant_builder_add(inner_builder1, "o", - char_info->char_path); - BT_DBG("%s", char_info->char_path); + for (char_list = serv_info->char_data; char_list != NULL; char_list = char_list->next) { + struct gatt_char_info *char_info = char_list->data; + g_variant_builder_add(inner_builder1, "o", char_info->char_path); + BT_DBG("%s", char_info->char_path); } svc_char = g_variant_new("ao", inner_builder1); - g_variant_builder_add(inner_builder, "{sv}", "Characteristics", - svc_char); - - g_variant_builder_add(svc_builder, "{sa{sv}}", - GATT_SERV_INTERFACE, - inner_builder); - - g_variant_builder_add(builder, "{oa{sa{sv}}}", - serv_info->serv_path, - svc_builder); - + g_variant_builder_add(inner_builder, "{sv}", "Characteristics", svc_char); + g_variant_builder_add(svc_builder, "{sa{sv}}", GATT_SERV_INTERFACE, inner_builder); + g_variant_builder_add(builder, "{oa{sa{sv}}}", serv_info->serv_path, svc_builder); g_variant_builder_unref(inner_builder1); /* Prepare inner builder for GattCharacteristic1 interface */ - - GSList *l2 = serv_info->char_data; - BT_DBG("Creating builder for characteristics \n"); - - if (l2 == NULL) - BT_DBG("characteristic data is NULL"); - - for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) { - + for (char_list = serv_info->char_data; char_list != NULL; char_list = char_list->next) { GVariantBuilder *char_builder = NULL; GVariantBuilder *inner_builder = NULL; GVariantBuilder *builder1 = NULL; @@ -698,155 +660,114 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, char *unicast = NULL; gboolean notify = FALSE; int i = 0; + struct gatt_char_info *char_info = char_list->data; - char_builder = g_variant_builder_new( - G_VARIANT_TYPE( - "a{sa{sv}}")); - inner_builder = g_variant_builder_new( - G_VARIANT_TYPE( - "a{sv}")); - - struct gatt_char_info *char_info = l2->data; if (char_info == NULL) { BT_ERR("char_info is NULL"); continue; } - /*Uuid*/ + BT_DBG("Creating builder for characteristic : %s", char_info->char_uuid); + char_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}")); + inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + + /* UUID */ g_variant_builder_add(inner_builder, "{sv}", "UUID", - g_variant_new_string(char_info->char_uuid)); - /*Service*/ + g_variant_new_string(char_info->char_uuid)); + + /* Service */ g_variant_builder_add(inner_builder, "{sv}", "Service", - g_variant_new("o", serv_info->serv_path)); - /*Value*/ - builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); + g_variant_new("o", serv_info->serv_path)); + /* Value */ + builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); if (char_info->char_value != NULL) { for (i = 0; i < char_info->value_length; i++) { - g_variant_builder_add(builder1, "y", - char_info->char_value[i]); + g_variant_builder_add(builder1, "y", char_info->char_value[i]); } char_val = g_variant_new("ay", builder1); - g_variant_builder_add(inner_builder, "{sv}", - "Value", char_val); + g_variant_builder_add(inner_builder, "{sv}", "Value", char_val); } + /*Flags*/ builder2 = g_variant_builder_new(G_VARIANT_TYPE("as")); - for (i = 0; i < char_info->flags_length; i++) { - g_variant_builder_add(builder2, "s", - char_info->char_flags[i]); + g_variant_builder_add(builder2, "s", char_info->char_flags[i]); } - flags_val = g_variant_new("as", builder2); - g_variant_builder_add(inner_builder, "{sv}", "Flags", - flags_val); + g_variant_builder_add(inner_builder, "{sv}", "Flags", flags_val); /* Notifying */ - g_variant_builder_add(inner_builder, "{sv}", "Notifying", - g_variant_new("b", notify)); + g_variant_builder_add(inner_builder, "{sv}", "Notifying", g_variant_new("b", notify)); /* Unicast */ unicast = g_strdup("00:00:00:00:00:00"); - g_variant_builder_add(inner_builder, "{sv}", "Unicast", - g_variant_new("s", unicast)); + g_variant_builder_add(inner_builder, "{sv}", "Unicast", g_variant_new("s", unicast)); /*Descriptors*/ builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao")); BT_DBG("Adding Descriptors list"); - - for (l4 = char_info->desc_data; l4 != NULL; l4 = l4->next) { - struct gatt_desc_info *desc_info = l4->data; - g_variant_builder_add(builder3, "o", - desc_info->desc_path); - BT_DBG("%s", desc_info->desc_path); + for (desc_list = char_info->desc_data; desc_list != NULL; desc_list = desc_list->next) { + struct gatt_desc_info *desc_info = desc_list->data; + g_variant_builder_add(builder3, "o", desc_info->desc_path); + BT_DBG("%s", desc_info->desc_path); } char_desc = g_variant_new("ao", builder3); - g_variant_builder_add(inner_builder, "{sv}", "Descriptors", - char_desc); - - g_variant_builder_add(char_builder, "{sa{sv}}", - GATT_CHAR_INTERFACE , inner_builder); - g_variant_builder_add(builder, "{oa{sa{sv}}}", - char_info->char_path, char_builder); + g_variant_builder_add(inner_builder, "{sv}", "Descriptors", char_desc); + g_variant_builder_add(char_builder, "{sa{sv}}", GATT_CHAR_INTERFACE , inner_builder); + g_variant_builder_add(builder, "{oa{sa{sv}}}", char_info->char_path, char_builder); /*Prepare inner builder for GattDescriptor1 interface*/ - - GSList *l3 = char_info->desc_data; - - if (l3 == NULL) - BT_DBG("descriptor data is NULL"); - - for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) { - - BT_DBG("Creating builder for descriptor \n"); - + for (desc_list = char_info->desc_data; desc_list != NULL; desc_list = desc_list->next) { GVariantBuilder *desc_builder = NULL; GVariantBuilder *inner_builder = NULL; GVariantBuilder *builder1 = NULL; GVariantBuilder *builder2 = NULL; GVariant *desc_val = NULL; + struct gatt_desc_info *desc_info = desc_list->data; - desc_builder = g_variant_builder_new( - G_VARIANT_TYPE( - "a{sa{sv}}")); - inner_builder = g_variant_builder_new( - G_VARIANT_TYPE( - "a{sv}")); - - struct gatt_desc_info *desc_info = l3->data; if (desc_info == NULL) { BT_ERR("desc_info is NULL"); continue; } - /*Uuid*/ - g_variant_builder_add(inner_builder, - "{sv}", "UUID", - g_variant_new_string( - desc_info->desc_uuid)); + BT_DBG("Creating builder for descriptor : %s", desc_info->desc_uuid); + desc_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}")); + inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); - /*Characteristic*/ - g_variant_builder_add(inner_builder, "{sv}", - "Characteristic", - g_variant_new("o", - char_info->char_path)); + /* UUID */ + g_variant_builder_add(inner_builder, "{sv}", "UUID", + g_variant_new_string(desc_info->desc_uuid)); - /*Value*/ - builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); + /* Characteristic */ + g_variant_builder_add(inner_builder, "{sv}", "Characteristic", + g_variant_new("o", char_info->char_path)); + /* Value */ + builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); if (desc_info->desc_value != NULL) { for (i = 0; i < desc_info->value_length; i++) { - g_variant_builder_add(builder1, "y", - desc_info->desc_value[i]); + g_variant_builder_add(builder1, "y", desc_info->desc_value[i]); } desc_val = g_variant_new("ay", builder1); - g_variant_builder_add(inner_builder, "{sv}", - "Value", desc_val); + g_variant_builder_add(inner_builder, "{sv}", "Value", desc_val); } - /*Flags*/ + /* Flags */ builder2 = g_variant_builder_new(G_VARIANT_TYPE("as")); - for (i = 0; i < desc_info->flags_length; i++) { - g_variant_builder_add(builder2, "s", - desc_info->desc_flags[i]); + g_variant_builder_add(builder2, "s", desc_info->desc_flags[i]); } - flags_val = g_variant_new("as", builder2); - g_variant_builder_add(inner_builder, "{sv}", "Flags", - flags_val); + g_variant_builder_add(inner_builder, "{sv}", "Flags", flags_val); - g_variant_builder_add(desc_builder, "{sa{sv}}", - GATT_DESC_INTERFACE, + g_variant_builder_add(desc_builder, "{sa{sv}}", GATT_DESC_INTERFACE, inner_builder); - - g_variant_builder_add(builder, "{oa{sa{sv}}}", - desc_info->desc_path, + g_variant_builder_add(builder, "{oa{sa{sv}}}", desc_info->desc_path, desc_builder); - /*unref descriptor builder pointers*/ + /* unref descriptor builder pointers */ g_variant_builder_unref(builder1); g_variant_builder_unref(builder2); g_variant_builder_unref(inner_builder); @@ -855,7 +776,8 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, if (unicast) g_free(unicast); - /*unref char builder pointers*/ + + /* unref char builder pointers */ g_variant_builder_unref(builder1); g_variant_builder_unref(builder2); g_variant_builder_unref(builder3); @@ -863,7 +785,7 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, g_variant_builder_unref(char_builder); } - /*unref service builder pointers*/ + /* unref service builder pointers */ g_variant_builder_unref(inner_builder); g_variant_builder_unref(svc_builder); } @@ -871,9 +793,7 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, /* Return builder as method reply */ BT_DBG("Sending gatt service builder values to Bluez"); g_dbus_method_invocation_return_value(invocation, - g_variant_new( - "(a{oa{sa{sv}}})", - builder)); + g_variant_new("(a{oa{sa{sv}}})", builder)); g_variant_builder_unref(builder); } } @@ -888,8 +808,7 @@ static struct gatt_service_info *__bt_gatt_find_gatt_service_from_char(const cha for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) { struct gatt_char_info *char_info = l2->data; - if (g_strcmp0(char_info->char_path, char_path) - == 0) + if (g_strcmp0(char_info->char_path, char_path) == 0) return serv_info; } } @@ -910,8 +829,7 @@ static struct gatt_service_info *__bt_gatt_find_gatt_service_from_desc(const cha for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) { struct gatt_desc_info *desc_info = l3->data; - if (g_strcmp0(desc_info->desc_path, desc_path) - == 0) + if (g_strcmp0(desc_info->desc_path, desc_path) == 0) return serv_info; } } @@ -1449,8 +1367,7 @@ static struct gatt_char_info *__bt_gatt_find_gatt_char_info( for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) { struct gatt_char_info *char_info = l2->data; - if (g_strcmp0(char_info->char_path, char_path) - == 0) + if (g_strcmp0(char_info->char_path, char_path) == 0) return char_info; } BT_ERR("Gatt characteristic not found"); @@ -1474,8 +1391,7 @@ static struct gatt_desc_info *__bt_gatt_find_gatt_desc_info( for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) { struct gatt_char_info *char_info = l2->data; - if (g_strcmp0(char_info->char_path, char_path) - == 0) { + if (g_strcmp0(char_info->char_path, char_path) == 0) { for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) { struct gatt_desc_info *desc_info = l3->data; if (g_strcmp0(desc_info->desc_path, @@ -1548,23 +1464,7 @@ static GDBusProxy *__bt_gatt_gdbus_get_manager_proxy(const gchar *service, path, interface); } - -static void __bt_gatt_set_service_state(const char *service_path, - gboolean state) -{ - struct gatt_service_info *svc_info = NULL; - svc_info = __bt_gatt_find_gatt_service_info(service_path); - - if (svc_info != NULL) { - BT_DBG("Updating the gatt service register state %d", state); - svc_info->is_svc_registered = state; - return; - } - - BT_DBG("gatt service not found"); -} - -static gboolean __bt_gatt_get_service_state(const char *service_path) +static gboolean __bt_gatt_is_service_registered(const char *service_path) { struct gatt_service_info *svc_info = NULL; @@ -1596,13 +1496,10 @@ void get_service_cb(GObject *object, GAsyncResult *res, gpointer user_data) result = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error); if (result == NULL) { - /* dBUS-RPC is failed */ - BT_ERR("Dbus-RPC is failed\n"); - + BT_ERR("Dbus-RPC is failed"); if (error != NULL) { - /* dBUS gives error cause */ - BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n", - error->code, error->message); + BT_ERR("D-Bus API failure: errCode[%x], message[%s]", + error->code, error->message); g_clear_error(&error); } } else { @@ -1641,40 +1538,25 @@ void register_application_cb(GObject *object, GAsyncResult *res, gpointer user_d GError *error = NULL; GVariant *result; - register_pending_cnt = 0; - if (register_cancel) { g_object_unref(register_cancel); register_cancel = NULL; } result = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error); - if (result == NULL) { - /* dBUS-RPC is failed */ - BT_ERR("Dbus-RPC is failed\n"); - + BT_ERR("Dbus-RPC is failed"); if (error != NULL) { - /* dBUS gives error cause */ - BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n", - error->code, error->message); + BT_ERR("D-Bus API failure: errCode[%x], message[%s]", + error->code, error->message); g_clear_error(&error); } + is_server_started = false; } else { g_variant_unref(result); } } -static int __bt_gatt_unregister_service(const char *service_path) -{ - if (!__bt_gatt_get_service_state(service_path)) { - BT_DBG("service not registered \n"); - return BLUETOOTH_ERROR_NOT_FOUND; - } - - return BLUETOOTH_ERROR_NONE; -} - BT_EXPORT_API int bluetooth_gatt_unregister_application(void) { GDBusProxy *proxy = NULL; @@ -1683,38 +1565,37 @@ BT_EXPORT_API int bluetooth_gatt_unregister_application(void) GVariant *ret; GError *err = NULL; + if (app_path == NULL) { + BT_ERR("app_path is NULL"); + return BLUETOOTH_ERROR_INTERNAL; + } + proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez", "/org/bluez/hci0", GATT_MNGR_INTERFACE); - - if (proxy == NULL || app_path == NULL) + if (proxy == NULL) { + BT_ERR("proxy is NULL"); return BLUETOOTH_ERROR_INTERNAL; + } BT_INFO("UnregisterApplication"); - is_server_started = false; - /* Async Call to Unregister Service */ - ret = g_dbus_proxy_call_sync(proxy, - "UnregisterApplication", - g_variant_new("(o)", - app_path), - G_DBUS_CALL_FLAGS_NONE, -1, + ret = g_dbus_proxy_call_sync(proxy, "UnregisterApplication", + g_variant_new("(o)", app_path), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); - if (ret == NULL) { - /* dBUS-RPC is failed */ BT_ERR("dBUS-RPC is failed"); if (err != NULL) { - /* dBUS gives error cause */ BT_ERR("D-Bus API failure: errCode[%x], message[%s]", - err->code, err->message); - + err->code, err->message); g_clear_error(&err); } return BLUETOOTH_ERROR_INTERNAL; } g_variant_unref(ret); + is_server_started = false; + BT_INFO("UnregisterApplication is completed"); return BLUETOOTH_ERROR_NONE; @@ -1860,44 +1741,41 @@ BT_EXPORT_API int bluetooth_gatt_deinit() register_cancel = NULL; } - /* Unown gdbus bus */ - if (owner_id) { - /* remove/unregister all services */ - BT_DBG("removing all registered gatt service\n"); - bluetooth_gatt_delete_services(); + if (owner_id == 0) { + BT_ERR("owner_id is zero"); + __bt_gatt_close_gdbus_connection(); + return BLUETOOTH_ERROR_NOT_FOUND; + } - /* unregister the exported interface for object manager */ - g_dbus_connection_unregister_object(g_conn, - manager_id); + BT_DBG("Removing all registered gatt services"); + bluetooth_gatt_delete_services(); + /* Unregister the exported interface for object manager */ + if (manager_id) { + g_dbus_connection_unregister_object(g_conn, manager_id); manager_id = 0; + } - ret = bluetooth_gatt_unregister_application(); - if (ret != BLUETOOTH_ERROR_NONE) - BT_ERR("Fail to unregister application\n"); - - g_bus_unown_name(owner_id); - owner_id = 0; - - g_free(app_path); - app_path = NULL; + ret = bluetooth_gatt_unregister_application(); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Fail to unregister application"); + } - BT_DBG("Gatt service deinitialized \n"); + g_bus_unown_name(owner_id); + owner_id = 0; - g_slist_free(gatt_services); - gatt_services = NULL; + g_free(app_path); + app_path = NULL; + if (manager_gproxy) { g_object_unref(manager_gproxy); manager_gproxy = NULL; - - __bt_gatt_close_gdbus_connection(); - - return ret; } __bt_gatt_close_gdbus_connection(); - return BLUETOOTH_ERROR_NOT_FOUND; + BT_DBG("-"); + return ret; } BT_EXPORT_API int bluetooth_gatt_add_service(const char *svc_uuid, @@ -2024,7 +1902,7 @@ BT_EXPORT_API int bluetooth_gatt_add_new_characteristic( return BLUETOOTH_ERROR_INVALID_PARAM; node_info = __bt_gatt_create_method_node_info( - characteristics_introspection_xml); + characteristics_introspection_xml); if (node_info == NULL) return BLUETOOTH_ERROR_INTERNAL; @@ -2032,9 +1910,9 @@ BT_EXPORT_API int bluetooth_gatt_add_new_characteristic( BT_DBG("gatt characteristic path is [%s]", path); object_id = g_dbus_connection_register_object(g_conn, path, - node_info->interfaces[0], - &char_interface_vtable, - NULL, NULL, &error); + node_info->interfaces[0], + &char_interface_vtable, + NULL, NULL, &error); g_dbus_node_info_unref(node_info); if (object_id == 0) { @@ -2074,9 +1952,9 @@ BT_EXPORT_API int bluetooth_gatt_add_new_characteristic( inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); g_variant_builder_add(inner_builder, "{sv}", "UUID", - g_variant_new("s", char_uuid)); + g_variant_new("s", char_uuid)); g_variant_builder_add(inner_builder, "{sv}", "Service", - g_variant_new("o", svc_path)); + g_variant_new("o", svc_path)); builder2 = g_variant_builder_new(G_VARIANT_TYPE("as")); @@ -2085,24 +1963,23 @@ BT_EXPORT_API int bluetooth_gatt_add_new_characteristic( flags_val = g_variant_new("as", builder2); g_variant_builder_add(inner_builder, "{sv}", "Flags", - flags_val); + flags_val); builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao")); g_variant_builder_add(inner_builder, "{sv}", "Descriptors", - g_variant_new("ao", builder3)); + g_variant_new("ao", builder3)); g_variant_builder_add(builder, "{sa{sv}}", - GATT_CHAR_INTERFACE, - inner_builder); + GATT_CHAR_INTERFACE, + inner_builder); g_dbus_connection_emit_signal(g_conn, NULL, "/", - "org.freedesktop.Dbus.ObjectManager", - "InterfacesAdded", - g_variant_new("(oa{sa{sv}})", + "org.freedesktop.Dbus.ObjectManager", + "InterfacesAdded", + g_variant_new("(oa{sa{sv}})", path, builder), - &error); - + &error); if (error) { /* dBUS gives error cause */ BT_ERR("Could not Emit Signal: errCode[%x], message[%s]", @@ -2376,15 +2253,15 @@ BT_EXPORT_API int bluetooth_gatt_set_descriptor_value( g_variant_builder_add(inner_builder, "{sv}", "Value", desc_val); g_variant_builder_add(builder, "{sa{sv}}", - GATT_DESC_INTERFACE, - inner_builder); + GATT_DESC_INTERFACE, + inner_builder); g_dbus_connection_emit_signal(g_conn, NULL, "/", - "org.freedesktop.Dbus.ObjectManager", - "InterfacesAdded", - g_variant_new("(oa{sa{sv}})", - desc_info->desc_path, builder), - &error); + "org.freedesktop.Dbus.ObjectManager", + "InterfacesAdded", + g_variant_new("(oa{sa{sv}})", + desc_info->desc_path, builder), + &error); if (error != NULL) { BT_ERR("D-Bus API failure: errCode[%x], \ @@ -2426,23 +2303,22 @@ int bluetooth_gatt_get_service(const char *svc_uuid) return BLUETOOTH_ERROR_NONE; } -BT_EXPORT_API int bluetooth_gatt_register_service( - const char *svc_path) +BT_EXPORT_API int bluetooth_gatt_register_service(const char *svc_path) { + struct gatt_service_info *svc_info = NULL; + if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_GATT_REGISTER_SERVICE) == BLUETOOTH_ERROR_PERMISSION_DEINED) { BT_ERR("Don't have aprivilege to use this API"); return BLUETOOTH_ERROR_PERMISSION_DEINED; } - register_pending_cnt++; - - if (__bt_gatt_get_service_state(svc_path)) { - BT_DBG("service already registered \n"); - return BLUETOOTH_ERROR_NONE; + svc_info = __bt_gatt_find_gatt_service_info(svc_path); + if (svc_info == NULL) { + BT_ERR("Cannot find service [%s]", svc_path); + return BLUETOOTH_ERROR_INTERNAL; } - - __bt_gatt_set_service_state(svc_path, TRUE); + svc_info->is_svc_registered = TRUE; return BLUETOOTH_ERROR_NONE; } @@ -2452,17 +2328,28 @@ BT_EXPORT_API int bluetooth_gatt_register_application(void) GDBusProxy *proxy = NULL; if (!is_server_started) { - if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_GATT_REGISTER_APPLICATION) == BLUETOOTH_ERROR_PERMISSION_DEINED) { BT_ERR("Don't have aprivilege to use this API"); return BLUETOOTH_ERROR_PERMISSION_DEINED; } + if (g_slist_length(gatt_services) == 0) { + BT_ERR("There is no registered service"); + return BLUETOOTH_ERROR_INTERNAL; + } + + if (app_path == NULL) { + BT_ERR("app_path is NULL"); + return BLUETOOTH_ERROR_INTERNAL; + } + proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez", "/org/bluez/hci0", GATT_MNGR_INTERFACE); - if (proxy == NULL || app_path == NULL) + if (proxy == NULL) { + BT_ERR("proxy is NULL"); return BLUETOOTH_ERROR_INTERNAL; + } BT_INFO("RegisterApplication"); @@ -2470,17 +2357,12 @@ BT_EXPORT_API int bluetooth_gatt_register_application(void) g_cancellable_cancel(register_cancel); g_object_unref(register_cancel); } - register_cancel = g_cancellable_new(); - g_dbus_proxy_call(proxy, - "RegisterApplication", - g_variant_new("(oa{sv})", - app_path, NULL), - G_DBUS_CALL_FLAGS_NONE, -1, - register_cancel, - (GAsyncReadyCallback) register_application_cb, - NULL); + g_dbus_proxy_call(proxy, "RegisterApplication", + g_variant_new("(oa{sv})", app_path, NULL), + G_DBUS_CALL_FLAGS_NONE, -1, register_cancel, + (GAsyncReadyCallback)register_application_cb, NULL); is_server_started = true; @@ -2506,13 +2388,11 @@ BT_EXPORT_API int bluetooth_gatt_delete_services(void) for (l = gatt_services; l != NULL; ) { struct gatt_service_info *info = l->data; - // In bluetooth_gatt_unregister_service, current node will be removed. - // Go forward to next node before calling bluetooth_gatt_unregister_service. + // In __bt_gatt_unregister_service, current node will be removed. + // Go forward to next node before calling __bt_gatt_unregister_service. l = l->next; - BT_DBG("svc_path is %s", info->serv_path); - if (bluetooth_gatt_unregister_service(info->serv_path) != BLUETOOTH_ERROR_NONE) { + if (__bt_gatt_unregister_service(info) != BLUETOOTH_ERROR_NONE) { ret = BLUETOOTH_ERROR_INTERNAL; - BT_ERR("Error in removing service %s", info->serv_path); } } BT_INFO("All services are removed : %d", ret); @@ -2543,8 +2423,8 @@ BT_EXPORT_API int bluetooth_gatt_update_characteristic( line_argv = g_strsplit_set(char_path, "/", 0); serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]); - if (!__bt_gatt_get_service_state(serv_path)) { - BT_DBG("service not registered for this characteristic \n"); + if (!__bt_gatt_is_service_registered(serv_path)) { + BT_DBG("service not registered for this characteristic"); g_free(serv_path); g_strfreev(line_argv); return BLUETOOTH_ERROR_INTERNAL; @@ -2562,7 +2442,7 @@ BT_EXPORT_API int bluetooth_gatt_update_characteristic( g_variant_builder_add(outer_builder, "{sv}", "Value", update_value); - BT_DBG("Updating characteristic value \n"); + BT_DBG("Updating characteristic value"); ret = g_dbus_connection_emit_signal(g_conn, NULL, char_path, "org.freedesktop.DBus.Properties", @@ -2707,54 +2587,63 @@ static void __char_info_free(gpointer data, gpointer user_data) __bt_gatt_free_characteristic_info(char_info); } -BT_EXPORT_API int bluetooth_gatt_unregister_service(const char *svc_path) +static int __bt_gatt_unregister_service(struct gatt_service_info *svc_info) { - struct gatt_service_info *svc_info; - gboolean ret; - int err = BLUETOOTH_ERROR_NONE; - - BT_DBG("svc_path %s", svc_path); - svc_info = __bt_gatt_find_gatt_service_info(svc_path); + int ret = BLUETOOTH_ERROR_NONE; - if (!svc_info) { - BT_ERR("Unable to find service info"); + if (svc_info == NULL) { + BT_ERR("svc_info is NULL"); return BLUETOOTH_ERROR_NOT_FOUND; } - err = __bt_gatt_unregister_service(svc_path); - if (err != BLUETOOTH_ERROR_NONE) { - BT_ERR("Could not unregister application"); - return err; + if (svc_info->is_svc_registered == FALSE) { + BT_ERR("%s is not registered", svc_info->serv_path); + return BLUETOOTH_ERROR_NOT_FOUND; } - g_slist_foreach(svc_info->char_data, __char_info_free, &err); + BT_DBG("svc_path %s", svc_info->serv_path); + + g_slist_foreach(svc_info->char_data, __char_info_free, &ret); g_slist_free(svc_info->char_data); svc_info->char_data = NULL; - ret = g_dbus_connection_unregister_object(g_conn, svc_info->serv_id); - if (ret) { - __bt_gatt_emit_interface_removed(svc_info->serv_path, - GATT_SERV_INTERFACE); + if (g_dbus_connection_unregister_object(g_conn, svc_info->serv_id) == FALSE) { + BT_ERR("Cannot unregister object for [%s]", svc_info->serv_path); + ret = BLUETOOTH_ERROR_INTERNAL; } else { - err = BLUETOOTH_ERROR_INTERNAL; + __bt_gatt_emit_interface_removed(svc_info->serv_path, GATT_SERV_INTERFACE); } - ret = g_dbus_connection_unregister_object(g_conn, svc_info->prop_id); - if (ret) - BT_DBG("Unregistered the service on properties interface"); - - /* list remove & free */ gatt_services = g_slist_remove(gatt_services, svc_info); __bt_gatt_free_service_info(svc_info); new_service = FALSE; - if (gatt_services == NULL) + if (gatt_services == NULL) { serv_id = 1; - else if (gatt_services->next == NULL) + } else if (gatt_services->next == NULL) { serv_id--; + } - return err; + return ret; +} + +BT_EXPORT_API int bluetooth_gatt_unregister_service(const char *svc_path) +{ + struct gatt_service_info *svc_info; + int ret = BLUETOOTH_ERROR_NONE; + + BT_DBG("+"); + + svc_info = __bt_gatt_find_gatt_service_info(svc_path); + + ret = __bt_gatt_unregister_service(svc_info); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Could not unregister service [%s]", svc_path); + } + + BT_DBG("-"); + return ret; } BT_EXPORT_API int bluetooth_gatt_send_response(int request_id, guint req_type, @@ -2835,8 +2724,8 @@ BT_EXPORT_API int bluetooth_gatt_server_set_notification(const char *char_path, line_argv = g_strsplit_set(char_path, "/", 0); serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]); - if (!__bt_gatt_get_service_state(serv_path)) { - BT_DBG("service not registered for this characteristic \n"); + if (!__bt_gatt_is_service_registered(serv_path)) { + BT_DBG("service not registered for this characteristic"); g_free(serv_path); g_strfreev(line_argv); return BLUETOOTH_ERROR_INTERNAL; @@ -2857,7 +2746,7 @@ BT_EXPORT_API int bluetooth_gatt_server_set_notification(const char *char_path, g_variant_builder_add(outer_builder, "{sv}", "Unicast", g_variant_new("s", addr)); - BT_DBG("Set characteristic Notification \n"); + BT_DBG("Set characteristic Notification"); ret = g_dbus_connection_emit_signal(g_conn, NULL, char_path, "org.freedesktop.DBus.Properties",