Get local IRK value
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-rfcomm-server.c
index ee29302..7a4e32a 100644 (file)
 #include "bt-common.h"
 #include "bt-request-sender.h"
 #include "bt-event-handler.h"
-
-#ifdef TIZEN_FEATURE_BT_DPM
 #include "bt-dpm.h"
-#endif
 
 #define BLUETOOTH_SOCK_CONNECT_INFO_LEN 16
+#define BATTERY_MONITOR_RFCOMM_INTERVAL 5
 
 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
 
@@ -55,6 +53,27 @@ typedef struct {
        guint disconnect_idle_id;
 } rfcomm_info_t;
 
+static unsigned int rx_data = 0;
+static guint rx_tag = 0;
+
+static bool __rfcomm_record_rx_data(void)
+{
+       if (rx_data) {
+               int ret = _bt_common_send_rfcomm_rx_details(rx_data);
+               if (ret == BLUETOOTH_ERROR_NONE) {
+                       rx_data = 0;
+                       return TRUE;
+               } else {
+                       BT_ERR("RFCOMM rx data could not be registered");
+               }
+       }
+
+       rx_data = 0;
+       rx_tag = 0;
+
+       return FALSE;
+}
+
 static rfcomm_info_t *__find_rfcomm_info_with_id(int id)
 {
        GSList *l;
@@ -95,7 +114,7 @@ static rfcomm_info_t *__find_rfcomm_info_with_path(const gchar *path)
        for (l = rfcomm_nodes; l != NULL; l = l->next) {
                rfcomm_info_t *info = l->data;
 
-               if (g_strcmp0(info->path, path) == 0)
+               if (g_ascii_strcasecmp(info->path, path) == 0)
                        return info;
        }
 
@@ -109,7 +128,7 @@ static rfcomm_info_t *__find_rfcomm_info_with_uuid(const char *uuid)
        for (l = rfcomm_nodes; l != NULL; l = l->next) {
                rfcomm_info_t *info = l->data;
 
-               if (g_strcmp0(info->uuid, uuid) == 0)
+               if (g_ascii_strcasecmp(info->uuid, uuid) == 0)
                        return info;
        }
 
@@ -154,7 +173,7 @@ gboolean _check_uuid_path(char *path, char *uuid)
        if (!info)
                return FALSE;
 
-       if (strcmp(info->uuid, uuid) == 0)
+       if (g_ascii_strcasecmp(info->uuid, uuid) == 0)
                return TRUE;
 
        return FALSE;
@@ -174,6 +193,11 @@ static void __connected_cb(rfcomm_info_t *info, rfcomm_conn_t *conn,
        conn_info.server_id = info->id;
 
        BT_INFO_C("### Connected [RFCOMM Server]");
+
+       if (_bt_common_send_rfcomm_conn_info(RFCOMM_ROLE_SERVER,
+                       TRUE, conn_info.socket_fd) != BLUETOOTH_ERROR_NONE)
+               BT_ERR("Fail to send the connection info");
+
        _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_CONNECTED,
                        BLUETOOTH_ERROR_NONE, &conn_info,
                        event_info->cb, event_info->user_data);
@@ -211,6 +235,10 @@ static void __rfcomm_server_disconnect_conn(rfcomm_conn_t *conn,
        BT_INFO("Disconnected FD [%d]", conn->fd);
        disconn_info.socket_fd = conn->fd;
 
+       if (_bt_common_send_rfcomm_conn_info(RFCOMM_ROLE_SERVER,
+                       FALSE, disconn_info.socket_fd) != BLUETOOTH_ERROR_NONE)
+               BT_ERR("Fail to send the connection info");
+
        _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DISCONNECTED,
                        BLUETOOTH_ERROR_NONE, &disconn_info,
                        event_info->cb, event_info->user_data);
@@ -236,13 +264,6 @@ static gboolean __rfcomm_server_disconnect(rfcomm_info_t *info)
        return FALSE;
 }
 
-static gboolean __is_error_by_disconnect(GError *err)
-{
-       return !g_strcmp0(err->message, "Connection reset by peer") ||
-                       !g_strcmp0(err->message, "Connection timed out") ||
-                       !g_strcmp0(err->message, "Software caused connection abort");
-}
-
 static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
                                                                gpointer data)
 {
@@ -284,43 +305,38 @@ static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
        }
 
        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);
