[PATCH 2/6] bluetooth: Add register service for bluetooth
Gustavo F. Padovan
gustavo at padovan.org
Fri Jul 9 07:20:39 PDT 2010
Hi Zhenhua,
* Zhenhua Zhang <zhenhua.zhang at intel.com> [2010-07-05 13:45:05 +0800]:
> Add bluetooth_register_service() and bluetooth_unregister_service()
> where bluetooth profiles plugins like DUN GW can register themselves per
> adapter. It shares existing bluetooth framework to listen bluetooth
> events (new adapters, bluetoothd shutdown, etc..)
> ---
> plugins/bluetooth.c | 125 ++++++++++++++++++++++++++++++++++++++++++---------
> plugins/bluetooth.h | 8 +++
> 2 files changed, 112 insertions(+), 21 deletions(-)
>
> diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
> index 5a85eaa..3a3b5e6 100644
> --- a/plugins/bluetooth.c
> +++ b/plugins/bluetooth.c
> @@ -38,8 +38,19 @@
>
> static DBusConnection *connection;
> static GHashTable *uuid_hash = NULL;
> +static GHashTable *service_hash = NULL;
> static GHashTable *adapter_address_hash = NULL;
>
> +static char *bluetooth_service_type_to_str(enum bluetooth_service_type type)
> +{
> + switch (type) {
> + case DUN_GATEWAY:
> + return "DUN";
> + default:
> + return "";
> + }
> +}
> +
We actually don't need this function, you can put the
'enum bluetooth_service_type' value as hash key. Sounds better.
> void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
> char *buf, int size)
> {
> @@ -376,6 +387,9 @@ static void adapter_properties_cb(DBusPendingCall *call, gpointer user_data)
> GSList *device_list = NULL;
> GSList *l;
> const char *addr;
> + GHashTableIter hash_iter;
> + gpointer key, value;
> + struct bluetooth_profile *profile;
>
> reply = dbus_pending_call_steal_reply(call);
>
> @@ -393,6 +407,12 @@ static void adapter_properties_cb(DBusPendingCall *call, gpointer user_data)
> g_hash_table_insert(adapter_address_hash,
> g_strdup(path), g_strdup(addr));
>
> + g_hash_table_iter_init(&hash_iter, service_hash);
> + while (g_hash_table_iter_next(&hash_iter, &key, &value)) {
> + profile = value;
> + profile->create(path, NULL, addr, NULL);
You have to check if profile and profile->create is not NULL. It is more
safe.
> + }
> +
> for (l = device_list; l; l = l->next) {
> const char *device = l->data;
>
> @@ -492,10 +512,13 @@ static void bluetooth_remove_all_modem(gpointer key, gpointer value,
>
> static void bluetooth_disconnect(DBusConnection *connection, void *user_data)
> {
> - if (!uuid_hash)
> - return;
> + if (uuid_hash)
> + g_hash_table_foreach(uuid_hash, bluetooth_remove_all_modem,
> + NULL);
>
> - g_hash_table_foreach(uuid_hash, bluetooth_remove_all_modem, NULL);
> + if (service_hash)
> + g_hash_table_foreach(service_hash, bluetooth_remove_all_modem,
> + NULL);
> }
>
> static guint bluetooth_watch;
> @@ -503,12 +526,12 @@ static guint adapter_added_watch;
> static guint adapter_removed_watch;
> s.tatic guint property_watch;
>
> -int bluetooth_register_uuid(const char *uuid, struct bluetooth_profile *profile)
> +static int bluetooth_init()
> {
So I prefer a real refcount structure here, and call this
bluetooth_ref(). What do you think?
> int err;
>
> - if (uuid_hash)
> - goto done;
> + if (adapter_address_hash)
> + return 0;
>
> connection = ofono_dbus_get_connection();
>
> @@ -536,19 +559,9 @@ int bluetooth_register_uuid(const char *uuid, struct bluetooth_profile *profile)
> goto remove;
> }
>
> - uuid_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
> - g_free, NULL);
> -
> adapter_address_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
> g_free, g_free);
>
> -done:
> - g_hash_table_insert(uuid_hash, g_strdup(uuid), profile);
> -
> - bluetooth_send_with_reply("/", BLUEZ_MANAGER_INTERFACE, "GetProperties",
> - manager_properties_cb, NULL, NULL, -1,
> - DBUS_TYPE_INVALID);
> -
> return 0;
>
> remove:
> @@ -556,14 +569,13 @@ remove:
> g_dbus_remove_watch(connection, adapter_added_watch);
> g_dbus_remove_watch(connection, adapter_removed_watch);
> g_dbus_remove_watch(connection, property_watch);
> +
> return err;
> }
>
> -void bluetooth_unregister_uuid(const char *uuid)
> +static void bluetooth_exit()
and this one coul be bluetooth_unref()
> {
> - g_hash_table_remove(uuid_hash, uuid);
> -
> - if (g_hash_table_size(uuid_hash))
> + if (uuid_hash != NULL || service_hash != NULL)
> return;
>
> g_dbus_remove_watch(connection, bluetooth_watch);
> @@ -571,9 +583,80 @@ void bluetooth_unregister_uuid(const char *uuid)
> g_dbus_remove_watch(connection, adapter_removed_watch);
> g_dbus_remove_watch(connection, property_watch);
>
> - g_hash_table_destroy(uuid_hash);
> g_hash_table_destroy(adapter_address_hash);
> +}
> +
> +
> +int bluetooth_register_uuid(const char *uuid, struct bluetooth_profile *profile)
> +{
> + int err;
> +
> + err = bluetooth_init();
> + if (err)
> + return err;
> +
> + if (!uuid_hash)
> + uuid_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
> + g_free, NULL);
> +
> + g_hash_table_insert(uuid_hash, g_strdup(uuid), profile);
> +
> + bluetooth_send_with_reply("/", BLUEZ_MANAGER_INTERFACE, "GetProperties",
> + manager_properties_cb, NULL, NULL, -1,
> + DBUS_TYPE_INVALID);
> +
> + return 0;
> +}
> +
> +void bluetooth_unregister_uuid(const char *uuid)
> +{
> + g_hash_table_remove(uuid_hash, uuid);
> +
> + if (g_hash_table_size(uuid_hash) > 0)
> + return;
> +
> + g_hash_table_destroy(uuid_hash);
> uuid_hash = NULL;
> + bluetooth_exit();
> +}
> +
> +int bluetooth_register_service(enum bluetooth_service_type type,
> + struct bluetooth_profile *profile)
> +{
> + int err;
> + char *type_str;
> +
> + err = bluetooth_init();
> + if (err)
> + return err;
> +
> + type_str = bluetooth_service_type_to_str(type);
> +
> + if (!service_hash)
> + service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
> + g_free, NULL);
> +
> + g_hash_table_insert(service_hash, g_strdup(type_str), profile);
> +
> + bluetooth_send_with_reply("/", BLUEZ_MANAGER_INTERFACE, "GetProperties",
> + manager_properties_cb, NULL, NULL, -1,
> + DBUS_TYPE_INVALID);
> +
> + return 0;
> +}
> +
> +void bluetooth_unregister_service(enum bluetooth_service_type type)
> +{
> + char *type_str = bluetooth_service_type_to_str(type);
> +
> + g_hash_table_remove(service_hash, type_str);
> +
> + if (g_hash_table_size(service_hash) > 0)
> + return;
> +
> + g_hash_table_destroy(service_hash);
> + service_hash = NULL;
> + bluetooth_exit();
> }
>
> OFONO_PLUGIN_DEFINE(bluetooth, "Bluetooth Utils Plugins", VERSION,
> diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h
> index fb0d841..84707a9 100644
> --- a/plugins/bluetooth.h
> +++ b/plugins/bluetooth.h
> @@ -28,6 +28,10 @@
> /* Profiles bitfield */
> #define HFP_AG 0x01
>
> +enum bluetooth_service_type {
> + DUN_GATEWAY,
> +};
> +
> struct bluetooth_profile {
> const char *name;
> int (*create)(const char *device, const char *dev_addr,
> @@ -40,6 +44,10 @@ int bluetooth_register_uuid(const char *uuid,
> struct bluetooth_profile *profile);
> void bluetooth_unregister_uuid(const char *uuid);
>
> +int bluetooth_register_service(enum bluetooth_service_type type,
> + struct bluetooth_profile *profile);
> +void bluetooth_unregister_service(enum bluetooth_service_type type);
> +
> void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
> char *buf, int size);
>
> --
> 1.6.3.3
--
Gustavo F. Padovan
http://padovan.org
More information about the ofono
mailing list