Update the RFCOMM server connection information
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / rfcomm / bt-service-rfcomm.c
index 19c1b07..a8ff590 100644 (file)
 #include "bt-service-common.h"
 #include "bt-service-rfcomm.h"
 #include "bt-service-socket.h"
+#include "bt-service-battery-monitor.h"
+
+typedef struct {
+       char *sender;
+       int client_fd;
+} bt_rfcomm_conn_info_t;
+
+static GSList *server_conn_list = NULL;
 
 static void __bt_rfcomm_reply_pending_request(int result,
                int service_function, void *user_data, unsigned int size)
@@ -86,6 +94,7 @@ static void __bt_rfcomm_reply_pending_request(int result,
                        g_array_free(out_param, TRUE);
                        break;
                }
+               case BT_RFCOMM_LISTEN_AND_ACCEPT:
                case BT_RFCOMM_LISTEN: {
                        GUnixFDList *fd_list = NULL;
                        GError *error = NULL;
@@ -207,7 +216,19 @@ gboolean __bt_send_rfcomm_server_fd(gpointer user_data)
        return FALSE;
 }
 
-int _bt_rfcomm_socket_listen(char *svc_name, char *uuid)
+gboolean __bt_send_rfcomm_server_fd_with_accept(gpointer user_data)
+{
+       BT_DBG("+");
+
+       __bt_rfcomm_reply_pending_request(BLUETOOTH_ERROR_NONE,
+                       BT_RFCOMM_LISTEN_AND_ACCEPT, user_data, sizeof(int));
+
+       g_free(user_data);
+       BT_DBG("-");
+       return FALSE;
+}
+
+int _bt_rfcomm_socket_listen(char *svc_name, char *uuid, bool accept)
 {
        int channel = 0;
        int sock_fd;
@@ -224,7 +245,111 @@ int _bt_rfcomm_socket_listen(char *svc_name, char *uuid)
                return BLUETOOTH_ERROR_INTERNAL;
        }
 
-       g_idle_add(__bt_send_rfcomm_server_fd, g_memdup(&sock_fd, sizeof(int)));
+       if (accept == false)
+               g_idle_add(__bt_send_rfcomm_server_fd, g_memdup(&sock_fd, sizeof(int)));
+       else
+               g_idle_add(__bt_send_rfcomm_server_fd_with_accept, g_memdup(&sock_fd, sizeof(int)));
+
        BT_DBG("-");
        return sock_fd;
 }
+
+static bt_rfcomm_conn_info_t* __bt_find_server_from_list(const char *sender, int client_fd)
+{
+       GSList *l;
+       bt_rfcomm_conn_info_t *conn_info;
+
+       retv_if(NULL == sender, NULL);
+
+       for (l = server_conn_list; l != NULL; l = g_slist_next(l)) {
+               conn_info = l->data;
+               if (g_strcmp0(conn_info->sender, sender) == 0) {
+                       if (client_fd == conn_info->client_fd)
+                               return conn_info;
+               }
+       }
+
+       return NULL;
+}
+
+int _bt_rfcomm_server_conn_added(char *svc_name, int client_fd)
+{
+       bt_rfcomm_conn_info_t *conn_info = NULL;
+
+       retv_if(NULL == svc_name, BLUETOOTH_ERROR_INVALID_PARAM);
+
+       if (__bt_find_server_from_list(svc_name, client_fd) != NULL) {
+               BT_ERR("Client fd already exist");
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+       }
+
+       BT_INFO("RFCOMM server is connected: [%s], [%d]", svc_name, client_fd);
+
+       conn_info = g_malloc0(sizeof(bt_rfcomm_conn_info_t));
+
+       if (conn_info == NULL)
+               return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
+
+       _bt_start_connect_time();
+
+       conn_info->sender = g_strdup(svc_name);
+       conn_info->client_fd = client_fd;
+
+       server_conn_list = g_slist_append(server_conn_list, conn_info);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_rfcomm_server_conn_removed(char *svc_name, int client_fd)
+{
+       bt_rfcomm_conn_info_t *conn_info = NULL;
+
+       retv_if(NULL == svc_name, BLUETOOTH_ERROR_INVALID_PARAM);
+
+       BT_INFO("RFCOMM server is disconnected: [%s], [%d]", svc_name, client_fd);
+
+       /* Find the first connection */
+       conn_info = __bt_find_server_from_list(svc_name, client_fd);
+
+       if (conn_info == NULL) {
+               BT_ERR("No client fd is in list");
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+       }
+
+       _bt_stop_connect_time();
+
+       server_conn_list = g_slist_remove(server_conn_list, conn_info);
+       g_free(conn_info->sender);
+       g_free(conn_info);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_rfcomm_server_check_termination(const char *name)
+{
+       GSList *l;
+       bt_rfcomm_conn_info_t *conn_info = NULL;
+
+       ret_if(NULL == name);
+
+       for (l = server_conn_list; l != NULL; ) {
+               conn_info = l->data;
+               l = g_slist_next(l);
+               if (g_strcmp0(conn_info->sender, name) == 0) {
+                       _bt_rfcomm_server_conn_removed((char *)name,
+                                               conn_info->client_fd);
+               }
+       }
+}
+
+static void __bt_free_server_conn(bt_rfcomm_conn_info_t *conn_info)
+{
+       g_free(conn_info->sender);
+       g_free(conn_info);
+}
+
+void _bt_rfcomm_server_all_conn_removed(void)
+{
+       g_slist_free_full(server_conn_list, (GDestroyNotify)__bt_free_server_conn);
+       server_conn_list = NULL;
+}