-
+               BT_ERR("IO Channel read is failed with %d(%s)", status, _bt_print_gio_status(status));
                g_free(buffer);
-               if (!err)
+
+               if (status == G_IO_STATUS_AGAIN)
                        return TRUE;
 
-               BT_ERR("IO Channel read error [%s]", err->message);
-               if (status == G_IO_STATUS_ERROR &&
-                   __is_error_by_disconnect(err)) {
-                       BT_ERR("cond : %d", cond);
+               if (err) {
+                       BT_ERR("IO Channel read error [%s]", err->message);
                        g_error_free(err);
+               }
 
-                       if (info->disconnect_idle_id > 0) {
-                               BT_INFO("Disconnect idle still not process remove source");
-                               g_source_remove(info->disconnect_idle_id);
-                               info->disconnect_idle_id = 0;
-                       }
-
-                       conn = __find_rfcomm_conn_with_fd(info, fd);
-                       if (conn == NULL) {
-                               BT_ERR("No Connection info found with FD [%d]", fd);
-                               return FALSE;
-                       }
+               if (info->disconnect_idle_id > 0) {
+                       BT_INFO("Disconnect idle still not process remove source");
+                       g_source_remove(info->disconnect_idle_id);
+                       info->disconnect_idle_id = 0;
+               }
 
-                       if (conn->disconnected == FALSE) {
-                               close(conn->fd);
-                               conn->disconnected = TRUE;
-                       }
-                       __rfcomm_server_disconnect(info);
+               conn = __find_rfcomm_conn_with_fd(info, fd);
+               if (conn == NULL) {
+                       BT_ERR("No Connection info found with FD [%d]", fd);
                        return FALSE;
                }
-               g_error_free(err);
-               return TRUE;
+
+               if (conn->disconnected == FALSE) {
+                       close(conn->fd);
+                       conn->disconnected = TRUE;
+               }
+               __rfcomm_server_disconnect(info);
+               return FALSE;
        }
 
        if (len == 0)
@@ -341,6 +357,14 @@ static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
                        result, &data_r,
                        event_info->cb, event_info->user_data);
 
+       if (bluetooth_get_battery_monitor_state()) {
+               if (rx_tag == 0) {
+                       BT_DBG("Adding rfcomm rx timeout function for battery monitor");
+                       rx_tag = g_timeout_add_seconds(BATTERY_MONITOR_RFCOMM_INTERVAL, (GSourceFunc)__rfcomm_record_rx_data, NULL);
+               }
+               rx_data += len;
+       }
+
        g_free(buffer);
 
        return TRUE;
@@ -361,7 +385,6 @@ int new_server_connection(const char *path, int fd, bluetooth_device_address_t *
                return -1;
        }
 
-#ifdef TIZEN_FEATURE_BT_DPM
        if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
                char addr_str[20];
 
@@ -373,7 +396,6 @@ int new_server_connection(const char *path, int fd, bluetooth_device_address_t *
 
                return -1;
        }
-#endif
 
        conn = g_new0(rfcomm_conn_t, 1);
        conn->fd = fd;
@@ -414,6 +436,7 @@ static rfcomm_info_t *__register_method()
        object_id = _bt_register_new_conn(path, new_server_connection);
        if (object_id < 0) {
                __rfcomm_delete_id(id);
+               g_free(path);
                return NULL;
        }
        info = g_new0(rfcomm_info_t, 1);
@@ -516,6 +539,16 @@ void _bt_rfcomm_server_disconnect_all(void)
 
        return;
 }
+
+void _bt_rfcomm_server_reset_timer(void)
+{
+       if (rx_tag > 0) {
+               g_source_remove(rx_tag);
+               rx_tag = 0;
+       }
+
+       rx_data = 0;
+}
 #else
 
 #define BT_RFCOMM_SERVER_ID_MAX 254
@@ -915,19 +948,17 @@ static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
        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);
+               BT_ERR("IO Channel read is failed with %d(%s)", status, _bt_print_gio_status(status));
                g_free(buffer);
