Implement the audio and nap_disconnect of Tizen2.3 02/33402/1
authorwu zheng <wu.zheng@intel.com>
Fri, 9 Jan 2015 05:29:58 +0000 (13:29 +0800)
committerwu zheng <wu.zheng@intel.com>
Fri, 9 Jan 2015 05:29:58 +0000 (13:29 +0800)
bt_audio_connect missed the profile of Tizen2.3 BT.
nap_disconnect need to be implemented for Tizen2.3.

Change-Id: Id352bcc7781000ef3ca0d266a534c384a9607813
Signed-off-by: Wu Zheng <wu.zheng@intel.com>
capi/bluetooth.c
include/bluetooth.h
include/bluez.h
lib/bluez.c
test/bluez-capi-test.c

index 2480e0c01a3cd7b8a0a4dc3ecc1939fdf0c8af8c..617d5243fc7c034dc91202ec28450cb8e0f86b51 100644 (file)
@@ -3360,7 +3360,7 @@ int bt_audio_connect(const char *remote_address,
        int user_privilieges, len;
        adapter_device_discovery_info_t *device_info;
 
-       DBG("");
+       DBG("type = %x", type);
 
        if (initialized == false)
                return BT_ERROR_NOT_INITIALIZED;
@@ -3394,6 +3394,9 @@ int bt_audio_connect(const char *remote_address,
        case BT_AUDIO_PROFILE_TYPE_ALL:
                uuid = BT_GENERIC_AUDIO_UUID;
                break;
+       case BT_AUDIO_PROFILE_TYPE_AG:
+               uuid = BT_A2DP_SOURCE_UUID;
+               break;
        default:
                DBG("Unknown role");
                return BT_ERROR_INVALID_PARAMETER;
@@ -3404,6 +3407,8 @@ int bt_audio_connect(const char *remote_address,
        if (device == NULL)
                return BT_ERROR_OPERATION_FAILED;
 
+       DBG("uuid = %s", uuid);
+
        if (type != BT_AUDIO_PROFILE_TYPE_ALL)
                bluez_device_connect_profile(device, uuid,
                                        profile_connect_callback);
@@ -3483,6 +3488,9 @@ int bt_audio_disconnect(const char *remote_address,
        case BT_AUDIO_PROFILE_TYPE_ALL:
                uuid = BT_GENERIC_AUDIO_UUID;
                break;
+       case BT_AUDIO_PROFILE_TYPE_AG:
+               uuid = BT_A2DP_SOURCE_UUID;
+               break;
        default:
                DBG("Unknown role");
                return BT_ERROR_INVALID_PARAMETER;
@@ -6293,6 +6301,51 @@ int bt_nap_disconnect_all(void)
                return BT_ERROR_OPERATION_FAILED;
 }
 
+int bt_nap_disconnect(const char *remote_address)
+{
+       bluez_device_t *device;
+       gboolean nap_server_connected;
+       int user_privilieges;
+
+       DBG("");
+
+       if (initialized == false)
+               return BT_ERROR_NOT_INITIALIZED;
+
+       if (default_adapter == NULL)
+               return BT_ERROR_ADAPTER_NOT_FOUND;
+
+       if (remote_address == NULL) {
+               DBG("address = NULL");
+               return BT_ERROR_INVALID_PARAMETER;
+       }
+
+       user_privilieges = bt_device_get_privileges(remote_address);
+
+       if (user_privilieges == 0) {
+               DBG("user not privilieges to pair and use");
+               /*todo: This point will check if Cynara allow user
+                       use the remote device
+                       if ok, return BT_SUCCESS.
+               */
+               return BT_ERROR_NOT_ENABLED;
+       }
+
+       nap_server_connected = bluez_find_network_address(remote_address);
+
+       if (!nap_server_connected)
+               return BT_ERROR_NOT_ENABLED;
+
+       device = bluez_adapter_get_device_by_address(default_adapter,
+                                                       remote_address);
+       if (device == NULL)
+               return BT_ERROR_OPERATION_FAILED;
+
+       bluez_device_disconnect_all(device, NULL);
+
+       return BT_SUCCESS;
+}
+
 int bt_hdp_register_sink_app(unsigned short data_type, char **app_id)
 {
        int result = BT_ERROR_NONE;
@@ -6744,8 +6797,9 @@ int bt_device_is_profile_connected(const char *remote_address,
        bluez_device_t *device;
        bt_device_info_s *device_info;
        gboolean rfcomm_connected;
-       gboolean is_type;
+       enum audio_profile_type audio_type;
        gboolean hid_connected = false;
+       gboolean nap_server_connected, nap_connected;
        int user_privilieges;
 
        DBG("");
@@ -6787,17 +6841,31 @@ int bt_device_is_profile_connected(const char *remote_address,
                *connected_status = rfcomm_connected;
                goto done;
        } else if (bt_profile == BT_PROFILE_A2DP) {
-               is_type = bluez_get_media_type(remote_address);
-
-               /*not check hfp and hsp connected, hfp is not ready*/
-               /*todo hfp and hsp checking*/
-               *connected_status = is_type;
+               audio_type = bluez_get_media_type(remote_address);
+               if (audio_type == AUDIO_TYPE_A2DP)
+                       *connected_status = TRUE;
+               else
+                       *connected_status = FALSE;
                goto done;
        } else if (bt_profile == BT_PROFILE_HID) {
                bluez_device_input_get_property_connected(device,
                                                        &hid_connected);
                *connected_status = hid_connected;
                goto done;
+       } else if (bt_profile == BT_PROFILE_AG) {
+               audio_type = bluez_get_media_type(remote_address);
+               if (audio_type == AUDIO_TYPE_AG)
+                       *connected_status = TRUE;
+               else
+                       *connected_status = FALSE;
+       }  else if (bt_profile == BT_PROFILE_NAP) {
+               bluez_device_network_get_property_connected(device,
+                                                       &nap_connected);
+               *connected_status = nap_connected;
+       }  else if (bt_profile == BT_PROFILE_NAP_SERVER) {
+               nap_server_connected =
+                               bluez_find_network_address(remote_address);
+               *connected_status = nap_server_connected;
        }
 
        free_device_info(device_info);
@@ -6815,9 +6883,10 @@ int bt_device_foreach_connected_profiles(
        bluez_device_t *device;
        bt_device_info_s *device_info;
        gboolean rfcomm_connected;
-       gboolean is_type;
-       gboolean hid_connected = false;
+       gboolean hid_connected = false, nap_connected;
+       gboolean nap_server_connected;
        int user_privilieges;
+       enum audio_profile_type audio_type;
 
        DBG("");
 
@@ -6857,13 +6926,15 @@ int bt_device_foreach_connected_profiles(
        if (rfcomm_connected)
                callback(BT_PROFILE_RFCOMM, user_data);
 
-       is_type = bluez_get_media_type(remote_address);
+       audio_type = bluez_get_media_type(remote_address);
 
        /*not check hfp and hsp connected, hfp is not ready*/
        /*todo hfp and hsp checking*/
 
-       if (is_type)
+       if (audio_type == AUDIO_TYPE_A2DP)
                callback(BT_PROFILE_A2DP, user_data);
+       else if (audio_type == AUDIO_TYPE_AG)
+               callback(BT_PROFILE_AG, user_data);
 
        if (!(bluez_device_input_get_property_connected(device,
                                        &hid_connected))) {
@@ -6871,6 +6942,14 @@ int bt_device_foreach_connected_profiles(
                        callback(BT_PROFILE_HID, user_data);
        }
 
+       bluez_device_network_get_property_connected(device, &nap_connected);
+       if (nap_connected)
+               callback(BT_PROFILE_NAP, user_data);
+
+       nap_server_connected = bluez_find_network_address(remote_address);
+       if (nap_server_connected)
+               callback(BT_PROFILE_NAP_SERVER, user_data);
+
        free_device_info(device_info);
 
        return BT_SUCCESS;
index 971e85f1d292ab0faa3d337529fc914cee2b7c6a..703e210e49c86bebf18064513ebae84d0abf02a7 100644 (file)
@@ -197,10 +197,14 @@ typedef enum
  */
 typedef enum
 {
-    BT_PROFILE_RFCOMM = 0x01, /**< RFCOMM Profile */
-    BT_PROFILE_A2DP = 0x02, /**< Advanced Audio Distribution Profile */
-    BT_PROFILE_HSP = 0x04, /**< Headset Profile */
-    BT_PROFILE_HID = 0x08, /**< Human Interface Device Profile */
+       BT_PROFILE_RFCOMM = 0x01, /**< RFCOMM Profile */
+       BT_PROFILE_A2DP = 0x02, /**< Advanced Audio Distribution Profile */
+       BT_PROFILE_HSP = 0x04, /**< Headset Profile */
+       BT_PROFILE_HID = 0x08, /**< Human Interface Device Profile */
+       BT_PROFILE_NAP = 0x10, /**< Network Access Point Profile */
+       BT_PROFILE_AG = 0x20, /**< Audio Gateway Profile */
+       BT_PROFILE_GATT = 0x40, /**< Generic Attribute Profile */
+       BT_PROFILE_NAP_SERVER = 0x80, /**< NAP server Profile */
 } bt_profile_e;
 
 /**
@@ -357,9 +361,10 @@ typedef enum {
  * @brief  Enumerations for the types of profiles related with audio
  */
 typedef enum {
-    BT_AUDIO_PROFILE_TYPE_ALL = 0,  /**< All supported profiles related with audio */
-    BT_AUDIO_PROFILE_TYPE_HSP_HFP,  /**< HSP(Headset Profile) and HFP(Hands-Free Profile) */
-    BT_AUDIO_PROFILE_TYPE_A2DP,  /**< A2DP(Advanced Audio Distribution Profile) */
+       BT_AUDIO_PROFILE_TYPE_ALL = 0,  /**< All supported profiles related with audio */
+       BT_AUDIO_PROFILE_TYPE_HSP_HFP,  /**< HSP(Headset Profile) and HFP(Hands-Free Profile) */
+       BT_AUDIO_PROFILE_TYPE_A2DP,  /**< A2DP(Advanced Audio Distribution Profile) */
+       BT_AUDIO_PROFILE_TYPE_AG,  /**< AG(Audio Gateway) */
 } bt_audio_profile_type_e;
 
 /**
@@ -2668,6 +2673,27 @@ int bt_nap_deactivate(void);
  */
 int bt_nap_disconnect_all(void);
 
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_NAP_MODULE
+ * @brief Disconnects the specified PANU(Personal Area Networking User) which is connected to you.
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/bluetooth
+ * @param[in] remote_address  The remote address
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #BT_ERROR_NONE  Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED  Not initialized
+ * @retval #BT_ERROR_NOT_ENABLED  Not enabled
+ * @retval #BT_ERROR_OPERATION_FAILED  Operation failed
+ * @retval #BT_ERROR_PERMISSION_DENIED  Permission denied
+ * @retval #BT_ERROR_NOT_SUPPORTED  Not supported
+ *
+ * @pre The Bluetooth NAP service must be activated with bt_nap_activate().
+ * @see bt_nap_activate()
+ */
+int bt_nap_disconnect(const char *remote_address);
+
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_NAP_MODULE
  * @brief  Registers a callback function that will be invoked when the connection state changes.
index 7601662894d9e01703e06851bb799ee055bbe8d9..5b5176aa8156c02cb339e2696a68383c4381c6aa 100644 (file)
@@ -511,7 +511,11 @@ void bluez_set_nap_connection_state_cb(
 void bluez_unset_nap_connection_state_cb(void);
 
 enum audio_profile_type {
+       AUDIO_TYPE_ALL,
+       AUDIO_TYPE_HSP_HFP,
        AUDIO_TYPE_A2DP,
+       AUDIO_TYPE_AG,
+       AUDIO_TYPE_UNKNOWN,
 };
 
 typedef void (*bluez_audio_state_cb_t)(int result,
@@ -749,7 +753,7 @@ void hdp_internal_handle_disconnect(gpointer user_data,
 void hdp_internal_handle_connect(gpointer user_data,
                                                GVariant *param);
 
-gboolean bluez_get_media_type(const char *remote_address);
+enum audio_profile_type bluez_get_media_type(const char *remote_address);
 
 int bluez_media_register_player(struct _bluez_adapter *adapter);
 
@@ -766,4 +770,6 @@ void bluez_unset_paired_changed_cb(void);
 int bluez_get_local_info(char **local_version, char **chipset,
                                char **firmware, char **stack_version);
 
+gboolean bluez_find_network_address(const char *address);
+
 #endif
index c240dc83222de8103672dc6e6a69d95369265af1..a68d424c23b96268d23b1ff8d14477c0dbd6ddac 100644 (file)
@@ -257,6 +257,7 @@ struct _bluez_gatt_desc {
 static GHashTable *bluez_object_hash;
 
 static GList *bluez_adapter_list;
+static GList *bluez_network_list;
 
 static GHashTable *bluez_adapter_hash;
 
@@ -553,6 +554,79 @@ static void handle_adapter_discoverable_timeout_changed(
                                adapter->discoverable_timeout_cb_data);
 }
 
+static void _bluez_remove_all_net_address(void)
+{
+       char *network_address;
+       GList *list, *next;
+
+       DBG("+");
+
+       if (bluez_network_list == NULL)
+               return;
+
+       for (list = g_list_first(bluez_network_list); list; list = next) {
+               next = g_list_next(list);
+               network_address = list->data;
+
+               bluez_network_list =
+                       g_list_remove(bluez_network_list, network_address);
+               g_free(network_address);
+       }
+
+       bluez_network_list = NULL;
+
+       DBG("-");
+
+       return;
+}
+
+static void _bluez_remove_network_address(const char *address)
+{
+       char *network_address;
+       GList *list, *next;
+
+       DBG("address = %s", address);
+
+       if (bluez_network_list == NULL)
+               return;
+
+       for (list = g_list_first(bluez_network_list); list; list = next) {
+               next = g_list_next(list);
+               network_address = list->data;
+
+               if (!g_strcmp0(network_address, address)) {
+                       bluez_network_list =
+                               g_list_remove(bluez_network_list,
+                                                       network_address);
+                       g_free(network_address);
+                       return;
+               }
+       }
+
+       return;
+}
+
+gboolean bluez_find_network_address(const char *address)
+{
+       char *network_address;
+       GList *list, *next;
+
+       DBG("address = %s", address);
+
+       if (bluez_network_list == NULL)
+               return FALSE;
+
+       for (list = g_list_first(bluez_network_list); list; list = next) {
+               next = g_list_next(list);
+               network_address = list->data;
+
+               if (!g_strcmp0(network_address, address))
+                       return TRUE;
+       }
+
+       return FALSE;
+}
+
 static void networkserver_on_signal(GDBusProxy *proxy,
                                        gchar *sender_name,
                                        gchar *signal_name,
@@ -578,8 +652,15 @@ static void networkserver_on_signal(GDBusProxy *proxy,
                        address, device,
                        nap_connnection_state_cb_data);
 
+       if (connected)
+               bluez_network_list =
+                       g_list_append(bluez_network_list, address);
+       else {
+               _bluez_remove_network_address(address);
+               g_free(address);
+       }
+
        g_free(device);
-       g_free(address);
 }
 
 static void adapter_properties_changed(GDBusProxy *proxy,
@@ -1241,7 +1322,7 @@ static void parse_bluez_control_interfaces(gpointer data, gpointer user_data)
        if (g_strcmp0(iface_name, MEDIATRANSPORT_INTERFACE) == 0) {
                gchar *uuid, *device_address;
                gchar *device_path;
-               enum audio_profile_type type;
+               enum audio_profile_type type = AUDIO_TYPE_ALL;
 
                path = g_dbus_proxy_get_object_path(proxy);
 
@@ -1280,10 +1361,13 @@ static void parse_bluez_control_interfaces(gpointer data, gpointer user_data)
                if (g_strcmp0(uuid, BT_A2DP_SINK_UUID) == 0) {
                        type = AUDIO_TYPE_A2DP;
                        object->media_type = type;
+               } else if (g_strcmp0(uuid, BT_A2DP_SOURCE_UUID) == 0) {
+                       type = AUDIO_TYPE_AG;
+                       object->media_type = type;
                }
 
                if (audio_state_cb) {
-                               audio_state_cb(0, TRUE, device_address,
+                       audio_state_cb(0, TRUE, device_address,
                                        type, audio_state_cb_data);
                }
 
@@ -2774,8 +2858,14 @@ static void detach_gatt_service_head(struct _bluez_device *device)
 
 static void unregister_bluez_device(struct _bluez_device *device)
 {
+       char address[BT_ADDRESS_STRING_SIZE];
+
        DBG("device path %s", device->object_path);
 
+       convert_device_path_to_address(device->object_path, address);
+
+       _bluez_remove_network_address((char *)address);
+
        g_hash_table_steal(bluez_device_hash, device->object_path);
 
        remove_device_from_head(device);
@@ -3201,6 +3291,7 @@ static void destruct_bluez_object_manager(void)
 
 void bluez_lib_deinit(void)
 {
+       _bluez_remove_all_net_address();
        destruct_bluez_objects();
        destruct_bluez_object_manager();
 }
@@ -4866,12 +4957,12 @@ void bluez_device_disconnect_le(struct _bluez_device *device)
                        bluez_device_disconnect_cb, notify);
 }
 
-gboolean bluez_get_media_type(const char *remote_address)
+enum audio_profile_type bluez_get_media_type(const char *remote_address)
 {
        struct _bluez_object *object;
        GList *list, *next;
        int length;
-       gboolean is_type = FALSE;
+       enum audio_profile_type type = AUDIO_TYPE_UNKNOWN;
        gchar device_address[BT_ADDRESS_STRING_SIZE];
 
        DBG("");
@@ -4888,14 +4979,18 @@ gboolean bluez_get_media_type(const char *remote_address)
                convert_device_path_to_address(object->path_name,
                                                (gchar *)device_address);
 
-               if (!g_strcmp0(remote_address, device_address) &&
-                       object->media_type == AUDIO_TYPE_A2DP) {
-                       is_type = TRUE;
-                       break;
+               if (!g_strcmp0(remote_address, device_address)) {
+                       if (object->media_type == AUDIO_TYPE_A2DP) {
+                               type = AUDIO_TYPE_A2DP;
+                               break;
+                       } else if (object->media_type == AUDIO_TYPE_AG) {
+                               type = AUDIO_TYPE_AG;
+                               break;
+                       }
                }
        }
 
-       return is_type;
+       return type;
 }
 
 static int bluez_read_local_info(int handle, guint8 *version,
index 5a4ef04caf6ef7dee1e50b472d1915db7c1a380e..50d2032c07ba2b9c50912ddaf7cb914bf8349c99 100644 (file)
@@ -1341,7 +1341,10 @@ static int audio_connect(const char *p1, const char *p2)
        int err;
 
        DBG("+");
-       if (g_strcmp0(p2, "a2dp") == 0) {
+       if (g_strcmp0(p2, "ag") == 0) {
+               DBG("ag");
+               err = bt_audio_connect(p1, BT_AUDIO_PROFILE_TYPE_AG);
+       } else if (g_strcmp0(p2, "a2dp") == 0) {
                DBG("a2dp");
                err = bt_audio_connect(p1, BT_AUDIO_PROFILE_TYPE_A2DP);
        } else if (g_strcmp0(p2, "all") == 0) {
@@ -2101,6 +2104,33 @@ static int nap_activate(const char *p1, const char *p2)
        return 0;
 }
 
+static int nap_disconnect_all(const char *p1, const char *p2)
+{
+       int ret;
+
+       ret = bt_nap_disconnect_all();
+       if (ret != BT_SUCCESS)
+               DBG("bt_nap_disconnect_all failed %d", ret);
+
+       return 0;
+}
+
+static int nap_disconnect(const char *p1, const char *p2)
+{
+       int ret;
+
+       if (p1 == NULL) {
+               ERROR("nap_disconnect need remote address");
+               return 0;
+       }
+
+       ret = bt_nap_disconnect(p1);
+       if (ret != BT_SUCCESS)
+               DBG("bt_nap_disconnect failed %d", ret);
+
+       return 0;
+}
+
 static int nap_deactivate(const char *p1, const char *p2)
 {
        int ret;
@@ -2630,10 +2660,10 @@ struct {
                "Usage: hid_disconnect 70:F9:27:64:DF:65\n\tDisconnect HID profile"},
 
        {"audio_connect", audio_connect,
-               "Usage: audio_connect address type(a2dp/all)\n\tConnect audio profile"},
+               "Usage: audio_connect address type(ag/a2dp/all)\n\tConnect audio profile"},
 
        {"audio_disconnect", audio_disconnect,
-               "Usage: audio_disconnect address type(a2dp/all)\n\tDisconnect audio profile"},
+               "Usage: audio_disconnect address type(ag/a2dp/all)\n\tDisconnect audio profile"},
 
        {"audio_set_connection_state_changed", audio_set_connection_state_changed,
                "Usage: audio_set_connection_state_changed\n\tset connection state callback"},
@@ -2762,6 +2792,12 @@ struct {
        {"nap_deactivate", nap_deactivate,
                "Usage: nap_deactivate\n\tdeactivate NAP"},
 
+       {"nap_disconnect_all", nap_disconnect_all,
+               "Usage: nap_disconnect_all\n\tdisconnect all nap connection"},
+
+       {"nap_disconnect", nap_disconnect,
+               "Usage: nap_disconnect remote_addr\n\tdisconnect nap connection"},
+
        {"nap_set_connection_state_changed_cb", nap_set_connection_state_changed_cb,
                "Usage: nap_set_connection_state_changed_cb\n\tset nap conn cb"},