*/
#include <string.h>
-#ifdef RFCOMM_DIRECT
+#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
#include <errno.h>
#include <gio/gunixfdlist.h>
#endif
#include "bt-request-sender.h"
#include "bt-event-handler.h"
-#ifdef TIZEN_DPM_ENABLE
+#ifdef TIZEN_FEATURE_BT_DPM
#include "bt-dpm.h"
#endif
-#ifdef RFCOMM_DIRECT
+#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
#define BT_TIMEOUT_MESSAGE "Did not receive a reply. Possible causes include: " \
"the remote application did not send a reply, " \
typedef struct {
char bt_addr[BT_ADDRESS_STRING_SIZE];
int fd;
- int watch_id;
+ guint watch_id;
gboolean disconnected;
} rfcomm_conn_info_t;
if (conn == NULL)
return;
- if (conn->fd > 0)
- close(conn->fd);
if (conn->watch_id > 0) {
g_source_remove(conn->watch_id);
conn->watch_id = 0;
}
+
g_free(conn);
BT_DBG("-");
{
GSList *l;
rfcomm_conn_info_t *device_node = NULL;
- for(l = info->rfcomm_conns; l != NULL; l = l->next) {
+ for (l = info->rfcomm_conns; l != NULL; l = l->next) {
device_node = l->data;
- if ( device_node && device_node->fd == fd)
+ if (device_node && device_node->fd == fd)
return device_node;
}
return NULL;
static void __rfcomm_client_connected_cb(rfcomm_cb_data_t *info,
char *dev_address, int result)
{
+ if (g_slist_find(rfcomm_clients, info) == NULL) {
+ BT_INFO("rfcomm resource is already freed");
+ return;
+ }
+
__client_connected_cb(info, dev_address, result);
__rfcomm_remove_conn_info_t(info, dev_address);
bluetooth_rfcomm_disconnection_t disconn_info;
bt_event_info_t *event_info = NULL;
+
if (conn_info->disconnected == FALSE)
return;
+
event_info = _bt_event_get_cb_data(BT_RFCOMM_CLIENT_EVENT);
if (event_info == NULL) {
+ __rfcomm_remove_conn_info_t(info, conn_info->bt_addr);
+
if (info->rfcomm_conns == NULL)
rfcomm_cb_data_remove(info);
return;
}
+
memset(&disconn_info, 0x00, sizeof(bluetooth_rfcomm_disconnection_t));
disconn_info.device_role = RFCOMM_ROLE_CLIENT;
g_strlcpy(disconn_info.uuid, info->uuid, BLUETOOTH_UUID_STRING_MAX);
- BT_DBG("Disconnected FD [%d]", conn_info->fd);
_bt_convert_addr_string_to_type(disconn_info.device_addr.addr,
conn_info->bt_addr);
+ BT_DBG("Disconnected FD [%d]", conn_info->fd);
disconn_info.socket_fd = conn_info->fd;
BT_DBG("Disconnection Result[%d] BT_ADDRESS[%s] UUID[%s] FD[%d]",
BLUETOOTH_ERROR_NONE, &disconn_info,
event_info->cb, event_info->user_data);
- if(conn_info) {
- BT_DBG("List is present deleting it");
- __rfcomm_remove_conn_info_t(info, conn_info->bt_addr);
- }
+ __rfcomm_remove_conn_info_t(info, conn_info->bt_addr);
+
if (info->rfcomm_conns == NULL)
rfcomm_cb_data_remove(info);
static gboolean __rfcomm_client_disconnect(gpointer user_data)
{
- rfcomm_cb_data_t *info = (rfcomm_cb_data_t *) user_data;
- BT_INFO_C("Disconnected [RFCOMM Client]");
+ rfcomm_cb_data_t *info = (rfcomm_cb_data_t *)user_data;
+
+ BT_INFO_C("### Disconnected [RFCOMM Client]");
+
retv_if(info == NULL, FALSE);
if (g_slist_find(rfcomm_clients, info) == NULL) {
return FALSE;
}
info->idle_id = 0;
+
g_slist_foreach(info->rfcomm_conns,
- (GFunc) _bt_rfcomm_disconnect_conn_info, info);
+ (GFunc)_bt_rfcomm_disconnect_conn_info, info);
+
BT_DBG("-");
return FALSE;
}
fd = g_io_channel_unix_get_fd(chan);
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
BT_ERR_C("RFComm Client disconnected: %d", fd);
+
conn_info = __get_conn_info_from_fd(info, fd);
if (conn_info == NULL) {
BT_ERR("No Connection info found with FD [%d]", fd);
return FALSE;
}
- conn_info->disconnected = TRUE;
+
+ if (conn_info->disconnected == FALSE) {
+ close(conn_info->fd);
+ conn_info->disconnected = TRUE;
+ }
__rfcomm_client_disconnect(info);
return FALSE;
}
__is_error_by_disconnect(err)) {
BT_ERR("cond : %d", cond);
g_error_free(err);
+
conn_info = __get_conn_info_from_fd(info, fd);
if (conn_info == NULL) {
BT_ERR("No Connection info found with FD [%d]", fd);
return FALSE;
}
- conn_info->disconnected = TRUE;
+
+ if (conn_info->disconnected == FALSE) {
+ close(conn_info->fd);
+ conn_info->disconnected = TRUE;
+ }
__rfcomm_client_disconnect(info);
return FALSE;
}
bluetooth_rfcomm_connection_t conn_info;
bt_event_info_t *event_info;
rfcomm_conn_info_t *conn_list_info = NULL;
- BT_INFO_C("Connected [RFCOMM Client]");
+
+ if (result == BLUETOOTH_ERROR_NONE)
+ BT_INFO_C("### Connected [RFCOMM Client]");
event_info = _bt_event_get_cb_data(BT_RFCOMM_CLIENT_EVENT);
if (event_info == NULL)
BT_DBG("-");
}
+void _bt_rfcomm_client_disconnect_all(void)
+{
+ GSList *client;
+ GSList *conn;
+
+ BT_INFO_C("### Disconnect all RFCOMM client connections");
+
+ for (client = rfcomm_clients; client; ) {
+ rfcomm_cb_data_t *info = client->data;
+
+ for (conn = info->rfcomm_conns; conn; conn = conn->next) {
+ rfcomm_conn_info_t *conn_info = conn->data;
+
+ if (conn_info == NULL)
+ continue;
+
+ if (conn_info->watch_id == 0 || conn_info->disconnected)
+ continue;
+
+ close(conn_info->fd);
+ conn_info->disconnected = TRUE;
+
+ _bt_disconnect_ext_profile(conn_info->bt_addr,
+ info->obj_path);
+ }
+
+ client = client->next;
+ __rfcomm_client_disconnect(info);
+ }
+
+ return;
+}
#endif
int new_connection(const char *path, int fd, bluetooth_device_address_t *addr)
rfcomm_cb_data_t *info;
GIOChannel *data_io;
rfcomm_conn_info_t *conn_info = NULL;
- BT_DBG("%s %d", path, fd);
char address[BT_ADDRESS_STRING_SIZE];
+
+ BT_INFO("%s %d", path, fd);
+
_bt_convert_addr_type_to_string(address,
(unsigned char *)addr);
+
info = __find_rfcomm_info_from_path(path);
- if (info == NULL)
+ if (info == NULL) {
+ BT_ERR("rfcomm info is NULL");
return -1;
- conn_info = __get_conn_info_from_address(info, address);
+ }
+ conn_info = __get_conn_info_from_address(info, address);
if (conn_info == NULL) {
- BT_ERR("Device Address %s not found in connection list", address);
+ BT_ERR("connection info is NULL");
return -1;
}
+
conn_info->fd = fd;
- BT_DBG("connection info fd %d", conn_info->fd);
+
data_io = g_io_channel_unix_new(fd);
+
g_io_channel_set_encoding(data_io, NULL, NULL);
g_io_channel_set_flags(data_io, G_IO_FLAG_NONBLOCK, NULL);
+
conn_info->watch_id = g_io_add_watch(data_io,
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
__client_data_received_cb, info);
g_io_channel_unref(data_io);
- __client_connected_cb(info, address,BLUETOOTH_ERROR_NONE);
+ __client_connected_cb(info, address, BLUETOOTH_ERROR_NONE);
return 0;
}
{
GError *error = NULL;
+ GVariant *value;
rfcomm_cb_data_t *cb_data;
char dev_address[BT_ADDRESS_STRING_SIZE];
const char *path;
cb_data = user_data;
- if (!g_dbus_proxy_call_finish(proxy, res, &error)) {
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (value == NULL) {
int result;
g_dbus_error_strip_remote_error(error);
BT_ERR("Error : %s \n", error->message);
__rfcomm_client_connected_cb(cb_data, dev_address, result);
g_error_free(error);
+ } else {
+ g_variant_unref(value);
}
+
if (proxy)
g_object_unref(proxy);
rfcomm_cb_data_t *cb_data;
int ret = 0;
GError *err = NULL;
+ GVariant *value;
bt_register_profile_info_t info = {0};
int result = BLUETOOTH_ERROR_NONE;
char dev_address[BT_ADDRESS_STRING_SIZE];
_bt_convert_device_path_to_address(path, dev_address);
BT_DBG("Device Adress [%s]", dev_address);
- g_dbus_proxy_call_finish(proxy, res, &err);
+ value = g_dbus_proxy_call_finish(proxy, res, &err);
if (proxy)
g_object_unref(proxy);
+ if (value)
+ g_variant_unref(value);
if (err != NULL) {
g_dbus_error_strip_remote_error(err);
const char *remote_uuid)
{
-#ifdef RFCOMM_DIRECT
+#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
rfcomm_cb_data_t *cb_data = NULL;
rfcomm_conn_info_t *conn = NULL;
#else
BT_CHECK_PARAMETER(remote_uuid, return);
BT_CHECK_ENABLED(return);
-#ifdef TIZEN_DPM_ENABLE
+#ifdef TIZEN_FEATURE_BT_DPM
if (_bt_check_dpm(BT_DPM_ADDRESS, (void *)remote_bt_address) == BT_DPM_RESTRICTED) {
BT_ERR("Blacklist device");
return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
}
#endif
-#ifdef RFCOMM_DIRECT
- BT_INFO_C("<<<<<<<<< RFCOMM Connect request from app >>>>>>>>>>>");
+#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
+ BT_INFO_C("### Connect RFCOMM");
int ret;
int id, object_id;
char *path;
object_id = _bt_register_new_conn(path, new_connection);
if (object_id < 0) {
__rfcomm_delete_id(id);
+ g_free(path);
return BLUETOOTH_ERROR_INTERNAL;
}
cb_data->object_id = object_id;
cb_data->id = id;
}
+
conn = g_new0(rfcomm_conn_info_t, 1);
conn->fd = -1;
_bt_convert_addr_type_to_string(conn->bt_addr,
BT_DBG("Connecting to %s uuid %s", conn->bt_addr, remote_uuid);
cb_data->rfcomm_conns = g_slist_append(cb_data->rfcomm_conns, conn);
+
ret = _bt_discover_services(conn->bt_addr, (char *)remote_uuid,
__bt_discover_service_response_cb, cb_data);
if (ret != BLUETOOTH_ERROR_NONE) {
rfcomm_cb_data_remove(cb_data);
return BLUETOOTH_ERROR_INTERNAL;
}
+
if (g_slist_find(rfcomm_clients, cb_data) == NULL) {
BT_INFO("Adding callback information to rfcomm_clients");
rfcomm_clients = g_slist_append(rfcomm_clients, cb_data);
client_info = l->data;
if (client_info == NULL)
continue;
- for(conn_list = client_info->rfcomm_conns;
+ for (conn_list = client_info->rfcomm_conns;
conn_list != NULL; conn_list = conn_list->next) {
conn_info = conn_list->data;
- if(conn_info == NULL)
+ if (conn_info == NULL)
continue;
if (g_strcmp0(address, conn_info->bt_addr) == 0) {
BT_EXPORT_API int bluetooth_rfcomm_disconnect(int socket_fd)
{
-#ifdef RFCOMM_DIRECT
+#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
rfcomm_cb_data_t *info;
rfcomm_conn_info_t *conn_info;
- BT_INFO_C("<<<<<<<<< RFCOMM Disconnect request from app >>>>>>>>");
+
+ BT_INFO_C("### Disconnect RFCOMM");
+
BT_CHECK_ENABLED(return);
if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_SOCKET_DISCONNECT)
return BLUETOOTH_ERROR_PERMISSION_DEINED;
}
+ BT_DBG("Requested FD %d", socket_fd);
if (socket_fd < 0) {
BT_ERR("Invalid FD");
return BLUETOOTH_ERROR_INVALID_PARAM;
BT_DBG("Could not find in client, so check in server");
return bluetooth_rfcomm_server_disconnect(socket_fd);
}
+
conn_info = __get_conn_info_from_fd(info, socket_fd);
if (conn_info == NULL) {
- BT_ERR("FATAL Error");
+ BT_ERR("Could not find connection info");
return BLUETOOTH_ERROR_INTERNAL;
}
- if (conn_info->watch_id <= 0) {
+
+ if (conn_info->watch_id == 0 || conn_info->disconnected) {
BT_ERR("Invalid state");
return BLUETOOTH_ERROR_NOT_CONNECTED;
}
+
+ close(conn_info->fd);
conn_info->disconnected = TRUE;
- close(socket_fd);
+
BT_INFO("conn_info %s", conn_info->bt_addr);
- _bt_disconnect_profile(conn_info->bt_addr, info->uuid, NULL,NULL);
+ _bt_disconnect_ext_profile(conn_info->bt_addr, info->obj_path);
+
if (info->idle_id == 0)
info->idle_id = g_idle_add(__rfcomm_client_disconnect, info);
return BLUETOOTH_ERROR_NONE;
#else
int result;
- int service_function;
BT_CHECK_ENABLED(return);
/* Support the OSP */
if (socket_fd == -1) {
/* Cancel connect */
- service_function = BT_RFCOMM_CLIENT_CANCEL_CONNECT;
+ result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_CLIENT_CANCEL_CONNECT,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
} else {
g_array_append_vals(in_param1, &socket_fd, sizeof(int));
- service_function = BT_RFCOMM_SOCKET_DISCONNECT;
+ result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_SOCKET_DISCONNECT,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
}
- result = _bt_send_request(BT_BLUEZ_SERVICE, service_function,
- in_param1, in_param2, in_param3, in_param4, &out_param);
-
BT_DBG("result: %x", result);
BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
BT_EXPORT_API int bluetooth_rfcomm_write(int fd, const char *buf, int length)
{
-#ifdef RFCOMM_DIRECT
+#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
int written;
#else
char *buffer;
return BLUETOOTH_ERROR_INVALID_PARAM;
}
- BT_DBG("FD : %d", fd);
-
-#ifndef RFCOMM_DIRECT
+#ifndef TIZEN_FEATURE_BT_RFCOMM_DIRECT
BT_CHECK_ENABLED(return);
#endif
retv_if(length <= 0, BLUETOOTH_ERROR_INVALID_PARAM);
-#ifdef TIZEN_DPM_ENABLE
+#ifdef TIZEN_FEATURE_BT_DPM
if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED ||
_bt_check_dpm(BT_DPM_HF_ONLY, NULL) == BT_DPM_RESTRICTED) {
BT_ERR("Not allow to write RFCOMM data");
}
#endif
-#ifdef RFCOMM_DIRECT
+#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
switch (privilege_token) {
case 0:
result = _bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_SOCKET_WRITE);