+
+               if (status == G_IO_STATUS_AGAIN)
+                       return TRUE;
+
                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;
+               goto fail;
        }
 
        if (len == 0) {
@@ -1126,12 +1157,10 @@ BT_EXPORT_API int bluetooth_rfcomm_create_socket(const char *uuid)
                return BLUETOOTH_ERROR_PERMISSION_DEINED;
        }
 
-#ifdef TIZEN_FEATURE_BT_DPM
        if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
                BT_ERR("Not allow to use SPP profile");
                return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
        }
-#endif
 
 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
        BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
@@ -1174,12 +1203,10 @@ BT_EXPORT_API int bluetooth_rfcomm_create_socket_ex(const char *uuid, const char
                return BLUETOOTH_ERROR_PERMISSION_DEINED;
        }
 
-#ifdef TIZEN_FEATURE_BT_DPM
        if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
                BT_ERR("Not allow to use SPP profile");
                return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
        }
-#endif
 
        BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
        info = __register_method_2(path, bus_name);
@@ -1434,16 +1461,24 @@ BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int id, int max_pending_con
                return BLUETOOTH_ERROR_INVALID_PARAM;
        }
 
-#ifdef TIZEN_FEATURE_BT_DPM
        if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
                BT_ERR("Not allow to use SPP profile");
                return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
        }
-#endif
 
 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
        BT_INFO("RFCOMM Listen & accept from app");
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+       if (access(CONTAINER_FILE, F_OK) == 0) {
+               if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_LISTEN_AND_ACCEPT)
+                       == BLUETOOTH_ERROR_PERMISSION_DEINED) {
+                       BT_ERR("Don't have a privilege to use this API");
+                       return BLUETOOTH_ERROR_PERMISSION_DEINED;
+               }
+       }
+#endif
+
        info = __find_rfcomm_info_with_id(id);
        if (info == NULL)
                return BLUETOOTH_ERROR_INVALID_PARAM;
@@ -1492,15 +1527,23 @@ BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept_ex(const char *uuid,
 
        BT_CHECK_ENABLED(return);
 
-#ifdef TIZEN_FEATURE_BT_DPM
        if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
                BT_ERR("Not allow to use SPP profile");
                return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
        }
-#endif
 
        BT_INFO("RFCOMM Listen & accept from app");
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+       if (access(CONTAINER_FILE, F_OK) == 0) {
+               if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_LISTEN)
+                       == BLUETOOTH_ERROR_PERMISSION_DEINED) {
+                       BT_ERR("Don't have a privilege to use this API");
+                       return BLUETOOTH_ERROR_PERMISSION_DEINED;
+               }
+       }
+#endif
+
        info = __find_rfcomm_info_with_uuid(uuid);
        if (info == NULL)
                return BLUETOOTH_ERROR_INVALID_PARAM;
@@ -1538,16 +1581,24 @@ BT_EXPORT_API int bluetooth_rfcomm_listen(int id, int max_pending_connection)
                return BLUETOOTH_ERROR_INVALID_PARAM;
        }
 
-#ifdef TIZEN_FEATURE_BT_DPM
        if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
                BT_ERR("Not allow to use SPP profile");
                return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
        }
-#endif
 
 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
        BT_INFO("RFCOMM Listen");
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+       if (access(CONTAINER_FILE, F_OK) == 0) {
+               if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_LISTEN)
+                       == BLUETOOTH_ERROR_PERMISSION_DEINED) {
+                       BT_ERR("Don't have a privilege to use this API");
+                       return BLUETOOTH_ERROR_PERMISSION_DEINED;
+               }
+       }
+#endif
+
        info = __find_rfcomm_info_with_id(id);
        if (info == NULL)
                return BLUETOOTH_ERROR_INVALID_PARAM;
@@ -1600,12 +1651,10 @@ BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd)
 
        BT_CHECK_ENABLED(return);
 
-#ifdef TIZEN_FEATURE_BT_DPM
        if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
                BT_ERR("Not allow to use SPP profile");
                return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
        }
-#endif
 
        if (server_fd < 0) {
                BT_ERR("Invalid FD");