X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-api%2Fbt-rfcomm-server.c;h=ee29302e034e3e4173e73a98db9d6b2900f29a37;hb=1fa07edcd0e77a445700975773db3300f556caf5;hp=aa592763025fe36ec95610f41e2aaadcd5c827a8;hpb=9641b1d6e4c6b8a25dc3b1c83785f5d7c1ab9690;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-api/bt-rfcomm-server.c b/bt-api/bt-rfcomm-server.c index aa59276..ee29302 100644 --- a/bt-api/bt-rfcomm-server.c +++ b/bt-api/bt-rfcomm-server.c @@ -33,6 +33,8 @@ #include "bt-dpm.h" #endif +#define BLUETOOTH_SOCK_CONNECT_INFO_LEN 16 + #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT static GSList *rfcomm_nodes; @@ -367,7 +369,7 @@ int new_server_connection(const char *path, int fd, bluetooth_device_address_t * close(fd); _bt_convert_addr_type_to_string(addr_str, addr->addr); - _bt_disconnect_profile(addr_str, info->uuid, NULL, NULL); + _bt_disconnect_ext_profile(addr_str, info->path); return -1; } @@ -486,7 +488,7 @@ void _bt_rfcomm_server_disconnect_all(void) GSList *conn; char addr[20]; - BT_INFO("### Disconnect all RFCOMM server connections"); + BT_INFO(" ### Disconnect all RFCOMM server connections"); for (server = rfcomm_nodes; server; ) { rfcomm_info_t *info = server->data; @@ -505,7 +507,7 @@ void _bt_rfcomm_server_disconnect_all(void) _bt_convert_addr_type_to_string(addr, conn_info->addr.addr); - _bt_disconnect_profile(addr, info->uuid, NULL, NULL); + _bt_disconnect_ext_profile(addr, info->path); } server = server->next; @@ -514,6 +516,596 @@ void _bt_rfcomm_server_disconnect_all(void) return; } +#else + +#define BT_RFCOMM_SERVER_ID_MAX 254 + +typedef struct { + char addr[BT_ADDRESS_STRING_SIZE]; + int sock_fd; + int watch_id; + int server_id; +} rfcomm_remote_client_info_t; + +typedef struct { + char uuid[BLUETOOTH_UUID_STRING_MAX]; + int server_id; + int server_fd; + int watch_id; + int max_pending_conn; + gboolean auto_accept; + char pending_addr[BT_ADDRESS_STRING_SIZE]; + GSList *conn_list; +} rfcomm_server_info_t; + +static GSList *rfcomm_servers; +static gboolean id_used[BT_RFCOMM_SERVER_ID_MAX]; +int latest_id = 0; + +int __rfcomm_assign_server_id(void) +{ + int index; + + BT_DBG("latest_id: %d", latest_id); + + index = latest_id + 1; + + if (index >= BT_RFCOMM_SERVER_ID_MAX) + index = 0; + + BT_DBG("index: %d", index); + + while (id_used[index] == TRUE) { + if (index == latest_id) { + /* No available ID */ + BT_ERR("All request ID is used"); + return -1; + } + + index++; + + if (index >= BT_RFCOMM_SERVER_ID_MAX) + index = 0; + } + + latest_id = index; + id_used[index] = TRUE; + + BT_DBG("Assigned Id: %d", latest_id); + + return latest_id; +} + +void __rfcomm_delete_server_id(int id) +{ + ret_if(id >= BT_RFCOMM_SERVER_ID_MAX); + ret_if(id < 0); + + id_used[id] = FALSE; + + /* Next server will use this ID */ + latest_id = id - 1; +} + +static rfcomm_server_info_t *__get_rfcomm_server_info_with_uuid(const char *uuid) +{ + GSList *l; + + if (!uuid) + return NULL; + + for (l = rfcomm_servers; l != NULL; l = l->next) { + rfcomm_server_info_t *info = l->data; + + if (!strncasecmp(info->uuid, uuid, strlen(info->uuid))) + return info; + } + + return NULL; +} + +int _get_rfcomm_server_id(char *uuid, gboolean *auto_accept) +{ + rfcomm_server_info_t *server_info; + + server_info = __get_rfcomm_server_info_with_uuid(uuid); + if (!server_info) + return -1; + + *auto_accept = server_info->auto_accept; + return server_info->server_id; +} + +static rfcomm_server_info_t *__get_rfcomm_server_info_with_id(int server_id) +{ + GSList *l; + + for (l = rfcomm_servers; l != NULL; l = l->next) { + rfcomm_server_info_t *info = l->data; + if (!info) + continue; + + BT_DBG("info->server_fd: %d, sock_fd:%d", info->server_id, server_id); + if (info->server_id == server_id) + return info; + } + + return NULL; +} + +void _bt_rfcomm_server_set_pending_conn(int server_id, char *address) +{ + rfcomm_server_info_t *server_info; + + + if (!address) + return; + + server_info = __get_rfcomm_server_info_with_id(server_id); + if (!server_info) + return; + + g_strlcpy(server_info->pending_addr, address, BT_ADDRESS_STRING_SIZE); +} + +static rfcomm_remote_client_info_t *__get_rfcomm_rem_client_info_with_fd(int sock_fd) +{ + GSList *l; + GSList *l1; + + for (l = rfcomm_servers; l != NULL; l = l->next) { + rfcomm_server_info_t *info = l->data; + + if (!info) + continue; + + for (l1 = info->conn_list; l1 != NULL; l1 = l1->next) { + rfcomm_remote_client_info_t *client_info = l1->data; + if (!client_info) + continue; + + if (client_info->sock_fd == sock_fd) + return client_info; + } + } + + return NULL; +} + +static rfcomm_remote_client_info_t *__get_rfcomm_rem_client_info_with_addr(char *addr) +{ + GSList *l; + GSList *l1; + + retv_if(NULL == addr, NULL); + + for (l = rfcomm_servers; l != NULL; l = l->next) { + rfcomm_server_info_t *info = l->data; + + if (!info) + continue; + + for (l1 = info->conn_list; l1 != NULL; l1 = l1->next) { + rfcomm_remote_client_info_t *client_info = l1->data; + if (!client_info) + continue; + + if (!strncasecmp(client_info->addr, addr, strlen(client_info->addr))) + return client_info; + } + } + + return NULL; +} + +static void __remove_remote_client_info(rfcomm_remote_client_info_t *rem_client) +{ + BT_DBG("+"); + + if (rem_client == NULL) + return; + + if (0 < rem_client->sock_fd) { + shutdown(rem_client->sock_fd, SHUT_RDWR); + close(rem_client->sock_fd); + } + + if (rem_client->watch_id > 0) + g_source_remove(rem_client->watch_id); + + g_free(rem_client); + + BT_DBG("-"); +} + +static void __handle_rfcomm_client_disconnected(rfcomm_server_info_t *server_info, + rfcomm_remote_client_info_t *rem_client) +{ + bluetooth_rfcomm_disconnection_t disconn_info; + bt_event_info_t *event_info; + + BT_DBG("+"); + + if (rem_client == NULL || server_info == NULL) + return; + + event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT); + if (event_info == NULL) + return; + + memset(&disconn_info, 0x00, sizeof(bluetooth_rfcomm_disconnection_t)); + disconn_info.device_role = RFCOMM_ROLE_SERVER; + g_strlcpy(disconn_info.uuid, server_info->uuid, BLUETOOTH_UUID_STRING_MAX); + _bt_convert_addr_string_to_type(disconn_info.device_addr.addr, rem_client->addr); + BT_DBG("Disconnected FD [%d]", rem_client->sock_fd); + disconn_info.socket_fd = rem_client->sock_fd; + + _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DISCONNECTED, + BLUETOOTH_ERROR_NONE, &disconn_info, + event_info->cb, event_info->user_data); +} + +static void __remove_rfcomm_server(rfcomm_server_info_t *info) +{ + rfcomm_remote_client_info_t *client_info; + + BT_DBG("+"); + + if (!info) + return; + + rfcomm_servers = g_slist_remove(rfcomm_servers, info); + if (info->conn_list) { + do { + client_info = info->conn_list->data; + if (!client_info) + break; + + info->conn_list = g_slist_remove(info->conn_list, client_info); + __handle_rfcomm_client_disconnected(info, client_info); + __remove_remote_client_info(client_info); + } while (info->conn_list); + } + + if (info->server_fd) { + shutdown(info->server_fd, SHUT_RDWR); + close(info->server_fd); + } + + if (info->watch_id) + g_source_remove(info->watch_id); + + __rfcomm_delete_server_id(info->server_id); + g_free(info); + + BT_DBG("-"); +} + +static void __connected_cb(rfcomm_remote_client_info_t *client_info, bt_event_info_t *event_info) +{ + bluetooth_rfcomm_connection_t conn_info; + rfcomm_server_info_t *server_info; + + server_info = __get_rfcomm_server_info_with_id(client_info->server_id); + ret_if(server_info == NULL); + + memset(&conn_info, 0x00, sizeof(bluetooth_rfcomm_connection_t)); + conn_info.device_role = RFCOMM_ROLE_SERVER; + g_strlcpy(conn_info.uuid, server_info->uuid, BLUETOOTH_UUID_STRING_MAX); + conn_info.socket_fd = client_info->sock_fd; + _bt_convert_addr_string_to_type(conn_info.device_addr.addr, client_info->addr); + conn_info.server_id = server_info->server_id; + + BT_INFO_C("Connected [RFCOMM Server]"); + _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_CONNECTED, + BLUETOOTH_ERROR_NONE, &conn_info, + event_info->cb, event_info->user_data); +} + +static int __process_cmsg(struct msghdr *msg) +{ + int sock_fd = -1; + struct cmsghdr *cmsg_ptr = NULL; + + for (cmsg_ptr = CMSG_FIRSTHDR(msg); cmsg_ptr != NULL; + cmsg_ptr = CMSG_NXTHDR(msg, cmsg_ptr)) { + + if (cmsg_ptr->cmsg_level != SOL_SOCKET) + continue; + + if (cmsg_ptr->cmsg_type == SCM_RIGHTS) { + //int *desc = (int *)CMSG_DATA(cmsg_ptr); + int count + = ((cmsg_ptr->cmsg_len - CMSG_LEN(0)) / sizeof(int)); + + if (count < 0) { + BT_ERR("ERROR Invalid count of descriptors"); + continue; + } + + //sock_fd = desc[0]; + memcpy(&sock_fd, CMSG_DATA(cmsg_ptr), sizeof(sock_fd)); + BT_DBG("Remote client fd: %d", sock_fd); + } + } + + return sock_fd; +} + +static int __read_incomming_client_connection( + int server_fd, char *buf, unsigned int len, int *client_fd) +{ + int ret; + struct msghdr msg; + struct iovec iv; + struct cmsghdr cmsgbuf[2 * sizeof(struct cmsghdr) + 4]; + int retryCount = 0; + + retv_if(0 > server_fd, -1); + retv_if(NULL == client_fd, -1); + + BT_INFO("server_fd = %d", server_fd); + + memset(&msg, 0, sizeof(msg)); + memset(&iv, 0, sizeof(iv)); + + iv.iov_base = buf; + iv.iov_len = len; + msg.msg_iov = &iv; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + + for (retryCount = 0; retryCount < 5; retryCount++) { + ret = recvmsg(server_fd, &msg, 0); + BT_DBG("recvmsg ret = %d", ret); + if (ret < 0 && errno == EINTR) + continue; + else + break; + } + + if (ret < 0 && errno == EPIPE) { + /* End of stream, server listining stopped */ + BT_ERR("EOS errno: %d", errno); + return 0; + } + + if (ret < 0) { + BT_ERR("Ret errno: %d", errno); + return -1; + } + + if ((msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) != 0) { + BT_ERR("MSG Flags errno: %d", errno); + return -1; + } + + BT_INFO("Connection received"); + *client_fd = __process_cmsg(&msg); + if (*client_fd < 0) + BT_ERR("Invalid client_fd received"); + + return ret; +} + +static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond, + gpointer data) +{ + char *buffer = NULL; + gsize len = 0; + int result = BLUETOOTH_ERROR_NONE; + bt_event_info_t *event_info; + bluetooth_rfcomm_received_data_t data_r; + GIOStatus status = G_IO_STATUS_NORMAL; + GError *err = NULL; + rfcomm_remote_client_info_t *client_info = data; + rfcomm_server_info_t *server_info; + + retv_if(client_info == NULL, FALSE); + + server_info = __get_rfcomm_server_info_with_id(client_info->server_id); + + if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { + BT_ERR_C("RFComm Server disconnected: %d", client_info->sock_fd); + goto fail; + } + + buffer = g_malloc0(BT_RFCOMM_BUFFER_LEN + 1); + status = g_io_channel_read_chars(chan, buffer, + BT_RFCOMM_BUFFER_LEN, &len, &err); + if (status != G_IO_STATUS_NORMAL) { + BT_ERR("IO Channel read is failed with %d", status); + g_free(buffer); + if (err) { + BT_ERR("IO Channel read error [%s]", err->message); + if (status == G_IO_STATUS_ERROR && + !g_strcmp0(err->message, "Connection reset by peer")) { + BT_ERR("cond : %d", cond); + g_error_free(err); + goto fail; + } + g_error_free(err); + } + return TRUE; + } + + if (len == 0) { + BT_ERR("Length is zero, remote end hang up"); + goto fail; + } + + event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT); + if (event_info == NULL) { + g_free(buffer); + return TRUE; + } + + data_r.socket_fd = client_info->sock_fd; + data_r.buffer_size = len; + data_r.buffer = buffer; + + _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DATA_RECEIVED, + result, &data_r, + event_info->cb, event_info->user_data); + + g_free(buffer); + + return TRUE; + +fail: + BT_ERR("Failure occured, remove client connection"); + server_info->conn_list = g_slist_remove( + server_info->conn_list, client_info); + __handle_rfcomm_client_disconnected(server_info, client_info); + __remove_remote_client_info(client_info); + return FALSE; +} + +static gboolean __new_connection_request_cb(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + int len; + int size; + int channel; + int status; + int client_fd; + char buf[BLUETOOTH_SOCK_CONNECT_INFO_LEN]; + unsigned char addr[BT_ADDRESS_LENGTH_MAX]; + + bt_event_info_t *event_info; + GIOChannel *io; + rfcomm_remote_client_info_t *rem_client; + rfcomm_server_info_t *server_info = data; + + if (!server_info) { + BT_ERR("Server info is invalid"); + return FALSE; + } + + if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { + BT_INFO("RFCOMM Server with fd:%d is closed with cond:0x%X", + server_info->server_fd, cond); + goto err; + } + + BT_INFO("Server fd: %d", server_info->server_fd); + len = __read_incomming_client_connection( + server_info->server_fd, buf, BLUETOOTH_SOCK_CONNECT_INFO_LEN, &client_fd); + BT_DBG("Socket Read len: %d", len); + if (len == 0) { + BT_ERR("Listen stopped"); + goto err; + } else if (len != BLUETOOTH_SOCK_CONNECT_INFO_LEN) { + BT_ERR("Read length is not same as socket info length"); + goto err; + } + + len = 0; + /* Read size of data */ + size = buf[len] | (buf[len + 1] << 8); + len += 2; + + /* Read bluetooth address */ + memcpy(addr, buf + len, BT_ADDRESS_LENGTH_MAX); + len += BT_ADDRESS_LENGTH_MAX; + + /* Read channel */ + channel = buf[len] | (buf[len + 1] << 8) | + (buf[len + 2] << 16) | (buf[len + 3] << 24); + len += 4; + + /* Read status */ + status = buf[len] | (buf[len + 1] << 8) | + (buf[len + 2] << 16) | (buf[len + 3] << 24); + len += 4; + + BT_DBG("size: %d, channel: %d, status: %d", size, channel, status); + + rem_client = g_malloc0(sizeof(rfcomm_remote_client_info_t)); + rem_client->sock_fd = client_fd; + rem_client->server_id = server_info->server_id; + _bt_convert_addr_type_to_string(rem_client->addr, addr); + + BT_INFO("New client [%s] connection with socket_fd: %d, server_id: %d", + rem_client->addr, rem_client->sock_fd, rem_client->server_id); + + io = g_io_channel_unix_new(rem_client->sock_fd); + g_io_channel_set_encoding(io, NULL, NULL); + g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL); + rem_client->watch_id = g_io_add_watch(io, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + __data_received_cb, rem_client); + g_io_channel_unref(io); + + server_info->conn_list = g_slist_append(server_info->conn_list, rem_client); + event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT); + if (event_info) + __connected_cb(rem_client, event_info); + + return TRUE; + +err: + /* Error occurred, Remove RFCOMM server*/ + __remove_rfcomm_server(server_info); + return FALSE; +} + +static int __rfcomm_listen(rfcomm_server_info_t *server_info, bool accept) +{ + int result; + GUnixFDList *out_fd_list = NULL; + GIOChannel *server_io; + + retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + if (accept == false) { + g_array_append_vals(in_param1, server_info->uuid, BLUETOOTH_UUID_STRING_MAX); + result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN, + in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list); + } else { + g_array_append_vals(in_param1, server_info->uuid, BLUETOOTH_UUID_STRING_MAX); + result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN_AND_ACCEPT, + in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list); + } + + BT_DBG("result: %x", result); + if (result != BLUETOOTH_ERROR_NONE) { + BT_ERR("Fail to send request"); + return result; + } else if (NULL == out_fd_list) { + BT_ERR("out_fd_list is NULL"); + return BLUETOOTH_ERROR_INTERNAL; + } else { + int *fd_list_array; + int len = 0; + + if (!out_fd_list) + return BLUETOOTH_ERROR_INTERNAL; + + fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len); + BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]); + server_info->server_fd = fd_list_array[0]; + BT_INFO("Socket fd: %d", server_info->server_fd); + + g_free(fd_list_array); + g_object_unref(out_fd_list); + } + + server_io = g_io_channel_unix_new(server_info->server_fd); + g_io_channel_set_encoding(server_io, NULL, NULL); + g_io_channel_set_flags(server_io, G_IO_FLAG_NONBLOCK, NULL); + server_info->watch_id = g_io_add_watch(server_io, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + __new_connection_request_cb, server_info); + g_io_channel_unref(server_io); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return BLUETOOTH_ERROR_NONE; +} #endif BT_EXPORT_API int bluetooth_rfcomm_create_socket(const char *uuid) @@ -521,16 +1113,14 @@ BT_EXPORT_API int bluetooth_rfcomm_create_socket(const char *uuid) #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT rfcomm_info_t *info; #else - int result; - int socket_fd = -1; - char uuid_str[BLUETOOTH_UUID_STRING_MAX]; + rfcomm_server_info_t *server_info; #endif BT_CHECK_ENABLED(return); BT_CHECK_PARAMETER(uuid, return); BT_INFO("UUID Provided %s", uuid); - if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET) + if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_CREATE_SOCKET) == BLUETOOTH_ERROR_PERMISSION_DEINED) { BT_ERR("Don't have a privilege to use this API"); return BLUETOOTH_ERROR_PERMISSION_DEINED; @@ -553,26 +1143,19 @@ BT_EXPORT_API int bluetooth_rfcomm_create_socket(const char *uuid) info->disconnect_idle_id = 0; return info->id; #else + BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>"); - BT_INIT_PARAMS(); - BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - g_strlcpy(uuid_str, uuid, sizeof(uuid_str)); - g_array_append_vals(in_param1, uuid_str, BLUETOOTH_UUID_STRING_MAX); - - result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET, - in_param1, in_param2, in_param3, in_param4, &out_param); - - BT_DBG("result: %x", result); - - if (result == BLUETOOTH_ERROR_NONE) - socket_fd = g_array_index(out_param, int, 0); - else - BT_ERR("Fail to send request"); - - BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - return socket_fd; + server_info = __get_rfcomm_server_info_with_uuid(uuid); + if (!server_info) { + server_info = g_malloc0(sizeof(rfcomm_server_info_t)); + g_strlcpy(server_info->uuid, uuid, BLUETOOTH_UUID_STRING_MAX); + server_info->server_id = __rfcomm_assign_server_id(); + server_info->server_fd = -1; + server_info->watch_id = -1; + server_info->auto_accept = FALSE; + rfcomm_servers = g_slist_append(rfcomm_servers, server_info); + } + return server_info->server_id; #endif } @@ -585,7 +1168,7 @@ BT_EXPORT_API int bluetooth_rfcomm_create_socket_ex(const char *uuid, const char BT_CHECK_PARAMETER(path, return); BT_INFO("PATH Provided %s", path); - if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET_EX) + if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_CREATE_SOCKET_EX) == BLUETOOTH_ERROR_PERMISSION_DEINED) { BT_ERR("Don't have a privilege to use this API"); return BLUETOOTH_ERROR_PERMISSION_DEINED; @@ -617,12 +1200,12 @@ BT_EXPORT_API int bluetooth_rfcomm_remove_socket(int id) #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT rfcomm_info_t *info; #else - int result; + rfcomm_server_info_t *server_info; #endif BT_CHECK_ENABLED(return); - if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET) + if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_REMOVE_SOCKET) == BLUETOOTH_ERROR_PERMISSION_DEINED) { BT_ERR("Don't have a privilege to use this API"); return BLUETOOTH_ERROR_PERMISSION_DEINED; @@ -648,22 +1231,17 @@ BT_EXPORT_API int bluetooth_rfcomm_remove_socket(int id) return BLUETOOTH_ERROR_NONE; #else - BT_INIT_PARAMS(); - BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - g_array_append_vals(in_param1, &id, sizeof(int)); - - result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET, - in_param1, in_param2, in_param3, in_param4, &out_param); + BT_INFO("<<<<<<<<< RFCOMM Remove socket request from app, fd=[%d] >>>>>>>>>>>", socket_fd); - BT_DBG("result: %x", result); - - if (result == BLUETOOTH_ERROR_NONE) - _bt_remove_server(id); + server_info = __get_rfcomm_server_info_with_id(id); + if (!server_info) { + BT_ERR("server_info not found for socket_fd: %d", id); + return BLUETOOTH_ERROR_INVALID_PARAM; + } - BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + __remove_rfcomm_server(server_info); - return result; + return BLUETOOTH_ERROR_NONE; #endif } @@ -674,7 +1252,7 @@ BT_EXPORT_API int bluetooth_rfcomm_remove_socket_ex(const char *uuid) BT_CHECK_ENABLED(return); - if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET) + if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_REMOVE_SOCKET) == BLUETOOTH_ERROR_PERMISSION_DEINED) { BT_ERR("Don't have a privilege to use this API"); return BLUETOOTH_ERROR_PERMISSION_DEINED; @@ -706,7 +1284,7 @@ BT_EXPORT_API int bluetooth_rfcomm_server_disconnect(int socket_fd) char address[20]; - BT_INFO("### Disconnect RFCOMM server"); + BT_INFO(" ### Disconnect RFCOMM server"); if (socket_fd < 0) { BT_ERR("Invalid FD"); return BLUETOOTH_ERROR_INVALID_PARAM; @@ -729,7 +1307,7 @@ BT_EXPORT_API int bluetooth_rfcomm_server_disconnect(int socket_fd) _bt_convert_addr_type_to_string(address, conn->addr.addr); BT_DBG("Address %s", address); - _bt_disconnect_profile(address, info->uuid, NULL, NULL); + _bt_disconnect_ext_profile(address, info->path); if (info->disconnect_idle_id == 0) info->disconnect_idle_id = g_idle_add( @@ -738,23 +1316,29 @@ BT_EXPORT_API int bluetooth_rfcomm_server_disconnect(int socket_fd) return BLUETOOTH_ERROR_NONE; #else - int result; + rfcomm_remote_client_info_t *client_info; BT_CHECK_ENABLED(return); - BT_INIT_PARAMS(); - BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - g_array_append_vals(in_param1, &socket_fd, sizeof(int)); - - result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_SOCKET_DISCONNECT, - in_param1, in_param2, in_param3, in_param4, &out_param); + BT_INFO(">>>>>>>>RFCOMM server disconnect request from APP>>>>>>>>>"); + if (socket_fd < 0) { + BT_ERR("Invalid FD"); + return BLUETOOTH_ERROR_INVALID_PARAM; + } - BT_DBG("result: %x", result); + client_info = __get_rfcomm_rem_client_info_with_fd(socket_fd); + if (!client_info) { + BT_ERR("client_info not found for socket_fd: %d", socket_fd); + return BLUETOOTH_ERROR_NOT_CONNECTED; + } - BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + if (client_info->sock_fd) { + shutdown(client_info->sock_fd, SHUT_RDWR); + close(client_info->sock_fd); + client_info->sock_fd = -1; + } - return result; + return BLUETOOTH_ERROR_NONE; #endif } @@ -791,16 +1375,22 @@ BT_EXPORT_API gboolean bluetooth_rfcomm_is_server_uuid_available(const char *uui BT_EXPORT_API int bluetooth_rfcomm_server_is_connected(const bluetooth_device_address_t *device_address, gboolean *connected) { +#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT GSList *l; GSList *ll; rfcomm_info_t *info; rfcomm_conn_t *conn; +#else + char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 }; + rfcomm_remote_client_info_t *info; +#endif BT_CHECK_PARAMETER(device_address, return); BT_CHECK_PARAMETER(connected, return); *connected = FALSE; +#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT for (l = rfcomm_nodes; l; l = l->next) { info = l->data; @@ -820,6 +1410,14 @@ BT_EXPORT_API int bluetooth_rfcomm_server_is_connected(const bluetooth_device_ad } return BLUETOOTH_ERROR_NONE; +#else + _bt_convert_addr_type_to_string(input_addr, (unsigned char *)device_address->addr); + info = __get_rfcomm_rem_client_info_with_addr(input_addr); + if (info) + *connected = TRUE; + + return BLUETOOTH_ERROR_NONE; +#endif } BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int id, int max_pending_connection) @@ -827,8 +1425,7 @@ BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int id, int max_pending_con #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT rfcomm_info_t *info; #else - int result; - gboolean native_service = TRUE; + rfcomm_server_info_t *server_info; #endif BT_CHECK_ENABLED(return); @@ -866,21 +1463,23 @@ BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int id, int max_pending_con return result; #else - BT_INIT_PARAMS(); - BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - g_array_append_vals(in_param1, &id, sizeof(int)); - g_array_append_vals(in_param2, &max_pending_connection, sizeof(int)); - g_array_append_vals(in_param3, &native_service, sizeof(gboolean)); + BT_INFO("<<<<<<<<< RFCOMM Listen & accept from app >>>>>>>>>>>"); - result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN, - in_param1, in_param2, in_param3, in_param4, &out_param); + server_info = __get_rfcomm_server_info_with_id(id); + if (!server_info) { + BT_ERR("server_info not found for id: %d", id); + return BLUETOOTH_ERROR_INVALID_PARAM; + } - BT_DBG("result: %x", result); + if (server_info->server_fd >= 0) { + BT_ERR("server already listining"); + return BLUETOOTH_ERROR_DEVICE_BUSY; + } - BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + server_info->max_pending_conn = max_pending_connection; + server_info->auto_accept = TRUE; - return result; + return __rfcomm_listen(server_info, true); #endif } @@ -930,8 +1529,7 @@ BT_EXPORT_API int bluetooth_rfcomm_listen(int id, int max_pending_connection) #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT rfcomm_info_t *info; #else - int result; - gboolean native_service = FALSE; + rfcomm_server_info_t *server_info; #endif BT_CHECK_ENABLED(return); @@ -973,30 +1571,32 @@ BT_EXPORT_API int bluetooth_rfcomm_listen(int id, int max_pending_connection) info->path, id); #else - BT_INIT_PARAMS(); - BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - g_array_append_vals(in_param1, &id, sizeof(int)); - g_array_append_vals(in_param2, &max_pending_connection, sizeof(int)); - g_array_append_vals(in_param3, &native_service, sizeof(gboolean)); - - result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN, - in_param1, in_param2, in_param3, in_param4, &out_param); - - BT_DBG("result: %x", result); + BT_INFO("<<<<<<<<< RFCOMM Listen >>>>>>>>>>>"); - if (result == BLUETOOTH_ERROR_NONE) - _bt_add_server(id); + server_info = __get_rfcomm_server_info_with_id(id); + if (!server_info) { + BT_ERR("server_info not found for id: %d", id); + return BLUETOOTH_ERROR_INVALID_PARAM; + } - BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + if (server_info->server_fd >= 0) { + BT_ERR("server already listining"); + return BLUETOOTH_ERROR_DEVICE_BUSY; + } - return result; + server_info->max_pending_conn = max_pending_connection; + server_info->auto_accept = FALSE; + return __rfcomm_listen(server_info, false); #endif } BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd) { int result; +#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT +#else + rfcomm_server_info_t *server_info; +#endif BT_CHECK_ENABLED(return); @@ -1015,7 +1615,17 @@ BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd) BT_INIT_PARAMS(); BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); +#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT g_array_append_vals(in_param1, &server_fd, sizeof(int)); +#else + server_info = __get_rfcomm_server_info_with_id(server_fd); + if (!server_info) { + BT_ERR("No server with fd: %d", server_fd); + return BLUETOOTH_ERROR_INVALID_PARAM; + } + + g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE); +#endif result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_ACCEPT_CONNECTION, in_param1, in_param2, in_param3, in_param4, &out_param); @@ -1030,6 +1640,10 @@ BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd) BT_EXPORT_API int bluetooth_rfcomm_reject_connection(int server_fd) { int result; +#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT +#else + rfcomm_server_info_t *server_info; +#endif BT_CHECK_ENABLED(return); @@ -1043,8 +1657,17 @@ BT_EXPORT_API int bluetooth_rfcomm_reject_connection(int server_fd) BT_INIT_PARAMS(); BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); +#ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT g_array_append_vals(in_param1, &server_fd, sizeof(int)); +#else + server_info = __get_rfcomm_server_info_with_id(server_fd); + if (!server_info) { + BT_ERR("No server with fd: %d", server_fd); + return BLUETOOTH_ERROR_INVALID_PARAM; + } + g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE); +#endif result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REJECT_CONNECTION, in_param1, in_param2, in_param3, in_param4, &out_param);